Blame SOURCES/0014-cmis-Initialize-CMIS-memory-map.patch

1f2507
From 912115ebf8ca6eb76dfdadbe8881b7c348743f27 Mon Sep 17 00:00:00 2001
1f2507
From: Ido Schimmel <idosch@nvidia.com>
1f2507
Date: Tue, 12 Oct 2021 16:25:13 +0300
1f2507
Subject: [PATCH 14/35] cmis: Initialize CMIS memory map
1f2507
1f2507
The CMIS memory map [1] consists of Lower Memory and Upper Memory.
1f2507
1f2507
The content of the Lower Memory is fixed and can be addressed using an
1f2507
offset between 0 and 127 (inclusive).
1f2507
1f2507
The Upper Memory is variable and optional and can be addressed by
1f2507
specifying a bank number, a page number and an offset between 128 and
1f2507
255 (inclusive).
1f2507
1f2507
Create a structure describing this memory map and initialize it with
1f2507
pointers to available pages.
1f2507
1f2507
In the IOCTL path, the structure holds pointers to regions of the
1f2507
continuous buffer passed to user space via the 'ETHTOOL_GMODULEEEPROM'
1f2507
command.
1f2507
1f2507
In the netlink path, the structure holds pointers to individual pages
1f2507
passed to user space via the 'MODULE_EEPROM_GET' message.
1f2507
1f2507
This structure will later allow us to consolidate the IOCTL and netlink
1f2507
parsing code paths and also easily support additional EEPROM pages.
1f2507
1f2507
[1] CMIS Rev. 5, pag. 97, section 8.1.1, Figure 8-1
1f2507
1f2507
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
1f2507
---
1f2507
 cmis.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1f2507
 cmis.h |  2 ++
1f2507
 2 files changed, 65 insertions(+)
1f2507
1f2507
diff --git a/cmis.c b/cmis.c
1f2507
index 68c5b2d3277b..8a6788416a00 100644
1f2507
--- a/cmis.c
1f2507
+++ b/cmis.c
1f2507
@@ -13,6 +13,15 @@
1f2507
 #include "sff-common.h"
1f2507
 #include "cmis.h"
1f2507
 
1f2507
+struct cmis_memory_map {
1f2507
+	const __u8 *lower_memory;
1f2507
+	const __u8 *upper_memory[1][2];	/* Bank, Page */
1f2507
+#define page_00h upper_memory[0x0][0x0]
1f2507
+#define page_01h upper_memory[0x0][0x1]
1f2507
+};
1f2507
+
1f2507
+#define CMIS_PAGE_SIZE		0x80
1f2507
+
1f2507
 static void cmis_show_identifier(const __u8 *id)
1f2507
 {
1f2507
 	sff8024_show_identifier(id, CMIS_ID_OFFSET);
1f2507
@@ -326,8 +335,34 @@ static void cmis_show_vendor_info(const __u8 *id)
1f2507
 			       "CLEI code");
1f2507
 }
1f2507
 
1f2507
+static void cmis_memory_map_init_buf(struct cmis_memory_map *map,
1f2507
+				     const __u8 *id)
1f2507
+{
1f2507
+	/* Lower Memory and Page 00h are always present.
1f2507
+	 *
1f2507
+	 * Offset into Upper Memory is between page size and twice the page
1f2507
+	 * size. Therefore, set the base address of each page to base address
1f2507
+	 * plus page size multiplied by the page number.
1f2507
+	 */
1f2507
+	map->lower_memory = id;
1f2507
+	map->page_00h = id;
1f2507
+
1f2507
+	/* Page 01h is only present when the module memory model is paged and
1f2507
+	 * not flat.
1f2507
+	 */
1f2507
+	if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
1f2507
+	    CMIS_MEMORY_MODEL_MASK)
1f2507
+		return;
1f2507
+
1f2507
+	map->page_01h = id + CMIS_PAGE_SIZE;
1f2507
+}
1f2507
+
1f2507
 void cmis_show_all_ioctl(const __u8 *id)
1f2507
 {
1f2507
+	struct cmis_memory_map map = {};
1f2507
+
1f2507
+	cmis_memory_map_init_buf(&map, id);
1f2507
+
1f2507
 	cmis_show_identifier(id);
1f2507
 	cmis_show_power_info(id);
1f2507
 	cmis_show_connector(id);
1f2507
@@ -340,10 +375,38 @@ void cmis_show_all_ioctl(const __u8 *id)
1f2507
 	cmis_show_rev_compliance(id);
1f2507
 }
1f2507
 
1f2507
+static void
1f2507
+cmis_memory_map_init_pages(struct cmis_memory_map *map,
1f2507
+			   const struct ethtool_module_eeprom *page_zero,
1f2507
+			   const struct ethtool_module_eeprom *page_one)
1f2507
+{
1f2507
+	/* Lower Memory and Page 00h are always present.
1f2507
+	 *
1f2507
+	 * Offset into Upper Memory is between page size and twice the page
1f2507
+	 * size. Therefore, set the base address of each page to its base
1f2507
+	 * address minus page size. For Page 00h, this is the address of the
1f2507
+	 * Lower Memory.
1f2507
+	 */
1f2507
+	map->lower_memory = page_zero->data;
1f2507
+	map->page_00h = page_zero->data;
1f2507
+
1f2507
+	/* Page 01h is only present when the module memory model is paged and
1f2507
+	 * not flat.
1f2507
+	 */
1f2507
+	if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
1f2507
+	    CMIS_MEMORY_MODEL_MASK)
1f2507
+		return;
1f2507
+
1f2507
+	map->page_01h = page_one->data - CMIS_PAGE_SIZE;
1f2507
+}
1f2507
+
1f2507
 void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
1f2507
 		      const struct ethtool_module_eeprom *page_one)
1f2507
 {
1f2507
 	const __u8 *page_zero_data = page_zero->data;
1f2507
+	struct cmis_memory_map map = {};
1f2507
+
1f2507
+	cmis_memory_map_init_pages(&map, page_zero, page_one);
1f2507
 
1f2507
 	cmis_show_identifier(page_zero_data);
1f2507
 	cmis_show_power_info(page_zero_data);
1f2507
diff --git a/cmis.h b/cmis.h
1f2507
index 734b90f4ddb4..53cbb5f57127 100644
1f2507
--- a/cmis.h
1f2507
+++ b/cmis.h
1f2507
@@ -4,6 +4,8 @@
1f2507
 /* Identifier and revision compliance (Page 0) */
1f2507
 #define CMIS_ID_OFFSET				0x00
1f2507
 #define CMIS_REV_COMPLIANCE_OFFSET		0x01
1f2507
+#define CMIS_MEMORY_MODEL_OFFSET		0x02
1f2507
+#define CMIS_MEMORY_MODEL_MASK			0x80
1f2507
 
1f2507
 #define CMIS_MODULE_TYPE_OFFSET			0x55
1f2507
 #define CMIS_MT_MMF				0x01
1f2507
-- 
1f2507
2.35.1
1f2507