From bc99862101aaf7b6496a29ab811e3f54d68702fb Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Tue, 9 Nov 2021 17:21:43 +0100 Subject: [PATCH] ixgbe: workaround to prevent an i2c bus read to keep trying to read an empty slot When executing `ifconfig -v` this will lead to stalls for a second per interface due to the timeout being set to a static 10 without a module placed, this patch makes sure this is only allowed once per insertion. --- sys/dev/ixgbe/if_ix.c | 6 ++++++ sys/dev/ixgbe/ixgbe_phy.c | 12 ++++++++++++ sys/dev/ixgbe/ixgbe_type.h | 2 ++ 3 files changed, 20 insertions(+) diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index 959afa79e7d..cea6d1752f2 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -1135,6 +1135,12 @@ 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) { device_printf(dev, "Device does not support legacy interrupts"); diff --git a/sys/dev/ixgbe/ixgbe_phy.c b/sys/dev/ixgbe/ixgbe_phy.c index 2a735ead9a1..4b85b43d4c6 100644 --- a/sys/dev/ixgbe/ixgbe_phy.c +++ b/sys/dev/ixgbe/ixgbe_phy.c @@ -2033,6 +2033,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; @@ -2091,6 +2100,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 91b46da72c7..32d8085edef 100644 --- a/sys/dev/ixgbe/ixgbe_type.h +++ b/sys/dev/ixgbe/ixgbe_type.h @@ -4260,6 +4260,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; };