Commit 11ca3c42 authored by Andrew Lunn's avatar Andrew Lunn Committed by Jakub Kicinski

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: default avatarAndrew Lunn <andrew@lunn.ch>
Reviewed-by: default avatarMichal Kubecek <mkubecek@suse.cz>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 97c22438
...@@ -204,6 +204,7 @@ Userspace to kernel: ...@@ -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: ...@@ -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. ...@@ -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''
=================================== ===================================== =================================== =====================================
...@@ -39,6 +39,7 @@ enum { ...@@ -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 { ...@@ -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
......
...@@ -455,6 +455,7 @@ config FAILOVER ...@@ -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,
......
...@@ -6,4 +6,4 @@ obj-$(CONFIG_ETHTOOL_NETLINK) += ethtool_nl.o ...@@ -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
// 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;
}
...@@ -839,6 +839,11 @@ static const struct genl_ops ethtool_genl_ops[] = { ...@@ -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[] = {
......
...@@ -357,5 +357,6 @@ int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info); ...@@ -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 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment