mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 12:35:52 +02:00
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>
This commit is contained in:
parent
3688ff3077
commit
e96c93aa4b
|
|
@ -126,7 +126,7 @@ struct strset_reply_data {
|
||||||
|
|
||||||
const struct nla_policy ethnl_strset_get_policy[] = {
|
const struct nla_policy ethnl_strset_get_policy[] = {
|
||||||
[ETHTOOL_A_STRSET_HEADER] =
|
[ETHTOOL_A_STRSET_HEADER] =
|
||||||
NLA_POLICY_NESTED(ethnl_header_policy),
|
NLA_POLICY_NESTED(ethnl_header_policy_phy),
|
||||||
[ETHTOOL_A_STRSET_STRINGSETS] = { .type = NLA_NESTED },
|
[ETHTOOL_A_STRSET_STRINGSETS] = { .type = NLA_NESTED },
|
||||||
[ETHTOOL_A_STRSET_COUNTS_ONLY] = { .type = NLA_FLAG },
|
[ETHTOOL_A_STRSET_COUNTS_ONLY] = { .type = NLA_FLAG },
|
||||||
};
|
};
|
||||||
|
|
@ -233,17 +233,18 @@ static void strset_cleanup_data(struct ethnl_reply_data *reply_base)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int strset_prepare_set(struct strset_info *info, struct net_device *dev,
|
static int strset_prepare_set(struct strset_info *info, struct net_device *dev,
|
||||||
unsigned int id, bool counts_only)
|
struct phy_device *phydev, unsigned int id,
|
||||||
|
bool counts_only)
|
||||||
{
|
{
|
||||||
const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
|
const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
|
||||||
const struct ethtool_ops *ops = dev->ethtool_ops;
|
const struct ethtool_ops *ops = dev->ethtool_ops;
|
||||||
void *strings;
|
void *strings;
|
||||||
int count, ret;
|
int count, ret;
|
||||||
|
|
||||||
if (id == ETH_SS_PHY_STATS && dev->phydev &&
|
if (id == ETH_SS_PHY_STATS && phydev &&
|
||||||
!ops->get_ethtool_phy_stats && phy_ops &&
|
!ops->get_ethtool_phy_stats && phy_ops &&
|
||||||
phy_ops->get_sset_count)
|
phy_ops->get_sset_count)
|
||||||
ret = phy_ops->get_sset_count(dev->phydev);
|
ret = phy_ops->get_sset_count(phydev);
|
||||||
else if (ops->get_sset_count && ops->get_strings)
|
else if (ops->get_sset_count && ops->get_strings)
|
||||||
ret = ops->get_sset_count(dev, id);
|
ret = ops->get_sset_count(dev, id);
|
||||||
else
|
else
|
||||||
|
|
@ -258,10 +259,10 @@ static int strset_prepare_set(struct strset_info *info, struct net_device *dev,
|
||||||
strings = kcalloc(count, ETH_GSTRING_LEN, GFP_KERNEL);
|
strings = kcalloc(count, ETH_GSTRING_LEN, GFP_KERNEL);
|
||||||
if (!strings)
|
if (!strings)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
if (id == ETH_SS_PHY_STATS && dev->phydev &&
|
if (id == ETH_SS_PHY_STATS && phydev &&
|
||||||
!ops->get_ethtool_phy_stats && phy_ops &&
|
!ops->get_ethtool_phy_stats && phy_ops &&
|
||||||
phy_ops->get_strings)
|
phy_ops->get_strings)
|
||||||
phy_ops->get_strings(dev->phydev, strings);
|
phy_ops->get_strings(phydev, strings);
|
||||||
else
|
else
|
||||||
ops->get_strings(dev, id, strings);
|
ops->get_strings(dev, id, strings);
|
||||||
info->strings = strings;
|
info->strings = strings;
|
||||||
|
|
@ -279,6 +280,8 @@ static int strset_prepare_data(const struct ethnl_req_info *req_base,
|
||||||
const struct strset_req_info *req_info = STRSET_REQINFO(req_base);
|
const struct strset_req_info *req_info = STRSET_REQINFO(req_base);
|
||||||
struct strset_reply_data *data = STRSET_REPDATA(reply_base);
|
struct strset_reply_data *data = STRSET_REPDATA(reply_base);
|
||||||
struct net_device *dev = reply_base->dev;
|
struct net_device *dev = reply_base->dev;
|
||||||
|
struct nlattr **tb = info->attrs;
|
||||||
|
struct phy_device *phydev;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
@ -296,6 +299,13 @@ static int strset_prepare_data(const struct ethnl_req_info *req_base,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
phydev = ethnl_req_get_phydev(req_base, tb[ETHTOOL_A_HEADER_FLAGS],
|
||||||
|
info->extack);
|
||||||
|
|
||||||
|
/* phydev can be NULL, check for errors only */
|
||||||
|
if (IS_ERR(phydev))
|
||||||
|
return PTR_ERR(phydev);
|
||||||
|
|
||||||
ret = ethnl_ops_begin(dev);
|
ret = ethnl_ops_begin(dev);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_strset;
|
goto err_strset;
|
||||||
|
|
@ -304,7 +314,7 @@ static int strset_prepare_data(const struct ethnl_req_info *req_base,
|
||||||
!data->sets[i].per_dev)
|
!data->sets[i].per_dev)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = strset_prepare_set(&data->sets[i], dev, i,
|
ret = strset_prepare_set(&data->sets[i], dev, phydev, i,
|
||||||
req_info->counts_only);
|
req_info->counts_only);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_ops;
|
goto err_ops;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user