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;