All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michal Kubecek <mkubecek@suse.cz>
To: David Miller <davem@davemloft.net>, netdev@vger.kernel.org
Cc: Jakub Kicinski <jakub.kicinski@netronome.com>,
	Jiri Pirko <jiri@resnulli.us>, Andrew Lunn <andrew@lunn.ch>,
	Florian Fainelli <f.fainelli@gmail.com>,
	John Linville <linville@tuxdriver.com>,
	linux-kernel@vger.kernel.org
Subject: [PATCH net-next v4 13/22] ethtool: provide driver/device information in GET_INFO request
Date: Thu, 21 Mar 2019 14:40:57 +0100 (CET)	[thread overview]
Message-ID: <084e52d43a6809a5ef2000c089a00540e8d54e72.1553170807.git.mkubecek@suse.cz> (raw)
In-Reply-To: <cover.1553170807.git.mkubecek@suse.cz>

Implement GET_INFO request to get basic driver and device information as
provided by ETHTOOL_GDRVINFO ioct command. The information is read only so
that the corresponding SET_INFO message is only used in kernel replies.

Move most of ethtool_get_drvinfo() int common.c so that the code can be
shared by both ioctl and netlink interface.

Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
---
 Documentation/networking/ethtool-netlink.txt |  43 ++++-
 include/uapi/linux/ethtool_netlink.h         |  30 ++++
 net/ethtool/Makefile                         |   2 +-
 net/ethtool/common.c                         |  52 ++++++
 net/ethtool/common.h                         |   2 +
 net/ethtool/info.c                           | 158 +++++++++++++++++++
 net/ethtool/ioctl.c                          |  50 +-----
 net/ethtool/netlink.c                        |   8 +
 net/ethtool/netlink.h                        |   1 +
 9 files changed, 299 insertions(+), 47 deletions(-)
 create mode 100644 net/ethtool/info.c

diff --git a/Documentation/networking/ethtool-netlink.txt b/Documentation/networking/ethtool-netlink.txt
index 1508c16a236e..cffa508ca6c6 100644
--- a/Documentation/networking/ethtool-netlink.txt
+++ b/Documentation/networking/ethtool-netlink.txt
@@ -129,6 +129,8 @@ List of message types
     ETHNL_CMD_EVENT			notification only
     ETHNL_CMD_GET_STRSET
     ETHNL_CMD_SET_STRSET		response only
+    ETHNL_CMD_GET_INFO
+    ETHNL_CMD_SET_INFO			response only
 
 All constants use ETHNL_CMD_ prefix, usually followed by "GET", "SET" or "ACT"
 to indicate the type.
@@ -209,6 +211,45 @@ ETHA_STRSET_COUNTS tells kernel to only return string counts of the sets, not
 the actual strings.
 
 
+GET_INFO
+--------
+
+GET_INFO requests information provided by ioctl commands ETHTOOL_GDRVINFO,
+ETHTOOL_GPERMADDR and ETHTOOL_GET_TS_INFO to provide basic device information.
+Common pattern is that all information is read only so that SET_INFO message
+exists but is only used by kernel for replies to GET_INFO requests. There is
+also no corresponding notification.
+
+Request contents:
+
+    ETHA_INFO_DEV		(nested)	device identification
+    ETHA_INFO_INFOMASK		(u32)		info mask
+    ETHA_INFO_COMPACT		(flag)		request compact bitsets
+
+Info mask bits meaning:
+
+    ETH_INFO_IM_DRVINFO			driver info (GDRVINFO)
+    ETH_INFO_IM_PERMADDR		permanent HW address (GPERMADDR)
+    ETH_INFO_IM_TSINFO			timestamping info (GET_TS_INFO)
+
+Kernel response contents:
+
+    ETHA_INFO_DEV		(nested)	device identification
+    ETHA_INFO_DRVINFO		(nested)	driver information
+        ETHA_DRVINFO_DRIVER		(string)	driver name
+        ETHA_DRVINFO_FWVERSION		(string)	firmware version
+        ETHA_DRVINFO_BUSINFO		(string)	device bus address
+        ETHA_DRVINFO_EROM_VER		(string)	expansion ROM version
+
+The meaning of DRVINFO attributes follows the corresponding fields of
+ETHTOOL_GDRVINFO response. Second part with various counts and sizes is
+omitted as these are not really needed (and if they are, they can be easily
+found by different means). Driver version is also omitted as it is rather
+misleading in most cases.
+
+GET_INFO requests allow dumps.
+
+
 Request translation
 -------------------
 
