diff --git a/.ethtool.metadata b/.ethtool.metadata index 7b43eeb..4ab498b 100644 --- a/.ethtool.metadata +++ b/.ethtool.metadata @@ -1 +1 @@ -cd71638cf3033dc83422b48a8c5e8831e6e05a84 SOURCES/ethtool-4.5.tar.xz +db82313f212aa1e1b8f5f892f25a9883bea26b9f SOURCES/ethtool-4.8.tar.xz diff --git a/.gitignore b/.gitignore index 135bc2d..8a95788 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/ethtool-4.5.tar.xz +SOURCES/ethtool-4.8.tar.xz diff --git a/SOURCES/0001-ethtool-add-register-dump-support-for-fjes-driver.patch b/SOURCES/0001-ethtool-add-register-dump-support-for-fjes-driver.patch new file mode 100644 index 0000000..c0010e4 --- /dev/null +++ b/SOURCES/0001-ethtool-add-register-dump-support-for-fjes-driver.patch @@ -0,0 +1,174 @@ +From 1be465a88eb247b78ddbc3129f53cc547ce8687b Mon Sep 17 00:00:00 2001 +From: Taku Izumi +Date: Wed, 16 Nov 2016 09:55:32 +0900 +Subject: [PATCH 1/3] ethtool: add register dump support for fjes driver + +This patch adds the register dump format for FUJITSU Extended +Network device like the following: + + # ethtool -d es0 + +0x0000: OWNER_EPID (Owner EPID) 0x00000001 +0x0004: MAX_EP (Maximum EP) 0x00000008 +0x0010: DCTL (Device Control) 0x00000000 +0x0020: CR (Command request) 0x80000002 +0x0024: CS (Command status) 0x80000002 +0x0028: SHSTSAL (Share status address Low) 0xE8215304 +0x002C: SHSTSAH (Share status address High) 0x00000007 +0x0034: REQBL (Request Buffer length) 0x00008028 +0x0038: REQBAL (Request Buffer Address Low) 0xEB0A0000 +0x003C: REQBAH (Request Buffer Address High) 0x00000007 +0x0044: RESPBL (Response Buffer Length) 0x00000018 +0x0048: RESPBAL (Response Buffer Address Low) 0xE41E1220 +0x004C: RESPBAH (Response Buffer Address High) 0x00000007 +0x0080: IS (Interrupt status) 0x00000000 +0x0084: IMS (Interrupt mask set) 0x7FE00000 +0x0088: IMC (Interrupt mask clear) 0x001F0000 +0x008C: IG (Interrupt generator) 0x00010000 +0x0090: ICTL (Interrupt control) 0x00000000 + +Signed-off-by: Taku Izumi +Signed-off-by: John W. Linville +(cherry picked from commit acc3d3a32940cdd3325520d212fa94f44b86ed09) +--- + Makefile.am | 2 +- + ethtool.c | 1 + + fjes.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + internal.h | 2 ++ + 4 files changed, 93 insertions(+), 1 deletion(-) + create mode 100644 fjes.c + +diff --git a/Makefile.am b/Makefile.am +index de2db2e..edbda57 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -14,7 +14,7 @@ ethtool_SOURCES += \ + pcnet32.c realtek.c tg3.c marvell.c vioc.c \ + smsc911x.c at76c50x-usb.c sfc.c stmmac.c \ + sff-common.c sff-common.h sfpid.c sfpdiag.c \ +- ixgbevf.c tse.c vmxnet3.c qsfp.c qsfp.h ++ ixgbevf.c tse.c vmxnet3.c qsfp.c qsfp.h fjes.c + endif + + TESTS = test-cmdline test-features +diff --git a/ethtool.c b/ethtool.c +index 49ac94e..75299c6 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -1136,6 +1136,7 @@ static const struct { + { "et131x", et131x_dump_regs }, + { "altera_tse", altera_tse_dump_regs }, + { "vmxnet3", vmxnet3_dump_regs }, ++ { "fjes", fjes_dump_regs }, + #endif + }; + +diff --git a/fjes.c b/fjes.c +new file mode 100644 +index 0000000..52f7c28 +--- /dev/null ++++ b/fjes.c +@@ -0,0 +1,89 @@ ++/* Copyright (c) 2016 FUJITSU LIMITED */ ++#include ++#include "internal.h" ++ ++int fjes_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs) ++{ ++ u32 *regs_buff = (u32 *)regs->data; ++ ++ if (regs->version != 1) ++ return -1; ++ ++ /* Information registers */ ++ fprintf(stdout, ++ "0x0000: OWNER_EPID (Owner EPID) 0x%08X\n", ++ regs_buff[0]); ++ ++ fprintf(stdout, ++ "0x0004: MAX_EP (Maximum EP) 0x%08X\n", ++ regs_buff[1]); ++ ++ /* Device Control registers */ ++ fprintf(stdout, ++ "0x0010: DCTL (Device Control) 0x%08X\n", ++ regs_buff[4]); ++ ++ /* Command Control registers */ ++ fprintf(stdout, ++ "0x0020: CR (Command request) 0x%08X\n", ++ regs_buff[8]); ++ ++ fprintf(stdout, ++ "0x0024: CS (Command status) 0x%08X\n", ++ regs_buff[9]); ++ ++ fprintf(stdout, ++ "0x0028: SHSTSAL (Share status address Low) 0x%08X\n", ++ regs_buff[10]); ++ ++ fprintf(stdout, ++ "0x002C: SHSTSAH (Share status address High) 0x%08X\n", ++ regs_buff[11]); ++ ++ fprintf(stdout, ++ "0x0034: REQBL (Request Buffer length) 0x%08X\n", ++ regs_buff[13]); ++ ++ fprintf(stdout, ++ "0x0038: REQBAL (Request Buffer Address Low) 0x%08X\n", ++ regs_buff[14]); ++ ++ fprintf(stdout, ++ "0x003C: REQBAH (Request Buffer Address High) 0x%08X\n", ++ regs_buff[15]); ++ ++ fprintf(stdout, ++ "0x0044: RESPBL (Response Buffer Length) 0x%08X\n", ++ regs_buff[17]); ++ ++ fprintf(stdout, ++ "0x0048: RESPBAL (Response Buffer Address Low) 0x%08X\n", ++ regs_buff[18]); ++ ++ fprintf(stdout, ++ "0x004C: RESPBAH (Response Buffer Address High) 0x%08X\n", ++ regs_buff[19]); ++ ++ /* Interrupt Control registers */ ++ fprintf(stdout, ++ "0x0080: IS (Interrupt status) 0x%08X\n", ++ regs_buff[32]); ++ ++ fprintf(stdout, ++ "0x0084: IMS (Interrupt mask set) 0x%08X\n", ++ regs_buff[33]); ++ ++ fprintf(stdout, ++ "0x0088: IMC (Interrupt mask clear) 0x%08X\n", ++ regs_buff[34]); ++ ++ fprintf(stdout, ++ "0x008C: IG (Interrupt generator) 0x%08X\n", ++ regs_buff[35]); ++ ++ fprintf(stdout, ++ "0x0090: ICTL (Interrupt control) 0x%08X\n", ++ regs_buff[36]); ++ ++ return 0; ++} +diff --git a/internal.h b/internal.h +index 3c08b74..4e658ea 100644 +--- a/internal.h ++++ b/internal.h +@@ -348,4 +348,6 @@ void sff8472_show_all(const __u8 *id); + /* QSFP Optics diagnostics */ + void sff8636_show_all(const __u8 *id, __u32 eeprom_len); + ++/* FUJITSU Extended Socket network device */ ++int fjes_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + #endif /* ETHTOOL_INTERNAL_H__ */ +-- +1.8.3.1 + diff --git a/SOURCES/0001-ethtool.c-fix-memory-leaks.patch b/SOURCES/0001-ethtool.c-fix-memory-leaks.patch deleted file mode 100644 index b592b31..0000000 --- a/SOURCES/0001-ethtool.c-fix-memory-leaks.patch +++ /dev/null @@ -1,223 +0,0 @@ -From 266d945d9c6432fc5746fa46e3e3ace2518600db Mon Sep 17 00:00:00 2001 -From: Ivan Vecera -Date: Fri, 18 Mar 2016 12:50:43 +0100 -Subject: [PATCH] ethtool.c: fix memory leaks - -Memory allocated at several places is not appropriately freed. - -Signed-off-by: Ivan Vecera ---- - ethtool.c | 60 +++++++++++++++++++++++++++++++++++++++++++++--------------- - 1 file changed, 45 insertions(+), 15 deletions(-) - -diff --git a/ethtool.c b/ethtool.c -index 0cd0d4f..ca0bf28 100644 ---- a/ethtool.c -+++ b/ethtool.c -@@ -2065,10 +2065,14 @@ static int do_gfeatures(struct cmd_context *ctx) - features = get_features(ctx, defs); - if (!features) { - fprintf(stdout, "no feature info available\n"); -+ free(defs); - return 1; - } - - dump_features(defs, features, NULL); -+ -+ free(features); -+ free(defs); - return 0; - } - -@@ -2078,11 +2082,11 @@ static int do_sfeatures(struct cmd_context *ctx) - int any_changed = 0, any_mismatch = 0; - u32 off_flags_wanted = 0; - u32 off_flags_mask = 0; -- struct ethtool_sfeatures *efeatures; -+ struct ethtool_sfeatures *efeatures = NULL; - struct cmdline_info *cmdline_features; -- struct feature_state *old_state, *new_state; -+ struct feature_state *old_state = NULL, *new_state = NULL; - struct ethtool_value eval; -- int err; -+ int err, retval = 1; - int i, j; - - defs = get_feature_defs(ctx); -@@ -2096,7 +2100,7 @@ static int do_sfeatures(struct cmd_context *ctx) - sizeof(efeatures->features[0])); - if (!efeatures) { - perror("Cannot parse arguments"); -- return 1; -+ goto finish; - } - efeatures->cmd = ETHTOOL_SFEATURES; - efeatures->size = FEATURE_BITS_TO_BLOCKS(defs->n_features); -@@ -2114,7 +2118,7 @@ static int do_sfeatures(struct cmd_context *ctx) - sizeof(cmdline_features[0])); - if (!cmdline_features) { - perror("Cannot parse arguments"); -- return 1; -+ goto finish; - } - for (i = 0; i < ARRAY_SIZE(off_flag_def); i++) - flag_to_cmdline_info(off_flag_def[i].short_name, -@@ -2133,12 +2137,13 @@ static int do_sfeatures(struct cmd_context *ctx) - - if (!any_changed) { - fprintf(stdout, "no features changed\n"); -- return 0; -+ retval = 0; -+ goto finish; - } - - old_state = get_features(ctx, defs); - if (!old_state) -- return 1; -+ goto finish; - - if (efeatures) { - /* For each offload that the user specified, update any -@@ -2182,7 +2187,7 @@ static int do_sfeatures(struct cmd_context *ctx) - err = send_ioctl(ctx, efeatures); - if (err < 0) { - perror("Cannot set device feature settings"); -- return 1; -+ goto finish; - } - } else { - for (i = 0; i < ARRAY_SIZE(off_flag_def); i++) { -@@ -2197,7 +2202,7 @@ static int do_sfeatures(struct cmd_context *ctx) - fprintf(stderr, - "Cannot set device %s settings: %m\n", - off_flag_def[i].long_name); -- return 1; -+ goto finish; - } - } - } -@@ -2211,7 +2216,8 @@ static int do_sfeatures(struct cmd_context *ctx) - err = send_ioctl(ctx, &eval); - if (err) { - perror("Cannot set device flag settings"); -- return 92; -+ retval = 92; -+ goto finish; - } - } - } -@@ -2219,7 +2225,7 @@ static int do_sfeatures(struct cmd_context *ctx) - /* Compare new state with requested state */ - new_state = get_features(ctx, defs); - if (!new_state) -- return 1; -+ goto finish; - any_changed = new_state->off_flags != old_state->off_flags; - any_mismatch = (new_state->off_flags != - ((old_state->off_flags & ~off_flags_mask) | -@@ -2238,13 +2244,19 @@ static int do_sfeatures(struct cmd_context *ctx) - if (!any_changed) { - fprintf(stderr, - "Could not change any device features\n"); -- return 1; -+ goto finish; - } - printf("Actual changes:\n"); - dump_features(defs, new_state, old_state); - } - -- return 0; -+ retval = 0; -+finish: -+ free(new_state); -+ free(old_state); -+ free(efeatures); -+ free(defs); -+ return retval; - } - - static int do_gset(struct cmd_context *ctx) -@@ -2705,8 +2717,18 @@ static int do_gregs(struct cmd_context *ctx) - return 75; - } - -- regs = realloc(regs, sizeof(*regs) + st.st_size); -- regs->len = st.st_size; -+ if (regs->len != st.st_size) { -+ struct ethtool_regs *new_regs; -+ new_regs = realloc(regs, sizeof(*regs) + st.st_size); -+ if (!new_regs) { -+ perror("Cannot allocate memory for register " -+ "dump"); -+ free(regs); -+ return 73; -+ } -+ regs = new_regs; -+ regs->len = st.st_size; -+ } - nread = fread(regs->data, regs->len, 1, f); - fclose(f); - if (nread != 1) { -@@ -3775,6 +3797,7 @@ static int do_gprivflags(struct cmd_context *ctx) - } - if (strings->len == 0) { - fprintf(stderr, "No private flags defined\n"); -+ free(strings); - return 1; - } - if (strings->len > 32) { -@@ -3786,6 +3809,7 @@ static int do_gprivflags(struct cmd_context *ctx) - flags.cmd = ETHTOOL_GPFLAGS; - if (send_ioctl(ctx, &flags)) { - perror("Cannot get private flags"); -+ free(strings); - return 1; - } - -@@ -3804,6 +3828,7 @@ static int do_gprivflags(struct cmd_context *ctx) - (const char *)strings->data + i * ETH_GSTRING_LEN, - (flags.data & (1U << i)) ? "on" : "off"); - -+ free(strings); - return 0; - } - -@@ -3825,6 +3850,7 @@ static int do_sprivflags(struct cmd_context *ctx) - } - if (strings->len == 0) { - fprintf(stderr, "No private flags defined\n"); -+ free(strings); - return 1; - } - if (strings->len > 32) { -@@ -3836,6 +3862,7 @@ static int do_sprivflags(struct cmd_context *ctx) - cmdline = calloc(strings->len, sizeof(*cmdline)); - if (!cmdline) { - perror("Cannot parse arguments"); -+ free(strings); - return 1; - } - for (i = 0; i < strings->len; i++) { -@@ -3852,6 +3879,7 @@ static int do_sprivflags(struct cmd_context *ctx) - flags.cmd = ETHTOOL_GPFLAGS; - if (send_ioctl(ctx, &flags)) { - perror("Cannot get private flags"); -+ free(strings); - return 1; - } - -@@ -3859,9 +3887,11 @@ static int do_sprivflags(struct cmd_context *ctx) - flags.data = (flags.data & ~seen_flags) | wanted_flags; - if (send_ioctl(ctx, &flags)) { - perror("Cannot set private flags"); -+ free(strings); - return 1; - } - -+ free(strings); - return 0; - } - --- -2.7.3 - diff --git a/SOURCES/0002-ethtool-sync-help-output-for-x-X-with-man-page.patch b/SOURCES/0002-ethtool-sync-help-output-for-x-X-with-man-page.patch new file mode 100644 index 0000000..17cb755 --- /dev/null +++ b/SOURCES/0002-ethtool-sync-help-output-for-x-X-with-man-page.patch @@ -0,0 +1,34 @@ +From d695f60666453d964a653c5033764c4b80121f56 Mon Sep 17 00:00:00 2001 +From: Ivan Vecera +Date: Mon, 20 Feb 2017 15:13:52 +0100 +Subject: [PATCH 2/3] ethtool: sync help output for -x/-X with man page + +Add missing words to the help output for -x and -X commands as well +as an ability to set the indirection table to default value. + +Signed-off-by: Ivan Vecera +--- + ethtool.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/ethtool.c b/ethtool.c +index 75299c6..0d3244e 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -4645,10 +4645,10 @@ static const struct option { + { "-T|--show-time-stamping", 1, do_tsinfo, + "Show time stamping capabilities" }, + { "-x|--show-rxfh-indir|--show-rxfh", 1, do_grxfh, +- "Show Rx flow hash indirection and/or hash key" }, ++ "Show Rx flow hash indirection table and/or RSS hash key" }, + { "-X|--set-rxfh-indir|--rxfh", 1, do_srxfh, +- "Set Rx flow hash indirection and/or hash key", +- " [ equal N | weight W0 W1 ... ]\n" ++ "Set Rx flow hash indirection table and/or RSS hash key", ++ " [ equal N | weight W0 W1 ... | default ]\n" + " [ hkey %x:%x:%x:%x:%x:.... ]\n" }, + { "-f|--flash", 1, do_flash, + "Flash firmware image from the specified file to a region on the device", +-- +1.8.3.1 + diff --git a/SOURCES/0002-ethtool.c-add-support-for-ETHTOOL_xLINKSETTINGS-ioctl.patch b/SOURCES/0002-ethtool.c-add-support-for-ETHTOOL_xLINKSETTINGS-ioctl.patch deleted file mode 100644 index 10392c4..0000000 --- a/SOURCES/0002-ethtool.c-add-support-for-ETHTOOL_xLINKSETTINGS-ioctl.patch +++ /dev/null @@ -1,1072 +0,0 @@ -From 00a31b21a767be682a27d631a7c9df2a41c41e06 Mon Sep 17 00:00:00 2001 -From: David Decotigny -Date: Fri, 25 Mar 2016 09:21:01 -0700 -Subject: [PATCH 2/7] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls - -More info with kernel commit 8d3f2806f8fb ("Merge branch -'ethtool-ksettings'"). - -Note: The new features implemented in this patch depend on kernel -commit 793cf87de9d1 ("Set cmd field in ETHTOOL_GLINKSETTINGS response to -wrong nwords"). - -Signed-off-by: David Decotigny -[bwh: Fix style: - - Remove '_' and '__' prefixes from newly defined names - - Add space around multiplication operator - - Remove space before semi-colon] -Signed-off-by: Ben Hutchings - -(cherry picked from commit 33133abf3b777a2e0730f826817c8e05b3616150) ---- - ethtool.c | 680 +++++++++++++++++++++++++++++++++++++++++++-------------- - internal.h | 66 ++++++ - test-cmdline.c | 13 ++ - 3 files changed, 601 insertions(+), 158 deletions(-) - -diff --git a/ethtool.c b/ethtool.c -index ca0bf28..796d0b5 100644 ---- a/ethtool.c -+++ b/ethtool.c -@@ -47,42 +47,6 @@ - #define MAX_ADDR_LEN 32 - #endif - --#define ALL_ADVERTISED_MODES \ -- (ADVERTISED_10baseT_Half | \ -- ADVERTISED_10baseT_Full | \ -- ADVERTISED_100baseT_Half | \ -- ADVERTISED_100baseT_Full | \ -- ADVERTISED_1000baseT_Half | \ -- ADVERTISED_1000baseT_Full | \ -- ADVERTISED_1000baseKX_Full| \ -- ADVERTISED_2500baseX_Full | \ -- ADVERTISED_10000baseT_Full | \ -- ADVERTISED_10000baseKX4_Full | \ -- ADVERTISED_10000baseKR_Full | \ -- ADVERTISED_10000baseR_FEC | \ -- ADVERTISED_20000baseMLD2_Full | \ -- ADVERTISED_20000baseKR2_Full | \ -- ADVERTISED_40000baseKR4_Full | \ -- ADVERTISED_40000baseCR4_Full | \ -- ADVERTISED_40000baseSR4_Full | \ -- ADVERTISED_40000baseLR4_Full | \ -- ADVERTISED_56000baseKR4_Full | \ -- ADVERTISED_56000baseCR4_Full | \ -- ADVERTISED_56000baseSR4_Full | \ -- ADVERTISED_56000baseLR4_Full) -- --#define ALL_ADVERTISED_FLAGS \ -- (ADVERTISED_Autoneg | \ -- ADVERTISED_TP | \ -- ADVERTISED_AUI | \ -- ADVERTISED_MII | \ -- ADVERTISED_FIBRE | \ -- ADVERTISED_BNC | \ -- ADVERTISED_Pause | \ -- ADVERTISED_Asym_Pause | \ -- ADVERTISED_Backplane | \ -- ALL_ADVERTISED_MODES) -- - #ifndef HAVE_NETIF_MSG - enum { - NETIF_MSG_DRV = 0x0001, -@@ -293,6 +257,43 @@ static void get_mac_addr(char *src, unsigned char *dest) - } - } - -+static int parse_hex_u32_bitmap(const char *s, -+ unsigned int nbits, u32 *result) -+{ -+ const unsigned int nwords = __KERNEL_DIV_ROUND_UP(nbits, 32); -+ size_t slen = strlen(s); -+ size_t i; -+ -+ /* ignore optional '0x' prefix */ -+ if ((slen > 2) && (strncasecmp(s, "0x", 2) == 0)) { -+ slen -= 2; -+ s += 2; -+ } -+ -+ if (slen > 8 * nwords) /* up to 2 digits per byte */ -+ return -1; -+ -+ memset(result, 0, 4 * nwords); -+ for (i = 0; i < slen; ++i) { -+ const unsigned int shift = (slen - 1 - i) * 4; -+ u32 *dest = &result[shift / 32]; -+ u32 nibble; -+ -+ if ('a' <= s[i] && s[i] <= 'f') -+ nibble = 0xa + (s[i] - 'a'); -+ else if ('A' <= s[i] && s[i] <= 'F') -+ nibble = 0xa + (s[i] - 'A'); -+ else if ('0' <= s[i] && s[i] <= '9') -+ nibble = (s[i] - '0'); -+ else -+ return -1; -+ -+ *dest |= (nibble << (shift % 32)); -+ } -+ -+ return 0; -+} -+ - static void parse_generic_cmdline(struct cmd_context *ctx, - int *changed, - struct cmdline_info *info, -@@ -472,64 +473,157 @@ static int do_version(struct cmd_context *ctx) - return 0; - } - --static void dump_link_caps(const char *prefix, const char *an_prefix, u32 mask, -- int link_mode_only); -+/* link mode routines */ - --static void dump_supported(struct ethtool_cmd *ep) -+static ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_modes); -+static ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_flags); -+ -+static void init_global_link_mode_masks(void) - { -- u32 mask = ep->supported; -+ static const enum ethtool_link_mode_bit_indices -+ all_advertised_modes_bits[] = { -+ ETHTOOL_LINK_MODE_10baseT_Half_BIT, -+ ETHTOOL_LINK_MODE_10baseT_Full_BIT, -+ ETHTOOL_LINK_MODE_100baseT_Half_BIT, -+ ETHTOOL_LINK_MODE_100baseT_Full_BIT, -+ ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -+ ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -+ ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, -+ ETHTOOL_LINK_MODE_2500baseX_Full_BIT, -+ ETHTOOL_LINK_MODE_10000baseT_Full_BIT, -+ ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, -+ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, -+ ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, -+ ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT, -+ ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT, -+ ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, -+ ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, -+ ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, -+ ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, -+ ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT, -+ ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT, -+ ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT, -+ ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT, -+ }; -+ static const enum ethtool_link_mode_bit_indices -+ additional_advertised_flags_bits[] = { -+ ETHTOOL_LINK_MODE_Autoneg_BIT, -+ ETHTOOL_LINK_MODE_TP_BIT, -+ ETHTOOL_LINK_MODE_AUI_BIT, -+ ETHTOOL_LINK_MODE_MII_BIT, -+ ETHTOOL_LINK_MODE_FIBRE_BIT, -+ ETHTOOL_LINK_MODE_BNC_BIT, -+ ETHTOOL_LINK_MODE_Pause_BIT, -+ ETHTOOL_LINK_MODE_Asym_Pause_BIT, -+ ETHTOOL_LINK_MODE_Backplane_BIT, -+ }; -+ unsigned int i; - -+ ethtool_link_mode_zero(all_advertised_modes); -+ ethtool_link_mode_zero(all_advertised_flags); -+ for (i = 0; i < ARRAY_SIZE(all_advertised_modes_bits); ++i) { -+ ethtool_link_mode_set_bit(all_advertised_modes_bits[i], -+ all_advertised_modes); -+ ethtool_link_mode_set_bit(all_advertised_modes_bits[i], -+ all_advertised_flags); -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(additional_advertised_flags_bits); ++i) { -+ ethtool_link_mode_set_bit( -+ additional_advertised_flags_bits[i], -+ all_advertised_flags); -+ } -+} -+ -+static void dump_link_caps(const char *prefix, const char *an_prefix, -+ const u32 *mask, int link_mode_only); -+ -+static void dump_supported(const struct ethtool_link_usettings *link_usettings) -+{ - fprintf(stdout, " Supported ports: [ "); -- if (mask & SUPPORTED_TP) -+ if (ethtool_link_mode_test_bit( -+ ETHTOOL_LINK_MODE_TP_BIT, -+ link_usettings->link_modes.supported)) - fprintf(stdout, "TP "); -- if (mask & SUPPORTED_AUI) -+ if (ethtool_link_mode_test_bit( -+ ETHTOOL_LINK_MODE_AUI_BIT, -+ link_usettings->link_modes.supported)) - fprintf(stdout, "AUI "); -- if (mask & SUPPORTED_BNC) -+ if (ethtool_link_mode_test_bit( -+ ETHTOOL_LINK_MODE_BNC_BIT, -+ link_usettings->link_modes.supported)) - fprintf(stdout, "BNC "); -- if (mask & SUPPORTED_MII) -+ if (ethtool_link_mode_test_bit( -+ ETHTOOL_LINK_MODE_MII_BIT, -+ link_usettings->link_modes.supported)) - fprintf(stdout, "MII "); -- if (mask & SUPPORTED_FIBRE) -+ if (ethtool_link_mode_test_bit( -+ ETHTOOL_LINK_MODE_FIBRE_BIT, -+ link_usettings->link_modes.supported)) - fprintf(stdout, "FIBRE "); -- if (mask & SUPPORTED_Backplane) -+ if (ethtool_link_mode_test_bit( -+ ETHTOOL_LINK_MODE_Backplane_BIT, -+ link_usettings->link_modes.supported)) - fprintf(stdout, "Backplane "); - fprintf(stdout, "]\n"); - -- dump_link_caps("Supported", "Supports", mask, 0); -+ dump_link_caps("Supported", "Supports", -+ link_usettings->link_modes.supported, 0); - } - - /* Print link capability flags (supported, advertised or lp_advertised). - * Assumes that the corresponding SUPPORTED and ADVERTISED flags are equal. - */ --static void --dump_link_caps(const char *prefix, const char *an_prefix, u32 mask, -- int link_mode_only) -+static void dump_link_caps(const char *prefix, const char *an_prefix, -+ const u32 *mask, int link_mode_only) - { - static const struct { - int same_line; /* print on same line as previous */ -- u32 value; -+ unsigned int bit_index; - const char *name; - } mode_defs[] = { -- { 0, ADVERTISED_10baseT_Half, "10baseT/Half" }, -- { 1, ADVERTISED_10baseT_Full, "10baseT/Full" }, -- { 0, ADVERTISED_100baseT_Half, "100baseT/Half" }, -- { 1, ADVERTISED_100baseT_Full, "100baseT/Full" }, -- { 0, ADVERTISED_1000baseT_Half, "1000baseT/Half" }, -- { 1, ADVERTISED_1000baseT_Full, "1000baseT/Full" }, -- { 0, ADVERTISED_1000baseKX_Full, "1000baseKX/Full" }, -- { 0, ADVERTISED_2500baseX_Full, "2500baseX/Full" }, -- { 0, ADVERTISED_10000baseT_Full, "10000baseT/Full" }, -- { 0, ADVERTISED_10000baseKX4_Full, "10000baseKX4/Full" }, -- { 0, ADVERTISED_10000baseKR_Full, "10000baseKR/Full" }, -- { 0, ADVERTISED_20000baseMLD2_Full, "20000baseMLD2/Full" }, -- { 0, ADVERTISED_20000baseKR2_Full, "20000baseKR2/Full" }, -- { 0, ADVERTISED_40000baseKR4_Full, "40000baseKR4/Full" }, -- { 0, ADVERTISED_40000baseCR4_Full, "40000baseCR4/Full" }, -- { 0, ADVERTISED_40000baseSR4_Full, "40000baseSR4/Full" }, -- { 0, ADVERTISED_40000baseLR4_Full, "40000baseLR4/Full" }, -- { 0, ADVERTISED_56000baseKR4_Full, "56000baseKR4/Full" }, -- { 0, ADVERTISED_56000baseCR4_Full, "56000baseCR4/Full" }, -- { 0, ADVERTISED_56000baseSR4_Full, "56000baseSR4/Full" }, -- { 0, ADVERTISED_56000baseLR4_Full, "56000baseLR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_10baseT_Half_BIT, -+ "10baseT/Half" }, -+ { 1, ETHTOOL_LINK_MODE_10baseT_Full_BIT, -+ "10baseT/Full" }, -+ { 0, ETHTOOL_LINK_MODE_100baseT_Half_BIT, -+ "100baseT/Half" }, -+ { 1, ETHTOOL_LINK_MODE_100baseT_Full_BIT, -+ "100baseT/Full" }, -+ { 0, ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -+ "1000baseT/Half" }, -+ { 1, ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -+ "1000baseT/Full" }, -+ { 0, ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, -+ "1000baseKX/Full" }, -+ { 0, ETHTOOL_LINK_MODE_2500baseX_Full_BIT, -+ "2500baseX/Full" }, -+ { 0, ETHTOOL_LINK_MODE_10000baseT_Full_BIT, -+ "10000baseT/Full" }, -+ { 0, ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, -+ "10000baseKX4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, -+ "10000baseKR/Full" }, -+ { 0, ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT, -+ "20000baseMLD2/Full" }, -+ { 0, ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT, -+ "20000baseKR2/Full" }, -+ { 0, ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, -+ "40000baseKR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, -+ "40000baseCR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, -+ "40000baseSR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, -+ "40000baseLR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT, -+ "56000baseKR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT, -+ "56000baseCR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT, -+ "56000baseSR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT, -+ "56000baseLR4/Full" }, - }; - int indent; - int did1, new_line_pend, i; -@@ -546,7 +640,8 @@ dump_link_caps(const char *prefix, const char *an_prefix, u32 mask, - for (i = 0; i < ARRAY_SIZE(mode_defs); i++) { - if (did1 && !mode_defs[i].same_line) - new_line_pend = 1; -- if (mask & mode_defs[i].value) { -+ if (ethtool_link_mode_test_bit(mode_defs[i].bit_index, -+ mask)) { - if (new_line_pend) { - fprintf(stdout, "\n"); - fprintf(stdout, " %*s", indent, ""); -@@ -562,46 +657,52 @@ dump_link_caps(const char *prefix, const char *an_prefix, u32 mask, - - if (!link_mode_only) { - fprintf(stdout, " %s pause frame use: ", prefix); -- if (mask & ADVERTISED_Pause) { -+ if (ethtool_link_mode_test_bit( -+ ETHTOOL_LINK_MODE_Pause_BIT, mask)) { - fprintf(stdout, "Symmetric"); -- if (mask & ADVERTISED_Asym_Pause) -+ if (ethtool_link_mode_test_bit( -+ ETHTOOL_LINK_MODE_Asym_Pause_BIT, mask)) - fprintf(stdout, " Receive-only"); - fprintf(stdout, "\n"); - } else { -- if (mask & ADVERTISED_Asym_Pause) -+ if (ethtool_link_mode_test_bit( -+ ETHTOOL_LINK_MODE_Asym_Pause_BIT, mask)) - fprintf(stdout, "Transmit-only\n"); - else - fprintf(stdout, "No\n"); - } - - fprintf(stdout, " %s auto-negotiation: ", an_prefix); -- if (mask & ADVERTISED_Autoneg) -+ if (ethtool_link_mode_test_bit( -+ ETHTOOL_LINK_MODE_Autoneg_BIT, mask)) - fprintf(stdout, "Yes\n"); - else - fprintf(stdout, "No\n"); - } - } - --static int dump_ecmd(struct ethtool_cmd *ep) -+static int -+dump_link_usettings(const struct ethtool_link_usettings *link_usettings) - { -- u32 speed; -- -- dump_supported(ep); -- dump_link_caps("Advertised", "Advertised", ep->advertising, 0); -- if (ep->lp_advertising) -+ dump_supported(link_usettings); -+ dump_link_caps("Advertised", "Advertised", -+ link_usettings->link_modes.advertising, 0); -+ if (!ethtool_link_mode_is_empty( -+ link_usettings->link_modes.lp_advertising)) - dump_link_caps("Link partner advertised", -- "Link partner advertised", ep->lp_advertising, -- 0); -+ "Link partner advertised", -+ link_usettings->link_modes.lp_advertising, 0); - - fprintf(stdout, " Speed: "); -- speed = ethtool_cmd_speed(ep); -- if (speed == 0 || speed == (u16)(-1) || speed == (u32)(-1)) -+ if (link_usettings->base.speed == 0 -+ || link_usettings->base.speed == (u16)(-1) -+ || link_usettings->base.speed == (u32)(-1)) - fprintf(stdout, "Unknown!\n"); - else -- fprintf(stdout, "%uMb/s\n", speed); -+ fprintf(stdout, "%uMb/s\n", link_usettings->base.speed); - - fprintf(stdout, " Duplex: "); -- switch (ep->duplex) { -+ switch (link_usettings->base.duplex) { - case DUPLEX_HALF: - fprintf(stdout, "Half\n"); - break; -@@ -609,12 +710,12 @@ static int dump_ecmd(struct ethtool_cmd *ep) - fprintf(stdout, "Full\n"); - break; - default: -- fprintf(stdout, "Unknown! (%i)\n", ep->duplex); -+ fprintf(stdout, "Unknown! (%i)\n", link_usettings->base.duplex); - break; - }; - - fprintf(stdout, " Port: "); -- switch (ep->port) { -+ switch (link_usettings->base.port) { - case PORT_TP: - fprintf(stdout, "Twisted Pair\n"); - break; -@@ -640,13 +741,13 @@ static int dump_ecmd(struct ethtool_cmd *ep) - fprintf(stdout, "Other\n"); - break; - default: -- fprintf(stdout, "Unknown! (%i)\n", ep->port); -+ fprintf(stdout, "Unknown! (%i)\n", link_usettings->base.port); - break; - }; - -- fprintf(stdout, " PHYAD: %d\n", ep->phy_address); -+ fprintf(stdout, " PHYAD: %d\n", link_usettings->base.phy_address); - fprintf(stdout, " Transceiver: "); -- switch (ep->transceiver) { -+ switch (link_usettings->deprecated.transceiver) { - case XCVR_INTERNAL: - fprintf(stdout, "internal\n"); - break; -@@ -659,17 +760,18 @@ static int dump_ecmd(struct ethtool_cmd *ep) - }; - - fprintf(stdout, " Auto-negotiation: %s\n", -- (ep->autoneg == AUTONEG_DISABLE) ? -+ (link_usettings->base.autoneg == AUTONEG_DISABLE) ? - "off" : "on"); - -- if (ep->port == PORT_TP) { -+ if (link_usettings->base.port == PORT_TP) { - fprintf(stdout, " MDI-X: "); -- if (ep->eth_tp_mdix_ctrl == ETH_TP_MDI) { -+ if (link_usettings->base.eth_tp_mdix_ctrl == ETH_TP_MDI) { - fprintf(stdout, "off (forced)\n"); -- } else if (ep->eth_tp_mdix_ctrl == ETH_TP_MDI_X) { -+ } else if (link_usettings->base.eth_tp_mdix_ctrl -+ == ETH_TP_MDI_X) { - fprintf(stdout, "on (forced)\n"); - } else { -- switch (ep->eth_tp_mdix) { -+ switch (link_usettings->base.eth_tp_mdix) { - case ETH_TP_MDI: - fprintf(stdout, "off"); - break; -@@ -680,7 +782,8 @@ static int dump_ecmd(struct ethtool_cmd *ep) - fprintf(stdout, "Unknown"); - break; - } -- if (ep->eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO) -+ if (link_usettings->base.eth_tp_mdix_ctrl -+ == ETH_TP_MDI_AUTO) - fprintf(stdout, " (auto)"); - fprintf(stdout, "\n"); - } -@@ -1368,6 +1471,7 @@ static int dump_rxfhash(int fhash, u64 val) - - static void dump_eeecmd(struct ethtool_eee *ep) - { -+ ETHTOOL_DECLARE_LINK_MODE_MASK(link_mode); - - fprintf(stdout, " EEE status: "); - if (!ep->supported) { -@@ -1389,9 +1493,16 @@ static void dump_eeecmd(struct ethtool_eee *ep) - else - fprintf(stdout, " disabled\n"); - -- dump_link_caps("Supported EEE", "", ep->supported, 1); -- dump_link_caps("Advertised EEE", "", ep->advertised, 1); -- dump_link_caps("Link partner advertised EEE", "", ep->lp_advertised, 1); -+ ethtool_link_mode_zero(link_mode); -+ -+ link_mode[0] = ep->supported; -+ dump_link_caps("Supported EEE", "", link_mode, 1); -+ -+ link_mode[0] = ep->advertised; -+ dump_link_caps("Advertised EEE", "", link_mode, 1); -+ -+ link_mode[0] = ep->lp_advertised; -+ dump_link_caps("Link partner advertised EEE", "", link_mode, 1); - } - - #define N_SOTS 7 -@@ -2259,10 +2370,220 @@ finish: - return retval; - } - --static int do_gset(struct cmd_context *ctx) -+static struct ethtool_link_usettings * -+do_ioctl_glinksettings(struct cmd_context *ctx) -+{ -+ int err; -+ struct { -+ struct ethtool_link_settings req; -+ __u32 link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32]; -+ } ecmd; -+ struct ethtool_link_usettings *link_usettings; -+ unsigned int u32_offs; -+ -+ /* Handshake with kernel to determine number of words for link -+ * mode bitmaps. When requested number of bitmap words is not -+ * the one expected by kernel, the latter returns the integer -+ * opposite of what it is expecting. We request length 0 below -+ * (aka. invalid bitmap length) to get this info. -+ */ -+ memset(&ecmd, 0, sizeof(ecmd)); -+ ecmd.req.cmd = ETHTOOL_GLINKSETTINGS; -+ err = send_ioctl(ctx, &ecmd); -+ if (err < 0) -+ return NULL; -+ -+ /* see above: we expect a strictly negative value from kernel. -+ */ -+ if (ecmd.req.link_mode_masks_nwords >= 0 -+ || ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) -+ return NULL; -+ -+ /* got the real ecmd.req.link_mode_masks_nwords, -+ * now send the real request -+ */ -+ ecmd.req.cmd = ETHTOOL_GLINKSETTINGS; -+ ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords; -+ err = send_ioctl(ctx, &ecmd); -+ if (err < 0) -+ return NULL; -+ -+ if (ecmd.req.link_mode_masks_nwords <= 0 -+ || ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) -+ return NULL; -+ -+ /* Convert to usettings struct */ -+ link_usettings = calloc(1, sizeof(*link_usettings)); -+ if (link_usettings == NULL) -+ return NULL; -+ -+ /* keep transceiver 0 */ -+ memcpy(&link_usettings->base, &ecmd.req, sizeof(link_usettings->base)); -+ -+ /* copy link mode bitmaps */ -+ u32_offs = 0; -+ memcpy(link_usettings->link_modes.supported, -+ &ecmd.link_mode_data[u32_offs], -+ 4 * ecmd.req.link_mode_masks_nwords); -+ -+ u32_offs += ecmd.req.link_mode_masks_nwords; -+ memcpy(link_usettings->link_modes.advertising, -+ &ecmd.link_mode_data[u32_offs], -+ 4 * ecmd.req.link_mode_masks_nwords); -+ -+ u32_offs += ecmd.req.link_mode_masks_nwords; -+ memcpy(link_usettings->link_modes.lp_advertising, -+ &ecmd.link_mode_data[u32_offs], -+ 4 * ecmd.req.link_mode_masks_nwords); -+ -+ return link_usettings; -+} -+ -+static int -+do_ioctl_slinksettings(struct cmd_context *ctx, -+ const struct ethtool_link_usettings *link_usettings) -+{ -+ struct { -+ struct ethtool_link_settings req; -+ __u32 link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32]; -+ } ecmd; -+ unsigned int u32_offs; -+ -+ /* refuse to send ETHTOOL_SLINKSETTINGS ioctl if -+ * link_usettings was retrieved with ETHTOOL_GSET -+ */ -+ if (link_usettings->base.cmd != ETHTOOL_GLINKSETTINGS) -+ return -1; -+ -+ /* refuse to send ETHTOOL_SLINKSETTINGS ioctl if deprecated fields -+ * were set -+ */ -+ if (link_usettings->deprecated.transceiver) -+ return -1; -+ -+ if (link_usettings->base.link_mode_masks_nwords <= 0) -+ return -1; -+ -+ memcpy(&ecmd.req, &link_usettings->base, sizeof(ecmd.req)); -+ ecmd.req.cmd = ETHTOOL_SLINKSETTINGS; -+ -+ /* copy link mode bitmaps */ -+ u32_offs = 0; -+ memcpy(&ecmd.link_mode_data[u32_offs], -+ link_usettings->link_modes.supported, -+ 4 * ecmd.req.link_mode_masks_nwords); -+ -+ u32_offs += ecmd.req.link_mode_masks_nwords; -+ memcpy(&ecmd.link_mode_data[u32_offs], -+ link_usettings->link_modes.advertising, -+ 4 * ecmd.req.link_mode_masks_nwords); -+ -+ u32_offs += ecmd.req.link_mode_masks_nwords; -+ memcpy(&ecmd.link_mode_data[u32_offs], -+ link_usettings->link_modes.lp_advertising, -+ 4 * ecmd.req.link_mode_masks_nwords); -+ -+ return send_ioctl(ctx, &ecmd); -+} -+ -+static struct ethtool_link_usettings * -+do_ioctl_gset(struct cmd_context *ctx) - { - int err; - struct ethtool_cmd ecmd; -+ struct ethtool_link_usettings *link_usettings; -+ -+ memset(&ecmd, 0, sizeof(ecmd)); -+ ecmd.cmd = ETHTOOL_GSET; -+ err = send_ioctl(ctx, &ecmd); -+ if (err < 0) -+ return NULL; -+ -+ link_usettings = calloc(1, sizeof(*link_usettings)); -+ if (link_usettings == NULL) -+ return NULL; -+ -+ /* remember that ETHTOOL_GSET was used */ -+ link_usettings->base.cmd = ETHTOOL_GSET; -+ -+ link_usettings->base.link_mode_masks_nwords = 1; -+ link_usettings->link_modes.supported[0] = ecmd.supported; -+ link_usettings->link_modes.advertising[0] = ecmd.advertising; -+ link_usettings->link_modes.lp_advertising[0] = ecmd.lp_advertising; -+ link_usettings->base.speed = ethtool_cmd_speed(&ecmd); -+ link_usettings->base.duplex = ecmd.duplex; -+ link_usettings->base.port = ecmd.port; -+ link_usettings->base.phy_address = ecmd.phy_address; -+ link_usettings->deprecated.transceiver = ecmd.transceiver; -+ link_usettings->base.autoneg = ecmd.autoneg; -+ link_usettings->base.mdio_support = ecmd.mdio_support; -+ /* ignored (fully deprecated): maxrxpkt, maxtxpkt */ -+ link_usettings->base.eth_tp_mdix = ecmd.eth_tp_mdix; -+ link_usettings->base.eth_tp_mdix_ctrl = ecmd.eth_tp_mdix_ctrl; -+ -+ return link_usettings; -+} -+ -+static bool ethtool_link_mode_is_backward_compatible(const u32 *mask) -+{ -+ unsigned int i; -+ -+ for (i = 1; i < ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32; ++i) -+ if (mask[i]) -+ return false; -+ -+ return true; -+} -+ -+static int -+do_ioctl_sset(struct cmd_context *ctx, -+ const struct ethtool_link_usettings *link_usettings) -+{ -+ struct ethtool_cmd ecmd; -+ -+ /* refuse to send ETHTOOL_SSET ioctl if link_usettings was -+ * retrieved with ETHTOOL_GLINKSETTINGS -+ */ -+ if (link_usettings->base.cmd != ETHTOOL_GSET) -+ return -1; -+ -+ if (link_usettings->base.link_mode_masks_nwords <= 0) -+ return -1; -+ -+ /* refuse to sset if any bit > 31 is set */ -+ if (!ethtool_link_mode_is_backward_compatible( -+ link_usettings->link_modes.supported)) -+ return -1; -+ if (!ethtool_link_mode_is_backward_compatible( -+ link_usettings->link_modes.advertising)) -+ return -1; -+ if (!ethtool_link_mode_is_backward_compatible( -+ link_usettings->link_modes.lp_advertising)) -+ return -1; -+ -+ memset(&ecmd, 0, sizeof(ecmd)); -+ ecmd.cmd = ETHTOOL_SSET; -+ -+ ecmd.supported = link_usettings->link_modes.supported[0]; -+ ecmd.advertising = link_usettings->link_modes.advertising[0]; -+ ecmd.lp_advertising = link_usettings->link_modes.lp_advertising[0]; -+ ethtool_cmd_speed_set(&ecmd, link_usettings->base.speed); -+ ecmd.duplex = link_usettings->base.duplex; -+ ecmd.port = link_usettings->base.port; -+ ecmd.phy_address = link_usettings->base.phy_address; -+ ecmd.transceiver = link_usettings->deprecated.transceiver; -+ ecmd.autoneg = link_usettings->base.autoneg; -+ ecmd.mdio_support = link_usettings->base.mdio_support; -+ /* ignored (fully deprecated): maxrxpkt, maxtxpkt */ -+ ecmd.eth_tp_mdix = link_usettings->base.eth_tp_mdix; -+ ecmd.eth_tp_mdix_ctrl = link_usettings->base.eth_tp_mdix_ctrl; -+ return send_ioctl(ctx, &ecmd); -+} -+ -+static int do_gset(struct cmd_context *ctx) -+{ -+ int err; -+ struct ethtool_link_usettings *link_usettings; - struct ethtool_wolinfo wolinfo; - struct ethtool_value edata; - int allfail = 1; -@@ -2272,10 +2593,12 @@ static int do_gset(struct cmd_context *ctx) - - fprintf(stdout, "Settings for %s:\n", ctx->devname); - -- ecmd.cmd = ETHTOOL_GSET; -- err = send_ioctl(ctx, &ecmd); -- if (err == 0) { -- err = dump_ecmd(&ecmd); -+ link_usettings = do_ioctl_glinksettings(ctx); -+ if (link_usettings == NULL) -+ link_usettings = do_ioctl_gset(ctx); -+ if (link_usettings != NULL) { -+ err = dump_link_usettings(link_usettings); -+ free(link_usettings); - if (err) - return err; - allfail = 0; -@@ -2334,8 +2657,10 @@ static int do_sset(struct cmd_context *ctx) - int autoneg_wanted = -1; - int phyad_wanted = -1; - int xcvr_wanted = -1; -- int full_advertising_wanted = -1; -- int advertising_wanted = -1; -+ u32 *full_advertising_wanted = NULL; -+ u32 *advertising_wanted = NULL; -+ ETHTOOL_DECLARE_LINK_MODE_MASK(mask_full_advertising_wanted); -+ ETHTOOL_DECLARE_LINK_MODE_MASK(mask_advertising_wanted); - int gset_changed = 0; /* did anything in GSET change? */ - u32 wol_wanted = 0; - int wol_change = 0; -@@ -2349,7 +2674,7 @@ static int do_sset(struct cmd_context *ctx) - int argc = ctx->argc; - char **argp = ctx->argp; - int i; -- int err; -+ int err = 0; - - for (i = 0; i < ARRAY_SIZE(flags_msglvl); i++) - flag_to_cmdline_info(flags_msglvl[i].name, -@@ -2423,7 +2748,12 @@ static int do_sset(struct cmd_context *ctx) - i += 1; - if (i >= argc) - exit_bad_args(); -- full_advertising_wanted = get_int(argp[i], 16); -+ if (parse_hex_u32_bitmap( -+ argp[i], -+ ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBITS, -+ mask_full_advertising_wanted)) -+ exit_bad_args(); -+ full_advertising_wanted = mask_full_advertising_wanted; - } else if (!strcmp(argp[i], "phyad")) { - gset_changed = 1; - i += 1; -@@ -2480,75 +2810,89 @@ static int do_sset(struct cmd_context *ctx) - } - } - -- if (full_advertising_wanted < 0) { -+ if (full_advertising_wanted == NULL) { - /* User didn't supply a full advertisement bitfield: - * construct one from the specified speed and duplex. - */ -+ int adv_bit = -1; -+ - if (speed_wanted == SPEED_10 && duplex_wanted == DUPLEX_HALF) -- advertising_wanted = ADVERTISED_10baseT_Half; -+ adv_bit = ETHTOOL_LINK_MODE_10baseT_Half_BIT; - else if (speed_wanted == SPEED_10 && - duplex_wanted == DUPLEX_FULL) -- advertising_wanted = ADVERTISED_10baseT_Full; -+ adv_bit = ETHTOOL_LINK_MODE_10baseT_Full_BIT; - else if (speed_wanted == SPEED_100 && - duplex_wanted == DUPLEX_HALF) -- advertising_wanted = ADVERTISED_100baseT_Half; -+ adv_bit = ETHTOOL_LINK_MODE_100baseT_Half_BIT; - else if (speed_wanted == SPEED_100 && - duplex_wanted == DUPLEX_FULL) -- advertising_wanted = ADVERTISED_100baseT_Full; -+ adv_bit = ETHTOOL_LINK_MODE_100baseT_Full_BIT; - else if (speed_wanted == SPEED_1000 && - duplex_wanted == DUPLEX_HALF) -- advertising_wanted = ADVERTISED_1000baseT_Half; -+ adv_bit = ETHTOOL_LINK_MODE_1000baseT_Half_BIT; - else if (speed_wanted == SPEED_1000 && - duplex_wanted == DUPLEX_FULL) -- advertising_wanted = ADVERTISED_1000baseT_Full; -+ adv_bit = ETHTOOL_LINK_MODE_1000baseT_Full_BIT; - else if (speed_wanted == SPEED_2500 && - duplex_wanted == DUPLEX_FULL) -- advertising_wanted = ADVERTISED_2500baseX_Full; -+ adv_bit = ETHTOOL_LINK_MODE_2500baseX_Full_BIT; - else if (speed_wanted == SPEED_10000 && - duplex_wanted == DUPLEX_FULL) -- advertising_wanted = ADVERTISED_10000baseT_Full; -- else -- /* auto negotiate without forcing, -- * all supported speed will be assigned below -- */ -- advertising_wanted = 0; -+ adv_bit = ETHTOOL_LINK_MODE_10000baseT_Full_BIT; -+ -+ if (adv_bit >= 0) { -+ advertising_wanted = mask_advertising_wanted; -+ ethtool_link_mode_zero(advertising_wanted); -+ ethtool_link_mode_set_bit( -+ adv_bit, advertising_wanted); -+ } -+ /* otherwise: auto negotiate without forcing, -+ * all supported speed will be assigned below -+ */ - } - - if (gset_changed) { -- struct ethtool_cmd ecmd; -+ struct ethtool_link_usettings *link_usettings; - -- ecmd.cmd = ETHTOOL_GSET; -- err = send_ioctl(ctx, &ecmd); -- if (err < 0) { -+ link_usettings = do_ioctl_glinksettings(ctx); -+ if (link_usettings == NULL) -+ link_usettings = do_ioctl_gset(ctx); -+ if (link_usettings == NULL) { - perror("Cannot get current device settings"); -+ err = -1; - } else { - /* Change everything the user specified. */ - if (speed_wanted != -1) -- ethtool_cmd_speed_set(&ecmd, speed_wanted); -+ link_usettings->base.speed = speed_wanted; - if (duplex_wanted != -1) -- ecmd.duplex = duplex_wanted; -+ link_usettings->base.duplex = duplex_wanted; - if (port_wanted != -1) -- ecmd.port = port_wanted; -+ link_usettings->base.port = port_wanted; - if (mdix_wanted != -1) { - /* check driver supports MDI-X */ -- if (ecmd.eth_tp_mdix_ctrl != ETH_TP_MDI_INVALID) -- ecmd.eth_tp_mdix_ctrl = mdix_wanted; -+ if (link_usettings->base.eth_tp_mdix_ctrl -+ != ETH_TP_MDI_INVALID) -+ link_usettings->base.eth_tp_mdix_ctrl -+ = mdix_wanted; - else -- fprintf(stderr, "setting MDI not supported\n"); -+ fprintf(stderr, -+ "setting MDI not supported\n"); - } - if (autoneg_wanted != -1) -- ecmd.autoneg = autoneg_wanted; -+ link_usettings->base.autoneg = autoneg_wanted; - if (phyad_wanted != -1) -- ecmd.phy_address = phyad_wanted; -+ link_usettings->base.phy_address = phyad_wanted; - if (xcvr_wanted != -1) -- ecmd.transceiver = xcvr_wanted; -+ link_usettings->deprecated.transceiver -+ = xcvr_wanted; - /* XXX If the user specified speed or duplex - * then we should mask the advertised modes - * accordingly. For now, warn that we aren't - * doing that. - */ - if ((speed_wanted != -1 || duplex_wanted != -1) && -- ecmd.autoneg && advertising_wanted == 0) { -+ link_usettings->base.autoneg && -+ advertising_wanted == NULL) { - fprintf(stderr, "Cannot advertise"); - if (speed_wanted >= 0) - fprintf(stderr, " speed %d", -@@ -2560,37 +2904,55 @@ static int do_sset(struct cmd_context *ctx) - fprintf(stderr, "\n"); - } - if (autoneg_wanted == AUTONEG_ENABLE && -- advertising_wanted == 0) { -+ advertising_wanted == NULL) { -+ unsigned int i; -+ - /* Auto negotiation enabled, but with - * unspecified speed and duplex: enable all - * supported speeds and duplexes. - */ -- ecmd.advertising = -- (ecmd.advertising & -- ~ALL_ADVERTISED_MODES) | -- (ALL_ADVERTISED_MODES & ecmd.supported); -+ ethtool_link_mode_for_each_u32(i) { -+ u32 sup = link_usettings->link_modes.supported[i]; -+ u32 *adv = link_usettings->link_modes.advertising + i; -+ -+ *adv = ((*adv & ~all_advertised_modes[i]) -+ | (sup & all_advertised_modes[i])); -+ } - - /* If driver supports unknown flags, we cannot - * be sure that we enable all link modes. - */ -- if ((ecmd.supported & ALL_ADVERTISED_FLAGS) != -- ecmd.supported) { -- fprintf(stderr, "Driver supports one " -- "or more unknown flags\n"); -+ ethtool_link_mode_for_each_u32(i) { -+ u32 sup = link_usettings->link_modes.supported[i]; -+ -+ if ((sup & all_advertised_flags[i]) != sup) { -+ fprintf(stderr, "Driver supports one or more unknown flags\n"); -+ break; -+ } - } -- } else if (advertising_wanted > 0) { -+ } else if (advertising_wanted != NULL) { -+ unsigned int i; -+ - /* Enable all requested modes */ -- ecmd.advertising = -- (ecmd.advertising & -- ~ALL_ADVERTISED_MODES) | -- advertising_wanted; -- } else if (full_advertising_wanted > 0) { -- ecmd.advertising = full_advertising_wanted; -+ ethtool_link_mode_for_each_u32(i) { -+ u32 *adv = link_usettings->link_modes.advertising + i; -+ -+ *adv = ((*adv & ~all_advertised_modes[i]) -+ | advertising_wanted[i]); -+ } -+ } else if (full_advertising_wanted != NULL) { -+ ethtool_link_mode_copy( -+ link_usettings->link_modes.advertising, -+ full_advertising_wanted); - } - - /* Try to perform the update. */ -- ecmd.cmd = ETHTOOL_SSET; -- err = send_ioctl(ctx, &ecmd); -+ if (link_usettings->base.cmd == ETHTOOL_GLINKSETTINGS) -+ err = do_ioctl_slinksettings(ctx, -+ link_usettings); -+ else -+ err = do_ioctl_sset(ctx, link_usettings); -+ free(link_usettings); - if (err < 0) - perror("Cannot set new settings"); - } -@@ -4260,6 +4622,8 @@ int main(int argc, char **argp) - struct cmd_context ctx; - int k; - -+ init_global_link_mode_masks(); -+ - /* Skip command name */ - argp++; - argc--; -diff --git a/internal.h b/internal.h -index e98f532..ef27ab2 100644 ---- a/internal.h -+++ b/internal.h -@@ -12,6 +12,7 @@ - #ifdef HAVE_CONFIG_H - #include "ethtool-config.h" - #endif -+#include - #include - #include - #include -@@ -122,6 +123,71 @@ static inline int test_bit(unsigned int nr, const unsigned long *addr) - ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE | \ - ETH_FLAG_RXHASH) - -+/* internal API for link mode bitmap interaction with kernel. */ -+ -+#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32 \ -+ (SCHAR_MAX) -+#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBITS \ -+ (32 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32) -+#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES \ -+ (4 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32) -+#define ETHTOOL_DECLARE_LINK_MODE_MASK(name) \ -+ u32 name[ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32] -+ -+struct ethtool_link_usettings { -+ struct { -+ __u8 transceiver; -+ } deprecated; -+ struct ethtool_link_settings base; -+ struct { -+ ETHTOOL_DECLARE_LINK_MODE_MASK(supported); -+ ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); -+ ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising); -+ } link_modes; -+}; -+ -+#define ethtool_link_mode_for_each_u32(index) \ -+ for ((index) = 0; \ -+ (index) < ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32; \ -+ ++(index)) -+ -+static inline void ethtool_link_mode_zero(u32 *dst) -+{ -+ memset(dst, 0, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES); -+} -+ -+static inline bool ethtool_link_mode_is_empty(const u32 *mask) -+{ -+ unsigned int i; -+ -+ ethtool_link_mode_for_each_u32(i) { -+ if (mask[i] != 0) -+ return false; -+ } -+ -+ return true; -+} -+ -+static inline void ethtool_link_mode_copy(u32 *dst, const u32 *src) -+{ -+ memcpy(dst, src, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES); -+} -+ -+static inline int ethtool_link_mode_test_bit(unsigned int nr, const u32 *mask) -+{ -+ if (nr >= ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBITS) -+ return !!0; -+ return !!(mask[nr / 32] & (1 << (nr % 32))); -+} -+ -+static inline int ethtool_link_mode_set_bit(unsigned int nr, u32 *mask) -+{ -+ if (nr >= ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBITS) -+ return -1; -+ mask[nr / 32] |= (1 << (nr % 32)); -+ return 0; -+} -+ - /* Context for sub-commands */ - struct cmd_context { - const char *devname; /* net device name */ -diff --git a/test-cmdline.c b/test-cmdline.c -index 2fd7cbb..a94edea 100644 ---- a/test-cmdline.c -+++ b/test-cmdline.c -@@ -37,7 +37,20 @@ static struct test_case { - { 1, "--change devname autoneg foo" }, - { 1, "-s devname autoneg" }, - { 0, "--change devname advertise 0x1" }, -+ { 0, "--change devname advertise 0xf" }, -+ { 0, "--change devname advertise 0Xf" }, -+ { 0, "--change devname advertise 1" }, -+ { 0, "--change devname advertise f" }, -+ { 0, "--change devname advertise 01" }, -+ { 0, "--change devname advertise 0f" }, -+ { 0, "--change devname advertise 0xfffffffffffffffffffffffffffffffff" }, -+ { 0, "--change devname advertise fffffffffffffffffffffffffffffffff" }, -+ { 0, "--change devname advertise 0x0000fffffffffffffffffffffffffffff" }, -+ { 0, "--change devname advertise 0000fffffffffffffffffffffffffffff" }, -+ { 1, "-s devname advertise" }, -+ { 1, "-s devname advertise 0x" }, - { 1, "-s devname advertise foo" }, -+ { 1, "-s devname advertise 0xfoo" }, - { 1, "--change devname advertise" }, - { 0, "-s devname phyad 1" }, - { 1, "--change devname phyad foo" }, --- -1.8.3.1 - diff --git a/SOURCES/0003-ethtool-Fix-the-advertise-parameter-logic.patch b/SOURCES/0003-ethtool-Fix-the-advertise-parameter-logic.patch new file mode 100644 index 0000000..8f47dc2 --- /dev/null +++ b/SOURCES/0003-ethtool-Fix-the-advertise-parameter-logic.patch @@ -0,0 +1,44 @@ +From 47b95959941b3d7d2d35a128da5685799329aaf6 Mon Sep 17 00:00:00 2001 +From: Michael Chan +Date: Tue, 22 Nov 2016 18:55:47 -0500 +Subject: [PATCH 3/3] ethtool: Fix the "advertise" parameter logic. + +The current code ignores the value of the advertise parameter. For example, + +ethtool -s ethx advertise 0x1000 + +The full_advertising_wanted parameter of 0x1000 is not passed to the kernel. +The reason is that advertising_wanted is NULL in this case, and ethtool +will think that the user has given no advertisement input and so it will +proceed to pass all supported advertisement speeds to the kernel. + +The older legacy ethtool with similar logic worked because +advertising_wanted was an integer and could take on -1 and 0. It would pass +the full_advertising_wanted value if advertising_wanted == -1. + +This fix is to pass all supported advertisement speeds only when both +advertising_wanted == NULL && full_advertising_wanted == NULL. + +Signed-off-by: Michael Chan +Signed-off-by: John W. Linville +--- + ethtool.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/ethtool.c b/ethtool.c +index 0d3244e..ce48639 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -2972,7 +2972,8 @@ static int do_sset(struct cmd_context *ctx) + fprintf(stderr, "\n"); + } + if (autoneg_wanted == AUTONEG_ENABLE && +- advertising_wanted == NULL) { ++ advertising_wanted == NULL && ++ full_advertising_wanted == NULL) { + unsigned int i; + + /* Auto negotiation enabled, but with +-- +1.8.3.1 + diff --git a/SOURCES/0003-ethtool-copy.h-sync-with-net.patch b/SOURCES/0003-ethtool-copy.h-sync-with-net.patch deleted file mode 100644 index b4fb20b..0000000 --- a/SOURCES/0003-ethtool-copy.h-sync-with-net.patch +++ /dev/null @@ -1,74 +0,0 @@ -From c3a3768ddec648ddc15402b8054ee1b4d3b2f336 Mon Sep 17 00:00:00 2001 -From: Vidya Sagar Ravipati -Date: Tue, 23 Aug 2016 06:30:30 -0700 -Subject: [PATCH 3/7] ethtool-copy.h:sync with net - -This covers kernel changes upto: - -commit 89da45b8b5b2187734a11038b8593714f964ffd1 -Author: Gal Pressman -Date: Thu Jun 23 17:02:43 2016 +0300 - - ethtool: Add 50G baseSR2 link mode - - Add ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT bit. - - Signed-off-by: Gal Pressman - Signed-off-by: Saeed Mahameed - Cc: Ben Hutchings - Cc: David Decotigny - Acked-By: David Decotigny - Signed-off-by: David S. Miller - -Signed-off-by: John W. Linville -(cherry picked from commit c431e762fadca8648d78d0e7e1842e1a0c9ac309) ---- - ethtool-copy.h | 18 ++++++++++++++---- - 1 file changed, 14 insertions(+), 4 deletions(-) - -diff --git a/ethtool-copy.h b/ethtool-copy.h -index 7c581ea..246f7b0 100644 ---- a/ethtool-copy.h -+++ b/ethtool-copy.h -@@ -1351,6 +1351,16 @@ enum ethtool_link_mode_bit_indices { - ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT = 28, - ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT = 29, - ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT = 30, -+ ETHTOOL_LINK_MODE_25000baseCR_Full_BIT = 31, -+ ETHTOOL_LINK_MODE_25000baseKR_Full_BIT = 32, -+ ETHTOOL_LINK_MODE_25000baseSR_Full_BIT = 33, -+ ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT = 34, -+ ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT = 35, -+ ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT = 36, -+ ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT = 37, -+ ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT = 38, -+ ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT = 39, -+ ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT = 40, - - /* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit - * 31. Please do NOT define any SUPPORTED_* or ADVERTISED_* -@@ -1359,7 +1369,7 @@ enum ethtool_link_mode_bit_indices { - */ - - __ETHTOOL_LINK_MODE_LAST -- = ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT, -+ = ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, - }; - - #define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) \ -@@ -1646,9 +1656,9 @@ enum ethtool_reset_flags { - * %ETHTOOL_GLINKSETTINGS: on entry, number of words passed by user - * (>= 0); on return, if handshake in progress, negative if - * request size unsupported by kernel: absolute value indicates -- * kernel recommended size and cmd field is 0, as well as all the -- * other fields; otherwise (handshake completed), strictly -- * positive to indicate size used by kernel and cmd field is -+ * kernel expected size and all the other fields but cmd -+ * are 0; otherwise (handshake completed), strictly positive -+ * to indicate size used by kernel and cmd field stays - * %ETHTOOL_GLINKSETTINGS, all other fields populated by driver. For - * %ETHTOOL_SLINKSETTINGS: must be valid on entry, ie. a positive - * value returned previously by %ETHTOOL_GLINKSETTINGS, otherwise --- -1.8.3.1 - diff --git a/SOURCES/0004-ethtool-Reorganizing-SFF-8024-fields-for-SFP-QSFP.patch b/SOURCES/0004-ethtool-Reorganizing-SFF-8024-fields-for-SFP-QSFP.patch deleted file mode 100644 index 3e6de4d..0000000 --- a/SOURCES/0004-ethtool-Reorganizing-SFF-8024-fields-for-SFP-QSFP.patch +++ /dev/null @@ -1,872 +0,0 @@ -From 0173e95eb07cef9f189299a040e11f31de15f638 Mon Sep 17 00:00:00 2001 -From: Vidya Sagar Ravipati -Date: Tue, 23 Aug 2016 06:30:31 -0700 -Subject: [PATCH 4/7] ethtool:Reorganizing SFF-8024 fields for SFP/QSFP - -This patch provides following support -a) Reorganized fields based out of SFF-8024 fields i.e. Identifier/ - Encoding/Connector types which are common across SFP/SFP+ (SFF-8472) - and QSFP+/QSFP28 (SFF-8436/SFF-8636) modules into sff-common files. -b) Moving the common functions for SFP+ and QSFP+ DOM into sff-common - files - -Standards for SFF-8024 -a) SFF-8024 Rev 4.0 dated May 31, 2016 - -Signed-off-by: Vidya Sagar Ravipati -Acked-by: Bert Kenward -Signed-off-by: John W. Linville -(cherry picked from commit 7a4c42258e3038ff943c1e27c74b4bca2d3190a0) ---- - Makefile.am | 3 +- - sff-common.c | 304 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - sff-common.h | 189 +++++++++++++++++++++++++++++++++++++ - sfpdiag.c | 105 +++------------------ - sfpid.c | 103 +------------------- - 5 files changed, 511 insertions(+), 193 deletions(-) - create mode 100644 sff-common.c - create mode 100644 sff-common.h - -diff --git a/Makefile.am b/Makefile.am -index 6814bc9..3c9f387 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -13,7 +13,8 @@ ethtool_SOURCES += \ - fec_8xx.c ibm_emac.c ixgb.c ixgbe.c natsemi.c \ - pcnet32.c realtek.c tg3.c marvell.c vioc.c \ - smsc911x.c at76c50x-usb.c sfc.c stmmac.c \ -- sfpid.c sfpdiag.c ixgbevf.c tse.c vmxnet3.c -+ sff-common.c sff-common.h sfpid.c sfpdiag.c \ -+ ixgbevf.c tse.c vmxnet3.c - endif - - TESTS = test-cmdline test-features -diff --git a/sff-common.c b/sff-common.c -new file mode 100644 -index 0000000..7700cbe ---- /dev/null -+++ b/sff-common.c -@@ -0,0 +1,304 @@ -+/* -+ * sff-common.c: Implements SFF-8024 Rev 4.0 i.e. Specifcation -+ * of pluggable I/O configuration -+ * -+ * Common utilities across SFF-8436/8636 and SFF-8472/8079 -+ * are defined in this file -+ * -+ * Copyright 2010 Solarflare Communications Inc. -+ * Aurelien Guillaume (C) 2012 -+ * Copyright (C) 2014 Cumulus networks Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Freeoftware Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * Vidya Sagar Ravipati -+ * This implementation is loosely based on current SFP parser -+ * and SFF-8024 Rev 4.0 spec (ftp://ftp.seagate.com/pub/sff/SFF-8024.PDF) -+ * by SFF Committee. -+ */ -+ -+#include -+#include -+#include "sff-common.h" -+ -+double convert_mw_to_dbm(double mw) -+{ -+ return (10. * log10(mw / 1000.)) + 30.; -+} -+ -+void sff_show_value_with_unit(const __u8 *id, unsigned int reg, -+ const char *name, unsigned int mult, -+ const char *unit) -+{ -+ unsigned int val = id[reg]; -+ -+ printf("\t%-41s : %u%s\n", name, val * mult, unit); -+} -+ -+void sff_show_ascii(const __u8 *id, unsigned int first_reg, -+ unsigned int last_reg, const char *name) -+{ -+ unsigned int reg, val; -+ -+ printf("\t%-41s : ", name); -+ while (first_reg <= last_reg && id[last_reg] == ' ') -+ last_reg--; -+ for (reg = first_reg; reg <= last_reg; reg++) { -+ val = id[reg]; -+ putchar(((val >= 32) && (val <= 126)) ? val : '_'); -+ } -+ printf("\n"); -+} -+ -+void sff8024_show_oui(const __u8 *id, int id_offset) -+{ -+ printf("\t%-41s : %02x:%02x:%02x\n", "Vendor OUI", -+ id[id_offset], id[(id_offset) + 1], -+ id[(id_offset) + 2]); -+} -+ -+void sff8024_show_identifier(const __u8 *id, int id_offset) -+{ -+ printf("\t%-41s : 0x%02x", "Identifier", id[id_offset]); -+ switch (id[id_offset]) { -+ case SFF8024_ID_UNKNOWN: -+ printf(" (no module present, unknown, or unspecified)\n"); -+ break; -+ case SFF8024_ID_GBIC: -+ printf(" (GBIC)\n"); -+ break; -+ case SFF8024_ID_SOLDERED_MODULE: -+ printf(" (module soldered to motherboard)\n"); -+ break; -+ case SFF8024_ID_SFP: -+ printf(" (SFP)\n"); -+ break; -+ case SFF8024_ID_300_PIN_XBI: -+ printf(" (300 pin XBI)\n"); -+ break; -+ case SFF8024_ID_XENPAK: -+ printf(" (XENPAK)\n"); -+ break; -+ case SFF8024_ID_XFP: -+ printf(" (XFP)\n"); -+ break; -+ case SFF8024_ID_XFF: -+ printf(" (XFF)\n"); -+ break; -+ case SFF8024_ID_XFP_E: -+ printf(" (XFP-E)\n"); -+ break; -+ case SFF8024_ID_XPAK: -+ printf(" (XPAK)\n"); -+ break; -+ case SFF8024_ID_X2: -+ printf(" (X2)\n"); -+ break; -+ case SFF8024_ID_DWDM_SFP: -+ printf(" (DWDM-SFP)\n"); -+ break; -+ case SFF8024_ID_QSFP: -+ printf(" (QSFP)\n"); -+ break; -+ case SFF8024_ID_QSFP_PLUS: -+ printf(" (QSFP+)\n"); -+ break; -+ case SFF8024_ID_CXP: -+ printf(" (CXP)\n"); -+ break; -+ case SFF8024_ID_HD4X: -+ printf(" (Shielded Mini Multilane HD 4X)\n"); -+ break; -+ case SFF8024_ID_HD8X: -+ printf(" (Shielded Mini Multilane HD 8X)\n"); -+ break; -+ case SFF8024_ID_QSFP28: -+ printf(" (QSFP28)\n"); -+ break; -+ case SFF8024_ID_CXP2: -+ printf(" (CXP2/CXP28)\n"); -+ break; -+ case SFF8024_ID_CDFP: -+ printf(" (CDFP Style 1/Style 2)\n"); -+ break; -+ case SFF8024_ID_HD4X_FANOUT: -+ printf(" (Shielded Mini Multilane HD 4X Fanout Cable)\n"); -+ break; -+ case SFF8024_ID_HD8X_FANOUT: -+ printf(" (Shielded Mini Multilane HD 8X Fanout Cable)\n"); -+ break; -+ case SFF8024_ID_CDFP_S3: -+ printf(" (CDFP Style 3)\n"); -+ break; -+ case SFF8024_ID_MICRO_QSFP: -+ printf(" (microQSFP)\n"); -+ break; -+ default: -+ printf(" (reserved or unknown)\n"); -+ break; -+ } -+} -+ -+void sff8024_show_connector(const __u8 *id, int ctor_offset) -+{ -+ printf("\t%-41s : 0x%02x", "Connector", id[ctor_offset]); -+ switch (id[ctor_offset]) { -+ case SFF8024_CTOR_UNKNOWN: -+ printf(" (unknown or unspecified)\n"); -+ break; -+ case SFF8024_CTOR_SC: -+ printf(" (SC)\n"); -+ break; -+ case SFF8024_CTOR_FC_STYLE_1: -+ printf(" (Fibre Channel Style 1 copper)\n"); -+ break; -+ case SFF8024_CTOR_FC_STYLE_2: -+ printf(" (Fibre Channel Style 2 copper)\n"); -+ break; -+ case SFF8024_CTOR_BNC_TNC: -+ printf(" (BNC/TNC)\n"); -+ break; -+ case SFF8024_CTOR_FC_COAX: -+ printf(" (Fibre Channel coaxial headers)\n"); -+ break; -+ case SFF8024_CTOR_FIBER_JACK: -+ printf(" (FibreJack)\n"); -+ break; -+ case SFF8024_CTOR_LC: -+ printf(" (LC)\n"); -+ break; -+ case SFF8024_CTOR_MT_RJ: -+ printf(" (MT-RJ)\n"); -+ break; -+ case SFF8024_CTOR_MU: -+ printf(" (MU)\n"); -+ break; -+ case SFF8024_CTOR_SG: -+ printf(" (SG)\n"); -+ break; -+ case SFF8024_CTOR_OPT_PT: -+ printf(" (Optical pigtail)\n"); -+ break; -+ case SFF8024_CTOR_MPO: -+ printf(" (MPO Parallel Optic)\n"); -+ break; -+ case SFF8024_CTOR_MPO_2: -+ printf(" (MPO Parallel Optic - 2x16)\n"); -+ break; -+ case SFF8024_CTOR_HSDC_II: -+ printf(" (HSSDC II)\n"); -+ break; -+ case SFF8024_CTOR_COPPER_PT: -+ printf(" (Copper pigtail)\n"); -+ break; -+ case SFF8024_CTOR_RJ45: -+ printf(" (RJ45)\n"); -+ break; -+ case SFF8024_CTOR_NO_SEPARABLE: -+ printf(" (No separable connector)\n"); -+ break; -+ case SFF8024_CTOR_MXC_2x16: -+ printf(" (MXC 2x16)\n"); -+ break; -+ default: -+ printf(" (reserved or unknown)\n"); -+ break; -+ } -+} -+ -+void sff8024_show_encoding(const __u8 *id, int encoding_offset, int sff_type) -+{ -+ printf("\t%-41s : 0x%02x", "Encoding", id[encoding_offset]); -+ switch (id[encoding_offset]) { -+ case SFF8024_ENCODING_UNSPEC: -+ printf(" (unspecified)\n"); -+ break; -+ case SFF8024_ENCODING_8B10B: -+ printf(" (8B/10B)\n"); -+ break; -+ case SFF8024_ENCODING_4B5B: -+ printf(" (4B/5B)\n"); -+ break; -+ case SFF8024_ENCODING_NRZ: -+ printf(" (NRZ)\n"); -+ break; -+ case SFF8024_ENCODING_4h: -+ if (sff_type == ETH_MODULE_SFF_8472) -+ printf(" (Manchester)\n"); -+ else if (sff_type == ETH_MODULE_SFF_8636) -+ printf(" (SONET Scrambled)\n"); -+ break; -+ case SFF8024_ENCODING_5h: -+ if (sff_type == ETH_MODULE_SFF_8472) -+ printf(" (SONET Scrambled)\n"); -+ else if (sff_type == ETH_MODULE_SFF_8636) -+ printf(" (64B/66B)\n"); -+ break; -+ case SFF8024_ENCODING_6h: -+ if (sff_type == ETH_MODULE_SFF_8472) -+ printf(" (64B/66B)\n"); -+ else if (sff_type == ETH_MODULE_SFF_8636) -+ printf(" (Manchester)\n"); -+ break; -+ case SFF8024_ENCODING_256B: -+ printf(" ((256B/257B (transcoded FEC-enabled data))\n"); -+ break; -+ case SFF8024_ENCODING_PAM4: -+ printf(" (PAM4)\n"); -+ break; -+ default: -+ printf(" (reserved or unknown)\n"); -+ break; -+ } -+} -+ -+void sff_show_thresholds(struct sff_diags sd) -+{ -+ PRINT_BIAS("Laser bias current high alarm threshold", -+ sd.bias_cur[HALRM]); -+ PRINT_BIAS("Laser bias current low alarm threshold", -+ sd.bias_cur[LALRM]); -+ PRINT_BIAS("Laser bias current high warning threshold", -+ sd.bias_cur[HWARN]); -+ PRINT_BIAS("Laser bias current low warning threshold", -+ sd.bias_cur[LWARN]); -+ -+ PRINT_xX_PWR("Laser output power high alarm threshold", -+ sd.tx_power[HALRM]); -+ PRINT_xX_PWR("Laser output power low alarm threshold", -+ sd.tx_power[LALRM]); -+ PRINT_xX_PWR("Laser output power high warning threshold", -+ sd.tx_power[HWARN]); -+ PRINT_xX_PWR("Laser output power low warning threshold", -+ sd.tx_power[LWARN]); -+ -+ PRINT_TEMP("Module temperature high alarm threshold", -+ sd.sfp_temp[HALRM]); -+ PRINT_TEMP("Module temperature low alarm threshold", -+ sd.sfp_temp[LALRM]); -+ PRINT_TEMP("Module temperature high warning threshold", -+ sd.sfp_temp[HWARN]); -+ PRINT_TEMP("Module temperature low warning threshold", -+ sd.sfp_temp[LWARN]); -+ -+ PRINT_VCC("Module voltage high alarm threshold", -+ sd.sfp_voltage[HALRM]); -+ PRINT_VCC("Module voltage low alarm threshold", -+ sd.sfp_voltage[LALRM]); -+ PRINT_VCC("Module voltage high warning threshold", -+ sd.sfp_voltage[HWARN]); -+ PRINT_VCC("Module voltage low warning threshold", -+ sd.sfp_voltage[LWARN]); -+ -+ PRINT_xX_PWR("Laser rx power high alarm threshold", -+ sd.rx_power[HALRM]); -+ PRINT_xX_PWR("Laser rx power low alarm threshold", -+ sd.rx_power[LALRM]); -+ PRINT_xX_PWR("Laser rx power high warning threshold", -+ sd.rx_power[HWARN]); -+ PRINT_xX_PWR("Laser rx power low warning threshold", -+ sd.rx_power[LWARN]); -+} -diff --git a/sff-common.h b/sff-common.h -new file mode 100644 -index 0000000..5562b4d ---- /dev/null -+++ b/sff-common.h -@@ -0,0 +1,189 @@ -+/* -+ * sff-common.h: Implements SFF-8024 Rev 4.0 i.e. Specifcation -+ * of pluggable I/O configuration -+ * -+ * Common utilities across SFF-8436/8636 and SFF-8472/8079 -+ * are defined in this file -+ * -+ * Copyright 2010 Solarflare Communications Inc. -+ * Aurelien Guillaume (C) 2012 -+ * Copyright (C) 2014 Cumulus networks Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Freeoftware Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * Vidya Sagar Ravipati -+ * This implementation is loosely based on current SFP parser -+ * and SFF-8024 specs (ftp://ftp.seagate.com/pub/sff/SFF-8024.PDF) -+ * by SFF Committee. -+ */ -+ -+#ifndef SFF_COMMON_H__ -+#define SFF_COMMON_H__ -+ -+#include -+#include "internal.h" -+ -+#define SFF8024_ID_OFFSET 0x00 -+#define SFF8024_ID_UNKNOWN 0x00 -+#define SFF8024_ID_GBIC 0x01 -+#define SFF8024_ID_SOLDERED_MODULE 0x02 -+#define SFF8024_ID_SFP 0x03 -+#define SFF8024_ID_300_PIN_XBI 0x04 -+#define SFF8024_ID_XENPAK 0x05 -+#define SFF8024_ID_XFP 0x06 -+#define SFF8024_ID_XFF 0x07 -+#define SFF8024_ID_XFP_E 0x08 -+#define SFF8024_ID_XPAK 0x09 -+#define SFF8024_ID_X2 0x0A -+#define SFF8024_ID_DWDM_SFP 0x0B -+#define SFF8024_ID_QSFP 0x0C -+#define SFF8024_ID_QSFP_PLUS 0x0D -+#define SFF8024_ID_CXP 0x0E -+#define SFF8024_ID_HD4X 0x0F -+#define SFF8024_ID_HD8X 0x10 -+#define SFF8024_ID_QSFP28 0x11 -+#define SFF8024_ID_CXP2 0x12 -+#define SFF8024_ID_CDFP 0x13 -+#define SFF8024_ID_HD4X_FANOUT 0x14 -+#define SFF8024_ID_HD8X_FANOUT 0x15 -+#define SFF8024_ID_CDFP_S3 0x16 -+#define SFF8024_ID_MICRO_QSFP 0x17 -+#define SFF8024_ID_LAST SFF8024_ID_MICRO_QSFP -+#define SFF8024_ID_UNALLOCATED_LAST 0x7F -+#define SFF8024_ID_VENDOR_START 0x80 -+#define SFF8024_ID_VENDOR_LAST 0xFF -+ -+#define SFF8024_CTOR_UNKNOWN 0x00 -+#define SFF8024_CTOR_SC 0x01 -+#define SFF8024_CTOR_FC_STYLE_1 0x02 -+#define SFF8024_CTOR_FC_STYLE_2 0x03 -+#define SFF8024_CTOR_BNC_TNC 0x04 -+#define SFF8024_CTOR_FC_COAX 0x05 -+#define SFF8024_CTOR_FIBER_JACK 0x06 -+#define SFF8024_CTOR_LC 0x07 -+#define SFF8024_CTOR_MT_RJ 0x08 -+#define SFF8024_CTOR_MU 0x09 -+#define SFF8024_CTOR_SG 0x0A -+#define SFF8024_CTOR_OPT_PT 0x0B -+#define SFF8024_CTOR_MPO 0x0C -+#define SFF8024_CTOR_MPO_2 0x0D -+/* 0E-1Fh --- Reserved */ -+#define SFF8024_CTOR_HSDC_II 0x20 -+#define SFF8024_CTOR_COPPER_PT 0x21 -+#define SFF8024_CTOR_RJ45 0x22 -+#define SFF8024_CTOR_NO_SEPARABLE 0x23 -+#define SFF8024_CTOR_MXC_2x16 0x24 -+#define SFF8024_CTOR_LAST SFF8024_CTOR_MXC_2x16 -+#define SFF8024_CTOR_UNALLOCATED_LAST 0x7F -+#define SFF8024_CTOR_VENDOR_START 0x80 -+#define SFF8024_CTOR_VENDOR_LAST 0xFF -+ -+/* ENCODING Values */ -+#define SFF8024_ENCODING_UNSPEC 0x00 -+#define SFF8024_ENCODING_8B10B 0x01 -+#define SFF8024_ENCODING_4B5B 0x02 -+#define SFF8024_ENCODING_NRZ 0x03 -+/* -+ * Value: 04h -+ * SFF-8472 - Manchester -+ * SFF-8436/8636 - SONET Scrambled -+ */ -+#define SFF8024_ENCODING_4h 0x04 -+/* -+ * Value: 05h -+ * SFF-8472 - SONET Scrambled -+ * SFF-8436/8636 - 64B/66B -+ */ -+#define SFF8024_ENCODING_5h 0x05 -+/* -+ * Value: 06h -+ * SFF-8472 - 64B/66B -+ * SFF-8436/8636 - Manchester -+ */ -+#define SFF8024_ENCODING_6h 0x06 -+#define SFF8024_ENCODING_256B 0x07 -+#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 PRINT_xX_PWR(string, var) \ -+ printf("\t%-41s : %.4f mW / %.2f dBm\n", (string), \ -+ (double)((var) / 10000.), \ -+ convert_mw_to_dbm((double)((var) / 10000.))) -+ -+#define PRINT_BIAS(string, bias_cur) \ -+ printf("\t%-41s : %.3f mA\n", (string), \ -+ (double)(bias_cur / 500.)) -+ -+#define PRINT_TEMP(string, temp) \ -+ printf("\t%-41s : %.2f degrees C / %.2f degrees F\n", \ -+ (string), (double)(temp / 256.), \ -+ (double)(temp / 256. * 1.8 + 32.)) -+ -+#define PRINT_VCC(string, sfp_voltage) \ -+ printf("\t%-41s : %.4f V\n", (string), \ -+ (double)(sfp_voltage / 10000.)) -+ -+# define PRINT_xX_THRESH_PWR(string, var, index) \ -+ PRINT_xX_PWR(string, (var)[(index)]) -+ -+/* Channel Monitoring Fields */ -+struct sff_channel_diags { -+ __u16 bias_cur; /* Measured bias current in 2uA units */ -+ __u16 rx_power; /* Measured RX Power */ -+ __u16 tx_power; /* Measured TX Power */ -+}; -+ -+/* Module Monitoring Fields */ -+struct sff_diags { -+ -+#define MAX_CHANNEL_NUM 4 -+#define LWARN 0 -+#define HWARN 1 -+#define LALRM 2 -+#define HALRM 3 -+#define MCURR 4 -+ -+ /* Supports DOM */ -+ __u8 supports_dom; -+ /* Supports alarm/warning thold */ -+ __u8 supports_alarms; -+ /* RX Power: 0 = OMA, 1 = Average power */ -+ __u8 rx_power_type; -+ /* TX Power: 0 = Not supported, 1 = Average power */ -+ __u8 tx_power_type; -+ -+ __u8 calibrated_ext; /* Is externally calibrated */ -+ /* [5] tables are low/high warn, low/high alarm, current */ -+ /* SFP voltage in 0.1mV units */ -+ __u16 sfp_voltage[5]; -+ /* SFP Temp in 16-bit signed 1/256 Celcius */ -+ __s16 sfp_temp[5]; -+ /* Measured bias current in 2uA units */ -+ __u16 bias_cur[5]; -+ /* Measured TX Power */ -+ __u16 tx_power[5]; -+ /* Measured RX Power */ -+ __u16 rx_power[5]; -+ struct sff_channel_diags scd[MAX_CHANNEL_NUM]; -+}; -+ -+double convert_mw_to_dbm(double mw); -+void sff_show_value_with_unit(const __u8 *id, unsigned int reg, -+ const char *name, unsigned int mult, -+ const char *unit); -+void sff_show_ascii(const __u8 *id, unsigned int first_reg, -+ unsigned int last_reg, const char *name); -+void sff_show_thresholds(struct sff_diags sd); -+ -+void sff8024_show_oui(const __u8 *id, int id_offset); -+void sff8024_show_identifier(const __u8 *id, int id_offset); -+void sff8024_show_connector(const __u8 *id, int ctor_offset); -+void sff8024_show_encoding(const __u8 *id, int encoding_offset, int sff_type); -+ -+#endif /* SFF_COMMON_H__ */ -diff --git a/sfpdiag.c b/sfpdiag.c -index a3dbc9b..32e4cd8 100644 ---- a/sfpdiag.c -+++ b/sfpdiag.c -@@ -12,6 +12,7 @@ - #include - #include - #include "internal.h" -+#include "sff-common.h" - - /* Offsets in decimal, for direct comparison with the SFF specs */ - -@@ -86,28 +87,6 @@ - #define SFF_A2_CAL_V_SLP 88 - #define SFF_A2_CAL_V_OFF 90 - -- --struct sff8472_diags { -- --#define MCURR 0 --#define LWARN 1 --#define HWARN 2 --#define LALRM 3 --#define HALRM 4 -- -- /* [5] tables are current, low/high warn, low/high alarm */ -- __u8 supports_dom; /* Supports DOM */ -- __u8 supports_alarms; /* Supports alarm/warning thold */ -- __u8 calibrated_ext; /* Is externally calibrated */ -- __u16 bias_cur[5]; /* Measured bias current in 2uA units */ -- __u16 tx_power[5]; /* Measured TX Power in 0.1uW units */ -- __u16 rx_power[5]; /* Measured RX Power */ -- __u8 rx_power_type; /* 0 = OMA, 1 = Average power */ -- __s16 sfp_temp[5]; /* SFP Temp in 16-bit signed 1/256 Celsius */ -- __u16 sfp_voltage[5]; /* SFP voltage in 0.1mV units */ -- --}; -- - static struct sff8472_aw_flags { - const char *str; /* Human-readable string, null at the end */ - int offset; /* A2-relative address offset */ -@@ -141,12 +120,6 @@ static struct sff8472_aw_flags { - { NULL, 0, 0 }, - }; - --static double convert_mw_to_dbm(double mw) --{ -- return (10. * log10(mw / 1000.)) + 30.; --} -- -- - /* Most common case: 16-bit unsigned integer in a certain unit */ - #define A2_OFFSET_TO_U16(offset) \ - (id[SFF_A2_BASE + (offset)] << 8 | id[SFF_A2_BASE + (offset) + 1]) -@@ -170,10 +143,8 @@ static double convert_mw_to_dbm(double mw) - */ - #define A2_OFFSET_TO_TEMP(offset) ((__s16)A2_OFFSET_TO_U16(offset)) - -- --static void sff8472_dom_parse(const __u8 *id, struct sff8472_diags *sd) -+static void sff8472_dom_parse(const __u8 *id, struct sff_diags *sd) - { -- - sd->bias_cur[MCURR] = A2_OFFSET_TO_U16(SFF_A2_BIAS); - sd->bias_cur[HALRM] = A2_OFFSET_TO_U16(SFF_A2_BIAS_HALRM); - sd->bias_cur[LALRM] = A2_OFFSET_TO_U16(SFF_A2_BIAS_LALRM); -@@ -203,7 +174,6 @@ static void sff8472_dom_parse(const __u8 *id, struct sff8472_diags *sd) - sd->sfp_temp[LALRM] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_LALRM); - sd->sfp_temp[HWARN] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_HWARN); - sd->sfp_temp[LWARN] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_LWARN); -- - } - - /* Converts to a float from a big-endian 4-byte source buffer. */ -@@ -218,7 +188,7 @@ static float befloattoh(const __u32 *source) - return converter.dst; - } - --static void sff8472_calibration(const __u8 *id, struct sff8472_diags *sd) -+static void sff8472_calibration(const __u8 *id, struct sff_diags *sd) - { - int i; - __u16 rx_reading; -@@ -252,7 +222,7 @@ static void sff8472_calibration(const __u8 *id, struct sff8472_diags *sd) - } - } - --static void sff8472_parse_eeprom(const __u8 *id, struct sff8472_diags *sd) -+static void sff8472_parse_eeprom(const __u8 *id, struct sff_diags *sd) - { - sd->supports_dom = id[SFF_A0_DOM] & SFF_A0_DOM_IMPL; - sd->supports_alarms = id[SFF_A0_OPTIONS] & SFF_A0_OPTIONS_AW; -@@ -271,7 +241,7 @@ static void sff8472_parse_eeprom(const __u8 *id, struct sff8472_diags *sd) - - void sff8472_show_all(const __u8 *id) - { -- struct sff8472_diags sd; -+ struct sff_diags sd; - char *rx_power_string = NULL; - int i; - -@@ -279,40 +249,22 @@ void sff8472_show_all(const __u8 *id) - - if (!sd.supports_dom) { - printf("\t%-41s : No\n", "Optical diagnostics support"); -- return ; -+ return; - } - printf("\t%-41s : Yes\n", "Optical diagnostics support"); - --#define PRINT_BIAS(string, index) \ -- printf("\t%-41s : %.3f mA\n", (string), \ -- (double)(sd.bias_cur[(index)] / 500.)) -- --# define PRINT_xX_PWR(string, var, index) \ -- printf("\t%-41s : %.4f mW / %.2f dBm\n", (string), \ -- (double)((var)[(index)] / 10000.), \ -- convert_mw_to_dbm((double)((var)[(index)] / 10000.))) -- --#define PRINT_TEMP(string, index) \ -- printf("\t%-41s : %.2f degrees C / %.2f degrees F\n", (string), \ -- (double)(sd.sfp_temp[(index)] / 256.), \ -- (double)(sd.sfp_temp[(index)] / 256. * 1.8 + 32.)) -- --#define PRINT_VCC(string, index) \ -- printf("\t%-41s : %.4f V\n", (string), \ -- (double)(sd.sfp_voltage[(index)] / 10000.)) -- -- PRINT_BIAS("Laser bias current", MCURR); -- PRINT_xX_PWR("Laser output power", sd.tx_power, MCURR); -+ PRINT_BIAS("Laser bias current", sd.bias_cur[MCURR]); -+ PRINT_xX_PWR("Laser output power", sd.tx_power[MCURR]); - - if (!sd.rx_power_type) - rx_power_string = "Receiver signal OMA"; - else - rx_power_string = "Receiver signal average optical power"; - -- PRINT_xX_PWR(rx_power_string, sd.rx_power, MCURR); -+ PRINT_xX_PWR(rx_power_string, sd.rx_power[MCURR]); - -- PRINT_TEMP("Module temperature", MCURR); -- PRINT_VCC("Module voltage", MCURR); -+ PRINT_TEMP("Module temperature", sd.sfp_temp[MCURR]); -+ PRINT_VCC("Module voltage", sd.sfp_voltage[MCURR]); - - printf("\t%-41s : %s\n", "Alarm/warning flags implemented", - (sd.supports_alarms ? "Yes" : "No")); -@@ -323,40 +275,7 @@ void sff8472_show_all(const __u8 *id) - id[SFF_A2_BASE + sff8472_aw_flags[i].offset] - & sff8472_aw_flags[i].value ? "On" : "Off"); - } -- -- PRINT_BIAS("Laser bias current high alarm threshold", HALRM); -- PRINT_BIAS("Laser bias current low alarm threshold", LALRM); -- PRINT_BIAS("Laser bias current high warning threshold", HWARN); -- PRINT_BIAS("Laser bias current low warning threshold", LWARN); -- -- PRINT_xX_PWR("Laser output power high alarm threshold", -- sd.tx_power, HALRM); -- PRINT_xX_PWR("Laser output power low alarm threshold", -- sd.tx_power, LALRM); -- PRINT_xX_PWR("Laser output power high warning threshold", -- sd.tx_power, HWARN); -- PRINT_xX_PWR("Laser output power low warning threshold", -- sd.tx_power, LWARN); -- -- PRINT_TEMP("Module temperature high alarm threshold", HALRM); -- PRINT_TEMP("Module temperature low alarm threshold", LALRM); -- PRINT_TEMP("Module temperature high warning threshold", HWARN); -- PRINT_TEMP("Module temperature low warning threshold", LWARN); -- -- PRINT_VCC("Module voltage high alarm threshold", HALRM); -- PRINT_VCC("Module voltage low alarm threshold", LALRM); -- PRINT_VCC("Module voltage high warning threshold", HWARN); -- PRINT_VCC("Module voltage low warning threshold", LWARN); -- -- PRINT_xX_PWR("Laser rx power high alarm threshold", -- sd.rx_power, HALRM); -- PRINT_xX_PWR("Laser rx power low alarm threshold", -- sd.rx_power, LALRM); -- PRINT_xX_PWR("Laser rx power high warning threshold", -- sd.rx_power, HWARN); -- PRINT_xX_PWR("Laser rx power low warning threshold", -- sd.rx_power, LWARN); -+ sff_show_thresholds(sd); - } -- - } - -diff --git a/sfpid.c b/sfpid.c -index 0b5cd62..fd6415c 100644 ---- a/sfpid.c -+++ b/sfpid.c -@@ -9,27 +9,11 @@ - - #include - #include "internal.h" -+#include "sff-common.h" - - static void sff8079_show_identifier(const __u8 *id) - { -- printf("\t%-41s : 0x%02x", "Identifier", id[0]); -- switch (id[0]) { -- case 0x00: -- printf(" (no module present, unknown, or unspecified)\n"); -- break; -- case 0x01: -- printf(" (GBIC)\n"); -- break; -- case 0x02: -- printf(" (module soldered to motherboard)\n"); -- break; -- case 0x03: -- printf(" (SFP)\n"); -- break; -- default: -- printf(" (reserved or unknown)\n"); -- break; -- } -+ sff8024_show_identifier(id, 0); - } - - static void sff8079_show_ext_identifier(const __u8 *id) -@@ -47,60 +31,7 @@ static void sff8079_show_ext_identifier(const __u8 *id) - - static void sff8079_show_connector(const __u8 *id) - { -- printf("\t%-41s : 0x%02x", "Connector", id[2]); -- switch (id[2]) { -- case 0x00: -- printf(" (unknown or unspecified)\n"); -- break; -- case 0x01: -- printf(" (SC)\n"); -- break; -- case 0x02: -- printf(" (Fibre Channel Style 1 copper)\n"); -- break; -- case 0x03: -- printf(" (Fibre Channel Style 2 copper)\n"); -- break; -- case 0x04: -- printf(" (BNC/TNC)\n"); -- break; -- case 0x05: -- printf(" (Fibre Channel coaxial headers)\n"); -- break; -- case 0x06: -- printf(" (FibreJack)\n"); -- break; -- case 0x07: -- printf(" (LC)\n"); -- break; -- case 0x08: -- printf(" (MT-RJ)\n"); -- break; -- case 0x09: -- printf(" (MU)\n"); -- break; -- case 0x0a: -- printf(" (SG)\n"); -- break; -- case 0x0b: -- printf(" (Optical pigtail)\n"); -- break; -- case 0x0c: -- printf(" (MPO Parallel Optic)\n"); -- break; -- case 0x20: -- printf(" (HSSDC II)\n"); -- break; -- case 0x21: -- printf(" (Copper pigtail)\n"); -- break; -- case 0x22: -- printf(" (RJ45)\n"); -- break; -- default: -- printf(" (reserved or unknown)\n"); -- break; -- } -+ sff8024_show_connector(id, 2); - } - - static void sff8079_show_transceiver(const __u8 *id) -@@ -241,33 +172,7 @@ static void sff8079_show_transceiver(const __u8 *id) - - static void sff8079_show_encoding(const __u8 *id) - { -- printf("\t%-41s : 0x%02x", "Encoding", id[11]); -- switch (id[11]) { -- case 0x00: -- printf(" (unspecified)\n"); -- break; -- case 0x01: -- printf(" (8B/10B)\n"); -- break; -- case 0x02: -- printf(" (4B/5B)\n"); -- break; -- case 0x03: -- printf(" (NRZ)\n"); -- break; -- case 0x04: -- printf(" (Manchester)\n"); -- break; -- case 0x05: -- printf(" (SONET Scrambled)\n"); -- break; -- case 0x06: -- printf(" (64B/66B)\n"); -- break; -- default: -- printf(" (reserved or unknown)\n"); -- break; -- } -+ sff8024_show_encoding(id, 11, ETH_MODULE_SFF_8472); - } - - static void sff8079_show_rate_identifier(const __u8 *id) --- -1.8.3.1 - diff --git a/SOURCES/0005-ethtool-QSFP-Plus-QSFP28-Diagnostics-Information-Sup.patch b/SOURCES/0005-ethtool-QSFP-Plus-QSFP28-Diagnostics-Information-Sup.patch deleted file mode 100644 index a893134..0000000 --- a/SOURCES/0005-ethtool-QSFP-Plus-QSFP28-Diagnostics-Information-Sup.patch +++ /dev/null @@ -1,1466 +0,0 @@ -From 3cfd8329790e382c88c670e4f9e7014f1cbd4ad6 Mon Sep 17 00:00:00 2001 -From: Vidya Sagar Ravipati -Date: Tue, 23 Aug 2016 06:30:32 -0700 -Subject: [PATCH 5/7] ethtool:QSFP Plus/QSFP28 Diagnostics Information Support - -This patch provides following support -a) Support for diagnostics information for QSFP Plus/QSFP28 modules - based on SFF-8436/SFF-8636 - -Standards for QSFP+/QSFP28 -a) QSFP+/QSFP28 - SFF 8636 Rev 2.7 dated January 26,2016 -b) SFF-8024 Rev 4.0 dated May 31, 2016 - -Signed-off-by: Vidya Sagar Ravipati -Acked-by: Bert Kenward -Signed-off-by: John W. Linville -(cherry picked from commit a5e73bb05ee4de0a1c06b117e0ee3ea4cba83561) ---- - Makefile.am | 2 +- - ethtool.c | 5 + - internal.h | 3 + - qsfp.c | 788 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - qsfp.h | 595 +++++++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 1392 insertions(+), 1 deletion(-) - create mode 100644 qsfp.c - create mode 100644 qsfp.h - -diff --git a/Makefile.am b/Makefile.am -index 3c9f387..de2db2e 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -14,7 +14,7 @@ ethtool_SOURCES += \ - pcnet32.c realtek.c tg3.c marvell.c vioc.c \ - smsc911x.c at76c50x-usb.c sfc.c stmmac.c \ - sff-common.c sff-common.h sfpid.c sfpdiag.c \ -- ixgbevf.c tse.c vmxnet3.c -+ ixgbevf.c tse.c vmxnet3.c qsfp.c qsfp.h - endif - - TESTS = test-cmdline test-features -diff --git a/ethtool.c b/ethtool.c -index 796d0b5..ffb3573 100644 ---- a/ethtool.c -+++ b/ethtool.c -@@ -4355,6 +4355,11 @@ static int do_getmodule(struct cmd_context *ctx) - sff8079_show_all(eeprom->data); - sff8472_show_all(eeprom->data); - break; -+ case ETH_MODULE_SFF_8436: -+ case ETH_MODULE_SFF_8636: -+ sff8636_show_all(eeprom->data, -+ modinfo.eeprom_len); -+ break; - #endif - default: - geeprom_dump_hex = 1; -diff --git a/internal.h b/internal.h -index ef27ab2..3c08b74 100644 ---- a/internal.h -+++ b/internal.h -@@ -345,4 +345,7 @@ void sff8079_show_all(const __u8 *id); - /* Optics diagnostics */ - void sff8472_show_all(const __u8 *id); - -+/* QSFP Optics diagnostics */ -+void sff8636_show_all(const __u8 *id, __u32 eeprom_len); -+ - #endif /* ETHTOOL_INTERNAL_H__ */ -diff --git a/qsfp.c b/qsfp.c -new file mode 100644 -index 0000000..213802e ---- /dev/null -+++ b/qsfp.c -@@ -0,0 +1,788 @@ -+/* -+ * qsfp.c: Implements SFF-8636 based QSFP+/QSFP28 Diagnostics Memory map. -+ * -+ * Copyright 2010 Solarflare Communications Inc. -+ * Aurelien Guillaume (C) 2012 -+ * Copyright (C) 2014 Cumulus networks Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Freeoftware Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * Vidya Ravipati -+ * This implementation is loosely based on current SFP parser -+ * and SFF-8636 spec Rev 2.7 (ftp://ftp.seagate.com/pub/sff/SFF-8636.PDF) -+ * by SFF Committee. -+ */ -+ -+/* -+ * Description: -+ * a) The register/memory layout is up to 5 128 byte pages defined by -+ * a "pages valid" register and switched via a "page select" -+ * register. Memory of 256 bytes can be memory mapped at a time -+ * according to SFF 8636. -+ * b) SFF 8636 based 640 bytes memory layout is presented for parser -+ * -+ * SFF 8636 based QSFP Memory Map -+ * -+ * 2-Wire Serial Address: 1010000x -+ * -+ * Lower Page 00h (128 bytes) -+ * ====================== -+ * | | -+ * |Page Select Byte(127)| -+ * ====================== -+ * | -+ * V -+ * ---------------------------------------- -+ * | | | | -+ * V V V V -+ * ---------- ---------- --------- ------------ -+ * | Upper | | Upper | | Upper | | Upper | -+ * | Page 00h | | Page 01h | | Page 02h | | Page 03h | -+ * | | |(Optional)| |(Optional)| | (Optional) | -+ * | | | | | | | | -+ * | | | | | | | | -+ * | ID | | AST | | User | | For | -+ * | Fields | | Table | | EEPROM | | Cable | -+ * | | | | | Data | | Assemblies | -+ * | | | | | | | | -+ * | | | | | | | | -+ * ----------- ----------- ---------- -------------- -+ * -+ * -+ **/ -+#include -+#include -+#include "internal.h" -+#include "sff-common.h" -+#include "qsfp.h" -+ -+#define MAX_DESC_SIZE 42 -+ -+static struct sff8636_aw_flags { -+ const char *str; /* Human-readable string, null at the end */ -+ int offset; /* A2-relative address offset */ -+ __u8 value; /* Alarm is on if (offset & value) != 0. */ -+} sff8636_aw_flags[] = { -+ { "Laser bias current high alarm (Chan 1)", -+ SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_1_HALARM) }, -+ { "Laser bias current low alarm (Chan 1)", -+ SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_1_LALARM) }, -+ { "Laser bias current high warning (Chan 1)", -+ SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_1_HWARN) }, -+ { "Laser bias current low warning (Chan 1)", -+ SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_1_LWARN) }, -+ -+ { "Laser bias current high alarm (Chan 2)", -+ SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_2_HALARM) }, -+ { "Laser bias current low alarm (Chan 2)", -+ SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_2_LALARM) }, -+ { "Laser bias current high warning (Chan 2)", -+ SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_2_HWARN) }, -+ { "Laser bias current low warning (Chan 2)", -+ SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_2_LWARN) }, -+ -+ { "Laser bias current high alarm (Chan 3)", -+ SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_3_HALARM) }, -+ { "Laser bias current low alarm (Chan 3)", -+ SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_3_LALARM) }, -+ { "Laser bias current high warning (Chan 3)", -+ SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_3_HWARN) }, -+ { "Laser bias current low warning (Chan 3)", -+ SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_3_LWARN) }, -+ -+ { "Laser bias current high alarm (Chan 4)", -+ SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_4_HALARM) }, -+ { "Laser bias current low alarm (Chan 4)", -+ SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_4_LALARM) }, -+ { "Laser bias current high warning (Chan 4)", -+ SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_4_HWARN) }, -+ { "Laser bias current low warning (Chan 4)", -+ SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_4_LWARN) }, -+ -+ { "Module temperature high alarm", -+ SFF8636_TEMP_AW_OFFSET, (SFF8636_TEMP_HALARM_STATUS) }, -+ { "Module temperature low alarm", -+ SFF8636_TEMP_AW_OFFSET, (SFF8636_TEMP_LALARM_STATUS) }, -+ { "Module temperature high warning", -+ SFF8636_TEMP_AW_OFFSET, (SFF8636_TEMP_HWARN_STATUS) }, -+ { "Module temperature low warning", -+ SFF8636_TEMP_AW_OFFSET, (SFF8636_TEMP_LWARN_STATUS) }, -+ -+ { "Module voltage high alarm", -+ SFF8636_VCC_AW_OFFSET, (SFF8636_VCC_HALARM_STATUS) }, -+ { "Module voltage low alarm", -+ SFF8636_VCC_AW_OFFSET, (SFF8636_VCC_LALARM_STATUS) }, -+ { "Module voltage high warning", -+ SFF8636_VCC_AW_OFFSET, (SFF8636_VCC_HWARN_STATUS) }, -+ { "Module voltage low warning", -+ SFF8636_VCC_AW_OFFSET, (SFF8636_VCC_LWARN_STATUS) }, -+ -+ { "Laser tx power high alarm (Channel 1)", -+ SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_1_HALARM) }, -+ { "Laser tx power low alarm (Channel 1)", -+ SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_1_LALARM) }, -+ { "Laser tx power high warning (Channel 1)", -+ SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_1_HWARN) }, -+ { "Laser tx power low warning (Channel 1)", -+ SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_1_LWARN) }, -+ -+ { "Laser tx power high alarm (Channel 2)", -+ SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_2_HALARM) }, -+ { "Laser tx power low alarm (Channel 2)", -+ SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_2_LALARM) }, -+ { "Laser tx power high warning (Channel 2)", -+ SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_2_HWARN) }, -+ { "Laser tx power low warning (Channel 2)", -+ SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_2_LWARN) }, -+ -+ { "Laser tx power high alarm (Channel 3)", -+ SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_3_HALARM) }, -+ { "Laser tx power low alarm (Channel 3)", -+ SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_3_LALARM) }, -+ { "Laser tx power high warning (Channel 3)", -+ SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_3_HWARN) }, -+ { "Laser tx power low warning (Channel 3)", -+ SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_3_LWARN) }, -+ -+ { "Laser tx power high alarm (Channel 4)", -+ SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_4_HALARM) }, -+ { "Laser tx power low alarm (Channel 4)", -+ SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_4_LALARM) }, -+ { "Laser tx power high warning (Channel 4)", -+ SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_4_HWARN) }, -+ { "Laser tx power low warning (Channel 4)", -+ SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_4_LWARN) }, -+ -+ { "Laser rx power high alarm (Channel 1)", -+ SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_1_HALARM) }, -+ { "Laser rx power low alarm (Channel 1)", -+ SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_1_LALARM) }, -+ { "Laser rx power high warning (Channel 1)", -+ SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_1_HWARN) }, -+ { "Laser rx power low warning (Channel 1)", -+ SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_1_LWARN) }, -+ -+ { "Laser rx power high alarm (Channel 2)", -+ SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_2_HALARM) }, -+ { "Laser rx power low alarm (Channel 2)", -+ SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_2_LALARM) }, -+ { "Laser rx power high warning (Channel 2)", -+ SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_2_HWARN) }, -+ { "Laser rx power low warning (Channel 2)", -+ SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_2_LWARN) }, -+ -+ { "Laser rx power high alarm (Channel 3)", -+ SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_3_HALARM) }, -+ { "Laser rx power low alarm (Channel 3)", -+ SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_3_LALARM) }, -+ { "Laser rx power high warning (Channel 3)", -+ SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_3_HWARN) }, -+ { "Laser rx power low warning (Channel 3)", -+ SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_3_LWARN) }, -+ -+ { "Laser rx power high alarm (Channel 4)", -+ SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_4_HALARM) }, -+ { "Laser rx power low alarm (Channel 4)", -+ SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_4_LALARM) }, -+ { "Laser rx power high warning (Channel 4)", -+ SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_4_HWARN) }, -+ { "Laser rx power low warning (Channel 4)", -+ SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_4_LWARN) }, -+ -+ { NULL, 0, 0 }, -+}; -+ -+static void sff8636_show_identifier(const __u8 *id) -+{ -+ sff8024_show_identifier(id, SFF8636_ID_OFFSET); -+} -+ -+static void sff8636_show_ext_identifier(const __u8 *id) -+{ -+ printf("\t%-41s : 0x%02x\n", "Extended identifier", -+ id[SFF8636_EXT_ID_OFFSET]); -+ -+ static const char *pfx = -+ "\tExtended identifier description :"; -+ -+ switch (id[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; -+ case SFF8636_EXT_ID_PWR_CLASS_2: -+ printf("%s 2.0W max. Power consumption\n", pfx); -+ break; -+ case SFF8636_EXT_ID_PWR_CLASS_3: -+ printf("%s 2.5W max. Power consumption\n", pfx); -+ break; -+ case SFF8636_EXT_ID_PWR_CLASS_4: -+ printf("%s 3.5W max. Power consumption\n", pfx); -+ break; -+ } -+ -+ if (id[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) -+ 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) { -+ case SFF8636_EXT_ID_PWR_CLASS_LEGACY: -+ printf("%s", pfx); -+ break; -+ case SFF8636_EXT_ID_PWR_CLASS_5: -+ printf("%s 4.0W max. Power consumption,", pfx); -+ break; -+ case SFF8636_EXT_ID_PWR_CLASS_6: -+ printf("%s 4.5W max. Power consumption, ", pfx); -+ break; -+ case SFF8636_EXT_ID_PWR_CLASS_7: -+ printf("%s 5.0W max. Power consumption, ", pfx); -+ break; -+ } -+ if (id[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) -+{ -+ sff8024_show_connector(id, SFF8636_CTOR_OFFSET); -+} -+ -+static void sff8636_show_transceiver(const __u8 *id) -+{ -+ static const char *pfx = -+ "\tTransceiver type :"; -+ -+ 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]); -+ -+ /* 10G/40G Ethernet Compliance Codes */ -+ if (id[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) -+ printf("%s 10G Ethernet: 10G Base-LR\n", pfx); -+ if (id[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) -+ printf("%s 40G Ethernet: 40G Base-CR4\n", pfx); -+ if (id[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) -+ printf("%s 40G Ethernet: 40G Base-LR4\n", pfx); -+ if (id[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]) { -+ case SFF8636_ETHERNET_UNSPECIFIED: -+ printf("%s (reserved or unknown)\n", pfx); -+ break; -+ case SFF8636_ETHERNET_100G_AOC: -+ printf("%s 100G Ethernet: 100G AOC or 25GAUI C2M AOC with worst BER of 5x10^(-5)\n", -+ pfx); -+ break; -+ case SFF8636_ETHERNET_100G_SR4: -+ printf("%s 100G Ethernet: 100G Base-SR4 or 25GBase-SR\n", -+ pfx); -+ break; -+ case SFF8636_ETHERNET_100G_LR4: -+ printf("%s 100G Ethernet: 100G Base-LR4\n", pfx); -+ break; -+ case SFF8636_ETHERNET_100G_ER4: -+ printf("%s 100G Ethernet: 100G Base-ER4\n", pfx); -+ break; -+ case SFF8636_ETHERNET_100G_SR10: -+ printf("%s 100G Ethernet: 100G Base-SR10\n", pfx); -+ break; -+ case SFF8636_ETHERNET_100G_CWDM4_FEC: -+ printf("%s 100G Ethernet: 100G CWDM4 MSA with FEC\n", pfx); -+ break; -+ case SFF8636_ETHERNET_100G_PSM4: -+ printf("%s 100G Ethernet: 100G PSM4 Parallel SMF\n", pfx); -+ break; -+ case SFF8636_ETHERNET_100G_ACC: -+ printf("%s 100G Ethernet: 100G ACC or 25GAUI C2M ACC with worst BER of 5x10^(-5)\n", -+ pfx); -+ break; -+ case SFF8636_ETHERNET_100G_CWDM4_NO_FEC: -+ printf("%s 100G Ethernet: 100G CWDM4 MSA without FEC\n", pfx); -+ break; -+ case SFF8636_ETHERNET_100G_RSVD1: -+ printf("%s (reserved or unknown)\n", pfx); -+ break; -+ case SFF8636_ETHERNET_100G_CR4: -+ printf("%s 100G Ethernet: 100G Base-CR4 or 25G Base-CR CA-L\n", -+ pfx); -+ break; -+ case SFF8636_ETHERNET_25G_CR_CA_S: -+ printf("%s 25G Ethernet: 25G Base-CR CA-S\n", pfx); -+ break; -+ case SFF8636_ETHERNET_25G_CR_CA_N: -+ printf("%s 25G Ethernet: 25G Base-CR CA-N\n", pfx); -+ break; -+ case SFF8636_ETHERNET_40G_ER4: -+ printf("%s 40G Ethernet: 40G Base-ER4\n", pfx); -+ break; -+ case SFF8636_ETHERNET_4X10_SR: -+ printf("%s 4x10G Ethernet: 10G Base-SR\n", pfx); -+ break; -+ case SFF8636_ETHERNET_40G_PSM4: -+ printf("%s 40G Ethernet: 40G PSM4 Parallel SMF\n", pfx); -+ break; -+ case SFF8636_ETHERNET_G959_P1I1_2D1: -+ printf("%s Ethernet: G959.1 profile P1I1-2D1 (10709 MBd, 2km, 1310nm SM)\n", -+ pfx); -+ break; -+ case SFF8636_ETHERNET_G959_P1S1_2D2: -+ printf("%s Ethernet: G959.1 profile P1S1-2D2 (10709 MBd, 40km, 1550nm SM)\n", -+ pfx); -+ break; -+ case SFF8636_ETHERNET_G959_P1L1_2D2: -+ printf("%s Ethernet: G959.1 profile P1L1-2D2 (10709 MBd, 80km, 1550nm SM)\n", -+ pfx); -+ break; -+ case SFF8636_ETHERNET_10GT_SFI: -+ printf("%s 10G Ethernet: 10G Base-T with SFI electrical interface\n", -+ pfx); -+ break; -+ case SFF8636_ETHERNET_100G_CLR4: -+ printf("%s 100G Ethernet: 100G CLR4\n", pfx); -+ break; -+ case SFF8636_ETHERNET_100G_AOC2: -+ printf("%s 100G Ethernet: 100G AOC or 25GAUI C2M AOC with worst BER of 10^(-12)\n", -+ pfx); -+ break; -+ case SFF8636_ETHERNET_100G_ACC2: -+ printf("%s 100G Ethernet: 100G ACC or 25GAUI C2M ACC with worst BER of 10^(-12)\n", -+ pfx); -+ break; -+ default: -+ printf("%s (reserved or unknown)\n", pfx); -+ break; -+ } -+ } -+ -+ /* SONET Compliance Codes */ -+ if (id[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)) -+ printf("%s SONET: OC-48, long reach\n", pfx); -+ if (id[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)) -+ printf("%s SONET: OC-48, short reach\n", pfx); -+ -+ /* SAS/SATA Compliance Codes */ -+ if (id[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_6G)) -+ printf("%s SAS 6.0G\n", pfx); -+ if (id[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) -+ printf("%s Ethernet: 1000BASE-T\n", pfx); -+ if (id[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) -+ printf("%s Ethernet: 1000BASE-LX\n", pfx); -+ if (id[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) -+ printf("%s FC: very long distance (V)\n", pfx); -+ if (id[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) -+ printf("%s FC: intermediate distance (I)\n", pfx); -+ if (id[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) -+ printf("%s FC: medium distance (M)\n", pfx); -+ -+ /* Fibre Channel transmitter technology */ -+ if (id[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) -+ printf("%s FC: Electrical inter-enclosure (EL)\n", pfx); -+ if (id[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) -+ printf("%s FC: Shortwave laser w/o OFC (SN)\n", pfx); -+ if (id[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) -+ printf("%s FC: Longwave laser (LL)\n", pfx); -+ -+ /* Fibre Channel transmission media */ -+ if (id[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) -+ printf("%s FC: Twisted Pair (TP)\n", pfx); -+ if (id[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) -+ printf("%s FC: Video Coax (TV)\n", pfx); -+ if (id[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) -+ printf("%s FC: Multimode, 50m (M5)\n", pfx); -+ if (id[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) -+ printf("%s FC: Single Mode (SM)\n", pfx); -+ -+ /* Fibre Channel speed */ -+ if (id[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) -+ printf("%s FC: 800 MBytes/sec\n", pfx); -+ if (id[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) -+ printf("%s FC: 400 MBytes/sec\n", pfx); -+ if (id[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) -+ printf("%s FC: 100 MBytes/sec\n", pfx); -+} -+ -+static void sff8636_show_encoding(const __u8 *id) -+{ -+ sff8024_show_encoding(id, SFF8636_ENCODING_OFFSET, ETH_MODULE_SFF_8636); -+} -+ -+static void sff8636_show_rate_identifier(const __u8 *id) -+{ -+ /* TODO: Need to fix rate select logic */ -+ printf("\t%-41s : 0x%02x\n", "Rate identifier", -+ id[SFF8636_EXT_RS_OFFSET]); -+} -+ -+static void sff8636_show_oui(const __u8 *id) -+{ -+ sff8024_show_oui(id, SFF8636_VENDOR_OUI_OFFSET); -+} -+ -+static void sff8636_show_wavelength_or_copper_compliance(const __u8 *id) -+{ -+ printf("\t%-41s : 0x%02x", "Transmitter technology", -+ (id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK)); -+ -+ switch (id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK) { -+ case SFF8636_TRANS_850_VCSEL: -+ printf(" (850 nm VCSEL)\n"); -+ break; -+ case SFF8636_TRANS_1310_VCSEL: -+ printf(" (1310 nm VCSEL)\n"); -+ break; -+ case SFF8636_TRANS_1550_VCSEL: -+ printf(" (1550 nm VCSEL)\n"); -+ break; -+ case SFF8636_TRANS_1310_FP: -+ printf(" (1310 nm FP)\n"); -+ break; -+ case SFF8636_TRANS_1310_DFB: -+ printf(" (1310 nm DFB)\n"); -+ break; -+ case SFF8636_TRANS_1550_DFB: -+ printf(" (1550 nm DFB)\n"); -+ break; -+ case SFF8636_TRANS_1310_EML: -+ printf(" (1310 nm EML)\n"); -+ break; -+ case SFF8636_TRANS_1550_EML: -+ printf(" (1550 nm EML)\n"); -+ break; -+ case SFF8636_TRANS_OTHERS: -+ printf(" (Others/Undefined)\n"); -+ break; -+ case SFF8636_TRANS_1490_DFB: -+ printf(" (1490 nm DFB)\n"); -+ break; -+ case SFF8636_TRANS_COPPER_PAS_UNEQUAL: -+ printf(" (Copper cable unequalized)\n"); -+ break; -+ case SFF8636_TRANS_COPPER_PAS_EQUAL: -+ printf(" (Copper cable passive equalized)\n"); -+ break; -+ case SFF8636_TRANS_COPPER_LNR_FAR_EQUAL: -+ printf(" (Copper cable, near and far end limiting active equalizers)\n"); -+ break; -+ case SFF8636_TRANS_COPPER_FAR_EQUAL: -+ printf(" (Copper cable, far end limiting active equalizers)\n"); -+ break; -+ case SFF8636_TRANS_COPPER_NEAR_EQUAL: -+ printf(" (Copper cable, near end limiting active equalizers)\n"); -+ break; -+ case SFF8636_TRANS_COPPER_LNR_EQUAL: -+ printf(" (Copper cable, linear active equalizers)\n"); -+ break; -+ } -+ -+ if ((id[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]); -+ printf("\t%-41s : %udb\n", "Attenuation at 5.0GHz", -+ id[SFF8636_WAVELEN_LOW_BYTE_OFFSET]); -+ printf("\t%-41s : %udb\n", "Attenuation at 7.0GHz", -+ id[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET]); -+ printf("\t%-41s : %udb\n", "Attenuation at 12.9GHz", -+ id[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)); -+ 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)); -+ } -+} -+ -+static void sff8636_show_revision_compliance(const __u8 *id) -+{ -+ static const char *pfx = -+ "\tRevision Compliance :"; -+ -+ switch (id[SFF8636_REV_COMPLIANCE_OFFSET]) { -+ case SFF8636_REV_UNSPECIFIED: -+ printf("%s Revision not specified\n", pfx); -+ break; -+ case SFF8636_REV_8436_48: -+ printf("%s SFF-8436 Rev 4.8 or earlier\n", pfx); -+ break; -+ case SFF8636_REV_8436_8636: -+ printf("%s SFF-8436 Rev 4.8 or earlier\n", pfx); -+ break; -+ case SFF8636_REV_8636_13: -+ printf("%s SFF-8636 Rev 1.3 or earlier\n", pfx); -+ break; -+ case SFF8636_REV_8636_14: -+ printf("%s SFF-8636 Rev 1.4\n", pfx); -+ break; -+ case SFF8636_REV_8636_15: -+ printf("%s SFF-8636 Rev 1.5\n", pfx); -+ break; -+ case SFF8636_REV_8636_20: -+ printf("%s SFF-8636 Rev 2.0\n", pfx); -+ break; -+ case SFF8636_REV_8636_27: -+ printf("%s SFF-8636 Rev 2.5/2.6/2.7\n", pfx); -+ break; -+ default: -+ printf("%s Unallocated\n", pfx); -+ break; -+ } -+} -+ -+/* -+ * 2-byte internal temperature conversions: -+ * First byte is a signed 8-bit integer, which is the temp decimal part -+ * 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)) -+ -+static void sff8636_dom_parse(const __u8 *id, struct sff_diags *sd) -+{ -+ int i = 0; -+ -+ /* Monitoring Thresholds for Alarms and Warnings */ -+ sd->sfp_voltage[MCURR] = OFFSET_TO_U16(SFF8636_VCC_CURR); -+ sd->sfp_voltage[HALRM] = OFFSET_TO_U16(SFF8636_VCC_HALRM); -+ sd->sfp_voltage[LALRM] = OFFSET_TO_U16(SFF8636_VCC_LALRM); -+ sd->sfp_voltage[HWARN] = OFFSET_TO_U16(SFF8636_VCC_HWARN); -+ sd->sfp_voltage[LWARN] = OFFSET_TO_U16(SFF8636_VCC_LWARN); -+ -+ sd->sfp_temp[MCURR] = SFF8636_OFFSET_TO_TEMP(SFF8636_TEMP_CURR); -+ sd->sfp_temp[HALRM] = SFF8636_OFFSET_TO_TEMP(SFF8636_TEMP_HALRM); -+ sd->sfp_temp[LALRM] = SFF8636_OFFSET_TO_TEMP(SFF8636_TEMP_LALRM); -+ sd->sfp_temp[HWARN] = SFF8636_OFFSET_TO_TEMP(SFF8636_TEMP_HWARN); -+ sd->sfp_temp[LWARN] = SFF8636_OFFSET_TO_TEMP(SFF8636_TEMP_LWARN); -+ -+ sd->bias_cur[HALRM] = OFFSET_TO_U16(SFF8636_TX_BIAS_HALRM); -+ sd->bias_cur[LALRM] = OFFSET_TO_U16(SFF8636_TX_BIAS_LALRM); -+ sd->bias_cur[HWARN] = OFFSET_TO_U16(SFF8636_TX_BIAS_HWARN); -+ sd->bias_cur[LWARN] = OFFSET_TO_U16(SFF8636_TX_BIAS_LWARN); -+ -+ sd->tx_power[HALRM] = OFFSET_TO_U16(SFF8636_TX_PWR_HALRM); -+ sd->tx_power[LALRM] = OFFSET_TO_U16(SFF8636_TX_PWR_LALRM); -+ sd->tx_power[HWARN] = OFFSET_TO_U16(SFF8636_TX_PWR_HWARN); -+ sd->tx_power[LWARN] = OFFSET_TO_U16(SFF8636_TX_PWR_LWARN); -+ -+ sd->rx_power[HALRM] = OFFSET_TO_U16(SFF8636_RX_PWR_HALRM); -+ sd->rx_power[LALRM] = OFFSET_TO_U16(SFF8636_RX_PWR_LALRM); -+ sd->rx_power[HWARN] = OFFSET_TO_U16(SFF8636_RX_PWR_HWARN); -+ sd->rx_power[LWARN] = OFFSET_TO_U16(SFF8636_RX_PWR_LWARN); -+ -+ -+ /* Channel Specific Data */ -+ for (i = 0; i < MAX_CHANNEL_NUM; i++) { -+ u8 rx_power_offset, tx_bias_offset; -+ u8 tx_power_offset; -+ -+ switch (i) { -+ case 0: -+ rx_power_offset = SFF8636_RX_PWR_1_OFFSET; -+ tx_power_offset = SFF8636_TX_PWR_1_OFFSET; -+ tx_bias_offset = SFF8636_TX_BIAS_1_OFFSET; -+ break; -+ case 1: -+ rx_power_offset = SFF8636_RX_PWR_2_OFFSET; -+ tx_power_offset = SFF8636_TX_PWR_2_OFFSET; -+ tx_bias_offset = SFF8636_TX_BIAS_2_OFFSET; -+ break; -+ case 2: -+ rx_power_offset = SFF8636_RX_PWR_3_OFFSET; -+ tx_power_offset = SFF8636_TX_PWR_3_OFFSET; -+ tx_bias_offset = SFF8636_TX_BIAS_3_OFFSET; -+ break; -+ case 3: -+ rx_power_offset = SFF8636_RX_PWR_4_OFFSET; -+ tx_power_offset = SFF8636_TX_PWR_4_OFFSET; -+ tx_bias_offset = SFF8636_TX_BIAS_4_OFFSET; -+ break; -+ default: -+ printf(" Invalid channel: %d\n", i); -+ break; -+ } -+ sd->scd[i].bias_cur = OFFSET_TO_U16(tx_bias_offset); -+ 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, __u32 eeprom_len) -+{ -+ struct sff_diags sd; -+ char *rx_power_string = NULL; -+ char power_string[MAX_DESC_SIZE]; -+ int i; -+ -+ /* -+ * There is no clear identifier to signify the existence of -+ * optical diagnostics similar to SFF-8472. So checking existence -+ * of page 3, will provide the gurantee for existence of alarms -+ * and thresholds -+ * If pagging support exists, then supports_alarms is marked as 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 = 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, &sd); -+ -+ PRINT_TEMP("Module temperature", sd.sfp_temp[MCURR]); -+ PRINT_VCC("Module voltage", sd.sfp_voltage[MCURR]); -+ -+ /* -+ * SFF-8636/8436 spec is not clear whether RX power/ TX bias -+ * current fields are supported or not. A valid temperature -+ * reading is used as existence for TX/RX power. -+ */ -+ if ((sd.sfp_temp[MCURR] == 0x0) || (sd.sfp_temp[MCURR] == 0xFFFF)) -+ return; -+ -+ printf("\t%-41s : %s\n", "Alarm/warning flags implemented", -+ (sd.supports_alarms ? "Yes" : "No")); -+ -+ for (i = 0; i < 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++) { -+ 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); -+ } -+ -+ if (!sd.rx_power_type) -+ rx_power_string = "Receiver signal OMA"; -+ else -+ rx_power_string = "Rcvr signal avg optical power"; -+ -+ for (i = 0; i < 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); -+ } -+ -+ 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] -+ & sff8636_aw_flags[i].value ? "On" : "Off"); -+ } -+ -+ sff_show_thresholds(sd); -+ } -+ -+} -+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)) { -+ 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_VENDOR_NAME_END_OFFSET, "Vendor name"); -+ sff8636_show_oui(id); -+ sff_show_ascii(id, SFF8636_VENDOR_PN_START_OFFSET, -+ SFF8636_VENDOR_PN_END_OFFSET, "Vendor PN"); -+ sff_show_ascii(id, SFF8636_VENDOR_REV_START_OFFSET, -+ SFF8636_VENDOR_REV_END_OFFSET, "Vendor rev"); -+ sff_show_ascii(id, SFF8636_VENDOR_SN_START_OFFSET, -+ SFF8636_VENDOR_SN_END_OFFSET, "Vendor SN"); -+ sff8636_show_revision_compliance(id); -+ sff8636_show_dom(id, eeprom_len); -+ } -+} -diff --git a/qsfp.h b/qsfp.h -new file mode 100644 -index 0000000..553ca5f ---- /dev/null -+++ b/qsfp.h -@@ -0,0 +1,595 @@ -+/* -+ * SFF 8636 standards based QSFP EEPROM Field Definitions -+ * -+ * Vidya Ravipati -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ */ -+ -+#ifndef QSFP_H__ -+#define QSFP_H__ -+ -+/*------------------------------------------------------------------------------ -+ * -+ * QSFP EEPROM data structures -+ * -+ * register info from SFF-8636 Rev 2.7 -+ */ -+ -+/*------------------------------------------------------------------------------ -+ * -+ * Lower Memory Page 00h -+ * Measurement, Diagnostic and Control Functions -+ * -+ */ -+/* Identifier - 0 */ -+/* Values are defined under SFF8024_ID_OFFSET */ -+#define SFF8636_ID_OFFSET 0x00 -+ -+#define SFF8636_REV_COMPLIANCE_OFFSET 0x01 -+#define SFF8636_REV_UNSPECIFIED 0x00 -+#define SFF8636_REV_8436_48 0x01 -+#define SFF8636_REV_8436_8636 0x02 -+#define SFF8636_REV_8636_13 0x03 -+#define SFF8636_REV_8636_14 0x04 -+#define SFF8636_REV_8636_15 0x05 -+#define SFF8636_REV_8636_20 0x06 -+#define SFF8636_REV_8636_27 0x07 -+ -+#define SFF8636_STATUS_2_OFFSET 0x02 -+/* Flat Memory:0- Paging, 1- Page 0 only */ -+#define SFF8636_STATUS_PAGE_3_PRESENT (1 << 2) -+#define SFF8636_STATUS_INTL_OUTPUT (1 << 1) -+#define SFF8636_STATUS_DATA_NOT_READY (1 << 0) -+ -+/* Channel Status Interrupt Flags - 3-5 */ -+#define SFF8636_LOS_AW_OFFSET 0x03 -+#define SFF8636_TX4_LOS_AW (1 << 7) -+#define SFF8636_TX3_LOS_AW (1 << 6) -+#define SFF8636_TX2_LOS_AW (1 << 5) -+#define SFF8636_TX1_LOS_AW (1 << 4) -+#define SFF8636_RX4_LOS_AW (1 << 3) -+#define SFF8636_RX3_LOS_AW (1 << 2) -+#define SFF8636_RX2_LOS_AW (1 << 1) -+#define SFF8636_RX1_LOS_AW (1 << 0) -+ -+#define SFF8636_FAULT_AW_OFFSET 0x04 -+#define SFF8636_TX4_FAULT_AW (1 << 3) -+#define SFF8636_TX3_FAULT_AW (1 << 2) -+#define SFF8636_TX2_FAULT_AW (1 << 1) -+#define SFF8636_TX1_FAULT_AW (1 << 0) -+ -+/* Module Monitor Interrupt Flags - 6-8 */ -+#define SFF8636_TEMP_AW_OFFSET 0x06 -+#define SFF8636_TEMP_HALARM_STATUS (1 << 7) -+#define SFF8636_TEMP_LALARM_STATUS (1 << 6) -+#define SFF8636_TEMP_HWARN_STATUS (1 << 5) -+#define SFF8636_TEMP_LWARN_STATUS (1 << 4) -+ -+#define SFF8636_VCC_AW_OFFSET 0x07 -+#define SFF8636_VCC_HALARM_STATUS (1 << 7) -+#define SFF8636_VCC_LALARM_STATUS (1 << 6) -+#define SFF8636_VCC_HWARN_STATUS (1 << 5) -+#define SFF8636_VCC_LWARN_STATUS (1 << 4) -+ -+/* Channel Monitor Interrupt Flags - 9-21 */ -+#define SFF8636_RX_PWR_12_AW_OFFSET 0x09 -+#define SFF8636_RX_PWR_1_HALARM (1 << 7) -+#define SFF8636_RX_PWR_1_LALARM (1 << 6) -+#define SFF8636_RX_PWR_1_HWARN (1 << 5) -+#define SFF8636_RX_PWR_1_LWARN (1 << 4) -+#define SFF8636_RX_PWR_2_HALARM (1 << 3) -+#define SFF8636_RX_PWR_2_LALARM (1 << 2) -+#define SFF8636_RX_PWR_2_HWARN (1 << 1) -+#define SFF8636_RX_PWR_2_LWARN (1 << 0) -+ -+#define SFF8636_RX_PWR_34_AW_OFFSET 0x0A -+#define SFF8636_RX_PWR_3_HALARM (1 << 7) -+#define SFF8636_RX_PWR_3_LALARM (1 << 6) -+#define SFF8636_RX_PWR_3_HWARN (1 << 5) -+#define SFF8636_RX_PWR_3_LWARN (1 << 4) -+#define SFF8636_RX_PWR_4_HALARM (1 << 3) -+#define SFF8636_RX_PWR_4_LALARM (1 << 2) -+#define SFF8636_RX_PWR_4_HWARN (1 << 1) -+#define SFF8636_RX_PWR_4_LWARN (1 << 0) -+ -+#define SFF8636_TX_BIAS_12_AW_OFFSET 0x0B -+#define SFF8636_TX_BIAS_1_HALARM (1 << 7) -+#define SFF8636_TX_BIAS_1_LALARM (1 << 6) -+#define SFF8636_TX_BIAS_1_HWARN (1 << 5) -+#define SFF8636_TX_BIAS_1_LWARN (1 << 4) -+#define SFF8636_TX_BIAS_2_HALARM (1 << 3) -+#define SFF8636_TX_BIAS_2_LALARM (1 << 2) -+#define SFF8636_TX_BIAS_2_HWARN (1 << 1) -+#define SFF8636_TX_BIAS_2_LWARN (1 << 0) -+ -+#define SFF8636_TX_BIAS_34_AW_OFFSET 0xC -+#define SFF8636_TX_BIAS_3_HALARM (1 << 7) -+#define SFF8636_TX_BIAS_3_LALARM (1 << 6) -+#define SFF8636_TX_BIAS_3_HWARN (1 << 5) -+#define SFF8636_TX_BIAS_3_LWARN (1 << 4) -+#define SFF8636_TX_BIAS_4_HALARM (1 << 3) -+#define SFF8636_TX_BIAS_4_LALARM (1 << 2) -+#define SFF8636_TX_BIAS_4_HWARN (1 << 1) -+#define SFF8636_TX_BIAS_4_LWARN (1 << 0) -+ -+#define SFF8636_TX_PWR_12_AW_OFFSET 0x0D -+#define SFF8636_TX_PWR_1_HALARM (1 << 7) -+#define SFF8636_TX_PWR_1_LALARM (1 << 6) -+#define SFF8636_TX_PWR_1_HWARN (1 << 5) -+#define SFF8636_TX_PWR_1_LWARN (1 << 4) -+#define SFF8636_TX_PWR_2_HALARM (1 << 3) -+#define SFF8636_TX_PWR_2_LALARM (1 << 2) -+#define SFF8636_TX_PWR_2_HWARN (1 << 1) -+#define SFF8636_TX_PWR_2_LWARN (1 << 0) -+ -+#define SFF8636_TX_PWR_34_AW_OFFSET 0x0E -+#define SFF8636_TX_PWR_3_HALARM (1 << 7) -+#define SFF8636_TX_PWR_3_LALARM (1 << 6) -+#define SFF8636_TX_PWR_3_HWARN (1 << 5) -+#define SFF8636_TX_PWR_3_LWARN (1 << 4) -+#define SFF8636_TX_PWR_4_HALARM (1 << 3) -+#define SFF8636_TX_PWR_4_LALARM (1 << 2) -+#define SFF8636_TX_PWR_4_HWARN (1 << 1) -+#define SFF8636_TX_PWR_4_LWARN (1 << 0) -+ -+/* Module Monitoring Values - 22-33 */ -+#define SFF8636_TEMP_CURR 0x16 -+#define SFF8636_TEMP_MSB_OFFSET 0x16 -+#define SFF8636_TEMP_LSB_OFFSET 0x17 -+ -+#define SFF8636_VCC_CURR 0x1A -+#define SFF8636_VCC_MSB_OFFSET 0x1A -+#define SFF8636_VCC_LSB_OFFSET 0x1B -+ -+/* Channel Monitoring Values - 34-81 */ -+#define SFF8636_RX_PWR_1_OFFSET 0x22 -+#define SFF8636_RX_PWR_2_OFFSET 0x24 -+#define SFF8636_RX_PWR_3_OFFSET 0x26 -+#define SFF8636_RX_PWR_4_OFFSET 0x28 -+ -+#define SFF8636_TX_BIAS_1_OFFSET 0x2A -+#define SFF8636_TX_BIAS_2_OFFSET 0x2C -+#define SFF8636_TX_BIAS_3_OFFSET 0x2E -+#define SFF8636_TX_BIAS_4_OFFSET 0x30 -+ -+#define SFF8636_TX_PWR_1_OFFSET 0x32 -+#define SFF8636_TX_PWR_2_OFFSET 0x34 -+#define SFF8636_TX_PWR_3_OFFSET 0x36 -+#define SFF8636_TX_PWR_4_OFFSET 0x38 -+ -+/* Control Bytes - 86 - 99 */ -+#define SFF8636_TX_DISABLE_OFFSET 0x56 -+#define SFF8636_TX_DISABLE_4 (1 << 3) -+#define SFF8636_TX_DISABLE_3 (1 << 2) -+#define SFF8636_TX_DISABLE_2 (1 << 1) -+#define SFF8636_TX_DISABLE_1 (1 << 0) -+ -+#define SFF8636_RX_RATE_SELECT_OFFSET 0x57 -+#define SFF8636_RX_RATE_SELECT_4_MASK (3 << 6) -+#define SFF8636_RX_RATE_SELECT_3_MASK (3 << 4) -+#define SFF8636_RX_RATE_SELECT_2_MASK (3 << 2) -+#define SFF8636_RX_RATE_SELECT_1_MASK (3 << 0) -+ -+#define SFF8636_TX_RATE_SELECT_OFFSET 0x58 -+#define SFF8636_TX_RATE_SELECT_4_MASK (3 << 6) -+#define SFF8636_TX_RATE_SELECT_3_MASK (3 << 4) -+#define SFF8636_TX_RATE_SELECT_2_MASK (3 << 2) -+#define SFF8636_TX_RATE_SELECT_1_MASK (3 << 0) -+ -+#define SFF8636_RX_APP_SELECT_4_OFFSET 0x58 -+#define SFF8636_RX_APP_SELECT_3_OFFSET 0x59 -+#define SFF8636_RX_APP_SELECT_2_OFFSET 0x5A -+#define SFF8636_RX_APP_SELECT_1_OFFSET 0x5B -+ -+#define SFF8636_PWR_MODE_OFFSET 0x5D -+#define SFF8636_HIGH_PWR_ENABLE (1 << 2) -+#define SFF8636_LOW_PWR_MODE (1 << 1) -+#define SFF8636_PWR_OVERRIDE (1 << 0) -+ -+#define SFF8636_TX_APP_SELECT_4_OFFSET 0x5E -+#define SFF8636_TX_APP_SELECT_3_OFFSET 0x5F -+#define SFF8636_TX_APP_SELECT_2_OFFSET 0x60 -+#define SFF8636_TX_APP_SELECT_1_OFFSET 0x61 -+ -+#define SFF8636_LOS_MASK_OFFSET 0x64 -+#define SFF8636_TX_LOS_4_MASK (1 << 7) -+#define SFF8636_TX_LOS_3_MASK (1 << 6) -+#define SFF8636_TX_LOS_2_MASK (1 << 5) -+#define SFF8636_TX_LOS_1_MASK (1 << 4) -+#define SFF8636_RX_LOS_4_MASK (1 << 3) -+#define SFF8636_RX_LOS_3_MASK (1 << 2) -+#define SFF8636_RX_LOS_2_MASK (1 << 1) -+#define SFF8636_RX_LOS_1_MASK (1 << 0) -+ -+#define SFF8636_FAULT_MASK_OFFSET 0x65 -+#define SFF8636_TX_FAULT_1_MASK (1 << 3) -+#define SFF8636_TX_FAULT_2_MASK (1 << 2) -+#define SFF8636_TX_FAULT_3_MASK (1 << 1) -+#define SFF8636_TX_FAULT_4_MASK (1 << 0) -+ -+#define SFF8636_TEMP_MASK_OFFSET 0x67 -+#define SFF8636_TEMP_HALARM_MASK (1 << 7) -+#define SFF8636_TEMP_LALARM_MASK (1 << 6) -+#define SFF8636_TEMP_HWARN_MASK (1 << 5) -+#define SFF8636_TEMP_LWARN_MASK (1 << 4) -+ -+#define SFF8636_VCC_MASK_OFFSET 0x68 -+#define SFF8636_VCC_HALARM_MASK (1 << 7) -+#define SFF8636_VCC_LALARM_MASK (1 << 6) -+#define SFF8636_VCC_HWARN_MASK (1 << 5) -+#define SFF8636_VCC_LWARN_MASK (1 << 4) -+ -+/*------------------------------------------------------------------------------ -+ * -+ * Upper Memory Page 00h -+ * Serial ID - Base ID, Extended ID and Vendor Specific ID fields -+ * -+ */ -+/* Identifier - 128 */ -+/* Identifier values same as Lower Memory Page 00h */ -+#define SFF8636_UPPER_PAGE_0_ID_OFFSET 0x80 -+ -+/* Extended Identifier - 128 */ -+#define SFF8636_EXT_ID_OFFSET 0x81 -+#define SFF8636_EXT_ID_PWR_CLASS_MASK 0xC0 -+#define SFF8636_EXT_ID_PWR_CLASS_1 (0 << 6) -+#define SFF8636_EXT_ID_PWR_CLASS_2 (1 << 6) -+#define SFF8636_EXT_ID_PWR_CLASS_3 (2 << 6) -+#define SFF8636_EXT_ID_PWR_CLASS_4 (3 << 6) -+#define SFF8636_EXT_ID_CLIE_MASK 0x10 -+#define SFF8636_EXT_ID_CLIEI_CODE_PRESENT (1 << 4) -+#define SFF8636_EXT_ID_CDR_TX_MASK 0x08 -+#define SFF8636_EXT_ID_CDR_TX_PRESENT (1 << 3) -+#define SFF8636_EXT_ID_CDR_RX_MASK 0x04 -+#define SFF8636_EXT_ID_CDR_RX_PRESENT (1 << 2) -+#define SFF8636_EXT_ID_EPWR_CLASS_MASK 0x03 -+#define SFF8636_EXT_ID_PWR_CLASS_LEGACY 0 -+#define SFF8636_EXT_ID_PWR_CLASS_5 1 -+#define SFF8636_EXT_ID_PWR_CLASS_6 2 -+#define SFF8636_EXT_ID_PWR_CLASS_7 3 -+ -+/* Connector Values offset - 130 */ -+/* Values are defined under SFF8024_CTOR */ -+#define SFF8636_CTOR_OFFSET 0x82 -+#define SFF8636_CTOR_UNKNOWN 0x00 -+#define SFF8636_CTOR_SC 0x01 -+#define SFF8636_CTOR_FC_STYLE_1 0x02 -+#define SFF8636_CTOR_FC_STYLE_2 0x03 -+#define SFF8636_CTOR_BNC_TNC 0x04 -+#define SFF8636_CTOR_FC_COAX 0x05 -+#define SFF8636_CTOR_FIBER_JACK 0x06 -+#define SFF8636_CTOR_LC 0x07 -+#define SFF8636_CTOR_MT_RJ 0x08 -+#define SFF8636_CTOR_MU 0x09 -+#define SFF8636_CTOR_SG 0x0A -+#define SFF8636_CTOR_OPT_PT 0x0B -+#define SFF8636_CTOR_MPO 0x0C -+/* 0D-1Fh --- Reserved */ -+#define SFF8636_CTOR_HSDC_II 0x20 -+#define SFF8636_CTOR_COPPER_PT 0x21 -+#define SFF8636_CTOR_RJ45 0x22 -+#define SFF8636_CTOR_NO_SEPARABLE 0x23 -+#define SFF8636_CTOR_MXC_2X16 0x24 -+ -+/* Specification Compliance - 131-138 */ -+/* Ethernet Compliance Codes - 131 */ -+#define SFF8636_ETHERNET_COMP_OFFSET 0x83 -+#define SFF8636_ETHERNET_RSRVD (1 << 7) -+#define SFF8636_ETHERNET_10G_LRM (1 << 6) -+#define SFF8636_ETHERNET_10G_LR (1 << 5) -+#define SFF8636_ETHERNET_10G_SR (1 << 4) -+#define SFF8636_ETHERNET_40G_CR4 (1 << 3) -+#define SFF8636_ETHERNET_40G_SR4 (1 << 2) -+#define SFF8636_ETHERNET_40G_LR4 (1 << 1) -+#define SFF8636_ETHERNET_40G_ACTIVE (1 << 0) -+ -+/* SONET Compliance Codes - 132 */ -+#define SFF8636_SONET_COMP_OFFSET 0x84 -+#define SFF8636_SONET_40G_OTN (1 << 3) -+#define SFF8636_SONET_OC48_LR (1 << 2) -+#define SFF8636_SONET_OC48_IR (1 << 1) -+#define SFF8636_SONET_OC48_SR (1 << 0) -+ -+/* SAS/SATA Complaince Codes - 133 */ -+#define SFF8636_SAS_COMP_OFFSET 0x85 -+#define SFF8636_SAS_12G (1 << 6) -+#define SFF8636_SAS_6G (1 << 5) -+#define SFF8636_SAS_3G (1 << 4) -+ -+/* Gigabit Ethernet Compliance Codes - 134 */ -+#define SFF8636_GIGE_COMP_OFFSET 0x86 -+#define SFF8636_GIGE_1000_BASE_T (1 << 3) -+#define SFF8636_GIGE_1000_BASE_CX (1 << 2) -+#define SFF8636_GIGE_1000_BASE_LX (1 << 1) -+#define SFF8636_GIGE_1000_BASE_SX (1 << 0) -+ -+/* Fibre Channel Link length/Transmitter Tech. - 135,136 */ -+#define SFF8636_FC_LEN_OFFSET 0x87 -+#define SFF8636_FC_LEN_VERY_LONG (1 << 7) -+#define SFF8636_FC_LEN_SHORT (1 << 6) -+#define SFF8636_FC_LEN_INT (1 << 5) -+#define SFF8636_FC_LEN_LONG (1 << 4) -+#define SFF8636_FC_LEN_MED (1 << 3) -+#define SFF8636_FC_TECH_LONG_LC (1 << 1) -+#define SFF8636_FC_TECH_ELEC_INTER (1 << 0) -+ -+#define SFF8636_FC_TECH_OFFSET 0x88 -+#define SFF8636_FC_TECH_ELEC_INTRA (1 << 7) -+#define SFF8636_FC_TECH_SHORT_WO_OFC (1 << 6) -+#define SFF8636_FC_TECH_SHORT_W_OFC (1 << 5) -+#define SFF8636_FC_TECH_LONG_LL (1 << 4) -+ -+/* Fibre Channel Transmitter Media - 137 */ -+#define SFF8636_FC_TRANS_MEDIA_OFFSET 0x89 -+/* Twin Axial Pair */ -+#define SFF8636_FC_TRANS_MEDIA_TW (1 << 7) -+/* Shielded Twisted Pair */ -+#define SFF8636_FC_TRANS_MEDIA_TP (1 << 6) -+/* Miniature Coax */ -+#define SFF8636_FC_TRANS_MEDIA_MI (1 << 5) -+/* Video Coax */ -+#define SFF8636_FC_TRANS_MEDIA_TV (1 << 4) -+/* Multi-mode 62.5m */ -+#define SFF8636_FC_TRANS_MEDIA_M6 (1 << 3) -+/* Multi-mode 50m */ -+#define SFF8636_FC_TRANS_MEDIA_M5 (1 << 2) -+/* Multi-mode 50um */ -+#define SFF8636_FC_TRANS_MEDIA_OM3 (1 << 1) -+/* Single Mode */ -+#define SFF8636_FC_TRANS_MEDIA_SM (1 << 0) -+ -+/* Fibre Channel Speed - 138 */ -+#define SFF8636_FC_SPEED_OFFSET 0x8A -+#define SFF8636_FC_SPEED_1200_MBPS (1 << 7) -+#define SFF8636_FC_SPEED_800_MBPS (1 << 6) -+#define SFF8636_FC_SPEED_1600_MBPS (1 << 5) -+#define SFF8636_FC_SPEED_400_MBPS (1 << 4) -+#define SFF8636_FC_SPEED_200_MBPS (1 << 2) -+#define SFF8636_FC_SPEED_100_MBPS (1 << 0) -+ -+/* Encoding - 139 */ -+/* Values are defined under SFF8024_ENCODING */ -+#define SFF8636_ENCODING_OFFSET 0x8B -+#define SFF8636_ENCODING_MANCHESTER 0x06 -+#define SFF8636_ENCODING_64B66B 0x05 -+#define SFF8636_ENCODING_SONET 0x04 -+#define SFF8636_ENCODING_NRZ 0x03 -+#define SFF8636_ENCODING_4B5B 0x02 -+#define SFF8636_ENCODING_8B10B 0x01 -+#define SFF8636_ENCODING_UNSPEC 0x00 -+ -+/* BR, Nominal - 140 */ -+#define SFF8636_BR_NOMINAL_OFFSET 0x8C -+ -+/* Extended RateSelect - 141 */ -+#define SFF8636_EXT_RS_OFFSET 0x8D -+#define SFF8636_EXT_RS_V1 (1 << 0) -+ -+/* Length (Standard SM Fiber)-km - 142 */ -+#define SFF8636_SM_LEN_OFFSET 0x8E -+ -+/* Length (OM3)-Unit 2m - 143 */ -+#define SFF8636_OM3_LEN_OFFSET 0x8F -+ -+/* Length (OM2)-Unit 1m - 144 */ -+#define SFF8636_OM2_LEN_OFFSET 0x90 -+ -+/* Length (OM1)-Unit 1m - 145 */ -+#define SFF8636_OM1_LEN_OFFSET 0x91 -+ -+/* Cable Assembly Length -Unit 1m - 146 */ -+#define SFF8636_CBL_LEN_OFFSET 0x92 -+ -+/* Device Technology - 147 */ -+#define SFF8636_DEVICE_TECH_OFFSET 0x93 -+/* Transmitter Technology */ -+#define SFF8636_TRANS_TECH_MASK 0xF0 -+/* Copper cable, linear active equalizers */ -+#define SFF8636_TRANS_COPPER_LNR_EQUAL (15 << 4) -+/* Copper cable, near end limiting active equalizers */ -+#define SFF8636_TRANS_COPPER_NEAR_EQUAL (14 << 4) -+/* Copper cable, far end limiting active equalizers */ -+#define SFF8636_TRANS_COPPER_FAR_EQUAL (13 << 4) -+/* Copper cable, near & far end limiting active equalizers */ -+#define SFF8636_TRANS_COPPER_LNR_FAR_EQUAL (12 << 4) -+/* Copper cable, passive equalized */ -+#define SFF8636_TRANS_COPPER_PAS_EQUAL (11 << 4) -+/* Copper cable, unequalized */ -+#define SFF8636_TRANS_COPPER_PAS_UNEQUAL (10 << 4) -+/* 1490 nm DFB */ -+#define SFF8636_TRANS_1490_DFB (9 << 4) -+/* Others */ -+#define SFF8636_TRANS_OTHERS (8 << 4) -+/* 1550 nm EML */ -+#define SFF8636_TRANS_1550_EML (7 << 4) -+/* 1310 nm EML */ -+#define SFF8636_TRANS_1310_EML (6 << 4) -+/* 1550 nm DFB */ -+#define SFF8636_TRANS_1550_DFB (5 << 4) -+/* 1310 nm DFB */ -+#define SFF8636_TRANS_1310_DFB (4 << 4) -+/* 1310 nm FP */ -+#define SFF8636_TRANS_1310_FP (3 << 4) -+/* 1550 nm VCSEL */ -+#define SFF8636_TRANS_1550_VCSEL (2 << 4) -+/* 1310 nm VCSEL */ -+#define SFF8636_TRANS_1310_VCSEL (1 << 4) -+/* 850 nm VCSEL */ -+#define SFF8636_TRANS_850_VCSEL (0 << 4) -+ -+ /* Active/No wavelength control */ -+#define SFF8636_DEV_TECH_ACTIVE_WAVE_LEN (1 << 3) -+/* Cooled transmitter */ -+#define SFF8636_DEV_TECH_COOL_TRANS (1 << 2) -+/* APD/Pin Detector */ -+#define SFF8636_DEV_TECH_APD_DETECTOR (1 << 1) -+/* Transmitter tunable */ -+#define SFF8636_DEV_TECH_TUNABLE (1 << 0) -+ -+/* Vendor Name - 148-163 */ -+#define SFF8636_VENDOR_NAME_START_OFFSET 0x94 -+#define SFF8636_VENDOR_NAME_END_OFFSET 0xA3 -+ -+/* Extended Module Codes - 164 */ -+#define SFF8636_EXT_MOD_CODE_OFFSET 0xA4 -+#define SFF8636_EXT_MOD_INFINIBAND_EDR (1 << 4) -+#define SFF8636_EXT_MOD_INFINIBAND_FDR (1 << 3) -+#define SFF8636_EXT_MOD_INFINIBAND_QDR (1 << 2) -+#define SFF8636_EXT_MOD_INFINIBAND_DDR (1 << 1) -+#define SFF8636_EXT_MOD_INFINIBAND_SDR (1 << 0) -+ -+/* Vendor OUI - 165-167 */ -+#define SFF8636_VENDOR_OUI_OFFSET 0xA5 -+#define SFF8636_VENDOR_OUI_LEN 3 -+ -+/* Vendor OUI - 165-167 */ -+#define SFF8636_VENDOR_PN_START_OFFSET 0xA8 -+#define SFF8636_VENDOR_PN_END_OFFSET 0xB7 -+ -+/* Vendor Revision - 184-185 */ -+#define SFF8636_VENDOR_REV_START_OFFSET 0xB8 -+#define SFF8636_VENDOR_REV_END_OFFSET 0xB9 -+ -+/* Wavelength - 186-187 */ -+#define SFF8636_WAVELEN_HIGH_BYTE_OFFSET 0xBA -+#define SFF8636_WAVELEN_LOW_BYTE_OFFSET 0xBB -+ -+/* Wavelength Tolerance- 188-189 */ -+#define SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET 0xBC -+#define SFF8636_WAVE_TOL_LOW_BYTE_OFFSET 0xBD -+ -+/* Max case temp - Other than 70 C - 190 */ -+#define SFF8636_MAXCASE_TEMP_OFFSET 0xBE -+ -+/* CC_BASE - 191 */ -+#define SFF8636_CC_BASE_OFFSET 0xBF -+ -+/* Option Values - 192-195 */ -+#define SFF8636_OPTION_1_OFFSET 0xC0 -+#define SFF8636_ETHERNET_UNSPECIFIED 0x00 -+#define SFF8636_ETHERNET_100G_AOC 0x01 -+#define SFF8636_ETHERNET_100G_SR4 0x02 -+#define SFF8636_ETHERNET_100G_LR4 0x03 -+#define SFF8636_ETHERNET_100G_ER4 0x04 -+#define SFF8636_ETHERNET_100G_SR10 0x05 -+#define SFF8636_ETHERNET_100G_CWDM4_FEC 0x06 -+#define SFF8636_ETHERNET_100G_PSM4 0x07 -+#define SFF8636_ETHERNET_100G_ACC 0x08 -+#define SFF8636_ETHERNET_100G_CWDM4_NO_FEC 0x09 -+#define SFF8636_ETHERNET_100G_RSVD1 0x0A -+#define SFF8636_ETHERNET_100G_CR4 0x0B -+#define SFF8636_ETHERNET_25G_CR_CA_S 0x0C -+#define SFF8636_ETHERNET_25G_CR_CA_N 0x0D -+#define SFF8636_ETHERNET_40G_ER4 0x10 -+#define SFF8636_ETHERNET_4X10_SR 0x11 -+#define SFF8636_ETHERNET_40G_PSM4 0x12 -+#define SFF8636_ETHERNET_G959_P1I1_2D1 0x13 -+#define SFF8636_ETHERNET_G959_P1S1_2D2 0x14 -+#define SFF8636_ETHERNET_G959_P1L1_2D2 0x15 -+#define SFF8636_ETHERNET_10GT_SFI 0x16 -+#define SFF8636_ETHERNET_100G_CLR4 0x17 -+#define SFF8636_ETHERNET_100G_AOC2 0x18 -+#define SFF8636_ETHERNET_100G_ACC2 0x19 -+ -+#define SFF8636_OPTION_2_OFFSET 0xC1 -+/* Rx output amplitude */ -+#define SFF8636_O2_RX_OUTPUT_AMP (1 << 0) -+#define SFF8636_OPTION_3_OFFSET 0xC2 -+/* Rx Squelch Disable */ -+#define SFF8636_O3_RX_SQL_DSBL (1 << 3) -+/* Rx Output Disable capable */ -+#define SFF8636_O3_RX_OUTPUT_DSBL (1 << 2) -+/* Tx Squelch Disable */ -+#define SFF8636_O3_TX_SQL_DSBL (1 << 1) -+/* Tx Squelch Impl */ -+#define SFF8636_O3_TX_SQL_IMPL (1 << 0) -+#define SFF8636_OPTION_4_OFFSET 0xC3 -+/* Memory Page 02 present */ -+#define SFF8636_O4_PAGE_02_PRESENT (1 << 7) -+/* Memory Page 01 present */ -+#define SFF8636_O4_PAGE_01_PRESENT (1 << 6) -+/* Rate Select implemented */ -+#define SFF8636_O4_RATE_SELECT (1 << 5) -+/* Tx_DISABLE implemented */ -+#define SFF8636_O4_TX_DISABLE (1 << 4) -+/* Tx_FAULT implemented */ -+#define SFF8636_O4_TX_FAULT (1 << 3) -+/* Tx Squelch implemented */ -+#define SFF8636_O4_TX_SQUELCH (1 << 2) -+/* Tx Loss of Signal */ -+#define SFF8636_O4_TX_LOS (1 << 1) -+ -+/* Vendor SN - 196-211 */ -+#define SFF8636_VENDOR_SN_START_OFFSET 0xC4 -+#define SFF8636_VENDOR_SN_END_OFFSET 0xD3 -+ -+/* Vendor Date - 212-219 */ -+#define SFF8636_DATE_YEAR_OFFSET 0xD4 -+#define SFF8636_DATE_YEAR_LEN 2 -+#define SFF8636_DATE_MONTH_OFFSET 0xD6 -+#define SFF8636_DATE_MONTH_LEN 2 -+#define SFF8636_DATE_DAY_OFFSET 0xD8 -+#define SFF8636_DATE_DAY_LEN 2 -+ -+/* Diagnostic Monitoring Type - 220 */ -+#define SFF8636_DIAG_TYPE_OFFSET 0xDC -+#define SFF8636_RX_PWR_TYPE_MASK 0x8 -+#define SFF8636_RX_PWR_TYPE_AVG_PWR (1 << 3) -+#define SFF8636_RX_PWR_TYPE_OMA (0 << 3) -+#define SFF8636_TX_PWR_TYPE_MASK 0x4 -+#define SFF8636_TX_PWR_TYPE_AVG_PWR (1 << 2) -+ -+/* Enhanced Options - 221 */ -+#define SFF8636_ENH_OPTIONS_OFFSET 0xDD -+#define SFF8636_RATE_SELECT_EXT_SUPPORT (1 << 3) -+#define SFF8636_RATE_SELECT_APP_TABLE_SUPPORT (1 << 2) -+ -+/* Check code - 223 */ -+#define SFF8636_CC_EXT_OFFSET 0xDF -+#define SFF8636_CC_EXT_LEN 1 -+ -+/*------------------------------------------------------------------------------ -+ * -+ * Upper Memory Page 03h -+ * Contains module thresholds, channel thresholds and masks, -+ * and optional channel controls -+ * -+ * Offset - Page Num(3) * PageSize(0x80) + Page offset -+ */ -+ -+/* Module Thresholds (48 Bytes) 128-175 */ -+/* MSB at low address, LSB at high address */ -+#define SFF8636_TEMP_HALRM 0x200 -+#define SFF8636_TEMP_LALRM 0x202 -+#define SFF8636_TEMP_HWARN 0x204 -+#define SFF8636_TEMP_LWARN 0x206 -+ -+#define SFF8636_VCC_HALRM 0x210 -+#define SFF8636_VCC_LALRM 0x212 -+#define SFF8636_VCC_HWARN 0x214 -+#define SFF8636_VCC_LWARN 0x216 -+ -+#define SFF8636_RX_PWR_HALRM 0x230 -+#define SFF8636_RX_PWR_LALRM 0x232 -+#define SFF8636_RX_PWR_HWARN 0x234 -+#define SFF8636_RX_PWR_LWARN 0x236 -+ -+#define SFF8636_TX_BIAS_HALRM 0x238 -+#define SFF8636_TX_BIAS_LALRM 0x23A -+#define SFF8636_TX_BIAS_HWARN 0x23C -+#define SFF8636_TX_BIAS_LWARN 0x23E -+ -+#define SFF8636_TX_PWR_HALRM 0x240 -+#define SFF8636_TX_PWR_LALRM 0x242 -+#define SFF8636_TX_PWR_HWARN 0x244 -+#define SFF8636_TX_PWR_LWARN 0x246 -+ -+#define ETH_MODULE_SFF_8636_MAX_LEN 640 -+#define ETH_MODULE_SFF_8436_MAX_LEN 640 -+ -+#endif /* QSFP_H__ */ --- -1.8.3.1 - diff --git a/SOURCES/0006-ethtool-Enhancing-link-mode-bits-to-support-25G-50G-.patch b/SOURCES/0006-ethtool-Enhancing-link-mode-bits-to-support-25G-50G-.patch deleted file mode 100644 index 9bd389a..0000000 --- a/SOURCES/0006-ethtool-Enhancing-link-mode-bits-to-support-25G-50G-.patch +++ /dev/null @@ -1,68 +0,0 @@ -From d1387987c21dbd4a41c1c5c3b6780b16545b19fc Mon Sep 17 00:00:00 2001 -From: Vidya Sagar Ravipati -Date: Tue, 23 Aug 2016 06:30:33 -0700 -Subject: [PATCH 6/7] ethtool: Enhancing link mode bits to support 25G/50G/100G - -Enhancing link mode bits to support 25G/50G/100G -for supported and advertised speed mode bits - -Signed-off-by: Vidya Sagar Ravipati -Acked-By: David Decotigny -Acked-By: David Decotigny -Signed-off-by: John W. Linville -(cherry picked from commit ac2f96d5f281a67ab8796badfa40f2da14033aba) ---- - ethtool.c | 30 ++++++++++++++++++++++++++++++ - 1 file changed, 30 insertions(+) - -diff --git a/ethtool.c b/ethtool.c -index ffb3573..3687ab0 100644 ---- a/ethtool.c -+++ b/ethtool.c -@@ -504,6 +504,16 @@ static void init_global_link_mode_masks(void) - ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT, - ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT, - ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT, -+ ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, -+ ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, -+ ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, -+ ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, -+ ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, -+ ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, -+ ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, -+ ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, -+ ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, -+ ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, - }; - static const enum ethtool_link_mode_bit_indices - additional_advertised_flags_bits[] = { -@@ -624,6 +634,26 @@ static void dump_link_caps(const char *prefix, const char *an_prefix, - "56000baseSR4/Full" }, - { 0, ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT, - "56000baseLR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, -+ "25000baseCR/Full" }, -+ { 0, ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, -+ "25000baseKR/Full" }, -+ { 0, ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, -+ "25000baseSR/Full" }, -+ { 0, ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, -+ "50000baseCR2/Full" }, -+ { 0, ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, -+ "50000baseKR2/Full" }, -+ { 0, ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, -+ "100000baseKR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, -+ "100000baseSR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, -+ "100000baseCR4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, -+ "100000baseLR4_ER4/Full" }, -+ { 0, ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, -+ "50000baseSR2/Full" }, - }; - int indent; - int did1, new_line_pend, i; --- -1.8.3.1 - diff --git a/SOURCES/0007-ethtool-Document-new-ethtool-advertise-speeds.patch b/SOURCES/0007-ethtool-Document-new-ethtool-advertise-speeds.patch deleted file mode 100644 index b98e4f3..0000000 --- a/SOURCES/0007-ethtool-Document-new-ethtool-advertise-speeds.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 17e87eace95b8742252707d6719124af6e0f60c0 Mon Sep 17 00:00:00 2001 -From: Yuval Mintz -Date: Mon, 22 Aug 2016 08:50:39 +0300 -Subject: [PATCH 7/7] ethtool: Document new ethtool advertise speeds - -Signed-off-by: Yuval Mintz -Signed-off-by: John W. Linville -(cherry picked from commit 215d157b130c0a4af9bd4122fb69bc9908a22bca) ---- - ethtool.8.in | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/ethtool.8.in b/ethtool.8.in -index 009711d..6eec78d 100644 ---- a/ethtool.8.in -+++ b/ethtool.8.in -@@ -580,10 +580,20 @@ lB l lB. - 0x80000 10000baseKR Full - 0x200000 20000baseMLD2 Full (not supported by IEEE standards) - 0x400000 20000baseKR2 Full (not supported by IEEE standards) -+0x80000000 25000baseCR Full -+0x100000000 25000baseKR Full -+0x200000000 25000baseSR Full - 0x800000 40000baseKR4 Full - 0x1000000 40000baseCR4 Full - 0x2000000 40000baseSR4 Full - 0x4000000 40000baseLR4 Full -+0x400000000 50000baseCR2 Full -+0x800000000 50000baseKR2 Full -+0x10000000000 50000baseSR2 Full -+0x1000000000 100000baseKR4 Full -+0x2000000000 100000baseSR4 Full -+0x4000000000 100000baseCR4 Full -+0x8000000000 100000baseLR4_ER4 Full - .TE - .TP - .BI phyad \ N --- -1.8.3.1 - diff --git a/SPECS/ethtool.spec b/SPECS/ethtool.spec index 31d5a78..3373cfd 100644 --- a/SPECS/ethtool.spec +++ b/SPECS/ethtool.spec @@ -1,7 +1,7 @@ Name: ethtool Epoch: 2 -Version: 4.5 -Release: 3%{?dist} +Version: 4.8 +Release: 1%{?dist} Summary: Settings tool for Ethernet NICs License: GPLv2 @@ -21,13 +21,9 @@ URL: http://ftp.kernel.org/pub/software/network/%{name}/ Source0: http://ftp.kernel.org/pub/software/network/%{name}/%{name}-%{version}.tar.xz BuildRequires: automake, autoconf Conflicts: filesystem < 3 -Patch0: 0001-ethtool.c-fix-memory-leaks.patch -Patch1: 0002-ethtool.c-add-support-for-ETHTOOL_xLINKSETTINGS-ioctl.patch -Patch2: 0003-ethtool-copy.h-sync-with-net.patch -Patch3: 0004-ethtool-Reorganizing-SFF-8024-fields-for-SFP-QSFP.patch -Patch4: 0005-ethtool-QSFP-Plus-QSFP28-Diagnostics-Information-Sup.patch -Patch5: 0006-ethtool-Enhancing-link-mode-bits-to-support-25G-50G-.patch -Patch6: 0007-ethtool-Document-new-ethtool-advertise-speeds.patch +Patch0: 0001-ethtool-add-register-dump-support-for-fjes-driver.patch +Patch1: 0002-ethtool-sync-help-output-for-x-X-with-man-page.patch +Patch2: 0003-ethtool-Fix-the-advertise-parameter-logic.patch %description This utility allows querying and changing settings such as speed, @@ -39,10 +35,6 @@ network devices, especially of Ethernet devices. %patch0 -p1 %patch1 -p1 %patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 -%patch6 -p1 # Only needed when using upstream git # aclocal @@ -65,6 +57,18 @@ make DESTDIR=%{buildroot} INSTALL='install -p' install %{_mandir}/man8/%{name}.8* %changelog +* Wed Mar 22 2017 Ivan Vecera - 2:4.8-1 +- Rebased against upstream v4.8 + +* Fri Mar 17 2017 Ivan Vecera - 2:4.5-6 +- Fixed the "advertise" parameter logic + +* Tue Feb 21 2017 Ivan Vecera - 2:4.5-5 +- Fixed help page for commands -x and -X + +* Thu Feb 2 2017 Ivan Vecera - 2:4.5-4 +- Add register dump support for fjes driver + * Tue Aug 16 2016 Ivan Vecera - 2:4.5-3 - Added support for new ETHTOOL_xLINKSETTINGS API - Added support for diagnostics information for QSFP Plus/QSFP28 modules