1f2507
From 85023fa5dd7e79ce46a92ab567b4b675c3145775 Mon Sep 17 00:00:00 2001
1f2507
From: Ido Schimmel <idosch@nvidia.com>
1f2507
Date: Tue, 12 Oct 2021 16:25:18 +0300
1f2507
Subject: [PATCH 19/35] sff-8636: Use memory map during parsing
1f2507
1f2507
Instead of passing one large buffer to the individual parsing functions,
1f2507
use the memory map structure from the previous patch.
1f2507
1f2507
This has the added benefit of checking which optional pages are actually
1f2507
available and it will also allow us to consolidate the IOCTL and netlink
1f2507
parsing code paths.
1f2507
1f2507
Tested by making sure that there are no differences in output in both
1f2507
the IOCTL and netlink paths before and after the patch.
1f2507
1f2507
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
1f2507
---
1f2507
 qsfp.c | 368 +++++++++++++++++++++++++++++++--------------------------
1f2507
 1 file changed, 201 insertions(+), 167 deletions(-)
1f2507
1f2507
diff --git a/qsfp.c b/qsfp.c
1f2507
index 80000d40f6e8..354b3b1ce9ff 100644
1f2507
--- a/qsfp.c
1f2507
+++ b/qsfp.c
1f2507
@@ -205,20 +205,21 @@ static struct sff8636_aw_flags {
1f2507
 	{ NULL, 0, 0 },
1f2507
 };
1f2507
 
1f2507
-static void sff8636_show_identifier(const __u8 *id)
1f2507
+static void sff8636_show_identifier(const struct sff8636_memory_map *map)
1f2507
 {
1f2507
-	sff8024_show_identifier(id, SFF8636_ID_OFFSET);
1f2507
+	sff8024_show_identifier(map->lower_memory, SFF8636_ID_OFFSET);
1f2507
 }
1f2507
 
1f2507
-static void sff8636_show_ext_identifier(const __u8 *id)
1f2507
+static void sff8636_show_ext_identifier(const struct sff8636_memory_map *map)
1f2507
 {
1f2507
 	printf("\t%-41s : 0x%02x\n", "Extended identifier",
1f2507
-			id[SFF8636_EXT_ID_OFFSET]);
1f2507
+	       map->page_00h[SFF8636_EXT_ID_OFFSET]);
1f2507
 
1f2507
 	static const char *pfx =
1f2507
 		"\tExtended identifier description           :";
1f2507
 
