summaryrefslogtreecommitdiff
path: root/net/ethtool
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2020-05-10 21:12:40 +0200
committerJakub Kicinski <kuba@kernel.org>2020-05-10 12:28:41 -0700
commit9896a4574ecb137d4e5b9283004aa34c688bc761 (patch)
tree663521d696ca521b454ae286dc01af09981bc26e /net/ethtool
parent4a459bdc7472b0e6bea6d0dd8df66253ac4f3fe2 (diff)
downloadlwn-9896a4574ecb137d4e5b9283004aa34c688bc761.tar.gz
lwn-9896a4574ecb137d4e5b9283004aa34c688bc761.zip
net: phy: Send notifier when starting the cable test
Given that it takes time to run a cable test, send a notify message at the start, as well as when it is completed. v3: EMSGSIZE when ethnl_bcastmsg_put() fails Print an error message on failure, since this is a void function. 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>
Diffstat (limited to 'net/ethtool')
-rw-r--r--net/ethtool/cabletest.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/net/ethtool/cabletest.c b/net/ethtool/cabletest.c
index e0c917918c70..5ba06eabe8c2 100644
--- a/net/ethtool/cabletest.c
+++ b/net/ethtool/cabletest.c
@@ -13,6 +13,43 @@ cable_test_act_policy[ETHTOOL_A_CABLE_TEST_MAX + 1] = {
[ETHTOOL_A_CABLE_TEST_HEADER] = { .type = NLA_NESTED },
};
+static int ethnl_cable_test_started(struct phy_device *phydev)
+{
+ struct sk_buff *skb;
+ int err = -ENOMEM;
+ void *ehdr;
+
+ skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!skb)
+ goto out;
+
+ ehdr = ethnl_bcastmsg_put(skb, ETHTOOL_MSG_CABLE_TEST_NTF);
+ if (!ehdr) {
+ err = -EMSGSIZE;
+ goto out;
+ }
+
+ err = ethnl_fill_reply_header(skb, phydev->attached_dev,
+ ETHTOOL_A_CABLE_TEST_NTF_HEADER);
+ if (err)
+ goto out;
+
+ err = nla_put_u8(skb, ETHTOOL_A_CABLE_TEST_NTF_STATUS,
+ ETHTOOL_A_CABLE_TEST_NTF_STATUS_STARTED);
+ if (err)
+ goto out;
+
+ genlmsg_end(skb, ehdr);
+
+ return ethnl_multicast(skb, phydev->attached_dev);
+
+out:
+ nlmsg_free(skb);
+ phydev_err(phydev, "%s: Error %pe\n", __func__, ERR_PTR(err));
+
+ return err;
+}
+
int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info)
{
struct nlattr *tb[ETHTOOL_A_CABLE_TEST_MAX + 1];
@@ -47,6 +84,10 @@ int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info)
ret = phy_start_cable_test(dev->phydev, info->extack);
ethnl_ops_complete(dev);
+
+ if (!ret)
+ ethnl_cable_test_started(dev->phydev);
+
out_rtnl:
rtnl_unlock();
out_dev_put: