Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: ethtool: cable-test: Target the command to the requested PHY

Cable testing is a PHY-specific command. Instead of targeting the command
towards dev->phydev, use the request to pick the targeted PHY.

Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Tested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Maxime Chevallier and committed by
David S. Miller
3688ff30 31748765

+22 -13
+22 -13
net/ethtool/cabletest.c
··· 13 13 14 14 const struct nla_policy ethnl_cable_test_act_policy[] = { 15 15 [ETHTOOL_A_CABLE_TEST_HEADER] = 16 - NLA_POLICY_NESTED(ethnl_header_policy), 16 + NLA_POLICY_NESTED(ethnl_header_policy_phy), 17 17 }; 18 18 19 19 static int ethnl_cable_test_started(struct phy_device *phydev, u8 cmd) ··· 58 58 struct ethnl_req_info req_info = {}; 59 59 const struct ethtool_phy_ops *ops; 60 60 struct nlattr **tb = info->attrs; 61 + struct phy_device *phydev; 61 62 struct net_device *dev; 62 63 int ret; 63 64 ··· 70 69 return ret; 71 70 72 71 dev = req_info.dev; 73 - if (!dev->phydev) { 72 + 73 + rtnl_lock(); 74 + phydev = ethnl_req_get_phydev(&req_info, 75 + tb[ETHTOOL_A_CABLE_TEST_HEADER], 76 + info->extack); 77 + if (IS_ERR_OR_NULL(phydev)) { 74 78 ret = -EOPNOTSUPP; 75 79 goto out_dev_put; 76 80 } 77 81 78 - rtnl_lock(); 79 82 ops = ethtool_phy_ops; 80 83 if (!ops || !ops->start_cable_test) { 81 84 ret = -EOPNOTSUPP; ··· 90 85 if (ret < 0) 91 86 goto out_rtnl; 92 87 93 - ret = ops->start_cable_test(dev->phydev, info->extack); 88 + ret = ops->start_cable_test(phydev, info->extack); 94 89 95 90 ethnl_ops_complete(dev); 96 91 97 92 if (!ret) 98 - ethnl_cable_test_started(dev->phydev, 99 - ETHTOOL_MSG_CABLE_TEST_NTF); 93 + ethnl_cable_test_started(phydev, ETHTOOL_MSG_CABLE_TEST_NTF); 100 94 101 95 out_rtnl: 102 96 rtnl_unlock(); ··· 220 216 221 217 const struct nla_policy ethnl_cable_test_tdr_act_policy[] = { 222 218 [ETHTOOL_A_CABLE_TEST_TDR_HEADER] = 223 - NLA_POLICY_NESTED(ethnl_header_policy), 219 + NLA_POLICY_NESTED(ethnl_header_policy_phy), 224 220 [ETHTOOL_A_CABLE_TEST_TDR_CFG] = { .type = NLA_NESTED }, 225 221 }; 226 222 ··· 309 305 struct ethnl_req_info req_info = {}; 310 306 const struct ethtool_phy_ops *ops; 311 307 struct nlattr **tb = info->attrs; 308 + struct phy_device *phydev; 312 309 struct phy_tdr_config cfg; 313 310 struct net_device *dev; 314 311 int ret; ··· 322 317 return ret; 323 318 324 319 dev = req_info.dev; 325 - if (!dev->phydev) { 326 - ret = -EOPNOTSUPP; 327 - goto out_dev_put; 328 - } 329 320 330 321 ret = ethnl_act_cable_test_tdr_cfg(tb[ETHTOOL_A_CABLE_TEST_TDR_CFG], 331 322 info, &cfg); ··· 329 328 goto out_dev_put; 330 329 331 330 rtnl_lock(); 331 + phydev = ethnl_req_get_phydev(&req_info, 332 + tb[ETHTOOL_A_CABLE_TEST_TDR_HEADER], 333 + info->extack); 334 + if (!IS_ERR_OR_NULL(phydev)) { 335 + ret = -EOPNOTSUPP; 336 + goto out_dev_put; 337 + } 338 + 332 339 ops = ethtool_phy_ops; 333 340 if (!ops || !ops->start_cable_test_tdr) { 334 341 ret = -EOPNOTSUPP; ··· 347 338 if (ret < 0) 348 339 goto out_rtnl; 349 340 350 - ret = ops->start_cable_test_tdr(dev->phydev, info->extack, &cfg); 341 + ret = ops->start_cable_test_tdr(phydev, info->extack, &cfg); 351 342 352 343 ethnl_ops_complete(dev); 353 344 354 345 if (!ret) 355 - ethnl_cable_test_started(dev->phydev, 346 + ethnl_cable_test_started(phydev, 356 347 ETHTOOL_MSG_CABLE_TEST_TDR_NTF); 357 348 358 349 out_rtnl: