net: ethtool: netlink: Add support for triggering a cable test

Add new ethtool netlink calls to trigger the starting of a PHY cable
test.

Add Kconfig'ury to ETHTOOL_NETLINK so that PHYLIB is not a module when
ETHTOOL_NETLINK is builtin, which would result in kernel linking errors.

v2:
Remove unwanted white space change
Remove ethnl_cable_test_act_ops and use doit handler
Rename cable_test_set_policy cable_test_act_policy
Remove ETHTOOL_MSG_CABLE_TEST_ACT_REPLY

v3:
Remove ETHTOOL_MSG_CABLE_TEST_ACT_REPLY from documentation
Remove unused cable_test_get_policy
Add Reviewed-by tags

v4:
Remove unwanted blank line

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Michal Kubecek <mkubecek@suse.cz>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Andrew Lunn
2020-05-10 21:12:33 +02:00
committed by Jakub Kicinski
parent 97c2243896
commit 11ca3c4261
7 changed files with 89 additions and 2 deletions

View File

@@ -204,6 +204,7 @@ Userspace to kernel:
``ETHTOOL_MSG_EEE_GET`` get EEE settings ``ETHTOOL_MSG_EEE_GET`` get EEE settings
``ETHTOOL_MSG_EEE_SET`` set EEE settings ``ETHTOOL_MSG_EEE_SET`` set EEE settings
``ETHTOOL_MSG_TSINFO_GET`` get timestamping info ``ETHTOOL_MSG_TSINFO_GET`` get timestamping info
``ETHTOOL_MSG_CABLE_TEST_ACT`` action start cable test
===================================== ================================ ===================================== ================================
Kernel to userspace: Kernel to userspace:
@@ -958,13 +959,25 @@ Kernel response contents:
is no special value for this case). The bitset attributes are omitted if they is no special value for this case). The bitset attributes are omitted if they
would be empty (no bit set). would be empty (no bit set).
CABLE_TEST
==========
Start a cable test.
Request contents:
==================================== ====== ==========================
``ETHTOOL_A_CABLE_TEST_HEADER`` nested request header
==================================== ====== ==========================
Request translation Request translation
=================== ===================
The following table maps ioctl commands to netlink commands providing their The following table maps ioctl commands to netlink commands providing their
functionality. Entries with "n/a" in right column are commands which do not functionality. Entries with "n/a" in right column are commands which do not
have their netlink replacement yet. have their netlink replacement yet. Entries which "n/a" in the left column
are netlink only.
=================================== ===================================== =================================== =====================================
ioctl command netlink command ioctl command netlink command
@@ -1053,4 +1066,5 @@ have their netlink replacement yet.
``ETHTOOL_PHY_STUNABLE`` n/a ``ETHTOOL_PHY_STUNABLE`` n/a
``ETHTOOL_GFECPARAM`` n/a ``ETHTOOL_GFECPARAM`` n/a
``ETHTOOL_SFECPARAM`` n/a ``ETHTOOL_SFECPARAM`` n/a
n/a ''ETHTOOL_MSG_CABLE_TEST_ACT''
=================================== ===================================== =================================== =====================================

View File

@@ -39,6 +39,7 @@ enum {
ETHTOOL_MSG_EEE_GET, ETHTOOL_MSG_EEE_GET,
ETHTOOL_MSG_EEE_SET, ETHTOOL_MSG_EEE_SET,
ETHTOOL_MSG_TSINFO_GET, ETHTOOL_MSG_TSINFO_GET,
ETHTOOL_MSG_CABLE_TEST_ACT,
/* add new constants above here */ /* add new constants above here */
__ETHTOOL_MSG_USER_CNT, __ETHTOOL_MSG_USER_CNT,
@@ -405,6 +406,17 @@ enum {
ETHTOOL_A_TSINFO_MAX = (__ETHTOOL_A_TSINFO_CNT - 1) ETHTOOL_A_TSINFO_MAX = (__ETHTOOL_A_TSINFO_CNT - 1)
}; };
/* CABLE TEST */
enum {
ETHTOOL_A_CABLE_TEST_UNSPEC,
ETHTOOL_A_CABLE_TEST_HEADER, /* nest - _A_HEADER_* */
/* add new constants above here */
__ETHTOOL_A_CABLE_TEST_CNT,
ETHTOOL_A_CABLE_TEST_MAX = __ETHTOOL_A_CABLE_TEST_CNT - 1
};
/* generic netlink info */ /* generic netlink info */
#define ETHTOOL_GENL_NAME "ethtool" #define ETHTOOL_GENL_NAME "ethtool"
#define ETHTOOL_GENL_VERSION 1 #define ETHTOOL_GENL_VERSION 1

