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