i40e: Check if transceiver implements DDM before access
authorMauro S. M. Rodrigues <maurosr@linux.vnet.ibm.com>
Thu, 18 Jul 2019 17:52:02 +0000 (14:52 -0300)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Thu, 22 Aug 2019 20:24:13 +0000 (13:24 -0700)
Similar to the ixgbe issue fixed in:
655c91414579 ("ixgbe: Check DDM existence in transceiver before access)

i40e has the same issue when reading eeprom from SFP's module that comply
with SFF-8472 but not implement the Digital Diagnostic Monitoring (DDM)
interface described in it. The existence of such area is specified by bit
6 of byte 92, set to 1 if implemented.

Without this patch, due to not checking this bit i40e fails to read SFP
module's eeprom with the follow message:

ethtool -m enP51p1s0f0
Cannot get Module EEPROM data: Input/output error

Because it fails to read the additional 256 bytes in which it was assumed
to exist the DDM data.

Signed-off-by: "Mauro S. M. Rodrigues" <maurosr@linux.vnet.ibm.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_type.h

index 01e4615b1b4b39f1ad6309d6f8f533a8c3050df7..41e1240acaea56f8822d061b14fbcf46081c0309 100644 (file)
@@ -5137,6 +5137,12 @@ static int i40e_get_module_info(struct net_device *netdev,
                        /* Module is not SFF-8472 compliant */
                        modinfo->type = ETH_MODULE_SFF_8079;
                        modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
+               } else if (!(sff8472_swap & I40E_MODULE_SFF_DDM_IMPLEMENTED)) {
+                       /* Module is SFF-8472 compliant but doesn't implement
+                        * Digital Diagnostic Monitoring (DDM).
+                        */
+                       modinfo->type = ETH_MODULE_SFF_8079;
+                       modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
                } else {
                        modinfo->type = ETH_MODULE_SFF_8472;
                        modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
index 8f43aa47c2631722e3cc4c13f02472976427c4a6..2a6219d66771bfd98b5f7e51d37c4e893d6a9476 100644 (file)
@@ -443,6 +443,7 @@ struct i40e_nvm_access {
 #define I40E_MODULE_SFF_8472_COMP      0x5E
 #define I40E_MODULE_SFF_8472_SWAP      0x5C
 #define I40E_MODULE_SFF_ADDR_MODE      0x04
+#define I40E_MODULE_SFF_DDM_IMPLEMENTED 0x40
 #define I40E_MODULE_TYPE_QSFP_PLUS     0x0D
 #define I40E_MODULE_TYPE_QSFP28                0x11
 #define I40E_MODULE_QSFP_MAX_LEN       640