[3/9] net/txgbe: fix issues caused by MNG veto bit setting

Message ID 20230614023429.1002071-4-jiawenwu@trustnetic.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series Wangxun bug fixes |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Jiawen Wu June 14, 2023, 2:34 a.m. UTC
  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(-)
  

Patch

diff --git a/drivers/net/txgbe/base/txgbe_hw.c b/drivers/net/txgbe/base/txgbe_hw.c
index e7c9754d26..2952c408fd 100644
--- a/drivers/net/txgbe/base/txgbe_hw.c
+++ b/drivers/net/txgbe/base/txgbe_hw.c
@@ -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);
diff --git a/drivers/net/txgbe/base/txgbe_regs.h b/drivers/net/txgbe/base/txgbe_regs.h
index bc2854b01a..79290a7afe 100644
--- a/drivers/net/txgbe/base/txgbe_regs.h
+++ b/drivers/net/txgbe/base/txgbe_regs.h
@@ -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)))
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 5eff1a766e..36c74d353d 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -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;