1f2507
-	switch (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_PWR_CLASS_MASK) {
1f2507
+	switch (map->page_00h[SFF8636_EXT_ID_OFFSET] &
1f2507
+		SFF8636_EXT_ID_PWR_CLASS_MASK) {
1f2507
 	case SFF8636_EXT_ID_PWR_CLASS_1:
1f2507
 		printf("%s 1.5W max. Power consumption\n", pfx);
1f2507
 		break;
1f2507
@@ -233,17 +234,18 @@ static void sff8636_show_ext_identifier(const __u8 *id)
1f2507
 		break;
1f2507
 	}
1f2507
 
1f2507
-	if (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_TX_MASK)
1f2507
+	if (map->page_00h[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_TX_MASK)
1f2507
 		printf("%s CDR present in TX,", pfx);
1f2507
 	else
1f2507
 		printf("%s No CDR in TX,", pfx);
1f2507
 
1f2507
-	if (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_RX_MASK)
1f2507
+	if (map->page_00h[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_RX_MASK)
1f2507
 		printf(" CDR present in RX\n");
1f2507
 	else
1f2507
 		printf(" No CDR in RX\n");
1f2507
 
1f2507
-	switch (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_EPWR_CLASS_MASK) {
1f2507
+	switch (map->page_00h[SFF8636_EXT_ID_OFFSET] &
1f2507
+		SFF8636_EXT_ID_EPWR_CLASS_MASK) {
1f2507
 	case SFF8636_EXT_ID_PWR_CLASS_LEGACY:
1f2507
 		printf("%s", pfx);
1f2507
 		break;
1f2507
@@ -257,18 +259,19 @@ static void sff8636_show_ext_identifier(const __u8 *id)
1f2507
 		printf("%s 5.0W max. Power consumption, ", pfx);
1f2507
 		break;
1f2507
 	}
1f2507
-	if (id[SFF8636_PWR_MODE_OFFSET] & SFF8636_HIGH_PWR_ENABLE)
1f2507
+	if (map->lower_memory[SFF8636_PWR_MODE_OFFSET] &
1f2507
+	    SFF8636_HIGH_PWR_ENABLE)
1f2507
 		printf(" High Power Class (> 3.5 W) enabled\n");
1f2507
 	else
1f2507
 		printf(" High Power Class (> 3.5 W) not enabled\n");
1f2507
 }
1f2507
 
1f2507
-static void sff8636_show_connector(const __u8 *id)
1f2507
+static void sff8636_show_connector(const struct sff8636_memory_map *map)
1f2507
 {
1f2507
-	sff8024_show_connector(id, SFF8636_CTOR_OFFSET);
1f2507
+	sff8024_show_connector(map->page_00h, SFF8636_CTOR_OFFSET);
1f2507
 }
1f2507
 
1f2507
-static void sff8636_show_transceiver(const __u8 *id)
1f2507
+static void sff8636_show_transceiver(const struct sff8636_memory_map *map)
1f2507
 {
1f2507
 	static const char *pfx =
1f2507
 		"\tTransceiver type                          :";
1f2507
@@ -276,33 +279,41 @@ static void sff8636_show_transceiver(const __u8 *id)
1f2507
 	printf("\t%-41s : 0x%02x 0x%02x 0x%02x " \
1f2507
 			"0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
1f2507
 			"Transceiver codes",
1f2507
-			id[SFF8636_ETHERNET_COMP_OFFSET],
1f2507
-			id[SFF8636_SONET_COMP_OFFSET],
1f2507
-			id[SFF8636_SAS_COMP_OFFSET],
1f2507
-			id[SFF8636_GIGE_COMP_OFFSET],
1f2507
-			id[SFF8636_FC_LEN_OFFSET],
1f2507
-			id[SFF8636_FC_TECH_OFFSET],
1f2507
-			id[SFF8636_FC_TRANS_MEDIA_OFFSET],
1f2507
-			id[SFF8636_FC_SPEED_OFFSET]);
1f2507
+			map->page_00h[SFF8636_ETHERNET_COMP_OFFSET],
1f2507
+			map->page_00h[SFF8636_SONET_COMP_OFFSET],
1f2507
+			map->page_00h[SFF8636_SAS_COMP_OFFSET],
1f2507
+			map->page_00h[SFF8636_GIGE_COMP_OFFSET],
1f2507
+			map->page_00h[SFF8636_FC_LEN_OFFSET],
1f2507
+			map->page_00h[SFF8636_FC_TECH_OFFSET],
1f2507
+			map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET],
1f2507
+			map->page_00h[SFF8636_FC_SPEED_OFFSET]);
1f2507
 
1f2507
 	/* 10G/40G Ethernet Compliance Codes */
1f2507
-	if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_10G_LRM)
1f2507
+	if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
1f2507
+	    SFF8636_ETHERNET_10G_LRM)
1f2507
 		printf("%s 10G Ethernet: 10G Base-LRM\n", pfx);
1f2507
-	if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_10G_LR)
1f2507
+	if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
1f2507
+	    SFF8636_ETHERNET_10G_LR)
1f2507
 		printf("%s 10G Ethernet: 10G Base-LR\n", pfx);
1f2507
-	if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_10G_SR)
1f2507
+	if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
1f2507
+	    SFF8636_ETHERNET_10G_SR)
1f2507
 		printf("%s 10G Ethernet: 10G Base-SR\n", pfx);
1f2507
-	if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_CR4)
1f2507
+	if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
1f2507
+	    SFF8636_ETHERNET_40G_CR4)
1f2507
 		printf("%s 40G Ethernet: 40G Base-CR4\n", pfx);
1f2507
-	if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_SR4)
1f2507
+	if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
1f2507
+	    SFF8636_ETHERNET_40G_SR4)
1f2507
 		printf("%s 40G Ethernet: 40G Base-SR4\n", pfx);
1f2507
-	if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_LR4)
1f2507
+	if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
1f2507
+	    SFF8636_ETHERNET_40G_LR4)
1f2507
 		printf("%s 40G Ethernet: 40G Base-LR4\n", pfx);
1f2507
-	if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_ACTIVE)
1f2507
+	if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
1f2507
+	    SFF8636_ETHERNET_40G_ACTIVE)
1f2507
 		printf("%s 40G Ethernet: 40G Active Cable (XLPPI)\n", pfx);
1f2507
 	/* Extended Specification Compliance Codes from SFF-8024 */
