import ethtool-5.13-2.el8
This commit is contained in:
parent
ab73c57020
commit
d1431a3c10
@ -0,0 +1,110 @@
|
||||
From bb89624c1a62de701f87d7deb669e40586c920d2 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 14 Sep 2021 14:27:34 +0300
|
||||
Subject: [PATCH 01/35] sff-8636: Fix parsing of Page 03h in IOCTL path
|
||||
|
||||
The offset of Page 03h compared to the base address of the Lower Memory
|
||||
is 512 bytes. However, all the offsets to the page start at address 128,
|
||||
which is the address that separates Lower and Upper memory (see Figure
|
||||
6-1 in SFF-8636). Therefore, reading these offsets compared to the start
|
||||
of Page 03h results in incorrect memory accesses as can be seen in the
|
||||
output below.
|
||||
|
||||
Instead, pass Page 03h with the correct offset.
|
||||
|
||||
This is a temporary solution until SFF-8636 is refactored to use a
|
||||
memory map for parsing.
|
||||
|
||||
Before patch:
|
||||
|
||||
# ethtool -m swp13
|
||||
...
|
||||
Laser bias current high alarm threshold : 16.448 mA
|
||||
Laser bias current low alarm threshold : 16.500 mA
|
||||
Laser bias current high warning threshold : 16.480 mA
|
||||
Laser bias current low warning threshold : 61.538 mA
|
||||
Laser output power high alarm threshold : 1.2576 mW / 1.00 dBm
|
||||
Laser output power low alarm threshold : 1.0321 mW / 0.14 dBm
|
||||
Laser output power high warning threshold : 2.1318 mW / 3.29 dBm
|
||||
Laser output power low warning threshold : 2.0530 mW / 3.12 dBm
|
||||
Module temperature high alarm threshold : 0.00 degrees C / 32.00 degrees F
|
||||
Module temperature low alarm threshold : 0.00 degrees C / 32.00 degrees F
|
||||
Module temperature high warning threshold : 0.00 degrees C / 32.00 degrees F
|
||||
Module temperature low warning threshold : 0.00 degrees C / 32.00 degrees F
|
||||
Module voltage high alarm threshold : 0.2377 V
|
||||
Module voltage low alarm threshold : 2.5701 V
|
||||
Module voltage high warning threshold : 2.8276 V
|
||||
Module voltage low warning threshold : 2.6982 V
|
||||
Laser rx power high alarm threshold : 0.8224 mW / -0.85 dBm
|
||||
Laser rx power low alarm threshold : 0.8224 mW / -0.85 dBm
|
||||
Laser rx power high warning threshold : 0.8224 mW / -0.85 dBm
|
||||
Laser rx power low warning threshold : 0.8224 mW / -0.85 dBm
|
||||
|
||||
After patch:
|
||||
|
||||
# ethtool -m swp13
|
||||
...
|
||||
Laser bias current high alarm threshold : 8.500 mA
|
||||
Laser bias current low alarm threshold : 5.492 mA
|
||||
Laser bias current high warning threshold : 8.000 mA
|
||||
Laser bias current low warning threshold : 6.000 mA
|
||||
Laser output power high alarm threshold : 3.4673 mW / 5.40 dBm
|
||||
Laser output power low alarm threshold : 0.0724 mW / -11.40 dBm
|
||||
Laser output power high warning threshold : 1.7378 mW / 2.40 dBm
|
||||
Laser output power low warning threshold : 0.1445 mW / -8.40 dBm
|
||||
Module temperature high alarm threshold : 80.00 degrees C / 176.00 degrees F
|
||||
Module temperature low alarm threshold : -10.00 degrees C / 14.00 degrees F
|
||||
Module temperature high warning threshold : 70.00 degrees C / 158.00 degrees F
|
||||
Module temperature low warning threshold : 0.00 degrees C / 32.00 degrees F
|
||||
Module voltage high alarm threshold : 3.5000 V
|
||||
Module voltage low alarm threshold : 3.1000 V
|
||||
Module voltage high warning threshold : 3.4650 V
|
||||
Module voltage low warning threshold : 3.1350 V
|
||||
Laser rx power high alarm threshold : 3.4673 mW / 5.40 dBm
|
||||
Laser rx power low alarm threshold : 0.0467 mW / -13.31 dBm
|
||||
Laser rx power high warning threshold : 1.7378 mW / 2.40 dBm
|
||||
Laser rx power low warning threshold : 0.0933 mW / -10.30 dBm
|
||||
|
||||
The following AddressSanitizer report is fixed:
|
||||
|
||||
==44670==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x617000000320 at pc 0x00000047ad93 bp 0x7ffcb4dc0070 sp 0x7ffcb4dc0068
|
||||
READ of size 1 at 0x617000000320 thread T0
|
||||
#0 0x47ad92 in sff8636_dom_parse qsfp.c:683
|
||||
#1 0x47c5d6 in sff8636_show_dom qsfp.c:771
|
||||
#2 0x47d21f in sff8636_show_all qsfp.c:870
|
||||
#3 0x42130b in do_getmodule ethtool.c:4908
|
||||
#4 0x42a38a in main ethtool.c:6383
|
||||
#5 0x7f500bf421e1 in __libc_start_main (/lib64/libc.so.6+0x281e1)
|
||||
#6 0x40258d in _start (ethtool+0x40258d)
|
||||
|
||||
0x617000000320 is located 16 bytes to the right of 656-byte region [0x617000000080,0x617000000310)
|
||||
allocated by thread T0 here:
|
||||
#0 0x7f500c2d6527 in __interceptor_calloc (/lib64/libasan.so.6+0xab527)
|
||||
#1 0x420d8c in do_getmodule ethtool.c:4859
|
||||
#2 0x42a38a in main ethtool.c:6383
|
||||
#3 0x7f500bf421e1 in __libc_start_main (/lib64/libc.so.6+0x281e1)
|
||||
|
||||
SUMMARY: AddressSanitizer: heap-buffer-overflow qsfp.c:683 in sff8636_dom_parse
|
||||
|
||||
Fixes: fc47fdb7c364 ("ethtool: Refactor human-readable module EEPROM output for new API")
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 644fe148a5aa..e84226bc1554 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -867,7 +867,7 @@ void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
|
||||
(id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_PLUS) ||
|
||||
(id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP28)) {
|
||||
sff6836_show_page_zero(id);
|
||||
- sff8636_show_dom(id, id + SFF8636_PAGE03H_OFFSET, eeprom_len);
|
||||
+ sff8636_show_dom(id, id + 3 * 0x80, eeprom_len);
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,55 @@
|
||||
From 1c14a6d8ebad07bc6ff090164ca15ab7656e7167 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 14 Sep 2021 14:27:35 +0300
|
||||
Subject: [PATCH 02/35] cmis: Fix invalid memory access in IOCTL path
|
||||
|
||||
Page 01h is an optional page that is not available for flat memory
|
||||
modules. Trying to blindly access it results in the following report
|
||||
from AddressSanitizer [1].
|
||||
|
||||
Instead, pass the base address of the Lower Memory. This results in
|
||||
wrong information being parsed, but this never worked correctly since
|
||||
CMIS support first appeared in cited commit.
|
||||
|
||||
The information will be parsed correctly in a follow-up submission that
|
||||
reworks the EEPROM parsing code to use a memory map with pointers to
|
||||
individual pages instead of passing one large buffer.
|
||||
|
||||
[1]
|
||||
==968785==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6120000001d4 at pc 0x0000004806ee bp 0x7ffefbc977a0 sp 0x7ffefbc97798
|
||||
READ of size 1 at 0x6120000001d4 thread T0
|
||||
#0 0x4806ed in cmis_print_smf_cbl_len cmis.c:127
|
||||
#1 0x48113e in cmis_show_link_len_from_page cmis.c:279
|
||||
#2 0x4811e3 in cmis_show_link_len cmis.c:300
|
||||
#3 0x481358 in qsfp_dd_show_all cmis.c:336
|
||||
#4 0x47d190 in sff8636_show_all qsfp.c:861
|
||||
#5 0x42130b in do_getmodule ethtool.c:4908
|
||||
#6 0x42a38a in main ethtool.c:6383
|
||||
#7 0x7f11db6c51e1 in __libc_start_main (/lib64/libc.so.6+0x281e1)
|
||||
#8 0x40258d in _start (ethtool+0x40258d)
|
||||
|
||||
Address 0x6120000001d4 is a wild pointer.
|
||||
SUMMARY: AddressSanitizer: heap-buffer-overflow cmis.c:127 in cmis_print_smf_cbl_len
|
||||
|
||||
Fixes: 88ca347ef35a ("Add QSFP-DD support").
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index 361b721f332f..1a91e798e4b8 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -297,7 +297,7 @@ static void cmis_show_link_len_from_page(const __u8 *page_one_data)
|
||||
*/
|
||||
static void cmis_show_link_len(const __u8 *id)
|
||||
{
|
||||
- cmis_show_link_len_from_page(id + PAG01H_UPPER_OFFSET);
|
||||
+ cmis_show_link_len_from_page(id);
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,87 @@
|
||||
From 04d36d7c373db7069554a6d21ece628e2cf6b21c Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 14 Sep 2021 14:27:36 +0300
|
||||
Subject: [PATCH 03/35] netlink: eeprom: Fallback to IOCTL when a complete
|
||||
hex/raw dump is requested
|
||||
|
||||
The IOCTL backend provides a complete hex/raw dump of the module EEPROM
|
||||
contents:
|
||||
|
||||
# ethtool -m swp11 hex on | wc -l
|
||||
34
|
||||
|
||||
# ethtool -m swp11 raw on | wc -c
|
||||
512
|
||||
|
||||
With the netlink backend, only the first 128 bytes from I2C address 0x50
|
||||
are dumped:
|
||||
|
||||
# ethtool -m swp11 hex on | wc -l
|
||||
10
|
||||
|
||||
# ethtool -m swp11 raw on | wc -c
|
||||
128
|
||||
|
||||
The presence of optional / banked pages is unknown without parsing the
|
||||
EEPROM contents which is unavailable when pretty printing is disabled
|
||||
(i.e., configure --disable-pretty-dump). With the IOCTL backend, this
|
||||
parsing happens inside the kernel.
|
||||
|
||||
Therefore, when a complete hex/raw dump is requested, fallback to the
|
||||
IOCTL backend.
|
||||
|
||||
After the patch:
|
||||
|
||||
# ethtool -m swp11 hex on | wc -l
|
||||
34
|
||||
|
||||
# ethtool -m swp11 raw on | wc -c
|
||||
512
|
||||
|
||||
This avoids breaking users that are relying on current behavior.
|
||||
|
||||
If users want a hex/raw dump of optional/banked pages that are not
|
||||
returned with the IOCTL backend, they will be required to request these
|
||||
explicitly via the netlink backend. For example:
|
||||
|
||||
# ethtool -m swp11 hex on page 0x2
|
||||
|
||||
This is desirable as that way there is no ambiguity regarding the
|
||||
location of optional/banked pages in the dump.
|
||||
|
||||
Another way to implement the above would be to use the 'nlchk' callback
|
||||
added in commit 67a9ef551661 ("ethtool: add nlchk for redirecting to
|
||||
netlink"). However, it is called before the netlink instance is
|
||||
initialized and before the command line parameters are parsed via
|
||||
nl_parser().
|
||||
|
||||
Fixes: 25b64c66f58d ("ethtool: Add netlink handler for getmodule (-m)")
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
netlink/module-eeprom.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index 38e7d2cd6cf3..e9a122df3259 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -365,6 +365,16 @@ int nl_getmodule(struct cmd_context *ctx)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ /* When complete hex/raw dump of the EEPROM is requested, fallback to
|
||||
+ * ioctl. Netlink can only request specific pages.
|
||||
+ */
|
||||
+ if ((getmodule_cmd_params.dump_hex || getmodule_cmd_params.dump_raw) &&
|
||||
+ !getmodule_cmd_params.page && !getmodule_cmd_params.bank &&
|
||||
+ !getmodule_cmd_params.i2c_address) {
|
||||
+ nlctx->ioctl_fallback = true;
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
request.i2c_address = ETH_I2C_ADDRESS_LOW;
|
||||
request.length = 128;
|
||||
ret = page_fetch(nlctx, &request);
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,84 @@
|
||||
From 3960c91ade7b1ca9979eec5200a90dc11f339cfd Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 14 Sep 2021 14:27:37 +0300
|
||||
Subject: [PATCH 04/35] ethtool: Fix compilation warning when pretty dump is
|
||||
disabled
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When pretty dump is disabled (i.e., configure --disable-pretty-dump),
|
||||
gcc 11.2.1 emits the following warning:
|
||||
|
||||
ethtool.c: In function ‘dump_regs’:
|
||||
ethtool.c:1160:31: warning: comparison is always false due to limited range of data type [-Wtype-limits]
|
||||
1160 | for (i = 0; i < ARRAY_SIZE(driver_list); i++)
|
||||
| ^
|
||||
|
||||
Fix it by avoiding iterating over 'driver_list' when pretty dump is
|
||||
disabled.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
ethtool.c | 13 ++++++++-----
|
||||
1 file changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ethtool.c b/ethtool.c
|
||||
index 33a0a492cb15..1b79e9f8d958 100644
|
||||
--- a/ethtool.c
|
||||
+++ b/ethtool.c
|
||||
@@ -1089,12 +1089,12 @@ static int parse_hkey(char **rss_hkey, u32 key_size,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
static const struct {
|
||||
const char *name;
|
||||
int (*func)(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
|
||||
|
||||
} driver_list[] = {
|
||||
-#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
{ "8139cp", realtek_dump_regs },
|
||||
{ "8139too", realtek_dump_regs },
|
||||
{ "r8169", realtek_dump_regs },
|
||||
@@ -1129,8 +1129,8 @@ static const struct {
|
||||
{ "fec", fec_dump_regs },
|
||||
{ "igc", igc_dump_regs },
|
||||
{ "bnxt_en", bnxt_dump_regs },
|
||||
-#endif
|
||||
};
|
||||
+#endif
|
||||
|
||||
void dump_hex(FILE *file, const u8 *data, int len, int offset)
|
||||
{
|
||||
@@ -1149,14 +1149,15 @@ void dump_hex(FILE *file, const u8 *data, int len, int offset)
|
||||
static int dump_regs(int gregs_dump_raw, int gregs_dump_hex,
|
||||
struct ethtool_drvinfo *info, struct ethtool_regs *regs)
|
||||
{
|
||||
- unsigned int i;
|
||||
-
|
||||
if (gregs_dump_raw) {
|
||||
fwrite(regs->data, regs->len, 1, stdout);
|
||||
goto nested;
|
||||
}
|
||||
|
||||
- if (!gregs_dump_hex)
|
||||
+#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
+ if (!gregs_dump_hex) {
|
||||
+ unsigned int i;
|
||||
+
|
||||
for (i = 0; i < ARRAY_SIZE(driver_list); i++)
|
||||
if (!strncmp(driver_list[i].name, info->driver,
|
||||
ETHTOOL_BUSINFO_LEN)) {
|
||||
@@ -1168,6 +1169,8 @@ static int dump_regs(int gregs_dump_raw, int gregs_dump_hex,
|
||||
*/
|
||||
break;
|
||||
}
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
dump_hex(stdout, regs->data, regs->len, 0);
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,62 @@
|
||||
From 08d9f72f5e4ce12e2cc1fc47d1ffde9aa1326c8c Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 14 Sep 2021 14:27:38 +0300
|
||||
Subject: [PATCH 05/35] netlink: eeprom: Fix compilation when pretty dump is
|
||||
disabled
|
||||
|
||||
When pretty dump is disabled (i.e., configure --disable-pretty-dump),
|
||||
the following errors are emitted:
|
||||
|
||||
/usr/bin/ld: netlink/module-eeprom.o: in function `decoder_print':
|
||||
netlink/module-eeprom.c:330: undefined reference to `sff8636_show_all_paged'
|
||||
netlink/module-eeprom.c:334: undefined reference to `cmis_show_all'
|
||||
netlink/module-eeprom.c:325: undefined reference to `sff8079_show_all'
|
||||
|
||||
The else clause is unreachable when pretty dump is disabled, so wrap it
|
||||
with ifdef directive.
|
||||
|
||||
This will be re-worked in future patches where the netlink code only
|
||||
queries the SFF-8024 Identifier Value and defers page requests to
|
||||
individual parsers.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
netlink/module-eeprom.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index e9a122df3259..48cd2cc55bee 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -275,6 +275,7 @@ static int page_fetch(struct nl_context *nlctx, const struct ethtool_module_eepr
|
||||
return nlsock_process_reply(nlsock, nomsg_reply_cb, NULL);
|
||||
}
|
||||
|
||||
+#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
static int decoder_prefetch(struct nl_context *nlctx)
|
||||
{
|
||||
struct ethtool_module_eeprom *page_zero_lower = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
|
||||
@@ -338,6 +339,7 @@ static void decoder_print(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
int nl_getmodule(struct cmd_context *ctx)
|
||||
{
|
||||
@@ -414,10 +416,12 @@ int nl_getmodule(struct cmd_context *ctx)
|
||||
else
|
||||
dump_hex(stdout, eeprom_data, dump_length, request.offset);
|
||||
} else {
|
||||
+#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
ret = decoder_prefetch(nlctx);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
decoder_print();
|
||||
+#endif
|
||||
}
|
||||
|
||||
cleanup:
|
||||
--
|
||||
2.35.1
|
||||
|
66
SOURCES/0006-cmis-Fix-CLEI-code-parsing.patch
Normal file
66
SOURCES/0006-cmis-Fix-CLEI-code-parsing.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From 5b46ca06c9888c663a74bdd804b0ecb7199cfb62 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Fri, 1 Oct 2021 18:06:21 +0300
|
||||
Subject: [PATCH 06/35] cmis: Fix CLEI code parsing
|
||||
|
||||
In CMIS, unlike SFF-8636, there is no presence indication for the CLEI
|
||||
code (Common Language Equipment Identification) field. The field is
|
||||
always present, but might not be supported. In which case, "a value of
|
||||
all ASCII 20h (spaces) shall be entered".
|
||||
|
||||
Therefore, remove the erroneous check which seems to be influenced from
|
||||
SFF-8636 and only print the string if it is supported and has a non-zero
|
||||
length.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 8 +++++---
|
||||
cmis.h | 4 ++--
|
||||
2 files changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index 1a91e798e4b8..499355d0e024 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -307,6 +307,8 @@ static void cmis_show_link_len(const __u8 *id)
|
||||
*/
|
||||
static void cmis_show_vendor_info(const __u8 *id)
|
||||
{
|
||||
+ const char *clei = (const char *)(id + CMIS_CLEI_START_OFFSET);
|
||||
+
|
||||
sff_show_ascii(id, CMIS_VENDOR_NAME_START_OFFSET,
|
||||
CMIS_VENDOR_NAME_END_OFFSET, "Vendor name");
|
||||
cmis_show_oui(id);
|
||||
@@ -319,9 +321,9 @@ static void cmis_show_vendor_info(const __u8 *id)
|
||||
sff_show_ascii(id, CMIS_DATE_YEAR_OFFSET,
|
||||
CMIS_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
|
||||
|
||||
- if (id[CMIS_CLEI_PRESENT_BYTE] & CMIS_CLEI_PRESENT_MASK)
|
||||
- sff_show_ascii(id, CMIS_CLEI_START_OFFSET,
|
||||
- CMIS_CLEI_END_OFFSET, "CLEI code");
|
||||
+ if (*clei && strncmp(clei, CMIS_CLEI_BLANK, CMIS_CLEI_LEN))
|
||||
+ sff_show_ascii(id, CMIS_CLEI_START_OFFSET, CMIS_CLEI_END_OFFSET,
|
||||
+ "CLEI code");
|
||||
}
|
||||
|
||||
void qsfp_dd_show_all(const __u8 *id)
|
||||
diff --git a/cmis.h b/cmis.h
|
||||
index 78ee1495bc33..cfac08f42904 100644
|
||||
--- a/cmis.h
|
||||
+++ b/cmis.h
|
||||
@@ -34,10 +34,10 @@
|
||||
#define CMIS_DATE_VENDOR_LOT_OFFSET 0xBC
|
||||
|
||||
/* CLEI Code (Page 0) */
|
||||
-#define CMIS_CLEI_PRESENT_BYTE 0x02
|
||||
-#define CMIS_CLEI_PRESENT_MASK 0x20
|
||||
#define CMIS_CLEI_START_OFFSET 0xBE
|
||||
#define CMIS_CLEI_END_OFFSET 0xC7
|
||||
+#define CMIS_CLEI_BLANK " "
|
||||
+#define CMIS_CLEI_LEN 0x0A
|
||||
|
||||
/* Cable assembly length */
|
||||
#define CMIS_CBL_ASM_LEN_OFFSET 0xCA
|
||||
--
|
||||
2.35.1
|
||||
|
42
SOURCES/0007-cmis-Fix-wrong-define-name.patch
Normal file
42
SOURCES/0007-cmis-Fix-wrong-define-name.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From a934091a0b42cd7c71c9e71a235e57af718c9952 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Fri, 1 Oct 2021 18:06:22 +0300
|
||||
Subject: [PATCH 07/35] cmis: Fix wrong define name
|
||||
|
||||
Offset 0x10 in the Lower Memory stores the "VccMonVoltage".
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 2 +-
|
||||
cmis.h | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index 499355d0e024..408db6f26c3b 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -271,7 +271,7 @@ static void cmis_show_mod_lvl_monitors(const __u8 *id)
|
||||
PRINT_TEMP("Module temperature",
|
||||
OFFSET_TO_TEMP(CMIS_CURR_TEMP_OFFSET));
|
||||
PRINT_VCC("Module voltage",
|
||||
- OFFSET_TO_U16(CMIS_CURR_CURR_OFFSET));
|
||||
+ OFFSET_TO_U16(CMIS_CURR_VCC_OFFSET));
|
||||
}
|
||||
|
||||
static void cmis_show_link_len_from_page(const __u8 *page_one_data)
|
||||
diff --git a/cmis.h b/cmis.h
|
||||
index cfac08f42904..e3012ccfdd79 100644
|
||||
--- a/cmis.h
|
||||
+++ b/cmis.h
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/* Module-Level Monitors (Page 0) */
|
||||
#define CMIS_CURR_TEMP_OFFSET 0x0E
|
||||
-#define CMIS_CURR_CURR_OFFSET 0x10
|
||||
+#define CMIS_CURR_VCC_OFFSET 0x10
|
||||
|
||||
#define CMIS_CTOR_OFFSET 0xCB
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
29
SOURCES/0008-cmis-Correct-comment.patch
Normal file
29
SOURCES/0008-cmis-Correct-comment.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From 030ba06f12761d13722a12773bb8063748242b50 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Fri, 1 Oct 2021 18:06:23 +0300
|
||||
Subject: [PATCH 08/35] cmis: Correct comment
|
||||
|
||||
The file is concerned with CMIS support, not QSFP-DD which is the
|
||||
physical form factor.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index 408db6f26c3b..591cc72953b7 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Description:
|
||||
*
|
||||
- * This module adds QSFP-DD support to ethtool. The changes are similar to
|
||||
+ * This module adds CMIS support to ethtool. The changes are similar to
|
||||
* the ones already existing in qsfp.c, but customized to use the memory
|
||||
* addresses and logic as defined in the specification's document.
|
||||
*
|
||||
--
|
||||
2.35.1
|
||||
|
30
SOURCES/0009-sff-8636-Remove-incorrect-comment.patch
Normal file
30
SOURCES/0009-sff-8636-Remove-incorrect-comment.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From f1b4bafbb30e77fedb10a23d1b70119b9059f684 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Fri, 1 Oct 2021 18:06:24 +0300
|
||||
Subject: [PATCH 09/35] sff-8636: Remove incorrect comment
|
||||
|
||||
The comment was copied from SFF-8472 (i.e., sfpdiag.c) where the
|
||||
diagnostic page is at I2C address 0x51. SFF-8636 only uses I2C address
|
||||
0x50.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index e84226bc1554..263cf188377d 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
static struct sff8636_aw_flags {
|
||||
const char *str; /* Human-readable string, null at the end */
|
||||
- int offset; /* A2-relative address offset */
|
||||
+ int offset;
|
||||
__u8 value; /* Alarm is on if (offset & value) != 0. */
|
||||
} sff8636_aw_flags[] = {
|
||||
{ "Laser bias current high alarm (Chan 1)",
|
||||
--
|
||||
2.35.1
|
||||
|
48
SOURCES/0010-sff-8636-Fix-incorrect-function-name.patch
Normal file
48
SOURCES/0010-sff-8636-Fix-incorrect-function-name.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From dc4a75242e8674da02a579e6c875ad4ac77a8c20 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Fri, 1 Oct 2021 18:06:25 +0300
|
||||
Subject: [PATCH 10/35] sff-8636: Fix incorrect function name
|
||||
|
||||
The specification is called SFF-8636, not SFF-6836.
|
||||
|
||||
Rename the function accordingly.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 263cf188377d..3401db84352d 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -820,7 +820,7 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
|
||||
}
|
||||
|
||||
|
||||
-static void sff6836_show_page_zero(const __u8 *id)
|
||||
+static void sff8636_show_page_zero(const __u8 *id)
|
||||
{
|
||||
sff8636_show_ext_identifier(id);
|
||||
sff8636_show_connector(id);
|
||||
@@ -866,7 +866,7 @@ void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
|
||||
if ((id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP) ||
|
||||
(id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_PLUS) ||
|
||||
(id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP28)) {
|
||||
- sff6836_show_page_zero(id);
|
||||
+ sff8636_show_page_zero(id);
|
||||
sff8636_show_dom(id, id + 3 * 0x80, eeprom_len);
|
||||
}
|
||||
}
|
||||
@@ -875,7 +875,7 @@ void sff8636_show_all_paged(const struct ethtool_module_eeprom *page_zero,
|
||||
const struct ethtool_module_eeprom *page_three)
|
||||
{
|
||||
sff8636_show_identifier(page_zero->data);
|
||||
- sff6836_show_page_zero(page_zero->data);
|
||||
+ sff8636_show_page_zero(page_zero->data);
|
||||
if (page_three)
|
||||
sff8636_show_dom(page_zero->data, page_three->data - 0x80,
|
||||
ETH_MODULE_SFF_8636_MAX_LEN);
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,37 @@
|
||||
From 9d6316a62b6ab24dfd3cb800841df7fbbdc648ae Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Fri, 1 Oct 2021 18:06:26 +0300
|
||||
Subject: [PATCH 11/35] sff-8636: Convert if statement to switch-case
|
||||
|
||||
The indentation is wrong and the statement can be more clearly
|
||||
represented using a switch-case statement. Convert it.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 3401db84352d..d1464cb50fdc 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -863,11 +863,13 @@ void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
|
||||
}
|
||||
|
||||
sff8636_show_identifier(id);
|
||||
- if ((id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP) ||
|
||||
- (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_PLUS) ||
|
||||
- (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP28)) {
|
||||
+ switch (id[SFF8636_ID_OFFSET]) {
|
||||
+ case SFF8024_ID_QSFP:
|
||||
+ case SFF8024_ID_QSFP_PLUS:
|
||||
+ case SFF8024_ID_QSFP28:
|
||||
sff8636_show_page_zero(id);
|
||||
sff8636_show_dom(id, id + 3 * 0x80, eeprom_len);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
35
SOURCES/0012-sff-8636-Remove-extra-blank-lines.patch
Normal file
35
SOURCES/0012-sff-8636-Remove-extra-blank-lines.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 539a255fab8401a197e2a98c0c3dd39800ca65e5 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Fri, 1 Oct 2021 18:06:27 +0300
|
||||
Subject: [PATCH 12/35] sff-8636: Remove extra blank lines
|
||||
|
||||
Not needed, so remove them.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index d1464cb50fdc..3f37f1036e96 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -738,7 +738,6 @@ static void sff8636_dom_parse(const __u8 *id, const __u8 *page_three, struct sff
|
||||
sd->scd[i].rx_power = OFFSET_TO_U16(rx_power_offset);
|
||||
sd->scd[i].tx_power = OFFSET_TO_U16(tx_power_offset);
|
||||
}
|
||||
-
|
||||
}
|
||||
|
||||
static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eeprom_len)
|
||||
@@ -819,7 +818,6 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
|
||||
}
|
||||
}
|
||||
|
||||
-
|
||||
static void sff8636_show_page_zero(const __u8 *id)
|
||||
{
|
||||
sff8636_show_ext_identifier(id);
|
||||
--
|
||||
2.35.1
|
||||
|
95
SOURCES/0013-cmis-Rename-CMIS-parsing-functions.patch
Normal file
95
SOURCES/0013-cmis-Rename-CMIS-parsing-functions.patch
Normal file
@ -0,0 +1,95 @@
|
||||
From 56c6dc7ab5f9170c6d399c12a87bbdb4c8de8958 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:12 +0300
|
||||
Subject: [PATCH 13/35] cmis: Rename CMIS parsing functions
|
||||
|
||||
Currently, there are two CMIS parsing functions. qsfp_dd_show_all() and
|
||||
cmis_show_all(). The former is called from the IOCTL path with a buffer
|
||||
containing EEPROM contents and the latter is called from the netlink
|
||||
path with pointer to individual EEPROM pages.
|
||||
|
||||
Rename them with '_ioctl' and '_nl' suffixes to make the distinction
|
||||
clear.
|
||||
|
||||
In subsequent patches, these two functions will only differ in the way
|
||||
they initialize the CMIS memory map for parsing, while the parsing code
|
||||
itself will be shared between the two.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 6 +++---
|
||||
cmis.h | 6 +++---
|
||||
netlink/module-eeprom.c | 2 +-
|
||||
qsfp.c | 2 +-
|
||||
4 files changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index 591cc72953b7..68c5b2d3277b 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -326,7 +326,7 @@ static void cmis_show_vendor_info(const __u8 *id)
|
||||
"CLEI code");
|
||||
}
|
||||
|
||||
-void qsfp_dd_show_all(const __u8 *id)
|
||||
+void cmis_show_all_ioctl(const __u8 *id)
|
||||
{
|
||||
cmis_show_identifier(id);
|
||||
cmis_show_power_info(id);
|
||||
@@ -340,8 +340,8 @@ void qsfp_dd_show_all(const __u8 *id)
|
||||
cmis_show_rev_compliance(id);
|
||||
}
|
||||
|
||||
-void cmis_show_all(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_one)
|
||||
+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;
|
||||
|
||||
diff --git a/cmis.h b/cmis.h
|
||||
index e3012ccfdd79..734b90f4ddb4 100644
|
||||
--- a/cmis.h
|
||||
+++ b/cmis.h
|
||||
@@ -120,9 +120,9 @@
|
||||
#define YESNO(x) (((x) != 0) ? "Yes" : "No")
|
||||
#define ONOFF(x) (((x) != 0) ? "On" : "Off")
|
||||
|
||||
-void qsfp_dd_show_all(const __u8 *id);
|
||||
+void cmis_show_all_ioctl(const __u8 *id);
|
||||
|
||||
-void cmis_show_all(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_one);
|
||||
+void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
+ const struct ethtool_module_eeprom *page_one);
|
||||
|
||||
#endif /* CMIS_H__ */
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index 48cd2cc55bee..fc4ef1a53aff 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -332,7 +332,7 @@ static void decoder_print(void)
|
||||
break;
|
||||
case SFF8024_ID_QSFP_DD:
|
||||
case SFF8024_ID_DSFP:
|
||||
- cmis_show_all(page_zero, page_one);
|
||||
+ cmis_show_all_nl(page_zero, page_one);
|
||||
break;
|
||||
default:
|
||||
dump_hex(stdout, page_zero->data, page_zero->length, page_zero->offset);
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 3f37f1036e96..27fdd3bd1771 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -856,7 +856,7 @@ static void sff8636_show_page_zero(const __u8 *id)
|
||||
void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
|
||||
{
|
||||
if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD) {
|
||||
- qsfp_dd_show_all(id);
|
||||
+ cmis_show_all_ioctl(id);
|
||||
return;
|
||||
}
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
145
SOURCES/0014-cmis-Initialize-CMIS-memory-map.patch
Normal file
145
SOURCES/0014-cmis-Initialize-CMIS-memory-map.patch
Normal file
@ -0,0 +1,145 @@
|
||||
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
|
||||
|
394
SOURCES/0015-cmis-Use-memory-map-during-parsing.patch
Normal file
394
SOURCES/0015-cmis-Use-memory-map-during-parsing.patch
Normal file
@ -0,0 +1,394 @@
|
||||
From 6e6aed12948d2d191660252a4be9bb33dc283bed Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:14 +0300
|
||||
Subject: [PATCH 15/35] cmis: Use memory map during parsing
|
||||
|
||||
Instead of passing one large buffer to the individual parsing functions,
|
||||
use the memory map structure from the previous patch.
|
||||
|
||||
This has the added benefit of checking which optional pages are actually
|
||||
available and it will also allow us to consolidate the IOCTL and netlink
|
||||
parsing code paths.
|
||||
|
||||
Tested by making sure that the only differences in output in both the
|
||||
IOCTL and netlink paths before and after the patch are in a few
|
||||
registers in Page 01h that were previously parsed from Page 00h.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 175 +++++++++++++++++++++++++++++----------------------------
|
||||
cmis.h | 1 -
|
||||
2 files changed, 88 insertions(+), 88 deletions(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index 8a6788416a00..2e01446b2315 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -22,19 +22,19 @@ struct cmis_memory_map {
|
||||
|
||||
#define CMIS_PAGE_SIZE 0x80
|
||||
|
||||
-static void cmis_show_identifier(const __u8 *id)
|
||||
+static void cmis_show_identifier(const struct cmis_memory_map *map)
|
||||
{
|
||||
- sff8024_show_identifier(id, CMIS_ID_OFFSET);
|
||||
+ sff8024_show_identifier(map->lower_memory, CMIS_ID_OFFSET);
|
||||
}
|
||||
|
||||
-static void cmis_show_connector(const __u8 *id)
|
||||
+static void cmis_show_connector(const struct cmis_memory_map *map)
|
||||
{
|
||||
- sff8024_show_connector(id, CMIS_CTOR_OFFSET);
|
||||
+ sff8024_show_connector(map->page_00h, CMIS_CTOR_OFFSET);
|
||||
}
|
||||
|
||||
-static void cmis_show_oui(const __u8 *id)
|
||||
+static void cmis_show_oui(const struct cmis_memory_map *map)
|
||||
{
|
||||
- sff8024_show_oui(id, CMIS_VENDOR_OUI_OFFSET);
|
||||
+ sff8024_show_oui(map->page_00h, CMIS_VENDOR_OUI_OFFSET);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,9 +42,9 @@ static void cmis_show_oui(const __u8 *id)
|
||||
* [1] CMIS Rev. 3, pag. 45, section 1.7.2.1, Table 18
|
||||
* [2] CMIS Rev. 4, pag. 81, section 8.2.1, Table 8-2
|
||||
*/
|
||||
-static void cmis_show_rev_compliance(const __u8 *id)
|
||||
+static void cmis_show_rev_compliance(const struct cmis_memory_map *map)
|
||||
{
|
||||
- __u8 rev = id[CMIS_REV_COMPLIANCE_OFFSET];
|
||||
+ __u8 rev = map->lower_memory[CMIS_REV_COMPLIANCE_OFFSET];
|
||||
int major = (rev >> 4) & 0x0F;
|
||||
int minor = rev & 0x0F;
|
||||
|
||||
@@ -58,17 +58,17 @@ static void cmis_show_rev_compliance(const __u8 *id)
|
||||
* [2] CMIS Rev. 4, pag. 94, section 8.3.9, Table 8-18
|
||||
* [3] QSFP-DD Hardware Rev 5.0, pag. 22, section 4.2.1
|
||||
*/
|
||||
-static void cmis_show_power_info(const __u8 *id)
|
||||
+static void cmis_show_power_info(const struct cmis_memory_map *map)
|
||||
{
|
||||
float max_power = 0.0f;
|
||||
__u8 base_power = 0;
|
||||
__u8 power_class;
|
||||
|
||||
/* Get the power class (first 3 most significat bytes) */
|
||||
- power_class = (id[CMIS_PWR_CLASS_OFFSET] >> 5) & 0x07;
|
||||
+ power_class = (map->page_00h[CMIS_PWR_CLASS_OFFSET] >> 5) & 0x07;
|
||||
|
||||
/* Get the base power in multiples of 0.25W */
|
||||
- base_power = id[CMIS_PWR_MAX_POWER_OFFSET];
|
||||
+ base_power = map->page_00h[CMIS_PWR_MAX_POWER_OFFSET];
|
||||
max_power = base_power * 0.25f;
|
||||
|
||||
printf("\t%-41s : %d\n", "Power class", power_class + 1);
|
||||
@@ -83,20 +83,20 @@ static void cmis_show_power_info(const __u8 *id)
|
||||
* [1] CMIS Rev. 3, pag. 59, section 1.7.3.10, Table 31
|
||||
* [2] CMIS Rev. 4, pag. 94, section 8.3.10, Table 8-19
|
||||
*/
|
||||
-static void cmis_show_cbl_asm_len(const __u8 *id)
|
||||
+static void cmis_show_cbl_asm_len(const struct cmis_memory_map *map)
|
||||
{
|
||||
static const char *fn = "Cable assembly length";
|
||||
float mul = 1.0f;
|
||||
float val = 0.0f;
|
||||
|
||||
/* Check if max length */
|
||||
- if (id[CMIS_CBL_ASM_LEN_OFFSET] == CMIS_6300M_MAX_LEN) {
|
||||
+ if (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] == CMIS_6300M_MAX_LEN) {
|
||||
printf("\t%-41s : > 6.3km\n", fn);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the multiplier from the first two bits */
|
||||
- switch (id[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
|
||||
+ switch (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
|
||||
case CMIS_MULTIPLIER_00:
|
||||
mul = 0.1f;
|
||||
break;
|
||||
@@ -114,7 +114,7 @@ static void cmis_show_cbl_asm_len(const __u8 *id)
|
||||
}
|
||||
|
||||
/* Get base value from first 6 bits and multiply by mul */
|
||||
- val = (id[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
|
||||
+ val = (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
|
||||
val = (float)val * mul;
|
||||
printf("\t%-41s : %0.2fm\n", fn, val);
|
||||
}
|
||||
@@ -126,14 +126,17 @@ static void cmis_show_cbl_asm_len(const __u8 *id)
|
||||
* [1] CMIS Rev. 3, pag. 63, section 1.7.4.2, Table 39
|
||||
* [2] CMIS Rev. 4, pag. 99, section 8.4.2, Table 8-27
|
||||
*/
|
||||
-static void cmis_print_smf_cbl_len(const __u8 *id)
|
||||
+static void cmis_print_smf_cbl_len(const struct cmis_memory_map *map)
|
||||
{
|
||||
static const char *fn = "Length (SMF)";
|
||||
float mul = 1.0f;
|
||||
float val = 0.0f;
|
||||
|
||||
+ if (!map->page_01h)
|
||||
+ return;
|
||||
+
|
||||
/* Get the multiplier from the first two bits */
|
||||
- switch (id[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
|
||||
+ switch (map->page_01h[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
|
||||
case CMIS_MULTIPLIER_00:
|
||||
mul = 0.1f;
|
||||
break;
|
||||
@@ -145,7 +148,7 @@ static void cmis_print_smf_cbl_len(const __u8 *id)
|
||||
}
|
||||
|
||||
/* Get base value from first 6 bits and multiply by mul */
|
||||
- val = (id[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
|
||||
+ val = (map->page_01h[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
|
||||
val = (float)val * mul;
|
||||
printf("\t%-41s : %0.2fkm\n", fn, val);
|
||||
}
|
||||
@@ -155,21 +158,24 @@ static void cmis_print_smf_cbl_len(const __u8 *id)
|
||||
* [1] CMIS Rev. 3, pag. 71, section 1.7.4.10, Table 46
|
||||
* [2] CMIS Rev. 4, pag. 105, section 8.4.10, Table 8-34
|
||||
*/
|
||||
-static void cmis_show_sig_integrity(const __u8 *id)
|
||||
+static void cmis_show_sig_integrity(const struct cmis_memory_map *map)
|
||||
{
|
||||
+ if (!map->page_01h)
|
||||
+ return;
|
||||
+
|
||||
/* CDR Bypass control: 2nd bit from each byte */
|
||||
printf("\t%-41s : ", "Tx CDR bypass control");
|
||||
- printf("%s\n", YESNO(id[CMIS_SIG_INTEG_TX_OFFSET] & 0x02));
|
||||
+ printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_TX_OFFSET] & 0x02));
|
||||
|
||||
printf("\t%-41s : ", "Rx CDR bypass control");
|
||||
- printf("%s\n", YESNO(id[CMIS_SIG_INTEG_RX_OFFSET] & 0x02));
|
||||
+ printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_RX_OFFSET] & 0x02));
|
||||
|
||||
/* CDR Implementation: 1st bit from each byte */
|
||||
printf("\t%-41s : ", "Tx CDR");
|
||||
- printf("%s\n", YESNO(id[CMIS_SIG_INTEG_TX_OFFSET] & 0x01));
|
||||
+ printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_TX_OFFSET] & 0x01));
|
||||
|
||||
printf("\t%-41s : ", "Rx CDR");
|
||||
- printf("%s\n", YESNO(id[CMIS_SIG_INTEG_RX_OFFSET] & 0x01));
|
||||
+ printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_RX_OFFSET] & 0x01));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,14 +188,14 @@ static void cmis_show_sig_integrity(const __u8 *id)
|
||||
* --> pag. 98, section 8.4, Table 8-25
|
||||
* --> page 100, section 8.4.3, 8.4.4
|
||||
*/
|
||||
-static void cmis_show_mit_compliance(const __u8 *id)
|
||||
+static void cmis_show_mit_compliance(const struct cmis_memory_map *map)
|
||||
{
|
||||
static const char *cc = " (Copper cable,";
|
||||
|
||||
printf("\t%-41s : 0x%02x", "Transmitter technology",
|
||||
- id[CMIS_MEDIA_INTF_TECH_OFFSET]);
|
||||
+ map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET]);
|
||||
|
||||
- switch (id[CMIS_MEDIA_INTF_TECH_OFFSET]) {
|
||||
+ switch (map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET]) {
|
||||
case CMIS_850_VCSEL:
|
||||
printf(" (850 nm VCSEL)\n");
|
||||
break;
|
||||
@@ -240,22 +246,22 @@ static void cmis_show_mit_compliance(const __u8 *id)
|
||||
break;
|
||||
}
|
||||
|
||||
- if (id[CMIS_MEDIA_INTF_TECH_OFFSET] >= CMIS_COPPER_UNEQUAL) {
|
||||
+ if (map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET] >= CMIS_COPPER_UNEQUAL) {
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 5GHz",
|
||||
- id[CMIS_COPPER_ATT_5GHZ]);
|
||||
+ map->page_00h[CMIS_COPPER_ATT_5GHZ]);
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 7GHz",
|
||||
- id[CMIS_COPPER_ATT_7GHZ]);
|
||||
+ map->page_00h[CMIS_COPPER_ATT_7GHZ]);
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 12.9GHz",
|
||||
- id[CMIS_COPPER_ATT_12P9GHZ]);
|
||||
+ map->page_00h[CMIS_COPPER_ATT_12P9GHZ]);
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 25.8GHz",
|
||||
- id[CMIS_COPPER_ATT_25P8GHZ]);
|
||||
- } else {
|
||||
+ map->page_00h[CMIS_COPPER_ATT_25P8GHZ]);
|
||||
+ } else if (map->page_01h) {
|
||||
printf("\t%-41s : %.3lfnm\n", "Laser wavelength",
|
||||
- (((id[CMIS_NOM_WAVELENGTH_MSB] << 8) |
|
||||
- id[CMIS_NOM_WAVELENGTH_LSB]) * 0.05));
|
||||
+ (((map->page_01h[CMIS_NOM_WAVELENGTH_MSB] << 8) |
|
||||
+ map->page_01h[CMIS_NOM_WAVELENGTH_LSB]) * 0.05));
|
||||
printf("\t%-41s : %.3lfnm\n", "Laser wavelength tolerance",
|
||||
- (((id[CMIS_WAVELENGTH_TOL_MSB] << 8) |
|
||||
- id[CMIS_WAVELENGTH_TOL_LSB]) * 0.005));
|
||||
+ (((map->page_01h[CMIS_WAVELENGTH_TOL_MSB] << 8) |
|
||||
+ map->page_01h[CMIS_WAVELENGTH_TOL_LSB]) * 0.005));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,28 +281,16 @@ static void cmis_show_mit_compliance(const __u8 *id)
|
||||
* [2] CMIS Rev. 4:
|
||||
* --> pag. 84, section 8.2.4, Table 8-6
|
||||
*/
|
||||
-static void cmis_show_mod_lvl_monitors(const __u8 *id)
|
||||
+static void cmis_show_mod_lvl_monitors(const struct cmis_memory_map *map)
|
||||
{
|
||||
+ const __u8 *id = map->lower_memory;
|
||||
+
|
||||
PRINT_TEMP("Module temperature",
|
||||
OFFSET_TO_TEMP(CMIS_CURR_TEMP_OFFSET));
|
||||
PRINT_VCC("Module voltage",
|
||||
OFFSET_TO_U16(CMIS_CURR_VCC_OFFSET));
|
||||
}
|
||||
|
||||
-static void cmis_show_link_len_from_page(const __u8 *page_one_data)
|
||||
-{
|
||||
- cmis_print_smf_cbl_len(page_one_data);
|
||||
- sff_show_value_with_unit(page_one_data, CMIS_OM5_LEN_OFFSET,
|
||||
- "Length (OM5)", 2, "m");
|
||||
- sff_show_value_with_unit(page_one_data, CMIS_OM4_LEN_OFFSET,
|
||||
- "Length (OM4)", 2, "m");
|
||||
- sff_show_value_with_unit(page_one_data, CMIS_OM3_LEN_OFFSET,
|
||||
- "Length (OM3 50/125um)", 2, "m");
|
||||
- sff_show_value_with_unit(page_one_data, CMIS_OM2_LEN_OFFSET,
|
||||
- "Length (OM2 50/125um)", 1, "m");
|
||||
-}
|
||||
-
|
||||
-
|
||||
/**
|
||||
* Print relevant info about the maximum supported fiber media length
|
||||
* for each type of fiber media at the maximum module-supported bit rate.
|
||||
@@ -304,9 +298,19 @@ static void cmis_show_link_len_from_page(const __u8 *page_one_data)
|
||||
* [1] CMIS Rev. 3, page 64, section 1.7.4.2, Table 39
|
||||
* [2] CMIS Rev. 4, page 99, section 8.4.2, Table 8-27
|
||||
*/
|
||||
-static void cmis_show_link_len(const __u8 *id)
|
||||
+static void cmis_show_link_len(const struct cmis_memory_map *map)
|
||||
{
|
||||
- cmis_show_link_len_from_page(id);
|
||||
+ cmis_print_smf_cbl_len(map);
|
||||
+ if (!map->page_01h)
|
||||
+ return;
|
||||
+ sff_show_value_with_unit(map->page_01h, CMIS_OM5_LEN_OFFSET,
|
||||
+ "Length (OM5)", 2, "m");
|
||||
+ sff_show_value_with_unit(map->page_01h, CMIS_OM4_LEN_OFFSET,
|
||||
+ "Length (OM4)", 2, "m");
|
||||
+ sff_show_value_with_unit(map->page_01h, CMIS_OM3_LEN_OFFSET,
|
||||
+ "Length (OM3 50/125um)", 2, "m");
|
||||
+ sff_show_value_with_unit(map->page_01h, CMIS_OM2_LEN_OFFSET,
|
||||
+ "Length (OM2 50/125um)", 1, "m");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,25 +318,26 @@ static void cmis_show_link_len(const __u8 *id)
|
||||
* [1] CMIS Rev. 3, page 56, section 1.7.3, Table 27
|
||||
* [2] CMIS Rev. 4, page 91, section 8.2, Table 8-15
|
||||
*/
|
||||
-static void cmis_show_vendor_info(const __u8 *id)
|
||||
+static void cmis_show_vendor_info(const struct cmis_memory_map *map)
|
||||
{
|
||||
- const char *clei = (const char *)(id + CMIS_CLEI_START_OFFSET);
|
||||
+ const char *clei;
|
||||
|
||||
- sff_show_ascii(id, CMIS_VENDOR_NAME_START_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, CMIS_VENDOR_NAME_START_OFFSET,
|
||||
CMIS_VENDOR_NAME_END_OFFSET, "Vendor name");
|
||||
- cmis_show_oui(id);
|
||||
- sff_show_ascii(id, CMIS_VENDOR_PN_START_OFFSET,
|
||||
+ cmis_show_oui(map);
|
||||
+ sff_show_ascii(map->page_00h, CMIS_VENDOR_PN_START_OFFSET,
|
||||
CMIS_VENDOR_PN_END_OFFSET, "Vendor PN");
|
||||
- sff_show_ascii(id, CMIS_VENDOR_REV_START_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, CMIS_VENDOR_REV_START_OFFSET,
|
||||
CMIS_VENDOR_REV_END_OFFSET, "Vendor rev");
|
||||
- sff_show_ascii(id, CMIS_VENDOR_SN_START_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, CMIS_VENDOR_SN_START_OFFSET,
|
||||
CMIS_VENDOR_SN_END_OFFSET, "Vendor SN");
|
||||
- sff_show_ascii(id, CMIS_DATE_YEAR_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, CMIS_DATE_YEAR_OFFSET,
|
||||
CMIS_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
|
||||
|
||||
+ clei = (const char *)(map->page_00h + CMIS_CLEI_START_OFFSET);
|
||||
if (*clei && strncmp(clei, CMIS_CLEI_BLANK, CMIS_CLEI_LEN))
|
||||
- sff_show_ascii(id, CMIS_CLEI_START_OFFSET, CMIS_CLEI_END_OFFSET,
|
||||
- "CLEI code");
|
||||
+ sff_show_ascii(map->page_00h, CMIS_CLEI_START_OFFSET,
|
||||
+ CMIS_CLEI_END_OFFSET, "CLEI code");
|
||||
}
|
||||
|
||||
static void cmis_memory_map_init_buf(struct cmis_memory_map *map,
|
||||
@@ -363,16 +368,16 @@ void cmis_show_all_ioctl(const __u8 *id)
|
||||
|
||||
cmis_memory_map_init_buf(&map, id);
|
||||
|
||||
- cmis_show_identifier(id);
|
||||
- cmis_show_power_info(id);
|
||||
- cmis_show_connector(id);
|
||||
- cmis_show_cbl_asm_len(id);
|
||||
- cmis_show_sig_integrity(id);
|
||||
- cmis_show_mit_compliance(id);
|
||||
- cmis_show_mod_lvl_monitors(id);
|
||||
- cmis_show_link_len(id);
|
||||
- cmis_show_vendor_info(id);
|
||||
- cmis_show_rev_compliance(id);
|
||||
+ cmis_show_identifier(&map);
|
||||
+ cmis_show_power_info(&map);
|
||||
+ cmis_show_connector(&map);
|
||||
+ cmis_show_cbl_asm_len(&map);
|
||||
+ cmis_show_sig_integrity(&map);
|
||||
+ cmis_show_mit_compliance(&map);
|
||||
+ cmis_show_mod_lvl_monitors(&map);
|
||||
+ cmis_show_link_len(&map);
|
||||
+ cmis_show_vendor_info(&map);
|
||||
+ cmis_show_rev_compliance(&map);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -403,22 +408,18 @@ cmis_memory_map_init_pages(struct cmis_memory_map *map,
|
||||
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);
|
||||
- cmis_show_connector(page_zero_data);
|
||||
- cmis_show_cbl_asm_len(page_zero_data);
|
||||
- cmis_show_sig_integrity(page_zero_data);
|
||||
- cmis_show_mit_compliance(page_zero_data);
|
||||
- cmis_show_mod_lvl_monitors(page_zero_data);
|
||||
-
|
||||
- if (page_one)
|
||||
- cmis_show_link_len_from_page(page_one->data - 0x80);
|
||||
-
|
||||
- cmis_show_vendor_info(page_zero_data);
|
||||
- cmis_show_rev_compliance(page_zero_data);
|
||||
+ cmis_show_identifier(&map);
|
||||
+ cmis_show_power_info(&map);
|
||||
+ cmis_show_connector(&map);
|
||||
+ cmis_show_cbl_asm_len(&map);
|
||||
+ cmis_show_sig_integrity(&map);
|
||||
+ cmis_show_mit_compliance(&map);
|
||||
+ cmis_show_mod_lvl_monitors(&map);
|
||||
+ cmis_show_link_len(&map);
|
||||
+ cmis_show_vendor_info(&map);
|
||||
+ cmis_show_rev_compliance(&map);
|
||||
}
|
||||
diff --git a/cmis.h b/cmis.h
|
||||
index 53cbb5f57127..c878e3bc5afd 100644
|
||||
--- a/cmis.h
|
||||
+++ b/cmis.h
|
||||
@@ -100,7 +100,6 @@
|
||||
* that are unique to active modules and cable assemblies.
|
||||
* GlobalOffset = 2 * 0x80 + LocalOffset
|
||||
*/
|
||||
-#define PAG01H_UPPER_OFFSET (0x02 * 0x80)
|
||||
|
||||
/* Supported Link Length (Page 1) */
|
||||
#define CMIS_SMF_LEN_OFFSET 0x84
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,77 @@
|
||||
From 284886fbb4a85103cd82d061ebe4d1c93730b783 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:15 +0300
|
||||
Subject: [PATCH 16/35] cmis: Consolidate code between IOCTL and netlink paths
|
||||
|
||||
Now that both the netlink and IOCTL paths use the same memory map
|
||||
structure for parsing, the code can be easily consolidated.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 38 ++++++++++++++++----------------------
|
||||
1 file changed, 16 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index 2e01446b2315..eb7791dd59df 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -340,6 +340,20 @@ static void cmis_show_vendor_info(const struct cmis_memory_map *map)
|
||||
CMIS_CLEI_END_OFFSET, "CLEI code");
|
||||
}
|
||||
|
||||
+static void cmis_show_all_common(const struct cmis_memory_map *map)
|
||||
+{
|
||||
+ cmis_show_identifier(map);
|
||||
+ cmis_show_power_info(map);
|
||||
+ cmis_show_connector(map);
|
||||
+ cmis_show_cbl_asm_len(map);
|
||||
+ cmis_show_sig_integrity(map);
|
||||
+ cmis_show_mit_compliance(map);
|
||||
+ cmis_show_mod_lvl_monitors(map);
|
||||
+ cmis_show_link_len(map);
|
||||
+ cmis_show_vendor_info(map);
|
||||
+ cmis_show_rev_compliance(map);
|
||||
+}
|
||||
+
|
||||
static void cmis_memory_map_init_buf(struct cmis_memory_map *map,
|
||||
const __u8 *id)
|
||||
{
|
||||
@@ -367,17 +381,7 @@ void cmis_show_all_ioctl(const __u8 *id)
|
||||
struct cmis_memory_map map = {};
|
||||
|
||||
cmis_memory_map_init_buf(&map, id);
|
||||
-
|
||||
- cmis_show_identifier(&map);
|
||||
- cmis_show_power_info(&map);
|
||||
- cmis_show_connector(&map);
|
||||
- cmis_show_cbl_asm_len(&map);
|
||||
- cmis_show_sig_integrity(&map);
|
||||
- cmis_show_mit_compliance(&map);
|
||||
- cmis_show_mod_lvl_monitors(&map);
|
||||
- cmis_show_link_len(&map);
|
||||
- cmis_show_vendor_info(&map);
|
||||
- cmis_show_rev_compliance(&map);
|
||||
+ cmis_show_all_common(&map);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -411,15 +415,5 @@ void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
struct cmis_memory_map map = {};
|
||||
|
||||
cmis_memory_map_init_pages(&map, page_zero, page_one);
|
||||
-
|
||||
- cmis_show_identifier(&map);
|
||||
- cmis_show_power_info(&map);
|
||||
- cmis_show_connector(&map);
|
||||
- cmis_show_cbl_asm_len(&map);
|
||||
- cmis_show_sig_integrity(&map);
|
||||
- cmis_show_mit_compliance(&map);
|
||||
- cmis_show_mod_lvl_monitors(&map);
|
||||
- cmis_show_link_len(&map);
|
||||
- cmis_show_vendor_info(&map);
|
||||
- cmis_show_rev_compliance(&map);
|
||||
+ cmis_show_all_common(&map);
|
||||
}
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,97 @@
|
||||
From a8419e965891901217756254e0ed1a3351b2a3cb Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:16 +0300
|
||||
Subject: [PATCH 17/35] sff-8636: Rename SFF-8636 parsing functions
|
||||
|
||||
Currently, there are two SFF-8636 parsing functions. sff8636_show_all()
|
||||
and sff8636_show_all_paged(). The former is called from the IOCTL path
|
||||
with a buffer containing EEPROM contents and the latter is called from
|
||||
the netlink path with pointer to individual EEPROM pages.
|
||||
|
||||
Rename them with '_ioctl' and '_nl' suffixes to make the distinction
|
||||
clear.
|
||||
|
||||
In subsequent patches, these two functions will only differ in the way
|
||||
they initialize the SFF-8636 memory map for parsing, while the parsing
|
||||
code itself will be shared between the two.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
ethtool.c | 4 ++--
|
||||
internal.h | 6 +++---
|
||||
netlink/module-eeprom.c | 2 +-
|
||||
qsfp.c | 6 +++---
|
||||
4 files changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/ethtool.c b/ethtool.c
|
||||
index 1b79e9f8d958..6c744ff84eb9 100644
|
||||
--- a/ethtool.c
|
||||
+++ b/ethtool.c
|
||||
@@ -4908,8 +4908,8 @@ static int do_getmodule(struct cmd_context *ctx)
|
||||
break;
|
||||
case ETH_MODULE_SFF_8436:
|
||||
case ETH_MODULE_SFF_8636:
|
||||
- sff8636_show_all(eeprom->data,
|
||||
- modinfo.eeprom_len);
|
||||
+ sff8636_show_all_ioctl(eeprom->data,
|
||||
+ modinfo.eeprom_len);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
diff --git a/internal.h b/internal.h
|
||||
index 33e619b3ac53..7ca6066d4e12 100644
|
||||
--- a/internal.h
|
||||
+++ b/internal.h
|
||||
@@ -390,9 +390,9 @@ void sff8079_show_all(const __u8 *id);
|
||||
void sff8472_show_all(const __u8 *id);
|
||||
|
||||
/* QSFP Optics diagnostics */
|
||||
-void sff8636_show_all(const __u8 *id, __u32 eeprom_len);
|
||||
-void sff8636_show_all_paged(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_three);
|
||||
+void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len);
|
||||
+void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
+ const struct ethtool_module_eeprom *page_three);
|
||||
|
||||
/* FUJITSU Extended Socket network device */
|
||||
int fjes_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index fc4ef1a53aff..18b1abbe1252 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -328,7 +328,7 @@ static void decoder_print(void)
|
||||
case SFF8024_ID_QSFP:
|
||||
case SFF8024_ID_QSFP28:
|
||||
case SFF8024_ID_QSFP_PLUS:
|
||||
- sff8636_show_all_paged(page_zero, page_three);
|
||||
+ sff8636_show_all_nl(page_zero, page_three);
|
||||
break;
|
||||
case SFF8024_ID_QSFP_DD:
|
||||
case SFF8024_ID_DSFP:
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 27fdd3bd1771..dc6407d3ef6f 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -853,7 +853,7 @@ static void sff8636_show_page_zero(const __u8 *id)
|
||||
|
||||
}
|
||||
|
||||
-void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
|
||||
+void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
{
|
||||
if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD) {
|
||||
cmis_show_all_ioctl(id);
|
||||
@@ -871,8 +871,8 @@ void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
|
||||
}
|
||||
}
|
||||
|
||||
-void sff8636_show_all_paged(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_three)
|
||||
+void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
+ const struct ethtool_module_eeprom *page_three)
|
||||
{
|
||||
sff8636_show_identifier(page_zero->data);
|
||||
sff8636_show_page_zero(page_zero->data);
|
||||
--
|
||||
2.35.1
|
||||
|
137
SOURCES/0018-sff-8636-Initialize-SFF-8636-memory-map.patch
Normal file
137
SOURCES/0018-sff-8636-Initialize-SFF-8636-memory-map.patch
Normal file
@ -0,0 +1,137 @@
|
||||
From c77b5adfb3f94762a08554d1b4d75f6cbd8a6abe Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:17 +0300
|
||||
Subject: [PATCH 18/35] sff-8636: Initialize SFF-8636 memory map
|
||||
|
||||
The SFF-8636 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 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, when
|
||||
needed.
|
||||
|
||||
[1] SFF-8636 Rev. 2.10a, pag. 30, section 6.1, Figure 6-1
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 65 insertions(+)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index dc6407d3ef6f..80000d40f6e8 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -60,6 +60,15 @@
|
||||
#include "qsfp.h"
|
||||
#include "cmis.h"
|
||||
|
||||
+struct sff8636_memory_map {
|
||||
+ const __u8 *lower_memory;
|
||||
+ const __u8 *upper_memory[4];
|
||||
+#define page_00h upper_memory[0x0]
|
||||
+#define page_03h upper_memory[0x3]
|
||||
+};
|
||||
+
|
||||
+#define SFF8636_PAGE_SIZE 0x80
|
||||
+
|
||||
#define MAX_DESC_SIZE 42
|
||||
|
||||
static struct sff8636_aw_flags {
|
||||
@@ -853,13 +862,40 @@ static void sff8636_show_page_zero(const __u8 *id)
|
||||
|
||||
}
|
||||
|
||||
+static void sff8636_memory_map_init_buf(struct sff8636_memory_map *map,
|
||||
+ const __u8 *id, __u32 eeprom_len)
|
||||
+{
|
||||
+ /* 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 03h is only present when the module memory model is paged and
|
||||
+ * not flat and when we got a big enough buffer from the kernel.
|
||||
+ */
|
||||
+ if (map->lower_memory[SFF8636_STATUS_2_OFFSET] &
|
||||
+ SFF8636_STATUS_PAGE_3_PRESENT ||
|
||||
+ eeprom_len != ETH_MODULE_SFF_8636_MAX_LEN)
|
||||
+ return;
|
||||
+
|
||||
+ map->page_03h = id + 3 * SFF8636_PAGE_SIZE;
|
||||
+}
|
||||
+
|
||||
void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
{
|
||||
+ struct sff8636_memory_map map = {};
|
||||
+
|
||||
if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD) {
|
||||
cmis_show_all_ioctl(id);
|
||||
return;
|
||||
}
|
||||
|
||||
+ sff8636_memory_map_init_buf(&map, id, eeprom_len);
|
||||
+
|
||||
sff8636_show_identifier(id);
|
||||
switch (id[SFF8636_ID_OFFSET]) {
|
||||
case SFF8024_ID_QSFP:
|
||||
@@ -871,9 +907,38 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+sff8636_memory_map_init_pages(struct sff8636_memory_map *map,
|
||||
+ const struct ethtool_module_eeprom *page_zero,
|
||||
+ const struct ethtool_module_eeprom *page_three)
|
||||
+{
|
||||
+ /* 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 03h is only present when the module memory model is paged and
|
||||
+ * not flat.
|
||||
+ */
|
||||
+ if (map->lower_memory[SFF8636_STATUS_2_OFFSET] &
|
||||
+ SFF8636_STATUS_PAGE_3_PRESENT)
|
||||
+ return;
|
||||
+
|
||||
+ map->page_03h = page_three->data - SFF8636_PAGE_SIZE;
|
||||
+}
|
||||
+
|
||||
void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
const struct ethtool_module_eeprom *page_three)
|
||||
{
|
||||
+ struct sff8636_memory_map map = {};
|
||||
+
|
||||
+ sff8636_memory_map_init_pages(&map, page_zero, page_three);
|
||||
+
|
||||
sff8636_show_identifier(page_zero->data);
|
||||
sff8636_show_page_zero(page_zero->data);
|
||||
if (page_three)
|
||||
--
|
||||
2.35.1
|
||||
|
607
SOURCES/0019-sff-8636-Use-memory-map-during-parsing.patch
Normal file
607
SOURCES/0019-sff-8636-Use-memory-map-during-parsing.patch
Normal file
@ -0,0 +1,607 @@
|
||||
From 85023fa5dd7e79ce46a92ab567b4b675c3145775 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:18 +0300
|
||||
Subject: [PATCH 19/35] sff-8636: Use memory map during parsing
|
||||
|
||||
Instead of passing one large buffer to the individual parsing functions,
|
||||
use the memory map structure from the previous patch.
|
||||
|
||||
This has the added benefit of checking which optional pages are actually
|
||||
available and it will also allow us to consolidate the IOCTL and netlink
|
||||
parsing code paths.
|
||||
|
||||
Tested by making sure that there are no differences in output in both
|
||||
the IOCTL and netlink paths before and after the patch.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 368 +++++++++++++++++++++++++++++++--------------------------
|
||||
1 file changed, 201 insertions(+), 167 deletions(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 80000d40f6e8..354b3b1ce9ff 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -205,20 +205,21 @@ static struct sff8636_aw_flags {
|
||||
{ NULL, 0, 0 },
|
||||
};
|
||||
|
||||
-static void sff8636_show_identifier(const __u8 *id)
|
||||
+static void sff8636_show_identifier(const struct sff8636_memory_map *map)
|
||||
{
|
||||
- sff8024_show_identifier(id, SFF8636_ID_OFFSET);
|
||||
+ sff8024_show_identifier(map->lower_memory, SFF8636_ID_OFFSET);
|
||||
}
|
||||
|
||||
-static void sff8636_show_ext_identifier(const __u8 *id)
|
||||
+static void sff8636_show_ext_identifier(const struct sff8636_memory_map *map)
|
||||
{
|
||||
printf("\t%-41s : 0x%02x\n", "Extended identifier",
|
||||
- id[SFF8636_EXT_ID_OFFSET]);
|
||||
+ map->page_00h[SFF8636_EXT_ID_OFFSET]);
|
||||
|
||||
static const char *pfx =
|
||||
"\tExtended identifier description :";
|
||||
|
||||
- switch (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_PWR_CLASS_MASK) {
|
||||
+ switch (map->page_00h[SFF8636_EXT_ID_OFFSET] &
|
||||
+ SFF8636_EXT_ID_PWR_CLASS_MASK) {
|
||||
case SFF8636_EXT_ID_PWR_CLASS_1:
|
||||
printf("%s 1.5W max. Power consumption\n", pfx);
|
||||
break;
|
||||
@@ -233,17 +234,18 @@ static void sff8636_show_ext_identifier(const __u8 *id)
|
||||
break;
|
||||
}
|
||||
|
||||
- if (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_TX_MASK)
|
||||
+ if (map->page_00h[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_TX_MASK)
|
||||
printf("%s CDR present in TX,", pfx);
|
||||
else
|
||||
printf("%s No CDR in TX,", pfx);
|
||||
|
||||
- if (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_RX_MASK)
|
||||
+ if (map->page_00h[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_RX_MASK)
|
||||
printf(" CDR present in RX\n");
|
||||
else
|
||||
printf(" No CDR in RX\n");
|
||||
|
||||
- switch (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_EPWR_CLASS_MASK) {
|
||||
+ switch (map->page_00h[SFF8636_EXT_ID_OFFSET] &
|
||||
+ SFF8636_EXT_ID_EPWR_CLASS_MASK) {
|
||||
case SFF8636_EXT_ID_PWR_CLASS_LEGACY:
|
||||
printf("%s", pfx);
|
||||
break;
|
||||
@@ -257,18 +259,19 @@ static void sff8636_show_ext_identifier(const __u8 *id)
|
||||
printf("%s 5.0W max. Power consumption, ", pfx);
|
||||
break;
|
||||
}
|
||||
- if (id[SFF8636_PWR_MODE_OFFSET] & SFF8636_HIGH_PWR_ENABLE)
|
||||
+ if (map->lower_memory[SFF8636_PWR_MODE_OFFSET] &
|
||||
+ SFF8636_HIGH_PWR_ENABLE)
|
||||
printf(" High Power Class (> 3.5 W) enabled\n");
|
||||
else
|
||||
printf(" High Power Class (> 3.5 W) not enabled\n");
|
||||
}
|
||||
|
||||
-static void sff8636_show_connector(const __u8 *id)
|
||||
+static void sff8636_show_connector(const struct sff8636_memory_map *map)
|
||||
{
|
||||
- sff8024_show_connector(id, SFF8636_CTOR_OFFSET);
|
||||
+ sff8024_show_connector(map->page_00h, SFF8636_CTOR_OFFSET);
|
||||
}
|
||||
|
||||
-static void sff8636_show_transceiver(const __u8 *id)
|
||||
+static void sff8636_show_transceiver(const struct sff8636_memory_map *map)
|
||||
{
|
||||
static const char *pfx =
|
||||
"\tTransceiver type :";
|
||||
@@ -276,33 +279,41 @@ static void sff8636_show_transceiver(const __u8 *id)
|
||||
printf("\t%-41s : 0x%02x 0x%02x 0x%02x " \
|
||||
"0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
|
||||
"Transceiver codes",
|
||||
- id[SFF8636_ETHERNET_COMP_OFFSET],
|
||||
- id[SFF8636_SONET_COMP_OFFSET],
|
||||
- id[SFF8636_SAS_COMP_OFFSET],
|
||||
- id[SFF8636_GIGE_COMP_OFFSET],
|
||||
- id[SFF8636_FC_LEN_OFFSET],
|
||||
- id[SFF8636_FC_TECH_OFFSET],
|
||||
- id[SFF8636_FC_TRANS_MEDIA_OFFSET],
|
||||
- id[SFF8636_FC_SPEED_OFFSET]);
|
||||
+ map->page_00h[SFF8636_ETHERNET_COMP_OFFSET],
|
||||
+ map->page_00h[SFF8636_SONET_COMP_OFFSET],
|
||||
+ map->page_00h[SFF8636_SAS_COMP_OFFSET],
|
||||
+ map->page_00h[SFF8636_GIGE_COMP_OFFSET],
|
||||
+ map->page_00h[SFF8636_FC_LEN_OFFSET],
|
||||
+ map->page_00h[SFF8636_FC_TECH_OFFSET],
|
||||
+ map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET],
|
||||
+ map->page_00h[SFF8636_FC_SPEED_OFFSET]);
|
||||
|
||||
/* 10G/40G Ethernet Compliance Codes */
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_10G_LRM)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_10G_LRM)
|
||||
printf("%s 10G Ethernet: 10G Base-LRM\n", pfx);
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_10G_LR)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_10G_LR)
|
||||
printf("%s 10G Ethernet: 10G Base-LR\n", pfx);
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_10G_SR)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_10G_SR)
|
||||
printf("%s 10G Ethernet: 10G Base-SR\n", pfx);
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_CR4)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_40G_CR4)
|
||||
printf("%s 40G Ethernet: 40G Base-CR4\n", pfx);
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_SR4)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_40G_SR4)
|
||||
printf("%s 40G Ethernet: 40G Base-SR4\n", pfx);
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_LR4)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_40G_LR4)
|
||||
printf("%s 40G Ethernet: 40G Base-LR4\n", pfx);
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_ACTIVE)
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_40G_ACTIVE)
|
||||
printf("%s 40G Ethernet: 40G Active Cable (XLPPI)\n", pfx);
|
||||
/* Extended Specification Compliance Codes from SFF-8024 */
|
||||
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_RSRVD) {
|
||||
- switch (id[SFF8636_OPTION_1_OFFSET]) {
|
||||
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
|
||||
+ SFF8636_ETHERNET_RSRVD) {
|
||||
+ switch (map->page_00h[SFF8636_OPTION_1_OFFSET]) {
|
||||
case SFF8636_ETHERNET_UNSPECIFIED:
|
||||
printf("%s (reserved or unknown)\n", pfx);
|
||||
break;
|
||||
@@ -493,113 +504,122 @@ static void sff8636_show_transceiver(const __u8 *id)
|
||||
}
|
||||
|
||||
/* SONET Compliance Codes */
|
||||
- if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_40G_OTN))
|
||||
+ if (map->page_00h[SFF8636_SONET_COMP_OFFSET] &
|
||||
+ (SFF8636_SONET_40G_OTN))
|
||||
printf("%s 40G OTN (OTU3B/OTU3C)\n", pfx);
|
||||
- if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_LR))
|
||||
+ if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_LR))
|
||||
printf("%s SONET: OC-48, long reach\n", pfx);
|
||||
- if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_IR))
|
||||
+ if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_IR))
|
||||
printf("%s SONET: OC-48, intermediate reach\n", pfx);
|
||||
- if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_SR))
|
||||
+ if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_SR))
|
||||
printf("%s SONET: OC-48, short reach\n", pfx);
|
||||
|
||||
/* SAS/SATA Compliance Codes */
|
||||
- if (id[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_6G))
|
||||
+ if (map->page_00h[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_6G))
|
||||
printf("%s SAS 6.0G\n", pfx);
|
||||
- if (id[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_3G))
|
||||
+ if (map->page_00h[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_3G))
|
||||
printf("%s SAS 3.0G\n", pfx);
|
||||
|
||||
/* Ethernet Compliance Codes */
|
||||
- if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_T)
|
||||
+ if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_T)
|
||||
printf("%s Ethernet: 1000BASE-T\n", pfx);
|
||||
- if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_CX)
|
||||
+ if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_CX)
|
||||
printf("%s Ethernet: 1000BASE-CX\n", pfx);
|
||||
- if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_LX)
|
||||
+ if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_LX)
|
||||
printf("%s Ethernet: 1000BASE-LX\n", pfx);
|
||||
- if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_SX)
|
||||
+ if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_SX)
|
||||
printf("%s Ethernet: 1000BASE-SX\n", pfx);
|
||||
|
||||
/* Fibre Channel link length */
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_VERY_LONG)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_VERY_LONG)
|
||||
printf("%s FC: very long distance (V)\n", pfx);
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_SHORT)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_SHORT)
|
||||
printf("%s FC: short distance (S)\n", pfx);
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_INT)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_INT)
|
||||
printf("%s FC: intermediate distance (I)\n", pfx);
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_LONG)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_LONG)
|
||||
printf("%s FC: long distance (L)\n", pfx);
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_MED)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_MED)
|
||||
printf("%s FC: medium distance (M)\n", pfx);
|
||||
|
||||
/* Fibre Channel transmitter technology */
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_LONG_LC)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_LONG_LC)
|
||||
printf("%s FC: Longwave laser (LC)\n", pfx);
|
||||
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_ELEC_INTER)
|
||||
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_ELEC_INTER)
|
||||
printf("%s FC: Electrical inter-enclosure (EL)\n", pfx);
|
||||
- if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_ELEC_INTRA)
|
||||
+ if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_ELEC_INTRA)
|
||||
printf("%s FC: Electrical intra-enclosure (EL)\n", pfx);
|
||||
- if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_SHORT_WO_OFC)
|
||||
+ if (map->page_00h[SFF8636_FC_TECH_OFFSET] &
|
||||
+ SFF8636_FC_TECH_SHORT_WO_OFC)
|
||||
printf("%s FC: Shortwave laser w/o OFC (SN)\n", pfx);
|
||||
- if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_SHORT_W_OFC)
|
||||
+ if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_SHORT_W_OFC)
|
||||
printf("%s FC: Shortwave laser with OFC (SL)\n", pfx);
|
||||
- if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_LONG_LL)
|
||||
+ if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_LONG_LL)
|
||||
printf("%s FC: Longwave laser (LL)\n", pfx);
|
||||
|
||||
/* Fibre Channel transmission media */
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_TW)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_TW)
|
||||
printf("%s FC: Twin Axial Pair (TW)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_TP)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_TP)
|
||||
printf("%s FC: Twisted Pair (TP)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_MI)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_MI)
|
||||
printf("%s FC: Miniature Coax (MI)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_TV)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_TV)
|
||||
printf("%s FC: Video Coax (TV)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_M6)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_M6)
|
||||
printf("%s FC: Multimode, 62.5m (M6)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_M5)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_M5)
|
||||
printf("%s FC: Multimode, 50m (M5)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_OM3)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_OM3)
|
||||
printf("%s FC: Multimode, 50um (OM3)\n", pfx);
|
||||
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_SM)
|
||||
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
|
||||
+ SFF8636_FC_TRANS_MEDIA_SM)
|
||||
printf("%s FC: Single Mode (SM)\n", pfx);
|
||||
|
||||
/* Fibre Channel speed */
|
||||
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1200_MBPS)
|
||||
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1200_MBPS)
|
||||
printf("%s FC: 1200 MBytes/sec\n", pfx);
|
||||
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_800_MBPS)
|
||||
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_800_MBPS)
|
||||
printf("%s FC: 800 MBytes/sec\n", pfx);
|
||||
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1600_MBPS)
|
||||
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1600_MBPS)
|
||||
printf("%s FC: 1600 MBytes/sec\n", pfx);
|
||||
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_400_MBPS)
|
||||
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_400_MBPS)
|
||||
printf("%s FC: 400 MBytes/sec\n", pfx);
|
||||
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_200_MBPS)
|
||||
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_200_MBPS)
|
||||
printf("%s FC: 200 MBytes/sec\n", pfx);
|
||||
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_100_MBPS)
|
||||
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_100_MBPS)
|
||||
printf("%s FC: 100 MBytes/sec\n", pfx);
|
||||
}
|
||||
|
||||
-static void sff8636_show_encoding(const __u8 *id)
|
||||
+static void sff8636_show_encoding(const struct sff8636_memory_map *map)
|
||||
{
|
||||
- sff8024_show_encoding(id, SFF8636_ENCODING_OFFSET, ETH_MODULE_SFF_8636);
|
||||
+ sff8024_show_encoding(map->page_00h, SFF8636_ENCODING_OFFSET,
|
||||
+ ETH_MODULE_SFF_8636);
|
||||
}
|
||||
|
||||
-static void sff8636_show_rate_identifier(const __u8 *id)
|
||||
+static void sff8636_show_rate_identifier(const struct sff8636_memory_map *map)
|
||||
{
|
||||
/* TODO: Need to fix rate select logic */
|
||||
printf("\t%-41s : 0x%02x\n", "Rate identifier",
|
||||
- id[SFF8636_EXT_RS_OFFSET]);
|
||||
+ map->page_00h[SFF8636_EXT_RS_OFFSET]);
|
||||
}
|
||||
|
||||
-static void sff8636_show_oui(const __u8 *id, int id_offset)
|
||||
-{
|
||||
- sff8024_show_oui(id, id_offset);
|
||||
-}
|
||||
-
|
||||
-static void sff8636_show_wavelength_or_copper_compliance(const __u8 *id)
|
||||
+static void
|
||||
+sff8636_show_wavelength_or_copper_compliance(const struct sff8636_memory_map *map)
|
||||
{
|
||||
printf("\t%-41s : 0x%02x", "Transmitter technology",
|
||||
- (id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK));
|
||||
+ map->page_00h[SFF8636_DEVICE_TECH_OFFSET] &
|
||||
+ SFF8636_TRANS_TECH_MASK);
|
||||
|
||||
- switch (id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK) {
|
||||
+ switch (map->page_00h[SFF8636_DEVICE_TECH_OFFSET] &
|
||||
+ SFF8636_TRANS_TECH_MASK) {
|
||||
case SFF8636_TRANS_850_VCSEL:
|
||||
printf(" (850 nm VCSEL)\n");
|
||||
break;
|
||||
@@ -650,31 +670,26 @@ static void sff8636_show_wavelength_or_copper_compliance(const __u8 *id)
|
||||
break;
|
||||
}
|
||||
|
||||
- if ((id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK)
|
||||
- >= SFF8636_TRANS_COPPER_PAS_UNEQUAL) {
|
||||
+ if ((map->page_00h[SFF8636_DEVICE_TECH_OFFSET] &
|
||||
+ SFF8636_TRANS_TECH_MASK) >= SFF8636_TRANS_COPPER_PAS_UNEQUAL) {
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 2.5GHz",
|
||||
- id[SFF8636_WAVELEN_HIGH_BYTE_OFFSET]);
|
||||
+ map->page_00h[SFF8636_WAVELEN_HIGH_BYTE_OFFSET]);
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 5.0GHz",
|
||||
- id[SFF8636_WAVELEN_LOW_BYTE_OFFSET]);
|
||||
+ map->page_00h[SFF8636_WAVELEN_LOW_BYTE_OFFSET]);
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 7.0GHz",
|
||||
- id[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET]);
|
||||
+ map->page_00h[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET]);
|
||||
printf("\t%-41s : %udb\n", "Attenuation at 12.9GHz",
|
||||
- id[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]);
|
||||
+ map->page_00h[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]);
|
||||
} else {
|
||||
printf("\t%-41s : %.3lfnm\n", "Laser wavelength",
|
||||
- (((id[SFF8636_WAVELEN_HIGH_BYTE_OFFSET] << 8) |
|
||||
- id[SFF8636_WAVELEN_LOW_BYTE_OFFSET])*0.05));
|
||||
+ (((map->page_00h[SFF8636_WAVELEN_HIGH_BYTE_OFFSET] << 8) |
|
||||
+ map->page_00h[SFF8636_WAVELEN_LOW_BYTE_OFFSET]) * 0.05));
|
||||
printf("\t%-41s : %.3lfnm\n", "Laser wavelength tolerance",
|
||||
- (((id[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET] << 8) |
|
||||
- id[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET])*0.005));
|
||||
+ (((map->page_00h[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET] << 8) |
|
||||
+ map->page_00h[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]) * 0.005));
|
||||
}
|
||||
}
|
||||
|
||||
-static void sff8636_show_revision_compliance(const __u8 *id)
|
||||
-{
|
||||
- sff_show_revision_compliance(id, SFF8636_REV_COMPLIANCE_OFFSET);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* 2-byte internal temperature conversions:
|
||||
* First byte is a signed 8-bit integer, which is the temp decimal part
|
||||
@@ -683,39 +698,65 @@ static void sff8636_show_revision_compliance(const __u8 *id)
|
||||
#define SFF8636_OFFSET_TO_TEMP(offset) ((__s16)OFFSET_TO_U16(offset))
|
||||
#define OFFSET_TO_U16_PTR(ptr, offset) (ptr[offset] << 8 | ptr[(offset) + 1])
|
||||
|
||||
-static void sff8636_dom_parse(const __u8 *id, const __u8 *page_three, struct sff_diags *sd)
|
||||
+static void sff8636_dom_parse(const struct sff8636_memory_map *map,
|
||||
+ struct sff_diags *sd)
|
||||
{
|
||||
+ const __u8 *id = map->lower_memory;
|
||||
int i = 0;
|
||||
|
||||
/* Monitoring Thresholds for Alarms and Warnings */
|
||||
sd->sfp_voltage[MCURR] = OFFSET_TO_U16_PTR(id, SFF8636_VCC_CURR);
|
||||
- sd->sfp_voltage[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_HALRM);
|
||||
- sd->sfp_voltage[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_LALRM);
|
||||
- sd->sfp_voltage[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_HWARN);
|
||||
- sd->sfp_voltage[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_LWARN);
|
||||
-
|
||||
sd->sfp_temp[MCURR] = SFF8636_OFFSET_TO_TEMP(SFF8636_TEMP_CURR);
|
||||
- sd->sfp_temp[HALRM] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_HALRM);
|
||||
- sd->sfp_temp[LALRM] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_LALRM);
|
||||
- sd->sfp_temp[HWARN] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_HWARN);
|
||||
- sd->sfp_temp[LWARN] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_LWARN);
|
||||
-
|
||||
- sd->bias_cur[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_HALRM);
|
||||
- sd->bias_cur[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_LALRM);
|
||||
- sd->bias_cur[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_HWARN);
|
||||
- sd->bias_cur[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_LWARN);
|
||||
-
|
||||
- sd->tx_power[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_HALRM);
|
||||
- sd->tx_power[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_LALRM);
|
||||
- sd->tx_power[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_HWARN);
|
||||
- sd->tx_power[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_LWARN);
|
||||
-
|
||||
- sd->rx_power[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_HALRM);
|
||||
- sd->rx_power[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_LALRM);
|
||||
- sd->rx_power[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_HWARN);
|
||||
- sd->rx_power[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_LWARN);
|
||||
-
|
||||
|
||||
+ if (!map->page_03h)
|
||||
+ goto out;
|
||||
+
|
||||
+ sd->sfp_voltage[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_VCC_HALRM);
|
||||
+ sd->sfp_voltage[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_VCC_LALRM);
|
||||
+ sd->sfp_voltage[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_VCC_HWARN);
|
||||
+ sd->sfp_voltage[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_VCC_LWARN);
|
||||
+
|
||||
+ sd->sfp_temp[HALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TEMP_HALRM);
|
||||
+ sd->sfp_temp[LALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TEMP_LALRM);
|
||||
+ sd->sfp_temp[HWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TEMP_HWARN);
|
||||
+ sd->sfp_temp[LWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TEMP_LWARN);
|
||||
+
|
||||
+ sd->bias_cur[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_BIAS_HALRM);
|
||||
+ sd->bias_cur[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_BIAS_LALRM);
|
||||
+ sd->bias_cur[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_BIAS_HWARN);
|
||||
+ sd->bias_cur[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_BIAS_LWARN);
|
||||
+
|
||||
+ sd->tx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_PWR_HALRM);
|
||||
+ sd->tx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_PWR_LALRM);
|
||||
+ sd->tx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_PWR_HWARN);
|
||||
+ sd->tx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_TX_PWR_LWARN);
|
||||
+
|
||||
+ sd->rx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_RX_PWR_HALRM);
|
||||
+ sd->rx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_RX_PWR_LALRM);
|
||||
+ sd->rx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_RX_PWR_HWARN);
|
||||
+ sd->rx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
|
||||
+ SFF8636_RX_PWR_LWARN);
|
||||
+
|
||||
+out:
|
||||
/* Channel Specific Data */
|
||||
for (i = 0; i < MAX_CHANNEL_NUM; i++) {
|
||||
u8 rx_power_offset, tx_bias_offset;
|
||||
@@ -749,7 +790,7 @@ static void sff8636_dom_parse(const __u8 *id, const __u8 *page_three, struct sff
|
||||
}
|
||||
}
|
||||
|
||||
-static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eeprom_len)
|
||||
+static void sff8636_show_dom(const struct sff8636_memory_map *map)
|
||||
{
|
||||
struct sff_diags sd = {0};
|
||||
char *rx_power_string = NULL;
|
||||
@@ -763,20 +804,15 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
|
||||
* and thresholds
|
||||
* If pagging support exists, then supports_alarms is marked as 1
|
||||
*/
|
||||
+ if (map->page_03h)
|
||||
+ sd.supports_alarms = 1;
|
||||
|
||||
- if (eeprom_len == ETH_MODULE_SFF_8636_MAX_LEN) {
|
||||
- if (!(id[SFF8636_STATUS_2_OFFSET] &
|
||||
- SFF8636_STATUS_PAGE_3_PRESENT)) {
|
||||
- sd.supports_alarms = 1;
|
||||
- }
|
||||
- }
|
||||
+ sd.rx_power_type = map->page_00h[SFF8636_DIAG_TYPE_OFFSET] &
|
||||
+ SFF8636_RX_PWR_TYPE_MASK;
|
||||
+ sd.tx_power_type = map->page_00h[SFF8636_DIAG_TYPE_OFFSET] &
|
||||
+ SFF8636_RX_PWR_TYPE_MASK;
|
||||
|
||||
- sd.rx_power_type = id[SFF8636_DIAG_TYPE_OFFSET] &
|
||||
- SFF8636_RX_PWR_TYPE_MASK;
|
||||
- sd.tx_power_type = id[SFF8636_DIAG_TYPE_OFFSET] &
|
||||
- SFF8636_RX_PWR_TYPE_MASK;
|
||||
-
|
||||
- sff8636_dom_parse(id, page_three, &sd);
|
||||
+ sff8636_dom_parse(map, &sd);
|
||||
|
||||
PRINT_TEMP("Module temperature", sd.sfp_temp[MCURR]);
|
||||
PRINT_VCC("Module voltage", sd.sfp_voltage[MCURR]);
|
||||
@@ -819,7 +855,7 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
|
||||
if (sd.supports_alarms) {
|
||||
for (i = 0; sff8636_aw_flags[i].str; ++i) {
|
||||
printf("\t%-41s : %s\n", sff8636_aw_flags[i].str,
|
||||
- id[sff8636_aw_flags[i].offset]
|
||||
+ map->lower_memory[sff8636_aw_flags[i].offset]
|
||||
& sff8636_aw_flags[i].value ? "On" : "Off");
|
||||
}
|
||||
|
||||
@@ -827,39 +863,39 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
|
||||
}
|
||||
}
|
||||
|
||||
-static void sff8636_show_page_zero(const __u8 *id)
|
||||
+static void sff8636_show_page_zero(const struct sff8636_memory_map *map)
|
||||
{
|
||||
- sff8636_show_ext_identifier(id);
|
||||
- sff8636_show_connector(id);
|
||||
- sff8636_show_transceiver(id);
|
||||
- sff8636_show_encoding(id);
|
||||
- sff_show_value_with_unit(id, SFF8636_BR_NOMINAL_OFFSET,
|
||||
- "BR, Nominal", 100, "Mbps");
|
||||
- sff8636_show_rate_identifier(id);
|
||||
- sff_show_value_with_unit(id, SFF8636_SM_LEN_OFFSET,
|
||||
- "Length (SMF,km)", 1, "km");
|
||||
- sff_show_value_with_unit(id, SFF8636_OM3_LEN_OFFSET,
|
||||
- "Length (OM3 50um)", 2, "m");
|
||||
- sff_show_value_with_unit(id, SFF8636_OM2_LEN_OFFSET,
|
||||
- "Length (OM2 50um)", 1, "m");
|
||||
- sff_show_value_with_unit(id, SFF8636_OM1_LEN_OFFSET,
|
||||
- "Length (OM1 62.5um)", 1, "m");
|
||||
- sff_show_value_with_unit(id, SFF8636_CBL_LEN_OFFSET,
|
||||
- "Length (Copper or Active cable)", 1, "m");
|
||||
- sff8636_show_wavelength_or_copper_compliance(id);
|
||||
- sff_show_ascii(id, SFF8636_VENDOR_NAME_START_OFFSET,
|
||||
+ sff8636_show_ext_identifier(map);
|
||||
+ sff8636_show_connector(map);
|
||||
+ sff8636_show_transceiver(map);
|
||||
+ sff8636_show_encoding(map);
|
||||
+ sff_show_value_with_unit(map->page_00h, SFF8636_BR_NOMINAL_OFFSET,
|
||||
+ "BR, Nominal", 100, "Mbps");
|
||||
+ sff8636_show_rate_identifier(map);
|
||||
+ sff_show_value_with_unit(map->page_00h, SFF8636_SM_LEN_OFFSET,
|
||||
+ "Length (SMF,km)", 1, "km");
|
||||
+ sff_show_value_with_unit(map->page_00h, SFF8636_OM3_LEN_OFFSET,
|
||||
+ "Length (OM3 50um)", 2, "m");
|
||||
+ sff_show_value_with_unit(map->page_00h, SFF8636_OM2_LEN_OFFSET,
|
||||
+ "Length (OM2 50um)", 1, "m");
|
||||
+ sff_show_value_with_unit(map->page_00h, SFF8636_OM1_LEN_OFFSET,
|
||||
+ "Length (OM1 62.5um)", 1, "m");
|
||||
+ sff_show_value_with_unit(map->page_00h, SFF8636_CBL_LEN_OFFSET,
|
||||
+ "Length (Copper or Active cable)", 1, "m");
|
||||
+ sff8636_show_wavelength_or_copper_compliance(map);
|
||||
+ sff_show_ascii(map->page_00h, SFF8636_VENDOR_NAME_START_OFFSET,
|
||||
SFF8636_VENDOR_NAME_END_OFFSET, "Vendor name");
|
||||
- sff8636_show_oui(id, SFF8636_VENDOR_OUI_OFFSET);
|
||||
- sff_show_ascii(id, SFF8636_VENDOR_PN_START_OFFSET,
|
||||
+ sff8024_show_oui(map->page_00h, SFF8636_VENDOR_OUI_OFFSET);
|
||||
+ sff_show_ascii(map->page_00h, SFF8636_VENDOR_PN_START_OFFSET,
|
||||
SFF8636_VENDOR_PN_END_OFFSET, "Vendor PN");
|
||||
- sff_show_ascii(id, SFF8636_VENDOR_REV_START_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, SFF8636_VENDOR_REV_START_OFFSET,
|
||||
SFF8636_VENDOR_REV_END_OFFSET, "Vendor rev");
|
||||
- sff_show_ascii(id, SFF8636_VENDOR_SN_START_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, SFF8636_VENDOR_SN_START_OFFSET,
|
||||
SFF8636_VENDOR_SN_END_OFFSET, "Vendor SN");
|
||||
- sff_show_ascii(id, SFF8636_DATE_YEAR_OFFSET,
|
||||
+ sff_show_ascii(map->page_00h, SFF8636_DATE_YEAR_OFFSET,
|
||||
SFF8636_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
|
||||
- sff8636_show_revision_compliance(id);
|
||||
-
|
||||
+ sff_show_revision_compliance(map->lower_memory,
|
||||
+ SFF8636_REV_COMPLIANCE_OFFSET);
|
||||
}
|
||||
|
||||
static void sff8636_memory_map_init_buf(struct sff8636_memory_map *map,
|
||||
@@ -896,13 +932,13 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
|
||||
sff8636_memory_map_init_buf(&map, id, eeprom_len);
|
||||
|
||||
- sff8636_show_identifier(id);
|
||||
- switch (id[SFF8636_ID_OFFSET]) {
|
||||
+ sff8636_show_identifier(&map);
|
||||
+ switch (map.lower_memory[SFF8636_ID_OFFSET]) {
|
||||
case SFF8024_ID_QSFP:
|
||||
case SFF8024_ID_QSFP_PLUS:
|
||||
case SFF8024_ID_QSFP28:
|
||||
- sff8636_show_page_zero(id);
|
||||
- sff8636_show_dom(id, id + 3 * 0x80, eeprom_len);
|
||||
+ sff8636_show_page_zero(&map);
|
||||
+ sff8636_show_dom(&map);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -939,9 +975,7 @@ void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
|
||||
sff8636_memory_map_init_pages(&map, page_zero, page_three);
|
||||
|
||||
- sff8636_show_identifier(page_zero->data);
|
||||
- sff8636_show_page_zero(page_zero->data);
|
||||
- if (page_three)
|
||||
- sff8636_show_dom(page_zero->data, page_three->data - 0x80,
|
||||
- ETH_MODULE_SFF_8636_MAX_LEN);
|
||||
+ sff8636_show_identifier(&map);
|
||||
+ sff8636_show_page_zero(&map);
|
||||
+ sff8636_show_dom(&map);
|
||||
}
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,73 @@
|
||||
From 2e122ad9aa2aa0259df1035e3ec2765d8e008394 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:19 +0300
|
||||
Subject: [PATCH 20/35] sff-8636: Consolidate code between IOCTL and netlink
|
||||
paths
|
||||
|
||||
Now that both the netlink and IOCTL paths use the same memory map
|
||||
structure for parsing, the code can be easily consolidated.
|
||||
|
||||
Note that the switch-case statement is not necessary for the netlink
|
||||
path, as the netlink code (i.e., netlink/module-eeprom.c) already
|
||||
performed the check, but it is required for the IOCTL path.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 29 +++++++++++++++--------------
|
||||
1 file changed, 15 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 354b3b1ce9ff..4aa49351e6b7 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -898,6 +898,19 @@ static void sff8636_show_page_zero(const struct sff8636_memory_map *map)
|
||||
SFF8636_REV_COMPLIANCE_OFFSET);
|
||||
}
|
||||
|
||||
+static void sff8636_show_all_common(const struct sff8636_memory_map *map)
|
||||
+{
|
||||
+ sff8636_show_identifier(map);
|
||||
+ switch (map->lower_memory[SFF8636_ID_OFFSET]) {
|
||||
+ case SFF8024_ID_QSFP:
|
||||
+ case SFF8024_ID_QSFP_PLUS:
|
||||
+ case SFF8024_ID_QSFP28:
|
||||
+ sff8636_show_page_zero(map);
|
||||
+ sff8636_show_dom(map);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void sff8636_memory_map_init_buf(struct sff8636_memory_map *map,
|
||||
const __u8 *id, __u32 eeprom_len)
|
||||
{
|
||||
@@ -931,16 +944,7 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
}
|
||||
|
||||
sff8636_memory_map_init_buf(&map, id, eeprom_len);
|
||||
-
|
||||
- sff8636_show_identifier(&map);
|
||||
- switch (map.lower_memory[SFF8636_ID_OFFSET]) {
|
||||
- case SFF8024_ID_QSFP:
|
||||
- case SFF8024_ID_QSFP_PLUS:
|
||||
- case SFF8024_ID_QSFP28:
|
||||
- sff8636_show_page_zero(&map);
|
||||
- sff8636_show_dom(&map);
|
||||
- break;
|
||||
- }
|
||||
+ sff8636_show_all_common(&map);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -974,8 +978,5 @@ void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
struct sff8636_memory_map map = {};
|
||||
|
||||
sff8636_memory_map_init_pages(&map, page_zero, page_three);
|
||||
-
|
||||
- sff8636_show_identifier(&map);
|
||||
- sff8636_show_page_zero(&map);
|
||||
- sff8636_show_dom(&map);
|
||||
+ sff8636_show_all_common(&map);
|
||||
}
|
||||
--
|
||||
2.35.1
|
||||
|
101
SOURCES/0021-sff-8079-Split-SFF-8079-parsing-function.patch
Normal file
101
SOURCES/0021-sff-8079-Split-SFF-8079-parsing-function.patch
Normal file
@ -0,0 +1,101 @@
|
||||
From 1f20fb8e8b94d049672e48388ae57f89e89e880b Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:20 +0300
|
||||
Subject: [PATCH 21/35] sff-8079: Split SFF-8079 parsing function
|
||||
|
||||
SFF-8079, unlike CMIS and SFF-8636, only has a single page and therefore
|
||||
its parsing function (i.e., sff8079_show_all()) is called from both the
|
||||
IOCTL and netlink paths with a buffer pointing to that single page.
|
||||
|
||||
In future patches, the netlink code (i.e., netlink/module-eeprom.c) will
|
||||
no longer call the SFF-8079 code with a buffer pointing to the first 128
|
||||
bytes of the EEPROM. Instead, the SFF-8079 code will need to request the
|
||||
needed EEPROM data, as will be done in CMIS and SFF-8636.
|
||||
|
||||
Therefore, as a preparation for this change, split the main parsing
|
||||
function into IOCTL and netlink variants.
|
||||
|
||||
No functional changes intended.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
ethtool.c | 4 ++--
|
||||
internal.h | 3 ++-
|
||||
netlink/module-eeprom.c | 2 +-
|
||||
sfpid.c | 12 +++++++++++-
|
||||
4 files changed, 16 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ethtool.c b/ethtool.c
|
||||
index 6c744ff84eb9..5d4b5afbfd47 100644
|
||||
--- a/ethtool.c
|
||||
+++ b/ethtool.c
|
||||
@@ -4900,10 +4900,10 @@ static int do_getmodule(struct cmd_context *ctx)
|
||||
switch (modinfo.type) {
|
||||
#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
case ETH_MODULE_SFF_8079:
|
||||
- sff8079_show_all(eeprom->data);
|
||||
+ sff8079_show_all_ioctl(eeprom->data);
|
||||
break;
|
||||
case ETH_MODULE_SFF_8472:
|
||||
- sff8079_show_all(eeprom->data);
|
||||
+ sff8079_show_all_ioctl(eeprom->data);
|
||||
sff8472_show_all(eeprom->data);
|
||||
break;
|
||||
case ETH_MODULE_SFF_8436:
|
||||
diff --git a/internal.h b/internal.h
|
||||
index 7ca6066d4e12..a77efd385698 100644
|
||||
--- a/internal.h
|
||||
+++ b/internal.h
|
||||
@@ -384,7 +384,8 @@ int rxclass_rule_ins(struct cmd_context *ctx,
|
||||
int rxclass_rule_del(struct cmd_context *ctx, __u32 loc);
|
||||
|
||||
/* Module EEPROM parsing code */
|
||||
-void sff8079_show_all(const __u8 *id);
|
||||
+void sff8079_show_all_ioctl(const __u8 *id);
|
||||
+void sff8079_show_all_nl(const __u8 *id);
|
||||
|
||||
/* Optics diagnostics */
|
||||
void sff8472_show_all(const __u8 *id);
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index 18b1abbe1252..101d5943c2bc 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -323,7 +323,7 @@ static void decoder_print(void)
|
||||
|
||||
switch (module_id) {
|
||||
case SFF8024_ID_SFP:
|
||||
- sff8079_show_all(page_zero->data);
|
||||
+ sff8079_show_all_nl(page_zero->data);
|
||||
break;
|
||||
case SFF8024_ID_QSFP:
|
||||
case SFF8024_ID_QSFP28:
|
||||
diff --git a/sfpid.c b/sfpid.c
|
||||
index da2b3f4df3d2..c214820226d1 100644
|
||||
--- a/sfpid.c
|
||||
+++ b/sfpid.c
|
||||
@@ -396,7 +396,7 @@ static void sff8079_show_options(const __u8 *id)
|
||||
printf("%s Power level 3 requirement\n", pfx);
|
||||
}
|
||||
|
||||
-void sff8079_show_all(const __u8 *id)
|
||||
+static void sff8079_show_all_common(const __u8 *id)
|
||||
{
|
||||
sff8079_show_identifier(id);
|
||||
if (((id[0] == 0x02) || (id[0] == 0x03)) && (id[1] == 0x04)) {
|
||||
@@ -439,3 +439,13 @@ void sff8079_show_all(const __u8 *id)
|
||||
sff8079_show_ascii(id, 84, 91, "Date code");
|
||||
}
|
||||
}
|
||||
+
|
||||
+void sff8079_show_all_ioctl(const __u8 *id)
|
||||
+{
|
||||
+ sff8079_show_all_common(id);
|
||||
+}
|
||||
+
|
||||
+void sff8079_show_all_nl(const __u8 *id)
|
||||
+{
|
||||
+ sff8079_show_all_common(id);
|
||||
+}
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,174 @@
|
||||
From fdb457a0ebb57c99fb987d0e34b2549f10dd4161 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:21 +0300
|
||||
Subject: [PATCH 22/35] netlink: eeprom: Export a function to request an EEPROM
|
||||
page
|
||||
|
||||
The function will be used by the EEPROM parsing code (e.g., cmis.c) to
|
||||
request a specific page for parsing.
|
||||
|
||||
All the data buffers used to store EEPROM page contents are stored on a
|
||||
linked list that is flushed on exit. This relieves callers from the need
|
||||
to explicitly free the requested pages.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
netlink/extapi.h | 11 +++++
|
||||
netlink/module-eeprom.c | 105 ++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 116 insertions(+)
|
||||
|
||||
diff --git a/netlink/extapi.h b/netlink/extapi.h
|
||||
index 91bf02b5e3be..129e2931d01d 100644
|
||||
--- a/netlink/extapi.h
|
||||
+++ b/netlink/extapi.h
|
||||
@@ -48,6 +48,9 @@ int nl_getmodule(struct cmd_context *ctx);
|
||||
|
||||
void nl_monitor_usage(void);
|
||||
|
||||
+int nl_get_eeprom_page(struct cmd_context *ctx,
|
||||
+ struct ethtool_module_eeprom *request);
|
||||
+
|
||||
#else /* ETHTOOL_ENABLE_NETLINK */
|
||||
|
||||
static inline void netlink_run_handler(struct cmd_context *ctx __maybe_unused,
|
||||
@@ -73,6 +76,14 @@ static inline void nl_monitor_usage(void)
|
||||
{
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+nl_get_eeprom_page(struct cmd_context *ctx __maybe_unused,
|
||||
+ struct ethtool_module_eeprom *request __maybe_unused)
|
||||
+{
|
||||
+ fprintf(stderr, "Netlink not supported by ethtool.\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
+
|
||||
#define nl_gset NULL
|
||||
#define nl_sset NULL
|
||||
#define nl_permaddr NULL
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index 101d5943c2bc..ee5508840157 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -341,6 +341,110 @@ static void decoder_print(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
+static struct list_head eeprom_page_list = LIST_HEAD_INIT(eeprom_page_list);
|
||||
+
|
||||
+struct eeprom_page_entry {
|
||||
+ struct list_head list; /* Member of eeprom_page_list */
|
||||
+ void *data;
|
||||
+};
|
||||
+
|
||||
+static int eeprom_page_list_add(void *data)
|
||||
+{
|
||||
+ struct eeprom_page_entry *entry;
|
||||
+
|
||||
+ entry = malloc(sizeof(*entry));
|
||||
+ if (!entry)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ entry->data = data;
|
||||
+ list_add(&entry->list, &eeprom_page_list);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void eeprom_page_list_flush(void)
|
||||
+{
|
||||
+ struct eeprom_page_entry *entry;
|
||||
+ struct list_head *head, *next;
|
||||
+
|
||||
+ list_for_each_safe(head, next, &eeprom_page_list) {
|
||||
+ entry = (struct eeprom_page_entry *) head;
|
||||
+ free(entry->data);
|
||||
+ list_del(head);
|
||||
+ free(entry);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int get_eeprom_page_reply_cb(const struct nlmsghdr *nlhdr, void *data)
|
||||
+{
|
||||
+ const struct nlattr *tb[ETHTOOL_A_MODULE_EEPROM_DATA + 1] = {};
|
||||
+ struct ethtool_module_eeprom *request = data;
|
||||
+ DECLARE_ATTR_TB_INFO(tb);
|
||||
+ u8 *eeprom_data;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!tb[ETHTOOL_A_MODULE_EEPROM_DATA])
|
||||
+ return MNL_CB_ERROR;
|
||||
+
|
||||
+ eeprom_data = mnl_attr_get_payload(tb[ETHTOOL_A_MODULE_EEPROM_DATA]);
|
||||
+ request->data = malloc(request->length);
|
||||
+ if (!request->data)
|
||||
+ return MNL_CB_ERROR;
|
||||
+ memcpy(request->data, eeprom_data, request->length);
|
||||
+
|
||||
+ ret = eeprom_page_list_add(request->data);
|
||||
+ if (ret < 0)
|
||||
+ goto err_list_add;
|
||||
+
|
||||
+ return MNL_CB_OK;
|
||||
+
|
||||
+err_list_add:
|
||||
+ free(request->data);
|
||||
+ return MNL_CB_ERROR;
|
||||
+}
|
||||
+
|
||||
+int nl_get_eeprom_page(struct cmd_context *ctx,
|
||||
+ struct ethtool_module_eeprom *request)
|
||||
+{
|
||||
+ struct nl_context *nlctx = ctx->nlctx;
|
||||
+ struct nl_socket *nlsock;
|
||||
+ struct nl_msg_buff *msg;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!request || request->i2c_address > ETH_I2C_MAX_ADDRESS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ nlsock = nlctx->ethnl_socket;
|
||||
+ msg = &nlsock->msgbuff;
|
||||
+
|
||||
+ ret = nlsock_prep_get_request(nlsock, ETHTOOL_MSG_MODULE_EEPROM_GET,
|
||||
+ ETHTOOL_A_MODULE_EEPROM_HEADER, 0);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_LENGTH,
|
||||
+ request->length) ||
|
||||
+ ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_OFFSET,
|
||||
+ request->offset) ||
|
||||
+ ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_PAGE,
|
||||
+ request->page) ||
|
||||
+ ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_BANK,
|
||||
+ request->bank) ||
|
||||
+ ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS,
|
||||
+ request->i2c_address))
|
||||
+ return -EMSGSIZE;
|
||||
+
|
||||
+ ret = nlsock_sendmsg(nlsock, NULL);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ return nlsock_process_reply(nlsock, get_eeprom_page_reply_cb,
|
||||
+ (void *)request);
|
||||
+}
|
||||
+
|
||||
int nl_getmodule(struct cmd_context *ctx)
|
||||
{
|
||||
struct cmd_params getmodule_cmd_params = {};
|
||||
@@ -425,6 +529,7 @@ int nl_getmodule(struct cmd_context *ctx)
|
||||
}
|
||||
|
||||
cleanup:
|
||||
+ eeprom_page_list_flush();
|
||||
cache_free();
|
||||
return ret;
|
||||
}
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,194 @@
|
||||
From 5f45f370e132f144cdbab9ea718393bd37ee23db Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:22 +0300
|
||||
Subject: [PATCH 23/35] cmis: Request specific pages for parsing in netlink
|
||||
path
|
||||
|
||||
In the netlink path, unlike the IOCTL path, user space requests specific
|
||||
EEPROM pages from the kernel. The presence of optional and banked pages
|
||||
is advertised via various bits in the EEPROM contents.
|
||||
|
||||
Currently, for CMIS, the Lower Memory, Page 00h and the optional Page
|
||||
01h are requested by the netlink code (i.e., netlink/module-eeprom.c)
|
||||
and passed to the CMIS code (i.e., cmis.c) as two arguments for parsing.
|
||||
|
||||
This is problematic for several reasons. First, this approach is not
|
||||
very scaleable as CMIS supports a lot of optional and banked pages.
|
||||
Passing them as separate arguments to the CMIS code is not going to
|
||||
work.
|
||||
|
||||
Second, the knowledge of which optional and banked pages are available
|
||||
is encapsulated in the CMIS parsing code. As such, the common netlink
|
||||
code has no business of fetching optional and banked pages that might be
|
||||
invalid.
|
||||
|
||||
Instead, pass the command context to the CMIS parsing function and allow
|
||||
it to fetch only valid pages via the 'MODULE_EEPROM_GET' netlink
|
||||
message.
|
||||
|
||||
Tested by making sure that the output of 'ethtool -m' does not change
|
||||
before and after the patch.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 60 ++++++++++++++++++++++++++++++++---------
|
||||
cmis.h | 3 +--
|
||||
netlink/module-eeprom.c | 7 +++--
|
||||
3 files changed, 51 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index eb7791dd59df..4798fd4c7d68 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -9,9 +9,11 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
+#include <errno.h>
|
||||
#include "internal.h"
|
||||
#include "sff-common.h"
|
||||
#include "cmis.h"
|
||||
+#include "netlink/extapi.h"
|
||||
|
||||
struct cmis_memory_map {
|
||||
const __u8 *lower_memory;
|
||||
@@ -21,6 +23,7 @@ struct cmis_memory_map {
|
||||
};
|
||||
|
||||
#define CMIS_PAGE_SIZE 0x80
|
||||
+#define CMIS_I2C_ADDRESS 0x50
|
||||
|
||||
static void cmis_show_identifier(const struct cmis_memory_map *map)
|
||||
{
|
||||
@@ -384,36 +387,67 @@ void cmis_show_all_ioctl(const __u8 *id)
|
||||
cmis_show_all_common(&map);
|
||||
}
|
||||
|
||||
-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)
|
||||
+static void cmis_request_init(struct ethtool_module_eeprom *request, u8 bank,
|
||||
+ u8 page, u32 offset)
|
||||
{
|
||||
+ request->offset = offset;
|
||||
+ request->length = CMIS_PAGE_SIZE;
|
||||
+ request->page = page;
|
||||
+ request->bank = bank;
|
||||
+ request->i2c_address = CMIS_I2C_ADDRESS;
|
||||
+ request->data = NULL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+cmis_memory_map_init_pages(struct cmd_context *ctx,
|
||||
+ struct cmis_memory_map *map)
|
||||
+{
|
||||
+ struct ethtool_module_eeprom request;
|
||||
+ int ret;
|
||||
+
|
||||
/* 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.
|
||||
+ * address minus page size.
|
||||
*/
|
||||
- map->lower_memory = page_zero->data;
|
||||
- map->page_00h = page_zero->data;
|
||||
+ cmis_request_init(&request, 0, 0x0, 0);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ map->lower_memory = request.data;
|
||||
+
|
||||
+ cmis_request_init(&request, 0, 0x0, CMIS_PAGE_SIZE);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ map->page_00h = request.data - CMIS_PAGE_SIZE;
|
||||
|
||||
/* 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;
|
||||
+ return 0;
|
||||
+
|
||||
+ cmis_request_init(&request, 0, 0x1, CMIS_PAGE_SIZE);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ map->page_01h = request.data - CMIS_PAGE_SIZE;
|
||||
|
||||
- map->page_01h = page_one->data - CMIS_PAGE_SIZE;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
-void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_one)
|
||||
+int cmis_show_all_nl(struct cmd_context *ctx)
|
||||
{
|
||||
struct cmis_memory_map map = {};
|
||||
+ int ret;
|
||||
|
||||
- cmis_memory_map_init_pages(&map, page_zero, page_one);
|
||||
+ ret = cmis_memory_map_init_pages(ctx, &map);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
cmis_show_all_common(&map);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
diff --git a/cmis.h b/cmis.h
|
||||
index c878e3bc5afd..911491dc5c8f 100644
|
||||
--- a/cmis.h
|
||||
+++ b/cmis.h
|
||||
@@ -123,7 +123,6 @@
|
||||
|
||||
void cmis_show_all_ioctl(const __u8 *id);
|
||||
|
||||
-void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_one);
|
||||
+int cmis_show_all_nl(struct cmd_context *ctx);
|
||||
|
||||
#endif /* CMIS_H__ */
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index ee5508840157..a8e2662e0b8c 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -314,11 +314,10 @@ static int decoder_prefetch(struct nl_context *nlctx)
|
||||
return page_fetch(nlctx, &request);
|
||||
}
|
||||
|
||||
-static void decoder_print(void)
|
||||
+static void decoder_print(struct cmd_context *ctx)
|
||||
{
|
||||
struct ethtool_module_eeprom *page_three = cache_get(3, 0, ETH_I2C_ADDRESS_LOW);
|
||||
struct ethtool_module_eeprom *page_zero = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
|
||||
- struct ethtool_module_eeprom *page_one = cache_get(1, 0, ETH_I2C_ADDRESS_LOW);
|
||||
u8 module_id = page_zero->data[SFF8636_ID_OFFSET];
|
||||
|
||||
switch (module_id) {
|
||||
@@ -332,7 +331,7 @@ static void decoder_print(void)
|
||||
break;
|
||||
case SFF8024_ID_QSFP_DD:
|
||||
case SFF8024_ID_DSFP:
|
||||
- cmis_show_all_nl(page_zero, page_one);
|
||||
+ cmis_show_all_nl(ctx);
|
||||
break;
|
||||
default:
|
||||
dump_hex(stdout, page_zero->data, page_zero->length, page_zero->offset);
|
||||
@@ -524,7 +523,7 @@ int nl_getmodule(struct cmd_context *ctx)
|
||||
ret = decoder_prefetch(nlctx);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
- decoder_print();
|
||||
+ decoder_print(ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,181 @@
|
||||
From fdae2732b25090f9d41e192a5dd47a45a6516a94 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:23 +0300
|
||||
Subject: [PATCH 24/35] sff-8636: Request specific pages for parsing in netlink
|
||||
path
|
||||
|
||||
In the netlink path, unlike the IOCTL path, user space requests specific
|
||||
EEPROM pages from the kernel. The presence of optional pages is
|
||||
advertised via various bits in the EEPROM contents.
|
||||
|
||||
Currently, for SFF-8636, the Lower Memory, Page 00h and the optional
|
||||
Page 03h are requested by the netlink code (i.e.,
|
||||
netlink/module-eeprom.c) and passed to the SFF-8636 code (i.e., qsfp.c)
|
||||
as two arguments for parsing.
|
||||
|
||||
This is problematic for several reasons. First, this approach is not
|
||||
very scaleable as SFF-8636 supports a lot of optional pages. Passing
|
||||
them as separate arguments to the SFF-8636 code is not going to work.
|
||||
|
||||
Second, the knowledge of which optional pages are available is
|
||||
encapsulated in the SFF-8636 parsing code. As such, the common netlink
|
||||
code has no business of fetching optional pages that might be invalid.
|
||||
|
||||
Instead, pass the command context to the SFF-8636 parsing function and
|
||||
allow it to fetch only valid pages via the 'MODULE_EEPROM_GET' netlink
|
||||
message.
|
||||
|
||||
Tested by making sure that the output of 'ethtool -m' does not change
|
||||
before and after the patch.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
internal.h | 3 +--
|
||||
netlink/module-eeprom.c | 3 +--
|
||||
qsfp.c | 60 ++++++++++++++++++++++++++++++++---------
|
||||
3 files changed, 49 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/internal.h b/internal.h
|
||||
index a77efd385698..2407d3c223fa 100644
|
||||
--- a/internal.h
|
||||
+++ b/internal.h
|
||||
@@ -392,8 +392,7 @@ void sff8472_show_all(const __u8 *id);
|
||||
|
||||
/* QSFP Optics diagnostics */
|
||||
void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len);
|
||||
-void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_three);
|
||||
+int sff8636_show_all_nl(struct cmd_context *ctx);
|
||||
|
||||
/* FUJITSU Extended Socket network device */
|
||||
int fjes_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index a8e2662e0b8c..f04f8e134223 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -316,7 +316,6 @@ static int decoder_prefetch(struct nl_context *nlctx)
|
||||
|
||||
static void decoder_print(struct cmd_context *ctx)
|
||||
{
|
||||
- struct ethtool_module_eeprom *page_three = cache_get(3, 0, ETH_I2C_ADDRESS_LOW);
|
||||
struct ethtool_module_eeprom *page_zero = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
|
||||
u8 module_id = page_zero->data[SFF8636_ID_OFFSET];
|
||||
|
||||
@@ -327,7 +326,7 @@ static void decoder_print(struct cmd_context *ctx)
|
||||
case SFF8024_ID_QSFP:
|
||||
case SFF8024_ID_QSFP28:
|
||||
case SFF8024_ID_QSFP_PLUS:
|
||||
- sff8636_show_all_nl(page_zero, page_three);
|
||||
+ sff8636_show_all_nl(ctx);
|
||||
break;
|
||||
case SFF8024_ID_QSFP_DD:
|
||||
case SFF8024_ID_DSFP:
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 4aa49351e6b7..e7c2f51cd9c6 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -55,10 +55,12 @@
|
||||
**/
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
+#include <errno.h>
|
||||
#include "internal.h"
|
||||
#include "sff-common.h"
|
||||
#include "qsfp.h"
|
||||
#include "cmis.h"
|
||||
+#include "netlink/extapi.h"
|
||||
|
||||
struct sff8636_memory_map {
|
||||
const __u8 *lower_memory;
|
||||
@@ -68,6 +70,7 @@ struct sff8636_memory_map {
|
||||
};
|
||||
|
||||
#define SFF8636_PAGE_SIZE 0x80
|
||||
+#define SFF8636_I2C_ADDRESS 0x50
|
||||
|
||||
#define MAX_DESC_SIZE 42
|
||||
|
||||
@@ -947,36 +950,67 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
|
||||
sff8636_show_all_common(&map);
|
||||
}
|
||||
|
||||
-static void
|
||||
-sff8636_memory_map_init_pages(struct sff8636_memory_map *map,
|
||||
- const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_three)
|
||||
+static void sff8636_request_init(struct ethtool_module_eeprom *request, u8 page,
|
||||
+ u32 offset)
|
||||
+{
|
||||
+ request->offset = offset;
|
||||
+ request->length = SFF8636_PAGE_SIZE;
|
||||
+ request->page = page;
|
||||
+ request->bank = 0;
|
||||
+ request->i2c_address = SFF8636_I2C_ADDRESS;
|
||||
+ request->data = NULL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+sff8636_memory_map_init_pages(struct cmd_context *ctx,
|
||||
+ struct sff8636_memory_map *map)
|
||||
{
|
||||
+ struct ethtool_module_eeprom request;
|
||||
+ int ret;
|
||||
+
|
||||
/* 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.
|
||||
+ * address minus page size.
|
||||
*/
|
||||
- map->lower_memory = page_zero->data;
|
||||
- map->page_00h = page_zero->data;
|
||||
+ sff8636_request_init(&request, 0x0, 0);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ map->lower_memory = request.data;
|
||||
+
|
||||
+ sff8636_request_init(&request, 0x0, SFF8636_PAGE_SIZE);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ map->page_00h = request.data - SFF8636_PAGE_SIZE;
|
||||
|
||||
/* Page 03h is only present when the module memory model is paged and
|
||||
* not flat.
|
||||
*/
|
||||
if (map->lower_memory[SFF8636_STATUS_2_OFFSET] &
|
||||
SFF8636_STATUS_PAGE_3_PRESENT)
|
||||
- return;
|
||||
+ return 0;
|
||||
|
||||
- map->page_03h = page_three->data - SFF8636_PAGE_SIZE;
|
||||
+ sff8636_request_init(&request, 0x3, SFF8636_PAGE_SIZE);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ map->page_03h = request.data - SFF8636_PAGE_SIZE;
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
-void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
|
||||
- const struct ethtool_module_eeprom *page_three)
|
||||
+int sff8636_show_all_nl(struct cmd_context *ctx)
|
||||
{
|
||||
struct sff8636_memory_map map = {};
|
||||
+ int ret;
|
||||
|
||||
- sff8636_memory_map_init_pages(&map, page_zero, page_three);
|
||||
+ ret = sff8636_memory_map_init_pages(ctx, &map);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
sff8636_show_all_common(&map);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,92 @@
|
||||
From bda06d81f41bb1cde16a319728d479cda4b9f295 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:24 +0300
|
||||
Subject: [PATCH 25/35] sff-8079: Request specific pages for parsing in netlink
|
||||
path
|
||||
|
||||
Convert the SFF-8079 code to request the required EEPROM contents in the
|
||||
netlink path as was done for CMIS and SFF-8636. It will allow us to
|
||||
remove standard-specific code from the netlink code (i.e.,
|
||||
netlink/module-eeprom.c).
|
||||
|
||||
In addition, in the future, it will allow the netlink path to support
|
||||
parsing of SFF-8472.
|
||||
|
||||
Tested by making sure that the output of 'ethtool -m' does not change
|
||||
before and after the patch.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
internal.h | 2 +-
|
||||
netlink/module-eeprom.c | 2 +-
|
||||
sfpid.c | 20 ++++++++++++++++++--
|
||||
3 files changed, 20 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/internal.h b/internal.h
|
||||
index 2407d3c223fa..0d9d816ab563 100644
|
||||
--- a/internal.h
|
||||
+++ b/internal.h
|
||||
@@ -385,7 +385,7 @@ int rxclass_rule_del(struct cmd_context *ctx, __u32 loc);
|
||||
|
||||
/* Module EEPROM parsing code */
|
||||
void sff8079_show_all_ioctl(const __u8 *id);
|
||||
-void sff8079_show_all_nl(const __u8 *id);
|
||||
+int sff8079_show_all_nl(struct cmd_context *ctx);
|
||||
|
||||
/* Optics diagnostics */
|
||||
void sff8472_show_all(const __u8 *id);
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index f04f8e134223..6d76b8a96461 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -321,7 +321,7 @@ static void decoder_print(struct cmd_context *ctx)
|
||||
|
||||
switch (module_id) {
|
||||
case SFF8024_ID_SFP:
|
||||
- sff8079_show_all_nl(page_zero->data);
|
||||
+ sff8079_show_all_nl(ctx);
|
||||
break;
|
||||
case SFF8024_ID_QSFP:
|
||||
case SFF8024_ID_QSFP28:
|
||||
diff --git a/sfpid.c b/sfpid.c
|
||||
index c214820226d1..621d1e86c278 100644
|
||||
--- a/sfpid.c
|
||||
+++ b/sfpid.c
|
||||
@@ -8,8 +8,13 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
+#include <errno.h>
|
||||
#include "internal.h"
|
||||
#include "sff-common.h"
|
||||
+#include "netlink/extapi.h"
|
||||
+
|
||||
+#define SFF8079_PAGE_SIZE 0x80
|
||||
+#define SFF8079_I2C_ADDRESS_LOW 0x50
|
||||
|
||||
static void sff8079_show_identifier(const __u8 *id)
|
||||
{
|
||||
@@ -445,7 +450,18 @@ void sff8079_show_all_ioctl(const __u8 *id)
|
||||
sff8079_show_all_common(id);
|
||||
}
|
||||
|
||||
-void sff8079_show_all_nl(const __u8 *id)
|
||||
+int sff8079_show_all_nl(struct cmd_context *ctx)
|
||||
{
|
||||
- sff8079_show_all_common(id);
|
||||
+ struct ethtool_module_eeprom request = {
|
||||
+ .length = SFF8079_PAGE_SIZE,
|
||||
+ .i2c_address = SFF8079_I2C_ADDRESS_LOW,
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ sff8079_show_all_common(request.data);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,428 @@
|
||||
From b6005ecf2ce2aaeb86995fa50df97e7384f46f99 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 12 Oct 2021 16:25:25 +0300
|
||||
Subject: [PATCH 26/35] netlink: eeprom: Defer page requests to individual
|
||||
parsers
|
||||
|
||||
The individual EEPROM parsers (e.g., CMIS, SFF-8636) now request the
|
||||
EEPROM pages they intend to parse and populate their memory maps before
|
||||
parsing them.
|
||||
|
||||
Therefore, there is no need for the common netlink code to request
|
||||
potentially invalid pages and pass them as blobs to these parsers.
|
||||
|
||||
Instead, only query the SFF-8024 Identifier Value which is located at
|
||||
I2C address 0x50, byte 0 and dispatch to the relevant EEPROM parser.
|
||||
|
||||
Tested by making sure that the output of 'ethtool -m' does not change
|
||||
for SFF-8079, SFF-8636 and CMIS before and after the patch.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
netlink/module-eeprom.c | 347 +++++++---------------------------------
|
||||
1 file changed, 59 insertions(+), 288 deletions(-)
|
||||
|
||||
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
|
||||
index 6d76b8a96461..f359aeec4ddf 100644
|
||||
--- a/netlink/module-eeprom.c
|
||||
+++ b/netlink/module-eeprom.c
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "parser.h"
|
||||
|
||||
#define ETH_I2C_ADDRESS_LOW 0x50
|
||||
-#define ETH_I2C_ADDRESS_HIGH 0x51
|
||||
#define ETH_I2C_MAX_ADDRESS 0x7F
|
||||
|
||||
struct cmd_params {
|
||||
@@ -78,267 +77,6 @@ static const struct param_parser getmodule_params[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
-struct page_entry {
|
||||
- struct list_head link;
|
||||
- struct ethtool_module_eeprom *page;
|
||||
-};
|
||||
-
|
||||
-static struct list_head page_list = LIST_HEAD_INIT(page_list);
|
||||
-
|
||||
-static int cache_add(struct ethtool_module_eeprom *page)
|
||||
-{
|
||||
- struct page_entry *list_element;
|
||||
-
|
||||
- if (!page)
|
||||
- return -1;
|
||||
- list_element = malloc(sizeof(*list_element));
|
||||
- if (!list_element)
|
||||
- return -ENOMEM;
|
||||
- list_element->page = page;
|
||||
-
|
||||
- list_add(&list_element->link, &page_list);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static void page_free(struct ethtool_module_eeprom *page)
|
||||
-{
|
||||
- free(page->data);
|
||||
- free(page);
|
||||
-}
|
||||
-
|
||||
-static void cache_del(struct ethtool_module_eeprom *page)
|
||||
-{
|
||||
- struct ethtool_module_eeprom *entry;
|
||||
- struct list_head *head, *next;
|
||||
-
|
||||
- list_for_each_safe(head, next, &page_list) {
|
||||
- entry = ((struct page_entry *)head)->page;
|
||||
- if (entry == page) {
|
||||
- list_del(head);
|
||||
- free(head);
|
||||
- page_free(entry);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void cache_free(void)
|
||||
-{
|
||||
- struct ethtool_module_eeprom *entry;
|
||||
- struct list_head *head, *next;
|
||||
-
|
||||
- list_for_each_safe(head, next, &page_list) {
|
||||
- entry = ((struct page_entry *)head)->page;
|
||||
- list_del(head);
|
||||
- free(head);
|
||||
- page_free(entry);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static struct ethtool_module_eeprom *page_join(struct ethtool_module_eeprom *page_a,
|
||||
- struct ethtool_module_eeprom *page_b)
|
||||
-{
|
||||
- struct ethtool_module_eeprom *joined_page;
|
||||
- u32 total_length;
|
||||
-
|
||||
- if (!page_a || !page_b ||
|
||||
- page_a->page != page_b->page ||
|
||||
- page_a->bank != page_b->bank ||
|
||||
- page_a->i2c_address != page_b->i2c_address)
|
||||
- return NULL;
|
||||
-
|
||||
- total_length = page_a->length + page_b->length;
|
||||
- joined_page = calloc(1, sizeof(*joined_page));
|
||||
- joined_page->data = calloc(1, total_length);
|
||||
- joined_page->page = page_a->page;
|
||||
- joined_page->bank = page_a->bank;
|
||||
- joined_page->length = total_length;
|
||||
- joined_page->i2c_address = page_a->i2c_address;
|
||||
-
|
||||
- if (page_a->offset < page_b->offset) {
|
||||
- memcpy(joined_page->data, page_a->data, page_a->length);
|
||||
- memcpy(joined_page->data + page_a->length, page_b->data, page_b->length);
|
||||
- joined_page->offset = page_a->offset;
|
||||
- } else {
|
||||
- memcpy(joined_page->data, page_b->data, page_b->length);
|
||||
- memcpy(joined_page->data + page_b->length, page_a->data, page_a->length);
|
||||
- joined_page->offset = page_b->offset;
|
||||
- }
|
||||
-
|
||||
- return joined_page;
|
||||
-}
|
||||
-
|
||||
-static struct ethtool_module_eeprom *cache_get(u32 page, u32 bank, u8 i2c_address)
|
||||
-{
|
||||
- struct ethtool_module_eeprom *entry;
|
||||
- struct list_head *head, *next;
|
||||
-
|
||||
- list_for_each_safe(head, next, &page_list) {
|
||||
- entry = ((struct page_entry *)head)->page;
|
||||
- if (entry->page == page && entry->bank == bank &&
|
||||
- entry->i2c_address == i2c_address)
|
||||
- return entry;
|
||||
- }
|
||||
-
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
-static int getmodule_page_fetch_reply_cb(const struct nlmsghdr *nlhdr,
|
||||
- void *data)
|
||||
-{
|
||||
- const struct nlattr *tb[ETHTOOL_A_MODULE_EEPROM_DATA + 1] = {};
|
||||
- DECLARE_ATTR_TB_INFO(tb);
|
||||
- struct ethtool_module_eeprom *lower_page;
|
||||
- struct ethtool_module_eeprom *response;
|
||||
- struct ethtool_module_eeprom *request;
|
||||
- struct ethtool_module_eeprom *joined;
|
||||
- u8 *eeprom_data;
|
||||
- int ret;
|
||||
-
|
||||
- ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- if (!tb[ETHTOOL_A_MODULE_EEPROM_DATA]) {
|
||||
- fprintf(stderr, "Malformed netlink message (getmodule)\n");
|
||||
- return MNL_CB_ERROR;
|
||||
- }
|
||||
-
|
||||
- response = calloc(1, sizeof(*response));
|
||||
- if (!response)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- request = (struct ethtool_module_eeprom *)data;
|
||||
- response->offset = request->offset;
|
||||
- response->page = request->page;
|
||||
- response->bank = request->bank;
|
||||
- response->i2c_address = request->i2c_address;
|
||||
- response->length = mnl_attr_get_payload_len(tb[ETHTOOL_A_MODULE_EEPROM_DATA]);
|
||||
- eeprom_data = mnl_attr_get_payload(tb[ETHTOOL_A_MODULE_EEPROM_DATA]);
|
||||
-
|
||||
- response->data = malloc(response->length);
|
||||
- if (!response->data) {
|
||||
- free(response);
|
||||
- return -ENOMEM;
|
||||
- }
|
||||
- memcpy(response->data, eeprom_data, response->length);
|
||||
-
|
||||
- if (!request->page) {
|
||||
- lower_page = cache_get(request->page, request->bank, response->i2c_address);
|
||||
- if (lower_page) {
|
||||
- joined = page_join(lower_page, response);
|
||||
- page_free(response);
|
||||
- cache_del(lower_page);
|
||||
- return cache_add(joined);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return cache_add(response);
|
||||
-}
|
||||
-
|
||||
-static int page_fetch(struct nl_context *nlctx, const struct ethtool_module_eeprom *request)
|
||||
-{
|
||||
- struct nl_socket *nlsock = nlctx->ethnl_socket;
|
||||
- struct nl_msg_buff *msg = &nlsock->msgbuff;
|
||||
- struct ethtool_module_eeprom *page;
|
||||
- int ret;
|
||||
-
|
||||
- if (!request || request->i2c_address > ETH_I2C_MAX_ADDRESS)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- /* Satisfy request right away, if region is already in cache */
|
||||
- page = cache_get(request->page, request->bank, request->i2c_address);
|
||||
- if (page && page->offset <= request->offset &&
|
||||
- page->offset + page->length >= request->offset + request->length) {
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- ret = nlsock_prep_get_request(nlsock, ETHTOOL_MSG_MODULE_EEPROM_GET,
|
||||
- ETHTOOL_A_MODULE_EEPROM_HEADER, 0);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- if (ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_LENGTH, request->length) ||
|
||||
- ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_OFFSET, request->offset) ||
|
||||
- ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_PAGE, request->page) ||
|
||||
- ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_BANK, request->bank) ||
|
||||
- ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS, request->i2c_address))
|
||||
- return -EMSGSIZE;
|
||||
-
|
||||
- ret = nlsock_sendmsg(nlsock, NULL);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
- ret = nlsock_process_reply(nlsock, getmodule_page_fetch_reply_cb, (void *)request);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- return nlsock_process_reply(nlsock, nomsg_reply_cb, NULL);
|
||||
-}
|
||||
-
|
||||
-#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
-static int decoder_prefetch(struct nl_context *nlctx)
|
||||
-{
|
||||
- struct ethtool_module_eeprom *page_zero_lower = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
|
||||
- struct ethtool_module_eeprom request = {0};
|
||||
- u8 module_id = page_zero_lower->data[0];
|
||||
- int err = 0;
|
||||
-
|
||||
- /* Fetch rest of page 00 */
|
||||
- request.i2c_address = ETH_I2C_ADDRESS_LOW;
|
||||
- request.offset = 128;
|
||||
- request.length = 128;
|
||||
- err = page_fetch(nlctx, &request);
|
||||
- if (err)
|
||||
- return err;
|
||||
-
|
||||
- switch (module_id) {
|
||||
- case SFF8024_ID_QSFP:
|
||||
- case SFF8024_ID_QSFP28:
|
||||
- case SFF8024_ID_QSFP_PLUS:
|
||||
- memset(&request, 0, sizeof(request));
|
||||
- request.i2c_address = ETH_I2C_ADDRESS_LOW;
|
||||
- request.offset = 128;
|
||||
- request.length = 128;
|
||||
- request.page = 3;
|
||||
- break;
|
||||
- case SFF8024_ID_QSFP_DD:
|
||||
- case SFF8024_ID_DSFP:
|
||||
- memset(&request, 0, sizeof(request));
|
||||
- request.i2c_address = ETH_I2C_ADDRESS_LOW;
|
||||
- request.offset = 128;
|
||||
- request.length = 128;
|
||||
- request.page = 1;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return page_fetch(nlctx, &request);
|
||||
-}
|
||||
-
|
||||
-static void decoder_print(struct cmd_context *ctx)
|
||||
-{
|
||||
- struct ethtool_module_eeprom *page_zero = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
|
||||
- u8 module_id = page_zero->data[SFF8636_ID_OFFSET];
|
||||
-
|
||||
- switch (module_id) {
|
||||
- case SFF8024_ID_SFP:
|
||||
- sff8079_show_all_nl(ctx);
|
||||
- break;
|
||||
- case SFF8024_ID_QSFP:
|
||||
- case SFF8024_ID_QSFP28:
|
||||
- case SFF8024_ID_QSFP_PLUS:
|
||||
- sff8636_show_all_nl(ctx);
|
||||
- break;
|
||||
- case SFF8024_ID_QSFP_DD:
|
||||
- case SFF8024_ID_DSFP:
|
||||
- cmis_show_all_nl(ctx);
|
||||
- break;
|
||||
- default:
|
||||
- dump_hex(stdout, page_zero->data, page_zero->length, page_zero->offset);
|
||||
- break;
|
||||
- }
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
static struct list_head eeprom_page_list = LIST_HEAD_INIT(eeprom_page_list);
|
||||
|
||||
struct eeprom_page_entry {
|
||||
@@ -443,14 +181,64 @@ int nl_get_eeprom_page(struct cmd_context *ctx,
|
||||
(void *)request);
|
||||
}
|
||||
|
||||
+static int eeprom_dump_hex(struct cmd_context *ctx)
|
||||
+{
|
||||
+ struct ethtool_module_eeprom request = {
|
||||
+ .length = 128,
|
||||
+ .i2c_address = ETH_I2C_ADDRESS_LOW,
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ dump_hex(stdout, request.data, request.length, request.offset);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int eeprom_parse(struct cmd_context *ctx)
|
||||
+{
|
||||
+ struct ethtool_module_eeprom request = {
|
||||
+ .length = 1,
|
||||
+ .i2c_address = ETH_I2C_ADDRESS_LOW,
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Fetch the SFF-8024 Identifier Value. For all supported standards, it
|
||||
+ * is located at I2C address 0x50, byte 0. See section 4.1 in SFF-8024,
|
||||
+ * revision 4.9.
|
||||
+ */
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ switch (request.data[0]) {
|
||||
+#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
+ case SFF8024_ID_SFP:
|
||||
+ return sff8079_show_all_nl(ctx);
|
||||
+ case SFF8024_ID_QSFP:
|
||||
+ case SFF8024_ID_QSFP28:
|
||||
+ case SFF8024_ID_QSFP_PLUS:
|
||||
+ return sff8636_show_all_nl(ctx);
|
||||
+ case SFF8024_ID_QSFP_DD:
|
||||
+ case SFF8024_ID_DSFP:
|
||||
+ return cmis_show_all_nl(ctx);
|
||||
+#endif
|
||||
+ default:
|
||||
+ /* If we cannot recognize the memory map, default to dumping
|
||||
+ * the first 128 bytes in hex.
|
||||
+ */
|
||||
+ return eeprom_dump_hex(ctx);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
int nl_getmodule(struct cmd_context *ctx)
|
||||
{
|
||||
struct cmd_params getmodule_cmd_params = {};
|
||||
struct ethtool_module_eeprom request = {0};
|
||||
- struct ethtool_module_eeprom *reply_page;
|
||||
struct nl_context *nlctx = ctx->nlctx;
|
||||
- u32 dump_length;
|
||||
- u8 *eeprom_data;
|
||||
int ret;
|
||||
|
||||
if (netlink_cmd_check(ctx, ETHTOOL_MSG_MODULE_EEPROM_GET, false))
|
||||
@@ -479,12 +267,6 @@ int nl_getmodule(struct cmd_context *ctx)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
- request.i2c_address = ETH_I2C_ADDRESS_LOW;
|
||||
- request.length = 128;
|
||||
- ret = page_fetch(nlctx, &request);
|
||||
- if (ret)
|
||||
- goto cleanup;
|
||||
-
|
||||
#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
if (getmodule_cmd_params.page || getmodule_cmd_params.bank ||
|
||||
getmodule_cmd_params.offset || getmodule_cmd_params.length)
|
||||
@@ -501,33 +283,22 @@ int nl_getmodule(struct cmd_context *ctx)
|
||||
request.offset = 128;
|
||||
|
||||
if (getmodule_cmd_params.dump_hex || getmodule_cmd_params.dump_raw) {
|
||||
- ret = page_fetch(nlctx, &request);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
- reply_page = cache_get(request.page, request.bank, request.i2c_address);
|
||||
- if (!reply_page) {
|
||||
- ret = -EINVAL;
|
||||
- goto cleanup;
|
||||
- }
|
||||
|
||||
- eeprom_data = reply_page->data + (request.offset - reply_page->offset);
|
||||
- dump_length = reply_page->length < request.length ? reply_page->length
|
||||
- : request.length;
|
||||
if (getmodule_cmd_params.dump_raw)
|
||||
- fwrite(eeprom_data, 1, request.length, stdout);
|
||||
+ fwrite(request.data, 1, request.length, stdout);
|
||||
else
|
||||
- dump_hex(stdout, eeprom_data, dump_length, request.offset);
|
||||
+ dump_hex(stdout, request.data, request.length,
|
||||
+ request.offset);
|
||||
} else {
|
||||
-#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
|
||||
- ret = decoder_prefetch(nlctx);
|
||||
- if (ret)
|
||||
+ ret = eeprom_parse(ctx);
|
||||
+ if (ret < 0)
|
||||
goto cleanup;
|
||||
- decoder_print(ctx);
|
||||
-#endif
|
||||
}
|
||||
|
||||
cleanup:
|
||||
eeprom_page_list_flush();
|
||||
- cache_free();
|
||||
return ret;
|
||||
}
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,84 @@
|
||||
From 37093971b0f645542c4bff603f41f807e8023bd3 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 23 Nov 2021 19:40:55 +0200
|
||||
Subject: [PATCH 27/35] sff-8636: Use an SFF-8636 specific define for maximum
|
||||
number of channels
|
||||
|
||||
'MAX_CHANNEL_NUM' is defined in the common SFF code as 4 and used to set
|
||||
the size of the per-channel diagnostics array in the common 'sff_diags'
|
||||
structure.
|
||||
|
||||
The CMIS parsing code is also going to use the structure, but it can
|
||||
have up to 32 channels, unlike SFF-8636 that only has 4.
|
||||
|
||||
Therefore, set 'MAX_CHANNEL_NUM' to 32 and change the SFF-8636 code to
|
||||
use an SFF-8636 specific define instead of the common 'MAX_CHANNEL_NUM'.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 9 +++++----
|
||||
sff-common.h | 2 +-
|
||||
2 files changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index e7c2f51cd9c6..58c4c4775e9b 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -71,6 +71,7 @@ struct sff8636_memory_map {
|
||||
|
||||
#define SFF8636_PAGE_SIZE 0x80
|
||||
#define SFF8636_I2C_ADDRESS 0x50
|
||||
+#define SFF8636_MAX_CHANNEL_NUM 4
|
||||
|
||||
#define MAX_DESC_SIZE 42
|
||||
|
||||
@@ -761,7 +762,7 @@ static void sff8636_dom_parse(const struct sff8636_memory_map *map,
|
||||
|
||||
out:
|
||||
/* Channel Specific Data */
|
||||
- for (i = 0; i < MAX_CHANNEL_NUM; i++) {
|
||||
+ for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) {
|
||||
u8 rx_power_offset, tx_bias_offset;
|
||||
u8 tx_power_offset;
|
||||
|
||||
@@ -832,13 +833,13 @@ static void sff8636_show_dom(const struct sff8636_memory_map *map)
|
||||
printf("\t%-41s : %s\n", "Alarm/warning flags implemented",
|
||||
(sd.supports_alarms ? "Yes" : "No"));
|
||||
|
||||
- for (i = 0; i < MAX_CHANNEL_NUM; i++) {
|
||||
+ for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) {
|
||||
snprintf(power_string, MAX_DESC_SIZE, "%s (Channel %d)",
|
||||
"Laser tx bias current", i+1);
|
||||
PRINT_BIAS(power_string, sd.scd[i].bias_cur);
|
||||
}
|
||||
|
||||
- for (i = 0; i < MAX_CHANNEL_NUM; i++) {
|
||||
+ for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) {
|
||||
snprintf(power_string, MAX_DESC_SIZE, "%s (Channel %d)",
|
||||
"Transmit avg optical power", i+1);
|
||||
PRINT_xX_PWR(power_string, sd.scd[i].tx_power);
|
||||
@@ -849,7 +850,7 @@ static void sff8636_show_dom(const struct sff8636_memory_map *map)
|
||||
else
|
||||
rx_power_string = "Rcvr signal avg optical power";
|
||||
|
||||
- for (i = 0; i < MAX_CHANNEL_NUM; i++) {
|
||||
+ for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) {
|
||||
snprintf(power_string, MAX_DESC_SIZE, "%s(Channel %d)",
|
||||
rx_power_string, i+1);
|
||||
PRINT_xX_PWR(power_string, sd.scd[i].rx_power);
|
||||
diff --git a/sff-common.h b/sff-common.h
|
||||
index 2183f41ff9c9..aab306e0b74f 100644
|
||||
--- a/sff-common.h
|
||||
+++ b/sff-common.h
|
||||
@@ -160,7 +160,7 @@ struct sff_channel_diags {
|
||||
/* Module Monitoring Fields */
|
||||
struct sff_diags {
|
||||
|
||||
-#define MAX_CHANNEL_NUM 4
|
||||
+#define MAX_CHANNEL_NUM 32
|
||||
#define LWARN 0
|
||||
#define HWARN 1
|
||||
#define LALRM 2
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,45 @@
|
||||
From 2dcf6b9dc1c1874705b9e71e13e00dde9f7f576c Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 23 Nov 2021 19:40:56 +0200
|
||||
Subject: [PATCH 28/35] sff-common: Move OFFSET_TO_U16_PTR() to common header
|
||||
file
|
||||
|
||||
The define is also useful for CMIS, so move it from SFF-8636 to the
|
||||
common header file.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 1 -
|
||||
sff-common.h | 4 ++--
|
||||
2 files changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index 58c4c4775e9b..b3c9e1516af9 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -700,7 +700,6 @@ sff8636_show_wavelength_or_copper_compliance(const struct sff8636_memory_map *ma
|
||||
* Second byte are 1/256th of degree, which are added to the dec part.
|
||||
*/
|
||||
#define SFF8636_OFFSET_TO_TEMP(offset) ((__s16)OFFSET_TO_U16(offset))
|
||||
-#define OFFSET_TO_U16_PTR(ptr, offset) (ptr[offset] << 8 | ptr[(offset) + 1])
|
||||
|
||||
static void sff8636_dom_parse(const struct sff8636_memory_map *map,
|
||||
struct sff_diags *sd)
|
||||
diff --git a/sff-common.h b/sff-common.h
|
||||
index aab306e0b74f..9e323008ba19 100644
|
||||
--- a/sff-common.h
|
||||
+++ b/sff-common.h
|
||||
@@ -126,8 +126,8 @@
|
||||
#define SFF8024_ENCODING_PAM4 0x08
|
||||
|
||||
/* Most common case: 16-bit unsigned integer in a certain unit */
|
||||
-#define OFFSET_TO_U16(offset) \
|
||||
- (id[offset] << 8 | id[(offset) + 1])
|
||||
+#define OFFSET_TO_U16_PTR(ptr, offset) (ptr[offset] << 8 | ptr[(offset) + 1])
|
||||
+#define OFFSET_TO_U16(offset) OFFSET_TO_U16_PTR(id, offset)
|
||||
|
||||
# define PRINT_xX_PWR(string, var) \
|
||||
printf("\t%-41s : %.4f mW / %.2f dBm\n", (string), \
|
||||
--
|
||||
2.35.1
|
||||
|
59
SOURCES/0029-cmis-Initialize-Page-02h-in-memory-map.patch
Normal file
59
SOURCES/0029-cmis-Initialize-Page-02h-in-memory-map.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From 86853162d53b47cd0f6bcb926810aa0fd68b8898 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 23 Nov 2021 19:40:57 +0200
|
||||
Subject: [PATCH 29/35] cmis: Initialize Page 02h in memory map
|
||||
|
||||
Page 02h stores module and lane thresholds 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.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 13 ++++++++++---
|
||||
1 file changed, 10 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index 4798fd4c7d68..55b9d1b959cd 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -17,9 +17,10 @@
|
||||
|
||||
struct cmis_memory_map {
|
||||
const __u8 *lower_memory;
|
||||
- const __u8 *upper_memory[1][2]; /* Bank, Page */
|
||||
+ const __u8 *upper_memory[1][3]; /* Bank, Page */
|
||||
#define page_00h upper_memory[0x0][0x0]
|
||||
#define page_01h upper_memory[0x0][0x1]
|
||||
+#define page_02h upper_memory[0x0][0x2]
|
||||
};
|
||||
|
||||
#define CMIS_PAGE_SIZE 0x80
|
||||
@@ -423,8 +424,8 @@ cmis_memory_map_init_pages(struct cmd_context *ctx,
|
||||
return ret;
|
||||
map->page_00h = request.data - CMIS_PAGE_SIZE;
|
||||
|
||||
- /* Page 01h is only present when the module memory model is paged and
|
||||
- * not flat.
|
||||
+ /* Pages 01h and 02h are only present when the module memory model is
|
||||
+ * paged and not flat.
|
||||
*/
|
||||
if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
|
||||
CMIS_MEMORY_MODEL_MASK)
|
||||
@@ -436,6 +437,12 @@ cmis_memory_map_init_pages(struct cmd_context *ctx,
|
||||
return ret;
|
||||
map->page_01h = request.data - CMIS_PAGE_SIZE;
|
||||
|
||||
+ cmis_request_init(&request, 0, 0x2, CMIS_PAGE_SIZE);
|
||||
+ ret = nl_get_eeprom_page(ctx, &request);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ map->page_02h = request.data - CMIS_PAGE_SIZE;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
122
SOURCES/0030-cmis-Initialize-Banked-Page-11h-in-memory-map.patch
Normal file
122
SOURCES/0030-cmis-Initialize-Banked-Page-11h-in-memory-map.patch
Normal file
@ -0,0 +1,122 @@
|
||||
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
|
||||
|
631
SOURCES/0031-cmis-Parse-and-print-diagnostic-information.patch
Normal file
631
SOURCES/0031-cmis-Parse-and-print-diagnostic-information.patch
Normal file
@ -0,0 +1,631 @@
|
||||
From 086662c0b884c2b2e44ec472566d56c68a4330e0 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 23 Nov 2021 19:40:59 +0200
|
||||
Subject: [PATCH 31/35] cmis: Parse and print diagnostic information
|
||||
|
||||
Like SFF-8636, CMIS has module-level monitors such as temperature and
|
||||
voltage and channel-level monitors such as Tx optical power.
|
||||
|
||||
These monitors have thresholds and flags that are set when the monitors
|
||||
cross the thresholds.
|
||||
|
||||
Print and parse these values in a similar fashion to SFF-8636.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 466 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
|
||||
cmis.h | 79 ++++++++++
|
||||
2 files changed, 518 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index 83ced4d253ae..d7b7097139b3 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -19,6 +19,8 @@
|
||||
* [1] CMIS Rev. 5, page. 128, section 8.4.4, Table 8-40
|
||||
*/
|
||||
#define CMIS_MAX_BANKS 4
|
||||
+#define CMIS_CHANNELS_PER_BANK 8
|
||||
+#define CMIS_MAX_CHANNEL_NUM (CMIS_MAX_BANKS * CMIS_CHANNELS_PER_BANK)
|
||||
|
||||
/* We are not parsing further than Page 11h. */
|
||||
#define CMIS_MAX_PAGES 18
|
||||
@@ -34,6 +36,80 @@ struct cmis_memory_map {
|
||||
#define CMIS_PAGE_SIZE 0x80
|
||||
#define CMIS_I2C_ADDRESS 0x50
|
||||
|
||||
+static struct {
|
||||
+ const char *str;
|
||||
+ int offset;
|
||||
+ __u8 value; /* Alarm is on if (offset & value) != 0. */
|
||||
+} cmis_aw_mod_flags[] = {
|
||||
+ { "Module temperature high alarm",
|
||||
+ CMIS_TEMP_AW_OFFSET, CMIS_TEMP_HALARM_STATUS },
|
||||
+ { "Module temperature low alarm",
|
||||
+ CMIS_TEMP_AW_OFFSET, CMIS_TEMP_LALARM_STATUS },
|
||||
+ { "Module temperature high warning",
|
||||
+ CMIS_TEMP_AW_OFFSET, CMIS_TEMP_HWARN_STATUS },
|
||||
+ { "Module temperature low warning",
|
||||
+ CMIS_TEMP_AW_OFFSET, CMIS_TEMP_LWARN_STATUS },
|
||||
+
|
||||
+ { "Module voltage high alarm",
|
||||
+ CMIS_VCC_AW_OFFSET, CMIS_VCC_HALARM_STATUS },
|
||||
+ { "Module voltage low alarm",
|
||||
+ CMIS_VCC_AW_OFFSET, CMIS_VCC_LALARM_STATUS },
|
||||
+ { "Module voltage high warning",
|
||||
+ CMIS_VCC_AW_OFFSET, CMIS_VCC_HWARN_STATUS },
|
||||
+ { "Module voltage low warning",
|
||||
+ CMIS_VCC_AW_OFFSET, CMIS_VCC_LWARN_STATUS },
|
||||
+
|
||||
+ { NULL, 0, 0 },
|
||||
+};
|
||||
+
|
||||
+static struct {
|
||||
+ const char *fmt_str;
|
||||
+ int offset;
|
||||
+ int adver_offset; /* In Page 01h. */
|
||||
+ __u8 adver_value; /* Supported if (offset & value) != 0. */
|
||||
+} cmis_aw_chan_flags[] = {
|
||||
+ { "Laser bias current high alarm (Chan %d)",
|
||||
+ CMIS_TX_BIAS_AW_HALARM_OFFSET,
|
||||
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK },
|
||||
+ { "Laser bias current low alarm (Chan %d)",
|
||||
+ CMIS_TX_BIAS_AW_LALARM_OFFSET,
|
||||
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK },
|
||||
+ { "Laser bias current high warning (Chan %d)",
|
||||
+ CMIS_TX_BIAS_AW_HWARN_OFFSET,
|
||||
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK },
|
||||
+ { "Laser bias current low warning (Chan %d)",
|
||||
+ CMIS_TX_BIAS_AW_LWARN_OFFSET,
|
||||
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK },
|
||||
+
|
||||
+ { "Laser tx power high alarm (Channel %d)",
|
||||
+ CMIS_TX_PWR_AW_HALARM_OFFSET,
|
||||
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK },
|
||||
+ { "Laser tx power low alarm (Channel %d)",
|
||||
+ CMIS_TX_PWR_AW_LALARM_OFFSET,
|
||||
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK },
|
||||
+ { "Laser tx power high warning (Channel %d)",
|
||||
+ CMIS_TX_PWR_AW_HWARN_OFFSET,
|
||||
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK },
|
||||
+ { "Laser tx power low warning (Channel %d)",
|
||||
+ CMIS_TX_PWR_AW_LWARN_OFFSET,
|
||||
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK },
|
||||
+
|
||||
+ { "Laser rx power high alarm (Channel %d)",
|
||||
+ CMIS_RX_PWR_AW_HALARM_OFFSET,
|
||||
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK },
|
||||
+ { "Laser rx power low alarm (Channel %d)",
|
||||
+ CMIS_RX_PWR_AW_LALARM_OFFSET,
|
||||
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK },
|
||||
+ { "Laser rx power high warning (Channel %d)",
|
||||
+ CMIS_RX_PWR_AW_HWARN_OFFSET,
|
||||
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK },
|
||||
+ { "Laser rx power low warning (Channel %d)",
|
||||
+ CMIS_RX_PWR_AW_LWARN_OFFSET,
|
||||
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK },
|
||||
+
|
||||
+ { NULL, 0, 0, 0 },
|
||||
+};
|
||||
+
|
||||
static void cmis_show_identifier(const struct cmis_memory_map *map)
|
||||
{
|
||||
sff8024_show_identifier(map->lower_memory, CMIS_ID_OFFSET);
|
||||
@@ -277,32 +353,6 @@ static void cmis_show_mit_compliance(const struct cmis_memory_map *map)
|
||||
}
|
||||
}
|
||||
|
||||
-/*
|
||||
- * 2-byte internal temperature conversions:
|
||||
- * First byte is a signed 8-bit integer, which is the temp decimal part
|
||||
- * Second byte is a multiple of 1/256th of a degree, which is added to
|
||||
- * the dec part.
|
||||
- */
|
||||
-#define OFFSET_TO_TEMP(offset) ((__s16)OFFSET_TO_U16(offset))
|
||||
-
|
||||
-/**
|
||||
- * Print relevant module level monitoring values. Relevant documents:
|
||||
- * [1] CMIS Rev. 3:
|
||||
- * --> pag. 50, section 1.7.2.4, Table 22
|
||||
- *
|
||||
- * [2] CMIS Rev. 4:
|
||||
- * --> pag. 84, section 8.2.4, Table 8-6
|
||||
- */
|
||||
-static void cmis_show_mod_lvl_monitors(const struct cmis_memory_map *map)
|
||||
-{
|
||||
- const __u8 *id = map->lower_memory;
|
||||
-
|
||||
- PRINT_TEMP("Module temperature",
|
||||
- OFFSET_TO_TEMP(CMIS_CURR_TEMP_OFFSET));
|
||||
- PRINT_VCC("Module voltage",
|
||||
- OFFSET_TO_U16(CMIS_CURR_VCC_OFFSET));
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* Print relevant info about the maximum supported fiber media length
|
||||
* for each type of fiber media at the maximum module-supported bit rate.
|
||||
@@ -352,6 +402,368 @@ static void cmis_show_vendor_info(const struct cmis_memory_map *map)
|
||||
CMIS_CLEI_END_OFFSET, "CLEI code");
|
||||
}
|
||||
|
||||
+static void cmis_parse_dom_power_type(const struct cmis_memory_map *map,
|
||||
+ struct sff_diags *sd)
|
||||
+{
|
||||
+ sd->rx_power_type = map->page_01h[CMIS_DIAG_TYPE_OFFSET] &
|
||||
+ CMIS_RX_PWR_TYPE_MASK;
|
||||
+ sd->tx_power_type = map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] &
|
||||
+ CMIS_TX_PWR_MON_MASK;
|
||||
+}
|
||||
+
|
||||
+static void cmis_parse_dom_mod_lvl_monitors(const struct cmis_memory_map *map,
|
||||
+ struct sff_diags *sd)
|
||||
+{
|
||||
+ sd->sfp_voltage[MCURR] = OFFSET_TO_U16_PTR(map->lower_memory,
|
||||
+ CMIS_CURR_VCC_OFFSET);
|
||||
+ sd->sfp_temp[MCURR] = (__s16)OFFSET_TO_U16_PTR(map->lower_memory,
|
||||
+ CMIS_CURR_TEMP_OFFSET);
|
||||
+}
|
||||
+
|
||||
+static void cmis_parse_dom_mod_lvl_thresh(const struct cmis_memory_map *map,
|
||||
+ struct sff_diags *sd)
|
||||
+{
|
||||
+ /* Page is not present in IOCTL path. */
|
||||
+ if (!map->page_02h)
|
||||
+ return;
|
||||
+ sd->supports_alarms = 1;
|
||||
+
|
||||
+ sd->sfp_voltage[HALRM] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_VCC_HALRM_OFFSET);
|
||||
+ sd->sfp_voltage[LALRM] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_VCC_LALRM_OFFSET);
|
||||
+ sd->sfp_voltage[HWARN] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_VCC_HWARN_OFFSET);
|
||||
+ sd->sfp_voltage[LWARN] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_VCC_LWARN_OFFSET);
|
||||
+
|
||||
+ sd->sfp_temp[HALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_TEMP_HALRM_OFFSET);
|
||||
+ sd->sfp_temp[LALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_TEMP_LALRM_OFFSET);
|
||||
+ sd->sfp_temp[HWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_TEMP_HWARN_OFFSET);
|
||||
+ sd->sfp_temp[LWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_TEMP_LWARN_OFFSET);
|
||||
+}
|
||||
+
|
||||
+static __u8 cmis_tx_bias_mul(const struct cmis_memory_map *map)
|
||||
+{
|
||||
+ switch (map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] &
|
||||
+ CMIS_TX_BIAS_MUL_MASK) {
|
||||
+ case CMIS_TX_BIAS_MUL_1:
|
||||
+ return 0;
|
||||
+ case CMIS_TX_BIAS_MUL_2:
|
||||
+ return 1;
|
||||
+ case CMIS_TX_BIAS_MUL_4:
|
||||
+ return 2;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+cmis_parse_dom_chan_lvl_monitors_bank(const struct cmis_memory_map *map,
|
||||
+ struct sff_diags *sd, int bank)
|
||||
+{
|
||||
+ const __u8 *page_11h = map->upper_memory[bank][0x11];
|
||||
+ int i;
|
||||
+
|
||||
+ if (!page_11h)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
|
||||
+ __u8 tx_bias_offset, rx_power_offset, tx_power_offset;
|
||||
+ int chan = bank * CMIS_CHANNELS_PER_BANK + i;
|
||||
+ __u8 bias_mul = cmis_tx_bias_mul(map);
|
||||
+
|
||||
+ tx_bias_offset = CMIS_TX_BIAS_OFFSET + i * sizeof(__u16);
|
||||
+ rx_power_offset = CMIS_RX_PWR_OFFSET + i * sizeof(__u16);
|
||||
+ tx_power_offset = CMIS_TX_PWR_OFFSET + i * sizeof(__u16);
|
||||
+
|
||||
+ sd->scd[chan].bias_cur = OFFSET_TO_U16_PTR(page_11h,
|
||||
+ tx_bias_offset);
|
||||
+ sd->scd[chan].bias_cur >>= bias_mul;
|
||||
+ sd->scd[chan].rx_power = OFFSET_TO_U16_PTR(page_11h,
|
||||
+ rx_power_offset);
|
||||
+ sd->scd[chan].tx_power = OFFSET_TO_U16_PTR(page_11h,
|
||||
+ tx_power_offset);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void cmis_parse_dom_chan_lvl_monitors(const struct cmis_memory_map *map,
|
||||
+ struct sff_diags *sd)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < CMIS_MAX_BANKS; i++)
|
||||
+ cmis_parse_dom_chan_lvl_monitors_bank(map, sd, i);
|
||||
+}
|
||||
+
|
||||
+static void cmis_parse_dom_chan_lvl_thresh(const struct cmis_memory_map *map,
|
||||
+ struct sff_diags *sd)
|
||||
+{
|
||||
+ __u8 bias_mul = cmis_tx_bias_mul(map);
|
||||
+
|
||||
+ if (!map->page_02h)
|
||||
+ return;
|
||||
+
|
||||
+ sd->bias_cur[HALRM] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_TX_BIAS_HALRM_OFFSET);
|
||||
+ sd->bias_cur[HALRM] >>= bias_mul;
|
||||
+ sd->bias_cur[LALRM] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_TX_BIAS_LALRM_OFFSET);
|
||||
+ sd->bias_cur[LALRM] >>= bias_mul;
|
||||
+ sd->bias_cur[HWARN] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_TX_BIAS_HWARN_OFFSET);
|
||||
+ sd->bias_cur[HWARN] >>= bias_mul;
|
||||
+ sd->bias_cur[LWARN] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_TX_BIAS_LWARN_OFFSET);
|
||||
+ sd->bias_cur[LWARN] >>= bias_mul;
|
||||
+
|
||||
+ sd->tx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_TX_PWR_HALRM_OFFSET);
|
||||
+ sd->tx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_TX_PWR_LALRM_OFFSET);
|
||||
+ sd->tx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_TX_PWR_HWARN_OFFSET);
|
||||
+ sd->tx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_TX_PWR_LWARN_OFFSET);
|
||||
+
|
||||
+ sd->rx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_RX_PWR_HALRM_OFFSET);
|
||||
+ sd->rx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_RX_PWR_LALRM_OFFSET);
|
||||
+ sd->rx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_RX_PWR_HWARN_OFFSET);
|
||||
+ sd->rx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_02h,
|
||||
+ CMIS_RX_PWR_LWARN_OFFSET);
|
||||
+}
|
||||
+
|
||||
+static void cmis_parse_dom(const struct cmis_memory_map *map,
|
||||
+ struct sff_diags *sd)
|
||||
+{
|
||||
+ cmis_parse_dom_power_type(map, sd);
|
||||
+ cmis_parse_dom_mod_lvl_monitors(map, sd);
|
||||
+ cmis_parse_dom_mod_lvl_thresh(map, sd);
|
||||
+ cmis_parse_dom_chan_lvl_monitors(map, sd);
|
||||
+ cmis_parse_dom_chan_lvl_thresh(map, sd);
|
||||
+}
|
||||
+
|
||||
+/* Print module-level monitoring values. Relevant documents:
|
||||
+ * [1] CMIS Rev. 5, page 110, section 8.2.5, Table 8-9
|
||||
+ */
|
||||
+static void cmis_show_dom_mod_lvl_monitors(const struct sff_diags *sd)
|
||||
+{
|
||||
+ PRINT_TEMP("Module temperature", sd->sfp_temp[MCURR]);
|
||||
+ PRINT_VCC("Module voltage", sd->sfp_voltage[MCURR]);
|
||||
+}
|
||||
+
|
||||
+/* Print channel Tx laser bias current. Relevant documents:
|
||||
+ * [1] CMIS Rev. 5, page 165, section 8.9.4, Table 8-79
|
||||
+ */
|
||||
+static void
|
||||
+cmis_show_dom_chan_lvl_tx_bias_bank(const struct cmis_memory_map *map,
|
||||
+ const struct sff_diags *sd, int bank)
|
||||
+{
|
||||
+ const __u8 *page_11h = map->upper_memory[bank][0x11];
|
||||
+ int i;
|
||||
+
|
||||
+ if (!page_11h)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
|
||||
+ int chan = bank * CMIS_CHANNELS_PER_BANK + i;
|
||||
+ char fmt_str[80];
|
||||
+
|
||||
+ snprintf(fmt_str, 80, "%s (Channel %d)",
|
||||
+ "Laser tx bias current", chan + 1);
|
||||
+ PRINT_BIAS(fmt_str, sd->scd[chan].bias_cur);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void cmis_show_dom_chan_lvl_tx_bias(const struct cmis_memory_map *map,
|
||||
+ const struct sff_diags *sd)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ if(!(map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] &
|
||||
+ CMIS_TX_BIAS_MON_MASK))
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < CMIS_MAX_BANKS; i++)
|
||||
+ cmis_show_dom_chan_lvl_tx_bias_bank(map, sd, i);
|
||||
+}
|
||||
+
|
||||
+/* Print channel Tx average optical power. Relevant documents:
|
||||
+ * [1] CMIS Rev. 5, page 165, section 8.9.4, Table 8-79
|
||||
+ */
|
||||
+static void
|
||||
+cmis_show_dom_chan_lvl_tx_power_bank(const struct cmis_memory_map *map,
|
||||
+ const struct sff_diags *sd, int bank)
|
||||
+{
|
||||
+ const __u8 *page_11h = map->upper_memory[bank][0x11];
|
||||
+ int i;
|
||||
+
|
||||
+ if (!page_11h)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
|
||||
+ int chan = bank * CMIS_CHANNELS_PER_BANK + i;
|
||||
+ char fmt_str[80];
|
||||
+
|
||||
+ snprintf(fmt_str, 80, "%s (Channel %d)",
|
||||
+ "Transmit avg optical power", chan + 1);
|
||||
+ PRINT_xX_PWR(fmt_str, sd->scd[chan].tx_power);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void cmis_show_dom_chan_lvl_tx_power(const struct cmis_memory_map *map,
|
||||
+ const struct sff_diags *sd)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ if (!sd->tx_power_type)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < CMIS_MAX_BANKS; i++)
|
||||
+ cmis_show_dom_chan_lvl_tx_power_bank(map, sd, i);
|
||||
+}
|
||||
+
|
||||
+/* Print channel Rx input optical power. Relevant documents:
|
||||
+ * [1] CMIS Rev. 5, page 165, section 8.9.4, Table 8-79
|
||||
+ */
|
||||
+static void
|
||||
+cmis_show_dom_chan_lvl_rx_power_bank(const struct cmis_memory_map *map,
|
||||
+ const struct sff_diags *sd, int bank)
|
||||
+{
|
||||
+ const __u8 *page_11h = map->upper_memory[bank][0x11];
|
||||
+ int i;
|
||||
+
|
||||
+ if (!page_11h)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
|
||||
+ int chan = bank * CMIS_CHANNELS_PER_BANK + i;
|
||||
+ char *rx_power_str;
|
||||
+ char fmt_str[80];
|
||||
+
|
||||
+ if (!sd->rx_power_type)
|
||||
+ rx_power_str = "Receiver signal OMA";
|
||||
+ else
|
||||
+ rx_power_str = "Rcvr signal avg optical power";
|
||||
+
|
||||
+ snprintf(fmt_str, 80, "%s (Channel %d)", rx_power_str,
|
||||
+ chan + 1);
|
||||
+ PRINT_xX_PWR(fmt_str, sd->scd[chan].rx_power);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void cmis_show_dom_chan_lvl_rx_power(const struct cmis_memory_map *map,
|
||||
+ const struct sff_diags *sd)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ if(!(map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] & CMIS_RX_PWR_MON_MASK))
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < CMIS_MAX_BANKS; i++)
|
||||
+ cmis_show_dom_chan_lvl_rx_power_bank(map, sd, i);
|
||||
+}
|
||||
+
|
||||
+static void cmis_show_dom_chan_lvl_monitors(const struct cmis_memory_map *map,
|
||||
+ const struct sff_diags *sd)
|
||||
+{
|
||||
+ cmis_show_dom_chan_lvl_tx_bias(map, sd);
|
||||
+ cmis_show_dom_chan_lvl_tx_power(map, sd);
|
||||
+ cmis_show_dom_chan_lvl_rx_power(map, sd);
|
||||
+}
|
||||
+
|
||||
+/* Print module-level flags. Relevant documents:
|
||||
+ * [1] CMIS Rev. 5, page 109, section 8.2.4, Table 8-8
|
||||
+ */
|
||||
+static void cmis_show_dom_mod_lvl_flags(const struct cmis_memory_map *map)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; cmis_aw_mod_flags[i].str; i++) {
|
||||
+ printf("\t%-41s : %s\n", cmis_aw_mod_flags[i].str,
|
||||
+ map->lower_memory[cmis_aw_mod_flags[i].offset] &
|
||||
+ cmis_aw_mod_flags[i].value ? "On" : "Off");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Print channel-level flags. Relevant documents:
|
||||
+ * [1] CMIS Rev. 5, page 162, section 8.9.3, Table 8-77
|
||||
+ * [1] CMIS Rev. 5, page 164, section 8.9.3, Table 8-78
|
||||
+ */
|
||||
+static void cmis_show_dom_chan_lvl_flags_chan(const struct cmis_memory_map *map,
|
||||
+ int bank, int chan)
|
||||
+{
|
||||
+ const __u8 *page_11h = map->upper_memory[bank][0x11];
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; cmis_aw_chan_flags[i].fmt_str; i++) {
|
||||
+ char str[80];
|
||||
+
|
||||
+ if (!(map->page_01h[cmis_aw_chan_flags[i].adver_offset] &
|
||||
+ cmis_aw_chan_flags[i].adver_value))
|
||||
+ continue;
|
||||
+
|
||||
+ snprintf(str, 80, cmis_aw_chan_flags[i].fmt_str, chan + 1);
|
||||
+ printf("\t%-41s : %s\n", str,
|
||||
+ page_11h[cmis_aw_chan_flags[i].offset] & chan ?
|
||||
+ "On" : "Off");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+cmis_show_dom_chan_lvl_flags_bank(const struct cmis_memory_map *map,
|
||||
+ int bank)
|
||||
+{
|
||||
+ const __u8 *page_11h = map->upper_memory[bank][0x11];
|
||||
+ int i;
|
||||
+
|
||||
+ if (!page_11h)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
|
||||
+ int chan = bank * CMIS_CHANNELS_PER_BANK + i;
|
||||
+
|
||||
+ cmis_show_dom_chan_lvl_flags_chan(map, bank, chan);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void cmis_show_dom_chan_lvl_flags(const struct cmis_memory_map *map)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < CMIS_MAX_BANKS; i++)
|
||||
+ cmis_show_dom_chan_lvl_flags_bank(map, i);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void cmis_show_dom(const struct cmis_memory_map *map)
|
||||
+{
|
||||
+ struct sff_diags sd = {};
|
||||
+
|
||||
+ /* Diagnostic information is only relevant when the module memory
|
||||
+ * model is paged and not flat.
|
||||
+ */
|
||||
+ if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
|
||||
+ CMIS_MEMORY_MODEL_MASK)
|
||||
+ return;
|
||||
+
|
||||
+ cmis_parse_dom(map, &sd);
|
||||
+
|
||||
+ cmis_show_dom_mod_lvl_monitors(&sd);
|
||||
+ cmis_show_dom_chan_lvl_monitors(map, &sd);
|
||||
+ cmis_show_dom_mod_lvl_flags(map);
|
||||
+ cmis_show_dom_chan_lvl_flags(map);
|
||||
+ if (sd.supports_alarms)
|
||||
+ sff_show_thresholds(sd);
|
||||
+}
|
||||
+
|
||||
static void cmis_show_all_common(const struct cmis_memory_map *map)
|
||||
{
|
||||
cmis_show_identifier(map);
|
||||
@@ -360,10 +772,10 @@ static void cmis_show_all_common(const struct cmis_memory_map *map)
|
||||
cmis_show_cbl_asm_len(map);
|
||||
cmis_show_sig_integrity(map);
|
||||
cmis_show_mit_compliance(map);
|
||||
- cmis_show_mod_lvl_monitors(map);
|
||||
cmis_show_link_len(map);
|
||||
cmis_show_vendor_info(map);
|
||||
cmis_show_rev_compliance(map);
|
||||
+ cmis_show_dom(map);
|
||||
}
|
||||
|
||||
static void cmis_memory_map_init_buf(struct cmis_memory_map *map,
|
||||
diff --git a/cmis.h b/cmis.h
|
||||
index 8d90a04756ad..310697b0ef32 100644
|
||||
--- a/cmis.h
|
||||
+++ b/cmis.h
|
||||
@@ -7,6 +7,18 @@
|
||||
#define CMIS_MEMORY_MODEL_OFFSET 0x02
|
||||
#define CMIS_MEMORY_MODEL_MASK 0x80
|
||||
|
||||
+/* Module Flags (Page 0) */
|
||||
+#define CMIS_VCC_AW_OFFSET 0x09
|
||||
+#define CMIS_VCC_LWARN_STATUS 0x80
|
||||
+#define CMIS_VCC_HWARN_STATUS 0x40
|
||||
+#define CMIS_VCC_LALARM_STATUS 0x20
|
||||
+#define CMIS_VCC_HALARM_STATUS 0x10
|
||||
+#define CMIS_TEMP_AW_OFFSET 0x09
|
||||
+#define CMIS_TEMP_LWARN_STATUS 0x08
|
||||
+#define CMIS_TEMP_HWARN_STATUS 0x04
|
||||
+#define CMIS_TEMP_LALARM_STATUS 0x02
|
||||
+#define CMIS_TEMP_HALARM_STATUS 0x01
|
||||
+
|
||||
#define CMIS_MODULE_TYPE_OFFSET 0x55
|
||||
#define CMIS_MT_MMF 0x01
|
||||
#define CMIS_MT_SMF 0x02
|
||||
@@ -121,10 +133,77 @@
|
||||
#define CMIS_BANK_0_1_SUPPORTED 0x01
|
||||
#define CMIS_BANK_0_3_SUPPORTED 0x02
|
||||
|
||||
+/* Module Characteristics Advertising (Page 1) */
|
||||
+#define CMIS_DIAG_TYPE_OFFSET 0x97
|
||||
+#define CMIS_RX_PWR_TYPE_MASK 0x10
|
||||
+
|
||||
+/* Supported Monitors Advertisement (Page 1) */
|
||||
+#define CMIS_DIAG_CHAN_ADVER_OFFSET 0xA0
|
||||
+#define CMIS_TX_BIAS_MON_MASK 0x01
|
||||
+#define CMIS_TX_PWR_MON_MASK 0x02
|
||||
+#define CMIS_RX_PWR_MON_MASK 0x04
|
||||
+#define CMIS_TX_BIAS_MUL_MASK 0x18
|
||||
+#define CMIS_TX_BIAS_MUL_1 0x00
|
||||
+#define CMIS_TX_BIAS_MUL_2 0x08
|
||||
+#define CMIS_TX_BIAS_MUL_4 0x10
|
||||
+
|
||||
/* Signal integrity controls */
|
||||
#define CMIS_SIG_INTEG_TX_OFFSET 0xA1
|
||||
#define CMIS_SIG_INTEG_RX_OFFSET 0xA2
|
||||
|
||||
+/*-----------------------------------------------------------------------
|
||||
+ * Upper Memory Page 0x02: Optional Page that informs about module-defined
|
||||
+ * thresholds for module-level and lane-specific threshold crossing monitors.
|
||||
+ */
|
||||
+
|
||||
+/* Module-Level Monitor Thresholds (Page 2) */
|
||||
+#define CMIS_TEMP_HALRM_OFFSET 0x80
|
||||
+#define CMIS_TEMP_LALRM_OFFSET 0x82
|
||||
+#define CMIS_TEMP_HWARN_OFFSET 0x84
|
||||
+#define CMIS_TEMP_LWARN_OFFSET 0x86
|
||||
+#define CMIS_VCC_HALRM_OFFSET 0x88
|
||||
+#define CMIS_VCC_LALRM_OFFSET 0x8A
|
||||
+#define CMIS_VCC_HWARN_OFFSET 0x8C
|
||||
+#define CMIS_VCC_LWARN_OFFSET 0x8E
|
||||
+
|
||||
+/* Lane-Related Monitor Thresholds (Page 2) */
|
||||
+#define CMIS_TX_PWR_HALRM_OFFSET 0xB0
|
||||
+#define CMIS_TX_PWR_LALRM_OFFSET 0xB2
|
||||
+#define CMIS_TX_PWR_HWARN_OFFSET 0xB4
|
||||
+#define CMIS_TX_PWR_LWARN_OFFSET 0xB6
|
||||
+#define CMIS_TX_BIAS_HALRM_OFFSET 0xB8
|
||||
+#define CMIS_TX_BIAS_LALRM_OFFSET 0xBA
|
||||
+#define CMIS_TX_BIAS_HWARN_OFFSET 0xBC
|
||||
+#define CMIS_TX_BIAS_LWARN_OFFSET 0xBE
|
||||
+#define CMIS_RX_PWR_HALRM_OFFSET 0xC0
|
||||
+#define CMIS_RX_PWR_LALRM_OFFSET 0xC2
|
||||
+#define CMIS_RX_PWR_HWARN_OFFSET 0xC4
|
||||
+#define CMIS_RX_PWR_LWARN_OFFSET 0xC6
|
||||
+
|
||||
+/*-----------------------------------------------------------------------
|
||||
+ * Upper Memory Page 0x11: Optional Page that contains lane dynamic status
|
||||
+ * bytes.
|
||||
+ */
|
||||
+
|
||||
+/* Media Lane-Specific Flags (Page 0x11) */
|
||||
+#define CMIS_TX_PWR_AW_HALARM_OFFSET 0x8B
|
||||
+#define CMIS_TX_PWR_AW_LALARM_OFFSET 0x8C
|
||||
+#define CMIS_TX_PWR_AW_HWARN_OFFSET 0x8D
|
||||
+#define CMIS_TX_PWR_AW_LWARN_OFFSET 0x8E
|
||||
+#define CMIS_TX_BIAS_AW_HALARM_OFFSET 0x8F
|
||||
+#define CMIS_TX_BIAS_AW_LALARM_OFFSET 0x90
|
||||
+#define CMIS_TX_BIAS_AW_HWARN_OFFSET 0x91
|
||||
+#define CMIS_TX_BIAS_AW_LWARN_OFFSET 0x92
|
||||
+#define CMIS_RX_PWR_AW_HALARM_OFFSET 0x95
|
||||
+#define CMIS_RX_PWR_AW_LALARM_OFFSET 0x96
|
||||
+#define CMIS_RX_PWR_AW_HWARN_OFFSET 0x97
|
||||
+#define CMIS_RX_PWR_AW_LWARN_OFFSET 0x98
|
||||
+
|
||||
+/* Media Lane-Specific Monitors (Page 0x11) */
|
||||
+#define CMIS_TX_PWR_OFFSET 0x9A
|
||||
+#define CMIS_TX_BIAS_OFFSET 0xAA
|
||||
+#define CMIS_RX_PWR_OFFSET 0xBA
|
||||
+
|
||||
#define YESNO(x) (((x) != 0) ? "Yes" : "No")
|
||||
#define ONOFF(x) (((x) != 0) ? "On" : "Off")
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
155
SOURCES/0032-cmis-Print-Module-State-and-Fault-Cause.patch
Normal file
155
SOURCES/0032-cmis-Print-Module-State-and-Fault-Cause.patch
Normal file
@ -0,0 +1,155 @@
|
||||
From 4a86034f138e1a96e54047b8036b0a4425e99944 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 23 Nov 2021 19:41:00 +0200
|
||||
Subject: [PATCH 32/35] cmis: Print Module State and Fault Cause
|
||||
|
||||
Print the CMIS Module State when dumping EEPROM contents via the '-m'
|
||||
option. It can be used, for example, to test module power mode settings.
|
||||
|
||||
Example output:
|
||||
|
||||
# ethtool -m swp11
|
||||
Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
|
||||
...
|
||||
Module State : 0x03 (ModuleReady)
|
||||
|
||||
# ethtool --set-module swp11 power-mode-policy auto
|
||||
|
||||
# ethtool -m swp11
|
||||
Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
|
||||
...
|
||||
Module State : 0x01 (ModuleLowPwr)
|
||||
|
||||
In case the module is in fault state, print the CMIS Module Fault Cause.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
cmis.h | 16 ++++++++++++++
|
||||
2 files changed, 86 insertions(+)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index d7b7097139b3..a32cc9f8b1f6 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -402,6 +402,74 @@ static void cmis_show_vendor_info(const struct cmis_memory_map *map)
|
||||
CMIS_CLEI_END_OFFSET, "CLEI code");
|
||||
}
|
||||
|
||||
+/* Print the current Module State. Relevant documents:
|
||||
+ * [1] CMIS Rev. 5, pag. 57, section 6.3.2.2, Figure 6-3
|
||||
+ * [2] CMIS Rev. 5, pag. 60, section 6.3.2.3, Figure 6-4
|
||||
+ * [3] CMIS Rev. 5, pag. 107, section 8.2.2, Table 8-6
|
||||
+ */
|
||||
+static void cmis_show_mod_state(const struct cmis_memory_map *map)
|
||||
+{
|
||||
+ __u8 mod_state;
|
||||
+
|
||||
+ mod_state = (map->lower_memory[CMIS_MODULE_STATE_OFFSET] &
|
||||
+ CMIS_MODULE_STATE_MASK) >> 1;
|
||||
+ printf("\t%-41s : 0x%02x", "Module State", mod_state);
|
||||
+ switch (mod_state) {
|
||||
+ case CMIS_MODULE_STATE_MODULE_LOW_PWR:
|
||||
+ printf(" (ModuleLowPwr)\n");
|
||||
+ break;
|
||||
+ case CMIS_MODULE_STATE_MODULE_PWR_UP:
|
||||
+ printf(" (ModulePwrUp)\n");
|
||||
+ break;
|
||||
+ case CMIS_MODULE_STATE_MODULE_READY:
|
||||
+ printf(" (ModuleReady)\n");
|
||||
+ break;
|
||||
+ case CMIS_MODULE_STATE_MODULE_PWR_DN:
|
||||
+ printf(" (ModulePwrDn)\n");
|
||||
+ break;
|
||||
+ case CMIS_MODULE_STATE_MODULE_FAULT:
|
||||
+ printf(" (ModuleFault)\n");
|
||||
+ break;
|
||||
+ default:
|
||||
+ printf(" (reserved or unknown)\n");
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Print the Module Fault Information. Relevant documents:
|
||||
+ * [1] CMIS Rev. 5, pag. 64, section 6.3.2.12
|
||||
+ * [2] CMIS Rev. 5, pag. 115, section 8.2.10, Table 8-15
|
||||
+ */
|
||||
+static void cmis_show_mod_fault_cause(const struct cmis_memory_map *map)
|
||||
+{
|
||||
+ __u8 mod_state, fault_cause;
|
||||
+
|
||||
+ mod_state = (map->lower_memory[CMIS_MODULE_STATE_OFFSET] &
|
||||
+ CMIS_MODULE_STATE_MASK) >> 1;
|
||||
+ if (mod_state != CMIS_MODULE_STATE_MODULE_FAULT)
|
||||
+ return;
|
||||
+
|
||||
+ fault_cause = map->lower_memory[CMIS_MODULE_FAULT_OFFSET];
|
||||
+ printf("\t%-41s : 0x%02x", "Module Fault Cause", fault_cause);
|
||||
+ switch (fault_cause) {
|
||||
+ case CMIS_MODULE_FAULT_NO_FAULT:
|
||||
+ printf(" (No fault detected / not supported)\n");
|
||||
+ break;
|
||||
+ case CMIS_MODULE_FAULT_TEC_RUNAWAY:
|
||||
+ printf(" (TEC runaway)\n");
|
||||
+ break;
|
||||
+ case CMIS_MODULE_FAULT_DATA_MEM_CORRUPTED:
|
||||
+ printf(" (Data memory corrupted)\n");
|
||||
+ break;
|
||||
+ case CMIS_MODULE_FAULT_PROG_MEM_CORRUPTED:
|
||||
+ printf(" (Program memory corrupted)\n");
|
||||
+ break;
|
||||
+ default:
|
||||
+ printf(" (reserved or unknown)\n");
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void cmis_parse_dom_power_type(const struct cmis_memory_map *map,
|
||||
struct sff_diags *sd)
|
||||
{
|
||||
@@ -775,6 +843,8 @@ static void cmis_show_all_common(const struct cmis_memory_map *map)
|
||||
cmis_show_link_len(map);
|
||||
cmis_show_vendor_info(map);
|
||||
cmis_show_rev_compliance(map);
|
||||
+ cmis_show_mod_state(map);
|
||||
+ cmis_show_mod_fault_cause(map);
|
||||
cmis_show_dom(map);
|
||||
}
|
||||
|
||||
diff --git a/cmis.h b/cmis.h
|
||||
index 310697b0ef32..2c67ad5640ab 100644
|
||||
--- a/cmis.h
|
||||
+++ b/cmis.h
|
||||
@@ -7,6 +7,15 @@
|
||||
#define CMIS_MEMORY_MODEL_OFFSET 0x02
|
||||
#define CMIS_MEMORY_MODEL_MASK 0x80
|
||||
|
||||
+/* Global Status Information (Page 0) */
|
||||
+#define CMIS_MODULE_STATE_OFFSET 0x03
|
||||
+#define CMIS_MODULE_STATE_MASK 0x0E
|
||||
+#define CMIS_MODULE_STATE_MODULE_LOW_PWR 0x01
|
||||
+#define CMIS_MODULE_STATE_MODULE_PWR_UP 0x02
|
||||
+#define CMIS_MODULE_STATE_MODULE_READY 0x03
|
||||
+#define CMIS_MODULE_STATE_MODULE_PWR_DN 0x04
|
||||
+#define CMIS_MODULE_STATE_MODULE_FAULT 0x05
|
||||
+
|
||||
/* Module Flags (Page 0) */
|
||||
#define CMIS_VCC_AW_OFFSET 0x09
|
||||
#define CMIS_VCC_LWARN_STATUS 0x80
|
||||
@@ -27,6 +36,13 @@
|
||||
#define CMIS_CURR_TEMP_OFFSET 0x0E
|
||||
#define CMIS_CURR_VCC_OFFSET 0x10
|
||||
|
||||
+/* Module Fault Information (Page 0) */
|
||||
+#define CMIS_MODULE_FAULT_OFFSET 0x29
|
||||
+#define CMIS_MODULE_FAULT_NO_FAULT 0x00
|
||||
+#define CMIS_MODULE_FAULT_TEC_RUNAWAY 0x01
|
||||
+#define CMIS_MODULE_FAULT_DATA_MEM_CORRUPTED 0x02
|
||||
+#define CMIS_MODULE_FAULT_PROG_MEM_CORRUPTED 0x03
|
||||
+
|
||||
#define CMIS_CTOR_OFFSET 0xCB
|
||||
|
||||
/* Vendor related information (Page 0) */
|
||||
--
|
||||
2.35.1
|
||||
|
196
SOURCES/0033-cmis-Print-Module-Level-Controls.patch
Normal file
196
SOURCES/0033-cmis-Print-Module-Level-Controls.patch
Normal file
@ -0,0 +1,196 @@
|
||||
From 0b45f392c6c92e9823d6332622d7a45e7a36365e Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 23 Nov 2021 19:41:01 +0200
|
||||
Subject: [PATCH 33/35] cmis: Print Module-Level Controls
|
||||
|
||||
Print the CMIS Module-Level Controls when dumping EEPROM contents via
|
||||
the '-m' option. It can be used to understand low power mode enforcement
|
||||
by the host.
|
||||
|
||||
Example output:
|
||||
|
||||
# ethtool -m swp11
|
||||
Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
|
||||
...
|
||||
Module State : 0x03 (ModuleReady)
|
||||
LowPwrAllowRequestHW : Off
|
||||
LowPwrRequestSW : Off
|
||||
...
|
||||
Transmit avg optical power (Channel 1) : 1.3222 mW / 1.21 dBm
|
||||
Transmit avg optical power (Channel 2) : 1.2666 mW / 1.03 dBm
|
||||
Transmit avg optical power (Channel 3) : 1.2860 mW / 1.09 dBm
|
||||
Transmit avg optical power (Channel 4) : 1.2988 mW / 1.14 dBm
|
||||
Transmit avg optical power (Channel 5) : 1.2828 mW / 1.08 dBm
|
||||
Transmit avg optical power (Channel 6) : 1.2913 mW / 1.11 dBm
|
||||
Transmit avg optical power (Channel 7) : 1.2636 mW / 1.02 dBm
|
||||
Transmit avg optical power (Channel 8) : 1.3408 mW / 1.27 dBm
|
||||
Transmit avg optical power (Channel 9) : 1.3222 mW / 1.21 dBm
|
||||
Transmit avg optical power (Channel 10) : 1.2666 mW / 1.03 dBm
|
||||
Transmit avg optical power (Channel 11) : 1.2860 mW / 1.09 dBm
|
||||
Transmit avg optical power (Channel 12) : 1.2988 mW / 1.14 dBm
|
||||
Transmit avg optical power (Channel 13) : 1.2828 mW / 1.08 dBm
|
||||
Transmit avg optical power (Channel 14) : 1.2913 mW / 1.11 dBm
|
||||
Transmit avg optical power (Channel 15) : 1.2636 mW / 1.02 dBm
|
||||
Transmit avg optical power (Channel 16) : 1.3408 mW / 1.27 dBm
|
||||
Rcvr signal avg optical power (Channel 1) : 1.1351 mW / 0.55 dBm
|
||||
Rcvr signal avg optical power (Channel 2) : 1.1603 mW / 0.65 dBm
|
||||
Rcvr signal avg optical power (Channel 3) : 1.1529 mW / 0.62 dBm
|
||||
Rcvr signal avg optical power (Channel 4) : 1.1670 mW / 0.67 dBm
|
||||
Rcvr signal avg optical power (Channel 5) : 1.1759 mW / 0.70 dBm
|
||||
Rcvr signal avg optical power (Channel 6) : 1.1744 mW / 0.70 dBm
|
||||
Rcvr signal avg optical power (Channel 7) : 1.1188 mW / 0.49 dBm
|
||||
Rcvr signal avg optical power (Channel 8) : 1.1640 mW / 0.66 dBm
|
||||
Rcvr signal avg optical power (Channel 9) : 1.1351 mW / 0.55 dBm
|
||||
Rcvr signal avg optical power (Channel 10) : 1.1603 mW / 0.65 dBm
|
||||
Rcvr signal avg optical power (Channel 11) : 1.1529 mW / 0.62 dBm
|
||||
Rcvr signal avg optical power (Channel 12) : 1.1670 mW / 0.67 dBm
|
||||
Rcvr signal avg optical power (Channel 13) : 1.1759 mW / 0.70 dBm
|
||||
Rcvr signal avg optical power (Channel 14) : 1.1744 mW / 0.70 dBm
|
||||
Rcvr signal avg optical power (Channel 15) : 1.1188 mW / 0.49 dBm
|
||||
Rcvr signal avg optical power (Channel 16) : 1.1640 mW / 0.66 dBm
|
||||
|
||||
# ethtool --set-module swp11 power-mode-policy auto
|
||||
|
||||
# ethtool -m swp11
|
||||
Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
|
||||
...
|
||||
Module State : 0x01 (ModuleLowPwr)
|
||||
LowPwrAllowRequestHW : Off
|
||||
LowPwrRequestSW : On
|
||||
...
|
||||
Transmit avg optical power (Channel 1) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 2) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 3) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 4) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 5) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 6) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 7) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 8) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 9) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 10) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 11) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 12) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 13) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 14) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 15) : 0.0001 mW / -40.00 dBm
|
||||
Transmit avg optical power (Channel 16) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 1) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 2) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 3) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 4) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 5) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 6) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 7) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 8) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 9) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 10) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 11) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 12) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 13) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 14) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 15) : 0.0001 mW / -40.00 dBm
|
||||
Rcvr signal avg optical power (Channel 16) : 0.0001 mW / -40.00 dBm
|
||||
|
||||
# ethtool --set-module swp11 power-mode-policy high
|
||||
|
||||
# ethtool -m swp11
|
||||
Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
|
||||
...
|
||||
Module State : 0x03 (ModuleReady)
|
||||
LowPwrAllowRequestHW : Off
|
||||
LowPwrRequestSW : Off
|
||||
...
|
||||
Transmit avg optical power (Channel 1) : 1.3690 mW / 1.36 dBm
|
||||
Transmit avg optical power (Channel 2) : 1.3036 mW / 1.15 dBm
|
||||
Transmit avg optical power (Channel 3) : 1.3358 mW / 1.26 dBm
|
||||
Transmit avg optical power (Channel 4) : 1.3509 mW / 1.31 dBm
|
||||
Transmit avg optical power (Channel 5) : 1.3193 mW / 1.20 dBm
|
||||
Transmit avg optical power (Channel 6) : 1.3314 mW / 1.24 dBm
|
||||
Transmit avg optical power (Channel 7) : 1.3042 mW / 1.15 dBm
|
||||
Transmit avg optical power (Channel 8) : 1.3919 mW / 1.44 dBm
|
||||
Transmit avg optical power (Channel 9) : 1.3690 mW / 1.36 dBm
|
||||
Transmit avg optical power (Channel 10) : 1.3036 mW / 1.15 dBm
|
||||
Transmit avg optical power (Channel 11) : 1.3358 mW / 1.26 dBm
|
||||
Transmit avg optical power (Channel 12) : 1.3509 mW / 1.31 dBm
|
||||
Transmit avg optical power (Channel 13) : 1.3193 mW / 1.20 dBm
|
||||
Transmit avg optical power (Channel 14) : 1.3314 mW / 1.24 dBm
|
||||
Transmit avg optical power (Channel 15) : 1.3042 mW / 1.15 dBm
|
||||
Transmit avg optical power (Channel 16) : 1.3919 mW / 1.44 dBm
|
||||
Rcvr signal avg optical power (Channel 1) : 1.1299 mW / 0.53 dBm
|
||||
Rcvr signal avg optical power (Channel 2) : 1.1566 mW / 0.63 dBm
|
||||
Rcvr signal avg optical power (Channel 3) : 1.1484 mW / 0.60 dBm
|
||||
Rcvr signal avg optical power (Channel 4) : 1.1655 mW / 0.67 dBm
|
||||
Rcvr signal avg optical power (Channel 5) : 1.1751 mW / 0.70 dBm
|
||||
Rcvr signal avg optical power (Channel 6) : 1.1595 mW / 0.64 dBm
|
||||
Rcvr signal avg optical power (Channel 7) : 1.1158 mW / 0.48 dBm
|
||||
Rcvr signal avg optical power (Channel 8) : 1.1595 mW / 0.64 dBm
|
||||
Rcvr signal avg optical power (Channel 9) : 1.1299 mW / 0.53 dBm
|
||||
Rcvr signal avg optical power (Channel 10) : 1.1566 mW / 0.63 dBm
|
||||
Rcvr signal avg optical power (Channel 11) : 1.1484 mW / 0.60 dBm
|
||||
Rcvr signal avg optical power (Channel 12) : 1.1655 mW / 0.67 dBm
|
||||
Rcvr signal avg optical power (Channel 13) : 1.1751 mW / 0.70 dBm
|
||||
Rcvr signal avg optical power (Channel 14) : 1.1595 mW / 0.64 dBm
|
||||
Rcvr signal avg optical power (Channel 15) : 1.1158 mW / 0.48 dBm
|
||||
Rcvr signal avg optical power (Channel 16) : 1.1595 mW / 0.64 dBm
|
||||
|
||||
In the above example, the LowPwrRequestHW signal is ignored and low
|
||||
power mode is controlled via software only.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
cmis.c | 15 +++++++++++++++
|
||||
cmis.h | 5 +++++
|
||||
2 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/cmis.c b/cmis.c
|
||||
index a32cc9f8b1f6..d0b62728e998 100644
|
||||
--- a/cmis.c
|
||||
+++ b/cmis.c
|
||||
@@ -470,6 +470,20 @@ static void cmis_show_mod_fault_cause(const struct cmis_memory_map *map)
|
||||
}
|
||||
}
|
||||
|
||||
+/* Print the current Module-Level Controls. Relevant documents:
|
||||
+ * [1] CMIS Rev. 5, pag. 58, section 6.3.2.2, Table 6-12
|
||||
+ * [2] CMIS Rev. 5, pag. 111, section 8.2.6, Table 8-10
|
||||
+ */
|
||||
+static void cmis_show_mod_lvl_controls(const struct cmis_memory_map *map)
|
||||
+{
|
||||
+ printf("\t%-41s : ", "LowPwrAllowRequestHW");
|
||||
+ printf("%s\n", ONOFF(map->lower_memory[CMIS_MODULE_CONTROL_OFFSET] &
|
||||
+ CMIS_LOW_PWR_ALLOW_REQUEST_HW_MASK));
|
||||
+ printf("\t%-41s : ", "LowPwrRequestSW");
|
||||
+ printf("%s\n", ONOFF(map->lower_memory[CMIS_MODULE_CONTROL_OFFSET] &
|
||||
+ CMIS_LOW_PWR_REQUEST_SW_MASK));
|
||||
+}
|
||||
+
|
||||
static void cmis_parse_dom_power_type(const struct cmis_memory_map *map,
|
||||
struct sff_diags *sd)
|
||||
{
|
||||
@@ -845,6 +859,7 @@ static void cmis_show_all_common(const struct cmis_memory_map *map)
|
||||
cmis_show_rev_compliance(map);
|
||||
cmis_show_mod_state(map);
|
||||
cmis_show_mod_fault_cause(map);
|
||||
+ cmis_show_mod_lvl_controls(map);
|
||||
cmis_show_dom(map);
|
||||
}
|
||||
|
||||
diff --git a/cmis.h b/cmis.h
|
||||
index 2c67ad5640ab..46797081f13c 100644
|
||||
--- a/cmis.h
|
||||
+++ b/cmis.h
|
||||
@@ -36,6 +36,11 @@
|
||||
#define CMIS_CURR_TEMP_OFFSET 0x0E
|
||||
#define CMIS_CURR_VCC_OFFSET 0x10
|
||||
|
||||
+/* Module Global Controls (Page 0) */
|
||||
+#define CMIS_MODULE_CONTROL_OFFSET 0x1A
|
||||
+#define CMIS_LOW_PWR_ALLOW_REQUEST_HW_MASK 0x40
|
||||
+#define CMIS_LOW_PWR_REQUEST_SW_MASK 0x10
|
||||
+
|
||||
/* Module Fault Information (Page 0) */
|
||||
#define CMIS_MODULE_FAULT_OFFSET 0x29
|
||||
#define CMIS_MODULE_FAULT_NO_FAULT 0x00
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,108 @@
|
||||
From 48391fa16592b47d37ef63466111c751a10c3e56 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@nvidia.com>
|
||||
Date: Tue, 23 Nov 2021 19:41:02 +0200
|
||||
Subject: [PATCH 34/35] sff-8636: Print Power set and Power override bits
|
||||
|
||||
Print the SFF-8636 Power set and Power override bits when dumping EEPROM
|
||||
contents via the '-m' option. They can be used to understand low power
|
||||
mode enforcement by the host.
|
||||
|
||||
The 'SFF8636_LOW_PWR_MODE' define is renamed to 'SFF8636_LOW_PWR_SET' to
|
||||
reflect its naming in the standard for QSFP+/QSFP28.
|
||||
|
||||
Example output:
|
||||
|
||||
# ethtool -m swp13
|
||||
Identifier : 0x11 (QSFP28)
|
||||
...
|
||||
Extended identifier description : 5.0W max. Power consumption, High Power Class (> 3.5 W) enabled
|
||||
Power set : Off
|
||||
Power override : On
|
||||
...
|
||||
Transmit avg optical power (Channel 1) : 0.7633 mW / -1.17 dBm
|
||||
Transmit avg optical power (Channel 2) : 0.7649 mW / -1.16 dBm
|
||||
Transmit avg optical power (Channel 3) : 0.7696 mW / -1.14 dBm
|
||||
Transmit avg optical power (Channel 4) : 0.7739 mW / -1.11 dBm
|
||||
Rcvr signal avg optical power(Channel 1) : 0.9240 mW / -0.34 dBm
|
||||
Rcvr signal avg optical power(Channel 2) : 0.9129 mW / -0.40 dBm
|
||||
Rcvr signal avg optical power(Channel 3) : 0.9194 mW / -0.36 dBm
|
||||
Rcvr signal avg optical power(Channel 4) : 0.8708 mW / -0.60 dBm
|
||||
|
||||
# ethtool --set-module swp13 power-mode-policy auto
|
||||
|
||||
# ethtool -m swp13
|
||||
Identifier : 0x11 (QSFP28)
|
||||
...
|
||||
Extended identifier description : 5.0W max. Power consumption, High Power Class (> 3.5 W) not enabled
|
||||
Power set : On
|
||||
Power override : On
|
||||
...
|
||||
Transmit avg optical power (Channel 1) : 0.0000 mW / -inf dBm
|
||||
Transmit avg optical power (Channel 2) : 0.0000 mW / -inf dBm
|
||||
Transmit avg optical power (Channel 3) : 0.0000 mW / -inf dBm
|
||||
Transmit avg optical power (Channel 4) : 0.0000 mW / -inf dBm
|
||||
Rcvr signal avg optical power(Channel 1) : 0.0000 mW / -inf dBm
|
||||
Rcvr signal avg optical power(Channel 2) : 0.0000 mW / -inf dBm
|
||||
Rcvr signal avg optical power(Channel 3) : 0.0000 mW / -inf dBm
|
||||
Rcvr signal avg optical power(Channel 4) : 0.0000 mW / -inf dBm
|
||||
|
||||
# ethtool --set-module swp13 power-mode-policy high
|
||||
|
||||
# ethtool -m swp13
|
||||
Identifier : 0x11 (QSFP28)
|
||||
...
|
||||
Extended identifier description : 5.0W max. Power consumption, High Power Class (> 3.5 W) enabled
|
||||
Power set : Off
|
||||
Power override : On
|
||||
...
|
||||
Transmit avg optical power (Channel 1) : 0.7733 mW / -1.12 dBm
|
||||
Transmit avg optical power (Channel 2) : 0.7754 mW / -1.10 dBm
|
||||
Transmit avg optical power (Channel 3) : 0.7885 mW / -1.03 dBm
|
||||
Transmit avg optical power (Channel 4) : 0.7886 mW / -1.03 dBm
|
||||
Rcvr signal avg optical power(Channel 1) : 0.9248 mW / -0.34 dBm
|
||||
Rcvr signal avg optical power(Channel 2) : 0.9129 mW / -0.40 dBm
|
||||
Rcvr signal avg optical power(Channel 3) : 0.9187 mW / -0.37 dBm
|
||||
Rcvr signal avg optical power(Channel 4) : 0.8785 mW / -0.56 dBm
|
||||
|
||||
In the above example, the LPMode signal is ignored (Power override is
|
||||
always on) and low power mode is controlled via software only.
|
||||
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
qsfp.c | 6 ++++++
|
||||
qsfp.h | 2 +-
|
||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/qsfp.c b/qsfp.c
|
||||
index b3c9e1516af9..57aac86bd5f6 100644
|
||||
--- a/qsfp.c
|
||||
+++ b/qsfp.c
|
||||
@@ -268,6 +268,12 @@ static void sff8636_show_ext_identifier(const struct sff8636_memory_map *map)
|
||||
printf(" High Power Class (> 3.5 W) enabled\n");
|
||||
else
|
||||
printf(" High Power Class (> 3.5 W) not enabled\n");
|
||||
+ printf("\t%-41s : ", "Power set");
|
||||
+ printf("%s\n", ONOFF(map->lower_memory[SFF8636_PWR_MODE_OFFSET] &
|
||||
+ SFF8636_LOW_PWR_SET));
|
||||
+ printf("\t%-41s : ", "Power override");
|
||||
+ printf("%s\n", ONOFF(map->lower_memory[SFF8636_PWR_MODE_OFFSET] &
|
||||
+ SFF8636_PWR_OVERRIDE));
|
||||
}
|
||||
|
||||
static void sff8636_show_connector(const struct sff8636_memory_map *map)
|
||||
diff --git a/qsfp.h b/qsfp.h
|
||||
index 1d8f24b5cbc2..aabf09fdc623 100644
|
||||
--- a/qsfp.h
|
||||
+++ b/qsfp.h
|
||||
@@ -180,7 +180,7 @@
|
||||
|
||||
#define SFF8636_PWR_MODE_OFFSET 0x5D
|
||||
#define SFF8636_HIGH_PWR_ENABLE (1 << 2)
|
||||
-#define SFF8636_LOW_PWR_MODE (1 << 1)
|
||||
+#define SFF8636_LOW_PWR_SET (1 << 1)
|
||||
#define SFF8636_PWR_OVERRIDE (1 << 0)
|
||||
|
||||
#define SFF8636_TX_APP_SELECT_4_OFFSET 0x5E
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,107 @@
|
||||
From 206cd00caf9b71ae20f897075b4bd261e923e563 Mon Sep 17 00:00:00 2001
|
||||
From: Ivan Vecera <ivecera@redhat.com>
|
||||
Date: Tue, 31 May 2022 20:55:03 +0200
|
||||
Subject: [PATCH 35/35] sff-8079/8472: Fix missing sff-8472 output in netlink
|
||||
path
|
||||
|
||||
Commit 25b64c66f58d ("ethtool: Add netlink handler for
|
||||
getmodule (-m)") provided a netlink variant for getmodule
|
||||
but also introduced a regression as netlink output is different
|
||||
from ioctl output that provides information from A2h page
|
||||
via sff8472_show_all().
|
||||
|
||||
To fix this the netlink path should check a presence of A2h page
|
||||
by value of bit 6 in byte 92 of page A0h and if it is set then
|
||||
get A2h page and call sff8472_show_all().
|
||||
|
||||
Fixes: 25b64c66f58d ("ethtool: Add netlink handler for getmodule (-m)")
|
||||
Tested-by: Daniel Juarez <djuarezg@cern.ch>
|
||||
Tested-by: Ido Schimmel <idosch@nvidia.com>
|
||||
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
|
||||
Co-authored-by: Ido Schimmel <idosch@nvidia.com>
|
||||
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
|
||||
---
|
||||
sfpid.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 46 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/sfpid.c b/sfpid.c
|
||||
index 621d1e86c278..1bc45c183770 100644
|
||||
--- a/sfpid.c
|
||||
+++ b/sfpid.c
|
||||
@@ -13,8 +13,9 @@
|
||||
#include "sff-common.h"
|
||||
#include "netlink/extapi.h"
|
||||
|
||||
-#define SFF8079_PAGE_SIZE 0x80
|
||||
-#define SFF8079_I2C_ADDRESS_LOW 0x50
|
||||
+#define SFF8079_PAGE_SIZE 0x80
|
||||
+#define SFF8079_I2C_ADDRESS_LOW 0x50
|
||||
+#define SFF8079_I2C_ADDRESS_HIGH 0x51
|
||||
|
||||
static void sff8079_show_identifier(const __u8 *id)
|
||||
{
|
||||
@@ -450,18 +451,55 @@ void sff8079_show_all_ioctl(const __u8 *id)
|
||||
sff8079_show_all_common(id);
|
||||
}
|
||||
|
||||
-int sff8079_show_all_nl(struct cmd_context *ctx)
|
||||
+static int sff8079_get_eeprom_page(struct cmd_context *ctx, u8 i2c_address,
|
||||
+ __u8 *buf)
|
||||
{
|
||||
struct ethtool_module_eeprom request = {
|
||||
.length = SFF8079_PAGE_SIZE,
|
||||
- .i2c_address = SFF8079_I2C_ADDRESS_LOW,
|
||||
+ .i2c_address = i2c_address,
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = nl_get_eeprom_page(ctx, &request);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
- sff8079_show_all_common(request.data);
|
||||
+ if (!ret)
|
||||
+ memcpy(buf, request.data, SFF8079_PAGE_SIZE);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int sff8079_show_all_nl(struct cmd_context *ctx)
|
||||
+{
|
||||
+ u8 *buf;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* The SFF-8472 parser expects a single buffer that contains the
|
||||
+ * concatenation of the first 256 bytes from addresses A0h and A2h,
|
||||
+ * respectively.
|
||||
+ */
|
||||
+ buf = calloc(1, ETH_MODULE_SFF_8472_LEN);
|
||||
+ if (!buf)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ /* Read A0h page */
|
||||
+ ret = sff8079_get_eeprom_page(ctx, SFF8079_I2C_ADDRESS_LOW, buf);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ sff8079_show_all_common(buf);
|
||||
+
|
||||
+ /* Finish if A2h page is not present */
|
||||
+ if (!(buf[92] & (1 << 6)))
|
||||
+ goto out;
|
||||
+
|
||||
+ /* Read A2h page */
|
||||
+ ret = sff8079_get_eeprom_page(ctx, SFF8079_I2C_ADDRESS_HIGH,
|
||||
+ buf + ETH_MODULE_SFF_8079_LEN);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ sff8472_show_all(buf);
|
||||
+out:
|
||||
+ free(buf);
|
||||
|
||||
- return 0;
|
||||
+ return ret;
|
||||
}
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,7 +1,7 @@
|
||||
Name: ethtool
|
||||
Epoch: 2
|
||||
Version: 5.13
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
Summary: Settings tool for Ethernet NICs
|
||||
License: GPLv2
|
||||
Group: Applications/System
|
||||
@ -10,6 +10,42 @@ Source0: https://www.kernel.org/pub/software/network/%{name}/%{name}-%{version}.
|
||||
BuildRequires: libmnl-devel
|
||||
Conflicts: filesystem < 3
|
||||
|
||||
Patch1: 0001-sff-8636-Fix-parsing-of-Page-03h-in-IOCTL-path.patch
|
||||
Patch2: 0002-cmis-Fix-invalid-memory-access-in-IOCTL-path.patch
|
||||
Patch3: 0003-netlink-eeprom-Fallback-to-IOCTL-when-a-complete-hex.patch
|
||||
Patch4: 0004-ethtool-Fix-compilation-warning-when-pretty-dump-is-.patch
|
||||
Patch5: 0005-netlink-eeprom-Fix-compilation-when-pretty-dump-is-d.patch
|
||||
Patch6: 0006-cmis-Fix-CLEI-code-parsing.patch
|
||||
Patch7: 0007-cmis-Fix-wrong-define-name.patch
|
||||
Patch8: 0008-cmis-Correct-comment.patch
|
||||
Patch9: 0009-sff-8636-Remove-incorrect-comment.patch
|
||||
Patch10: 0010-sff-8636-Fix-incorrect-function-name.patch
|
||||
Patch11: 0011-sff-8636-Convert-if-statement-to-switch-case.patch
|
||||
Patch12: 0012-sff-8636-Remove-extra-blank-lines.patch
|
||||
Patch13: 0013-cmis-Rename-CMIS-parsing-functions.patch
|
||||
Patch14: 0014-cmis-Initialize-CMIS-memory-map.patch
|
||||
Patch15: 0015-cmis-Use-memory-map-during-parsing.patch
|
||||
Patch16: 0016-cmis-Consolidate-code-between-IOCTL-and-netlink-path.patch
|
||||
Patch17: 0017-sff-8636-Rename-SFF-8636-parsing-functions.patch
|
||||
Patch18: 0018-sff-8636-Initialize-SFF-8636-memory-map.patch
|
||||
Patch19: 0019-sff-8636-Use-memory-map-during-parsing.patch
|
||||
Patch20: 0020-sff-8636-Consolidate-code-between-IOCTL-and-netlink-.patch
|
||||
Patch21: 0021-sff-8079-Split-SFF-8079-parsing-function.patch
|
||||
Patch22: 0022-netlink-eeprom-Export-a-function-to-request-an-EEPRO.patch
|
||||
Patch23: 0023-cmis-Request-specific-pages-for-parsing-in-netlink-p.patch
|
||||
Patch24: 0024-sff-8636-Request-specific-pages-for-parsing-in-netli.patch
|
||||
Patch25: 0025-sff-8079-Request-specific-pages-for-parsing-in-netli.patch
|
||||
Patch26: 0026-netlink-eeprom-Defer-page-requests-to-individual-par.patch
|
||||
Patch27: 0027-sff-8636-Use-an-SFF-8636-specific-define-for-maximum.patch
|
||||
Patch28: 0028-sff-common-Move-OFFSET_TO_U16_PTR-to-common-header-f.patch
|
||||
Patch29: 0029-cmis-Initialize-Page-02h-in-memory-map.patch
|
||||
Patch30: 0030-cmis-Initialize-Banked-Page-11h-in-memory-map.patch
|
||||
Patch31: 0031-cmis-Parse-and-print-diagnostic-information.patch
|
||||
Patch32: 0032-cmis-Print-Module-State-and-Fault-Cause.patch
|
||||
Patch33: 0033-cmis-Print-Module-Level-Controls.patch
|
||||
Patch34: 0034-sff-8636-Print-Power-set-and-Power-override-bits.patch
|
||||
Patch35: 0035-sff-8079-8472-Fix-missing-sff-8472-output-in-netlink.patch
|
||||
|
||||
%description
|
||||
This utility allows querying and changing settings such as speed,
|
||||
port, auto-negotiation, PCI locations and checksum offload on many
|
||||
@ -17,6 +53,41 @@ network devices, especially of Ethernet devices.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch13 -p1
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
%patch18 -p1
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
%patch23 -p1
|
||||
%patch24 -p1
|
||||
%patch25 -p1
|
||||
%patch26 -p1
|
||||
%patch27 -p1
|
||||
%patch28 -p1
|
||||
%patch29 -p1
|
||||
%patch30 -p1
|
||||
%patch31 -p1
|
||||
%patch32 -p1
|
||||
%patch33 -p1
|
||||
%patch34 -p1
|
||||
%patch35 -p1
|
||||
|
||||
%build
|
||||
%configure
|
||||
@ -33,6 +104,9 @@ make DESTDIR=%{buildroot} INSTALL='install -p' install
|
||||
%{_datadir}/bash-completion/completions/ethtool
|
||||
|
||||
%changelog
|
||||
* Thu Jun 02 2022 Ivan Vecera <ivecera@redhat.com> - 2:5.13-2
|
||||
- Module (SFP/QSFP/CMIS) related bugfixes
|
||||
|
||||
* Thu Nov 18 2021 Ivan Vecera <ivecera@redhat.com> - 2:5.13-1
|
||||
- Updated to upstream v5.13
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user