Blame SOURCES/0014-ethtool-Support-for-FEC-encoding-control.patch

4cc9fb
From 6477a1f47b15c2a81a9995397942a0fc17f0b06f Mon Sep 17 00:00:00 2001
4cc9fb
From: Dustin Byford <dustin@cumulusnetworks.com>
4cc9fb
Date: Mon, 18 Dec 2017 14:57:41 -0800
4cc9fb
Subject: [PATCH 14/14] ethtool: Support for FEC encoding control
4cc9fb
4cc9fb
As FEC settings and different FEC modes are mandatory
4cc9fb
and configurable across various interfaces of 25G/50G/100G/40G,
4cc9fb
the lack of FEC encoding control and reporting today is a source
4cc9fb
for interoperability issues for many vendors
4cc9fb
4cc9fb
set-fec/show-fec option(s) are designed to provide control and report
4cc9fb
the FEC encoding on the link.
4cc9fb
4cc9fb
$ethtool --set-fec swp1 encoding [off | RS | BaseR | auto]
4cc9fb
4cc9fb
Encoding: Types of encoding
4cc9fb
Off    :  Turning off FEC
4cc9fb
RS     :  Force RS-FEC encoding
4cc9fb
BaseR  :  Force BaseR encoding
4cc9fb
Auto   :  Default FEC settings for drivers, and would represent
4cc9fb
          asking the hardware to essentially go into a best effort mode.
4cc9fb
4cc9fb
Here are a few examples of what we would expect if encoding=auto:
4cc9fb
- if autoneg is on, we are  expecting FEC to be negotiated as on or off
4cc9fb
  as long as protocol supports it
4cc9fb
- if the hardware is capable of detecting the FEC encoding on it's
4cc9fb
  receiver it will reconfigure its encoder to match
4cc9fb
- in absence of the above, the configuration would be set to IEEE
4cc9fb
  defaults.
4cc9fb
4cc9fb
>From our understanding, this is essentially what most hardware/driver
4cc9fb
combinations are doing today in the absence of a way for users to
4cc9fb
control the behavior.
4cc9fb
4cc9fb
$ethtool --show-fec  swp1
4cc9fb
FEC parameters for swp1:
4cc9fb
FEC encodings:  RS
4cc9fb
4cc9fb
ethtool devname output:
4cc9fb
$ethtool swp1
4cc9fb
Settings for swp1:
4cc9fb
root@hpe-7712-03:~# ethtool swp18
4cc9fb
Settings for swp18:
4cc9fb
    Supported ports: [ FIBRE ]
4cc9fb
    Supported link modes:   40000baseCR4/Full
4cc9fb
                            40000baseSR4/Full
4cc9fb
                            40000baseLR4/Full
4cc9fb
                            100000baseSR4/Full
4cc9fb
                            100000baseCR4/Full
4cc9fb
                            100000baseLR4_ER4/Full
4cc9fb
    Supported pause frame use: No
4cc9fb
    Supports auto-negotiation: Yes
4cc9fb
    Supported FEC modes: [RS | BaseR | None | Not reported]
4cc9fb
    Advertised link modes:  Not reported
4cc9fb
    Advertised pause frame use: No
4cc9fb
    Advertised auto-negotiation: No
4cc9fb
    Advertised FEC modes: [RS | BaseR | None | Not reported]
4cc9fb
    Speed: 100000Mb/s
4cc9fb
    Duplex: Full
4cc9fb
    Port: FIBRE
4cc9fb
    PHYAD: 106
4cc9fb
    Transceiver: internal
4cc9fb
    Auto-negotiation: off
4cc9fb
    Link detected: yes
4cc9fb
4cc9fb
Signed-off-by: Vidya Sagar Ravipati <vidya.chowdary@gmail.com>
4cc9fb
Signed-off-by: Dustin Byford <dustin@cumulusnetworks.com>
4cc9fb
[code style + man page edits + commit message update]
4cc9fb
Signed-off-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
4cc9fb
Signed-off-by: John W. Linville <linville@tuxdriver.com>
4cc9fb
4cc9fb
(cherry picked from commit 8db75d1e4001ac4cdfc73d5bedd0ec6d58a3d617)
4cc9fb
4cc9fb
Conflicts:
4cc9fb
	ethtool.8.in
