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 bdee13929c..98840f69d3 100644 --- a/doc/guides/rel_notes/release_22_03.rst +++ b/doc/guides/rel_notes/release_22_03.rst @@ -111,6 +111,10 @@ New Features - YT8521S PHY connects to SFP * Added LED OEM support. +* **Updated Wangxun txgbe driver.** + + * Added LED OEM support. + * **Updated Marvell cnxk crypto PMD.** * Added SHA256-HMAC support in lookaside protocol (IPsec) for CN10K. 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 6024397072..b756ea5e6c 100644 --- a/drivers/net/txgbe/txgbe_ethdev.c +++ b/drivers/net/txgbe/txgbe_ethdev.c @@ -3162,7 +3162,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 @@ -3171,7 +3171,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