lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 20 Jun 2022 22:32:34 +0000
From:   Arthur Gautier <baloo@...erbaloo.net>
To:     Raju Rangoju <rajur@...lsio.com>
Cc:     Arthur Gautier <baloo@...erbaloo.net>, netdev@...r.kernel.org
Subject: [PATCH] cxgb4: DOM support when using a QSFP to SFP adaptor

When a QSFP to SFP adaptor is used, the DOM eeprom is then presented
with the SFF-8472 layout and not translated to SFF-8636 format.

When parsing the eeprom, we can't just read the type of port but we
need to identify the type of transceiver instead.

Signed-off-by: Arthur Gautier <baloo@...erbaloo.net>
Cc: Raju Rangoju <rajur@...lsio.com>
Cc: netdev@...r.kernel.org
---
 .../ethernet/chelsio/cxgb4/cxgb4_ethtool.c    | 69 ++++++++++++++-----
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.h    |  3 +
 2 files changed, 53 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
index 6c790af92170..ff769216dbec 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
@@ -2002,11 +2002,43 @@ static bool cxgb4_fw_mod_type_info_available(unsigned int fw_mod_type)
 		fw_mod_type != FW_PORT_MOD_TYPE_ERROR);
 }
 
+static int cxgb4_read_eeprom_sfp(struct adapter *adapter,
+				 struct port_info *pi,
+				 struct ethtool_modinfo *modinfo)
+{
+	u8 sff8472_comp, sff_diag_type;
+	int ret;
+
+	ret = t4_i2c_rd(adapter, adapter->mbox, pi->tx_chan,
+			I2C_DEV_ADDR_A0, SFF_8472_COMP_ADDR,
+			SFF_8472_COMP_LEN, &sff8472_comp);
+	if (ret)
+		return ret;
+	ret = t4_i2c_rd(adapter, adapter->mbox, pi->tx_chan,
+			I2C_DEV_ADDR_A0, SFP_DIAG_TYPE_ADDR,
+			SFP_DIAG_TYPE_LEN, &sff_diag_type);
+	if (ret)
+		return ret;
+
+	if (!sff8472_comp || (sff_diag_type & SFP_DIAG_ADDRMODE)) {
+		modinfo->type = ETH_MODULE_SFF_8079;
+		modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
+	} else {
+		modinfo->type = ETH_MODULE_SFF_8472;
+		if (sff_diag_type & SFP_DIAG_IMPLEMENTED)
+			modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
+		else
+			modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN / 2;
+	}
+
+	return 0;
+}
+
 static int cxgb4_get_module_info(struct net_device *dev,
 				 struct ethtool_modinfo *modinfo)
 {
 	struct port_info *pi = netdev_priv(dev);
-	u8 sff8472_comp, sff_diag_type, sff_rev;
+	u8 sff_rev, module_type;
 	struct adapter *adapter = pi->adapter;
 	int ret;
 
@@ -2017,27 +2049,10 @@ static int cxgb4_get_module_info(struct net_device *dev,
 	case FW_PORT_TYPE_SFP:
 	case FW_PORT_TYPE_QSA:
 	case FW_PORT_TYPE_SFP28:
-		ret = t4_i2c_rd(adapter, adapter->mbox, pi->tx_chan,
-				I2C_DEV_ADDR_A0, SFF_8472_COMP_ADDR,
-				SFF_8472_COMP_LEN, &sff8472_comp);
-		if (ret)
-			return ret;
-		ret = t4_i2c_rd(adapter, adapter->mbox, pi->tx_chan,
-				I2C_DEV_ADDR_A0, SFP_DIAG_TYPE_ADDR,
-				SFP_DIAG_TYPE_LEN, &sff_diag_type);
+		ret = cxgb4_read_eeprom_sfp(adapter, pi, modinfo);
 		if (ret)
 			return ret;
 
-		if (!sff8472_comp || (sff_diag_type & SFP_DIAG_ADDRMODE)) {
-			modinfo->type = ETH_MODULE_SFF_8079;
-			modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
-		} else {
-			modinfo->type = ETH_MODULE_SFF_8472;
-			if (sff_diag_type & SFP_DIAG_IMPLEMENTED)
-				modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
-			else
-				modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN / 2;
-		}
 		break;
 
 	case FW_PORT_TYPE_QSFP:
@@ -2045,6 +2060,22 @@ static int cxgb4_get_module_info(struct net_device *dev,
 	case FW_PORT_TYPE_CR_QSFP:
 	case FW_PORT_TYPE_CR2_QSFP:
 	case FW_PORT_TYPE_CR4_QSFP:
+		// lookup the transceiver type, we could be using a SFP
+		// plugged into a QSFP to SFP adapter
+		ret = t4_i2c_rd(adapter, adapter->mbox, pi->tx_chan,
+				I2C_DEV_ADDR_A0, SFF_8636_ID,
+				SFF_8636_ID_LEN, &module_type);
+		if (ret)
+			return ret;
+
+		if (module_type == SFF_8024_ID_SFP) {
+			ret = cxgb4_read_eeprom_sfp(adapter, pi, modinfo);
+			if (ret)
+				return ret;
+
+			break;
+		}
+
 		ret = t4_i2c_rd(adapter, adapter->mbox, pi->tx_chan,
 				I2C_DEV_ADDR_A0, SFF_REV_ADDR,
 				SFF_REV_LEN, &sff_rev);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
index 63bc956d2037..a27e20dc1268 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
@@ -297,6 +297,9 @@ enum {
 #define SFP_DIAG_IMPLEMENTED	BIT(6)
 #define SFF_8472_COMP_ADDR	0x5e
 #define SFF_8472_COMP_LEN	0x1
+#define SFF_8636_ID		0x0
+#define SFF_8636_ID_LEN	0x1
+#define SFF_8024_ID_SFP	0x3
 #define SFF_REV_ADDR		0x1
 #define SFF_REV_LEN		0x1
 
-- 
2.33.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