git: f89ea9e7b61b - stable/14 - ixgbe: Defer firmware recovery transitions to iflib

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Wed, 26 Aug 2026 01:07:09 UTC
The branch stable/14 has been updated by kbowling:

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

commit f89ea9e7b61b2d6ba5c1ddcd6795dd4463f1f080
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-08-12 03:36:03 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-08-26 01:02:47 +0000

    ixgbe: Defer firmware recovery transitions to iflib
    
    The firmware-mode callout invoked ixgbe_if_stop() directly.  This
    performed a full device reset without the iflib context lock or the
    iflib queue lifecycle.  It could also poll the E610 firmware command
    interface from callout context while identification was active.
    
    Request an iflib reset from the callout instead.  Reject initialization
    while firmware recovery remains active.  This leaves the interface
    stopped and lets iflib publish that state.  Request initialization when
    firmware exits recovery so an administratively-up interface can recover
    without operator intervention.
    
    (cherry picked from commit 43aa553ef45a4345bdfabadae40d811730151144)
---
 sys/dev/ixgbe/if_ix.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c
index 78fcabc3d68b..df3435434525 100644
--- a/sys/dev/ixgbe/if_ix.c
+++ b/sys/dev/ixgbe/if_ix.c
@@ -4026,6 +4026,10 @@ ixgbe_if_init(if_ctx_t ctx)
 	int i, j, err;
 
 	INIT_DEBUGOUT("ixgbe_if_init: begin");
+	if (atomic_load_acq_int(&sc->recovery_mode)) {
+		iflib_init_failed(ctx);
+		return;
+	}
 
 	/* Preserve the largest frame requested by the PF or an active VF. */
 	sc->max_frame_size = if_getmtu(ifp) + IXGBE_MTU_HDR;
@@ -4569,11 +4573,15 @@ ixgbe_fw_mode_timer(void *arg)
 			    " Adapters and Devices User Guide for details on"
 			    " firmware recovery mode.\n");
 
-			if (hw->adapter_stopped == FALSE)
-				ixgbe_if_stop(sc->ctx);
+			/* Stop and publish the failure from the iflib taskqueue. */
+			iflib_request_reset_if_up(sc->ctx);
+			iflib_admin_intr_deferred(sc->ctx);
 		}
-	} else
-		atomic_cmpset_acq_int(&sc->recovery_mode, 1, 0);
+	} else if (atomic_cmpset_acq_int(&sc->recovery_mode, 1, 0)) {
+		/* Reinitialize an interface which was up when recovery began. */
+		iflib_request_reset_if_up(sc->ctx);
+		iflib_admin_intr_deferred(sc->ctx);
+	}
 
 
 	callout_reset(&sc->fw_mode_timer, hz,