4cc9fb
	ethtool.c
4cc9fb
---
4cc9fb
 ethtool.8.in |  31 ++++++++++++++++
4cc9fb
 ethtool.c    | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4cc9fb
 2 files changed, 150 insertions(+)
4cc9fb
4cc9fb
diff --git a/ethtool.8.in b/ethtool.8.in
4cc9fb
index c176cac..6816020 100644
4cc9fb
--- a/ethtool.8.in
4cc9fb
+++ b/ethtool.8.in
4cc9fb
@@ -342,6 +342,13 @@ ethtool \- query or control network driver and hardware settings
4cc9fb
 .B2 tx-lpi on off
4cc9fb
 .BN tx-timer
4cc9fb
 .BN advertise
4cc9fb
+.HP
4cc9fb
+.B ethtool \-\-show\-fec
4cc9fb
+.I devname
4cc9fb
+.HP
4cc9fb
+.B ethtool \-\-set\-fec
4cc9fb
+.I devname
4cc9fb
+.B4 encoding auto off rs baser
4cc9fb
 .
4cc9fb
 .\" Adjust lines (i.e. full justification) and hyphenate.
4cc9fb
 .ad
4cc9fb
@@ -959,6 +966,30 @@ Values are as for
4cc9fb
 Sets the amount of time the device should stay in idle mode prior to asserting
4cc9fb
 its Tx LPI (in microseconds). This has meaning only when Tx LPI is enabled.
4cc9fb
 .RE
4cc9fb
+.TP
4cc9fb
+.B \-\-show\-fec
4cc9fb
+Queries the specified network device for its support of Forward Error Correction.
4cc9fb
+.TP
4cc9fb
+.B \-\-set\-fec
4cc9fb
+Configures Forward Error Correction for the specified network device.
4cc9fb
+
4cc9fb
+Forward Error Correction modes selected by a user are expected to be persisted
4cc9fb
+after any hotplug events. If a module is swapped that does not support the
4cc9fb
+current FEC mode, the driver or firmware must take the link down
4cc9fb
+administratively and report the problem in the system logs for users to correct.
4cc9fb
+.RS 4
4cc9fb
+.TP
4cc9fb
+.A4 encoding auto off rs baser
4cc9fb
+Sets the FEC encoding for the device.
4cc9fb
+.TS
4cc9fb
+nokeep;
4cc9fb
+lB	l.
4cc9fb
+auto	Use the driver's default encoding
4cc9fb
+off	Turn off FEC
4cc9fb
+RS	Force RS-FEC encoding
4cc9fb
+BaseR	Force BaseR encoding
4cc9fb
+.TE
4cc9fb
+.RE
4cc9fb
 .SH BUGS
4cc9fb
 Not supported (in part or whole) on all network drivers.
4cc9fb
 .SH AUTHOR
4cc9fb
diff --git a/ethtool.c b/ethtool.c
4cc9fb
index 1411d62..2e9ee2c 100644
4cc9fb
--- a/ethtool.c
4cc9fb
+++ b/ethtool.c
4cc9fb
@@ -543,6 +543,9 @@ static void init_global_link_mode_masks(void)
4cc9fb
 		ETHTOOL_LINK_MODE_Pause_BIT,
4cc9fb
 		ETHTOOL_LINK_MODE_Asym_Pause_BIT,
4cc9fb
 		ETHTOOL_LINK_MODE_Backplane_BIT,
4cc9fb
+		ETHTOOL_LINK_MODE_FEC_NONE_BIT,
4cc9fb
+		ETHTOOL_LINK_MODE_FEC_RS_BIT,
4cc9fb
+		ETHTOOL_LINK_MODE_FEC_BASER_BIT,
4cc9fb
 	};
4cc9fb
 	unsigned int i;
4cc9fb
 