@@ -220,7 +261,7 @@ ioctl command			netlink command
 ---------------------------------------------------------------------
 ETHTOOL_GSET			n/a
 ETHTOOL_SSET			n/a
-ETHTOOL_GDRVINFO		n/a
+ETHTOOL_GDRVINFO		ETHNL_CMD_GET_INFO
 ETHTOOL_GREGS			n/a
 ETHTOOL_GWOL			n/a
 ETHTOOL_SWOL			n/a
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 66aeb436b822..386d4273ac44 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -16,6 +16,8 @@ enum {
 	ETHNL_CMD_EVENT,		/* only for notifications */
 	ETHNL_CMD_GET_STRSET,
 	ETHNL_CMD_SET_STRSET,		/* only for reply */
+	ETHNL_CMD_GET_INFO,
+	ETHNL_CMD_SET_INFO,		/* only for reply */
 
 	__ETHNL_CMD_CNT,
 	ETHNL_CMD_MAX = (__ETHNL_CMD_CNT - 1)
@@ -141,6 +143,34 @@ enum {
 	ETHA_STRSET_MAX = (__ETHA_STRSET_CNT - 1)
 };
 
+/* GET_INFO / SET_INFO */
+
+enum {
+	ETHA_INFO_UNSPEC,
+	ETHA_INFO_DEV,				/* nest - ETHA_DEV_* */
+	ETHA_INFO_INFOMASK,			/* u32 */
+	ETHA_INFO_COMPACT,			/* flag */
+	ETHA_INFO_DRVINFO,			/* nest - ETHA_DRVINFO_* */
+
+	__ETHA_INFO_CNT,
+	ETHA_INFO_MAX = (__ETHA_INFO_CNT - 1)
+};
+
+#define ETH_INFO_IM_DRVINFO			(1U << 0)
+
+#define ETH_INFO_IM_ALL (ETH_INFO_IM_DRVINFO)
+
+enum {
+	ETHA_DRVINFO_UNSPEC,
+	ETHA_DRVINFO_DRIVER,			/* string */
+	ETHA_DRVINFO_FWVERSION,			/* string */
+	ETHA_DRVINFO_BUSINFO,			/* string */
+	ETHA_DRVINFO_EROM_VER,			/* string */
+
+	__ETHA_DRVINFO_CNT,
+	ETHA_DRVINFO_MAX = (__ETHA_DRVINFO_CNT - 1)
+};
+
 /* generic netlink info */
 #define ETHTOOL_GENL_NAME "ethtool"
 #define ETHTOOL_GENL_VERSION 1
diff --git a/net/ethtool/Makefile b/net/ethtool/Makefile
index 11ceb00821b3..96d41dc45d4f 100644
--- a/net/ethtool/Makefile
+++ b/net/ethtool/Makefile
@@ -4,4 +4,4 @@ obj-y				+= ioctl.o common.o
 
 obj-$(CONFIG_ETHTOOL_NETLINK)	+= ethtool_nl.o
 
-ethtool_nl-y	:= netlink.o bitset.o strset.o
+ethtool_nl-y	:= netlink.o bitset.o strset.o info.o
diff --git a/net/ethtool/common.c b/net/ethtool/common.c
index 73f721a1c557..8da992129321 100644
--- a/net/ethtool/common.c
+++ b/net/ethtool/common.c
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
 
+#include <linux/rtnetlink.h>
+#include <net/devlink.h>
 #include "common.h"
 
 const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] = {
@@ -81,3 +83,53 @@ phy_tunable_strings[__ETHTOOL_PHY_TUNABLE_COUNT][ETH_GSTRING_LEN] = {
 	[ETHTOOL_ID_UNSPEC]     = "Unspec",
 	[ETHTOOL_PHY_DOWNSHIFT]	= "phy-downshift",
 };
+
+int __ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	const struct ethtool_ops *ops = dev->ethtool_ops;
+
+	memset(info, 0, sizeof(*info));
+	info->cmd = ETHTOOL_GDRVINFO;
+	if (ops->get_drvinfo) {
+		ops->get_drvinfo(dev, info);
+	} else if (dev->dev.parent && dev->dev.parent->driver) {
+		strlcpy(info->bus_info, dev_name(dev->dev.parent),
+			sizeof(info->bus_info));
+		strlcpy(info->driver, dev->dev.parent->driver->name,
+			sizeof(info->driver));
+	} else {
+		return -EOPNOTSUPP;
+	}
+
+	/* this method of obtaining string set info is deprecated;
+	 * Use ETHTOOL_GSSET_INFO instead.
+	 */
+	if (ops->get_sset_count) {
+		int rc;
+
+		rc = ops->get_sset_count(dev, ETH_SS_TEST);
+		if (rc >= 0)
+			info->testinfo_len = rc;
+		rc = ops->get_sset_count(dev, ETH_SS_STATS);
+		if (rc >= 0)
+			info->n_stats = rc;
+		rc = ops->get_sset_count(dev, ETH_SS_PRIV_FLAGS);
+		if (rc >= 0)
+			info->n_priv_flags = rc;
+	}
+	if (ops->get_regs_len) {
+		int ret = ops->get_regs_len(dev);
+
+		if (ret > 0)
+			info->regdump_len = ret;
+	}
+
+	if (ops->get_eeprom_len)
+		info->eedump_len = ops->get_eeprom_len(dev);
+
+	if (!info->fw_version[0])
+		devlink_compat_running_version(dev, info->fw_version,
+					       sizeof(info->fw_version));
+
+	return 0;
+}
diff --git a/net/ethtool/common.h b/net/ethtool/common.h
index 41b2efc1e4e1..e87e58b3a274 100644
--- a/net/ethtool/common.h
+++ b/net/ethtool/common.h
@@ -3,6 +3,7 @@
 #ifndef _ETHTOOL_COMMON_H
 #define _ETHTOOL_COMMON_H
 