1f2507
-	if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_RSRVD) {
1f2507
-		switch (id[SFF8636_OPTION_1_OFFSET]) {
1f2507
+	if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
1f2507
+	    SFF8636_ETHERNET_RSRVD) {
1f2507
+		switch (map->page_00h[SFF8636_OPTION_1_OFFSET]) {
1f2507
 		case SFF8636_ETHERNET_UNSPECIFIED:
1f2507
 			printf("%s (reserved or unknown)\n", pfx);
1f2507
 			break;
1f2507
@@ -493,113 +504,122 @@ static void sff8636_show_transceiver(const __u8 *id)
1f2507
 	}
1f2507
 
1f2507
 	/* SONET Compliance Codes */
1f2507
-	if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_40G_OTN))
1f2507
+	if (map->page_00h[SFF8636_SONET_COMP_OFFSET] &
1f2507
+	    (SFF8636_SONET_40G_OTN))
1f2507
 		printf("%s 40G OTN (OTU3B/OTU3C)\n", pfx);
1f2507
-	if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_LR))
1f2507
+	if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_LR))
1f2507
 		printf("%s SONET: OC-48, long reach\n", pfx);
1f2507
-	if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_IR))
1f2507
+	if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_IR))
1f2507
 		printf("%s SONET: OC-48, intermediate reach\n", pfx);
1f2507
-	if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_SR))
1f2507
+	if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_SR))
1f2507
 		printf("%s SONET: OC-48, short reach\n", pfx);
1f2507
 
1f2507
 	/* SAS/SATA Compliance Codes */
1f2507
-	if (id[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_6G))
1f2507
+	if (map->page_00h[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_6G))
1f2507
 		printf("%s SAS 6.0G\n", pfx);
1f2507
-	if (id[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_3G))
1f2507
+	if (map->page_00h[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_3G))
1f2507
 		printf("%s SAS 3.0G\n", pfx);
1f2507
 
1f2507
 	/* Ethernet Compliance Codes */
1f2507
-	if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_T)
1f2507
+	if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_T)
1f2507
 		printf("%s Ethernet: 1000BASE-T\n", pfx);
1f2507
-	if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_CX)
1f2507
+	if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_CX)
1f2507
 		printf("%s Ethernet: 1000BASE-CX\n", pfx);
1f2507
-	if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_LX)
1f2507
+	if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_LX)
1f2507
 		printf("%s Ethernet: 1000BASE-LX\n", pfx);
1f2507
-	if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_SX)
1f2507
+	if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_SX)
1f2507
 		printf("%s Ethernet: 1000BASE-SX\n", pfx);
1f2507
 
1f2507
 	/* Fibre Channel link length */
1f2507
-	if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_VERY_LONG)
1f2507
+	if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_VERY_LONG)
1f2507
 		printf("%s FC: very long distance (V)\n", pfx);
1f2507
-	if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_SHORT)
1f2507
+	if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_SHORT)
1f2507
 		printf("%s FC: short distance (S)\n", pfx);
1f2507
-	if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_INT)
1f2507
+	if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_INT)
1f2507
 		printf("%s FC: intermediate distance (I)\n", pfx);
1f2507
-	if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_LONG)
1f2507
+	if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_LONG)
1f2507
 		printf("%s FC: long distance (L)\n", pfx);
1f2507
-	if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_MED)
1f2507
+	if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_MED)
1f2507
 		printf("%s FC: medium distance (M)\n", pfx);
1f2507
 
1f2507
 	/* Fibre Channel transmitter technology */
1f2507
-	if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_LONG_LC)
1f2507
+	if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_LONG_LC)
1f2507
 		printf("%s FC: Longwave laser (LC)\n", pfx);
1f2507
-	if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_ELEC_INTER)
1f2507
+	if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_ELEC_INTER)
1f2507
 		printf("%s FC: Electrical inter-enclosure (EL)\n", pfx);
1f2507
-	if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_ELEC_INTRA)
1f2507
+	if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_ELEC_INTRA)
1f2507
 		printf("%s FC: Electrical intra-enclosure (EL)\n", pfx);
1f2507
-	if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_SHORT_WO_OFC)
1f2507
+	if (map->page_00h[SFF8636_FC_TECH_OFFSET] &
1f2507
+	    SFF8636_FC_TECH_SHORT_WO_OFC)
1f2507
 		printf("%s FC: Shortwave laser w/o OFC (SN)\n", pfx);
1f2507
-	if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_SHORT_W_OFC)
1f2507
+	if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_SHORT_W_OFC)
1f2507
 		printf("%s FC: Shortwave laser with OFC (SL)\n", pfx);
1f2507
-	if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_LONG_LL)
1f2507
+	if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_LONG_LL)
1f2507
 		printf("%s FC: Longwave laser (LL)\n", pfx);
1f2507
 
1f2507
 	/* Fibre Channel transmission media */
