ixgbe: Check DDM existence in transceiver before access [Linux 4.4.187]

This Linux kernel change "ixgbe: Check DDM existence in transceiver before access" is included in the Linux 4.4.187 release. This change is authored by Mauro S. M. Rodrigues <maurosr [at] linux.vnet.ibm.com> on Thu May 23 16:11:12 2019 -0300. The commit for this change in Linux stable tree is 1ba62e5 (patch) which is from upstream commit 655c914. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 655c914.

ixgbe: Check DDM existence in transceiver before access

[ Upstream commit 655c91414579d7bb115a4f7898ee726fc18e0984 ]

Some transceivers may 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.

Currently, due to not checking this bit ixgbe fails trying 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.

This issue was noticed using a Mellanox Passive DAC PN 01FT738. The eeprom
data was confirmed by Mellanox as correct and present in other Passive
DACs in from other manufacturers.

Signed-off-by: "Mauro S. M. Rodrigues" <maurosr@linux.vnet.ibm.com>
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>

There are 4 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 3 ++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h     | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index d681273..9d38634 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -3133,7 +3133,8 @@ static int ixgbe_get_module_info(struct net_device *dev,
        page_swap = true;

-   if (sff8472_rev == IXGBE_SFF_SFF_8472_UNSUP || page_swap) {
+   if (sff8472_rev == IXGBE_SFF_SFF_8472_UNSUP || page_swap ||
+       !(addr_mode & IXGBE_SFF_DDM_IMPLEMENTED)) {
        /* We have a SFP, but it does not support SFF-8472 */
        modinfo->type = ETH_MODULE_SFF_8079;
        modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
index 5abd66c..7b7dc6d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
@@ -70,6 +70,7 @@
 #define IXGBE_SFF_SOFT_RS_SELECT_10G       0x8
 #define IXGBE_SFF_SOFT_RS_SELECT_1G        0x0
+#define IXGBE_SFF_DDM_IMPLEMENTED      0x40

Leave a Reply

Your email address will not be published. Required fields are marked *