[v2,09/12] net/txgbe: add LED OEM support

Message ID 20220209104213.602728-10-jiawenwu@trustnetic.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series Wangxun fixes and supports |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Jiawen Wu Feb. 9, 2022, 10:42 a.m. UTC
  Support to configure LED in firmware. Driver commands firmware to turn
the LED on and off. And OEM customize their LED solutions in firmware.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
 doc/guides/nics/features/txgbe.ini     |  1 +
 doc/guides/rel_notes/release_22_03.rst |  4 ++
 drivers/net/txgbe/base/txgbe_hw.c      | 21 ++++----
 drivers/net/txgbe/base/txgbe_mng.c     | 69 ++++++++++++++++++++++++++
 drivers/net/txgbe/base/txgbe_mng.h     |  7 +++
 drivers/net/txgbe/base/txgbe_regs.h    | 12 +++--
 drivers/net/txgbe/txgbe_ethdev.c       |  4 +-
 7 files changed, 101 insertions(+), 17 deletions(-)
  

Patch

diff --git a/doc/guides/nics/features/txgbe.ini b/doc/guides/nics/features/txgbe.ini
index 6d0cc8afdd..22c74ba9e3 100644
--- a/doc/guides/nics/features/txgbe.ini
+++ b/doc/guides/nics/features/txgbe.ini
@@ -45,6 +45,7 @@  FW version           = Y
 EEPROM dump          = Y
 Module EEPROM dump   = Y
 Registers dump       = Y
+LED                  = Y
 Multiprocess aware   = Y
 Linux                = Y
 ARMv8                = Y
diff --git a/doc/guides/rel_notes/release_22_03.rst b/doc/guides/rel_notes/release_22_03.rst
index 46bc286934..b6aaed1dcf 100644
--- a/doc/guides/rel_notes/release_22_03.rst
+++ b/doc/guides/rel_notes/release_22_03.rst
@@ -77,6 +77,10 @@  New Features
     - YT8521S PHY connects to SFP
   * Added LED OEM support.
 
+* **Updated Wangxun txgbe driver.**
+
+  * Added LED OEM support.
+
 * **Added an API to retrieve event port id of ethdev Rx adapter.**
 
   The new API ``rte_event_eth_rx_adapter_event_port_get()`` was added.
diff --git a/drivers/net/txgbe/base/txgbe_hw.c b/drivers/net/txgbe/base/txgbe_hw.c
index 00a8db78bf..db8ffe61a4 100644
--- a/drivers/net/txgbe/base/txgbe_hw.c
+++ b/drivers/net/txgbe/base/txgbe_hw.c
@@ -529,12 +529,9 @@  s32 txgbe_led_on(struct txgbe_hw *hw, u32 index)
 
 	DEBUGFUNC("txgbe_led_on");
 
-	if (index > 4)
-		return TXGBE_ERR_PARAM;
-
 	/* To turn on the LED, set mode to ON. */
-	led_reg |= TXGBE_LEDCTL_SEL(index);
-	led_reg |= TXGBE_LEDCTL_ORD(index);
+	led_reg |= index << TXGBE_LEDCTL_ORD_SHIFT;
+	led_reg |= index;
 	wr32(hw, TXGBE_LEDCTL, led_reg);
 	txgbe_flush(hw);
 
@@ -552,12 +549,9 @@  s32 txgbe_led_off(struct txgbe_hw *hw, u32 index)
 
 	DEBUGFUNC("txgbe_led_off");
 
-	if (index > 4)
-		return TXGBE_ERR_PARAM;
-
 	/* To turn off the LED, set mode to OFF. */
-	led_reg &= ~(TXGBE_LEDCTL_SEL(index));
-	led_reg &= ~(TXGBE_LEDCTL_ORD(index));
+	led_reg &= ~(index << TXGBE_LEDCTL_ORD_SHIFT);
+	led_reg |= index;
 	wr32(hw, TXGBE_LEDCTL, led_reg);
 	txgbe_flush(hw);
 
@@ -3054,6 +3048,10 @@  void txgbe_disable_tx_laser_multispeed_fiber(struct txgbe_hw *hw)
 	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);
+
 	/* Disable Tx laser; allow 100us to go dark per spec */
 	esdp_reg |= (TXGBE_GPIOBIT_0 | TXGBE_GPIOBIT_1);
 	wr32(hw, TXGBE_GPIODATA, esdp_reg);
