git: 26e3a8045ec7 - main - ixv: Tolerate temporary PF mailbox unavailability

Kevin Bowling <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a76d6e2.40b4b.6229f492__5529.20446950651$1786173206$gmane$org@gitrepo.freebsd.org>
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;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.