diff --git a/SOURCES/0001-netlink-Fix-the-condition-for-displaying-actual-chan.patch b/SOURCES/0001-netlink-Fix-the-condition-for-displaying-actual-chan.patch
new file mode 100644
index 0000000..f0fc6af
--- /dev/null
+++ b/SOURCES/0001-netlink-Fix-the-condition-for-displaying-actual-chan.patch
@@ -0,0 +1,46 @@
+From 89b49b2a88392c510c6a171940701ba4cf580116 Mon Sep 17 00:00:00 2001
+From: Maxim Mikityanskiy <maximmi@mellanox.com>
+Date: Fri, 14 Aug 2020 16:17:44 +0300
+Subject: [PATCH 01/17] netlink: Fix the condition for displaying actual
+ changes
+
+This comment in the code:
+
+    /* result is not exactly as requested, show differences */
+
+implies that the "Actual changes" output should be displayed only if the
+result is not as requested, which matches the legacy ethtool behavior.
+However, in fact, ethtool-netlink displays "actual changes" even when
+the changes are expected (e.g., one bit was requested, and it was
+changed as requested).
+
+This commit fixes the condition above to make the behavior match the
+description in the comment and the behavior of the legacy ethtool. The
+new condition excludes the req_mask bits from active_mask to avoid
+reacting on bit changes that we asked for. The new condition now
+matches the ifs in the loop above that print "[requested on/off]" and
+"[not requested]".
+
+Signed-off-by: Maxim Mikityanskiy <maximmi@mellanox.com>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 83d2b635de121a16a27663cc4e3045243e56063b)
+---
+ netlink/features.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/netlink/features.c b/netlink/features.c
+index 8b5b8588ca23..133529da2b9f 100644
+--- a/netlink/features.c
++++ b/netlink/features.c
+@@ -413,7 +413,7 @@ static void show_feature_changes(struct nl_context *nlctx,
+ 
+ 	diff = false;
+ 	for (i = 0; i < words; i++)
+-		if (wanted_mask[i] || active_mask[i])
++		if (wanted_mask[i] || (active_mask[i] & ~sfctx->req_mask[i]))
+ 			diff = true;
+ 	if (!diff)
+ 		return;
+-- 
+2.26.2
+
diff --git a/SOURCES/0002-netlink-Print-and-return-an-error-when-features-were.patch b/SOURCES/0002-netlink-Print-and-return-an-error-when-features-were.patch
new file mode 100644
index 0000000..8e9dd10
--- /dev/null
+++ b/SOURCES/0002-netlink-Print-and-return-an-error-when-features-were.patch
@@ -0,0 +1,61 @@
+From ad9e296622adf2cd775c93a94c4ba2756d07e0d5 Mon Sep 17 00:00:00 2001
+From: Maxim Mikityanskiy <maximmi@mellanox.com>
+Date: Tue, 25 Aug 2020 11:11:38 +0300
+Subject: [PATCH 02/17] netlink: Print and return an error when features
+ weren't changed
+
+The legacy ethtool prints an error message and returns 1 if no features
+were changed as requested. Port this behavior to ethtool-netlink.
+req_mask is compared to wanted_mask to detect if any feature was
+changed. If these masks are equal, it means that the kernel hasn't
+changed anything, and all bits got to wanted.
+
+Signed-off-by: Maxim Mikityanskiy <maximmi@mellanox.com>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit e06cf83352d5161399da49eae7296126cd5e4ea1)
+---
+ netlink/features.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/netlink/features.c b/netlink/features.c
+index 133529da2b9f..762259405acc 100644
+--- a/netlink/features.c
++++ b/netlink/features.c
+@@ -243,6 +243,7 @@ int nl_gfeatures(struct cmd_context *ctx)
+ /* FEATURES_SET */
+ 
+ struct sfeatures_context {
++	bool			nothing_changed;
+ 	uint32_t		req_mask[0];
+ };
+ 
+@@ -411,10 +412,14 @@ static void show_feature_changes(struct nl_context *nlctx,
+ 	if (!wanted_val || !wanted_mask || !active_val || !active_mask)
+ 		goto err;
+ 
++	sfctx->nothing_changed = true;
+ 	diff = false;
+-	for (i = 0; i < words; i++)
++	for (i = 0; i < words; i++) {
++		if (wanted_mask[i] != sfctx->req_mask[i])
++			sfctx->nothing_changed = false;
+ 		if (wanted_mask[i] || (active_mask[i] & ~sfctx->req_mask[i]))
+ 			diff = true;
++	}
+ 	if (!diff)
+ 		return;
+ 
+@@ -520,6 +525,10 @@ int nl_sfeatures(struct cmd_context *ctx)
+ 	if (ret < 0)
+ 		return 92;
+ 	ret = nlsock_process_reply(nlsk, sfeatures_reply_cb, nlctx);
++	if (sfctx->nothing_changed) {
++		fprintf(stderr, "Could not change any device features\n");
++		return nlctx->exit_code ?: 1;
++	}
+ 	if (ret == 0)
+ 		return 0;
+ 	return nlctx->exit_code ?: 92;
+-- 
+2.26.2
+
diff --git a/SOURCES/0003-netlink-get-rid-of-signed-unsigned-comparison-warnin.patch b/SOURCES/0003-netlink-get-rid-of-signed-unsigned-comparison-warnin.patch
new file mode 100644
index 0000000..cae78ed
--- /dev/null
+++ b/SOURCES/0003-netlink-get-rid-of-signed-unsigned-comparison-warnin.patch
@@ -0,0 +1,147 @@
+From aef2a21a2221c03e4e00fd06ea74002317fbfd5e Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Sun, 23 Aug 2020 21:40:18 +0200
+Subject: [PATCH 03/17] netlink: get rid of signed/unsigned comparison warnings
+
+Use unsigned types where appropriate to get rid of compiler warnings about
+comparison between signed and unsigned integer values in netlink code.
+
+v2: avoid casts in dump_features()
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+(cherry picked from commit b038eef080221b1f9df944c3d2307bad172cf318)
+---
+ netlink/features.c | 6 +++---
+ netlink/netlink.c  | 4 ++--
+ netlink/netlink.h  | 2 +-
+ netlink/nlsock.c   | 2 +-
+ netlink/parser.c   | 2 +-
+ netlink/settings.c | 6 +++---
+ 6 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/netlink/features.c b/netlink/features.c
+index 762259405acc..3f1240437350 100644
+--- a/netlink/features.c
++++ b/netlink/features.c
+@@ -109,9 +109,9 @@ static bool flag_pattern_match(const char *name, const char *pattern)
+ int dump_features(const struct nlattr *const *tb,
+ 		  const struct stringset *feature_names)
+ {
++	unsigned int *feature_flags = NULL;
+ 	struct feature_results results;
+ 	unsigned int i, j;
+-	int *feature_flags = NULL;
+ 	int ret;
+ 
+ 	ret = prepare_feature_results(tb, &results);
+@@ -126,7 +126,7 @@ int dump_features(const struct nlattr *const *tb,
+ 	/* map netdev features to legacy flags */
+ 	for (i = 0; i < results.count; i++) {
+ 		const char *name = get_string(feature_names, i);
+-		feature_flags[i] = -1;
++		feature_flags[i] = UINT_MAX;
+ 
+ 		if (!name || !*name)
+ 			continue;
+@@ -177,7 +177,7 @@ int dump_features(const struct nlattr *const *tb,
+ 	for (i = 0; i < results.count; i++) {
+ 		const char *name = get_string(feature_names, i);
+ 
+-		if (!name || !*name || feature_flags[i] >= 0)
++		if (!name || !*name || feature_flags[i] != UINT_MAX)
+ 			continue;
+ 		dump_feature(&results, NULL, NULL, i, name, "");
+ 	}
+diff --git a/netlink/netlink.c b/netlink/netlink.c
+index 76b6e825b1d0..e42d57076a4b 100644
+--- a/netlink/netlink.c
++++ b/netlink/netlink.c
+@@ -33,9 +33,9 @@ int nomsg_reply_cb(const struct nlmsghdr *nlhdr, void *data __maybe_unused)
+ int attr_cb(const struct nlattr *attr, void *data)
+ {
+ 	const struct attr_tb_info *tb_info = data;
+-	int type = mnl_attr_get_type(attr);
++	uint16_t type = mnl_attr_get_type(attr);
+ 
+-	if (type >= 0 && type <= tb_info->max_type)
++	if (type <= tb_info->max_type)
+ 		tb_info->tb[type] = attr;
+ 
+ 	return MNL_CB_OK;
+diff --git a/netlink/netlink.h b/netlink/netlink.h
+index a4984c82ae76..dd4a02bcc916 100644
+--- a/netlink/netlink.h
++++ b/netlink/netlink.h
+@@ -45,7 +45,7 @@ struct nl_context {
+ 	const char		*cmd;
+ 	const char		*param;
+ 	char			**argp;
+-	int			argc;
++	unsigned int		argc;
+ 	bool			ioctl_fallback;
+ 	bool			wildcard_unsupported;
+ };
+diff --git a/netlink/nlsock.c b/netlink/nlsock.c
+index c3f09b6ee9ab..ef31d8c33b29 100644
+--- a/netlink/nlsock.c
++++ b/netlink/nlsock.c
+@@ -168,7 +168,7 @@ static void debug_msg(struct nl_socket *nlsk, const void *msg, unsigned int len,
+  *
+  * Return: error code extracted from the message
+  */
+-static int nlsock_process_ack(struct nlmsghdr *nlhdr, ssize_t len,
++static int nlsock_process_ack(struct nlmsghdr *nlhdr, unsigned long len,
+ 			      unsigned int suppress_nlerr, bool pretty)
+ {
+ 	const struct nlattr *tb[NLMSGERR_ATTR_MAX + 1] = {};
+diff --git a/netlink/parser.c b/netlink/parser.c
+index 395bd5743af9..c5a368a65a7a 100644
+--- a/netlink/parser.c
++++ b/netlink/parser.c
+@@ -604,7 +604,7 @@ static int parse_numeric_bitset(struct nl_context *nlctx, uint16_t type,
+ 		parser_err_invalid_value(nlctx, arg);
+ 		return -EINVAL;
+ 	}
+-	len1 = maskptr ? (maskptr - arg) : strlen(arg);
++	len1 = maskptr ? (unsigned int)(maskptr - arg) : strlen(arg);
+ 	nwords = DIV_ROUND_UP(len1, 8);
+ 	nbits = 0;
+ 
+diff --git a/netlink/settings.c b/netlink/settings.c
+index 17ef000ed812..2b9c6e7a782c 100644
+--- a/netlink/settings.c
++++ b/netlink/settings.c
+@@ -276,10 +276,10 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset,
+ 	const struct nlattr *bitset_tb[ETHTOOL_A_BITSET_MAX + 1] = {};
+ 	DECLARE_ATTR_TB_INFO(bitset_tb);
+ 	const unsigned int before_len = strlen(before);
++	unsigned int prev = UINT_MAX - 1;
+ 	const struct nlattr *bits;
+ 	const struct nlattr *bit;
+ 	bool first = true;
+-	int prev = -2;
+ 	bool nomask;
+ 	int ret;
+ 
+@@ -333,7 +333,7 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset,
+ 			if (first)
+ 				first = false;
+ 			/* ugly hack to preserve old output format */
+-			if (class == LM_CLASS_REAL && (prev == idx - 1) &&
++			if (class == LM_CLASS_REAL && (idx == prev + 1) &&
+ 			    prev < link_modes_count &&
+ 			    link_modes[prev].class == LM_CLASS_REAL &&
+ 			    link_modes[prev].duplex == DUPLEX_HALF)
+@@ -375,7 +375,7 @@ int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset,
+ 			first = false;
+ 		} else {
+ 			/* ugly hack to preserve old output format */
+-			if ((class == LM_CLASS_REAL) && (prev == idx - 1) &&
++			if ((class == LM_CLASS_REAL) && (idx == prev + 1) &&
+ 			    (prev < link_modes_count) &&
+ 			    (link_modes[prev].class == LM_CLASS_REAL) &&
+ 			    (link_modes[prev].duplex == DUPLEX_HALF))
+-- 
+2.26.2
+
diff --git a/SOURCES/0004-ioctl-check-presence-of-eeprom-length-argument-prope.patch b/SOURCES/0004-ioctl-check-presence-of-eeprom-length-argument-prope.patch
new file mode 100644
index 0000000..f83e89c
--- /dev/null
+++ b/SOURCES/0004-ioctl-check-presence-of-eeprom-length-argument-prope.patch
@@ -0,0 +1,108 @@
+From ce297bec23dd0054600678b4297f6e73ecdc540d Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Sun, 23 Aug 2020 21:40:21 +0200
+Subject: [PATCH 04/17] ioctl: check presence of eeprom length argument
+ properly
+
+In do_geeprom(), do_seprom() and do_getmodule(), check if user used
+"length" command line argument is done by setting the value to -1 before
+parsing and checking if it changed. This is quite ugly and also causes
+compiler warnings as the variable is u32.
+
+Use proper "seen" flag to let parser tell us if the argument was used.
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+(cherry picked from commit 923c3f51c4442a5f25afb529bd49ec2ef4f185a3)
+---
+ ethtool.c | 24 +++++++++++++++---------
+ 1 file changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/ethtool.c b/ethtool.c
+index c4ad186cd390..4fa7a2c1716f 100644
+--- a/ethtool.c
++++ b/ethtool.c
+@@ -3184,10 +3184,12 @@ static int do_geeprom(struct cmd_context *ctx)
+ 	int geeprom_changed = 0;
+ 	int geeprom_dump_raw = 0;
+ 	u32 geeprom_offset = 0;
+-	u32 geeprom_length = -1;
++	u32 geeprom_length = 0;
++	int geeprom_length_seen = 0;
+ 	struct cmdline_info cmdline_geeprom[] = {
+ 		{ "offset", CMDL_U32, &geeprom_offset, NULL },
+-		{ "length", CMDL_U32, &geeprom_length, NULL },
++		{ "length", CMDL_U32, &geeprom_length, NULL,
++		  0, &geeprom_length_seen },
+ 		{ "raw", CMDL_BOOL, &geeprom_dump_raw, NULL },
+ 	};
+ 	int err;
+@@ -3204,7 +3206,7 @@ static int do_geeprom(struct cmd_context *ctx)
+ 		return 74;
+ 	}
+ 
+-	if (geeprom_length == -1)
++	if (!geeprom_length_seen)
+ 		geeprom_length = drvinfo.eedump_len;
+ 
+ 	if (drvinfo.eedump_len < geeprom_offset + geeprom_length)
+@@ -3234,14 +3236,16 @@ static int do_seeprom(struct cmd_context *ctx)
+ {
+ 	int seeprom_changed = 0;
+ 	u32 seeprom_magic = 0;
+-	u32 seeprom_length = -1;
++	u32 seeprom_length = 0;
+ 	u32 seeprom_offset = 0;
+ 	u8 seeprom_value = 0;
++	int seeprom_length_seen = 0;
+ 	int seeprom_value_seen = 0;
+ 	struct cmdline_info cmdline_seeprom[] = {
+ 		{ "magic", CMDL_U32, &seeprom_magic, NULL },
+ 		{ "offset", CMDL_U32, &seeprom_offset, NULL },
+-		{ "length", CMDL_U32, &seeprom_length, NULL },
++		{ "length", CMDL_U32, &seeprom_length, NULL,
++		  0, &seeprom_length_seen },
+ 		{ "value", CMDL_U8, &seeprom_value, NULL,
+ 		  0, &seeprom_value_seen },
+ 	};
+@@ -3262,7 +3266,7 @@ static int do_seeprom(struct cmd_context *ctx)
+ 	if (seeprom_value_seen)
+ 		seeprom_length = 1;
+ 
+-	if (seeprom_length == -1)
++	if (!seeprom_length_seen)
+ 		seeprom_length = drvinfo.eedump_len;
+ 
+ 	if (drvinfo.eedump_len < seeprom_offset + seeprom_length) {
+@@ -4538,15 +4542,17 @@ static int do_getmodule(struct cmd_context *ctx)
+ 	struct ethtool_modinfo modinfo;
+ 	struct ethtool_eeprom *eeprom;
+ 	u32 geeprom_offset = 0;
+-	u32 geeprom_length = -1;
++	u32 geeprom_length = 0;
+ 	int geeprom_changed = 0;
+ 	int geeprom_dump_raw = 0;
+ 	int geeprom_dump_hex = 0;
++	int geeprom_length_seen = 0;
+ 	int err;
+ 
+ 	struct cmdline_info cmdline_geeprom[] = {
+ 		{ "offset", CMDL_U32, &geeprom_offset, NULL },
+-		{ "length", CMDL_U32, &geeprom_length, NULL },
++		{ "length", CMDL_U32, &geeprom_length, NULL,
++		  0, &geeprom_length_seen },
+ 		{ "raw", CMDL_BOOL, &geeprom_dump_raw, NULL },
+ 		{ "hex", CMDL_BOOL, &geeprom_dump_hex, NULL },
+ 	};
+@@ -4566,7 +4572,7 @@ static int do_getmodule(struct cmd_context *ctx)
+ 		return 1;
+ 	}
+ 
+-	if (geeprom_length == -1)
++	if (!geeprom_length_seen)
+ 		geeprom_length = modinfo.eeprom_len;
+ 
+ 	if (modinfo.eeprom_len < geeprom_offset + geeprom_length)
+-- 
+2.26.2
+
diff --git a/SOURCES/0005-ioctl-prevent-argc-underflow-in-do_perqueue.patch b/SOURCES/0005-ioctl-prevent-argc-underflow-in-do_perqueue.patch
new file mode 100644
index 0000000..422f028
--- /dev/null
+++ b/SOURCES/0005-ioctl-prevent-argc-underflow-in-do_perqueue.patch
@@ -0,0 +1,33 @@
+From 04315b072d623ba9200612a4c5f5330f1eb28a27 Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Sun, 23 Aug 2020 21:40:24 +0200
+Subject: [PATCH 05/17] ioctl: prevent argc underflow in do_perqueue()
+
+When first command line argument after "-Q" is "queue_mask", we parse
+the queue mask and following subcommand without checking if these
+arguments do actually exist. Add check if we have at least two arguments
+left after "queue_mask" in the corresponding branch.
+
+Fixes: 9ecd54248b1a ("ethtool: introduce new ioctl for per-queue settings")
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 39c354e591b66cc29edaab89f90ed03a513ad88f)
+---
+ ethtool.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/ethtool.c b/ethtool.c
+index 4fa7a2c1716f..6c12452be7b4 100644
+--- a/ethtool.c
++++ b/ethtool.c
+@@ -5880,6 +5880,8 @@ static int do_perqueue(struct cmd_context *ctx)
+ 			"The sub commands will be applied to all %d queues\n",
+ 			n_queues);
+ 	} else {
++		if (ctx->argc <= 2)
++			exit_bad_args();
+ 		ctx->argc--;
+ 		ctx->argp++;
+ 		if (parse_hex_u32_bitmap(*ctx->argp, MAX_NUM_QUEUE,
+-- 
+2.26.2
+
diff --git a/SOURCES/0006-ioctl-make-argc-counters-unsigned.patch b/SOURCES/0006-ioctl-make-argc-counters-unsigned.patch
new file mode 100644
index 0000000..229f05e
--- /dev/null
+++ b/SOURCES/0006-ioctl-make-argc-counters-unsigned.patch
@@ -0,0 +1,113 @@
+From 7e3888aeb31d2920c3c282b135563a06c3bcf6e1 Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Sun, 23 Aug 2020 21:40:27 +0200
+Subject: [PATCH 06/17] ioctl: make argc counters unsigned
+
+Use unsigned int for cmd_context::argc and local variables used for
+command line argument count. These counters may never get negative and are
+often compared to unsigned expressions.
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+(cherry picked from commit 519f95bd59034e672cfbac70ca8d7badc4f26cc7)
+---
+ ethtool.c  | 24 ++++++++++++------------
+ internal.h |  2 +-
+ 2 files changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/ethtool.c b/ethtool.c
+index 6c12452be7b4..7c7e98957c80 100644
+--- a/ethtool.c
++++ b/ethtool.c
+@@ -223,9 +223,9 @@ static void parse_generic_cmdline(struct cmd_context *ctx,
+ 				  struct cmdline_info *info,
+ 				  unsigned int n_info)
+ {
+-	int argc = ctx->argc;
++	unsigned int argc = ctx->argc;
+ 	char **argp = ctx->argp;
+-	int i, idx;
++	unsigned int i, idx;
+ 	int found;
+ 
+ 	for (i = 0; i < argc; i++) {
+@@ -2724,9 +2724,9 @@ static int do_sset(struct cmd_context *ctx)
+ 	u32 msglvl_wanted = 0;
+ 	u32 msglvl_mask = 0;
+ 	struct cmdline_info cmdline_msglvl[n_flags_msglvl];
+-	int argc = ctx->argc;
++	unsigned int argc = ctx->argc;
+ 	char **argp = ctx->argp;
+-	int i;
++	unsigned int i;
+ 	int err = 0;
+ 
+ 	for (i = 0; i < n_flags_msglvl; i++)
+@@ -3671,7 +3671,7 @@ static int do_grxfh(struct cmd_context *ctx)
+ 	struct ethtool_rxfh *rss;
+ 	u32 rss_context = 0;
+ 	u32 i, indir_bytes;
+-	int arg_num = 0;
++	unsigned int arg_num = 0;
+ 	char *hkey;
+ 	int err;
+ 
+@@ -4832,9 +4832,8 @@ static int do_gtunable(struct cmd_context *ctx)
+ {
+ 	struct ethtool_tunable_info *tinfo = tunables_info;
+ 	char **argp = ctx->argp;
+-	int argc = ctx->argc;
+-	int i;
+-	int j;
++	unsigned int argc = ctx->argc;
++	unsigned int i, j;
+ 
+ 	if (argc < 1)
+ 		exit_bad_args();
+@@ -4876,7 +4875,7 @@ static int do_gtunable(struct cmd_context *ctx)
+ 
+ static int do_get_phy_tunable(struct cmd_context *ctx)
+ {
+-	int argc = ctx->argc;
++	unsigned int argc = ctx->argc;
+ 	char **argp = ctx->argp;
+ 
+ 	if (argc < 1)
+@@ -4980,9 +4979,9 @@ static int do_reset(struct cmd_context *ctx)
+ {
+ 	struct ethtool_value resetinfo;
+ 	__u32 data;
+-	int argc = ctx->argc;
++	unsigned int argc = ctx->argc;
+ 	char **argp = ctx->argp;
+-	int i;
++	unsigned int i;
+ 
+ 	if (argc == 0)
+ 		exit_bad_args();
+@@ -5270,7 +5269,8 @@ static int do_sfec(struct cmd_context *ctx)
+ 	enum { ARG_NONE, ARG_ENCODING } state = ARG_NONE;
+ 	struct ethtool_fecparam feccmd;
+ 	int fecmode = 0, newmode;
+-	int rv, i;
++	unsigned int i;
++	int rv;
+ 
+ 	for (i = 0; i < ctx->argc; i++) {
+ 		if (!strcmp(ctx->argp[i], "encoding")) {
+diff --git a/internal.h b/internal.h
+index 8ae1efab5b5c..d096a28abfa2 100644
+--- a/internal.h
++++ b/internal.h
+@@ -221,7 +221,7 @@ struct cmd_context {
+ 	const char *devname;	/* net device name */
+ 	int fd;			/* socket suitable for ethtool ioctl */
+ 	struct ifreq ifr;	/* ifreq suitable for ethtool ioctl */
+-	int argc;		/* number of arguments to the sub-command */
++	unsigned int argc;	/* number of arguments to the sub-command */
+ 	char **argp;		/* arguments to the sub-command */
+ 	unsigned long debug;	/* debugging mask */
+ 	bool json;		/* Output JSON, if supported */
+-- 
+2.26.2
+
diff --git a/SOURCES/0007-ioctl-get-rid-of-signed-unsigned-comparison-warnings.patch b/SOURCES/0007-ioctl-get-rid-of-signed-unsigned-comparison-warnings.patch
new file mode 100644
index 0000000..2d94966
--- /dev/null
+++ b/SOURCES/0007-ioctl-get-rid-of-signed-unsigned-comparison-warnings.patch
@@ -0,0 +1,144 @@
+From 4be3e49856ef6c4f09f2230bbcf40cb7492313ca Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Sun, 23 Aug 2020 21:40:30 +0200
+Subject: [PATCH 07/17] ioctl: get rid of signed/unsigned comparison warnings
+
+Comparison between signed and unsigned values is fragile and causes
+compiler warnings with recent compilers and stricter CFLAGS. Prevent such
+comparisons either by properly declaring variables (mostly loop iterators)
+as unsigned or by explicitly casting one side of the comparison.
+
+v2: rework argc related changes and split them into a separate patch
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit f2f0fca943ffa25458865e4187690c9c7d6a89bc)
+---
+ ethtool.c | 31 +++++++++++++++++--------------
+ 1 file changed, 17 insertions(+), 14 deletions(-)
+
+diff --git a/ethtool.c b/ethtool.c
+index 7c7e98957c80..3c30824016d5 100644
+--- a/ethtool.c
++++ b/ethtool.c
+@@ -641,8 +641,9 @@ static void dump_link_caps(const char *prefix, const char *an_prefix,
+ 		  "200000baseCR4/Full" },
+ 	};
+ 	int indent;
+-	int did1, new_line_pend, i;
++	int did1, new_line_pend;
+ 	int fecreported = 0;
++	unsigned int i;
+ 
+ 	/* Indent just like the separate functions used to */
+ 	indent = strlen(prefix) + 14;
+@@ -1071,7 +1072,7 @@ void dump_hex(FILE *file, const u8 *data, int len, int offset)
+ static int dump_regs(int gregs_dump_raw, int gregs_dump_hex,
+ 		     struct ethtool_drvinfo *info, struct ethtool_regs *regs)
+ {
+-	int i;
++	unsigned int i;
+ 
+ 	if (gregs_dump_raw) {
+ 		fwrite(regs->data, regs->len, 1, stdout);
+@@ -1128,7 +1129,8 @@ static int dump_eeprom(int geeprom_dump_raw,
+ static int dump_test(struct ethtool_test *test,
+ 		     struct ethtool_gstrings *strings)
+ {
+-	int i, rc;
++	unsigned int i;
++	int rc;
+ 
+ 	rc = test->flags & ETH_TEST_FL_FAILED;
+ 	fprintf(stdout, "The test result is %s\n", rc ? "FAIL" : "PASS");
+@@ -1359,7 +1361,7 @@ static void dump_one_feature(const char *indent, const char *name,
+ 	       : "");
+ }
+ 
+-static int linux_version_code(void)
++static unsigned int linux_version_code(void)
+ {
+ 	struct utsname utsname;
+ 	unsigned version, patchlevel, sublevel = 0;
+@@ -1375,10 +1377,10 @@ static void dump_features(const struct feature_defs *defs,
+ 			  const struct feature_state *state,
+ 			  const struct feature_state *ref_state)
+ {
+-	int kernel_ver = linux_version_code();
+-	u32 value;
++	unsigned int kernel_ver = linux_version_code();
++	unsigned int i, j;
+ 	int indent;
+-	int i, j;
++	u32 value;
+ 
+ 	for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) {
+ 		/* Don't show features whose state is unknown on this
+@@ -1411,7 +1413,7 @@ static void dump_features(const struct feature_defs *defs,
+ 
+ 		/* Show matching features */
+ 		for (j = 0; j < defs->n_features; j++) {
+-			if (defs->def[j].off_flag_index != i)
++			if (defs->def[j].off_flag_index != (int)i)
+ 				continue;
+ 			if (defs->off_flag_matched[i] != 1)
+ 				/* Show all matching feature states */
+@@ -1668,8 +1670,8 @@ static struct feature_defs *get_feature_defs(struct cmd_context *ctx)
+ {
+ 	struct ethtool_gstrings *names;
+ 	struct feature_defs *defs;
++	unsigned int i, j;
+ 	u32 n_features;
+-	int i, j;
+ 
+ 	names = get_stringset(ctx, ETH_SS_FEATURES, 0, 1);
+ 	if (names) {
+@@ -2236,8 +2238,8 @@ static int do_sfeatures(struct cmd_context *ctx)
+ 	struct cmdline_info *cmdline_features;
+ 	struct feature_state *old_state, *new_state;
+ 	struct ethtool_value eval;
++	unsigned int i, j;
+ 	int err, rc;
+-	int i, j;
+ 
+ 	defs = get_feature_defs(ctx);
+ 	if (!defs) {
+@@ -2317,7 +2319,7 @@ static int do_sfeatures(struct cmd_context *ctx)
+ 				continue;
+ 
+ 			for (j = 0; j < defs->n_features; j++) {
+-				if (defs->def[j].off_flag_index != i ||
++				if (defs->def[j].off_flag_index != (int)i ||
+ 				    !FEATURE_BIT_IS_SET(
+ 					    old_state->features.features,
+ 					    j, available) ||
+@@ -3869,7 +3871,7 @@ static int do_srxfh(struct cmd_context *ctx)
+ 	char *hfunc_name = NULL;
+ 	char *hkey = NULL;
+ 	int err = 0;
+-	int i;
++	unsigned int i;
+ 	u32 arg_num = 0, indir_bytes = 0;
+ 	u32 req_hfunc = 0;
+ 	u32 entry_size = sizeof(rss_head.rss_config[0]);
+@@ -4135,7 +4137,8 @@ static int do_flash(struct cmd_context *ctx)
+ 
+ static int do_permaddr(struct cmd_context *ctx)
+ {
+-	int i, err;
++	unsigned int i;
++	int err;
+ 	struct ethtool_perm_addr *epaddr;
+ 
+ 	epaddr = malloc(sizeof(struct ethtool_perm_addr) + MAX_ADDR_LEN);
+@@ -4750,7 +4753,7 @@ static int do_stunable(struct cmd_context *ctx)
+ 	struct cmdline_info cmdline_tunable[TUNABLES_INFO_SIZE];
+ 	struct ethtool_tunable_info *tinfo = tunables_info;
+ 	int changed = 0;
+-	int i;
++	unsigned int i;
+ 
+ 	for (i = 0; i < TUNABLES_INFO_SIZE; i++) {
+ 		cmdline_tunable[i].name = tunable_strings[tinfo[i].t_id];
+-- 
+2.26.2
+
diff --git a/SOURCES/0008-get-rid-of-signed-unsigned-comparison-warnings-in-re.patch b/SOURCES/0008-get-rid-of-signed-unsigned-comparison-warnings-in-re.patch
new file mode 100644
index 0000000..218240f
--- /dev/null
+++ b/SOURCES/0008-get-rid-of-signed-unsigned-comparison-warnings-in-re.patch
@@ -0,0 +1,164 @@
+From a76ac50c3049b7fa77f71828c4e0a3569eea626d Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Sun, 23 Aug 2020 21:40:33 +0200
+Subject: [PATCH 08/17] get rid of signed/unsigned comparison warnings in
+ register dump parsers
+
+All of these are avoided by declaring a variable (mostly loop iterators)
+holding only unsigned values as unsigned.
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+(cherry picked from commit 16c87d0a03757958d857d7054bd296bfc74c6d39)
+---
+ dsa.c      | 2 +-
+ fec.c      | 2 +-
+ ibm_emac.c | 2 +-
+ marvell.c  | 2 +-
+ natsemi.c  | 2 +-
+ rxclass.c  | 8 +++++---
+ sfpdiag.c  | 2 +-
+ tg3.c      | 4 ++--
+ 8 files changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/dsa.c b/dsa.c
+index 65502a899194..33c1d39d6605 100644
+--- a/dsa.c
++++ b/dsa.c
+@@ -824,8 +824,8 @@ static int dsa_mv88e6xxx_dump_regs(struct ethtool_regs *regs)
+ {
+ 	const struct dsa_mv88e6xxx_switch *sw = NULL;
+ 	const u16 *data = (u16 *)regs->data;
++	unsigned int i;
+ 	u16 id;
+-	int i;
+ 
+ 	/* Marvell chips have 32 per-port 16-bit registers */
+ 	if (regs->len < 32 * sizeof(u16))
+diff --git a/fec.c b/fec.c
+index 9cb4f8b1d4e1..d2373d6124c0 100644
+--- a/fec.c
++++ b/fec.c
+@@ -198,7 +198,7 @@ int fec_dump_regs(struct ethtool_drvinfo *info __maybe_unused,
+ 		  struct ethtool_regs *regs)
+ {
+ 	const u32 *data = (u32 *)regs->data;
+-	int offset;
++	unsigned int offset;
+ 	u32 val;
+ 
+ 	for (offset = 0; offset < regs->len; offset += 4) {
+diff --git a/ibm_emac.c b/ibm_emac.c
+index ea01d56f609c..9f7cae605482 100644
+--- a/ibm_emac.c
++++ b/ibm_emac.c
+@@ -238,7 +238,7 @@ static void *print_mal_regs(void *buf)
+ {
+ 	struct emac_ethtool_regs_subhdr *hdr = buf;
+ 	struct mal_regs *p = (struct mal_regs *)(hdr + 1);
+-	int i;
++	unsigned int i;
+ 
+ 	printf("MAL%d Registers\n", hdr->index);
+ 	printf("-----------------\n");
+diff --git a/marvell.c b/marvell.c
+index 8afb150327a3..d3d570e4d4ad 100644
+--- a/marvell.c
++++ b/marvell.c
+@@ -130,7 +130,7 @@ static void dump_fifo(const char *name, const void *p)
+ static void dump_gmac_fifo(const char *name, const void *p)
+ {
+ 	const u32 *r = p;
+-	int i;
++	unsigned int i;
+ 	static const char *regs[] = {
+ 		"End Address",
+ 		"Almost Full Thresh",
+diff --git a/natsemi.c b/natsemi.c
+index 0af465959cbc..4d9fc092b623 100644
+--- a/natsemi.c
++++ b/natsemi.c
+@@ -967,8 +967,8 @@ int
+ natsemi_dump_eeprom(struct ethtool_drvinfo *info __maybe_unused,
+ 		    struct ethtool_eeprom *ee)
+ {
+-	int i;
+ 	u16 *eebuf = (u16 *)ee->data;
++	unsigned int i;
+ 
+ 	if (ee->magic != NATSEMI_MAGIC) {
+ 		fprintf(stderr, "Magic number 0x%08x does not match 0x%08x\n",
+diff --git a/rxclass.c b/rxclass.c
+index 79972651e706..6cf81fdafc85 100644
+--- a/rxclass.c
++++ b/rxclass.c
+@@ -348,8 +348,9 @@ int rxclass_rule_getall(struct cmd_context *ctx)
+ {
+ 	struct ethtool_rxnfc *nfccmd;
+ 	__u32 *rule_locs;
+-	int err, i;
++	unsigned int i;
+ 	__u32 count;
++	int err;
+ 
+ 	/* determine rule count */
+ 	err = rxclass_get_dev_info(ctx, &count, NULL);
+@@ -481,8 +482,9 @@ static int rmgr_find_empty_slot(struct rmgr_ctrl *rmgr,
+ static int rmgr_init(struct cmd_context *ctx, struct rmgr_ctrl *rmgr)
+ {
+ 	struct ethtool_rxnfc *nfccmd;
+-	int err, i;
+ 	__u32 *rule_locs;
++	unsigned int i;
++	int err;
+ 
+ 	/* clear rule manager settings */
+ 	memset(rmgr, 0, sizeof(*rmgr));
+@@ -941,7 +943,7 @@ static int rxclass_get_long(char *str, long long *val, int size)
+ 
+ static int rxclass_get_ulong(char *str, unsigned long long *val, int size)
+ {
+-	long long max = ~0ULL >> (64 - size);
++	unsigned long long max = ~0ULL >> (64 - size);
+ 	char *endp;
+ 
+ 	errno = 0;
+diff --git a/sfpdiag.c b/sfpdiag.c
+index fa41651422ea..1fa8b7ba8fec 100644
+--- a/sfpdiag.c
++++ b/sfpdiag.c
+@@ -190,8 +190,8 @@ static float befloattoh(const __u32 *source)
+ 
+ static void sff8472_calibration(const __u8 *id, struct sff_diags *sd)
+ {
+-	int i;
+ 	__u16 rx_reading;
++	unsigned int i;
+ 
+ 	/* Calibration should occur for all values (threshold and current) */
+ 	for (i = 0; i < ARRAY_SIZE(sd->bias_cur); ++i) {
+diff --git a/tg3.c b/tg3.c
+index ac73b33ae4e3..ebdef2d60e6b 100644
+--- a/tg3.c
++++ b/tg3.c
+@@ -7,7 +7,7 @@
+ int tg3_dump_eeprom(struct ethtool_drvinfo *info __maybe_unused,
+ 		    struct ethtool_eeprom *ee)
+ {
+-	int i;
++	unsigned int i;
+ 
+ 	if (ee->magic != TG3_MAGIC) {
+ 		fprintf(stderr, "Magic number 0x%08x does not match 0x%08x\n",
+@@ -26,7 +26,7 @@ int tg3_dump_eeprom(struct ethtool_drvinfo *info __maybe_unused,
+ int tg3_dump_regs(struct ethtool_drvinfo *info __maybe_unused,
+ 		  struct ethtool_regs *regs)
+ {
+-	int i;
++	unsigned int i;
+ 	u32 reg;
+ 
+ 	fprintf(stdout, "Offset\tValue\n");
+-- 
+2.26.2
+
diff --git a/SOURCES/0009-settings-simplify-link_mode_info-initializers.patch b/SOURCES/0009-settings-simplify-link_mode_info-initializers.patch
new file mode 100644
index 0000000..1e3d9b2
--- /dev/null
+++ b/SOURCES/0009-settings-simplify-link_mode_info-initializers.patch
@@ -0,0 +1,273 @@
+From f99224132fba926ac0fb736748586ecdd51bb9d4 Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Sun, 23 Aug 2020 21:40:36 +0200
+Subject: [PATCH 09/17] settings: simplify link_mode_info[] initializers
+
+Use macro helpers to make link_mode_info[] initializers easier to read and
+less prone to mistakes. As a bonus, this gets rid of "missing field
+initializer" warnings in netlink/settings.c
+
+This commit should have no effect on resulting code (checked with gcc-11
+and -O2).
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+(cherry picked from commit 5319fae14254df9cb38cb2db0a4e39973c3fc1d8)
+---
+ netlink/settings.c | 236 +++++++++++++++++----------------------------
+ 1 file changed, 86 insertions(+), 150 deletions(-)
+
+diff --git a/netlink/settings.c b/netlink/settings.c
+index 2b9c6e7a782c..d1da995b434c 100644
+--- a/netlink/settings.c
++++ b/netlink/settings.c
+@@ -64,160 +64,96 @@ static const char *const names_transceiver[] = {
+  * there is little chance of getting them separated any time soon so let's
+  * sort them out ourselves
+  */
++#define __REAL(_speed) \
++	{ .class = LM_CLASS_REAL, .speed = _speed, .duplex = DUPLEX_FULL }
++#define __HALF_DUPLEX(_speed) \
++	{ .class = LM_CLASS_REAL, .speed = _speed, .duplex = DUPLEX_HALF }
++#define __SPECIAL(_class) \
++	{ .class = LM_CLASS_ ## _class }
++
+ static const struct link_mode_info link_modes[] = {
+-	[ETHTOOL_LINK_MODE_10baseT_Half_BIT] =
+-		{ LM_CLASS_REAL,	10,	DUPLEX_HALF },
+-	[ETHTOOL_LINK_MODE_10baseT_Full_BIT] =
+-		{ LM_CLASS_REAL,	10,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_100baseT_Half_BIT] =
+-		{ LM_CLASS_REAL,	100,	DUPLEX_HALF },
+-	[ETHTOOL_LINK_MODE_100baseT_Full_BIT] =
+-		{ LM_CLASS_REAL,	100,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_1000baseT_Half_BIT] =
+-		{ LM_CLASS_REAL,	1000,	DUPLEX_HALF },
+-	[ETHTOOL_LINK_MODE_1000baseT_Full_BIT] =
+-		{ LM_CLASS_REAL,	1000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_Autoneg_BIT] =
+-		{ LM_CLASS_AUTONEG },
+-	[ETHTOOL_LINK_MODE_TP_BIT] =
+-		{ LM_CLASS_PORT },
+-	[ETHTOOL_LINK_MODE_AUI_BIT] =
+-		{ LM_CLASS_PORT },
+-	[ETHTOOL_LINK_MODE_MII_BIT] =
+-		{ LM_CLASS_PORT },
+-	[ETHTOOL_LINK_MODE_FIBRE_BIT] =
+-		{ LM_CLASS_PORT },
+-	[ETHTOOL_LINK_MODE_BNC_BIT] =
+-		{ LM_CLASS_PORT },
+-	[ETHTOOL_LINK_MODE_10000baseT_Full_BIT] =
+-		{ LM_CLASS_REAL,	10000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_Pause_BIT] =
+-		{ LM_CLASS_PAUSE },
+-	[ETHTOOL_LINK_MODE_Asym_Pause_BIT] =
+-		{ LM_CLASS_PAUSE },
+-	[ETHTOOL_LINK_MODE_2500baseX_Full_BIT] =
+-		{ LM_CLASS_REAL,	2500,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_Backplane_BIT] =
+-		{ LM_CLASS_PORT },
+-	[ETHTOOL_LINK_MODE_1000baseKX_Full_BIT] =
+-		{ LM_CLASS_REAL,	1000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT] =
+-		{ LM_CLASS_REAL,	10000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_10000baseKR_Full_BIT] =
+-		{ LM_CLASS_REAL,	10000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_10000baseR_FEC_BIT] =
+-		{ LM_CLASS_REAL,	10000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT] =
+-		{ LM_CLASS_REAL,	20000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT] =
+-		{ LM_CLASS_REAL,	20000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	40000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	40000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	40000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	40000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	56000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	56000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	56000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	56000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_25000baseCR_Full_BIT] =
+-		{ LM_CLASS_REAL,	25000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_25000baseKR_Full_BIT] =
+-		{ LM_CLASS_REAL,	25000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_25000baseSR_Full_BIT] =
+-		{ LM_CLASS_REAL,	25000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT] =
+-		{ LM_CLASS_REAL,	50000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT] =
+-		{ LM_CLASS_REAL,	50000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	100000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	100000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	100000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT] =
+-		{ LM_CLASS_REAL,	100000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT] =
+-		{ LM_CLASS_REAL,	50000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_1000baseX_Full_BIT] =
+-		{ LM_CLASS_REAL,	1000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_10000baseCR_Full_BIT] =
+-		{ LM_CLASS_REAL,	10000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_10000baseSR_Full_BIT] =
+-		{ LM_CLASS_REAL,	10000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_10000baseLR_Full_BIT] =
+-		{ LM_CLASS_REAL,	10000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT] =
+-		{ LM_CLASS_REAL,	10000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_10000baseER_Full_BIT] =
+-		{ LM_CLASS_REAL,	10000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_2500baseT_Full_BIT] =
+-		{ LM_CLASS_REAL,	2500,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_5000baseT_Full_BIT] =
+-		{ LM_CLASS_REAL,	5000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_FEC_NONE_BIT] =
+-		{ LM_CLASS_FEC },
+-	[ETHTOOL_LINK_MODE_FEC_RS_BIT] =
+-		{ LM_CLASS_FEC },
+-	[ETHTOOL_LINK_MODE_FEC_BASER_BIT] =
+-		{ LM_CLASS_FEC },
+-	[ETHTOOL_LINK_MODE_50000baseKR_Full_BIT] =
+-		{ LM_CLASS_REAL,	50000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_50000baseSR_Full_BIT] =
+-		{ LM_CLASS_REAL,	50000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_50000baseCR_Full_BIT] =
+-		{ LM_CLASS_REAL,	50000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT] =
+-		{ LM_CLASS_REAL,	50000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_50000baseDR_Full_BIT] =
+-		{ LM_CLASS_REAL,	50000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT] =
+-		{ LM_CLASS_REAL,	100000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT] =
+-		{ LM_CLASS_REAL,	100000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT] =
+-		{ LM_CLASS_REAL,	100000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT] =
+-		{ LM_CLASS_REAL,	100000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT] =
+-		{ LM_CLASS_REAL,	100000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	200000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	200000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	200000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	200000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT] =
+-		{ LM_CLASS_REAL,	200000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_100baseT1_Full_BIT] =
+-		{ LM_CLASS_REAL,	100,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_1000baseT1_Full_BIT] =
+-		{ LM_CLASS_REAL,	1000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT] =
+-		{ LM_CLASS_REAL,	400000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT] =
+-		{ LM_CLASS_REAL,	400000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT] =
+-		{ LM_CLASS_REAL,	400000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT] =
+-		{ LM_CLASS_REAL,	400000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT] =
+-		{ LM_CLASS_REAL,	400000,	DUPLEX_FULL },
+-	[ETHTOOL_LINK_MODE_FEC_LLRS_BIT] =
+-		{ LM_CLASS_FEC },
++	[ETHTOOL_LINK_MODE_10baseT_Half_BIT]		= __HALF_DUPLEX(10),
++	[ETHTOOL_LINK_MODE_10baseT_Full_BIT]		= __REAL(10),
++	[ETHTOOL_LINK_MODE_100baseT_Half_BIT]		= __HALF_DUPLEX(100),
++	[ETHTOOL_LINK_MODE_100baseT_Full_BIT]		= __REAL(100),
++	[ETHTOOL_LINK_MODE_1000baseT_Half_BIT]		= __HALF_DUPLEX(1000),
++	[ETHTOOL_LINK_MODE_1000baseT_Full_BIT]		= __REAL(1000),
++	[ETHTOOL_LINK_MODE_Autoneg_BIT]			= __SPECIAL(AUTONEG),
++	[ETHTOOL_LINK_MODE_TP_BIT]			= __SPECIAL(PORT),
++	[ETHTOOL_LINK_MODE_AUI_BIT]			= __SPECIAL(PORT),
++	[ETHTOOL_LINK_MODE_MII_BIT]			= __SPECIAL(PORT),
++	[ETHTOOL_LINK_MODE_FIBRE_BIT]			= __SPECIAL(PORT),
++	[ETHTOOL_LINK_MODE_BNC_BIT]			= __SPECIAL(PORT),
++	[ETHTOOL_LINK_MODE_10000baseT_Full_BIT]		= __REAL(10000),
++	[ETHTOOL_LINK_MODE_Pause_BIT]			= __SPECIAL(PAUSE),
++	[ETHTOOL_LINK_MODE_Asym_Pause_BIT]		= __SPECIAL(PAUSE),
++	[ETHTOOL_LINK_MODE_2500baseX_Full_BIT]		= __REAL(2500),
++	[ETHTOOL_LINK_MODE_Backplane_BIT]		= __SPECIAL(PORT),
++	[ETHTOOL_LINK_MODE_1000baseKX_Full_BIT]		= __REAL(1000),
++	[ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT]	= __REAL(10000),
++	[ETHTOOL_LINK_MODE_10000baseKR_Full_BIT]	= __REAL(10000),
++	[ETHTOOL_LINK_MODE_10000baseR_FEC_BIT]		= __REAL(10000),
++	[ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT]	= __REAL(20000),
++	[ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT]	= __REAL(20000),
++	[ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT]	= __REAL(40000),
++	[ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT]	= __REAL(40000),
++	[ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT]	= __REAL(40000),
++	[ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT]	= __REAL(40000),
++	[ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT]	= __REAL(56000),
++	[ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT]	= __REAL(56000),
++	[ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT]	= __REAL(56000),
++	[ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT]	= __REAL(56000),
++	[ETHTOOL_LINK_MODE_25000baseCR_Full_BIT]	= __REAL(25000),
++	[ETHTOOL_LINK_MODE_25000baseKR_Full_BIT]	= __REAL(25000),
++	[ETHTOOL_LINK_MODE_25000baseSR_Full_BIT]	= __REAL(25000),
++	[ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT]	= __REAL(50000),
++	[ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT]	= __REAL(50000),
++	[ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT]	= __REAL(100000),
++	[ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT]	= __REAL(100000),
++	[ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT]	= __REAL(100000),
++	[ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT]	= __REAL(100000),
++	[ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT]	= __REAL(50000),
++	[ETHTOOL_LINK_MODE_1000baseX_Full_BIT]		= __REAL(1000),
++	[ETHTOOL_LINK_MODE_10000baseCR_Full_BIT]	= __REAL(10000),
++	[ETHTOOL_LINK_MODE_10000baseSR_Full_BIT]	= __REAL(10000),
++	[ETHTOOL_LINK_MODE_10000baseLR_Full_BIT]	= __REAL(10000),
++	[ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT]	= __REAL(10000),
++	[ETHTOOL_LINK_MODE_10000baseER_Full_BIT]	= __REAL(10000),
++	[ETHTOOL_LINK_MODE_2500baseT_Full_BIT]		= __REAL(2500),
++	[ETHTOOL_LINK_MODE_5000baseT_Full_BIT]		= __REAL(5000),
++	[ETHTOOL_LINK_MODE_FEC_NONE_BIT]		= __SPECIAL(FEC),
++	[ETHTOOL_LINK_MODE_FEC_RS_BIT]			= __SPECIAL(FEC),
++	[ETHTOOL_LINK_MODE_FEC_BASER_BIT]		= __SPECIAL(FEC),
++	[ETHTOOL_LINK_MODE_50000baseKR_Full_BIT]	= __REAL(50000),
++	[ETHTOOL_LINK_MODE_50000baseSR_Full_BIT]	= __REAL(50000),
++	[ETHTOOL_LINK_MODE_50000baseCR_Full_BIT]	= __REAL(50000),
++	[ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT]	= __REAL(50000),
++	[ETHTOOL_LINK_MODE_50000baseDR_Full_BIT]	= __REAL(50000),
++	[ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT]	= __REAL(100000),
++	[ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT]	= __REAL(100000),
++	[ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT]	= __REAL(100000),
++	[ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT] = __REAL(100000),
++	[ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT]	= __REAL(100000),
++	[ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT]	= __REAL(200000),
++	[ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT]	= __REAL(200000),
++	[ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT] = __REAL(200000),
++	[ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT]	= __REAL(200000),
++	[ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT]	= __REAL(200000),
++	[ETHTOOL_LINK_MODE_100baseT1_Full_BIT]		= __REAL(100),
++	[ETHTOOL_LINK_MODE_1000baseT1_Full_BIT]		= __REAL(1000),
++	[ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT]	= __REAL(400000),
++	[ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT]	= __REAL(400000),
++	[ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT] = __REAL(400000),
++	[ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT]	= __REAL(400000),
++	[ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT]	= __REAL(400000),
++	[ETHTOOL_LINK_MODE_FEC_LLRS_BIT]		= __SPECIAL(FEC),
+ };
+ const unsigned int link_modes_count = ARRAY_SIZE(link_modes);
+ 
++#undef __REAL
++#undef __HALF_DUPLEX
++#undef __SPECIAL
++
+ static bool lm_class_match(unsigned int mode, enum link_mode_class class)
+ {
+ 	unsigned int mode_class = (mode < link_modes_count) ?
+-- 
+2.26.2
+
diff --git a/SOURCES/0010-ioctl-convert-cmdline_info-arrays-to-named-initializ.patch b/SOURCES/0010-ioctl-convert-cmdline_info-arrays-to-named-initializ.patch
new file mode 100644
index 0000000..dc7309e
--- /dev/null
+++ b/SOURCES/0010-ioctl-convert-cmdline_info-arrays-to-named-initializ.patch
@@ -0,0 +1,468 @@
+From 35fb9ff49c579d6e6819d71ab4c614cb3d2c0dae Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Sun, 23 Aug 2020 21:40:39 +0200
+Subject: [PATCH 10/17] ioctl: convert cmdline_info arrays to named
+ initializers
+
+To get rid of remaining "missing field initializer" compiler warnings,
+convert arrays of struct cmdline_info used for command line parser to
+named initializers. This also makes the initializers easier to read.
+
+This commit should have no effect on resulting code (checked with gcc-11
+and -O2).
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+(cherry picked from commit 0c43dec5cf64aee41bbd4195c96671032ea6556d)
+---
+ ethtool.c | 378 ++++++++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 296 insertions(+), 82 deletions(-)
+
+diff --git a/ethtool.c b/ethtool.c
+index 3c30824016d5..e32a93b41088 100644
+--- a/ethtool.c
++++ b/ethtool.c
+@@ -1825,10 +1825,24 @@ static int do_spause(struct cmd_context *ctx)
+ 	int pause_rx_wanted = -1;
+ 	int pause_tx_wanted = -1;
+ 	struct cmdline_info cmdline_pause[] = {
+-		{ "autoneg", CMDL_BOOL, &pause_autoneg_wanted,
+-		  &epause.autoneg },
+-		{ "rx", CMDL_BOOL, &pause_rx_wanted, &epause.rx_pause },
+-		{ "tx", CMDL_BOOL, &pause_tx_wanted, &epause.tx_pause },
++		{
++			.name		= "autoneg",
++			.type		= CMDL_BOOL,
++			.wanted_val	= &pause_autoneg_wanted,
++			.ioctl_val	= &epause.autoneg,
++		},
++		{
++			.name		= "rx",
++			.type		= CMDL_BOOL,
++			.wanted_val	= &pause_rx_wanted,
++			.ioctl_val	= &epause.rx_pause,
++		},
++		{
++			.name		= "tx",
++			.type		= CMDL_BOOL,
++			.wanted_val	= &pause_tx_wanted,
++			.ioctl_val	= &epause.tx_pause,
++		},
+ 	};
+ 	int err, changed = 0;
+ 
+@@ -1868,12 +1882,30 @@ static int do_sring(struct cmd_context *ctx)
+ 	s32 ring_rx_jumbo_wanted = -1;
+ 	s32 ring_tx_wanted = -1;
+ 	struct cmdline_info cmdline_ring[] = {
+-		{ "rx", CMDL_S32, &ring_rx_wanted, &ering.rx_pending },
+-		{ "rx-mini", CMDL_S32, &ring_rx_mini_wanted,
+-		  &ering.rx_mini_pending },
+-		{ "rx-jumbo", CMDL_S32, &ring_rx_jumbo_wanted,
+-		  &ering.rx_jumbo_pending },
+-		{ "tx", CMDL_S32, &ring_tx_wanted, &ering.tx_pending },
++		{
++			.name		= "rx",
++			.type		= CMDL_S32,
++			.wanted_val	= &ring_rx_wanted,
++			.ioctl_val	= &ering.rx_pending,
++		},
++		{
++			.name		= "rx-mini",
++			.type		= CMDL_S32,
++			.wanted_val	= &ring_rx_mini_wanted,
++			.ioctl_val	= &ering.rx_mini_pending,
++		},
++		{
++			.name		= "rx-jumbo",
++			.type		= CMDL_S32,
++			.wanted_val	= &ring_rx_jumbo_wanted,
++			.ioctl_val	= &ering.rx_jumbo_pending,
++		},
++		{
++			.name		= "tx",
++			.type		= CMDL_S32,
++			.wanted_val	= &ring_tx_wanted,
++			.ioctl_val	= &ering.tx_pending,
++		},
+ 	};
+ 	int err, changed = 0;
+ 
+@@ -1937,12 +1969,30 @@ static int do_schannels(struct cmd_context *ctx)
+ 	s32 channels_other_wanted = -1;
+ 	s32 channels_combined_wanted = -1;
+ 	struct cmdline_info cmdline_channels[] = {
+-		{ "rx", CMDL_S32, &channels_rx_wanted, &echannels.rx_count },
+-		{ "tx", CMDL_S32, &channels_tx_wanted, &echannels.tx_count },
+-		{ "other", CMDL_S32, &channels_other_wanted,
+-		  &echannels.other_count },
+-		{ "combined", CMDL_S32, &channels_combined_wanted,
+-		  &echannels.combined_count },
++		{
++			.name		= "rx",
++			.type		= CMDL_S32,
++			.wanted_val	= &channels_rx_wanted,
++			.ioctl_val	= &echannels.rx_count,
++		},
++		{
++			.name		= "tx",
++			.type		= CMDL_S32,
++			.wanted_val	= &channels_tx_wanted,
++			.ioctl_val	= &echannels.tx_count,
++		},
++		{
++			.name		= "other",
++			.type		= CMDL_S32,
++			.wanted_val	= &channels_other_wanted,
++			.ioctl_val	= &echannels.other_count,
++		},
++		{
++			.name		= "combined",
++			.type		= CMDL_S32,
++			.wanted_val	= &channels_combined_wanted,
++			.ioctl_val	= &echannels.combined_count,
++		},
+ 	};
+ 	int err, changed = 0;
+ 
+@@ -2052,50 +2102,138 @@ static int do_gcoalesce(struct cmd_context *ctx)
+ 
+ #define COALESCE_CMDLINE_INFO(__ecoal)					\
+ {									\
+-	{ "adaptive-rx", CMDL_BOOL, &coal_adaptive_rx_wanted,		\
+-	  &__ecoal.use_adaptive_rx_coalesce },				\
+-	{ "adaptive-tx", CMDL_BOOL, &coal_adaptive_tx_wanted,		\
+-	  &__ecoal.use_adaptive_tx_coalesce },				\
+-	{ "sample-interval", CMDL_S32, &coal_sample_rate_wanted,	\
+-	  &__ecoal.rate_sample_interval },				\
+-	{ "stats-block-usecs", CMDL_S32, &coal_stats_wanted,		\
+-	  &__ecoal.stats_block_coalesce_usecs },			\
+-	{ "pkt-rate-low", CMDL_S32, &coal_pkt_rate_low_wanted,		\
+-	  &__ecoal.pkt_rate_low },					\
+-	{ "pkt-rate-high", CMDL_S32, &coal_pkt_rate_high_wanted,	\
+-	  &__ecoal.pkt_rate_high },					\
+-	{ "rx-usecs", CMDL_S32, &coal_rx_usec_wanted,			\
+-	  &__ecoal.rx_coalesce_usecs },					\
+-	{ "rx-frames", CMDL_S32, &coal_rx_frames_wanted,		\
+-	  &__ecoal.rx_max_coalesced_frames },				\
+-	{ "rx-usecs-irq", CMDL_S32, &coal_rx_usec_irq_wanted,		\
+-	  &__ecoal.rx_coalesce_usecs_irq },				\
+-	{ "rx-frames-irq", CMDL_S32, &coal_rx_frames_irq_wanted,	\
+-	  &__ecoal.rx_max_coalesced_frames_irq },			\
+-	{ "tx-usecs", CMDL_S32, &coal_tx_usec_wanted,			\
+-	  &__ecoal.tx_coalesce_usecs },					\
+-	{ "tx-frames", CMDL_S32, &coal_tx_frames_wanted,		\
+-	  &__ecoal.tx_max_coalesced_frames },				\
+-	{ "tx-usecs-irq", CMDL_S32, &coal_tx_usec_irq_wanted,		\
+-	  &__ecoal.tx_coalesce_usecs_irq },				\
+-	{ "tx-frames-irq", CMDL_S32, &coal_tx_frames_irq_wanted,	\
+-	  &__ecoal.tx_max_coalesced_frames_irq },			\
+-	{ "rx-usecs-low", CMDL_S32, &coal_rx_usec_low_wanted,		\
+-	  &__ecoal.rx_coalesce_usecs_low },				\
+-	{ "rx-frames-low", CMDL_S32, &coal_rx_frames_low_wanted,	\
+-	  &__ecoal.rx_max_coalesced_frames_low },			\
+-	{ "tx-usecs-low", CMDL_S32, &coal_tx_usec_low_wanted,		\
+-	  &__ecoal.tx_coalesce_usecs_low },				\
+-	{ "tx-frames-low", CMDL_S32, &coal_tx_frames_low_wanted,	\
+-	  &__ecoal.tx_max_coalesced_frames_low },			\
+-	{ "rx-usecs-high", CMDL_S32, &coal_rx_usec_high_wanted,		\
+-	  &__ecoal.rx_coalesce_usecs_high },				\
+-	{ "rx-frames-high", CMDL_S32, &coal_rx_frames_high_wanted,	\
+-	  &__ecoal.rx_max_coalesced_frames_high },			\
+-	{ "tx-usecs-high", CMDL_S32, &coal_tx_usec_high_wanted,		\
+-	  &__ecoal.tx_coalesce_usecs_high },				\
+-	{ "tx-frames-high", CMDL_S32, &coal_tx_frames_high_wanted,	\
+-	  &__ecoal.tx_max_coalesced_frames_high },			\
++	{								\
++		.name		= "adaptive-rx",			\
++		.type		= CMDL_BOOL,				\
++		.wanted_val	= &coal_adaptive_rx_wanted,		\
++		.ioctl_val	= &__ecoal.use_adaptive_rx_coalesce,	\
++	},								\
++	{								\
++		.name		= "adaptive-tx",			\
++		.type		= CMDL_BOOL,				\
++		.wanted_val	= &coal_adaptive_tx_wanted,		\
++		.ioctl_val	= &__ecoal.use_adaptive_tx_coalesce,	\
++	},								\
++	{								\
++		.name		= "sample-interval",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_sample_rate_wanted,		\
++		.ioctl_val	= &__ecoal.rate_sample_interval,	\
++	},								\
++	{								\
++		.name		= "stats-block-usecs",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_stats_wanted,			\
++		.ioctl_val	= &__ecoal.stats_block_coalesce_usecs,	\
++	},								\
++	{								\
++		.name		= "pkt-rate-low",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_pkt_rate_low_wanted,		\
++		.ioctl_val	= &__ecoal.pkt_rate_low,		\
++	},								\
++	{								\
++		.name		= "pkt-rate-high",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_pkt_rate_high_wanted,		\
++		.ioctl_val	= &__ecoal.pkt_rate_high,		\
++	},								\
++	{								\
++		.name		= "rx-usecs",				\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_rx_usec_wanted,			\
++		.ioctl_val	= &__ecoal.rx_coalesce_usecs,		\
++	},								\
++	{								\
++		.name		= "rx-frames",				\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_rx_frames_wanted,		\
++		.ioctl_val	= &__ecoal.rx_max_coalesced_frames,	\
++	},								\
++	{								\
++		.name		= "rx-usecs-irq",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_rx_usec_irq_wanted,		\
++		.ioctl_val	= &__ecoal.rx_coalesce_usecs_irq,	\
++	},								\
++	{								\
++		.name		= "rx-frames-irq",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_rx_frames_irq_wanted,		\
++		.ioctl_val	= &__ecoal.rx_max_coalesced_frames_irq,	\
++	},								\
++	{								\
++		.name		= "tx-usecs",				\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_tx_usec_wanted,			\
++		.ioctl_val	= &__ecoal.tx_coalesce_usecs,		\
++	},								\
++	{								\
++		.name		= "tx-frames",				\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_tx_frames_wanted,		\
++		.ioctl_val	= &__ecoal.tx_max_coalesced_frames,	\
++	},								\
++	{								\
++		.name		= "tx-usecs-irq",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_tx_usec_irq_wanted,		\
++		.ioctl_val	= &__ecoal.tx_coalesce_usecs_irq,	\
++	},								\
++	{								\
++		.name		= "tx-frames-irq",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_tx_frames_irq_wanted,		\
++		.ioctl_val	= &__ecoal.tx_max_coalesced_frames_irq,	\
++	},								\
++	{								\
++		.name		= "rx-usecs-low",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_rx_usec_low_wanted,		\
++		.ioctl_val	= &__ecoal.rx_coalesce_usecs_low,	\
++	},								\
++	{								\
++		.name		= "rx-frames-low",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_rx_frames_low_wanted,		\
++		.ioctl_val	= &__ecoal.rx_max_coalesced_frames_low,	\
++	},								\
++	{								\
++		.name		= "tx-usecs-low",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_tx_usec_low_wanted,		\
++		.ioctl_val	= &__ecoal.tx_coalesce_usecs_low,	\
++	},								\
++	{								\
++		.name		= "tx-frames-low",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_tx_frames_low_wanted,		\
++		.ioctl_val	= &__ecoal.tx_max_coalesced_frames_low,	\
++	},								\
++	{								\
++		.name		= "rx-usecs-high",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_rx_usec_high_wanted,		\
++		.ioctl_val	= &__ecoal.rx_coalesce_usecs_high,	\
++	},								\
++	{								\
++		.name		= "rx-frames-high",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_rx_frames_high_wanted,		\
++		.ioctl_val	= &__ecoal.rx_max_coalesced_frames_high,\
++	},								\
++	{								\
++		.name		= "tx-usecs-high",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_tx_usec_high_wanted,		\
++		.ioctl_val	= &__ecoal.tx_coalesce_usecs_high,	\
++	},								\
++	{								\
++		.name		= "tx-frames-high",			\
++		.type		= CMDL_S32,				\
++		.wanted_val	= &coal_tx_frames_high_wanted,		\
++		.ioctl_val	= &__ecoal.tx_max_coalesced_frames_high,\
++	},								\
+ }
+ 
+ static int do_scoalesce(struct cmd_context *ctx)
+@@ -3090,9 +3228,21 @@ static int do_gregs(struct cmd_context *ctx)
+ 	int gregs_dump_hex = 0;
+ 	char *gregs_dump_file = NULL;
+ 	struct cmdline_info cmdline_gregs[] = {
+-		{ "raw", CMDL_BOOL, &gregs_dump_raw, NULL },
+-		{ "hex", CMDL_BOOL, &gregs_dump_hex, NULL },
+-		{ "file", CMDL_STR, &gregs_dump_file, NULL },
++		{
++			.name		= "raw",
++			.type		= CMDL_BOOL,
++			.wanted_val	= &gregs_dump_raw,
++		},
++		{
++			.name		= "hex",
++			.type		= CMDL_BOOL,
++			.wanted_val	= &gregs_dump_hex,
++		},
++		{
++			.name		= "file",
++			.type		= CMDL_STR,
++			.wanted_val	= &gregs_dump_file,
++		},
+ 	};
+ 	int err;
+ 	struct ethtool_drvinfo drvinfo;
+@@ -3189,10 +3339,22 @@ static int do_geeprom(struct cmd_context *ctx)
+ 	u32 geeprom_length = 0;
+ 	int geeprom_length_seen = 0;
+ 	struct cmdline_info cmdline_geeprom[] = {
+-		{ "offset", CMDL_U32, &geeprom_offset, NULL },
+-		{ "length", CMDL_U32, &geeprom_length, NULL,
+-		  0, &geeprom_length_seen },
+-		{ "raw", CMDL_BOOL, &geeprom_dump_raw, NULL },
++		{
++			.name		= "offset",
++			.type		= CMDL_U32,
++			.wanted_val	= &geeprom_offset,
++		},
++		{
++			.name		= "length",
++			.type		= CMDL_U32,
++			.wanted_val	= &geeprom_length,
++			.seen_val	= &geeprom_length_seen,
++		},
++		{
++			.name		= "raw",
++			.type		= CMDL_BOOL,
++			.wanted_val	= &geeprom_dump_raw,
++		},
+ 	};
+ 	int err;
+ 	struct ethtool_drvinfo drvinfo;
+@@ -3244,12 +3406,28 @@ static int do_seeprom(struct cmd_context *ctx)
+ 	int seeprom_length_seen = 0;
+ 	int seeprom_value_seen = 0;
+ 	struct cmdline_info cmdline_seeprom[] = {
+-		{ "magic", CMDL_U32, &seeprom_magic, NULL },
+-		{ "offset", CMDL_U32, &seeprom_offset, NULL },
+-		{ "length", CMDL_U32, &seeprom_length, NULL,
+-		  0, &seeprom_length_seen },
+-		{ "value", CMDL_U8, &seeprom_value, NULL,
+-		  0, &seeprom_value_seen },
++		{
++			.name		= "magic",
++			.type		= CMDL_U32,
++			.wanted_val	= &seeprom_magic,
++		},
++		{
++			.name		= "offset",
++			.type		= CMDL_U32,
++			.wanted_val	= &seeprom_offset,
++		},
++		{
++			.name		= "length",
++			.type		= CMDL_U32,
++			.wanted_val	= &seeprom_length,
++			.seen_val	= &seeprom_length_seen,
++		},
++		{
++			.name		= "value",
++			.type		= CMDL_U8,
++			.wanted_val	= &seeprom_value,
++			.seen_val	= &seeprom_value_seen,
++		},
+ 	};
+ 	int err;
+ 	struct ethtool_drvinfo drvinfo;
+@@ -4553,11 +4731,27 @@ static int do_getmodule(struct cmd_context *ctx)
+ 	int err;
+ 
+ 	struct cmdline_info cmdline_geeprom[] = {
+-		{ "offset", CMDL_U32, &geeprom_offset, NULL },
+-		{ "length", CMDL_U32, &geeprom_length, NULL,
+-		  0, &geeprom_length_seen },
+-		{ "raw", CMDL_BOOL, &geeprom_dump_raw, NULL },
+-		{ "hex", CMDL_BOOL, &geeprom_dump_hex, NULL },
++		{
++			.name		= "offset",
++			.type		= CMDL_U32,
++			.wanted_val	= &geeprom_offset,
++		},
++		{
++			.name		= "length",
++			.type		= CMDL_U32,
++			.wanted_val	= &geeprom_length,
++			.seen_val	= &geeprom_length_seen,
++		},
++		{
++			.name		= "raw",
++			.type		= CMDL_BOOL,
++			.wanted_val	= &geeprom_dump_raw,
++		},
++		{
++			.name		= "hex",
++			.type		= CMDL_BOOL,
++			.wanted_val	= &geeprom_dump_hex,
++		},
+ 	};
+ 
+ 	parse_generic_cmdline(ctx, &geeprom_changed,
+@@ -4669,10 +4863,30 @@ static int do_seee(struct cmd_context *ctx)
+ 	int change = -1, change2 = 0;
+ 	struct ethtool_eee eeecmd;
+ 	struct cmdline_info cmdline_eee[] = {
+-		{ "advertise",    CMDL_U32,  &adv_c,       &eeecmd.advertised },
+-		{ "tx-lpi",       CMDL_BOOL, &lpi_c,   &eeecmd.tx_lpi_enabled },
+-		{ "tx-timer",	  CMDL_U32,  &lpi_time_c, &eeecmd.tx_lpi_timer},
+-		{ "eee",	  CMDL_BOOL, &eee_c,	   &eeecmd.eee_enabled},
++		{
++			.name		= "advertise",
++			.type		= CMDL_U32,
++			.wanted_val	= &adv_c,
++			.ioctl_val	= &eeecmd.advertised,
++		},
++		{
++			.name		= "tx-lpi",
++			.type		= CMDL_BOOL,
++			.wanted_val	= &lpi_c,
++			.ioctl_val	= &eeecmd.tx_lpi_enabled,
++		},
++		{
++			.name		= "tx-timer",
++			.type		= CMDL_U32,
++			.wanted_val	= &lpi_time_c,
++			.ioctl_val	= &eeecmd.tx_lpi_timer,
++		},
++		{
++			.name		= "eee",
++			.type		= CMDL_BOOL,
++			.wanted_val	= &eee_c,
++			.ioctl_val	= &eeecmd.eee_enabled,
++		},
+ 	};
+ 
+ 	if (ctx->argc == 0)
+-- 
+2.26.2
+
diff --git a/SOURCES/0011-build-add-Wextra-to-default-CFLAGS.patch b/SOURCES/0011-build-add-Wextra-to-default-CFLAGS.patch
new file mode 100644
index 0000000..dc6330b
--- /dev/null
+++ b/SOURCES/0011-build-add-Wextra-to-default-CFLAGS.patch
@@ -0,0 +1,31 @@
+From 0d042007945d6fadb9b59ce8d01502575689067d Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Sun, 23 Aug 2020 21:40:42 +0200
+Subject: [PATCH 11/17] build: add -Wextra to default CFLAGS
+
+As a result of previous commits, ethtool source now builds with gcc
+versions 7-11 without any compiler warning with "-Wall -Wextra". Add
+"-Wextra" to default cflags to make sure that any new warnings are
+caught as early as possible.
+
+Suggested-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+(cherry picked from commit 257d90cd946699c0951b670576d2d63a12b92541)
+---
+ Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 2abb2742c335..099182e8d6ad 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,4 +1,4 @@
+-AM_CFLAGS = -Wall
++AM_CFLAGS = -Wall -Wextra
+ AM_CPPFLAGS = -I$(top_srcdir)/uapi
+ LDADD = -lm
+ 
+-- 
+2.26.2
+
diff --git a/SOURCES/0012-ioctl-only-memset-non-NULL-link-settings.patch b/SOURCES/0012-ioctl-only-memset-non-NULL-link-settings.patch
new file mode 100644
index 0000000..0dcf3a6
--- /dev/null
+++ b/SOURCES/0012-ioctl-only-memset-non-NULL-link-settings.patch
@@ -0,0 +1,42 @@
+From a4186edd5bcb44d3236852816c21752eb82e5039 Mon Sep 17 00:00:00 2001
+From: Hans-Christian Noren Egtvedt <hegtvedt@cisco.com>
+Date: Thu, 27 Aug 2020 11:50:33 +0200
+Subject: [PATCH 12/17] ioctl: only memset non-NULL link settings
+
+In commit bef780467fa ("ioctl: do not pass transceiver value back to
+kernel") a regression slipped in. If we have a kernel that does not
+support the ETHTOOL_xLINKSETTINGS API, then the do_ioctl_glinksettings()
+function will return a NULL pointer.
+
+Hence before memset'ing the pointer to zero we must first check it is
+valid, as NULL return is perfectly fine when running on old kernels.
+
+Fixes: bef780467fa7 ("ioctl: do not pass transceiver value back to kernel")
+Signed-off-by: Hans-Christian Noren Egtvedt <hegtvedt@cisco.com>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit cf12872ebe7d8fac2088e7d2cd5e2a0a5f03499d)
+---
+ ethtool.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/ethtool.c b/ethtool.c
+index e32a93b41088..606af3e6b48f 100644
+--- a/ethtool.c
++++ b/ethtool.c
+@@ -3048,10 +3048,11 @@ static int do_sset(struct cmd_context *ctx)
+ 		struct ethtool_link_usettings *link_usettings;
+ 
+ 		link_usettings = do_ioctl_glinksettings(ctx);
+-		memset(&link_usettings->deprecated, 0,
+-		       sizeof(link_usettings->deprecated));
+ 		if (link_usettings == NULL)
+ 			link_usettings = do_ioctl_gset(ctx);
++		else
++			memset(&link_usettings->deprecated, 0,
++			       sizeof(link_usettings->deprecated));
+ 		if (link_usettings == NULL) {
+ 			perror("Cannot get current device settings");
+ 			err = -1;
+-- 
+2.26.2
+
diff --git a/SOURCES/0013-netlink-mark-unused-function-parameters-of-non-netli.patch b/SOURCES/0013-netlink-mark-unused-function-parameters-of-non-netli.patch
new file mode 100644
index 0000000..8acc678
--- /dev/null
+++ b/SOURCES/0013-netlink-mark-unused-function-parameters-of-non-netli.patch
@@ -0,0 +1,44 @@
+From fd001f7b3e530afefe470db246e8fc299077329e Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Wed, 16 Sep 2020 18:48:20 +0200
+Subject: [PATCH 13/17] netlink: mark unused function parameters of non-netlink
+ stubs
+
+Recent compiler warning cleanup missed three unused parameters in versions
+of netlink_run_handler() and nl_monitor() used when netlink support is
+disabled (configure --disable-netlink).
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit eb5bd877ec5bd2a2d2b5e09fc90033be1a64c95a)
+---
+ netlink/extapi.h | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/netlink/extapi.h b/netlink/extapi.h
+index a35d5f2c0b26..4fee6a9c3a99 100644
+--- a/netlink/extapi.h
++++ b/netlink/extapi.h
+@@ -43,8 +43,9 @@ void nl_monitor_usage(void);
+ 
+ #else /* ETHTOOL_ENABLE_NETLINK */
+ 
+-static inline void netlink_run_handler(struct cmd_context *ctx,
+-				       nl_func_t nlfunc, bool no_fallback)
++static inline void netlink_run_handler(struct cmd_context *ctx __maybe_unused,
++				       nl_func_t nlfunc __maybe_unused,
++				       bool no_fallback)
+ {
+ 	if (no_fallback) {
+ 		fprintf(stderr,
+@@ -54,7 +55,7 @@ static inline void netlink_run_handler(struct cmd_context *ctx,
+ 	}
+ }
+ 
+-static inline int nl_monitor(struct cmd_context *ctx)
++static inline int nl_monitor(struct cmd_context *ctx __maybe_unused)
+ {
+ 	fprintf(stderr, "Netlink not supported by ethtool, option --monitor unsupported.\n");
+ 	return -EOPNOTSUPP;
+-- 
+2.26.2
+
diff --git a/SOURCES/0014-update-UAPI-header-copies.patch b/SOURCES/0014-update-UAPI-header-copies.patch
new file mode 100644
index 0000000..43c781d
--- /dev/null
+++ b/SOURCES/0014-update-UAPI-header-copies.patch
@@ -0,0 +1,490 @@
+From 708dee5555dc4849bc03038048b9b9d08404f18e Mon Sep 17 00:00:00 2001
+From: Jakub Kicinski <kuba@kernel.org>
+Date: Thu, 10 Sep 2020 12:09:14 -0700
+Subject: [PATCH 14/17] update UAPI header copies
+
+Update to kernel commit 4f6a5caf187f.
+
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 1be081a983c94ab2eaa81686fbb9bcd707a2bac6)
+---
+ uapi/linux/ethtool.h         |  17 +++
+ uapi/linux/ethtool_netlink.h |  55 +++++++++
+ uapi/linux/if_link.h         | 227 ++++++++++++++++++++++++++++++++---
+ uapi/linux/rtnetlink.h       |  46 +++----
+ 4 files changed, 305 insertions(+), 40 deletions(-)
+
+diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h
+index 6074caa2f220..355e718a99fd 100644
+--- a/uapi/linux/ethtool.h
++++ b/uapi/linux/ethtool.h
+@@ -597,6 +597,7 @@ struct ethtool_pauseparam {
+  * @ETH_SS_SOF_TIMESTAMPING: SOF_TIMESTAMPING_* flags
+  * @ETH_SS_TS_TX_TYPES: timestamping Tx types
+  * @ETH_SS_TS_RX_FILTERS: timestamping Rx filters
++ * @ETH_SS_UDP_TUNNEL_TYPES: UDP tunnel types
+  */
+ enum ethtool_stringset {
+ 	ETH_SS_TEST		= 0,
+@@ -614,6 +615,7 @@ enum ethtool_stringset {
+ 	ETH_SS_SOF_TIMESTAMPING,
+ 	ETH_SS_TS_TX_TYPES,
+ 	ETH_SS_TS_RX_FILTERS,
++	ETH_SS_UDP_TUNNEL_TYPES,
+ 
+ 	/* add new constants above here */
+ 	ETH_SS_COUNT
+@@ -1528,6 +1530,21 @@ enum ethtool_link_mode_bit_indices {
+ 	ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT	 = 72,
+ 	ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT	 = 73,
+ 	ETHTOOL_LINK_MODE_FEC_LLRS_BIT			 = 74,
++	ETHTOOL_LINK_MODE_100000baseKR_Full_BIT		 = 75,
++	ETHTOOL_LINK_MODE_100000baseSR_Full_BIT		 = 76,
++	ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT	 = 77,
++	ETHTOOL_LINK_MODE_100000baseCR_Full_BIT		 = 78,
++	ETHTOOL_LINK_MODE_100000baseDR_Full_BIT		 = 79,
++	ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT	 = 80,
++	ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT	 = 81,
++	ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT = 82,
++	ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT	 = 83,
++	ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT	 = 84,
++	ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT	 = 85,
++	ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT	 = 86,
++	ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT = 87,
++	ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT	 = 88,
++	ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT	 = 89,
+ 	/* must be last entry */
+ 	__ETHTOOL_LINK_MODE_MASK_NBITS
+ };
+diff --git a/uapi/linux/ethtool_netlink.h b/uapi/linux/ethtool_netlink.h
+index b18e7bc539f2..c1b4d67d35d1 100644
+--- a/uapi/linux/ethtool_netlink.h
++++ b/uapi/linux/ethtool_netlink.h
+@@ -41,6 +41,7 @@ enum {
+ 	ETHTOOL_MSG_TSINFO_GET,
+ 	ETHTOOL_MSG_CABLE_TEST_ACT,
+ 	ETHTOOL_MSG_CABLE_TEST_TDR_ACT,
++	ETHTOOL_MSG_TUNNEL_INFO_GET,
+ 
+ 	/* add new constants above here */
+ 	__ETHTOOL_MSG_USER_CNT,
+@@ -554,6 +555,60 @@ enum {
+ 	ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX = __ETHTOOL_A_CABLE_TEST_TDR_NTF_CNT - 1
+ };
+ 
++/* TUNNEL INFO */
++
++enum {
++	ETHTOOL_UDP_TUNNEL_TYPE_VXLAN,
++	ETHTOOL_UDP_TUNNEL_TYPE_GENEVE,
++	ETHTOOL_UDP_TUNNEL_TYPE_VXLAN_GPE,
++
++	__ETHTOOL_UDP_TUNNEL_TYPE_CNT
++};
++
++enum {
++	ETHTOOL_A_TUNNEL_UDP_ENTRY_UNSPEC,
++
++	ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT,		/* be16 */
++	ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE,		/* u32 */
++
++	/* add new constants above here */
++	__ETHTOOL_A_TUNNEL_UDP_ENTRY_CNT,
++	ETHTOOL_A_TUNNEL_UDP_ENTRY_MAX = (__ETHTOOL_A_TUNNEL_UDP_ENTRY_CNT - 1)
++};
++
++enum {
++	ETHTOOL_A_TUNNEL_UDP_TABLE_UNSPEC,
++
++	ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE,		/* u32 */
++	ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES,		/* bitset */
++	ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY,		/* nest - _UDP_ENTRY_* */
++
++	/* add new constants above here */
++	__ETHTOOL_A_TUNNEL_UDP_TABLE_CNT,
++	ETHTOOL_A_TUNNEL_UDP_TABLE_MAX = (__ETHTOOL_A_TUNNEL_UDP_TABLE_CNT - 1)
++};
++
++enum {
++	ETHTOOL_A_TUNNEL_UDP_UNSPEC,
++
++	ETHTOOL_A_TUNNEL_UDP_TABLE,			/* nest - _UDP_TABLE_* */
++
++	/* add new constants above here */
++	__ETHTOOL_A_TUNNEL_UDP_CNT,
++	ETHTOOL_A_TUNNEL_UDP_MAX = (__ETHTOOL_A_TUNNEL_UDP_CNT - 1)
++};
++
++enum {
++	ETHTOOL_A_TUNNEL_INFO_UNSPEC,
++	ETHTOOL_A_TUNNEL_INFO_HEADER,			/* nest - _A_HEADER_* */
++
++	ETHTOOL_A_TUNNEL_INFO_UDP_PORTS,		/* nest - _UDP_TABLE */
++
++	/* add new constants above here */
++	__ETHTOOL_A_TUNNEL_INFO_CNT,
++	ETHTOOL_A_TUNNEL_INFO_MAX = (__ETHTOOL_A_TUNNEL_INFO_CNT - 1)
++};
++
+ /* generic netlink info */
+ #define ETHTOOL_GENL_NAME "ethtool"
+ #define ETHTOOL_GENL_VERSION 1
+diff --git a/uapi/linux/if_link.h b/uapi/linux/if_link.h
+index a8901a39a345..9d96890f9742 100644
+--- a/uapi/linux/if_link.h
++++ b/uapi/linux/if_link.h
+@@ -40,26 +40,197 @@ struct rtnl_link_stats {
+ 	__u32	rx_nohandler;		/* dropped, no handler found	*/
+ };
+ 
+-/* The main device statistics structure */
++/**
++ * struct rtnl_link_stats64 - The main device statistics structure.
++ *
++ * @rx_packets: Number of good packets received by the interface.
++ *   For hardware interfaces counts all good packets received from the device
++ *   by the host, including packets which host had to drop at various stages
++ *   of processing (even in the driver).
++ *
++ * @tx_packets: Number of packets successfully transmitted.
++ *   For hardware interfaces counts packets which host was able to successfully
++ *   hand over to the device, which does not necessarily mean that packets
++ *   had been successfully transmitted out of the device, only that device
++ *   acknowledged it copied them out of host memory.
++ *
++ * @rx_bytes: Number of good received bytes, corresponding to @rx_packets.
++ *
++ *   For IEEE 802.3 devices should count the length of Ethernet Frames
++ *   excluding the FCS.
++ *
++ * @tx_bytes: Number of good transmitted bytes, corresponding to @tx_packets.
++ *
++ *   For IEEE 802.3 devices should count the length of Ethernet Frames
++ *   excluding the FCS.
++ *
++ * @rx_errors: Total number of bad packets received on this network device.
++ *   This counter must include events counted by @rx_length_errors,
++ *   @rx_crc_errors, @rx_frame_errors and other errors not otherwise
++ *   counted.
++ *
++ * @tx_errors: Total number of transmit problems.
++ *   This counter must include events counter by @tx_aborted_errors,
++ *   @tx_carrier_errors, @tx_fifo_errors, @tx_heartbeat_errors,
++ *   @tx_window_errors and other errors not otherwise counted.
++ *
++ * @rx_dropped: Number of packets received but not processed,
++ *   e.g. due to lack of resources or unsupported protocol.
++ *   For hardware interfaces this counter should not include packets
++ *   dropped by the device which are counted separately in
++ *   @rx_missed_errors (since procfs folds those two counters together).
++ *
++ * @tx_dropped: Number of packets dropped on their way to transmission,
++ *   e.g. due to lack of resources.
++ *
++ * @multicast: Multicast packets received.
++ *   For hardware interfaces this statistic is commonly calculated
++ *   at the device level (unlike @rx_packets) and therefore may include
++ *   packets which did not reach the host.
++ *
++ *   For IEEE 802.3 devices this counter may be equivalent to:
++ *
++ *    - 30.3.1.1.21 aMulticastFramesReceivedOK
++ *
++ * @collisions: Number of collisions during packet transmissions.
++ *
++ * @rx_length_errors: Number of packets dropped due to invalid length.
++ *   Part of aggregate "frame" errors in `/proc/net/dev`.
++ *
++ *   For IEEE 802.3 devices this counter should be equivalent to a sum
++ *   of the following attributes:
++ *
++ *    - 30.3.1.1.23 aInRangeLengthErrors
++ *    - 30.3.1.1.24 aOutOfRangeLengthField
++ *    - 30.3.1.1.25 aFrameTooLongErrors
++ *
++ * @rx_over_errors: Receiver FIFO overflow event counter.
++ *
++ *   Historically the count of overflow events. Such events may be
++ *   reported in the receive descriptors or via interrupts, and may
++ *   not correspond one-to-one with dropped packets.
++ *
++ *   The recommended interpretation for high speed interfaces is -
++ *   number of packets dropped because they did not fit into buffers
++ *   provided by the host, e.g. packets larger than MTU or next buffer
++ *   in the ring was not available for a scatter transfer.
++ *
++ *   Part of aggregate "frame" errors in `/proc/net/dev`.
++ *
++ *   This statistics was historically used interchangeably with
++ *   @rx_fifo_errors.
++ *
++ *   This statistic corresponds to hardware events and is not commonly used
++ *   on software devices.
++ *
++ * @rx_crc_errors: Number of packets received with a CRC error.
++ *   Part of aggregate "frame" errors in `/proc/net/dev`.
++ *
++ *   For IEEE 802.3 devices this counter must be equivalent to:
++ *
++ *    - 30.3.1.1.6 aFrameCheckSequenceErrors
++ *
++ * @rx_frame_errors: Receiver frame alignment errors.
++ *   Part of aggregate "frame" errors in `/proc/net/dev`.
++ *
++ *   For IEEE 802.3 devices this counter should be equivalent to:
++ *
++ *    - 30.3.1.1.7 aAlignmentErrors
++ *
++ * @rx_fifo_errors: Receiver FIFO error counter.
++ *
++ *   Historically the count of overflow events. Those events may be
++ *   reported in the receive descriptors or via interrupts, and may
++ *   not correspond one-to-one with dropped packets.
++ *
++ *   This statistics was used interchangeably with @rx_over_errors.
++ *   Not recommended for use in drivers for high speed interfaces.
++ *
++ *   This statistic is used on software devices, e.g. to count software
++ *   packet queue overflow (can) or sequencing errors (GRE).
++ *
++ * @rx_missed_errors: Count of packets missed by the host.
++ *   Folded into the "drop" counter in `/proc/net/dev`.
++ *
++ *   Counts number of packets dropped by the device due to lack
++ *   of buffer space. This usually indicates that the host interface
++ *   is slower than the network interface, or host is not keeping up
++ *   with the receive packet rate.
++ *
++ *   This statistic corresponds to hardware events and is not used
++ *   on software devices.
++ *
++ * @tx_aborted_errors:
++ *   Part of aggregate "carrier" errors in `/proc/net/dev`.
++ *   For IEEE 802.3 devices capable of half-duplex operation this counter
++ *   must be equivalent to:
++ *
++ *    - 30.3.1.1.11 aFramesAbortedDueToXSColls
++ *
++ *   High speed interfaces may use this counter as a general device
++ *   discard counter.
++ *
++ * @tx_carrier_errors: Number of frame transmission errors due to loss
++ *   of carrier during transmission.
++ *   Part of aggregate "carrier" errors in `/proc/net/dev`.
++ *
++ *   For IEEE 802.3 devices this counter must be equivalent to:
++ *
++ *    - 30.3.1.1.13 aCarrierSenseErrors
++ *
++ * @tx_fifo_errors: Number of frame transmission errors due to device
++ *   FIFO underrun / underflow. This condition occurs when the device
++ *   begins transmission of a frame but is unable to deliver the
++ *   entire frame to the transmitter in time for transmission.
++ *   Part of aggregate "carrier" errors in `/proc/net/dev`.
++ *
++ * @tx_heartbeat_errors: Number of Heartbeat / SQE Test errors for
++ *   old half-duplex Ethernet.
++ *   Part of aggregate "carrier" errors in `/proc/net/dev`.
++ *
++ *   For IEEE 802.3 devices possibly equivalent to:
++ *
++ *    - 30.3.2.1.4 aSQETestErrors
++ *
++ * @tx_window_errors: Number of frame transmission errors due
++ *   to late collisions (for Ethernet - after the first 64B of transmission).
++ *   Part of aggregate "carrier" errors in `/proc/net/dev`.
++ *
++ *   For IEEE 802.3 devices this counter must be equivalent to:
++ *
++ *    - 30.3.1.1.10 aLateCollisions
++ *
++ * @rx_compressed: Number of correctly received compressed packets.
++ *   This counters is only meaningful for interfaces which support
++ *   packet compression (e.g. CSLIP, PPP).
++ *
++ * @tx_compressed: Number of transmitted compressed packets.
++ *   This counters is only meaningful for interfaces which support
++ *   packet compression (e.g. CSLIP, PPP).
++ *
++ * @rx_nohandler: Number of packets received on the interface
++ *   but dropped by the networking stack because the device is
++ *   not designated to receive packets (e.g. backup link in a bond).
++ */
+ struct rtnl_link_stats64 {
+-	__u64	rx_packets;		/* total packets received	*/
+-	__u64	tx_packets;		/* total packets transmitted	*/
+-	__u64	rx_bytes;		/* total bytes received 	*/
+-	__u64	tx_bytes;		/* total bytes transmitted	*/
+-	__u64	rx_errors;		/* bad packets received		*/
+-	__u64	tx_errors;		/* packet transmit problems	*/
+-	__u64	rx_dropped;		/* no space in linux buffers	*/
+-	__u64	tx_dropped;		/* no space available in linux	*/
+-	__u64	multicast;		/* multicast packets received	*/
++	__u64	rx_packets;
++	__u64	tx_packets;
++	__u64	rx_bytes;
++	__u64	tx_bytes;
++	__u64	rx_errors;
++	__u64	tx_errors;
++	__u64	rx_dropped;
++	__u64	tx_dropped;
++	__u64	multicast;
+ 	__u64	collisions;
+ 
+ 	/* detailed rx_errors: */
+ 	__u64	rx_length_errors;
+-	__u64	rx_over_errors;		/* receiver ring buff overflow	*/
+-	__u64	rx_crc_errors;		/* recved pkt with crc error	*/
+-	__u64	rx_frame_errors;	/* recv'd frame alignment error */
+-	__u64	rx_fifo_errors;		/* recv'r fifo overrun		*/
+-	__u64	rx_missed_errors;	/* receiver missed packet	*/
++	__u64	rx_over_errors;
++	__u64	rx_crc_errors;
++	__u64	rx_frame_errors;
++	__u64	rx_fifo_errors;
++	__u64	rx_missed_errors;
+ 
+ 	/* detailed tx_errors */
+ 	__u64	tx_aborted_errors;
+@@ -71,8 +242,7 @@ struct rtnl_link_stats64 {
+ 	/* for cslip etc */
+ 	__u64	rx_compressed;
+ 	__u64	tx_compressed;
+-
+-	__u64	rx_nohandler;		/* dropped, no handler found	*/
++	__u64	rx_nohandler;
+ };
+ 
+ /* The struct should be in sync with struct ifmap */
+@@ -170,12 +340,22 @@ enum {
+ 	IFLA_PROP_LIST,
+ 	IFLA_ALT_IFNAME, /* Alternative ifname */
+ 	IFLA_PERM_ADDRESS,
++	IFLA_PROTO_DOWN_REASON,
+ 	__IFLA_MAX
+ };
+ 
+ 
+ #define IFLA_MAX (__IFLA_MAX - 1)
+ 
++enum {
++	IFLA_PROTO_DOWN_REASON_UNSPEC,
++	IFLA_PROTO_DOWN_REASON_MASK,	/* u32, mask for reason bits */
++	IFLA_PROTO_DOWN_REASON_VALUE,   /* u32, reason bit value */
++
++	__IFLA_PROTO_DOWN_REASON_CNT,
++	IFLA_PROTO_DOWN_REASON_MAX = __IFLA_PROTO_DOWN_REASON_CNT - 1
++};
++
+ /* backwards compatibility for userspace */
+ #define IFLA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
+ #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
+@@ -342,6 +522,7 @@ enum {
+ 	IFLA_BRPORT_ISOLATED,
+ 	IFLA_BRPORT_BACKUP_PORT,
+ 	IFLA_BRPORT_MRP_RING_OPEN,
++	IFLA_BRPORT_MRP_IN_OPEN,
+ 	__IFLA_BRPORT_MAX
+ };
+ #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
+@@ -904,7 +1085,14 @@ enum {
+ #define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
+ 
+ 
+-/* HSR section */
++/* HSR/PRP section, both uses same interface */
++
++/* Different redundancy protocols for hsr device */
++enum {
++	HSR_PROTOCOL_HSR,
++	HSR_PROTOCOL_PRP,
++	HSR_PROTOCOL_MAX,
++};
+ 
+ enum {
+ 	IFLA_HSR_UNSPEC,
+@@ -914,6 +1102,9 @@ enum {
+ 	IFLA_HSR_SUPERVISION_ADDR,	/* Supervision frame multicast addr */
+ 	IFLA_HSR_SEQ_NR,
+ 	IFLA_HSR_VERSION,		/* HSR version */
++	IFLA_HSR_PROTOCOL,		/* Indicate different protocol than
++					 * HSR. For example PRP.
++					 */
+ 	__IFLA_HSR_MAX,
+ };
+ 
+diff --git a/uapi/linux/rtnetlink.h b/uapi/linux/rtnetlink.h
+index bcb1ba4d0146..5ad84e663d01 100644
+--- a/uapi/linux/rtnetlink.h
++++ b/uapi/linux/rtnetlink.h
+@@ -257,12 +257,12 @@ enum {
+ 
+ /* rtm_protocol */
+ 
+-#define RTPROT_UNSPEC	0
+-#define RTPROT_REDIRECT	1	/* Route installed by ICMP redirects;
+-				   not used by current IPv4 */
+-#define RTPROT_KERNEL	2	/* Route installed by kernel		*/
+-#define RTPROT_BOOT	3	/* Route installed during boot		*/
+-#define RTPROT_STATIC	4	/* Route installed by administrator	*/
++#define RTPROT_UNSPEC		0
++#define RTPROT_REDIRECT		1	/* Route installed by ICMP redirects;
++					   not used by current IPv4 */
++#define RTPROT_KERNEL		2	/* Route installed by kernel		*/
++#define RTPROT_BOOT		3	/* Route installed during boot		*/
++#define RTPROT_STATIC		4	/* Route installed by administrator	*/
+ 
+ /* Values of protocol >= RTPROT_STATIC are not interpreted by kernel;
+    they are just passed from user and back as is.
+@@ -271,22 +271,23 @@ enum {
+    avoid conflicts.
+  */
+ 
+-#define RTPROT_GATED	8	/* Apparently, GateD */
+-#define RTPROT_RA	9	/* RDISC/ND router advertisements */
+-#define RTPROT_MRT	10	/* Merit MRT */
+-#define RTPROT_ZEBRA	11	/* Zebra */
+-#define RTPROT_BIRD	12	/* BIRD */
+-#define RTPROT_DNROUTED	13	/* DECnet routing daemon */
+-#define RTPROT_XORP	14	/* XORP */
+-#define RTPROT_NTK	15	/* Netsukuku */
+-#define RTPROT_DHCP	16      /* DHCP client */
+-#define RTPROT_MROUTED	17      /* Multicast daemon */
+-#define RTPROT_BABEL	42      /* Babel daemon */
+-#define RTPROT_BGP	186     /* BGP Routes */
+-#define RTPROT_ISIS	187     /* ISIS Routes */
+-#define RTPROT_OSPF	188     /* OSPF Routes */
+-#define RTPROT_RIP	189     /* RIP Routes */
+-#define RTPROT_EIGRP	192     /* EIGRP Routes */
++#define RTPROT_GATED		8	/* Apparently, GateD */
++#define RTPROT_RA		9	/* RDISC/ND router advertisements */
++#define RTPROT_MRT		10	/* Merit MRT */
++#define RTPROT_ZEBRA		11	/* Zebra */
++#define RTPROT_BIRD		12	/* BIRD */
++#define RTPROT_DNROUTED		13	/* DECnet routing daemon */
++#define RTPROT_XORP		14	/* XORP */
++#define RTPROT_NTK		15	/* Netsukuku */
++#define RTPROT_DHCP		16	/* DHCP client */
++#define RTPROT_MROUTED		17	/* Multicast daemon */
++#define RTPROT_KEEPALIVED	18	/* Keepalived daemon */
++#define RTPROT_BABEL		42	/* Babel daemon */
++#define RTPROT_BGP		186	/* BGP Routes */
++#define RTPROT_ISIS		187	/* ISIS Routes */
++#define RTPROT_OSPF		188	/* OSPF Routes */
++#define RTPROT_RIP		189	/* RIP Routes */
++#define RTPROT_EIGRP		192	/* EIGRP Routes */
+ 
+ /* rtm_scope
+ 
+@@ -775,6 +776,7 @@ enum {
+ #define RTEXT_FILTER_BRVLAN	(1 << 1)
+ #define RTEXT_FILTER_BRVLAN_COMPRESSED	(1 << 2)
+ #define	RTEXT_FILTER_SKIP_STATS	(1 << 3)
++#define RTEXT_FILTER_MRP	(1 << 4)
+ 
+ /* End of information exported to user level */
+ 
+-- 
+2.26.2
+
diff --git a/SOURCES/0015-update-link-mode-tables.patch b/SOURCES/0015-update-link-mode-tables.patch
new file mode 100644
index 0000000..d5e1c5d
--- /dev/null
+++ b/SOURCES/0015-update-link-mode-tables.patch
@@ -0,0 +1,158 @@
+From aefd1fcb99c1d64198f315a20e087888d7715632 Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Wed, 16 Sep 2020 23:12:18 +0200
+Subject: [PATCH 15/17] update link mode tables
+
+Update tables of link modes to cover all modes currently defined in uapi
+header:
+
+  - link_modes[] array in netlink/settings.c
+  - all_advertised_modes_bits[] array in ethtool.c
+  - table of modes and corresponding bit values in manual page
+
+In the manual page table, fix also whitespace and order inconsistencies.
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 63130d0b00040136629988a1170da93ae742ca51)
+---
+ ethtool.8.in       | 32 ++++++++++++++++++++++++++------
+ ethtool.c          | 24 ++++++++++++++++++++++--
+ netlink/settings.c | 15 +++++++++++++++
+ 3 files changed, 63 insertions(+), 8 deletions(-)
+
+diff --git a/ethtool.8.in b/ethtool.8.in
+index a50a4769895c..12866dc456cf 100644
+--- a/ethtool.8.in
++++ b/ethtool.8.in
+@@ -721,21 +721,21 @@ lB	l	lB.
+ 0x80000000000000000	100baseT1 Full
+ 0x010	1000baseT Half	(not supported by IEEE standards)
+ 0x020	1000baseT Full
+-0x100000000000000000	1000baseT1 Full
+ 0x20000	1000baseKX Full
+ 0x20000000000	1000baseX Full
+-0x800000000000	2500baseT Full
++0x100000000000000000	1000baseT1 Full
+ 0x8000	2500baseX Full	(not supported by IEEE standards)
++0x800000000000	2500baseT Full
+ 0x1000000000000	5000baseT Full
+ 0x1000	10000baseT Full
+ 0x40000	10000baseKX4 Full
+ 0x80000	10000baseKR Full
+ 0x100000	10000baseR_FEC
+-0x40000000000	10000baseCR  Full
+-0x80000000000	10000baseSR  Full
+-0x100000000000	10000baseLR  Full
++0x40000000000	10000baseCR Full
++0x80000000000	10000baseSR Full
++0x100000000000	10000baseLR Full
+ 0x200000000000	10000baseLRM Full
+-0x400000000000	10000baseER  Full
++0x400000000000	10000baseER Full
+ 0x200000	20000baseMLD2 Full	(not supported by IEEE standards)
+ 0x400000	20000baseKR2 Full	(not supported by IEEE standards)
+ 0x80000000	25000baseCR Full
+@@ -766,11 +766,31 @@ lB	l	lB.
+ 0x800000000000000	100000baseCR2 Full
+ 0x1000000000000000	100000baseLR2_ER2_FR2 Full
+ 0x2000000000000000	100000baseDR2 Full
++0x8000000000000000000	100000baseKR Full
++0x10000000000000000000	100000baseSR Full
++0x20000000000000000000	100000baseLR_ER_FR Full
++0x40000000000000000000	100000baseCR Full
++0x80000000000000000000	100000baseDR Full
+ 0x4000000000000000	200000baseKR4 Full
+ 0x8000000000000000	200000baseSR4 Full
+ 0x10000000000000000	200000baseLR4_ER4_FR4 Full
+ 0x20000000000000000	200000baseDR4 Full
+ 0x40000000000000000	200000baseCR4 Full
++0x100000000000000000000	200000baseKR2 Full
++0x200000000000000000000	200000baseSR2 Full
++0x400000000000000000000	200000baseLR2_ER2_FR2 Full
++0x800000000000000000000	200000baseDR2 Full
++0x1000000000000000000000	200000baseCR2 Full
++0x200000000000000000	400000baseKR8 Full
++0x400000000000000000	400000baseSR8 Full
++0x800000000000000000	400000baseLR8_ER8_FR8 Full
++0x1000000000000000000	400000baseDR8 Full
++0x2000000000000000000	400000baseCR8 Full
++0x2000000000000000000000	400000baseKR4 Full
++0x4000000000000000000000	400000baseSR4 Full
++0x8000000000000000000000	400000baseLR4_ER4_FR4 Full
++0x10000000000000000000000	400000baseDR4 Full
++0x20000000000000000000000	400000baseCR4 Full
+ .TE
+ .TP
+ .BI phyad \ N
+diff --git a/ethtool.c b/ethtool.c
+index 606af3e6b48f..2e24e98187d2 100644
+--- a/ethtool.c
++++ b/ethtool.c
+@@ -392,9 +392,9 @@ static void init_global_link_mode_masks(void)
+ 		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_2500baseX_Full_BIT,
++		ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+ 		ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
+ 		ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+ 		ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
+@@ -443,6 +443,26 @@ static void init_global_link_mode_masks(void)
+ 		ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT,
+ 		ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
+ 		ETHTOOL_LINK_MODE_1000baseT1_Full_BIT,
++		ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT,
++		ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT,
++		ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT,
++		ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT,
++		ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT,
++		ETHTOOL_LINK_MODE_100000baseKR_Full_BIT,
++		ETHTOOL_LINK_MODE_100000baseSR_Full_BIT,
++		ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT,
++		ETHTOOL_LINK_MODE_100000baseCR_Full_BIT,
++		ETHTOOL_LINK_MODE_100000baseDR_Full_BIT,
++		ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT,
++		ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT,
++		ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT,
++		ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT,
++		ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT,
++		ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT,
++		ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT,
++		ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT,
++		ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT,
++		ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT,
+ 	};
+ 	static const enum ethtool_link_mode_bit_indices
+ 		additional_advertised_flags_bits[] = {
+diff --git a/netlink/settings.c b/netlink/settings.c
+index d1da995b434c..3a9518a7e12b 100644
+--- a/netlink/settings.c
++++ b/netlink/settings.c
+@@ -147,6 +147,21 @@ static const struct link_mode_info link_modes[] = {
+ 	[ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT]	= __REAL(400000),
+ 	[ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT]	= __REAL(400000),
+ 	[ETHTOOL_LINK_MODE_FEC_LLRS_BIT]		= __SPECIAL(FEC),
++	[ETHTOOL_LINK_MODE_100000baseKR_Full_BIT]	= __REAL(100000),
++	[ETHTOOL_LINK_MODE_100000baseSR_Full_BIT]	= __REAL(100000),
++	[ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT]	= __REAL(100000),
++	[ETHTOOL_LINK_MODE_100000baseCR_Full_BIT]	= __REAL(100000),
++	[ETHTOOL_LINK_MODE_100000baseDR_Full_BIT]	= __REAL(100000),
++	[ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT]	= __REAL(200000),
++	[ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT]	= __REAL(200000),
++	[ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT] = __REAL(200000),
++	[ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT]	= __REAL(200000),
++	[ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT]	= __REAL(200000),
++	[ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT]	= __REAL(400000),
++	[ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT]	= __REAL(400000),
++	[ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT] = __REAL(400000),
++	[ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT]	= __REAL(400000),
++	[ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT]	= __REAL(400000),
+ };
+ const unsigned int link_modes_count = ARRAY_SIZE(link_modes);
+ 
+-- 
+2.26.2
+
diff --git a/SOURCES/0016-netlink-return-ENOMEM-when-calloc-fails.patch b/SOURCES/0016-netlink-return-ENOMEM-when-calloc-fails.patch
new file mode 100644
index 0000000..6140036
--- /dev/null
+++ b/SOURCES/0016-netlink-return-ENOMEM-when-calloc-fails.patch
@@ -0,0 +1,50 @@
+From d0362097e60d227bac4f66a06891ee1d807d2c48 Mon Sep 17 00:00:00 2001
+From: Ivan Vecera <cera@cera.cz>
+Date: Thu, 24 Sep 2020 19:51:47 +0200
+Subject: [PATCH 16/17] netlink: return -ENOMEM when calloc fails
+
+Fixes: f2c17e107900 ("netlink: add netlink handler for gfeatures (-k)")
+
+Cc: Michal Kubecek <mkubecek@suse.cz>
+Signed-off-by: Ivan Vecera <cera@cera.cz>
+---
+ netlink/features.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/netlink/features.c b/netlink/features.c
+index 3f1240437350..b2cf57eea660 100644
+--- a/netlink/features.c
++++ b/netlink/features.c
+@@ -112,16 +112,17 @@ int dump_features(const struct nlattr *const *tb,
+ 	unsigned int *feature_flags = NULL;
+ 	struct feature_results results;
+ 	unsigned int i, j;
+-	int ret;
++	int ret = 0;
+ 
+ 	ret = prepare_feature_results(tb, &results);
+ 	if (ret < 0)
+ 		return -EFAULT;
+ 
+-	ret = -ENOMEM;
+ 	feature_flags = calloc(results.count, sizeof(feature_flags[0]));
+-	if (!feature_flags)
++	if (!feature_flags) {
++		ret = -ENOMEM;
+ 		goto out_free;
++	}
+ 
+ 	/* map netdev features to legacy flags */
+ 	for (i = 0; i < results.count; i++) {
+@@ -184,7 +185,7 @@ int dump_features(const struct nlattr *const *tb,
+ 
+ out_free:
+ 	free(feature_flags);
+-	return 0;
++	return ret;
+ }
+ 
+ int features_reply_cb(const struct nlmsghdr *nlhdr, void *data)
+-- 
+2.26.2
+
diff --git a/SOURCES/0017-netlink-fix-memory-leak.patch b/SOURCES/0017-netlink-fix-memory-leak.patch
new file mode 100644
index 0000000..306bd38
--- /dev/null
+++ b/SOURCES/0017-netlink-fix-memory-leak.patch
@@ -0,0 +1,35 @@
+From f1bb0c6263ca11bedea9e18bc9753c6b1d4c924d Mon Sep 17 00:00:00 2001
+From: Ivan Vecera <cera@cera.cz>
+Date: Thu, 24 Sep 2020 20:10:31 +0200
+Subject: [PATCH 17/17] netlink: fix memory leak
+
+Potentially allocated memory allocated for mask is not freed when
+the allocation for value fails.
+
+Fixes: 81a30f416ec7 ("netlink: add bitset command line parser handlers")
+
+Cc: Michal Kubecek <mkubecek@suse.cz>
+Signed-off-by: Ivan Vecera <cera@cera.cz>
+---
+ netlink/parser.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/netlink/parser.c b/netlink/parser.c
+index c5a368a65a7a..3b25f5d5a88e 100644
+--- a/netlink/parser.c
++++ b/netlink/parser.c
+@@ -630,8 +630,10 @@ static int parse_numeric_bitset(struct nl_context *nlctx, uint16_t type,
+ 	}
+ 
+ 	value = calloc(nwords, sizeof(uint32_t));
+-	if (!value)
++	if (!value) {
++		free(mask);
+ 		return -ENOMEM;
++	}
+ 	ret = __parse_num_string(arg, len1, value, force_hex1);
+ 	if (ret < 0) {
+ 		parser_err_invalid_value(nlctx, arg);
+-- 
+2.26.2
+
diff --git a/SOURCES/0018-fix-memory-leaks-in-do_sfeatures.patch b/SOURCES/0018-fix-memory-leaks-in-do_sfeatures.patch
new file mode 100644
index 0000000..6fa5fcc
--- /dev/null
+++ b/SOURCES/0018-fix-memory-leaks-in-do_sfeatures.patch
@@ -0,0 +1,60 @@
+From 78b5b29e6cf286ce687e7b4d42745fb06cfb2353 Mon Sep 17 00:00:00 2001
+From: Ivan Vecera <ivecera@redhat.com>
+Date: Fri, 25 Sep 2020 08:39:16 +0200
+Subject: [PATCH 18/19] fix memory leaks in do_sfeatures()
+
+Memory blocks referenced by new_state and old_state are never freed.
+For efeatures there is no need to check pointer as free() can be called
+with NULL parameter.
+
+Fixes: 6042804cf6ec ("Change -k/-K options to use ETHTOOL_{G,S}FEATURES")
+
+Cc: Michal Kubecek <mkubecek@suse.cz>
+Signed-off-by: Ivan Vecera <ivecera@redhat.com>
+---
+ ethtool.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/ethtool.c b/ethtool.c
+index 2e24e98187d2..32ef80add923 100644
+--- a/ethtool.c
++++ b/ethtool.c
+@@ -2392,9 +2392,10 @@ 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 feature_state *old_state = NULL;
++	struct feature_state *new_state = NULL;
+ 	struct cmdline_info *cmdline_features;
+-	struct feature_state *old_state, *new_state;
+ 	struct ethtool_value eval;
+ 	unsigned int i, j;
+ 	int err, rc;
+@@ -2418,8 +2419,6 @@ static int do_sfeatures(struct cmd_context *ctx)
+ 		memset(efeatures->features, 0,
+ 		       FEATURE_BITS_TO_BLOCKS(defs->n_features) *
+ 		       sizeof(efeatures->features[0]));
+-	} else {
+-		efeatures = NULL;
+ 	}
+ 
+ 	/* Generate cmdline_info for legacy flags and kernel-named
+@@ -2578,9 +2577,11 @@ static int do_sfeatures(struct cmd_context *ctx)
+ 	rc = 0;
+ 
+ err:
++	free(new_state);
++	free(old_state);
+ 	free(defs);
+-	if (efeatures)
+-		free(efeatures);
++	free(efeatures);
++
+ 	return rc;
+ }
+ 
+-- 
+2.26.2
+
diff --git a/SOURCES/0019-netlink-fix-copy-paste-error-in-rtm_link_summary.patch b/SOURCES/0019-netlink-fix-copy-paste-error-in-rtm_link_summary.patch
new file mode 100644
index 0000000..7542e7f
--- /dev/null
+++ b/SOURCES/0019-netlink-fix-copy-paste-error-in-rtm_link_summary.patch
@@ -0,0 +1,29 @@
+From d76260a0c91c0590f9c82a2771fd10f40b8c81fd Mon Sep 17 00:00:00 2001
+From: Ivan Vecera <ivecera@redhat.com>
+Date: Fri, 25 Sep 2020 09:03:57 +0200
+Subject: [PATCH 19/19] netlink: fix copy-paste error in rtm_link_summary()
+
+Fixes: bdfffab54933 ("netlink: message format descriptions for rtnetlink")
+
+Cc: Michal Kubecek <mkubecek@suse.cz>
+Signed-off-by: Ivan Vecera <ivecera@redhat.com>
+---
+ netlink/prettymsg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/netlink/prettymsg.c b/netlink/prettymsg.c
+index 9e62bebe615e..f992dcaf071f 100644
+--- a/netlink/prettymsg.c
++++ b/netlink/prettymsg.c
+@@ -202,7 +202,7 @@ static void rtm_link_summary(const struct ifinfomsg *ifinfo)
+ 		printf(" ifindex=%d", ifinfo->ifi_index);
+ 	if (ifinfo->ifi_flags)
+ 		printf(" flags=0x%x", ifinfo->ifi_flags);
+-	if (ifinfo->ifi_flags)
++	if (ifinfo->ifi_change)
+ 		printf(" change=0x%x", ifinfo->ifi_change);
+ }
+ 
+-- 
+2.26.2
+
diff --git a/SPECS/ethtool.spec b/SPECS/ethtool.spec
index 35abbf5..2ad4bbd 100644
--- a/SPECS/ethtool.spec
+++ b/SPECS/ethtool.spec
@@ -1,12 +1,31 @@
 Name:		ethtool
 Epoch:		2
 Version:	5.8
-Release:	1%{?dist}
+Release:	3%{?dist}
 Summary:	Settings tool for Ethernet NICs
 License:	GPLv2
 Group:		Applications/System
 URL:		https://www.kernel.org/pub/software/network/%{name}/
 Source0:	https://www.kernel.org/pub/software/network/%{name}/%{name}-%{version}.tar.xz
+Patch1:		0001-netlink-Fix-the-condition-for-displaying-actual-chan.patch
+Patch2:		0002-netlink-Print-and-return-an-error-when-features-were.patch
+Patch3:		0003-netlink-get-rid-of-signed-unsigned-comparison-warnin.patch
+Patch4:		0004-ioctl-check-presence-of-eeprom-length-argument-prope.patch
+Patch5:		0005-ioctl-prevent-argc-underflow-in-do_perqueue.patch
+Patch6:		0006-ioctl-make-argc-counters-unsigned.patch
+Patch7:		0007-ioctl-get-rid-of-signed-unsigned-comparison-warnings.patch
+Patch8:		0008-get-rid-of-signed-unsigned-comparison-warnings-in-re.patch
+Patch9:		0009-settings-simplify-link_mode_info-initializers.patch
+Patch10:	0010-ioctl-convert-cmdline_info-arrays-to-named-initializ.patch
+Patch11:	0011-build-add-Wextra-to-default-CFLAGS.patch
+Patch12:	0012-ioctl-only-memset-non-NULL-link-settings.patch
+Patch13:	0013-netlink-mark-unused-function-parameters-of-non-netli.patch
+Patch14:	0014-update-UAPI-header-copies.patch
+Patch15:	0015-update-link-mode-tables.patch
+Patch16:	0016-netlink-return-ENOMEM-when-calloc-fails.patch
+Patch17:	0017-netlink-fix-memory-leak.patch
+Patch18:	0018-fix-memory-leaks-in-do_sfeatures.patch
+Patch19:	0019-netlink-fix-copy-paste-error-in-rtm_link_summary.patch
 BuildRequires:	libmnl-devel
 Conflicts:	filesystem < 3
 
@@ -17,6 +36,25 @@ network devices, especially of Ethernet devices.
 
 %prep
 %setup -q
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
 
 %build
 %configure
@@ -33,6 +71,12 @@ make DESTDIR=%{buildroot} INSTALL='install -p' install
 %{_datadir}/bash-completion/completions/ethtool
 
 %changelog
+* Fri Sep 25 2020 Ivan Vecera <ivecera@redhat.com> - 2:5.8-3
+- Fixed memory leak
+
+* Thu Sep 24 2020 Ivan Vecera <ivecera@redhat.com> - 2:5.8-2
+- Add post-5.8 bugfixes
+
 * Tue Sep 15 2020 Ivan Vecera <ivecera@redhat.com> - 2:5.8-1
 - Update to 5.8 (#1878826)