1f2507
-	if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_TW)
1f2507
+	if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
1f2507
+	    SFF8636_FC_TRANS_MEDIA_TW)
1f2507
 		printf("%s FC: Twin Axial Pair (TW)\n", pfx);
1f2507
-	if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_TP)
1f2507
+	if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
1f2507
+	    SFF8636_FC_TRANS_MEDIA_TP)
1f2507
 		printf("%s FC: Twisted Pair (TP)\n", pfx);
1f2507
-	if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_MI)
1f2507
+	if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
1f2507
+	    SFF8636_FC_TRANS_MEDIA_MI)
1f2507
 		printf("%s FC: Miniature Coax (MI)\n", pfx);
1f2507
-	if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_TV)
1f2507
+	if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
1f2507
+	    SFF8636_FC_TRANS_MEDIA_TV)
1f2507
 		printf("%s FC: Video Coax (TV)\n", pfx);
1f2507
-	if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_M6)
1f2507
+	if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
1f2507
+	    SFF8636_FC_TRANS_MEDIA_M6)
1f2507
 		printf("%s FC: Multimode, 62.5m (M6)\n", pfx);
1f2507
-	if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_M5)
1f2507
+	if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
1f2507
+	    SFF8636_FC_TRANS_MEDIA_M5)
1f2507
 		printf("%s FC: Multimode, 50m (M5)\n", pfx);
1f2507
-	if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_OM3)
1f2507
+	if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
1f2507
+	    SFF8636_FC_TRANS_MEDIA_OM3)
1f2507
 		printf("%s FC: Multimode, 50um (OM3)\n", pfx);
1f2507
-	if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_SM)
1f2507
+	if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
1f2507
+	    SFF8636_FC_TRANS_MEDIA_SM)
1f2507
 		printf("%s FC: Single Mode (SM)\n", pfx);
1f2507
 
1f2507
 	/* Fibre Channel speed */
1f2507
-	if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1200_MBPS)
1f2507
+	if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1200_MBPS)
1f2507
 		printf("%s FC: 1200 MBytes/sec\n", pfx);
1f2507
-	if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_800_MBPS)
1f2507
+	if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_800_MBPS)
1f2507
 		printf("%s FC: 800 MBytes/sec\n", pfx);
1f2507
-	if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1600_MBPS)
1f2507
+	if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1600_MBPS)
1f2507
 		printf("%s FC: 1600 MBytes/sec\n", pfx);
1f2507
-	if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_400_MBPS)
1f2507
+	if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_400_MBPS)
1f2507
 		printf("%s FC: 400 MBytes/sec\n", pfx);
1f2507
-	if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_200_MBPS)
1f2507
+	if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_200_MBPS)
1f2507
 		printf("%s FC: 200 MBytes/sec\n", pfx);
1f2507
-	if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_100_MBPS)
1f2507
+	if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_100_MBPS)
1f2507
 		printf("%s FC: 100 MBytes/sec\n", pfx);
1f2507
 }
1f2507
 
1f2507
-static void sff8636_show_encoding(const __u8 *id)
1f2507
+static void sff8636_show_encoding(const struct sff8636_memory_map *map)
1f2507
 {
1f2507
-	sff8024_show_encoding(id, SFF8636_ENCODING_OFFSET, ETH_MODULE_SFF_8636);
1f2507
+	sff8024_show_encoding(map->page_00h, SFF8636_ENCODING_OFFSET,
1f2507
+			      ETH_MODULE_SFF_8636);
1f2507
 }
1f2507
 
1f2507
-static void sff8636_show_rate_identifier(const __u8 *id)
1f2507
+static void sff8636_show_rate_identifier(const struct sff8636_memory_map *map)
1f2507
 {
1f2507
 	/* TODO: Need to fix rate select logic */
1f2507
 	printf("\t%-41s : 0x%02x\n", "Rate identifier",
1f2507
-			id[SFF8636_EXT_RS_OFFSET]);
1f2507
+	       map->page_00h[SFF8636_EXT_RS_OFFSET]);
1f2507
 }
1f2507
 
1f2507
-static void sff8636_show_oui(const __u8 *id, int id_offset)
1f2507
-{
1f2507
-	sff8024_show_oui(id, id_offset);
1f2507
-}
1f2507
-
1f2507
-static void sff8636_show_wavelength_or_copper_compliance(const __u8 *id)
1f2507
+static void
1f2507
+sff8636_show_wavelength_or_copper_compliance(const struct sff8636_memory_map *map)
1f2507
 {
1f2507
 	printf("\t%-41s : 0x%02x", "Transmitter technology",
1f2507
-		(id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK));
1f2507
+	       map->page_00h[SFF8636_DEVICE_TECH_OFFSET] &
1f2507
+	       SFF8636_TRANS_TECH_MASK);
1f2507
 