@@ -3073,6 +3071,9 @@  void txgbe_enable_tx_laser_multispeed_fiber(struct txgbe_hw *hw)
 {
 	u32 esdp_reg = rd32(hw, TXGBE_GPIODATA);
 
+	if (txgbe_open_notify(hw))
+		wr32(hw, TXGBE_LEDCTL, 0);
+
 	/* Enable Tx laser; allow 100ms to light up */
 	esdp_reg &= ~(TXGBE_GPIOBIT_0 | TXGBE_GPIOBIT_1);
 	wr32(hw, TXGBE_GPIODATA, esdp_reg);
diff --git a/drivers/net/txgbe/base/txgbe_mng.c b/drivers/net/txgbe/base/txgbe_mng.c
index dbe512122c..d0aa665d4a 100644
--- a/drivers/net/txgbe/base/txgbe_mng.c
+++ b/drivers/net/txgbe/base/txgbe_mng.c
@@ -82,6 +82,11 @@  txgbe_hic_unlocked(struct txgbe_hw *hw, u32 *buffer, u32 length, u32 timeout)
 		return TXGBE_ERR_HOST_INTERFACE_COMMAND;
 	}
 
+	if ((rd32(hw, TXGBE_MNGMBX) & 0xff0000) >> 16 == 0x80) {
+		DEBUGOUT("It's unknown command.\n");
+		return TXGBE_ERR_MNG_ACCESS_FAILED;
+	}
+
 	return 0;
 }
 
@@ -262,6 +267,70 @@  s32 txgbe_hic_sr_write(struct txgbe_hw *hw, u32 addr, u8 *buf, int len)
 	return err;
 }
 
+s32 txgbe_close_notify(struct txgbe_hw *hw)
+{
+	u32 tmp;
+	s32 status;
+	struct txgbe_hic_write_shadow_ram buffer;
+
+	DEBUGFUNC("txgbe_close_notify");
+
+	buffer.hdr.req.cmd = FW_DW_CLOSE_NOTIFY;
+	buffer.hdr.req.buf_lenh = 0;
+	buffer.hdr.req.buf_lenl = 0;
+	buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
+
+	/* one word */
+	buffer.length = 0;
+	buffer.address = 0;
+
+	status = txgbe_host_interface_command(hw, (u32 *)&buffer,
+					      sizeof(buffer),
+					      TXGBE_HI_COMMAND_TIMEOUT, false);
+	if (status)
+		return status;
+
+	tmp = rd32(hw, TXGBE_MNGSWSYNC);
+	if (tmp == TXGBE_CHECKSUM_CAP_ST_PASS)
+		status = 0;
+	else
+		status = TXGBE_ERR_EEPROM_CHECKSUM;
+
+	return status;
+}
+
+s32 txgbe_open_notify(struct txgbe_hw *hw)
+{
+	u32 tmp;
+	s32 status;
+	struct txgbe_hic_write_shadow_ram buffer;
+
+	DEBUGFUNC("txgbe_open_notify");
+
+	buffer.hdr.req.cmd = FW_DW_OPEN_NOTIFY;
+	buffer.hdr.req.buf_lenh = 0;
+	buffer.hdr.req.buf_lenl = 0;
+	buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
+
+	/* one word */
+	buffer.length = 0;
+	buffer.address = 0;
+
+	status = txgbe_host_interface_command(hw, (u32 *)&buffer,
+					      sizeof(buffer),
+					      TXGBE_HI_COMMAND_TIMEOUT, false);
+	if (status)
+		return status;
+
+	tmp = rd32(hw, TXGBE_MNGSWSYNC);
+	if (tmp == TXGBE_CHECKSUM_CAP_ST_PASS)
+		status = 0;
+	else
+		status = TXGBE_ERR_EEPROM_CHECKSUM;
+
+	return status;
+}
+
 /**
  *  txgbe_hic_set_drv_ver - Sends driver version to firmware
  *  @hw: pointer to the HW structure
diff --git a/drivers/net/txgbe/base/txgbe_mng.h b/drivers/net/txgbe/base/txgbe_mng.h
index 1004f41c72..24d938fecf 100644
--- a/drivers/net/txgbe/base/txgbe_mng.h
+++ b/drivers/net/txgbe/base/txgbe_mng.h
@@ -51,6 +51,11 @@ 
 #define FW_PHY_TOKEN_DELAY		5	/* milliseconds */
 #define FW_PHY_TOKEN_WAIT		5	/* seconds */
 #define FW_PHY_TOKEN_RETRIES ((FW_PHY_TOKEN_WAIT * 1000) / FW_PHY_TOKEN_DELAY)