View File

@@ -455,6 +455,7 @@ config FAILOVER
config ETHTOOL_NETLINK config ETHTOOL_NETLINK
bool "Netlink interface for ethtool" bool "Netlink interface for ethtool"
default y default y
depends on PHYLIB=y || PHYLIB=n
help help
An alternative userspace interface for ethtool based on generic An alternative userspace interface for ethtool based on generic
netlink. It provides better extensibility and some new features, netlink. It provides better extensibility and some new features,

View File

@@ -6,4 +6,4 @@ obj-$(CONFIG_ETHTOOL_NETLINK) += ethtool_nl.o
ethtool_nl-y := netlink.o bitset.o strset.o linkinfo.o linkmodes.o \ ethtool_nl-y := netlink.o bitset.o strset.o linkinfo.o linkmodes.o \
linkstate.o debug.o wol.o features.o privflags.o rings.o \ linkstate.o debug.o wol.o features.o privflags.o rings.o \
channels.o coalesce.o pause.o eee.o tsinfo.o channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o

54
net/ethtool/cabletest.c Normal file
View File

@@ -0,0 +1,54 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/phy.h>
#include "netlink.h"
#include "common.h"
/* CABLE_TEST_ACT */
static const struct nla_policy
cable_test_act_policy[ETHTOOL_A_CABLE_TEST_MAX + 1] = {
[ETHTOOL_A_CABLE_TEST_UNSPEC] = { .type = NLA_REJECT },
[ETHTOOL_A_CABLE_TEST_HEADER] = { .type = NLA_NESTED },
};
int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info)
{
struct nlattr *tb[ETHTOOL_A_CABLE_TEST_MAX + 1];
struct ethnl_req_info req_info = {};
struct net_device *dev;
int ret;
ret = nlmsg_parse(info->nlhdr, GENL_HDRLEN, tb,
ETHTOOL_A_CABLE_TEST_MAX,
cable_test_act_policy, info->extack);
if (ret < 0)
return ret;
ret = ethnl_parse_header_dev_get(&req_info,
tb[ETHTOOL_A_CABLE_TEST_HEADER],
genl_info_net(info), info->extack,
true);
if (ret < 0)
return ret;
dev = req_info.dev;
if (!dev->phydev) {
ret = -EOPNOTSUPP;
goto out_dev_put;
}
rtnl_lock();
ret = ethnl_ops_begin(dev);
if (ret < 0)
goto out_rtnl;
ret = phy_start_cable_test(dev->phydev, info->extack);
ethnl_ops_complete(dev);
out_rtnl:
rtnl_unlock();
out_dev_put:
dev_put(dev);
return ret;
}

View File

@@ -839,6 +839,11 @@ static const struct genl_ops ethtool_genl_ops[] = {
.dumpit = ethnl_default_dumpit, .dumpit = ethnl_default_dumpit,
.done = ethnl_default_done, .done = ethnl_default_done,
}, },
{
.cmd = ETHTOOL_MSG_CABLE_TEST_ACT,
.flags = GENL_UNS_ADMIN_PERM,
.doit = ethnl_act_cable_test,
},
}; };
static const struct genl_multicast_group ethtool_nl_mcgrps[] = { static const struct genl_multicast_group ethtool_nl_mcgrps[] = {

View File

@@ -357,5 +357,6 @@ int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info);
int ethnl_set_coalesce(struct sk_buff *skb, struct genl_info *info); int ethnl_set_coalesce(struct sk_buff *skb, struct genl_info *info);
int ethnl_set_pause(struct sk_buff *skb, struct genl_info *info); int ethnl_set_pause(struct sk_buff *skb, struct genl_info *info);
int ethnl_set_eee(struct sk_buff *skb, struct genl_info *info); int ethnl_set_eee(struct sk_buff *skb, struct genl_info *info);
int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info);
#endif /* _NET_ETHTOOL_NETLINK_H */ #endif /* _NET_ETHTOOL_NETLINK_H */