[PATCH v2 17/20] net/txgbe: fix get module info operation
Zaiyu Wang
zaiyuwang at trustnetic.com
Wed Apr 29 12:25:11 CEST 2026
The original I2C access flow in the module information retrieval
process was flawed. Correct the implementation to properly fetch
module info.
Fixes: abf042d32b39 ("net/txgbe: add Amber-Lite 25G/40G NICs")
Cc: stable at dpdk.org
Signed-off-by: Zaiyu Wang <zaiyuwang at trustnetic.com>
---
drivers/net/txgbe/base/txgbe_phy.h | 6 +-
drivers/net/txgbe/txgbe_ethdev.c | 116 ++++++++++++++++++++++-------
2 files changed, 95 insertions(+), 27 deletions(-)
diff --git a/drivers/net/txgbe/base/txgbe_phy.h b/drivers/net/txgbe/base/txgbe_phy.h
index 4da4be0d5f..581f667bdc 100644
--- a/drivers/net/txgbe/base/txgbe_phy.h
+++ b/drivers/net/txgbe/base/txgbe_phy.h
@@ -257,11 +257,15 @@
#define TXGBE_SFF_CABLE_DA_PASSIVE 0x4
#define TXGBE_SFF_CABLE_DA_ACTIVE 0x8
#define TXGBE_SFF_CABLE_SPEC_COMP 0x3C
+#define TXGBE_SFF_DDM_IMPLEMENTED 0x40
#define TXGBE_SFF_SFF_8472_SWAP 0x5C
#define TXGBE_SFF_SFF_8472_COMP 0x5E
#define TXGBE_SFF_SFF_8472_OSCB 0x6E
#define TXGBE_SFF_SFF_8472_ESCB 0x76
-#define TXGBE_SFF_QSFP_PAGE_SELECT 0x7F
+#define TXGBE_SFF_SFF_REVISION_ADDR 0x01
+#define TXGBE_SFF_QSFP_PAGE_SELECT 0x7F
+
+#define TXGBE_MODULE_QSFP_MAX_LEN 640
#define TXGBE_SFF_IDENTIFIER_QSFP 0x0C
#define TXGBE_SFF_IDENTIFIER_QSFP_PLUS 0x0D
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 2221153347..4e9da14697 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -5342,41 +5342,105 @@ txgbe_get_module_info(struct rte_eth_dev *dev,
struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
uint32_t status;
uint8_t sff8472_rev, addr_mode;
+ u8 identifier = 0;
+ u8 sff8636_rev = 0;
bool page_swap = false;
+ u32 value;
- /* Check whether we support SFF-8472 or not */
- status = hw->phy.read_i2c_eeprom(hw,
- TXGBE_SFF_SFF_8472_COMP,
- &sff8472_rev);
- if (status != 0)
- return -EIO;
-
- /* addressing mode is not supported */
- status = hw->phy.read_i2c_eeprom(hw,
- TXGBE_SFF_SFF_8472_SWAP,
- &addr_mode);
- if (status != 0)
- return -EIO;
+ if (hw->mac.type == txgbe_mac_aml40) {
+ value = rd32(hw, TXGBE_GPIOEXT);
+ if (value & TXGBE_SFP1_MOD_PRST_LS)
+ return -EIO;
+ }
- if (addr_mode & TXGBE_SFF_ADDRESSING_MODE) {
- PMD_DRV_LOG(ERR,
- "Address change required to access page 0xA2, "
- "but not supported. Please report the module "
- "type to the driver maintainers.");
- page_swap = true;
+ if (hw->mac.type == txgbe_mac_aml) {
+ value = rd32(hw, TXGBE_GPIOEXT);
+ if (value & TXGBE_SFP1_MOD_ABS_LS)
+ return -EIO;
}
- if (sff8472_rev == TXGBE_SFF_SFF_8472_UNSUP || page_swap) {
- /* We have a SFP, but it does not support SFF-8472 */
- modinfo->type = RTE_ETH_MODULE_SFF_8079;
- modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8079_LEN;
+ status = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
+ if (status)
+ return -EBUSY;
+
+ if (hw->mac.type == txgbe_mac_aml40) {
+ status = hw->phy.read_i2c_sff8636(hw, 0,
+ TXGBE_SFF_IDENTIFIER,
+ &identifier);
} else {
- /* We have a SFP which supports a revision of SFF-8472. */
- modinfo->type = RTE_ETH_MODULE_SFF_8472;
- modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
+ status = hw->phy.read_i2c_eeprom(hw,
+ TXGBE_SFF_IDENTIFIER,
+ &identifier);
}
+ if (status != 0)
+ goto ERROR_IO;
+
+ switch (identifier) {
+ case TXGBE_SFF_IDENTIFIER_SFP:
+ /* Check whether we support SFF-8472 or not */
+ status = hw->phy.read_i2c_eeprom(hw,
+ TXGBE_SFF_SFF_8472_COMP,
+ &sff8472_rev);
+ if (status != 0)
+ goto ERROR_IO;
+
+ /* addressing mode is not supported */
+ status = hw->phy.read_i2c_eeprom(hw,
+ TXGBE_SFF_SFF_8472_SWAP,
+ &addr_mode);
+ if (status != 0)
+ goto ERROR_IO;
+
+ if (addr_mode & TXGBE_SFF_ADDRESSING_MODE) {
+ PMD_DRV_LOG(ERR,
+ "Address change required to access page 0xA2, "
+ "but not supported. Please report the module "
+ "type to the driver maintainers.");
+ page_swap = true;
+ }
+
+ if (sff8472_rev == TXGBE_SFF_SFF_8472_UNSUP || page_swap ||
+ !(addr_mode & TXGBE_SFF_DDM_IMPLEMENTED)) {
+ /* We have a SFP, but it does not support SFF-8472 */
+ modinfo->type = RTE_ETH_MODULE_SFF_8079;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8079_LEN;
+ } else {
+ /* We have a SFP which supports a revision of SFF-8472. */
+ modinfo->type = RTE_ETH_MODULE_SFF_8472;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
+ }
+ break;
+ case TXGBE_SFF_IDENTIFIER_QSFP:
+ case TXGBE_SFF_IDENTIFIER_QSFP_PLUS:
+ status = hw->phy.read_i2c_sff8636(hw, 0,
+ TXGBE_SFF_SFF_REVISION_ADDR,
+ &sff8636_rev);
+ if (status != 0)
+ goto ERROR_IO;
+ /* Check revision compliance */
+ if (sff8636_rev > 0x02) {
+ /* Module is SFF-8636 compliant */
+ modinfo->type = RTE_ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = TXGBE_MODULE_QSFP_MAX_LEN;
+ } else {
+ modinfo->type = RTE_ETH_MODULE_SFF_8436;
+ modinfo->eeprom_len = TXGBE_MODULE_QSFP_MAX_LEN;
+ }
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "SFF Module Type not recognized.");
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
+ return -EINVAL;
+ }
+
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
return 0;
+
+ERROR_IO:
+ PMD_DRV_LOG(ERR, "I2C IO ERROR.");
+ hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
+ return -EIO;
}
static int
--
2.21.0.windows.1
More information about the stable
mailing list