The branch main has been updated by kbowling:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=26e3a8045ec7e2abfea9e2e49577c5e2c4226df1

commit 26e3a8045ec7e2abfea9e2e49577c5e2c4226df1
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-08-06 08:22:11 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-08-08 06:59:02 +0000

    ixv: Tolerate temporary PF mailbox unavailability
    
    A PF can be resetting, handling a slow link event, or deliberately
    withholding mailbox CTS while its VFs enumerate. Keep the VF attached
    when the reset handshake is temporarily unavailable so a later if_init
    can retry.
    
    Never leave VF hardware running without a negotiated mailbox API: start
    hardware only after reset succeeds, stop it when negotiation fails in
    attach or init, and defer later recovery through iflib. This prevents a
    tight reset loop while preserving recovery when the PF returns.
    
    MFC after:      2 weeks
---
 sys/dev/ixgbe/if_ixv.c | 77 ++++++++++++++++++++++++++++++++------------------
 1 file changed, 49 insertions(+), 28 deletions(-)

diff --git a/sys/dev/ixgbe/if_ixv.c b/sys/dev/ixgbe/if_ixv.c
index b954e092c04c..7fffc5ec00bb 100644
--- a/sys/dev/ixgbe/if_ixv.c
+++ b/sys/dev/ixgbe/if_ixv.c
@@ -406,6 +406,7 @@ ixv_if_attach_pre(if_ctx_t ctx)
        device_t dev;
        if_softc_ctx_t scctx;
        struct ixgbe_hw *hw;
+       bool mailbox_ready;
        int error = 0;
 
        INIT_DEBUGOUT("ixv_attach: begin");
@@ -448,36 +449,40 @@ ixv_if_attach_pre(if_ctx_t ctx)
        /* Setup the mailbox */
        ixgbe_init_mbx_params_vf(hw);
 
+       mailbox_ready = false;
        error = hw->mac.ops.reset_hw(hw);
-       if (error == IXGBE_ERR_RESET_FAILED)
-               device_printf(dev, "...reset_hw() failure: Reset Failed!\n");
-       else if (error)
-               device_printf(dev, "...reset_hw() failed with error %d\n",
-                   error);
-       if (error) {
-               error = EIO;
-               goto err_out;
-       }
-
-       error = hw->mac.ops.init_hw(hw);
-       if (error) {
-               device_printf(dev, "...init_hw() failed with error %d\n",
-                   error);
-               error = EIO;
-               goto err_out;
-       }
-
-       /* Negotiate mailbox API version */
-       error = ixv_negotiate_api(sc);
-       if (error) {
+       if (error != IXGBE_SUCCESS) {
+               /*
+                * A PF may be resetting or servicing a slow link event while 
its
+                * VFs are enumerated.  Keep the VF attached so a later if_init 
can
+                * retry the mailbox handshake.
+                */
                device_printf(dev,
-                   "Mailbox API negotiation failed during attach!\n");
-               goto err_out;
+                   "PF did not respond to the reset handshake: %d; "
+                   "continuing attach\n", error);
+       } else {
+               error = hw->mac.ops.init_hw(hw);
+               if (error != IXGBE_SUCCESS) {
+                       device_printf(dev, "...init_hw() failed with error 
%d\n",
+                           error);
+                       error = EIO;
+                       goto err_out;
+               }
+
+               /* Negotiate mailbox API version. */
+               error = ixv_negotiate_api(sc);
+               if (error != 0) {
+                       device_printf(dev,
+                           "Mailbox API negotiation failed during attach; "
+                           "continuing attach\n");
+                       hw->mac.ops.stop_adapter(hw);
+               } else
+                       mailbox_ready = true;
        }
 
-       /* Check if VF was disabled by PF */
-       error = hw->mac.ops.get_link_state(hw, &sc->link_enabled);
-       if (error) {
+       /* Check if VF was disabled by PF. */
+       if (!mailbox_ready ||
+           hw->mac.ops.get_link_state(hw, &sc->link_enabled) != 0) {
                /* PF is not capable of controlling VF state. Enable link. */
                sc->link_enabled = true;
        }
@@ -654,8 +659,13 @@ ixv_if_init(if_ctx_t ctx)
        bcopy(if_getlladdr(ifp), hw->mac.addr, IXGBE_ETH_LENGTH_OF_ADDRESS);
        hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, 1);
 
-       /* Reset VF and renegotiate mailbox API version */
-       hw->mac.ops.reset_hw(hw);
+       /* Reset VF and renegotiate mailbox API version. */
+       error = hw->mac.ops.reset_hw(hw);
+       if (error != IXGBE_SUCCESS) {
+               device_printf(dev,
+                   "PF did not respond to the reset handshake: %d\n", error);
+               return;
+       }
        hw->mac.ops.start_hw(hw);
        hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
        ixv_reconcile_mac(sc, ifp);
@@ -663,6 +673,14 @@ ixv_if_init(if_ctx_t ctx)
        if (error) {
                device_printf(dev,
                    "Mailbox API negotiation failed in if_init!\n");
+               /*
+                * Leave the adapter stopped until an explicit or deferred 
retry.
+                * Otherwise the admin-status callback immediately requests 
another
+                * reset and can keep its taskqueue in a tight loop while the 
PF is
+                * deliberately withholding mailbox CTS (for example, when the 
VF is
+                * quarantined).
+                */
+               hw->mac.ops.stop_adapter(hw);
                return;
        }
 
@@ -1865,6 +1883,9 @@ ixv_if_enable_intr(if_ctx_t ctx)
        struct ix_rx_queue *que = sc->rx_queues;
        u32 mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
 
+       if (hw->adapter_stopped)
+               return;
+
        IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
 
        mask = IXGBE_EIMS_ENABLE_MASK;

Reply via email to