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;