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

net: ethtool: strset: Allow querying phy stats by index

The ETH_SS_PHY_STATS command gets PHY statistics. Use the phydev pointer
from the ethnl request to allow query phy stats from each PHY on the
link.

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
e96c93aa 3688ff30

+17 -7
+17 -7
net/ethtool/strset.c
··· 126 126 127 127 const struct nla_policy ethnl_strset_get_policy[] = { 128 128 [ETHTOOL_A_STRSET_HEADER] = 129 - NLA_POLICY_NESTED(ethnl_header_policy), 129 + NLA_POLICY_NESTED(ethnl_header_policy_phy), 130 130 [ETHTOOL_A_STRSET_STRINGSETS] = { .type = NLA_NESTED }, 131 131 [ETHTOOL_A_STRSET_COUNTS_ONLY] = { .type = NLA_FLAG }, 132 132 }; ··· 233 233 } 234 234 235 235 static int strset_prepare_set(struct strset_info *info, struct net_device *dev, 236 - unsigned int id, bool counts_only) 236 + struct phy_device *phydev, unsigned int id, 237 + bool counts_only) 237 238 { 238 239 const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops; 239 240 const struct ethtool_ops *ops = dev->ethtool_ops; 240 241 void *strings; 241 242 int count, ret; 242 243 243 - if (id == ETH_SS_PHY_STATS && dev->phydev && 244 + if (id == ETH_SS_PHY_STATS && phydev && 244 245 !ops->get_ethtool_phy_stats && phy_ops && 245 246 phy_ops->get_sset_count) 246 - ret = phy_ops->get_sset_count(dev->phydev); 247 + ret = phy_ops->get_sset_count(phydev); 247 248 else if (ops->get_sset_count && ops->get_strings) 248 249 ret = ops->get_sset_count(dev, id); 249 250 else ··· 259 258 strings = kcalloc(count, ETH_GSTRING_LEN, GFP_KERNEL); 260 259 if (!strings) 261 260 return -ENOMEM; 262 - if (id == ETH_SS_PHY_STATS && dev->phydev && 261 + if (id == ETH_SS_PHY_STATS && phydev && 263 262 !ops->get_ethtool_phy_stats && phy_ops && 264 263 phy_ops->get_strings) 265 - phy_ops->get_strings(dev->phydev, strings); 264 + phy_ops->get_strings(phydev, strings); 266 265 else 267 266 ops->get_strings(dev, id, strings); 268 267 info->strings = strings; ··· 280 279 const struct strset_req_info *req_info = STRSET_REQINFO(req_base); 281 280 struct strset_reply_data *data = STRSET_REPDATA(reply_base); 282 281 struct net_device *dev = reply_base->dev; 282 + struct nlattr **tb = info->attrs; 283 + struct phy_device *phydev; 283 284 unsigned int i; 284 285 int ret; 285 286 ··· 299 296 return 0; 300 297 } 301 298 299 + phydev = ethnl_req_get_phydev(req_base, tb[ETHTOOL_A_HEADER_FLAGS], 300 + info->extack); 301 + 302 + /* phydev can be NULL, check for errors only */ 303 + if (IS_ERR(phydev)) 304 + return PTR_ERR(phydev); 305 + 302 306 ret = ethnl_ops_begin(dev); 303 307 if (ret < 0) 304 308 goto err_strset; ··· 314 304 !data->sets[i].per_dev) 315 305 continue; 316 306 317 - ret = strset_prepare_set(&data->sets[i], dev, i, 307 + ret = strset_prepare_set(&data->sets[i], dev, phydev, i, 318 308 req_info->counts_only); 319 309 if (ret < 0) 320 310 goto err_ops;