1f2507
-	switch (id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK) {
1f2507
+	switch (map->page_00h[SFF8636_DEVICE_TECH_OFFSET] &
1f2507
+		SFF8636_TRANS_TECH_MASK) {
1f2507
 	case SFF8636_TRANS_850_VCSEL:
1f2507
 		printf(" (850 nm VCSEL)\n");
1f2507
 		break;
1f2507
@@ -650,31 +670,26 @@ static void sff8636_show_wavelength_or_copper_compliance(const __u8 *id)
1f2507
 		break;
1f2507
 	}
1f2507
 
1f2507
-	if ((id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK)
1f2507
-			>= SFF8636_TRANS_COPPER_PAS_UNEQUAL) {
1f2507
+	if ((map->page_00h[SFF8636_DEVICE_TECH_OFFSET] &
1f2507
+	     SFF8636_TRANS_TECH_MASK) >= SFF8636_TRANS_COPPER_PAS_UNEQUAL) {
1f2507
 		printf("\t%-41s : %udb\n", "Attenuation at 2.5GHz",
1f2507
-			id[SFF8636_WAVELEN_HIGH_BYTE_OFFSET]);
1f2507
+			map->page_00h[SFF8636_WAVELEN_HIGH_BYTE_OFFSET]);
1f2507
 		printf("\t%-41s : %udb\n", "Attenuation at 5.0GHz",
1f2507
-			id[SFF8636_WAVELEN_LOW_BYTE_OFFSET]);
1f2507
+			map->page_00h[SFF8636_WAVELEN_LOW_BYTE_OFFSET]);
1f2507
 		printf("\t%-41s : %udb\n", "Attenuation at 7.0GHz",
1f2507
-			id[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET]);
1f2507
+			map->page_00h[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET]);
1f2507
 		printf("\t%-41s : %udb\n", "Attenuation at 12.9GHz",
1f2507
-			id[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]);
1f2507
+		       map->page_00h[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]);
1f2507
 	} else {
1f2507
 		printf("\t%-41s : %.3lfnm\n", "Laser wavelength",
1f2507
-			(((id[SFF8636_WAVELEN_HIGH_BYTE_OFFSET] << 8) |
1f2507
-				id[SFF8636_WAVELEN_LOW_BYTE_OFFSET])*0.05));
1f2507
+		       (((map->page_00h[SFF8636_WAVELEN_HIGH_BYTE_OFFSET] << 8) |
1f2507
+			 map->page_00h[SFF8636_WAVELEN_LOW_BYTE_OFFSET]) * 0.05));
1f2507
 		printf("\t%-41s : %.3lfnm\n", "Laser wavelength tolerance",
1f2507
-			(((id[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET] << 8) |
1f2507
-			id[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET])*0.005));
1f2507
+		       (((map->page_00h[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET] << 8) |
1f2507
+			 map->page_00h[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]) * 0.005));
1f2507
 	}
1f2507
 }
1f2507
 
1f2507
-static void sff8636_show_revision_compliance(const __u8 *id)
1f2507
-{
1f2507
-	sff_show_revision_compliance(id, SFF8636_REV_COMPLIANCE_OFFSET);
1f2507
-}
1f2507
-
1f2507
 /*
1f2507
  * 2-byte internal temperature conversions:
1f2507
  * First byte is a signed 8-bit integer, which is the temp decimal part
1f2507
@@ -683,39 +698,65 @@ static void sff8636_show_revision_compliance(const __u8 *id)
1f2507
 #define SFF8636_OFFSET_TO_TEMP(offset) ((__s16)OFFSET_TO_U16(offset))
1f2507
 #define OFFSET_TO_U16_PTR(ptr, offset) (ptr[offset] << 8 | ptr[(offset) + 1])
1f2507
 
1f2507
-static void sff8636_dom_parse(const __u8 *id, const __u8 *page_three, struct sff_diags *sd)
1f2507
+static void sff8636_dom_parse(const struct sff8636_memory_map *map,
1f2507
+			      struct sff_diags *sd)
1f2507
 {
1f2507
+	const __u8 *id = map->lower_memory;
1f2507
 	int i = 0;
1f2507
 
1f2507
 	/* Monitoring Thresholds for Alarms and Warnings */
1f2507
 	sd->sfp_voltage[MCURR] = OFFSET_TO_U16_PTR(id, SFF8636_VCC_CURR);
