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: [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 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

Reply via email to