4cc9fb
@@ -690,6 +693,7 @@ static void dump_link_caps(const char *prefix, const char *an_prefix,
4cc9fb
 	};
4cc9fb
 	int indent;
4cc9fb
 	int did1, new_line_pend, i;
4cc9fb
+	int fecreported = 0;
4cc9fb
 
4cc9fb
 	/* Indent just like the separate functions used to */
4cc9fb
 	indent = strlen(prefix) + 14;
4cc9fb
@@ -741,6 +745,26 @@ static void dump_link_caps(const char *prefix, const char *an_prefix,
4cc9fb
 			fprintf(stdout, "Yes\n");
4cc9fb
 		else
4cc9fb
 			fprintf(stdout, "No\n");
4cc9fb
+
4cc9fb
+		fprintf(stdout, "	%s FEC modes:", prefix);
4cc9fb
+		if (ethtool_link_mode_test_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT,
4cc9fb
+					       mask)) {
4cc9fb
+			fprintf(stdout, " None");
4cc9fb
+			fecreported = 1;
4cc9fb
+		}
4cc9fb
+		if (ethtool_link_mode_test_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT,
4cc9fb
+					       mask)) {
4cc9fb
+			fprintf(stdout, " BaseR");
4cc9fb
+			fecreported = 1;
4cc9fb
+		}
4cc9fb
+		if (ethtool_link_mode_test_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT,
4cc9fb
+					       mask)) {
4cc9fb
+			fprintf(stdout, " RS");
4cc9fb
+			fecreported = 1;
4cc9fb
+		}
4cc9fb
+		if (!fecreported)
4cc9fb
+			fprintf(stdout, " Not reported");
4cc9fb
+		fprintf(stdout, "\n");
4cc9fb
 	}
4cc9fb
 }
4cc9fb
 
4cc9fb
@@ -1569,6 +1593,20 @@ static void dump_eeecmd(struct ethtool_eee *ep)
4cc9fb
 	dump_link_caps("Link partner advertised EEE", "", link_mode, 1);
4cc9fb
 }
4cc9fb
 
4cc9fb
+static void dump_fec(u32 fec)
4cc9fb
+{
4cc9fb
+	if (fec & ETHTOOL_FEC_NONE)
4cc9fb
+		fprintf(stdout, " None");
4cc9fb
+	if (fec & ETHTOOL_FEC_AUTO)
4cc9fb
+		fprintf(stdout, " Auto");
4cc9fb
+	if (fec & ETHTOOL_FEC_OFF)
4cc9fb
+		fprintf(stdout, " Off");
4cc9fb
+	if (fec & ETHTOOL_FEC_BASER)
4cc9fb
+		fprintf(stdout, " BaseR");
4cc9fb
+	if (fec & ETHTOOL_FEC_RS)
4cc9fb
+		fprintf(stdout, " RS");
4cc9fb
+}
4cc9fb
+
4cc9fb
 #define N_SOTS 7
4cc9fb
 
4cc9fb
 static char *so_timestamping_labels[N_SOTS] = {
4cc9fb
@@ -4592,6 +4630,84 @@ static int do_seee(struct cmd_context *ctx)
4cc9fb
 	return 0;
4cc9fb
 }
4cc9fb
 
