If the NIC is in some error state during device attach (seen on a i219LM 
when em_read_phy_reg_ex() returns at "MDI Error"), it can happen that we 
loop endlessly because the loop variable is modified again down in the 
call stack:

em_match_gig_phy() -> em_read_phy_reg() -> em_access_phy_reg_hv() -> sets 
hw->phy_addr

Fixing the underlying issue needs some more debugging. But we can use a 
separate variable to avoid the hang. The attach will then error out with 
"Hardware Initialization Failed".

OK?


diff --git a/sys/dev/pci/if_em_hw.c b/sys/dev/pci/if_em_hw.c
index 77adfe5707b..ccbc620739d 100644
--- a/sys/dev/pci/if_em_hw.c
+++ b/sys/dev/pci/if_em_hw.c
@@ -5810,7 +5810,12 @@ em_detect_gig_phy(struct em_hw *hw)
        }
 
        /* Read the PHY ID Registers to identify which PHY is onboard. */
-       for (hw->phy_addr = 1; (hw->phy_addr < 4); hw->phy_addr++) {
+       for (int i = 1; i < 4; i++) {
+               /*
+                * hw->phy_addr may be modified down in the call stack,
+                * we can't use it as loop variable.
+                */
+               hw->phy_addr = i;
                ret_val = em_match_gig_phy(hw);
                if (ret_val == E1000_SUCCESS)
                        return E1000_SUCCESS;

Reply via email to