1f2507
-	sd->sfp_voltage[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_HALRM);
1f2507
-	sd->sfp_voltage[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_LALRM);
1f2507
-	sd->sfp_voltage[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_HWARN);
1f2507
-	sd->sfp_voltage[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_LWARN);
1f2507
-
1f2507
 	sd->sfp_temp[MCURR] = SFF8636_OFFSET_TO_TEMP(SFF8636_TEMP_CURR);
1f2507
-	sd->sfp_temp[HALRM] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_HALRM);
1f2507
-	sd->sfp_temp[LALRM] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_LALRM);
1f2507
-	sd->sfp_temp[HWARN] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_HWARN);
1f2507
-	sd->sfp_temp[LWARN] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_LWARN);
1f2507
-
1f2507
-	sd->bias_cur[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_HALRM);
1f2507
-	sd->bias_cur[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_LALRM);
1f2507
-	sd->bias_cur[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_HWARN);
1f2507
-	sd->bias_cur[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_LWARN);
1f2507
-
1f2507
-	sd->tx_power[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_HALRM);
1f2507
-	sd->tx_power[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_LALRM);
1f2507
-	sd->tx_power[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_HWARN);
1f2507
-	sd->tx_power[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_LWARN);
1f2507
-
1f2507
-	sd->rx_power[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_HALRM);
1f2507
-	sd->rx_power[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_LALRM);
1f2507
-	sd->rx_power[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_HWARN);
1f2507
-	sd->rx_power[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_LWARN);
1f2507
-
1f2507
 
1f2507
+	if (!map->page_03h)
1f2507
+		goto out;
1f2507
+
1f2507
+	sd->sfp_voltage[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						   SFF8636_VCC_HALRM);
1f2507
+	sd->sfp_voltage[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						   SFF8636_VCC_LALRM);
1f2507
+	sd->sfp_voltage[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						   SFF8636_VCC_HWARN);
1f2507
+	sd->sfp_voltage[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						   SFF8636_VCC_LWARN);
1f2507
+
1f2507
+	sd->sfp_temp[HALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						       SFF8636_TEMP_HALRM);
1f2507
+	sd->sfp_temp[LALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						       SFF8636_TEMP_LALRM);
1f2507
+	sd->sfp_temp[HWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						       SFF8636_TEMP_HWARN);
1f2507
+	sd->sfp_temp[LWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						       SFF8636_TEMP_LWARN);
1f2507
+
1f2507
+	sd->bias_cur[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						SFF8636_TX_BIAS_HALRM);
1f2507
+	sd->bias_cur[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						SFF8636_TX_BIAS_LALRM);
1f2507
+	sd->bias_cur[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						SFF8636_TX_BIAS_HWARN);
1f2507
+	sd->bias_cur[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						SFF8636_TX_BIAS_LWARN);
1f2507
+
1f2507
+	sd->tx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						SFF8636_TX_PWR_HALRM);
1f2507
+	sd->tx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						SFF8636_TX_PWR_LALRM);
1f2507
+	sd->tx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						SFF8636_TX_PWR_HWARN);
1f2507
+	sd->tx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						SFF8636_TX_PWR_LWARN);
1f2507
+
1f2507
+	sd->rx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						SFF8636_RX_PWR_HALRM);
1f2507
+	sd->rx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						SFF8636_RX_PWR_LALRM);
1f2507
+	sd->rx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						SFF8636_RX_PWR_HWARN);
1f2507
+	sd->rx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
1f2507
+						SFF8636_RX_PWR_LWARN);
1f2507
+
1f2507
+out:
1f2507
 	/* Channel Specific Data */
1f2507
 	for (i = 0; i < MAX_CHANNEL_NUM; i++) {
1f2507
 		u8 rx_power_offset, tx_bias_offset;
1f2507
@@ -749,7 +790,7 @@ static void sff8636_dom_parse(const __u8 *id, const __u8 *page_three, struct sff
1f2507
 	}
1f2507
 }
1f2507
 
