When a port is started before the DAC cable is plugged in,
hot-plugging the cable never brings the link up and the port has to
be stopped and started again.
The AN73 watchdog txgbe_dev_e56_check_bp_event() is armed once in
txgbe_dev_start(). Its first tick finds no module, so
txgbe_xpcs_an_enabled() returns false and the handler returns without
re-arming itself. Once the cable is inserted, nobody polls the AN73
completion any more and the link stays down.
Re-arm the watchdog from txgbe_dev_detect_sfp() once a module has
been identified, cancelling any pending instance first so that only
one of them is running at a time. On the removal path, drop the
cached SFP type and cancel the watchdog. Also sample the
module-present pin (GPIO_EXT bit 2 on 25G, bit 4 on 40G) on every
watchdog tick, so that pulling the cable is noticed even if no GPIO
interrupt is delivered.
Fixes: 234ce0d1fa9d ("net/txgbe: fix link stability for Amber-Lite backplane
mode")
Cc: [email protected]
Signed-off-by: Zaiyu Wang <[email protected]>
---
drivers/net/txgbe/txgbe_ethdev.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index ae755996e6..9a29539f14 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -2987,6 +2987,20 @@ void txgbe_dev_e56_check_bp_event(void *param)
if (!hw)
return;
+ /* Sample the module-present pin on every tick. When the cable is
+ * pulled, drop the cached SFP type so that txgbe_xpcs_an_enabled()
+ * turns false and this alarm stops re-arming itself.
+ */
+ if (hw->mac.type == txgbe_mac_aml)
+ value = rd32(hw, TXGBE_GPIOEXT) & TXGBE_SFP1_MOD_ABS_LS;
+ else if (hw->mac.type == txgbe_mac_aml40)
+ value = rd32(hw, TXGBE_GPIOEXT) & TXGBE_SFP1_MOD_PRST_LS;
+
+ if (value != 0 && hw->phy.sfp_type != txgbe_sfp_type_not_present) {
+ PMD_DRV_LOG(INFO, "SFP module removed, stop AN73 watchdog.");
+ hw->phy.sfp_type = txgbe_sfp_type_not_present;
+ }
+
if (!(txgbe_xpcs_an_enabled(hw)))
return;
@@ -3110,10 +3124,22 @@ txgbe_dev_detect_sfp(void *param)
PMD_DRV_LOG(ERR, "Unsupported SFP+ module type was detected.");
} else if (err == TXGBE_ERR_SFP_NOT_PRESENT) {
PMD_DRV_LOG(INFO, "SFP not present.");
+ /* Module removed: drop the cached type and stop the watchdog.
*/
+ hw->phy.sfp_type = txgbe_sfp_type_not_present;
+ rte_eal_alarm_cancel(txgbe_dev_e56_check_bp_event, dev);
} else if (err == 0) {
hw->mac.setup_sfp(hw);
PMD_DRV_LOG(INFO, "detected SFP+: %d", hw->phy.sfp_type);
txgbe_dev_setup_link_alarm_handler(dev);
+ /* Re-arm the AN73 watchdog for the newly inserted module, so
+ * that only one instance of it is running at a time.
+ */
+ if (hw->mac.type == txgbe_mac_aml ||
+ hw->mac.type == txgbe_mac_aml40) {
+ rte_eal_alarm_cancel(txgbe_dev_e56_check_bp_event, dev);
+ rte_eal_alarm_set(hw->bp_event_interval,
+ txgbe_dev_e56_check_bp_event, dev);
+ }
txgbe_dev_link_update(dev, 0);
}
}
--
2.55.0.windows.2