Support to identify the new SFP/SFP+ module when the device is started. Signed-off-by: Jiawen Wu <jiawe...@trustnetic.com> --- doc/guides/rel_notes/release_23_03.rst | 1 + drivers/net/txgbe/base/txgbe_regs.h | 1 + drivers/net/txgbe/txgbe_ethdev.c | 65 ++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 4 deletions(-)
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst index e64cb2d974..3c43b75ac0 100644 --- a/doc/guides/rel_notes/release_23_03.rst +++ b/doc/guides/rel_notes/release_23_03.rst @@ -62,6 +62,7 @@ New Features * **Updated Wangxun txgbe driver.** * Added chip overheat detection support. + * Added SFP hot-plug identification support. Removed Items diff --git a/drivers/net/txgbe/base/txgbe_regs.h b/drivers/net/txgbe/base/txgbe_regs.h index 911bb6e04e..bc2854b01a 100644 --- a/drivers/net/txgbe/base/txgbe_regs.h +++ b/drivers/net/txgbe/base/txgbe_regs.h @@ -1579,6 +1579,7 @@ enum txgbe_5tuple_protocol { #define TXGBE_GPIOINTMASK 0x014834 #define TXGBE_GPIOINTTYPE 0x014838 #define TXGBE_GPIOINTSTAT 0x014840 +#define TXGBE_GPIORAWINTSTAT 0x014844 #define TXGBE_GPIOEOI 0x01484C diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c index 6e939b8ce3..a502618bc5 100644 --- a/drivers/net/txgbe/txgbe_ethdev.c +++ b/drivers/net/txgbe/txgbe_ethdev.c @@ -114,6 +114,7 @@ static int txgbe_dev_interrupt_get_status(struct rte_eth_dev *dev, static int txgbe_dev_interrupt_action(struct rte_eth_dev *dev, struct rte_intr_handle *handle); static void txgbe_dev_interrupt_handler(void *param); +static void txgbe_dev_detect_sfp(void *param); static void txgbe_dev_interrupt_delayed_handler(void *param); static void txgbe_configure_msix(struct rte_eth_dev *dev); @@ -1535,11 +1536,20 @@ txgbe_dev_phy_intr_setup(struct rte_eth_dev *dev) { struct txgbe_hw *hw = TXGBE_DEV_HW(dev); struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev); + u8 device_type = hw->subsystem_device_id & 0xF0; uint32_t gpie; - gpie = rd32(hw, TXGBE_GPIOINTEN); - gpie |= TXGBE_GPIOBIT_6; - wr32(hw, TXGBE_GPIOINTEN, gpie); + if (device_type != TXGBE_DEV_ID_MAC_XAUI && + device_type != TXGBE_DEV_ID_MAC_SGMII) { + gpie = rd32(hw, TXGBE_GPIOINTEN); + gpie |= TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3 | TXGBE_GPIOBIT_6; + wr32(hw, TXGBE_GPIOINTEN, gpie); + + gpie = rd32(hw, TXGBE_GPIOINTTYPE); + gpie |= TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3 | TXGBE_GPIOBIT_6; + wr32(hw, TXGBE_GPIOINTTYPE, gpie); + } + intr->mask_misc |= TXGBE_ICRMISC_GPIO; intr->mask_misc |= TXGBE_ICRMISC_ANDONE; intr->mask_misc |= TXGBE_ICRMISC_HEAT; @@ -1648,6 +1658,7 @@ txgbe_dev_start(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); /* Stop the link setup handler before resetting the HW. */ + rte_eal_alarm_cancel(txgbe_dev_detect_sfp, dev); rte_eal_alarm_cancel(txgbe_dev_setup_link_alarm_handler, dev); /* disable uio/vfio intr/eventfd mapping */ @@ -1880,6 +1891,7 @@ txgbe_dev_stop(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); + rte_eal_alarm_cancel(txgbe_dev_detect_sfp, dev); rte_eal_alarm_cancel(txgbe_dev_setup_link_alarm_handler, dev); /* disable interrupts */ @@ -2673,6 +2685,51 @@ txgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev) return NULL; } +static void +txgbe_dev_detect_sfp(void *param) +{ + struct rte_eth_dev *dev = (struct rte_eth_dev *)param; + struct txgbe_hw *hw = TXGBE_DEV_HW(dev); + s32 err; + + err = hw->phy.identify_sfp(hw); + if (err == TXGBE_ERR_SFP_NOT_SUPPORTED) { + 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."); + } else if (err == 0) { + hw->mac.setup_sfp(hw); + PMD_DRV_LOG(INFO, "detected SFP+: %d\n", hw->phy.sfp_type); + txgbe_dev_setup_link_alarm_handler(dev); + txgbe_dev_link_update(dev, 0); + } +} + +static void +txgbe_dev_sfp_event(struct rte_eth_dev *dev) +{ + struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev); + struct txgbe_hw *hw = TXGBE_DEV_HW(dev); + u32 reg; + + wr32(hw, TXGBE_GPIOINTMASK, 0xFF); + reg = rd32(hw, TXGBE_GPIORAWINTSTAT); + if (reg & TXGBE_GPIOBIT_2) { + wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_2); + rte_eal_alarm_set(1000 * 100, txgbe_dev_detect_sfp, dev); + } + if (reg & TXGBE_GPIOBIT_3) { + wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_3); + intr->flags |= TXGBE_FLAG_NEED_LINK_UPDATE; + } + if (reg & TXGBE_GPIOBIT_6) { + wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_6); + intr->flags |= TXGBE_FLAG_NEED_LINK_UPDATE; + } + + wr32(hw, TXGBE_GPIOINTMASK, 0); +} + static void txgbe_dev_overheat(struct rte_eth_dev *dev) { @@ -3063,7 +3120,7 @@ txgbe_dev_interrupt_action(struct rte_eth_dev *dev, } if (intr->flags & TXGBE_FLAG_PHY_INTERRUPT) { - hw->phy.handle_lasi(hw); + txgbe_dev_sfp_event(dev); intr->flags &= ~TXGBE_FLAG_PHY_INTERRUPT; } -- 2.27.0