[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <bc656ef4e9b65a9b4e59c4833d5ff9faeea821f5.1581892124.git.mkubecek@suse.cz>
Date: Sun, 16 Feb 2020 23:48:01 +0100 (CET)
From: Michal Kubecek <mkubecek@...e.cz>
To: John Linville <linville@...driver.com>, netdev@...r.kernel.org
Cc: Andrew Lunn <andrew@...n.ch>,
Florian Fainelli <f.fainelli@...il.com>
Subject: [PATCH ethtool 18/19] netlink: add netlink handler for sset (-s)
Implement "ethtool -s <dev>" subcommand using netlink interface request
ETHTOOL_MSG_LINKINFO_SET, ETHTOOL_MSG_LINKMODES_SET, ETHTOOL_MSG_WOL_SET
and ETHTOOL_MSG_DEBUG_SET.
Parser grouping with PARSER_GROUP_MSG group style is used to create
multiple request messages from one set of attributes which can be in
arbitrary order.
Signed-off-by: Michal Kubecek <mkubecek@...e.cz>
---
ethtool.8.in | 15 ++--
ethtool.c | 9 ++-
netlink/extapi.h | 2 +
netlink/settings.c | 193 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 210 insertions(+), 9 deletions(-)
diff --git a/ethtool.8.in b/ethtool.8.in
index 28e4f75eee8d..ba85cfe4f413 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -242,16 +242,21 @@ ethtool \- query or control network driver and hardware settings
.I devname
.BN speed
.B2 duplex half full
-.B4 port tp aui bnc mii fibre
+.B4 port tp aui bnc mii fibre da
.B3 mdix auto on off
.B2 autoneg on off
-.BN advertise
+.RB [ advertise \ \fIN\fP[\fB/\fP\fIM\fP]
+|
+.BI advertise \ mode
+.A1 on off
+.RB ...]
.BN phyad
.B2 xcvr internal external
-.RB [ wol \ \*(WO]
+.RB [ wol \ \fIN\fP[\fB/\fP\fIM\fP]
+.RB | \ wol \ \*(WO]
.RB [ sopass \ \*(MA]
.RB [ msglvl
-.IR N \ |
+.IR N\fP[/\fIM\fP] \ |
.BI msglvl \ type
.A1 on off
.RB ...]
@@ -638,7 +643,7 @@ with just the device name as an argument will show you the supported device spee
.A2 duplex half full
Sets full or half duplex mode.
.TP
-.A4 port tp aui bnc mii fibre
+.A4 port tp aui bnc mii fibre da
Selects device port.
.TP
.A3 mdix auto on off
diff --git a/ethtool.c b/ethtool.c
index a69233bd73fc..baa6458bb486 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -5166,18 +5166,19 @@ static const struct option args[] = {
{
.opts = "-s|--change",
.func = do_sset,
+ .nlfunc = nl_sset,
.help = "Change generic options",
.xhelp = " [ speed %d ]\n"
" [ duplex half|full ]\n"
- " [ port tp|aui|bnc|mii|fibre ]\n"
+ " [ port tp|aui|bnc|mii|fibre|da ]\n"
" [ mdix auto|on|off ]\n"
" [ autoneg on|off ]\n"
- " [ advertise %x ]\n"
+ " [ advertise %x[/%x] | mode on|off ... [--] ]\n"
" [ phyad %d ]\n"
" [ xcvr internal|external ]\n"
- " [ wol p|u|m|b|a|g|s|f|d... ]\n"
+ " [ wol %d[/%d] | p|u|m|b|a|g|s|f|d... ]\n"
" [ sopass %x:%x:%x:%x:%x:%x ]\n"
- " [ msglvl %d | msglvl type on|off ... ]\n"
+ " [ msglvl %d[/%d] | type on|off ... [--] ]\n"
},
{
.opts = "-a|--show-pause",
diff --git a/netlink/extapi.h b/netlink/extapi.h
index 8608ea7f51f5..612002e8228b 100644
--- a/netlink/extapi.h
+++ b/netlink/extapi.h
@@ -16,6 +16,7 @@ int netlink_init(struct cmd_context *ctx);
void netlink_done(struct cmd_context *ctx);
int nl_gset(struct cmd_context *ctx);
+int nl_sset(struct cmd_context *ctx);
int nl_monitor(struct cmd_context *ctx);
void nl_monitor_usage(void);
@@ -36,6 +37,7 @@ static inline void nl_monitor_usage(void)
}
#define nl_gset NULL
+#define nl_sset NULL
#endif /* ETHTOOL_ENABLE_NETLINK */
diff --git a/netlink/settings.c b/netlink/settings.c
index fed121471d0f..9922747470ce 100644
--- a/netlink/settings.c
+++ b/netlink/settings.c
@@ -13,6 +13,7 @@
#include "netlink.h"
#include "strset.h"
#include "bitset.h"
+#include "parser.h"
/* GET_SETTINGS */
@@ -750,3 +751,195 @@ int nl_gset(struct cmd_context *ctx)
err:
return 75;
}
+
+/* SET_SETTINGS */
+
+enum {
+ WAKE_PHY_BIT = 0,
+ WAKE_UCAST_BIT = 1,
+ WAKE_MCAST_BIT = 2,
+ WAKE_BCAST_BIT = 3,
+ WAKE_ARP_BIT = 4,
+ WAKE_MAGIC_BIT = 5,
+ WAKE_MAGICSECURE_BIT = 6,
+ WAKE_FILTER_BIT = 7,
+};
+
+#define WAKE_ALL (WAKE_PHY | WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_ARP | \
+ WAKE_MAGIC | WAKE_MAGICSECURE)
+
+static const struct lookup_entry_u8 port_values[] = {
+ { .arg = "tp", .val = PORT_TP },
+ { .arg = "aui", .val = PORT_AUI },
+ { .arg = "mii", .val = PORT_MII },
+ { .arg = "fibre", .val = PORT_FIBRE },
+ { .arg = "bnc", .val = PORT_BNC },
+ { .arg = "da", .val = PORT_DA },
+ {}
+};
+
+static const struct lookup_entry_u8 mdix_values[] = {
+ { .arg = "auto", .val = ETH_TP_MDI_AUTO },
+ { .arg = "on", .val = ETH_TP_MDI_X },
+ { .arg = "off", .val = ETH_TP_MDI },
+ {}
+};
+
+static const struct error_parser_data xcvr_parser_data = {
+ .err_msg = "deprecated parameter '%s' not supported by kernel\n",
+ .ret_val = -EINVAL,
+ .extra_args = 1,
+};
+
+static const struct lookup_entry_u8 autoneg_values[] = {
+ { .arg = "off", .val = AUTONEG_DISABLE },
+ { .arg = "on", .val = AUTONEG_ENABLE },
+ {}
+};
+
+static const struct bitset_parser_data advertise_parser_data = {
+ .no_mask = false,
+ .force_hex = true,
+};
+
+static const struct lookup_entry_u32 duplex_values[] = {
+ { .arg = "half", .val = DUPLEX_HALF },
+ { .arg = "full", .val = DUPLEX_FULL },
+ {}
+};
+
+char wol_bit_chars[WOL_MODE_COUNT] = {
+ [WAKE_PHY_BIT] = 'p',
+ [WAKE_UCAST_BIT] = 'u',
+ [WAKE_MCAST_BIT] = 'm',
+ [WAKE_BCAST_BIT] = 'b',
+ [WAKE_ARP_BIT] = 'a',
+ [WAKE_MAGIC_BIT] = 'g',
+ [WAKE_MAGICSECURE_BIT] = 's',
+ [WAKE_FILTER_BIT] = 'f',
+};
+
+const struct char_bitset_parser_data wol_parser_data = {
+ .bit_chars = wol_bit_chars,
+ .nbits = WOL_MODE_COUNT,
+ .reset_char = 'd',
+};
+
+const struct byte_str_parser_data sopass_parser_data = {
+ .min_len = 6,
+ .max_len = 6,
+ .delim = ':',
+};
+
+static const struct bitset_parser_data msglvl_parser_data = {
+ .no_mask = false,
+ .force_hex = false,
+};
+
+static const struct param_parser sset_params[] = {
+ {
+ .arg = "port",
+ .group = ETHTOOL_MSG_LINKINFO_SET,
+ .type = ETHTOOL_A_LINKINFO_PORT,
+ .handler = nl_parse_lookup_u8,
+ .handler_data = port_values,
+ .min_argc = 1,
+ },
+ {
+ .arg = "mdix",
+ .group = ETHTOOL_MSG_LINKINFO_SET,
+ .type = ETHTOOL_A_LINKINFO_TP_MDIX_CTRL,
+ .handler = nl_parse_lookup_u8,
+ .handler_data = mdix_values,
+ .min_argc = 1,
+ },
+ {
+ .arg = "phyad",
+ .group = ETHTOOL_MSG_LINKINFO_SET,
+ .type = ETHTOOL_A_LINKINFO_PHYADDR,
+ .handler = nl_parse_direct_u8,
+ .min_argc = 1,
+ },
+ {
+ .arg = "xcvr",
+ .group = ETHTOOL_MSG_LINKINFO_SET,
+ .handler = nl_parse_error,
+ .handler_data = &xcvr_parser_data,
+ .min_argc = 1,
+ },
+ {
+ .arg = "autoneg",
+ .group = ETHTOOL_MSG_LINKMODES_SET,
+ .type = ETHTOOL_A_LINKMODES_AUTONEG,
+ .handler = nl_parse_lookup_u8,
+ .handler_data = autoneg_values,
+ .min_argc = 1,
+ },
+ {
+ .arg = "advertise",
+ .group = ETHTOOL_MSG_LINKMODES_SET,
+ .type = ETHTOOL_A_LINKMODES_OURS,
+ .handler = nl_parse_bitset,
+ .handler_data = &advertise_parser_data,
+ .min_argc = 1,
+ },
+ {
+ .arg = "speed",
+ .group = ETHTOOL_MSG_LINKMODES_SET,
+ .type = ETHTOOL_A_LINKMODES_SPEED,
+ .handler = nl_parse_direct_u32,
+ .min_argc = 1,
+ },
+ {
+ .arg = "duplex",
+ .group = ETHTOOL_MSG_LINKMODES_SET,
+ .type = ETHTOOL_A_LINKMODES_DUPLEX,
+ .handler = nl_parse_lookup_u8,
+ .handler_data = duplex_values,
+ .min_argc = 1,
+ },
+ {
+ .arg = "wol",
+ .group = ETHTOOL_MSG_WOL_SET,
+ .type = ETHTOOL_A_WOL_MODES,
+ .handler = nl_parse_char_bitset,
+ .handler_data = &wol_parser_data,
+ .min_argc = 1,
+ },
+ {
+ .arg = "sopass",
+ .group = ETHTOOL_MSG_WOL_SET,
+ .type = ETHTOOL_A_WOL_SOPASS,
+ .handler = nl_parse_byte_str,
+ .handler_data = &sopass_parser_data,
+ .min_argc = 1,
+ },
+ {
+ .arg = "msglvl",
+ .group = ETHTOOL_MSG_DEBUG_SET,
+ .type = ETHTOOL_A_DEBUG_MSGMASK,
+ .handler = nl_parse_bitset,
+ .handler_data = &msglvl_parser_data,
+ .min_argc = 1,
+ },
+ {}
+};
+
+int nl_sset(struct cmd_context *ctx)
+{
+ struct nl_context *nlctx = ctx->nlctx;
+ int ret;
+
+ nlctx->cmd = "-s";
+ nlctx->argp = ctx->argp;
+ nlctx->argc = ctx->argc;
+ nlctx->devname = ctx->devname;
+
+ ret = nl_parser(nlctx, sset_params, NULL, PARSER_GROUP_MSG);
+ if (ret < 0)
+ return 1;
+
+ if (ret == 0)
+ return 0;
+ return nlctx->exit_code ?: 75;
+}
--
2.25.0
Powered by blists - more mailing lists