+#define FW_DW_OPEN_NOTIFY               0xE9
+#define FW_DW_CLOSE_NOTIFY              0xEA
+
+#define TXGBE_CHECKSUM_CAP_ST_PASS      0x80658383
+#define TXGBE_CHECKSUM_CAP_ST_FAIL      0x70657376
 
 /* Host Interface Command Structures */
 struct txgbe_hic_hdr {
@@ -168,6 +173,8 @@  struct txgbe_hic_upg_verify {
 
 s32 txgbe_hic_sr_read(struct txgbe_hw *hw, u32 addr, u8 *buf, int len);
 s32 txgbe_hic_sr_write(struct txgbe_hw *hw, u32 addr, u8 *buf, int len);
+s32 txgbe_close_notify(struct txgbe_hw *hw);
+s32 txgbe_open_notify(struct txgbe_hw *hw);
 
 s32 txgbe_hic_set_drv_ver(struct txgbe_hw *hw, u8 maj, u8 min, u8 build,
 			u8 ver, u16 len, const char *str);
diff --git a/drivers/net/txgbe/base/txgbe_regs.h b/drivers/net/txgbe/base/txgbe_regs.h
index 144047ba62..3139796911 100644
--- a/drivers/net/txgbe/base/txgbe_regs.h
+++ b/drivers/net/txgbe/base/txgbe_regs.h
@@ -302,11 +302,13 @@ 
 #define TXGBE_TEREDOPORT                0x01441C
 #define TXGBE_LEDCTL                    0x014424
 #define   TXGBE_LEDCTL_SEL_MASK         MS(0, 0xFFFF)
-#define   TXGBE_LEDCTL_SEL(s)           MS((s), 0x1)
-#define   TXGBE_LEDCTL_ORD_MASK          MS(16, 0xFFFF)
-#define   TXGBE_LEDCTL_ORD(s)            MS(((s)+16), 0x1)
-	/* s=UP(0),10G(1),1G(2),100M(3),BSY(4) */
-#define   TXGBE_LEDCTL_ACTIVE      (TXGBE_LEDCTL_SEL(4) | TXGBE_LEDCTL_ORD(4))
+#define   TXGBE_LEDCTL_ORD_MASK         MS(16, 0xFFFF)
+#define   TXGBE_LEDCTL_ORD_SHIFT        16
+#define   TXGBE_LEDCTL_UP		MS(0, 0x1)
+#define   TXGBE_LEDCTL_10G		MS(1, 0x1)
+#define   TXGBE_LEDCTL_1G		MS(2, 0x1)
+#define   TXGBE_LEDCTL_100M		MS(3, 0x1)
+#define   TXGBE_LEDCTL_ACTIVE		MS(4, 0x1)
 #define TXGBE_TAGTPID(i)                (0x014430 + (i) * 4) /* 0-3 */
 #define   TXGBE_TAGTPID_LSB_MASK        MS(0, 0xFFFF)
 #define   TXGBE_TAGTPID_LSB(v)          LS(v, 0, 0xFFFF)
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index ac4d4e08f4..4799a60116 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -3166,7 +3166,7 @@  txgbe_dev_led_on(struct rte_eth_dev *dev)
 	struct txgbe_hw *hw;
 
 	hw = TXGBE_DEV_HW(dev);
-	return txgbe_led_on(hw, 4) == 0 ? 0 : -ENOTSUP;
+	return txgbe_led_on(hw, TXGBE_LEDCTL_ACTIVE) == 0 ? 0 : -ENOTSUP;
 }
 
 static int
@@ -3175,7 +3175,7 @@  txgbe_dev_led_off(struct rte_eth_dev *dev)
 	struct txgbe_hw *hw;
 
 	hw = TXGBE_DEV_HW(dev);
-	return txgbe_led_off(hw, 4) == 0 ? 0 : -ENOTSUP;
+	return txgbe_led_off(hw, TXGBE_LEDCTL_ACTIVE) == 0 ? 0 : -ENOTSUP;
 }
 
 static int