aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Bowling <kbowling@FreeBSD.org>2026-08-12 03:36:03 +0000
committerKevin Bowling <kbowling@FreeBSD.org>2026-08-12 03:39:40 +0000
commit43aa553ef45a4345bdfabadae40d811730151144 (patch)
treea0aa6114fa97a492b9118a90c37eb6a72cb9f20c
parentc28f2c551daf07345ac78b74459efe1014c49464 (diff)
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. MFC after: 2 weeks
-rw-r--r--sys/dev/ixgbe/if_ix.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c
index c12956fb6e07..0ec9dd584b60 100644
--- a/sys/dev/ixgbe/if_ix.c
+++ b/sys/dev/ixgbe/if_ix.c
@@ -4035,6 +4035,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;
@@ -4578,11 +4582,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,