+#include <linux/netdevice.h>
 #include <linux/ethtool.h>
 
 extern const char
@@ -14,4 +15,5 @@ tunable_strings[__ETHTOOL_TUNABLE_COUNT][ETH_GSTRING_LEN];
 extern const char
 phy_tunable_strings[__ETHTOOL_PHY_TUNABLE_COUNT][ETH_GSTRING_LEN];
 
+int __ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
 #endif /* _ETHTOOL_COMMON_H */
diff --git a/net/ethtool/info.c b/net/ethtool/info.c
new file mode 100644
index 000000000000..cc42993bb05b
--- /dev/null
+++ b/net/ethtool/info.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+
+#include "netlink.h"
+#include "common.h"
+#include "bitset.h"
+
+struct info_data {
+	struct common_req_info		reqinfo_base;
+
+	/* everything below here will be reset for each device in dumps */
+	struct common_reply_data	repdata_base;
+	struct ethtool_drvinfo		drvinfo;
+};
+
+static const struct nla_policy get_info_policy[ETHA_INFO_MAX + 1] = {
+	[ETHA_INFO_UNSPEC]		= { .type = NLA_REJECT },
+	[ETHA_INFO_DEV]			= { .type = NLA_NESTED },
+	[ETHA_INFO_INFOMASK]		= { .type = NLA_U32 },
+	[ETHA_INFO_COMPACT]		= { .type = NLA_FLAG },
+	[ETHA_INFO_DRVINFO]		= { .type = NLA_REJECT },
+};
+
+/* parse_request() handler */
+static int parse_info(struct common_req_info *req_info, struct sk_buff *skb,
+		      struct genl_info *info, const struct nlmsghdr *nlhdr)
+{
+	struct nlattr *tb[ETHA_INFO_MAX + 1];
+	int ret;
+
+	ret = ethnlmsg_parse(nlhdr, tb, ETHA_INFO_MAX, get_info_policy, info);
+	if (ret < 0)
+		return ret;
+
+	if (tb[ETHA_INFO_DEV]) {
+		req_info->dev = ethnl_dev_get(info, tb[ETHA_INFO_DEV]);
+		if (IS_ERR(req_info->dev)) {
+			ret = PTR_ERR(req_info->dev);
+			req_info->dev = NULL;
+			return ret;
+		}
+	}
+	if (tb[ETHA_INFO_INFOMASK])
+		req_info->req_mask = nla_get_u32(tb[ETHA_INFO_INFOMASK]);
+	if (tb[ETHA_INFO_COMPACT])
+		req_info->compact = true;
+	if (req_info->req_mask == 0)
+		req_info->req_mask = ETH_INFO_IM_ALL;
+
+	return 0;
+}
+
+/* prepare_data() handler */
+static int prepare_info(struct common_req_info *req_info,
+			struct genl_info *info)
+{
+	struct info_data *data =
+		container_of(req_info, struct info_data, reqinfo_base);
+	struct net_device *dev = data->repdata_base.dev;
+	u32 req_mask = req_info->req_mask & ETH_INFO_IM_ALL;
+	int ret;
+
+	ret = ethnl_before_ops(dev);
+	if (ret < 0)
+		return ret;
+	if (req_mask & ETH_INFO_IM_DRVINFO) {
+		ret = __ethtool_get_drvinfo(dev, &data->drvinfo);
+		if (ret < 0)
+			req_mask &= ~ETH_INFO_IM_DRVINFO;
+	}
+	ethnl_after_ops(dev);
+
+	data->repdata_base.info_mask = req_mask;
+	if (req_info->req_mask & ~req_mask)
+		warn_partial_info(info);
+	return 0;
+}
+
+static int drvinfo_size(const struct ethtool_drvinfo *drvinfo)
+{
+	int len = 0;
+
+	len += ethnl_str_ifne_size(drvinfo->driver);
+	len += ethnl_str_ifne_size(drvinfo->fw_version);
+	len += ethnl_str_ifne_size(drvinfo->bus_info);
+	len += ethnl_str_ifne_size(drvinfo->erom_version);
+
+	return nla_total_size(len);
+}
+
+/* reply_size() handler */
+static int info_size(const struct common_req_info *req_info)
+{
+	const struct info_data *data =
+		container_of(req_info, struct info_data, reqinfo_base);
+	u32 info_mask = data->repdata_base.info_mask;
+	int len = 0;
+
+	len += dev_ident_size();
+	if (info_mask & ETH_INFO_IM_DRVINFO)
+		len += drvinfo_size(&data->drvinfo);
+
+	return len;
+}
+
+static int fill_drvinfo(struct sk_buff *skb,
+			const struct ethtool_drvinfo *drvinfo)
+{
+	struct nlattr *nest = ethnl_nest_start(skb, ETHA_INFO_DRVINFO);
+	int ret;
+
+	if (!nest)
+		return -EMSGSIZE;
+	ret = -EMSGSIZE;
+	if (ethnl_put_str_ifne(skb, ETHA_DRVINFO_DRIVER, drvinfo->driver) ||
+	    ethnl_put_str_ifne(skb, ETHA_DRVINFO_FWVERSION,
+			       drvinfo->fw_version) ||
+	    ethnl_put_str_ifne(skb, ETHA_DRVINFO_BUSINFO, drvinfo->bus_info) ||
+	    ethnl_put_str_ifne(skb, ETHA_DRVINFO_EROM_VER,
+			       drvinfo->erom_version))
+		goto err;
+
+	nla_nest_end(skb, nest);
+	return 0;
+err:
+	nla_nest_cancel(skb, nest);
+	return ret;
+}
+
+/* fill_reply() handler */
+static int fill_info(struct sk_buff *skb,
+		     const struct common_req_info *req_info)
+{
+	const struct info_data *data =
+		container_of(req_info, struct info_data, reqinfo_base);
+	u32 info_mask = data->repdata_base.info_mask;
+	int ret;
+
+	if (info_mask & ETH_INFO_IM_DRVINFO) {
+		ret = fill_drvinfo(skb, &data->drvinfo);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+const struct get_request_ops info_request_ops = {
+	.request_cmd		= ETHNL_CMD_GET_INFO,
+	.reply_cmd		= ETHNL_CMD_SET_INFO,
+	.dev_attrtype		= ETHA_INFO_DEV,
+	.data_size		= sizeof(struct info_data),
+	.repdata_offset		= offsetof(struct info_data, repdata_base),
+
+	.parse_request		= parse_info,
+	.prepare_data		= prepare_info,
+	.reply_size		= info_size,
+	.fill_reply		= fill_info,
+};
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 04d747056070..844a4f4b1552 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -685,54 +685,14 @@ static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
 						  void __user *useraddr)
 {
 	struct ethtool_drvinfo info;
-	const struct ethtool_ops *ops = dev->ethtool_ops;
-
-	memset(&info, 0, sizeof(info));
-	info.cmd = ETHTOOL_GDRVINFO;
-	if (ops->get_drvinfo) {
-		ops->get_drvinfo(dev, &info);
-	} else if (dev->dev.parent && dev->dev.parent->driver) {
-		strlcpy(info.bus_info, dev_name(dev->dev.parent),
-			sizeof(info.bus_info));
-		strlcpy(info.driver, dev->dev.parent->driver->name,
-			sizeof(info.driver));
-	} else {
-		return -EOPNOTSUPP;
-	}
-
-	/*
-	 * this method of obtaining string set info is deprecated;
-	 * Use ETHTOOL_GSSET_INFO instead.
-	 */
-	if (ops->get_sset_count) {
-		int rc;
-
-		rc = ops->get_sset_count(dev, ETH_SS_TEST);
-		if (rc >= 0)
-			info.testinfo_len = rc;
-		rc = ops->get_sset_count(dev, ETH_SS_STATS);
-		if (rc >= 0)
-			info.n_stats = rc;
-		rc = ops->get_sset_count(dev, ETH_SS_PRIV_FLAGS);
-		if (rc >= 0)
-			info.n_priv_flags = rc;
-	}
-	if (ops->get_regs_len) {
-		int ret = ops->get_regs_len(dev);
-
-		if (ret > 0)
-			info.regdump_len = ret;
-	}
-
-	if (ops->get_eeprom_len)
-		info.eedump_len = ops->get_eeprom_len(dev);
-
-	if (!info.fw_version[0])
-		devlink_compat_running_version(dev, info.fw_version,
-					       sizeof(info.fw_version));
+	int rc;
 
+	rc = __ethtool_get_drvinfo(dev, &info);
+	if (rc < 0)
+		return rc;
 	if (copy_to_user(useraddr, &info, sizeof(info)))
 		return -EFAULT;
+
 	return 0;
 }
 
diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
index 3559f5c7040f..ab30f77eda25 100644
--- a/net/ethtool/netlink.c
+++ b/net/ethtool/netlink.c
@@ -153,6 +153,7 @@ struct sk_buff *ethnl_reply_init(size_t payload, struct net_device *dev, u8 cmd,
 
 const struct get_request_ops *get_requests[__ETHNL_CMD_CNT] = {
 	[ETHNL_CMD_GET_STRSET]		= &strset_request_ops,
+	[ETHNL_CMD_GET_INFO]		= &info_request_ops,
 };
 
 /**
@@ -564,6 +565,13 @@ static const struct genl_ops ethtool_genl_ops[] = {
 		.dumpit	= ethnl_get_dumpit,
 		.done	= ethnl_get_done,
 	},
+	{
+		.cmd	= ETHNL_CMD_GET_INFO,
+		.doit	= ethnl_get_doit,
+		.start	= ethnl_get_start,
+		.dumpit	= ethnl_get_dumpit,
+		.done	= ethnl_get_done,
+	},
 };
 
 static const struct genl_multicast_group ethtool_nl_mcgrps[] = {
diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h
index 32d85bb5c49a..48980ae9e963 100644
--- a/net/ethtool/netlink.h
+++ b/net/ethtool/netlink.h
@@ -278,5 +278,6 @@ struct get_request_ops {
 /* request handlers */
 
 extern const struct get_request_ops strset_request_ops;
+extern const struct get_request_ops info_request_ops;
 
 #endif /* _NET_ETHTOOL_NETLINK_H */
-- 
2.21.0


  parent reply	other threads:[~2019-03-21 13:41 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-21 13:40 [PATCH net-next v4 00/22] ethtool netlink interface, part 1 Michal Kubecek
2019-03-21 13:31 ` Michal Kubecek
2019-03-21 13:56   ` Michal Kubecek
2019-03-21 13:40 ` [PATCH net-next v4 01/22] rtnetlink: provide permanent hardware address in RTM_NEWLINK Michal Kubecek
2019-03-21 15:47   ` Stephen Hemminger
2019-03-21 20:35   ` Jakub Kicinski
2019-03-22  6:32     ` Michal Kubecek
2019-03-21 21:58   ` David Miller
2019-03-21 13:40 ` [PATCH net-next v4 02/22] netlink: introduce nla_put_bitfield32() Michal Kubecek
2019-03-21 13:40 ` [PATCH net-next v4 03/22] netlink: add strict version of nla_parse_nested() Michal Kubecek
2019-03-21 13:40 ` [PATCH net-next v4 04/22] ethtool: move to its own directory Michal Kubecek
2019-03-21 13:40 ` [PATCH net-next v4 05/22] ethtool: introduce ethtool netlink interface Michal Kubecek
2019-03-21 13:57   ` Andrew Lunn
2019-03-21 14:13     ` Michal Kubecek
2019-03-21 15:25       ` Andrew Lunn
2019-03-21 16:21         ` Jiri Pirko
2019-03-21 16:47         ` Michal Kubecek
2019-03-21 13:40 ` [PATCH net-next v4 06/22] ethtool: helper functions for " Michal Kubecek
2019-03-21 13:40 ` [PATCH net-next v4 07/22] ethtool: netlink bitset handling Michal Kubecek
2019-03-21 13:40 ` [PATCH net-next v4 08/22] ethtool: support for netlink notifications Michal Kubecek
2019-03-21 13:40 ` [PATCH net-next v4 09/22] ethtool: implement EVENT notifications Michal Kubecek
2019-03-21 13:40 ` [PATCH net-next v4 10/22] ethtool: generic handlers for GET requests Michal Kubecek
2019-03-21 13:40 ` [PATCH net-next v4 11/22] ethtool: move string arrays into common file Michal Kubecek
2019-03-21 13:40 ` [PATCH net-next v4 12/22] ethtool: provide string sets with GET_STRSET request Michal Kubecek
2019-03-21 13:40 ` Michal Kubecek [this message]
2019-03-21 13:41 ` [PATCH net-next v4 14/22] ethtool: provide timestamping information in GET_INFO request Michal Kubecek
2019-03-21 13:41 ` [PATCH net-next v4 15/22] ethtool: provide link mode names as a string set Michal Kubecek
2019-03-21 13:41 ` [PATCH net-next v4 16/22] ethtool: provide link settings and link modes in GET_SETTINGS request Michal Kubecek
2019-03-21 13:41 ` [PATCH net-next v4 17/22] ethtool: set link settings and link modes with SET_SETTINGS request Michal Kubecek
2019-03-21 13:41 ` [PATCH net-next v4 18/22] ethtool: provide link state in GET_SETTINGS request Michal Kubecek
2019-03-21 13:41 ` [PATCH net-next v4 19/22] ethtool: provide WoL information " Michal Kubecek
2019-03-21 13:41 ` [PATCH net-next v4 20/22] ethtool: set WoL settings with SET_SETTINGS request Michal Kubecek
2019-03-21 13:41 ` [PATCH net-next v4 21/22] ethtool: provide message level in GET_SETTINGS request Michal Kubecek
2019-03-21 13:41 ` [PATCH net-next v4 22/22] ethtool: set message level with SET_SETTINGS request Michal Kubecek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=084e52d43a6809a5ef2000c089a00540e8d54e72.1553170807.git.mkubecek@suse.cz \
    --to=mkubecek@suse.cz \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=f.fainelli@gmail.com \
    --cc=jakub.kicinski@netronome.com \
    --cc=jiri@resnulli.us \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.