1f2507
-static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eeprom_len)
1f2507
+static void sff8636_show_dom(const struct sff8636_memory_map *map)
1f2507
 {
1f2507
 	struct sff_diags sd = {0};
1f2507
 	char *rx_power_string = NULL;
1f2507
@@ -763,20 +804,15 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
1f2507
 	 * and thresholds
1f2507
 	 * If pagging support exists, then supports_alarms is marked as 1
1f2507
 	 */
1f2507
+	if (map->page_03h)
1f2507
+		sd.supports_alarms = 1;
1f2507
 
1f2507
-	if (eeprom_len == ETH_MODULE_SFF_8636_MAX_LEN) {
1f2507
-		if (!(id[SFF8636_STATUS_2_OFFSET] &
1f2507
-					SFF8636_STATUS_PAGE_3_PRESENT)) {
1f2507
-			sd.supports_alarms = 1;
1f2507
-		}
1f2507
-	}
1f2507
+	sd.rx_power_type = map->page_00h[SFF8636_DIAG_TYPE_OFFSET] &
1f2507
+			   SFF8636_RX_PWR_TYPE_MASK;
1f2507
+	sd.tx_power_type = map->page_00h[SFF8636_DIAG_TYPE_OFFSET] &
1f2507
+			   SFF8636_RX_PWR_TYPE_MASK;
1f2507
 
1f2507
-	sd.rx_power_type = id[SFF8636_DIAG_TYPE_OFFSET] &
1f2507
-						SFF8636_RX_PWR_TYPE_MASK;
1f2507
-	sd.tx_power_type = id[SFF8636_DIAG_TYPE_OFFSET] &
1f2507
-						SFF8636_RX_PWR_TYPE_MASK;
1f2507
-
1f2507
-	sff8636_dom_parse(id, page_three, &sd);
1f2507
+	sff8636_dom_parse(map, &sd);
1f2507
 
1f2507
 	PRINT_TEMP("Module temperature", sd.sfp_temp[MCURR]);
1f2507
 	PRINT_VCC("Module voltage", sd.sfp_voltage[MCURR]);
1f2507
@@ -819,7 +855,7 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
1f2507
 	if (sd.supports_alarms) {
1f2507
 		for (i = 0; sff8636_aw_flags[i].str; ++i) {
1f2507
 			printf("\t%-41s : %s\n", sff8636_aw_flags[i].str,
1f2507
-			       id[sff8636_aw_flags[i].offset]
1f2507
+			       map->lower_memory[sff8636_aw_flags[i].offset]
1f2507
 			       & sff8636_aw_flags[i].value ? "On" : "Off");
1f2507
 		}
1f2507
 
1f2507
@@ -827,39 +863,39 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
1f2507
 	}
1f2507
 }
1f2507
 
