Blob Blame History Raw
From 21367ae2b8ebbe5173cbed22dfa51680a3fe48d2 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 23 Nov 2021 19:40:58 +0200
Subject: [PATCH 30/35] cmis: Initialize Banked Page 11h in memory map

Banked Page 11h stores, among other things, lane-specific flags and
monitors that are going to be parsed and displayed in subsequent
patches.

Request it via the 'MODULE_EEPROM_GET' netlink message and initialize it
in the memory map.

Only initialize it in supported Banks.

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
 cmis.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
 cmis.h |  7 +++++++
 2 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/cmis.c b/cmis.c
index 55b9d1b959cd..83ced4d253ae 100644
--- a/cmis.c
+++ b/cmis.c
@@ -15,9 +15,17 @@
 #include "cmis.h"
 #include "netlink/extapi.h"
 
+/* The maximum number of supported Banks. Relevant documents:
+ * [1] CMIS Rev. 5, page. 128, section 8.4.4, Table 8-40
+ */
+#define CMIS_MAX_BANKS	4
+
+/* We are not parsing further than Page 11h. */
+#define CMIS_MAX_PAGES	18
+
 struct cmis_memory_map {
 	const __u8 *lower_memory;
-	const __u8 *upper_memory[1][3];	/* Bank, Page */
+	const __u8 *upper_memory[CMIS_MAX_BANKS][CMIS_MAX_PAGES];
 #define page_00h upper_memory[0x0][0x0]
 #define page_01h upper_memory[0x0][0x1]
 #define page_02h upper_memory[0x0][0x2]
@@ -399,12 +407,33 @@ static void cmis_request_init(struct ethtool_module_eeprom *request, u8 bank,
 	request->data = NULL;
 }
 
+static int cmis_num_banks_get(const struct cmis_memory_map *map,
+			      int *p_num_banks)
+{
+	switch (map->page_01h[CMIS_PAGES_ADVER_OFFSET] &
+		CMIS_BANKS_SUPPORTED_MASK) {
+	case CMIS_BANK_0_SUPPORTED:
+		*p_num_banks = 1;
+		break;
+	case CMIS_BANK_0_1_SUPPORTED:
+		*p_num_banks = 2;
+		break;
+	case CMIS_BANK_0_3_SUPPORTED:
+		*p_num_banks = 4;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int
 cmis_memory_map_init_pages(struct cmd_context *ctx,
 			   struct cmis_memory_map *map)
 {
 	struct ethtool_module_eeprom request;
-	int ret;
+	int num_banks, i, ret;
 
 	/* Lower Memory and Page 00h are always present.
 	 *
@@ -443,6 +472,22 @@ cmis_memory_map_init_pages(struct cmd_context *ctx,
 		return ret;
 	map->page_02h = request.data - CMIS_PAGE_SIZE;
 
+	/* Bank 0 of Page 11h provides lane-specific registers for the first 8
+	 * lanes, and each additional Banks provides support for an additional
+	 * 8 lanes. Only initialize supported Banks.
+	 */
+	ret = cmis_num_banks_get(map, &num_banks);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < num_banks; i++) {
+		cmis_request_init(&request, i, 0x11, CMIS_PAGE_SIZE);
+		ret = nl_get_eeprom_page(ctx, &request);
+		if (ret < 0)
+			return ret;
+		map->upper_memory[i][0x11] = request.data - CMIS_PAGE_SIZE;
+	}
+
 	return 0;
 }
 
diff --git a/cmis.h b/cmis.h
index 911491dc5c8f..8d90a04756ad 100644
--- a/cmis.h
+++ b/cmis.h
@@ -114,6 +114,13 @@
 #define CMIS_WAVELENGTH_TOL_MSB			0x8C
 #define CMIS_WAVELENGTH_TOL_LSB			0x8D
 
+/* Supported Pages Advertising (Page 1) */
+#define CMIS_PAGES_ADVER_OFFSET			0x8E
+#define CMIS_BANKS_SUPPORTED_MASK		0x03
+#define CMIS_BANK_0_SUPPORTED			0x00
+#define CMIS_BANK_0_1_SUPPORTED			0x01
+#define CMIS_BANK_0_3_SUPPORTED			0x02
+
 /* Signal integrity controls */
 #define CMIS_SIG_INTEG_TX_OFFSET		0xA1
 #define CMIS_SIG_INTEG_RX_OFFSET		0xA2
-- 
2.35.1