4cc9fb
+static int fecmode_str_to_type(const char *str)
4cc9fb
+{
4cc9fb
+	int fecmode = 0;
4cc9fb
+
4cc9fb
+	if (!str)
4cc9fb
+		return fecmode;
4cc9fb
+
4cc9fb
+	if (!strcasecmp(str, "auto"))
4cc9fb
+		fecmode |= ETHTOOL_FEC_AUTO;
4cc9fb
+	else if (!strcasecmp(str, "off"))
4cc9fb
+		fecmode |= ETHTOOL_FEC_OFF;
4cc9fb
+	else if (!strcasecmp(str, "rs"))
4cc9fb
+		fecmode |= ETHTOOL_FEC_RS;
4cc9fb
+	else if (!strcasecmp(str, "baser"))
4cc9fb
+		fecmode |= ETHTOOL_FEC_BASER;
4cc9fb
+
4cc9fb
+	return fecmode;
4cc9fb
+}
4cc9fb
+
4cc9fb
+static int do_gfec(struct cmd_context *ctx)
4cc9fb
+{
4cc9fb
+	struct ethtool_fecparam feccmd = { 0 };
4cc9fb
+	int rv;
4cc9fb
+
4cc9fb
+	if (ctx->argc != 0)
4cc9fb
+		exit_bad_args();
4cc9fb
+
4cc9fb
+	feccmd.cmd = ETHTOOL_GFECPARAM;
4cc9fb
+	rv = send_ioctl(ctx, &feccmd);
4cc9fb
+	if (rv != 0) {
4cc9fb
+		perror("Cannot get FEC settings");
4cc9fb
+		return rv;
4cc9fb
+	}
4cc9fb
+
4cc9fb
+	fprintf(stdout, "FEC parameters for %s:\n", ctx->devname);
4cc9fb
+	fprintf(stdout, "Configured FEC encodings:");
4cc9fb
+	dump_fec(feccmd.fec);
4cc9fb
+	fprintf(stdout, "\n");
4cc9fb
+
4cc9fb
+	fprintf(stdout, "Active FEC encoding:");
4cc9fb
+	dump_fec(feccmd.active_fec);
4cc9fb
+	fprintf(stdout, "\n");
4cc9fb
+
4cc9fb
+	return 0;
4cc9fb
+}
4cc9fb
+
4cc9fb
+static int do_sfec(struct cmd_context *ctx)
4cc9fb
+{
4cc9fb
+	char *fecmode_str = NULL;
4cc9fb
+	struct ethtool_fecparam feccmd;
4cc9fb
+	struct cmdline_info cmdline_fec[] = {
4cc9fb
+		{ "encoding", CMDL_STR,  &fecmode_str,  &feccmd.fec},
4cc9fb
+	};
4cc9fb
+	int changed;
4cc9fb
+	int fecmode;
4cc9fb
+	int rv;
4cc9fb
+
4cc9fb
+	parse_generic_cmdline(ctx, &changed, cmdline_fec,
4cc9fb
+			      ARRAY_SIZE(cmdline_fec));
4cc9fb
+
4cc9fb
+	if (!fecmode_str)
4cc9fb
+		exit_bad_args();
4cc9fb
+
4cc9fb
+	fecmode = fecmode_str_to_type(fecmode_str);
4cc9fb
+	if (!fecmode)
4cc9fb
+		exit_bad_args();
4cc9fb
+
4cc9fb
+	feccmd.cmd = ETHTOOL_SFECPARAM;
4cc9fb
+	feccmd.fec = fecmode;
4cc9fb
+	rv = send_ioctl(ctx, &feccmd);
4cc9fb
+	if (rv != 0) {
4cc9fb
+		perror("Cannot set FEC settings");
4cc9fb
+		return rv;
4cc9fb
+	}
4cc9fb
+
4cc9fb
+	return 0;
4cc9fb
+}
4cc9fb
+
4cc9fb
 #ifndef TEST_ETHTOOL
4cc9fb
 int send_ioctl(struct cmd_context *ctx, void *cmd)
4cc9fb
 {
4cc9fb
@@ -4754,6 +4870,9 @@ static const struct option {
4cc9fb
 	  "		[ advertise %x ]\n"
4cc9fb
 	  "		[ tx-lpi on|off ]\n"
4cc9fb
 	  "		[ tx-timer %d ]\n"},
4cc9fb
+	{ "--show-fec", 1, do_gfec, "Show FEC settings"},
4cc9fb
+	{ "--set-fec", 1, do_sfec, "Set FEC settings",
4cc9fb
+	  "		[ encoding auto|off|rs|baser ]\n"},
4cc9fb
 	{ "-h|--help", 0, show_usage, "Show this help" },
4cc9fb
 	{ "--version", 0, do_version, "Show version number" },
4cc9fb
 	{}
4cc9fb
-- 
4cc9fb
1.8.3.1
4cc9fb