1f2507
-static void sff8636_show_page_zero(const __u8 *id)
1f2507
+static void sff8636_show_page_zero(const struct sff8636_memory_map *map)
1f2507
 {
1f2507
-	sff8636_show_ext_identifier(id);
1f2507
-	sff8636_show_connector(id);
1f2507
-	sff8636_show_transceiver(id);
1f2507
-	sff8636_show_encoding(id);
1f2507
-	sff_show_value_with_unit(id, SFF8636_BR_NOMINAL_OFFSET,
1f2507
-			"BR, Nominal", 100, "Mbps");
1f2507
-	sff8636_show_rate_identifier(id);
1f2507
-	sff_show_value_with_unit(id, SFF8636_SM_LEN_OFFSET,
1f2507
-		     "Length (SMF,km)", 1, "km");
1f2507
-	sff_show_value_with_unit(id, SFF8636_OM3_LEN_OFFSET,
1f2507
-			"Length (OM3 50um)", 2, "m");
1f2507
-	sff_show_value_with_unit(id, SFF8636_OM2_LEN_OFFSET,
1f2507
-			"Length (OM2 50um)", 1, "m");
1f2507
-	sff_show_value_with_unit(id, SFF8636_OM1_LEN_OFFSET,
1f2507
-		     "Length (OM1 62.5um)", 1, "m");
1f2507
-	sff_show_value_with_unit(id, SFF8636_CBL_LEN_OFFSET,
1f2507
-		     "Length (Copper or Active cable)", 1, "m");
1f2507
-	sff8636_show_wavelength_or_copper_compliance(id);
1f2507
-	sff_show_ascii(id, SFF8636_VENDOR_NAME_START_OFFSET,
1f2507
+	sff8636_show_ext_identifier(map);
1f2507
+	sff8636_show_connector(map);
1f2507
+	sff8636_show_transceiver(map);
1f2507
+	sff8636_show_encoding(map);
1f2507
+	sff_show_value_with_unit(map->page_00h, SFF8636_BR_NOMINAL_OFFSET,
1f2507
+				 "BR, Nominal", 100, "Mbps");
1f2507
+	sff8636_show_rate_identifier(map);
1f2507
+	sff_show_value_with_unit(map->page_00h, SFF8636_SM_LEN_OFFSET,
1f2507
+				 "Length (SMF,km)", 1, "km");
1f2507
+	sff_show_value_with_unit(map->page_00h, SFF8636_OM3_LEN_OFFSET,
1f2507
+				 "Length (OM3 50um)", 2, "m");
1f2507
+	sff_show_value_with_unit(map->page_00h, SFF8636_OM2_LEN_OFFSET,
1f2507
+				 "Length (OM2 50um)", 1, "m");
1f2507
+	sff_show_value_with_unit(map->page_00h, SFF8636_OM1_LEN_OFFSET,
1f2507
+				 "Length (OM1 62.5um)", 1, "m");
1f2507
+	sff_show_value_with_unit(map->page_00h, SFF8636_CBL_LEN_OFFSET,
1f2507
+				 "Length (Copper or Active cable)", 1, "m");
1f2507
+	sff8636_show_wavelength_or_copper_compliance(map);
1f2507
+	sff_show_ascii(map->page_00h, SFF8636_VENDOR_NAME_START_OFFSET,
1f2507
 		       SFF8636_VENDOR_NAME_END_OFFSET, "Vendor name");
1f2507
-	sff8636_show_oui(id, SFF8636_VENDOR_OUI_OFFSET);
1f2507
-	sff_show_ascii(id, SFF8636_VENDOR_PN_START_OFFSET,
1f2507
+	sff8024_show_oui(map->page_00h, SFF8636_VENDOR_OUI_OFFSET);
1f2507
+	sff_show_ascii(map->page_00h, SFF8636_VENDOR_PN_START_OFFSET,
1f2507
 		       SFF8636_VENDOR_PN_END_OFFSET, "Vendor PN");
1f2507
-	sff_show_ascii(id, SFF8636_VENDOR_REV_START_OFFSET,
1f2507
+	sff_show_ascii(map->page_00h, SFF8636_VENDOR_REV_START_OFFSET,
1f2507
 		       SFF8636_VENDOR_REV_END_OFFSET, "Vendor rev");
1f2507
-	sff_show_ascii(id, SFF8636_VENDOR_SN_START_OFFSET,
1f2507
+	sff_show_ascii(map->page_00h, SFF8636_VENDOR_SN_START_OFFSET,
1f2507
 		       SFF8636_VENDOR_SN_END_OFFSET, "Vendor SN");
1f2507
-	sff_show_ascii(id, SFF8636_DATE_YEAR_OFFSET,
1f2507
+	sff_show_ascii(map->page_00h, SFF8636_DATE_YEAR_OFFSET,
1f2507
 		       SFF8636_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
1f2507
-	sff8636_show_revision_compliance(id);
1f2507
-
1f2507
+	sff_show_revision_compliance(map->lower_memory,
1f2507
+				     SFF8636_REV_COMPLIANCE_OFFSET);
1f2507
 }
1f2507
 
1f2507
 static void sff8636_memory_map_init_buf(struct sff8636_memory_map *map,
1f2507
@@ -896,13 +932,13 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
1f2507
 
1f2507
 	sff8636_memory_map_init_buf(&map, id, eeprom_len);
1f2507
 
1f2507
-	sff8636_show_identifier(id);
1f2507
-	switch (id[SFF8636_ID_OFFSET]) {
1f2507
+	sff8636_show_identifier(&map);
1f2507
+	switch (map.lower_memory[SFF8636_ID_OFFSET]) {
1f2507
 	case SFF8024_ID_QSFP:
1f2507
 	case SFF8024_ID_QSFP_PLUS:
1f2507
 	case SFF8024_ID_QSFP28:
1f2507
-		sff8636_show_page_zero(id);
1f2507
-		sff8636_show_dom(id, id + 3 * 0x80, eeprom_len);
1f2507
+		sff8636_show_page_zero(&map);
1f2507
+		sff8636_show_dom(&map);
1f2507
 		break;
1f2507
 	}
1f2507
 }
1f2507
@@ -939,9 +975,7 @@ void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
1f2507
 
1f2507
 	sff8636_memory_map_init_pages(&map, page_zero, page_three);
1f2507
 
1f2507
-	sff8636_show_identifier(page_zero->data);
1f2507
-	sff8636_show_page_zero(page_zero->data);
1f2507
-	if (page_three)
1f2507
-		sff8636_show_dom(page_zero->data, page_three->data - 0x80,
1f2507
-				 ETH_MODULE_SFF_8636_MAX_LEN);
1f2507
+	sff8636_show_identifier(&map);
1f2507
+	sff8636_show_page_zero(&map);
1f2507
+	sff8636_show_dom(&map);
1f2507
 }
1f2507
-- 
1f2507
2.35.1
1f2507