git: 41a0f7a0a447 - main - e1000: Propagate hardware initialization failures

Kevin Bowling <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a818ef0.271a6.34215172__17806.858422567$1786875643$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by kbowling:

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

commit 41a0f7a0a447ef2092faadb35f6d4c3f80c088bf
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-08-16 07:55:37 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-08-16 10:20:17 +0000

    e1000: Propagate hardware initialization failures
    
    The reset helper discards reset_hw and init_hw errors.  Runtime
    initialization then continues programming rings and filters, and iflib
    publishes the interface as running even though the controller did not
    reach a usable state.  Initial attach similarly continues into NVM and
    MAC setup after a failed reset.
    
    Return errors from the reset helper.  Fail attach when the controller
    cannot be reset or initialized, and report runtime failures through
    iflib_init_failed() so iflib leaves the interface stopped.  Also stop
    register accesses and report the error when a stop-path reset fails.
    
    MFC after:      2 weeks
    Sponsored by:   BBOX.io
---
 sys/dev/e1000/if_em.c | 46 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 34 insertions(+), 12 deletions(-)

diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index 1622468bd2a0..6574b2d0e7d7 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -440,7 +440,7 @@ static bool	em_if_needs_restart(if_ctx_t, enum iflib_restart_event);
 static void	em_identify_hardware(if_ctx_t);
 static int	em_allocate_pci_resources(if_ctx_t);
 static void	em_free_pci_resources(if_ctx_t);
-static void	em_reset(if_ctx_t);
+static int	em_reset(if_ctx_t);
 static int	em_setup_interface(if_ctx_t);
 static int	em_setup_msix(if_ctx_t);
 
@@ -1571,6 +1571,10 @@ em_if_attach_pre(if_ctx_t ctx)
 		    error == E1000_SUCCESS);
 		if (error != E1000_SUCCESS)
 			igbv_log_reset_failure(sc, error, true);
+	} else if (error != E1000_SUCCESS) {
+		device_printf(dev, "Hardware reset failed: %d\n", error);
+		error = EIO;
+		goto err_late;
 	}
 
 	/* Make sure a PF has a good EEPROM before we read from it. */
@@ -1656,10 +1660,12 @@ em_if_attach_post(if_ctx_t ctx)
 		goto err_late;
 	}
 
-	if (sc->vf_ifp)
+	if (sc->vf_ifp) {
 		(void)igbv_reset(ctx);
-	else
-		em_reset(ctx);
+	} else if (em_reset(ctx) != E1000_SUCCESS) {
+		error = EIO;
+		goto err_late;
+	}
 
 	/* Initialize statistics */
 	if (sc->vf_ifp)
@@ -1870,8 +1876,9 @@ em_if_init(if_ctx_t ctx)
 	if (sc->vf_ifp) {
 		(void)igbv_reset(ctx);
 		em_rebase_vf_stats(sc);
-	} else {
-		em_reset(ctx);
+	} else if (em_reset(ctx) != E1000_SUCCESS) {
+		iflib_init_failed(ctx);
+		return;
 	}
 	if (sc->vf_ifp && !sc->vf_queues_sanitized) {
 		/*
@@ -3461,6 +3468,7 @@ static void
 em_if_stop(if_ctx_t ctx)
 {
 	struct e1000_softc *sc = iflib_get_softc(ctx);
+	s32 error;
 
 	INIT_DEBUGOUT("em_if_stop: begin");
 
@@ -3478,7 +3486,12 @@ em_if_stop(if_ctx_t ctx)
 	    (atomic_load_acq_32(&sc->vf_mbx_ready) != 0 &&
 	    (if_getflags(iflib_get_ifp(ctx)) & IFF_UP) == 0)) {
 		em_prepare_fatal_error_reset(sc);
-		e1000_reset_hw(&sc->hw);
+		error = e1000_reset_hw(&sc->hw);
+		if (!sc->vf_ifp && error != E1000_SUCCESS) {
+			device_printf(sc->dev, "Hardware reset failed while "
+			    "stopping: %d\n", error);
+			return;
+		}
 	}
 	if (sc->vf_ifp)
 		atomic_store_rel_32(&sc->vf_mbx_ready, 0);
@@ -4225,7 +4238,7 @@ em_flush_desc_rings(struct e1000_softc *sc)
  *  sc structure.
  *
  **********************************************************************/
-static void
+static int
 em_reset(if_ctx_t ctx)
 {
 	device_t dev = iflib_get_dev(ctx);
@@ -4234,6 +4247,7 @@ em_reset(if_ctx_t ctx)
 	struct e1000_hw *hw = &sc->hw;
 	u32 rx_buffer_size;
 	u32 pba;
+	s32 error;
 
 	INIT_DEBUGOUT("em_reset: begin");
 	KASSERT(!sc->vf_ifp, ("%s called for a VF", __func__));
@@ -4463,7 +4477,11 @@ em_reset(if_ctx_t ctx)
 
 	/* Issue a global reset */
 	em_prepare_fatal_error_reset(sc);
-	e1000_reset_hw(hw);
+	error = e1000_reset_hw(hw);
+	if (error != E1000_SUCCESS) {
+		device_printf(dev, "Hardware reset failed: %d\n", error);
+		return (error);
+	}
 	if (hw->mac.type >= igb_mac_min) {
 		E1000_WRITE_REG(hw, E1000_WUC, 0);
 	} else {
@@ -4476,9 +4494,11 @@ em_reset(if_ctx_t ctx)
 		sc->flags &= ~IGB_MEDIA_RESET;
 	}
 	/* and a re-init */
-	if (e1000_init_hw(hw) < 0) {
-		device_printf(dev, "Hardware Initialization Failed\n");
-		return;
+	error = e1000_init_hw(hw);
+	if (error != E1000_SUCCESS) {
+		device_printf(dev, "Hardware initialization failed: %d\n",
+		    error);
+		return (error);
 	}
 	em_configure_82576_memory_errors(sc);
 	em_finish_fatal_error_reset(sc);
@@ -4491,6 +4511,8 @@ em_reset(if_ctx_t ctx)
 	E1000_WRITE_REG(hw, E1000_VET, ETHERTYPE_VLAN);
 	e1000_get_phy_info(hw);
 	e1000_check_for_link(hw);
+
+	return (E1000_SUCCESS);
 }
 
 /*
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.