diff options
author | Andrew Lunn <andrew@lunn.ch> | 2020-05-10 21:12:36 +0200 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2020-05-10 12:28:41 -0700 |
commit | 1dd3f212af30b42c90ba252c165f2f6d2ddf5230 (patch) | |
tree | de9a4697a11d2968403b1de30b5f00a8974941d8 /net | |
parent | 0df960f14e17e55e68dfd1342f063d17dbcc6107 (diff) |
net: ethtool: Add infrastructure for reporting cable test results
Provide infrastructure for PHY drivers to report the cable test
results. A netlink skb is associated to the phydev. Helpers will be
added which can add results to this skb. Once the test has finished
the results are sent to user space.
When netlink ethtool is not part of the kernel configuration stubs are
provided. It is also impossible to trigger a cable test, so the error
code returned by the alloc function is of no consequence.
v2:
Include the status complete in the netlink notification message
v4:
Replace -EINVAL with -EMSGSIZE
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/ethtool/cabletest.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/net/ethtool/cabletest.c b/net/ethtool/cabletest.c index aeb6672a46d0..ae8e63647663 100644 --- a/net/ethtool/cabletest.c +++ b/net/ethtool/cabletest.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only #include <linux/phy.h> +#include <linux/ethtool_netlink.h> #include "netlink.h" #include "common.h" @@ -52,3 +53,57 @@ out_dev_put: dev_put(dev); return ret; } + +int ethnl_cable_test_alloc(struct phy_device *phydev) +{ + int err = -ENOMEM; + + phydev->skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!phydev->skb) + goto out; + + phydev->ehdr = ethnl_bcastmsg_put(phydev->skb, + ETHTOOL_MSG_CABLE_TEST_NTF); + if (!phydev->ehdr) { + err = -EMSGSIZE; + goto out; + } + + err = ethnl_fill_reply_header(phydev->skb, phydev->attached_dev, + ETHTOOL_A_CABLE_TEST_NTF_HEADER); + if (err) + goto out; + + err = nla_put_u8(phydev->skb, ETHTOOL_A_CABLE_TEST_NTF_STATUS, + ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED); + if (err) + goto out; + + phydev->nest = nla_nest_start(phydev->skb, + ETHTOOL_A_CABLE_TEST_NTF_NEST); + if (!phydev->nest) + goto out; + + return 0; + +out: + nlmsg_free(phydev->skb); + return err; +} +EXPORT_SYMBOL_GPL(ethnl_cable_test_alloc); + +void ethnl_cable_test_free(struct phy_device *phydev) +{ + nlmsg_free(phydev->skb); +} +EXPORT_SYMBOL_GPL(ethnl_cable_test_free); + +void ethnl_cable_test_finished(struct phy_device *phydev) +{ + nla_nest_end(phydev->skb, phydev->nest); + + genlmsg_end(phydev->skb, phydev->ehdr); + + ethnl_multicast(phydev->skb, phydev->attached_dev); +} +EXPORT_SYMBOL_GPL(ethnl_cable_test_finished); |