1f2507
From 21367ae2b8ebbe5173cbed22dfa51680a3fe48d2 Mon Sep 17 00:00:00 2001
1f2507
From: Ido Schimmel <idosch@nvidia.com>
1f2507
Date: Tue, 23 Nov 2021 19:40:58 +0200
1f2507
Subject: [PATCH 30/35] cmis: Initialize Banked Page 11h in memory map
1f2507
1f2507
Banked Page 11h stores, among other things, lane-specific flags and
1f2507
monitors that are going to be parsed and displayed in subsequent
1f2507
patches.
1f2507
1f2507
Request it via the 'MODULE_EEPROM_GET' netlink message and initialize it
1f2507
in the memory map.
1f2507
1f2507
Only initialize it in supported Banks.
1f2507
1f2507
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
1f2507
---
1f2507
 cmis.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
1f2507
 cmis.h |  7 +++++++
1f2507
 2 files changed, 54 insertions(+), 2 deletions(-)
1f2507
1f2507
diff --git a/cmis.c b/cmis.c
1f2507
index 55b9d1b959cd..83ced4d253ae 100644
1f2507
--- a/cmis.c
1f2507
+++ b/cmis.c
1f2507
@@ -15,9 +15,17 @@
1f2507
 #include "cmis.h"
1f2507
 #include "netlink/extapi.h"
1f2507
 
1f2507
+/* The maximum number of supported Banks. Relevant documents:
1f2507
+ * [1] CMIS Rev. 5, page. 128, section 8.4.4, Table 8-40
1f2507
+ */
1f2507
+#define CMIS_MAX_BANKS	4
1f2507
+
1f2507
+/* We are not parsing further than Page 11h. */
1f2507
+#define CMIS_MAX_PAGES	18
1f2507
+
1f2507
 struct cmis_memory_map {
1f2507
 	const __u8 *lower_memory;
1f2507
-	const __u8 *upper_memory[1][3];	/* Bank, Page */
1f2507
+	const __u8 *upper_memory[CMIS_MAX_BANKS][CMIS_MAX_PAGES];
1f2507
 #define page_00h upper_memory[0x0][0x0]
1f2507
 #define page_01h upper_memory[0x0][0x1]
1f2507
 #define page_02h upper_memory[0x0][0x2]
1f2507
@@ -399,12 +407,33 @@ static void cmis_request_init(struct ethtool_module_eeprom *request, u8 bank,
1f2507
 	request->data = NULL;
1f2507
 }
1f2507
 
1f2507
+static int cmis_num_banks_get(const struct cmis_memory_map *map,
1f2507
+			      int *p_num_banks)
1f2507
+{
1f2507
+	switch (map->page_01h[CMIS_PAGES_ADVER_OFFSET] &
1f2507
+		CMIS_BANKS_SUPPORTED_MASK) {
1f2507
+	case CMIS_BANK_0_SUPPORTED:
1f2507
+		*p_num_banks = 1;
1f2507
+		break;
1f2507
+	case CMIS_BANK_0_1_SUPPORTED:
1f2507
+		*p_num_banks = 2;
1f2507
+		break;
1f2507
+	case CMIS_BANK_0_3_SUPPORTED:
1f2507
+		*p_num_banks = 4;
1f2507
+		break;
1f2507
+	default:
1f2507
+		return -EINVAL;
1f2507
+	}
1f2507
+
1f2507
+	return 0;
1f2507
+}
1f2507
+
1f2507
 static int
1f2507
 cmis_memory_map_init_pages(struct cmd_context *ctx,
1f2507
 			   struct cmis_memory_map *map)
1f2507
 {
1f2507
 	struct ethtool_module_eeprom request;
1f2507
-	int ret;
1f2507
+	int num_banks, i, ret;
1f2507
 
1f2507
 	/* Lower Memory and Page 00h are always present.
1f2507
 	 *
1f2507
@@ -443,6 +472,22 @@ cmis_memory_map_init_pages(struct cmd_context *ctx,
1f2507
 		return ret;
1f2507
 	map->page_02h = request.data - CMIS_PAGE_SIZE;
1f2507
 
1f2507
+	/* Bank 0 of Page 11h provides lane-specific registers for the first 8
1f2507
+	 * lanes, and each additional Banks provides support for an additional
1f2507
+	 * 8 lanes. Only initialize supported Banks.
1f2507
+	 */
1f2507
+	ret = cmis_num_banks_get(map, &num_banks);
1f2507
+	if (ret < 0)
1f2507
+		return ret;
1f2507
+
1f2507
+	for (i = 0; i < num_banks; i++) {
1f2507
+		cmis_request_init(&request, i, 0x11, CMIS_PAGE_SIZE);
1f2507
+		ret = nl_get_eeprom_page(ctx, &request);
1f2507
+		if (ret < 0)
1f2507
+			return ret;
1f2507
+		map->upper_memory[i][0x11] = request.data - CMIS_PAGE_SIZE;
1f2507
+	}
1f2507
+
1f2507
 	return 0;
1f2507
 }
1f2507
 
1f2507
diff --git a/cmis.h b/cmis.h
1f2507
index 911491dc5c8f..8d90a04756ad 100644
1f2507
--- a/cmis.h
1f2507
+++ b/cmis.h
1f2507
@@ -114,6 +114,13 @@
1f2507
 #define CMIS_WAVELENGTH_TOL_MSB			0x8C
1f2507
 #define CMIS_WAVELENGTH_TOL_LSB			0x8D
1f2507
 
1f2507
+/* Supported Pages Advertising (Page 1) */
1f2507
+#define CMIS_PAGES_ADVER_OFFSET			0x8E
1f2507
+#define CMIS_BANKS_SUPPORTED_MASK		0x03
1f2507
+#define CMIS_BANK_0_SUPPORTED			0x00
1f2507
+#define CMIS_BANK_0_1_SUPPORTED			0x01
1f2507
+#define CMIS_BANK_0_3_SUPPORTED			0x02
1f2507
+
1f2507
 /* Signal integrity controls */
1f2507
 #define CMIS_SIG_INTEG_TX_OFFSET		0xA1
1f2507
 #define CMIS_SIG_INTEG_RX_OFFSET		0xA2
1f2507
-- 
1f2507
2.35.1
1f2507