In the new firmware, MNG veto bit is set by default for new features.
It leads to several issues, so driver makes the following changes:
1. Change the way by sending reset command to firmware to LAN reset.
So that MNG domain will not be reset.
2. Change the hardware flush register since the original register cannot
be read temporarily after LAN reset.
3. Remove checking of MNG veto bit when handling Tx laser.
4. Workaround for GPIO interrupt lost.
Fixes: f58ae2fcfea6 ("net/txgbe: add HW init and reset operation")
Fixes: e4c515a7bc7e ("net/txgbe: add multi-speed link setup")
Fixes: d3bb4a04eac1 ("net/txgbe: add SFP hotplug identification")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_hw.c | 23 +++--------------------
drivers/net/txgbe/base/txgbe_regs.h | 14 +++++++++++++-
drivers/net/txgbe/txgbe_ethdev.c | 27 +++++++++++++++++++++++++++
3 files changed, 43 insertions(+), 21 deletions(-)
@@ -2988,10 +2988,6 @@ void txgbe_disable_tx_laser_multispeed_fiber(struct txgbe_hw *hw)
{
u32 esdp_reg = rd32(hw, TXGBE_GPIODATA);
- /* Blocked by MNG FW so bail */
- if (txgbe_check_reset_blocked(hw))
- return;
-
if (txgbe_close_notify(hw))
txgbe_led_off(hw, TXGBE_LEDCTL_UP | TXGBE_LEDCTL_10G |
TXGBE_LEDCTL_1G | TXGBE_LEDCTL_ACTIVE);
@@ -3039,10 +3035,6 @@ void txgbe_enable_tx_laser_multispeed_fiber(struct txgbe_hw *hw)
**/
void txgbe_flap_tx_laser_multispeed_fiber(struct txgbe_hw *hw)
{
- /* Blocked by MNG FW so bail */
- if (txgbe_check_reset_blocked(hw))
- return;
-
if (hw->mac.autotry_restart) {
txgbe_disable_tx_laser_multispeed_fiber(hw);
txgbe_enable_tx_laser_multispeed_fiber(hw);
@@ -3433,18 +3425,9 @@ s32 txgbe_reset_hw(struct txgbe_hw *hw)
autoc = hw->mac.autoc_read(hw);
mac_reset_top:
- /*
- * Issue global reset to the MAC. Needs to be SW reset if link is up.
- * If link reset is used when link is up, it might reset the PHY when
- * mng is using it. If link is down or the flag to force full link
- * reset is set, then perform link reset.
- */
- if (txgbe_mng_present(hw)) {
- txgbe_hic_reset(hw);
- } else {
- wr32(hw, TXGBE_RST, TXGBE_RST_LAN(hw->bus.lan_id));
- txgbe_flush(hw);
- }
+ /* Do LAN reset, the MNG domain will not be reset. */
+ wr32(hw, TXGBE_RST, TXGBE_RST_LAN(hw->bus.lan_id));
+ txgbe_flush(hw);
usec_delay(10);
txgbe_reset_misc(hw);
@@ -1885,7 +1885,19 @@ po32m(struct txgbe_hw *hw, u32 reg, u32 mask, u32 expect, u32 *actual,
}
/* flush all write operations */
-#define txgbe_flush(hw) rd32(hw, 0x00100C)
+static inline void txgbe_flush(struct txgbe_hw *hw)
+{
+ switch (hw->mac.type) {
+ case txgbe_mac_raptor:
+ rd32(hw, TXGBE_PWR);
+ break;
+ case txgbe_mac_raptor_vf:
+ rd32(hw, TXGBE_VFSTATUS);
+ break;
+ default:
+ break;
+ }
+}
#define rd32a(hw, reg, idx) ( \
rd32((hw), (reg) + ((idx) << 2)))
@@ -1531,6 +1531,25 @@ txgbe_dev_configure(struct rte_eth_dev *dev)
return 0;
}
+static void txgbe_reinit_gpio_intr(struct txgbe_hw *hw)
+{
+ u32 reg;
+
+ wr32(hw, TXGBE_GPIOINTMASK, 0xFF);
+ reg = rd32(hw, TXGBE_GPIORAWINTSTAT);
+
+ if (reg & TXGBE_GPIOBIT_2)
+ wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_2);
+
+ if (reg & TXGBE_GPIOBIT_3)
+ wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_3);
+
+ if (reg & TXGBE_GPIOBIT_6)
+ wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_6);
+
+ wr32(hw, TXGBE_GPIOINTMASK, 0);
+}
+
static void
txgbe_dev_phy_intr_setup(struct rte_eth_dev *dev)
{
@@ -1680,6 +1699,10 @@ txgbe_dev_start(struct rte_eth_dev *dev)
hw->mac.get_link_status = true;
hw->dev_start = true;
+ /* workaround for GPIO intr lost when mng_veto bit is set */
+ if (txgbe_check_reset_blocked(hw))
+ txgbe_reinit_gpio_intr(hw);
+
/* configure PF module if SRIOV enabled */
txgbe_pf_host_configure(dev);
@@ -1897,6 +1920,10 @@ txgbe_dev_stop(struct rte_eth_dev *dev)
/* disable interrupts */
txgbe_disable_intr(hw);
+ /* workaround for GPIO intr lost when mng_veto bit is set */
+ if (txgbe_check_reset_blocked(hw))
+ txgbe_reinit_gpio_intr(hw);
+
/* reset the NIC */
txgbe_pf_reset_hw(hw);
hw->adapter_stopped = 0;