diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index 80f288a4ccf..e76ac6e5ace 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -1079,6 +1079,11 @@ ixgbe_if_attach_post(if_ctx_t ctx) sc = iflib_get_softc(ctx); hw = &sc->hw; + /** + * XXX: Since we don't seem to be able to flag a missing module, make sure we don't keep reading an i2c bus for something that isn't there + * sfp_probe_timed_out will be set when i2c probe timeout is reached and will be reset on reinit using this event. + */ + hw->sfp_probe_timed_out = false; if (sc->intr_type == IFLIB_INTR_LEGACY && (sc->feat_cap & IXGBE_FEATURE_LEGACY_IRQ) == 0) { diff --git a/sys/dev/ixgbe/ixgbe_phy.c b/sys/dev/ixgbe/ixgbe_phy.c index da7d16a514d..ed069a75c7c 100644 --- a/sys/dev/ixgbe/ixgbe_phy.c +++ b/sys/dev/ixgbe/ixgbe_phy.c @@ -2016,6 +2016,15 @@ static s32 ixgbe_read_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset, if (ixgbe_is_sfp_probe(hw, byte_offset, dev_addr)) max_retry = IXGBE_SFP_DETECT_RETRIES; + /*** + * XXX : Workaround to prevent reading an sfp slot with nothing connected to it. + * There likely should be some signal to detect an empty slot, trying to keep reading for 1 second on every attempt isn't very practical + * sfp_probe_timed_out is reset on ixgbe_if_attach_post() which should be triggered on module placement. + */ + if (hw->sfp_probe_timed_out) { + max_retry = 0; + } + do { if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) return IXGBE_ERR_SWFW_SYNC; @@ -2074,6 +2083,9 @@ fail: retry++; } while (retry <= max_retry); + /* XXX it's probably enough to set this to true since we are in the error path */ + hw->sfp_probe_timed_out = hw->sfp_probe_timed_out || retry >= max_retry; + return status; } diff --git a/sys/dev/ixgbe/ixgbe_type.h b/sys/dev/ixgbe/ixgbe_type.h index a414e27142e..b6eeabc502e 100644 --- a/sys/dev/ixgbe/ixgbe_type.h +++ b/sys/dev/ixgbe/ixgbe_type.h @@ -4258,6 +4258,8 @@ struct ixgbe_hw { bool allow_unsupported_sfp; bool wol_enabled; bool need_crosstalk_fix; + /* XXX flag for workaround to prevent reading an sfp[+] slot with nothing connected to it. */ + bool sfp_probe_timed_out; u32 fw_rst_cnt; };