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/txgbe_ethdev.c | 67 ++++++++++++++++++++++++++++----
 1 file changed, 60 insertions(+), 7 deletions(-)

diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 4e9da14697..9c9606cc92 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -5452,23 +5452,76 @@ txgbe_get_module_eeprom(struct rte_eth_dev *dev,
        uint8_t databyte = 0xFF;
        uint8_t *data = info->data;
        uint32_t i = 0;
+       bool is_sfp = false;
+       u32 value;
+       u8 identifier = 0;
+       u16 offset;
+       u8 page = 0;
+
+       if (hw->mac.type == txgbe_mac_aml40) {
+               value = rd32(hw, TXGBE_GPIOEXT);
+               if (value & TXGBE_SFP1_MOD_PRST_LS)
+                       return -EIO;
+       }
+
+       if (hw->mac.type == txgbe_mac_aml) {
+               value = rd32(hw, TXGBE_GPIOEXT);
+               if (value & TXGBE_SFP1_MOD_ABS_LS)
+                       return -EIO;
+       }
 
        if (info->length == 0)
                return -EINVAL;
 
-       for (i = info->offset; i < info->offset + info->length; i++) {
-               if (i < RTE_ETH_MODULE_SFF_8079_LEN)
-                       status = hw->phy.read_i2c_eeprom(hw, i, &databyte);
-               else
-                       status = hw->phy.read_i2c_sff8472(hw, i, &databyte);
+       status = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
+       if (status)
+               return -EBUSY;
 
-               if (status != 0)
-                       return -EIO;
+       status = hw->phy.read_i2c_eeprom(hw,
+                                            TXGBE_SFF_IDENTIFIER,
+                                            &identifier);
+       if (status != 0)
+               goto ERROR_IO;
 
+       if (identifier == TXGBE_SFF_IDENTIFIER_SFP)
+               is_sfp = true;
+
+       memset(data, 0, info->length);
+
+       for (i = info->offset; i < info->offset + info->length; i++) {
+               if (is_sfp) {
+                       if (i < RTE_ETH_MODULE_SFF_8079_LEN)
+                               status = hw->phy.read_i2c_eeprom(hw, i,
+                                              &databyte);
+                       else
+                               status = hw->phy.read_i2c_sff8472(hw, i,
+                                              &databyte);
+
+                       if (status != 0)
+                               goto ERROR_IO;
+               } else {
+                       offset = i;
+                       while (offset >= RTE_ETH_MODULE_SFF_8436_LEN) {
+                               offset -= RTE_ETH_MODULE_SFF_8436_LEN / 2;
+                               page++;
+                       }
+                       if (page == 0 || !(data[0x2] & 0x4)) {
+                               status = hw->phy.read_i2c_sff8636(hw, page, 
offset,
+                                              &databyte);
+                               if (status != 0)
+                                       goto ERROR_IO;
+                       }
+               }
                data[i - info->offset] = databyte;
        }
 
+       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;
 }
 
 bool
-- 
2.21.0.windows.1

Reply via email to