diff --git a/SOURCES/0027-update-UAPI-header-copies.patch b/SOURCES/0027-update-UAPI-header-copies.patch
new file mode 100644
index 0000000..4159a4a
--- /dev/null
+++ b/SOURCES/0027-update-UAPI-header-copies.patch
@@ -0,0 +1,135 @@
+From 43ffee8b0530b0ee0458ba9c0cf651cc77201ba0 Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Mon, 28 Sep 2020 16:55:49 +0200
+Subject: [PATCH 27/37] update UAPI header copies
+
+Update to kernel commit 0675c285ea65.
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 0cd0742eab2edd702306da79ddee48644ebe0c9a)
+---
+ uapi/linux/ethtool.h         |  2 ++
+ uapi/linux/ethtool_netlink.h | 19 ++++++++++++++++++-
+ uapi/linux/if_link.h         | 31 +++++++++++++++----------------
+ 3 files changed, 35 insertions(+), 17 deletions(-)
+
+diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h
+index 847ccd0b1fce..052689bcc90c 100644
+--- a/uapi/linux/ethtool.h
++++ b/uapi/linux/ethtool.h
+@@ -1615,6 +1615,8 @@ enum ethtool_link_mode_bit_indices {
+ 	ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT = 87,
+ 	ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT	 = 88,
+ 	ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT	 = 89,
++	ETHTOOL_LINK_MODE_100baseFX_Half_BIT		 = 90,
++	ETHTOOL_LINK_MODE_100baseFX_Full_BIT		 = 91,
+ 	/* must be last entry */
+ 	__ETHTOOL_LINK_MODE_MASK_NBITS
+ };
+diff --git a/uapi/linux/ethtool_netlink.h b/uapi/linux/ethtool_netlink.h
+index cebdb52e6a05..c022883cdb22 100644
+--- a/uapi/linux/ethtool_netlink.h
++++ b/uapi/linux/ethtool_netlink.h
+@@ -79,6 +79,7 @@ enum {
+ 	ETHTOOL_MSG_TSINFO_GET_REPLY,
+ 	ETHTOOL_MSG_CABLE_TEST_NTF,
+ 	ETHTOOL_MSG_CABLE_TEST_TDR_NTF,
++	ETHTOOL_MSG_TUNNEL_INFO_GET_REPLY,
+ 
+ 	/* add new constants above here */
+ 	__ETHTOOL_MSG_KERNEL_CNT,
+@@ -91,9 +92,12 @@ enum {
+ #define ETHTOOL_FLAG_COMPACT_BITSETS	(1 << 0)
+ /* provide optional reply for SET or ACT requests */
+ #define ETHTOOL_FLAG_OMIT_REPLY	(1 << 1)
++/* request statistics, if supported by the driver */
++#define ETHTOOL_FLAG_STATS		(1 << 2)
+ 
+ #define ETHTOOL_FLAG_ALL (ETHTOOL_FLAG_COMPACT_BITSETS | \
+-			  ETHTOOL_FLAG_OMIT_REPLY)
++			  ETHTOOL_FLAG_OMIT_REPLY | \
++			  ETHTOOL_FLAG_STATS)
+ 
+ enum {
+ 	ETHTOOL_A_HEADER_UNSPEC,
+@@ -376,12 +380,25 @@ enum {
+ 	ETHTOOL_A_PAUSE_AUTONEG,			/* u8 */
+ 	ETHTOOL_A_PAUSE_RX,				/* u8 */
+ 	ETHTOOL_A_PAUSE_TX,				/* u8 */
++	ETHTOOL_A_PAUSE_STATS,				/* nest - _PAUSE_STAT_* */
+ 
+ 	/* add new constants above here */
+ 	__ETHTOOL_A_PAUSE_CNT,
+ 	ETHTOOL_A_PAUSE_MAX = (__ETHTOOL_A_PAUSE_CNT - 1)
+ };
+ 
++enum {
++	ETHTOOL_A_PAUSE_STAT_UNSPEC,
++	ETHTOOL_A_PAUSE_STAT_PAD,
++
++	ETHTOOL_A_PAUSE_STAT_TX_FRAMES,
++	ETHTOOL_A_PAUSE_STAT_RX_FRAMES,
++
++	/* add new constants above here */
++	__ETHTOOL_A_PAUSE_STAT_CNT,
++	ETHTOOL_A_PAUSE_STAT_MAX = (__ETHTOOL_A_PAUSE_STAT_CNT - 1)
++};
++
+ /* EEE */
+ 
+ enum {
+diff --git a/uapi/linux/if_link.h b/uapi/linux/if_link.h
+index 9d96890f9742..307e5c245e9f 100644
+--- a/uapi/linux/if_link.h
++++ b/uapi/linux/if_link.h
+@@ -7,24 +7,23 @@
+ 
+ /* This struct should be in sync with struct rtnl_link_stats64 */
+ struct rtnl_link_stats {
+-	__u32	rx_packets;		/* total packets received	*/
+-	__u32	tx_packets;		/* total packets transmitted	*/
+-	__u32	rx_bytes;		/* total bytes received 	*/
+-	__u32	tx_bytes;		/* total bytes transmitted	*/
+-	__u32	rx_errors;		/* bad packets received		*/
+-	__u32	tx_errors;		/* packet transmit problems	*/
+-	__u32	rx_dropped;		/* no space in linux buffers	*/
+-	__u32	tx_dropped;		/* no space available in linux	*/
+-	__u32	multicast;		/* multicast packets received	*/
++	__u32	rx_packets;
++	__u32	tx_packets;
++	__u32	rx_bytes;
++	__u32	tx_bytes;
++	__u32	rx_errors;
++	__u32	tx_errors;
++	__u32	rx_dropped;
++	__u32	tx_dropped;
++	__u32	multicast;
+ 	__u32	collisions;
+-
+ 	/* detailed rx_errors: */
+ 	__u32	rx_length_errors;
+-	__u32	rx_over_errors;		/* receiver ring buff overflow	*/
+-	__u32	rx_crc_errors;		/* recved pkt with crc error	*/
+-	__u32	rx_frame_errors;	/* recv'd frame alignment error */
+-	__u32	rx_fifo_errors;		/* recv'r fifo overrun		*/
+-	__u32	rx_missed_errors;	/* receiver missed packet	*/
++	__u32	rx_over_errors;
++	__u32	rx_crc_errors;
++	__u32	rx_frame_errors;
++	__u32	rx_fifo_errors;
++	__u32	rx_missed_errors;
+ 
+ 	/* detailed tx_errors */
+ 	__u32	tx_aborted_errors;
+@@ -37,7 +36,7 @@ struct rtnl_link_stats {
+ 	__u32	rx_compressed;
+ 	__u32	tx_compressed;
+ 
+-	__u32	rx_nohandler;		/* dropped, no handler found	*/
++	__u32	rx_nohandler;
+ };
+ 
+ /**
+-- 
+2.26.2
+
diff --git a/SOURCES/0028-update-UAPI-header-copies.patch b/SOURCES/0028-update-UAPI-header-copies.patch
new file mode 100644
index 0000000..ad113ea
--- /dev/null
+++ b/SOURCES/0028-update-UAPI-header-copies.patch
@@ -0,0 +1,83 @@
+From 526176cf61c011c2b63d7b9d86581f54f60e55cd Mon Sep 17 00:00:00 2001
+From: Jakub Kicinski <kuba@kernel.org>
+Date: Sun, 18 Oct 2020 14:31:45 -0700
+Subject: [PATCH 28/37] update UAPI header copies
+
+Update to kernel commit 9453b2d4694c.
+
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 77613ca972ac37f11477539be8d2b604972e9c18)
+---
+ uapi/linux/genetlink.h | 11 +++++++++++
+ uapi/linux/netlink.h   |  4 ++++
+ 2 files changed, 15 insertions(+)
+
+diff --git a/uapi/linux/genetlink.h b/uapi/linux/genetlink.h
+index 7c6c390c48ee..9fa720ee87ae 100644
+--- a/uapi/linux/genetlink.h
++++ b/uapi/linux/genetlink.h
+@@ -64,6 +64,8 @@ enum {
+ 	CTRL_ATTR_OPS,
+ 	CTRL_ATTR_MCAST_GROUPS,
+ 	CTRL_ATTR_POLICY,
++	CTRL_ATTR_OP_POLICY,
++	CTRL_ATTR_OP,
+ 	__CTRL_ATTR_MAX,
+ };
+ 
+@@ -85,6 +87,15 @@ enum {
+ 	__CTRL_ATTR_MCAST_GRP_MAX,
+ };
+ 
++enum {
++	CTRL_ATTR_POLICY_UNSPEC,
++	CTRL_ATTR_POLICY_DO,
++	CTRL_ATTR_POLICY_DUMP,
++
++	__CTRL_ATTR_POLICY_DUMP_MAX,
++	CTRL_ATTR_POLICY_DUMP_MAX = __CTRL_ATTR_POLICY_DUMP_MAX - 1
++};
++
+ #define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1)
+ 
+ 
+diff --git a/uapi/linux/netlink.h b/uapi/linux/netlink.h
+index 695c88e3c29d..dfef006be9f9 100644
+--- a/uapi/linux/netlink.h
++++ b/uapi/linux/netlink.h
+@@ -129,6 +129,7 @@ struct nlmsgerr {
+  * @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to
+  *	be used - in the success case - to identify a created
+  *	object or operation or similar (binary)
++ * @NLMSGERR_ATTR_POLICY: policy for a rejected attribute
+  * @__NLMSGERR_ATTR_MAX: number of attributes
+  * @NLMSGERR_ATTR_MAX: highest attribute number
+  */
+@@ -137,6 +138,7 @@ enum nlmsgerr_attrs {
+ 	NLMSGERR_ATTR_MSG,
+ 	NLMSGERR_ATTR_OFFS,
+ 	NLMSGERR_ATTR_COOKIE,
++	NLMSGERR_ATTR_POLICY,
+ 
+ 	__NLMSGERR_ATTR_MAX,
+ 	NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1
+@@ -327,6 +329,7 @@ enum netlink_attribute_type {
+  *	the index, if limited inside the nesting (U32)
+  * @NL_POLICY_TYPE_ATTR_BITFIELD32_MASK: valid mask for the
+  *	bitfield32 type (U32)
++ * @NL_POLICY_TYPE_ATTR_MASK: mask of valid bits for unsigned integers (U64)
+  * @NL_POLICY_TYPE_ATTR_PAD: pad attribute for 64-bit alignment
+  */
+ enum netlink_policy_type_attr {
+@@ -342,6 +345,7 @@ enum netlink_policy_type_attr {
+ 	NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE,
+ 	NL_POLICY_TYPE_ATTR_BITFIELD32_MASK,
+ 	NL_POLICY_TYPE_ATTR_PAD,
++	NL_POLICY_TYPE_ATTR_MASK,
+ 
+ 	/* keep last */
+ 	__NL_POLICY_TYPE_ATTR_MAX,
+-- 
+2.26.2
+
diff --git a/SOURCES/0029-pause-add-json-support.patch b/SOURCES/0029-pause-add-json-support.patch
new file mode 100644
index 0000000..44432e0
--- /dev/null
+++ b/SOURCES/0029-pause-add-json-support.patch
@@ -0,0 +1,183 @@
+From 7bb75228e6849f3371cd434cf36d29f406db1ccc Mon Sep 17 00:00:00 2001
+From: Jakub Kicinski <kuba@kernel.org>
+Date: Sun, 18 Oct 2020 14:31:46 -0700
+Subject: [PATCH 29/37] pause: add --json support
+
+No change in normal text output:
+
+ # ./ethtool  -a eth0
+Pause parameters for eth0:
+Autonegotiate:	on
+RX:		on
+TX:		on
+RX negotiated: on
+TX negotiated: on
+
+JSON:
+
+ # ./ethtool --json -a eth0
+[ {
+        "ifname": "eth0",
+        "autonegotiate": true,
+        "rx": true,
+        "tx": true,
+        "negotiated": {
+            "rx": true,
+            "tx": true
+        }
+    } ]
+
+v2:
+ - restructure show_bool() so we can use its logic for show_bool_val()
+
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 7e5c1ddbe67d0eefe9004e9a69f2ea5378e3bc5e)
+---
+ netlink/coalesce.c |  6 +++---
+ netlink/netlink.h  | 21 ++++++++++++++++-----
+ netlink/pause.c    | 44 ++++++++++++++++++++++++++++++++------------
+ 3 files changed, 51 insertions(+), 20 deletions(-)
+
+diff --git a/netlink/coalesce.c b/netlink/coalesce.c
+index 0223f8e3484e..75922a91c2e7 100644
+--- a/netlink/coalesce.c
++++ b/netlink/coalesce.c
+@@ -36,9 +36,9 @@ int coalesce_reply_cb(const struct nlmsghdr *nlhdr, void *data)
+ 	if (silent)
+ 		putchar('\n');
+ 	printf("Coalesce parameters for %s:\n", nlctx->devname);
+-	printf("Adaptive RX: %s  TX: %s\n",
+-	       u8_to_bool(tb[ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX]),
+-	       u8_to_bool(tb[ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX]));
++	show_bool("rx", "Adaptive RX: %s  ",
++		  tb[ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX]);
++	show_bool("tx", "TX: %s\n", tb[ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX]);
+ 	show_u32(tb[ETHTOOL_A_COALESCE_STATS_BLOCK_USECS],
+ 		 "stats-block-usecs: ");
+ 	show_u32(tb[ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL],
+diff --git a/netlink/netlink.h b/netlink/netlink.h
+index 61a072db8ed9..e79143016bd5 100644
+--- a/netlink/netlink.h
++++ b/netlink/netlink.h
+@@ -102,17 +102,28 @@ static inline void show_u32(const struct nlattr *attr, const char *label)
+ 		printf("%sn/a\n", label);
+ }
+ 
+-static inline const char *u8_to_bool(const struct nlattr *attr)
++static inline const char *u8_to_bool(const uint8_t *val)
+ {
+-	if (attr)
+-		return mnl_attr_get_u8(attr) ? "on" : "off";
++	if (val)
++		return *val ? "on" : "off";
+ 	else
+ 		return "n/a";
+ }
+ 
+-static inline void show_bool(const struct nlattr *attr, const char *label)
++static inline void show_bool_val(const char *key, const char *fmt, uint8_t *val)
++{
++	if (is_json_context()) {
++		if (val)
++			print_bool(PRINT_JSON, key, NULL, val);
++	} else {
++		print_string(PRINT_FP, NULL, fmt, u8_to_bool(val));
++	}
++}
++
++static inline void show_bool(const char *key, const char *fmt,
++			     const struct nlattr *attr)
+ {
+-	printf("%s%s\n", label, u8_to_bool(attr));
++	show_bool_val(key, fmt, attr ? mnl_attr_get_payload(attr) : NULL);
+ }
+ 
+ /* misc */
+diff --git a/netlink/pause.c b/netlink/pause.c
+index 048320b123d2..c54488d71fce 100644
+--- a/netlink/pause.c
++++ b/netlink/pause.c
+@@ -40,8 +40,8 @@ static int pause_autoneg_cb(const struct nlmsghdr *nlhdr, void *data)
+ 	struct pause_autoneg_status ours = {};
+ 	struct pause_autoneg_status peer = {};
+ 	struct nl_context *nlctx = data;
+-	bool rx_status = false;
+-	bool tx_status = false;
++	uint8_t rx_status = false;
++	uint8_t tx_status = false;
+ 	bool silent;
+ 	int err_ret;
+ 	int ret;
+@@ -72,8 +72,11 @@ static int pause_autoneg_cb(const struct nlmsghdr *nlhdr, void *data)
+ 		else if (peer.pause)
+ 			tx_status = true;
+ 	}
+-	printf("RX negotiated: %s\nTX negotiated: %s\n",
+-	       rx_status ? "on" : "off", tx_status ? "on" : "off");
++
++	open_json_object("negotiated");
++	show_bool_val("rx", "RX negotiated: %s\n", &rx_status);
++	show_bool_val("tx", "TX negotiated: %s\n", &tx_status);
++	close_json_object();
+ 
+ 	return MNL_CB_OK;
+ }
+@@ -121,21 +124,34 @@ int pause_reply_cb(const struct nlmsghdr *nlhdr, void *data)
+ 		return err_ret;
+ 
+ 	if (silent)
+-		putchar('\n');
+-	printf("Pause parameters for %s:\n", nlctx->devname);
+-	show_bool(tb[ETHTOOL_A_PAUSE_AUTONEG], "Autonegotiate:\t");
+-	show_bool(tb[ETHTOOL_A_PAUSE_RX], "RX:\t\t");
+-	show_bool(tb[ETHTOOL_A_PAUSE_TX], "TX:\t\t");
++		print_nl();
++
++	open_json_object(NULL);
++
++	print_string(PRINT_ANY, "ifname", "Pause parameters for %s:\n",
++		     nlctx->devname);
++
++	show_bool("autonegotiate", "Autonegotiate:\t%s\n",
++		  tb[ETHTOOL_A_PAUSE_AUTONEG]);
++	show_bool("rx", "RX:\t\t%s\n", tb[ETHTOOL_A_PAUSE_RX]);
++	show_bool("tx", "TX:\t\t%s\n", tb[ETHTOOL_A_PAUSE_TX]);
++
+ 	if (!nlctx->is_monitor && tb[ETHTOOL_A_PAUSE_AUTONEG] &&
+ 	    mnl_attr_get_u8(tb[ETHTOOL_A_PAUSE_AUTONEG])) {
+ 		ret = show_pause_autoneg_status(nlctx);
+ 		if (ret < 0)
+-			return err_ret;
++			goto err_close_dev;
+ 	}
+ 	if (!silent)
+-		putchar('\n');
++		print_nl();
++
++	close_json_object();
+ 
+ 	return MNL_CB_OK;
++
++err_close_dev:
++	close_json_object();
++	return err_ret;
+ }
+ 
+ int nl_gpause(struct cmd_context *ctx)
+@@ -156,7 +172,11 @@ int nl_gpause(struct cmd_context *ctx)
+ 				      ETHTOOL_A_PAUSE_HEADER, 0);
+ 	if (ret < 0)
+ 		return ret;
+-	return nlsock_send_get_request(nlsk, pause_reply_cb);
++
++	new_json_obj(ctx->json);
++	ret = nlsock_send_get_request(nlsk, pause_reply_cb);
++	delete_json_obj();
++	return ret;
+ }
+ 
+ /* PAUSE_SET */
+-- 
+2.26.2
+
diff --git a/SOURCES/0030-separate-FLAGS-out-in-h.patch b/SOURCES/0030-separate-FLAGS-out-in-h.patch
new file mode 100644
index 0000000..1c0df96
--- /dev/null
+++ b/SOURCES/0030-separate-FLAGS-out-in-h.patch
@@ -0,0 +1,50 @@
+From ca9ed7a3b07e68b17f63ce8de6c201267ef48887 Mon Sep 17 00:00:00 2001
+From: Jakub Kicinski <kuba@kernel.org>
+Date: Sun, 18 Oct 2020 14:31:47 -0700
+Subject: [PATCH 30/37] separate FLAGS out in -h
+
+Help output is quite crowded already with every command
+being prefixed by --debug and --json options, and we're
+about to add a third one.
+
+Add an indirection.
+
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit d944e60dbeee28ef0c3581e6a90f2e3b75b1c8f7)
+---
+ ethtool.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/ethtool.c b/ethtool.c
+index 32ef80add923..9b56b0e2a628 100644
+--- a/ethtool.c
++++ b/ethtool.c
+@@ -5963,10 +5963,10 @@ static int show_usage(struct cmd_context *ctx __maybe_unused)
+ 	fprintf(stdout, PACKAGE " version " VERSION "\n");
+ 	fprintf(stdout,
+ 		"Usage:\n"
+-		"        ethtool [ --debug MASK ][ --json ] DEVNAME\t"
++		"        ethtool [ FLAGS ] DEVNAME\t"
+ 		"Display standard information about device\n");
+ 	for (i = 0; args[i].opts; i++) {
+-		fputs("        ethtool [ --debug MASK ][ --json ] ", stdout);
++		fputs("        ethtool [ FLAGS ] ", stdout);
+ 		fprintf(stdout, "%s %s\t%s\n",
+ 			args[i].opts,
+ 			args[i].no_dev ? "\t" : "DEVNAME",
+@@ -5975,7 +5975,10 @@ static int show_usage(struct cmd_context *ctx __maybe_unused)
+ 			fputs(args[i].xhelp, stdout);
+ 	}
+ 	nl_monitor_usage();
+-	fprintf(stdout, "Not all options support JSON output\n");
++	fprintf(stdout, "\n");
++	fprintf(stdout, "FLAGS:\n");
++	fprintf(stdout, "	--debug MASK	turn on debugging messages\n");
++	fprintf(stdout, "	--json		enable JSON output format (not supported by all commands)\n");
+ 
+ 	return 0;
+ }
+-- 
+2.26.2
+
diff --git a/SOURCES/0031-add-support-for-stats-in-subcommands.patch b/SOURCES/0031-add-support-for-stats-in-subcommands.patch
new file mode 100644
index 0000000..5c2ac2f
--- /dev/null
+++ b/SOURCES/0031-add-support-for-stats-in-subcommands.patch
@@ -0,0 +1,83 @@
+From 26b419d729ee84a1924c31b2140281dace819dbc Mon Sep 17 00:00:00 2001
+From: Jakub Kicinski <kuba@kernel.org>
+Date: Sun, 18 Oct 2020 14:31:48 -0700
+Subject: [PATCH 31/37] add support for stats in subcommands
+
+Add new parameters (-I | --include-statistics) which will
+control requesting statistic dumps from the kernel.
+
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 66ecd38ca8b4e6184af4c38c234a9dcfb6804a4a)
+---
+ ethtool.8.in | 7 +++++++
+ ethtool.c    | 8 ++++++++
+ internal.h   | 1 +
+ 3 files changed, 16 insertions(+)
+
+diff --git a/ethtool.8.in b/ethtool.8.in
+index 12866dc456cf..e0601b3db0cf 100644
+--- a/ethtool.8.in
++++ b/ethtool.8.in
+@@ -140,6 +140,9 @@ ethtool \- query or control network driver and hardware settings
+ .B ethtool [--json]
+ .I args
+ .HP
++.B ethtool [-I | --include-statistics]
++.I args
++.HP
+ .B ethtool \-\-monitor
+ [
+ .I command
+@@ -496,6 +499,10 @@ Output results in JavaScript Object Notation (JSON). Only a subset of
+ options support this. Those which do not will continue to output
+ plain text in the presence of this option.
+ .TP
++.B \-I \-\-include\-statistics
++Include command-related statistics in the output. This option allows
++displaying relevant device statistics for selected get commands.
++.TP
+ .B \-a \-\-show\-pause
+ Queries the specified Ethernet device for pause parameter information.
+ .TP
+diff --git a/ethtool.c b/ethtool.c
+index 9b56b0e2a628..f5fbb01e553a 100644
+--- a/ethtool.c
++++ b/ethtool.c
+@@ -5979,6 +5979,7 @@ static int show_usage(struct cmd_context *ctx __maybe_unused)
+ 	fprintf(stdout, "FLAGS:\n");
+ 	fprintf(stdout, "	--debug MASK	turn on debugging messages\n");
+ 	fprintf(stdout, "	--json		enable JSON output format (not supported by all commands)\n");
++	fprintf(stdout, "	-I|--include-statistics		request device statistics related to the command (not supported by all commands)\n");
+ 
+ 	return 0;
+ }
+@@ -6239,6 +6240,13 @@ int main(int argc, char **argp)
+ 			argc -= 1;
+ 			continue;
+ 		}
++		if (*argp && (!strcmp(*argp, "--include-statistics") ||
++			      !strcmp(*argp, "-I"))) {
++			ctx.show_stats = true;
++			argp += 1;
++			argc -= 1;
++			continue;
++		}
+ 		break;
+ 	}
+ 	if (*argp && !strcmp(*argp, "--monitor")) {
+diff --git a/internal.h b/internal.h
+index d096a28abfa2..1c0652d28793 100644
+--- a/internal.h
++++ b/internal.h
+@@ -225,6 +225,7 @@ struct cmd_context {
+ 	char **argp;		/* arguments to the sub-command */
+ 	unsigned long debug;	/* debugging mask */
+ 	bool json;		/* Output JSON, if supported */
++	bool show_stats;	/* include command-specific stats */
+ #ifdef ETHTOOL_ENABLE_NETLINK
+ 	struct nl_context *nlctx;	/* netlink context (opaque) */
+ #endif
+-- 
+2.26.2
+
diff --git a/SOURCES/0032-netlink-use-policy-dumping-to-check-if-stats-flag-is.patch b/SOURCES/0032-netlink-use-policy-dumping-to-check-if-stats-flag-is.patch
new file mode 100644
index 0000000..2ec74dc
--- /dev/null
+++ b/SOURCES/0032-netlink-use-policy-dumping-to-check-if-stats-flag-is.patch
@@ -0,0 +1,232 @@
+From 5966f5dae0dd173fdc7fe34af5f400e36fe782c7 Mon Sep 17 00:00:00 2001
+From: Jakub Kicinski <kuba@kernel.org>
+Date: Sun, 18 Oct 2020 14:31:50 -0700
+Subject: [PATCH 32/37] netlink: use policy dumping to check if stats flag is
+ supported
+
+Older kernels don't support statistics, to avoid retries
+make use of netlink policy dumps to figure out which
+flags kernel actually supports.
+
+v3:
+ - s/ctx/policy_ctx/
+ - save the flags in nl_context to be able to reuse them,
+   and not have to return errors and values from the policy
+   get function
+
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 5c90128a47d7c96cc4dd2c4ad26a0fed1ab60940)
+---
+ netlink/msgbuff.h |   6 ++
+ netlink/netlink.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++
+ netlink/netlink.h |   4 ++
+ 3 files changed, 164 insertions(+)
+
+diff --git a/netlink/msgbuff.h b/netlink/msgbuff.h
+index 24b99c5a28d7..7d6731fc24a3 100644
+--- a/netlink/msgbuff.h
++++ b/netlink/msgbuff.h
+@@ -81,6 +81,12 @@ static inline bool ethnla_put_u32(struct nl_msg_buff *msgbuff, uint16_t type,
+ 	return ethnla_put(msgbuff, type, sizeof(uint32_t), &data);
+ }
+ 
++static inline bool ethnla_put_u16(struct nl_msg_buff *msgbuff, uint16_t type,
++				  uint16_t data)
++{
++	return ethnla_put(msgbuff, type, sizeof(uint16_t), &data);
++}
++
+ static inline bool ethnla_put_u8(struct nl_msg_buff *msgbuff, uint16_t type,
+ 				 uint8_t data)
+ {
+diff --git a/netlink/netlink.c b/netlink/netlink.c
+index 5677274c2fce..ffe06339f099 100644
+--- a/netlink/netlink.c
++++ b/netlink/netlink.c
+@@ -135,6 +135,160 @@ bool netlink_cmd_check(struct cmd_context *ctx, unsigned int cmd,
+ 	return !(nlctx->ops_info[cmd].op_flags & cap);
+ }
+ 
++struct ethtool_op_policy_query_ctx {
++	struct nl_context *nlctx;
++	unsigned int op;
++	unsigned int op_hdr_attr;
++
++	bool op_policy_found;
++	bool hdr_policy_found;
++	unsigned int op_policy_idx;
++	unsigned int hdr_policy_idx;
++	uint64_t flag_mask;
++};
++
++static int family_policy_find_op(struct ethtool_op_policy_query_ctx *policy_ctx,
++				 const struct nlattr *op_policy)
++{
++	const struct nlattr *attr;
++	unsigned int type;
++	int ret;
++
++	type = policy_ctx->nlctx->is_dump ?
++		CTRL_ATTR_POLICY_DUMP : CTRL_ATTR_POLICY_DO;
++
++	mnl_attr_for_each_nested(attr, op_policy) {
++		const struct nlattr *tb[CTRL_ATTR_POLICY_DUMP_MAX + 1] = {};
++		DECLARE_ATTR_TB_INFO(tb);
++
++		if (mnl_attr_get_type(attr) != policy_ctx->op)
++			continue;
++
++		ret = mnl_attr_parse_nested(attr, attr_cb, &tb_info);
++		if (ret < 0)
++			return ret;
++
++		if (!tb[type])
++			continue;
++
++		policy_ctx->op_policy_found = true;
++		policy_ctx->op_policy_idx = mnl_attr_get_u32(tb[type]);
++		break;
++	}
++
++	return 0;
++}
++
++static int family_policy_cb(const struct nlmsghdr *nlhdr, void *data)
++{
++	const struct nlattr *tba[NL_POLICY_TYPE_ATTR_MAX + 1] = {};
++	DECLARE_ATTR_TB_INFO(tba);
++	const struct nlattr *tb[CTRL_ATTR_MAX + 1] = {};
++	DECLARE_ATTR_TB_INFO(tb);
++	struct ethtool_op_policy_query_ctx *policy_ctx = data;
++	const struct nlattr *policy_attr, *attr_attr, *attr;
++	unsigned int attr_idx, policy_idx;
++	int ret;
++
++	ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
++	if (ret < 0)
++		return MNL_CB_ERROR;
++
++	if (!policy_ctx->op_policy_found) {
++		if (!tb[CTRL_ATTR_OP_POLICY]) {
++			fprintf(stderr, "Error: op policy map not present\n");
++			return MNL_CB_ERROR;
++		}
++		ret = family_policy_find_op(policy_ctx, tb[CTRL_ATTR_OP_POLICY]);
++		return ret < 0 ? MNL_CB_ERROR : MNL_CB_OK;
++	}
++
++	if (!tb[CTRL_ATTR_POLICY])
++		return MNL_CB_OK;
++
++	policy_attr = mnl_attr_get_payload(tb[CTRL_ATTR_POLICY]);
++	policy_idx = mnl_attr_get_type(policy_attr);
++	attr_attr = mnl_attr_get_payload(policy_attr);
++	attr_idx = mnl_attr_get_type(attr_attr);
++
++	ret = mnl_attr_parse_nested(attr_attr, attr_cb, &tba_info);
++	if (ret < 0)
++		return MNL_CB_ERROR;
++
++	if (policy_idx == policy_ctx->op_policy_idx &&
++	    attr_idx == policy_ctx->op_hdr_attr) {
++		attr = tba[NL_POLICY_TYPE_ATTR_POLICY_IDX];
++		if (!attr) {
++			fprintf(stderr,	"Error: no policy index in what was expected to be ethtool header attribute\n");
++			return MNL_CB_ERROR;
++		}
++		policy_ctx->hdr_policy_found = true;
++		policy_ctx->hdr_policy_idx = mnl_attr_get_u32(attr);
++	}
++
++	if (policy_ctx->hdr_policy_found &&
++	    policy_ctx->hdr_policy_idx == policy_idx &&
++	    attr_idx == ETHTOOL_A_HEADER_FLAGS) {
++		attr = tba[NL_POLICY_TYPE_ATTR_MASK];
++		if (!attr) {
++			fprintf(stderr,	"Error: validation mask not reported for ethtool header flags\n");
++			return MNL_CB_ERROR;
++		}
++
++		policy_ctx->flag_mask = mnl_attr_get_u64(attr);
++	}
++
++	return MNL_CB_OK;
++}
++
++static int read_flags_policy(struct nl_context *nlctx, struct nl_socket *nlsk,
++			     unsigned int nlcmd, unsigned int hdrattr)
++{
++	struct ethtool_op_policy_query_ctx policy_ctx;
++	struct nl_msg_buff *msgbuff = &nlsk->msgbuff;
++	int ret;
++
++	if (nlctx->ops_info[nlcmd].hdr_policy_loaded)
++		return 0;
++
++	memset(&policy_ctx, 0, sizeof(policy_ctx));
++	policy_ctx.nlctx = nlctx;
++	policy_ctx.op = nlcmd;
++	policy_ctx.op_hdr_attr = hdrattr;
++
++	ret = __msg_init(msgbuff, GENL_ID_CTRL, CTRL_CMD_GETPOLICY,
++			 NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, 1);
++	if (ret < 0)
++		return ret;
++	ret = -EMSGSIZE;
++	if (ethnla_put_u16(msgbuff, CTRL_ATTR_FAMILY_ID, nlctx->ethnl_fam))
++		return ret;
++	if (ethnla_put_u32(msgbuff, CTRL_ATTR_OP, nlcmd))
++		return ret;
++
++	nlsock_sendmsg(nlsk, NULL);
++	nlsock_process_reply(nlsk, family_policy_cb, &policy_ctx);
++
++	nlctx->ops_info[nlcmd].hdr_policy_loaded = 1;
++	nlctx->ops_info[nlcmd].hdr_flags = policy_ctx.flag_mask;
++	return 0;
++}
++
++u32 get_stats_flag(struct nl_context *nlctx, unsigned int nlcmd,
++		   unsigned int hdrattr)
++{
++	if (!nlctx->ctx->show_stats)
++		return 0;
++	if (nlcmd > ETHTOOL_MSG_USER_MAX ||
++	    !(nlctx->ops_info[nlcmd].op_flags & GENL_CMD_CAP_HASPOL))
++		return 0;
++
++	if (read_flags_policy(nlctx, nlctx->ethnl_socket, nlcmd, hdrattr) < 0)
++		return 0;
++
++	return nlctx->ops_info[nlcmd].hdr_flags & ETHTOOL_FLAG_STATS;
++}
++
+ /* initialization */
+ 
+ static int genl_read_ops(struct nl_context *nlctx,
+diff --git a/netlink/netlink.h b/netlink/netlink.h
+index e79143016bd5..c02558540218 100644
+--- a/netlink/netlink.h
++++ b/netlink/netlink.h
+@@ -27,6 +27,8 @@ enum link_mode_class {
+ 
+ struct nl_op_info {
+ 	uint32_t		op_flags;
++	uint32_t		hdr_flags;
++	uint8_t			hdr_policy_loaded:1;
+ };
+ 
+ struct nl_context {
+@@ -70,6 +72,8 @@ bool netlink_cmd_check(struct cmd_context *ctx, unsigned int cmd,
+ 		       bool allow_wildcard);
+ const char *get_dev_name(const struct nlattr *nest);
+ int get_dev_info(const struct nlattr *nest, int *ifindex, char *ifname);
++u32 get_stats_flag(struct nl_context *nlctx, unsigned int nlcmd,
++		   unsigned int hdrattr);
+ 
+ int linkmodes_reply_cb(const struct nlmsghdr *nlhdr, void *data);
+ int linkinfo_reply_cb(const struct nlmsghdr *nlhdr, void *data);
+-- 
+2.26.2
+
diff --git a/SOURCES/0033-pause-add-support-for-dumping-statistics.patch b/SOURCES/0033-pause-add-support-for-dumping-statistics.patch
new file mode 100644
index 0000000..938e5b1
--- /dev/null
+++ b/SOURCES/0033-pause-add-support-for-dumping-statistics.patch
@@ -0,0 +1,147 @@
+From dd5f8a5e8a13ce389269d6be24ba17a903dc6fd9 Mon Sep 17 00:00:00 2001
+From: Jakub Kicinski <kuba@kernel.org>
+Date: Sun, 18 Oct 2020 14:31:51 -0700
+Subject: [PATCH 33/37] pause: add support for dumping statistics
+
+Add support for requesting pause frame stats from the kernel.
+
+ # ./ethtool -I -a eth0
+Pause parameters for eth0:
+Autonegotiate:	on
+RX:		on
+TX:		on
+Statistics:
+  tx_pause_frames: 1
+  rx_pause_frames: 1
+
+ # ./ethtool -I --json -a eth0
+[ {
+        "ifname": "eth0",
+        "autonegotiate": true,
+        "rx": true,
+        "tx": true,
+        "statistics": {
+            "tx_pause_frames": 1,
+            "rx_pause_frames": 1
+        }
+    } ]
+
+v2: - correct print format for u64
+
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 1166ed2fbc603e739759961a77c7ecb5cf2d5443)
+---
+ netlink/pause.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 66 insertions(+), 1 deletion(-)
+
+diff --git a/netlink/pause.c b/netlink/pause.c
+index c54488d71fce..867d0da71f72 100644
+--- a/netlink/pause.c
++++ b/netlink/pause.c
+@@ -5,6 +5,7 @@
+  */
+ 
+ #include <errno.h>
++#include <inttypes.h>
+ #include <string.h>
+ #include <stdio.h>
+ 
+@@ -105,6 +106,62 @@ out:
+ 	return ret;
+ }
+ 
++static int show_pause_stats(const struct nlattr *nest)
++{
++	const struct nlattr *tb[ETHTOOL_A_PAUSE_STAT_MAX + 1] = {};
++	DECLARE_ATTR_TB_INFO(tb);
++	static const struct {
++		unsigned int attr;
++		char *name;
++	} stats[] = {
++		{ ETHTOOL_A_PAUSE_STAT_TX_FRAMES, "tx_pause_frames" },
++		{ ETHTOOL_A_PAUSE_STAT_RX_FRAMES, "rx_pause_frames" },
++	};
++	bool header = false;
++	unsigned int i;
++	size_t n;
++	int ret;
++
++	ret = mnl_attr_parse_nested(nest, attr_cb, &tb_info);
++	if (ret < 0)
++		return ret;
++
++	open_json_object("statistics");
++	for (i = 0; i < ARRAY_SIZE(stats); i++) {
++		char fmt[32];
++
++		if (!tb[stats[i].attr])
++			continue;
++
++		if (!header && !is_json_context()) {
++			printf("Statistics:\n");
++			header = true;
++		}
++
++		if (mnl_attr_validate(tb[stats[i].attr], MNL_TYPE_U64)) {
++			fprintf(stderr, "malformed netlink message (statistic)\n");
++			goto err_close_stats;
++		}
++
++		n = snprintf(fmt, sizeof(fmt), "  %s: %%" PRIu64 "\n",
++			     stats[i].name);
++		if (n >= sizeof(fmt)) {
++			fprintf(stderr, "internal error - malformed label\n");
++			goto err_close_stats;
++		}
++
++		print_u64(PRINT_ANY, stats[i].name, fmt,
++			  mnl_attr_get_u64(tb[stats[i].attr]));
++	}
++	close_json_object();
++
++	return 0;
++
++err_close_stats:
++	close_json_object();
++	return -1;
++}
++
+ int pause_reply_cb(const struct nlmsghdr *nlhdr, void *data)
+ {
+ 	const struct nlattr *tb[ETHTOOL_A_PAUSE_MAX + 1] = {};
+@@ -142,6 +199,11 @@ int pause_reply_cb(const struct nlmsghdr *nlhdr, void *data)
+ 		if (ret < 0)
+ 			goto err_close_dev;
+ 	}
++	if (tb[ETHTOOL_A_PAUSE_STATS]) {
++		ret = show_pause_stats(tb[ETHTOOL_A_PAUSE_STATS]);
++		if (ret < 0)
++			goto err_close_dev;
++	}
+ 	if (!silent)
+ 		print_nl();
+ 
+@@ -158,6 +220,7 @@ int nl_gpause(struct cmd_context *ctx)
+ {
+ 	struct nl_context *nlctx = ctx->nlctx;
+ 	struct nl_socket *nlsk = nlctx->ethnl_socket;
++	u32 flags;
+ 	int ret;
+ 
+ 	if (netlink_cmd_check(ctx, ETHTOOL_MSG_PAUSE_GET, true))
+@@ -168,8 +231,10 @@ int nl_gpause(struct cmd_context *ctx)
+ 		return 1;
+ 	}
+ 
++	flags = get_stats_flag(nlctx, ETHTOOL_MSG_PAUSE_GET,
++			       ETHTOOL_A_PAUSE_HEADER);
+ 	ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_PAUSE_GET,
+-				      ETHTOOL_A_PAUSE_HEADER, 0);
++				      ETHTOOL_A_PAUSE_HEADER, flags);
+ 	if (ret < 0)
+ 		return ret;
+ 
+-- 
+2.26.2
+
diff --git a/SOURCES/0034-netlink-support-u32-enumerated-types-in-pretty-print.patch b/SOURCES/0034-netlink-support-u32-enumerated-types-in-pretty-print.patch
new file mode 100644
index 0000000..36d5033
--- /dev/null
+++ b/SOURCES/0034-netlink-support-u32-enumerated-types-in-pretty-print.patch
@@ -0,0 +1,83 @@
+From 856c0c40eb221499b7326c216aaf87691062eacb Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Mon, 19 Oct 2020 23:32:40 +0200
+Subject: [PATCH 34/37] netlink: support u32 enumerated types in pretty
+ printing
+
+Some numeric attributes take values from a short list/range with symbolic
+names. Showing the symbolic names instead of numeric values will make the
+pretty printed netlink messages easier to read. If the value is too big for
+provided names array (e.g. running on newer kernel) or the name is omitted,
+numeric attribute value is shown.
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit c7fe2f38477f5f90569f73bacd6fab3a8a739f62)
+---
+ netlink/prettymsg.c |  9 +++++++++
+ netlink/prettymsg.h | 18 ++++++++++++++++--
+ 2 files changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/netlink/prettymsg.c b/netlink/prettymsg.c
+index f992dcaf071f..d5d999fddfbb 100644
+--- a/netlink/prettymsg.c
++++ b/netlink/prettymsg.c
+@@ -137,6 +137,15 @@ static int pretty_print_attr(const struct nlattr *attr,
+ 	case NLA_BOOL:
+ 		printf("%s", mnl_attr_get_u8(attr) ? "on" : "off");
+ 		break;
++	case NLA_U32_ENUM: {
++		uint32_t val = mnl_attr_get_u32(attr);
++
++		if (adesc && val < adesc->n_names && adesc->names[val])
++			printf("%s", adesc->names[val]);
++		else
++			printf("%u", val);
++		break;
++	}
+ 	default:
+ 		if (alen <= __DUMP_LINE)
+ 			__print_binary_short(adata, alen);
+diff --git a/netlink/prettymsg.h b/netlink/prettymsg.h
+index b5e5f735ac8a..6987c6ec5bca 100644
+--- a/netlink/prettymsg.h
++++ b/netlink/prettymsg.h
+@@ -28,13 +28,20 @@ enum pretty_nla_format {
+ 	NLA_BOOL,
+ 	NLA_NESTED,
+ 	NLA_ARRAY,
++	NLA_U32_ENUM,
+ };
+ 
+ struct pretty_nla_desc {
+ 	enum pretty_nla_format		format;
+ 	const char			*name;
+-	const struct pretty_nla_desc	*children;
+-	unsigned int			n_children;
++	union {
++		const struct pretty_nla_desc	*children;
++		const char			*const *names;
++	};
++	union {
++		unsigned int			n_children;
++		unsigned int			n_names;
++	};
+ };
+ 
+ struct pretty_nlmsg_desc {
+@@ -81,6 +88,13 @@ struct pretty_nlmsg_desc {
+ 		.children = __ ## _children_desc ## _desc, \
+ 		.n_children = 1, \
+ 	}
++#define NLATTR_DESC_U32_ENUM(_name, _names_table) \
++	[_name] = { \
++		.format = NLA_U32_ENUM, \
++		.name = #_name, \
++		.names = __ ## _names_table ## _names, \
++		.n_children = ARRAY_SIZE(__ ## _names_table ## _names), \
++	}
+ 
+ #define NLMSG_DESC(_name, _attrs) \
+ 	[_name] = { \
+-- 
+2.26.2
+
diff --git a/SOURCES/0035-netlink-support-64-bit-attribute-types-in-pretty-pri.patch b/SOURCES/0035-netlink-support-64-bit-attribute-types-in-pretty-pri.patch
new file mode 100644
index 0000000..ad6fa56
--- /dev/null
+++ b/SOURCES/0035-netlink-support-64-bit-attribute-types-in-pretty-pri.patch
@@ -0,0 +1,97 @@
+From 2ed28d2a92d05a4a1d8bd98dab1607741202f4a3 Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Mon, 19 Oct 2020 23:32:43 +0200
+Subject: [PATCH 35/37] netlink: support 64-bit attribute types in pretty
+ printed messages
+
+Add NLA_U64 (unsigned), NLA_X64 (unsigned, printed as hex) and NLA_S64
+(signed) attribute types in pretty printing code.
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 0f5f1bacee2bfb0b29fe037f8236b3cd714fb10e)
+---
+ netlink/prettymsg.c | 10 ++++++++++
+ netlink/prettymsg.h |  6 ++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/netlink/prettymsg.c b/netlink/prettymsg.c
+index d5d999fddfbb..0a1fae3da54e 100644
+--- a/netlink/prettymsg.c
++++ b/netlink/prettymsg.c
+@@ -9,6 +9,7 @@
+ #include <errno.h>
+ #include <stdint.h>
+ #include <limits.h>
++#include <inttypes.h>
+ #include <linux/genetlink.h>
+ #include <linux/rtnetlink.h>
+ #include <linux/if_link.h>
+@@ -110,6 +111,9 @@ static int pretty_print_attr(const struct nlattr *attr,
+ 	case NLA_U32:
+ 		printf("%u", mnl_attr_get_u32(attr));
+ 		break;
++	case NLA_U64:
++		printf("%" PRIu64, mnl_attr_get_u64(attr));
++		break;
+ 	case NLA_X8:
+ 		printf("0x%02x", mnl_attr_get_u8(attr));
+ 		break;
+@@ -119,6 +123,9 @@ static int pretty_print_attr(const struct nlattr *attr,
+ 	case NLA_X32:
+ 		printf("0x%08x", mnl_attr_get_u32(attr));
+ 		break;
++	case NLA_X64:
++		printf("%" PRIx64, mnl_attr_get_u64(attr));
++		break;
+ 	case NLA_S8:
+ 		printf("%d", (int)mnl_attr_get_u8(attr));
+ 		break;
+@@ -128,6 +135,9 @@ static int pretty_print_attr(const struct nlattr *attr,
+ 	case NLA_S32:
+ 		printf("%d", (int)mnl_attr_get_u32(attr));
+ 		break;
++	case NLA_S64:
++		printf("%" PRId64, (int64_t)mnl_attr_get_u64(attr));
++		break;
+ 	case NLA_STRING:
+ 		printf("\"%.*s\"", alen, (const char *)adata);
+ 		break;
+diff --git a/netlink/prettymsg.h b/netlink/prettymsg.h
+index 6987c6ec5bca..25990cceffca 100644
+--- a/netlink/prettymsg.h
++++ b/netlink/prettymsg.h
+@@ -17,12 +17,15 @@ enum pretty_nla_format {
+ 	NLA_U8,
+ 	NLA_U16,
+ 	NLA_U32,
++	NLA_U64,
+ 	NLA_X8,
+ 	NLA_X16,
+ 	NLA_X32,
++	NLA_X64,
+ 	NLA_S8,
+ 	NLA_S16,
+ 	NLA_S32,
++	NLA_S64,
+ 	NLA_STRING,
+ 	NLA_FLAG,
+ 	NLA_BOOL,
+@@ -62,12 +65,15 @@ struct pretty_nlmsg_desc {
+ #define NLATTR_DESC_U8(_name)		NLATTR_DESC(_name, NLA_U8)
+ #define NLATTR_DESC_U16(_name)		NLATTR_DESC(_name, NLA_U16)
+ #define NLATTR_DESC_U32(_name)		NLATTR_DESC(_name, NLA_U32)
++#define NLATTR_DESC_U64(_name)		NLATTR_DESC(_name, NLA_U64)
+ #define NLATTR_DESC_X8(_name)		NLATTR_DESC(_name, NLA_X8)
+ #define NLATTR_DESC_X16(_name)		NLATTR_DESC(_name, NLA_X16)
+ #define NLATTR_DESC_X32(_name)		NLATTR_DESC(_name, NLA_X32)
++#define NLATTR_DESC_X64(_name)		NLATTR_DESC(_name, NLA_X64)
+ #define NLATTR_DESC_S8(_name)		NLATTR_DESC(_name, NLA_U8)
+ #define NLATTR_DESC_S16(_name)		NLATTR_DESC(_name, NLA_U16)
+ #define NLATTR_DESC_S32(_name)		NLATTR_DESC(_name, NLA_U32)
++#define NLATTR_DESC_S64(_name)		NLATTR_DESC(_name, NLA_S64)
+ #define NLATTR_DESC_STRING(_name)	NLATTR_DESC(_name, NLA_STRING)
+ #define NLATTR_DESC_FLAG(_name)		NLATTR_DESC(_name, NLA_FLAG)
+ #define NLATTR_DESC_BOOL(_name)		NLATTR_DESC(_name, NLA_BOOL)
+-- 
+2.26.2
+
diff --git a/SOURCES/0036-netlink-add-descriptions-for-genetlink-policy-dumps.patch b/SOURCES/0036-netlink-add-descriptions-for-genetlink-policy-dumps.patch
new file mode 100644
index 0000000..a03ba96
--- /dev/null
+++ b/SOURCES/0036-netlink-add-descriptions-for-genetlink-policy-dumps.patch
@@ -0,0 +1,99 @@
+From 536adfb31d821ad19fd823e56dec5e384ed5588c Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Mon, 19 Oct 2020 23:32:46 +0200
+Subject: [PATCH 36/37] netlink: add descriptions for genetlink policy dumps
+
+Add GENL_ID_CTRL message descriptions for messages and attributes used
+for policy dumps.
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit e88f3127a007e07d81cc30c2ac9a3e752d66c0af)
+---
+ netlink/desc-genlctrl.c | 57 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 57 insertions(+)
+
+diff --git a/netlink/desc-genlctrl.c b/netlink/desc-genlctrl.c
+index 9840179b0a1a..43b41ab395b8 100644
+--- a/netlink/desc-genlctrl.c
++++ b/netlink/desc-genlctrl.c
+@@ -29,6 +29,59 @@ static const struct pretty_nla_desc __mcgrps_desc[] = {
+ 	NLATTR_DESC_NESTED(0, mcgrp),
+ };
+ 
++static const char *__policy_attr_type_names[] = {
++	[NL_ATTR_TYPE_INVALID]		= "NL_ATTR_TYPE_INVALID",
++	[NL_ATTR_TYPE_FLAG]		= "NL_ATTR_TYPE_FLAG",
++	[NL_ATTR_TYPE_U8]		= "NL_ATTR_TYPE_U8",
++	[NL_ATTR_TYPE_U16]		= "NL_ATTR_TYPE_U16",
++	[NL_ATTR_TYPE_U32]		= "NL_ATTR_TYPE_U32",
++	[NL_ATTR_TYPE_U64]		= "NL_ATTR_TYPE_U64",
++	[NL_ATTR_TYPE_S8]		= "NL_ATTR_TYPE_S8",
++	[NL_ATTR_TYPE_S16]		= "NL_ATTR_TYPE_S16",
++	[NL_ATTR_TYPE_S32]		= "NL_ATTR_TYPE_S32",
++	[NL_ATTR_TYPE_S64]		= "NL_ATTR_TYPE_S64",
++	[NL_ATTR_TYPE_BINARY]		= "NL_ATTR_TYPE_BINARY",
++	[NL_ATTR_TYPE_STRING]		= "NL_ATTR_TYPE_STRING",
++	[NL_ATTR_TYPE_NUL_STRING]	= "NL_ATTR_TYPE_NUL_STRING",
++	[NL_ATTR_TYPE_NESTED]		= "NL_ATTR_TYPE_NESTED",
++	[NL_ATTR_TYPE_NESTED_ARRAY]	= "NL_ATTR_TYPE_NESTED_ARRAY",
++	[NL_ATTR_TYPE_BITFIELD32]	= "NL_ATTR_TYPE_BITFIELD32",
++};
++
++static const struct pretty_nla_desc __policy_attr_desc[] = {
++	NLATTR_DESC_INVALID(NL_POLICY_TYPE_ATTR_UNSPEC),
++	NLATTR_DESC_U32_ENUM(NL_POLICY_TYPE_ATTR_TYPE, policy_attr_type),
++	NLATTR_DESC_S64(NL_POLICY_TYPE_ATTR_MIN_VALUE_S),
++	NLATTR_DESC_S64(NL_POLICY_TYPE_ATTR_MAX_VALUE_S),
++	NLATTR_DESC_U64(NL_POLICY_TYPE_ATTR_MIN_VALUE_U),
++	NLATTR_DESC_U64(NL_POLICY_TYPE_ATTR_MAX_VALUE_U),
++	NLATTR_DESC_U32(NL_POLICY_TYPE_ATTR_MIN_LENGTH),
++	NLATTR_DESC_U32(NL_POLICY_TYPE_ATTR_MAX_LENGTH),
++	NLATTR_DESC_U32(NL_POLICY_TYPE_ATTR_POLICY_IDX),
++	NLATTR_DESC_U32(NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE),
++	NLATTR_DESC_X32(NL_POLICY_TYPE_ATTR_BITFIELD32_MASK),
++	NLATTR_DESC_X64(NL_POLICY_TYPE_ATTR_PAD),
++	NLATTR_DESC_BINARY(NL_POLICY_TYPE_ATTR_MASK),
++};
++
++static const struct pretty_nla_desc __policy_attrs_desc[] = {
++	NLATTR_DESC_NESTED(0, policy_attr),
++};
++
++static const struct pretty_nla_desc __policies_desc[] = {
++	NLATTR_DESC_ARRAY(0, policy_attrs),
++};
++
++static const struct pretty_nla_desc __op_policy_desc[] = {
++	NLATTR_DESC_INVALID(CTRL_ATTR_POLICY_UNSPEC),
++	NLATTR_DESC_U32(CTRL_ATTR_POLICY_DO),
++	NLATTR_DESC_U32(CTRL_ATTR_POLICY_DUMP),
++};
++
++static const struct pretty_nla_desc __op_policies_desc[] = {
++	NLATTR_DESC_NESTED(0, op_policy),
++};
++
+ static const struct pretty_nla_desc __attr_desc[] = {
+ 	NLATTR_DESC_INVALID(CTRL_ATTR_UNSPEC),
+ 	NLATTR_DESC_U16(CTRL_ATTR_FAMILY_ID),
+@@ -38,6 +91,9 @@ static const struct pretty_nla_desc __attr_desc[] = {
+ 	NLATTR_DESC_U32(CTRL_ATTR_MAXATTR),
+ 	NLATTR_DESC_ARRAY(CTRL_ATTR_OPS, attrops),
+ 	NLATTR_DESC_ARRAY(CTRL_ATTR_MCAST_GROUPS, mcgrps),
++	NLATTR_DESC_ARRAY(CTRL_ATTR_POLICY, policies),
++	NLATTR_DESC_ARRAY(CTRL_ATTR_OP_POLICY, op_policies),
++	NLATTR_DESC_U32(CTRL_ATTR_OP),
+ };
+ 
+ const struct pretty_nlmsg_desc genlctrl_msg_desc[] = {
+@@ -51,6 +107,7 @@ const struct pretty_nlmsg_desc genlctrl_msg_desc[] = {
+ 	NLMSG_DESC(CTRL_CMD_NEWMCAST_GRP, attr),
+ 	NLMSG_DESC(CTRL_CMD_DELMCAST_GRP, attr),
+ 	NLMSG_DESC(CTRL_CMD_GETMCAST_GRP, attr),
++	NLMSG_DESC(CTRL_CMD_GETPOLICY, attr),
+ };
+ 
+ const unsigned int genlctrl_msg_n_desc = ARRAY_SIZE(genlctrl_msg_desc);
+-- 
+2.26.2
+
diff --git a/SOURCES/0037-netlink-add-message-descriptions-for-pause-stats.patch b/SOURCES/0037-netlink-add-message-descriptions-for-pause-stats.patch
new file mode 100644
index 0000000..3a39fa8
--- /dev/null
+++ b/SOURCES/0037-netlink-add-message-descriptions-for-pause-stats.patch
@@ -0,0 +1,41 @@
+From 5d4ecfe153434ffae3bf9858b870eafc70e55ccf Mon Sep 17 00:00:00 2001
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Mon, 19 Oct 2020 23:32:49 +0200
+Subject: [PATCH 37/37] netlink: add message descriptions for pause stats
+
+Add message descriptions for pretty printing of new attributes used for pause
+statistics.
+
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 9922adcbb4383c50eb8d0046f283873b999b40ba)
+---
+ netlink/desc-ethtool.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/netlink/desc-ethtool.c b/netlink/desc-ethtool.c
+index 54f057915d6d..8dd4a91ad0d7 100644
+--- a/netlink/desc-ethtool.c
++++ b/netlink/desc-ethtool.c
+@@ -178,12 +178,19 @@ static const struct pretty_nla_desc __coalesce_desc[] = {
+ 	NLATTR_DESC_U32(ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL),
+ };
+ 
++static const struct pretty_nla_desc __pause_stats_desc[] = {
++	NLATTR_DESC_BINARY(ETHTOOL_A_PAUSE_STAT_PAD),
++	NLATTR_DESC_U64(ETHTOOL_A_PAUSE_STAT_TX_FRAMES),
++	NLATTR_DESC_U64(ETHTOOL_A_PAUSE_STAT_RX_FRAMES),
++};
++
+ static const struct pretty_nla_desc __pause_desc[] = {
+ 	NLATTR_DESC_INVALID(ETHTOOL_A_PAUSE_UNSPEC),
+ 	NLATTR_DESC_NESTED(ETHTOOL_A_PAUSE_HEADER, header),
+ 	NLATTR_DESC_BOOL(ETHTOOL_A_PAUSE_AUTONEG),
+ 	NLATTR_DESC_BOOL(ETHTOOL_A_PAUSE_RX),
+ 	NLATTR_DESC_BOOL(ETHTOOL_A_PAUSE_TX),
++	NLATTR_DESC_NESTED(ETHTOOL_A_PAUSE_STATS, pause_stats),
+ };
+ 
+ static const struct pretty_nla_desc __eee_desc[] = {
+-- 
+2.26.2
+
diff --git a/SOURCES/0038-update-UAPI-header-copies.patch b/SOURCES/0038-update-UAPI-header-copies.patch
new file mode 100644
index 0000000..47f1b1c
--- /dev/null
+++ b/SOURCES/0038-update-UAPI-header-copies.patch
@@ -0,0 +1,152 @@
+From b70c39e968db6cb67d64526cafd72fc0763d959a Mon Sep 17 00:00:00 2001
+From: Danielle Ratson <danieller@nvidia.com>
+Date: Wed, 10 Feb 2021 15:48:36 +0200
+Subject: [PATCH 38/42] update UAPI header copies
+
+Update to kernel commit 012ce4dd3102.
+
+Signed-off-by: Danielle Ratson <danieller@nvidia.com>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 18e509526a727c594c29622489437c7376f44d32)
+---
+ uapi/linux/ethtool.h         |  2 +-
+ uapi/linux/ethtool_netlink.h |  1 +
+ uapi/linux/if_link.h         | 10 ++++++++--
+ uapi/linux/netlink.h         |  2 +-
+ uapi/linux/rtnetlink.h       | 20 +++++++++++++++-----
+ 5 files changed, 26 insertions(+), 9 deletions(-)
+
+diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h
+index 052689bcc90c..a951137bdba9 100644
+--- a/uapi/linux/ethtool.h
++++ b/uapi/linux/ethtool.h
+@@ -14,7 +14,7 @@
+ #ifndef _LINUX_ETHTOOL_H
+ #define _LINUX_ETHTOOL_H
+ 
+-#include <linux/kernel.h>
++#include <linux/const.h>
+ #include <linux/types.h>
+ #include <linux/if_ether.h>
+ 
+diff --git a/uapi/linux/ethtool_netlink.h b/uapi/linux/ethtool_netlink.h
+index c022883cdb22..0cd6906aa5d5 100644
+--- a/uapi/linux/ethtool_netlink.h
++++ b/uapi/linux/ethtool_netlink.h
+@@ -227,6 +227,7 @@ enum {
+ 	ETHTOOL_A_LINKMODES_DUPLEX,		/* u8 */
+ 	ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG,	/* u8 */
+ 	ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE,	/* u8 */
++	ETHTOOL_A_LINKMODES_LANES,		/* u32 */
+ 
+ 	/* add new constants above here */
+ 	__ETHTOOL_A_LINKMODES_CNT,
+diff --git a/uapi/linux/if_link.h b/uapi/linux/if_link.h
+index 307e5c245e9f..c96880c51c93 100644
+--- a/uapi/linux/if_link.h
++++ b/uapi/linux/if_link.h
+@@ -75,8 +75,9 @@ struct rtnl_link_stats {
+  *
+  * @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
++ *   For hardware interfaces this counter may include packets discarded
++ *   due to L2 address filtering but should not include packets dropped
++ *   by the device due to buffer exhaustion 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,
+@@ -522,6 +523,8 @@ enum {
+ 	IFLA_BRPORT_BACKUP_PORT,
+ 	IFLA_BRPORT_MRP_RING_OPEN,
+ 	IFLA_BRPORT_MRP_IN_OPEN,
++	IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT,
++	IFLA_BRPORT_MCAST_EHT_HOSTS_CNT,
+ 	__IFLA_BRPORT_MAX
+ };
+ #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
+@@ -586,6 +589,8 @@ enum {
+ 	IFLA_MACVLAN_MACADDR,
+ 	IFLA_MACVLAN_MACADDR_DATA,
+ 	IFLA_MACVLAN_MACADDR_COUNT,
++	IFLA_MACVLAN_BC_QUEUE_LEN,
++	IFLA_MACVLAN_BC_QUEUE_LEN_USED,
+ 	__IFLA_MACVLAN_MAX,
+ };
+ 
+@@ -804,6 +809,7 @@ enum {
+ 	IFLA_GTP_FD1,
+ 	IFLA_GTP_PDP_HASHSIZE,
+ 	IFLA_GTP_ROLE,
++	IFLA_GTP_COLLECT_METADATA,
+ 	__IFLA_GTP_MAX,
+ };
+ #define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1)
+diff --git a/uapi/linux/netlink.h b/uapi/linux/netlink.h
+index dfef006be9f9..5024c5435749 100644
+--- a/uapi/linux/netlink.h
++++ b/uapi/linux/netlink.h
+@@ -2,7 +2,7 @@
+ #ifndef __LINUX_NETLINK_H
+ #define __LINUX_NETLINK_H
+ 
+-#include <linux/kernel.h>
++#include <linux/const.h>
+ #include <linux/socket.h> /* for __kernel_sa_family_t */
+ #include <linux/types.h>
+ 
+diff --git a/uapi/linux/rtnetlink.h b/uapi/linux/rtnetlink.h
+index 5ad84e663d01..c66fd247d90a 100644
+--- a/uapi/linux/rtnetlink.h
++++ b/uapi/linux/rtnetlink.h
+@@ -396,11 +396,13 @@ struct rtnexthop {
+ #define RTNH_F_DEAD		1	/* Nexthop is dead (used by multipath)	*/
+ #define RTNH_F_PERVASIVE	2	/* Do recursive gateway lookup	*/
+ #define RTNH_F_ONLINK		4	/* Gateway is forced on link	*/
+-#define RTNH_F_OFFLOAD		8	/* offloaded route */
++#define RTNH_F_OFFLOAD		8	/* Nexthop is offloaded */
+ #define RTNH_F_LINKDOWN		16	/* carrier-down on nexthop */
+ #define RTNH_F_UNRESOLVED	32	/* The entry is unresolved (ipmr) */
++#define RTNH_F_TRAP		64	/* Nexthop is trapping packets */
+ 
+-#define RTNH_COMPARE_MASK	(RTNH_F_DEAD | RTNH_F_LINKDOWN | RTNH_F_OFFLOAD)
++#define RTNH_COMPARE_MASK	(RTNH_F_DEAD | RTNH_F_LINKDOWN | \
++				 RTNH_F_OFFLOAD | RTNH_F_TRAP)
+ 
+ /* Macros to handle hexthops */
+ 
+@@ -764,12 +766,18 @@ enum {
+ #define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg))
+ /* tcamsg flags stored in attribute TCA_ROOT_FLAGS
+  *
+- * TCA_FLAG_LARGE_DUMP_ON user->kernel to request for larger than TCA_ACT_MAX_PRIO
+- * actions in a dump. All dump responses will contain the number of actions
+- * being dumped stored in for user app's consumption in TCA_ROOT_COUNT
++ * TCA_ACT_FLAG_LARGE_DUMP_ON user->kernel to request for larger than
++ * TCA_ACT_MAX_PRIO actions in a dump. All dump responses will contain the
++ * number of actions being dumped stored in for user app's consumption in
++ * TCA_ROOT_COUNT
++ *
++ * TCA_ACT_FLAG_TERSE_DUMP user->kernel to request terse (brief) dump that only
++ * includes essential action info (kind, index, etc.)
+  *
+  */
+ #define TCA_FLAG_LARGE_DUMP_ON		(1 << 0)
++#define TCA_ACT_FLAG_LARGE_DUMP_ON	TCA_FLAG_LARGE_DUMP_ON
++#define TCA_ACT_FLAG_TERSE_DUMP		(1 << 1)
+ 
+ /* New extended info filters for IFLA_EXT_MASK */
+ #define RTEXT_FILTER_VF		(1 << 0)
+@@ -777,6 +785,8 @@ enum {
+ #define RTEXT_FILTER_BRVLAN_COMPRESSED	(1 << 2)
+ #define	RTEXT_FILTER_SKIP_STATS	(1 << 3)
+ #define RTEXT_FILTER_MRP	(1 << 4)
++#define RTEXT_FILTER_CFM_CONFIG	(1 << 5)
++#define RTEXT_FILTER_CFM_STATUS	(1 << 6)
+ 
+ /* End of information exported to user level */
+ 
+-- 
+2.31.1
+
diff --git a/SOURCES/0039-netlink-settings-Add-netlink-support-for-lanes-param.patch b/SOURCES/0039-netlink-settings-Add-netlink-support-for-lanes-param.patch
new file mode 100644
index 0000000..b8a9ea8
--- /dev/null
+++ b/SOURCES/0039-netlink-settings-Add-netlink-support-for-lanes-param.patch
@@ -0,0 +1,63 @@
+From e9ee8ed549fbc02527356c3c82cec23434fc2f56 Mon Sep 17 00:00:00 2001
+From: Danielle Ratson <danieller@mellanox.com>
+Date: Wed, 10 Feb 2021 15:48:37 +0200
+Subject: [PATCH 39/42] netlink: settings: Add netlink support for lanes
+ parameter
+
+Add support for "ethtool -s <dev> lanes N ..." for setting a specific
+number of lanes.
+
+Signed-off-by: Danielle Ratson <danieller@mellanox.com>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit 107ee330ec7bf83e8c3938375f3466bc8e102b93)
+---
+ ethtool.c              | 1 +
+ netlink/desc-ethtool.c | 1 +
+ netlink/settings.c     | 7 +++++++
+ 3 files changed, 9 insertions(+)
+
+diff --git a/ethtool.c b/ethtool.c
+index f5fbb01e553a..61f136c5bf2c 100644
+--- a/ethtool.c
++++ b/ethtool.c
+@@ -5568,6 +5568,7 @@ static const struct option args[] = {
+ 		.nlfunc	= nl_sset,
+ 		.help	= "Change generic options",
+ 		.xhelp	= "		[ speed %d ]\n"
++			  "		[ lanes %d ]\n"
+ 			  "		[ duplex half|full ]\n"
+ 			  "		[ port tp|aui|bnc|mii|fibre|da ]\n"
+ 			  "		[ mdix auto|on|off ]\n"
+diff --git a/netlink/desc-ethtool.c b/netlink/desc-ethtool.c
+index 8dd4a91ad0d7..c8447ce33f4d 100644
+--- a/netlink/desc-ethtool.c
++++ b/netlink/desc-ethtool.c
+@@ -87,6 +87,7 @@ static const struct pretty_nla_desc __linkmodes_desc[] = {
+ 	NLATTR_DESC_U8(ETHTOOL_A_LINKMODES_DUPLEX),
+ 	NLATTR_DESC_U8(ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG),
+ 	NLATTR_DESC_U8(ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE),
++	NLATTR_DESC_U32(ETHTOOL_A_LINKMODES_LANES),
+ };
+ 
+ static const struct pretty_nla_desc __linkstate_desc[] = {
+diff --git a/netlink/settings.c b/netlink/settings.c
+index 01c1d38d323f..37222db5c833 100644
+--- a/netlink/settings.c
++++ b/netlink/settings.c
+@@ -1065,6 +1065,13 @@ static const struct param_parser sset_params[] = {
+ 		.handler	= nl_parse_direct_u32,
+ 		.min_argc	= 1,
+ 	},
++	{
++		.arg		= "lanes",
++		.group		= ETHTOOL_MSG_LINKMODES_SET,
++		.type		= ETHTOOL_A_LINKMODES_LANES,
++		.handler	= nl_parse_direct_u32,
++		.min_argc	= 1,
++	},
+ 	{
+ 		.arg		= "duplex",
+ 		.group		= ETHTOOL_MSG_LINKMODES_SET,
+-- 
+2.31.1
+
diff --git a/SOURCES/0040-netlink-settings-Expose-the-number-of-lanes-in-use.patch b/SOURCES/0040-netlink-settings-Expose-the-number-of-lanes-in-use.patch
new file mode 100644
index 0000000..047897c
--- /dev/null
+++ b/SOURCES/0040-netlink-settings-Expose-the-number-of-lanes-in-use.patch
@@ -0,0 +1,41 @@
+From 53e33fe5f4f982afe13e45677d134eb1b11d4d2a Mon Sep 17 00:00:00 2001
+From: Danielle Ratson <danieller@nvidia.com>
+Date: Wed, 10 Feb 2021 15:48:38 +0200
+Subject: [PATCH 40/42] netlink: settings: Expose the number of lanes in use
+
+Currently, the user does not have the information regarding how many lanes
+are used when the link is up.
+
+After adding a possibility to advertise or force a specific number of
+lanes this information becomes helpful.
+
+Expose the number of lanes in use if the information is passed from
+kernel.
+
+Signed-off-by: Danielle Ratson <danieller@nvidia.com>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit db7d457e49833d8a68be03d48cffa1d617498adc)
+---
+ netlink/settings.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/netlink/settings.c b/netlink/settings.c
+index 37222db5c833..2835805667d2 100644
+--- a/netlink/settings.c
++++ b/netlink/settings.c
+@@ -471,6 +471,12 @@ int linkmodes_reply_cb(const struct nlmsghdr *nlhdr, void *data)
+ 		else
+ 			printf("\tSpeed: %uMb/s\n", val);
+ 	}
++	if (tb[ETHTOOL_A_LINKMODES_LANES]) {
++		uint32_t val = mnl_attr_get_u32(tb[ETHTOOL_A_LINKMODES_LANES]);
++
++		print_banner(nlctx);
++		printf("\tLanes: %u\n", val);
++	}
+ 	if (tb[ETHTOOL_A_LINKMODES_DUPLEX]) {
+ 		uint8_t val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKMODES_DUPLEX]);
+ 
+-- 
+2.31.1
+
diff --git a/SOURCES/0041-shell-completion-Add-completion-for-lanes.patch b/SOURCES/0041-shell-completion-Add-completion-for-lanes.patch
new file mode 100644
index 0000000..a41e40e
--- /dev/null
+++ b/SOURCES/0041-shell-completion-Add-completion-for-lanes.patch
@@ -0,0 +1,42 @@
+From 68c18af78f4e5eac30ed4fd4c6f3bb0ca8dc347e Mon Sep 17 00:00:00 2001
+From: Danielle Ratson <danieller@mellanox.com>
+Date: Wed, 10 Feb 2021 15:48:39 +0200
+Subject: [PATCH 41/42] shell-completion: Add completion for lanes
+
+Lanes was added as a new link mode setting in ethtool.
+
+Support completion for lanes when setting parameters.
+
+Signed-off-by: Danielle Ratson <danieller@mellanox.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit c323bcb248c2424cebe533cb2607283aa4538a0b)
+---
+ shell-completion/bash/ethtool | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/shell-completion/bash/ethtool b/shell-completion/bash/ethtool
+index 53055594b649..45573413985d 100644
+--- a/shell-completion/bash/ethtool
++++ b/shell-completion/bash/ethtool
+@@ -97,6 +97,7 @@ _ethtool_change()
+ 		[speed]=notseen
+ 		[wol]=notseen
+ 		[xcvr]=notseen
++		[lanes]=notseen
+ 	)
+ 
+ 	local -A msgtypes=(
+@@ -175,6 +176,9 @@ _ethtool_change()
+ 		xcvr)
+ 			COMPREPLY=( $( compgen -W 'internal external' -- "$cur" ) )
+ 			return ;;
++		lanes)
++			# Number
++			return ;;
+ 	esac
+ 
+ 	local -a comp_words=()
+-- 
+2.31.1
+
diff --git a/SOURCES/0042-man-Add-man-page-for-setting-lanes-parameter.patch b/SOURCES/0042-man-Add-man-page-for-setting-lanes-parameter.patch
new file mode 100644
index 0000000..c99481d
--- /dev/null
+++ b/SOURCES/0042-man-Add-man-page-for-setting-lanes-parameter.patch
@@ -0,0 +1,41 @@
+From c8883327ddbbdcc8241104a98800bd50c0a667e1 Mon Sep 17 00:00:00 2001
+From: Danielle Ratson <danieller@nvidia.com>
+Date: Wed, 10 Feb 2021 15:48:40 +0200
+Subject: [PATCH 42/42] man: Add man page for setting lanes parameter
+
+Lanes parameter was added for setting using ethtool.
+
+Update the man page to include the new parameter.
+
+Signed-off-by: Danielle Ratson <danieller@nvidia.com>
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+(cherry picked from commit e2a120e1d44e6c4d64f53ac78c9c08427922b33b)
+---
+ ethtool.8.in | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ethtool.8.in b/ethtool.8.in
+index e0601b3db0cf..3a7a8f947cc1 100644
+--- a/ethtool.8.in
++++ b/ethtool.8.in
+@@ -251,6 +251,7 @@ ethtool \- query or control network driver and hardware settings
+ .B ethtool \-s
+ .I devname
+ .BN speed
++.BN lanes
+ .B2 duplex half full
+ .B4 port tp aui bnc mii fibre da
+ .B3 mdix auto on off
+@@ -682,6 +683,9 @@ Set speed in Mb/s.
+ .B ethtool
+ with just the device name as an argument will show you the supported device speeds.
+ .TP
++.BI lanes \ N
++Set number of lanes.
++.TP
+ .A2 duplex half full
+ Sets full or half duplex mode.
+ .TP
+-- 
+2.31.1
+
diff --git a/SPECS/ethtool.spec b/SPECS/ethtool.spec
index 874fba0..c5bf8ad 100644
--- a/SPECS/ethtool.spec
+++ b/SPECS/ethtool.spec
@@ -1,7 +1,7 @@
 Name:		ethtool
 Epoch:		2
 Version:	5.8
-Release:	5%{?dist}
+Release:	7%{?dist}
 Summary:	Settings tool for Ethernet NICs
 License:	GPLv2
 Group:		Applications/System
@@ -33,6 +33,22 @@ Patch23:	0023-netlink-fix-use-after-free-in-netlink_run_handler.patch
 Patch24:	0024-netlink-fix-leaked-instances-of-struct-nl_socket.patch
 Patch25:	0025-netlink-do-not-send-messages-and-process-replies-in-.patch
 Patch26:	0026-ethtool-Improve-compatibility-between-netlink-and-io.patch
+Patch27:	0027-update-UAPI-header-copies.patch
+Patch28:	0028-update-UAPI-header-copies.patch
+Patch29:	0029-pause-add-json-support.patch
+Patch30:	0030-separate-FLAGS-out-in-h.patch
+Patch31:	0031-add-support-for-stats-in-subcommands.patch
+Patch32:	0032-netlink-use-policy-dumping-to-check-if-stats-flag-is.patch
+Patch33:	0033-pause-add-support-for-dumping-statistics.patch
+Patch34:	0034-netlink-support-u32-enumerated-types-in-pretty-print.patch
+Patch35:	0035-netlink-support-64-bit-attribute-types-in-pretty-pri.patch
+Patch36:	0036-netlink-add-descriptions-for-genetlink-policy-dumps.patch
+Patch37:	0037-netlink-add-message-descriptions-for-pause-stats.patch
+Patch38:        0038-update-UAPI-header-copies.patch
+Patch39:        0039-netlink-settings-Add-netlink-support-for-lanes-param.patch
+Patch40:        0040-netlink-settings-Expose-the-number-of-lanes-in-use.patch
+Patch41:        0041-shell-completion-Add-completion-for-lanes.patch
+Patch42:        0042-man-Add-man-page-for-setting-lanes-parameter.patch
 BuildRequires:	libmnl-devel
 Conflicts:	filesystem < 3
 
@@ -69,6 +85,22 @@ network devices, especially of Ethernet devices.
 %patch24 -p1
 %patch25 -p1
 %patch26 -p1
+%patch27 -p1
+%patch28 -p1
+%patch29 -p1
+%patch30 -p1
+%patch31 -p1
+%patch32 -p1
+%patch33 -p1
+%patch34 -p1
+%patch35 -p1
+%patch36 -p1
+%patch37 -p1
+%patch38 -p1
+%patch39 -p1
+%patch40 -p1
+%patch41 -p1
+%patch42 -p1
 
 %build
 %configure
@@ -85,6 +117,12 @@ make DESTDIR=%{buildroot} INSTALL='install -p' install
 %{_datadir}/bash-completion/completions/ethtool
 
 %changelog
+* Thu Jun 03 2021 Ivan Vecera <ivecera@redhat.com> - 2:5.8-7
+- Added support for lanes
+
+* Thu Mar 11 2021 Ivan Vecera <ivecera@redhat.com> - 2:5.8-6
+- Added support for pause frame statistics
+
 * Thu Nov 12 2020 Ivan Vecera <ivecera@redhat.com> - 2:5.8-5
 - Fixed a regression