The original I2C access flow in the module information retrieval process was flawed. Correct the implementation to properly fetch module info.
Cc: [email protected] Signed-off-by: Zaiyu Wang <[email protected]> --- 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 796a0f6748..fe6c0dd170 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 c28afbe7aa..41ec432983 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

