diff options
| -rw-r--r-- | net/ethtool/strset.c | 24 | 
1 files changed, 17 insertions, 7 deletions
diff --git a/net/ethtool/strset.c b/net/ethtool/strset.c index 56b99606f00b..b3382b3cf325 100644 --- a/net/ethtool/strset.c +++ b/net/ethtool/strset.c @@ -126,7 +126,7 @@ struct strset_reply_data {  const struct nla_policy ethnl_strset_get_policy[] = {  	[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_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, -			      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_ops *ops = dev->ethtool_ops;  	void *strings;  	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 &&  	    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)  		ret = ops->get_sset_count(dev, id);  	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);  		if (!strings)  			return -ENOMEM; -		if (id == ETH_SS_PHY_STATS && dev->phydev && +		if (id == ETH_SS_PHY_STATS && phydev &&  		    !ops->get_ethtool_phy_stats && phy_ops &&  		    phy_ops->get_strings) -			phy_ops->get_strings(dev->phydev, strings); +			phy_ops->get_strings(phydev, strings);  		else  			ops->get_strings(dev, id, 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);  	struct strset_reply_data *data = STRSET_REPDATA(reply_base);  	struct net_device *dev = reply_base->dev; +	struct nlattr **tb = info->attrs; +	struct phy_device *phydev;  	unsigned int i;  	int ret; @@ -296,6 +299,13 @@ static int strset_prepare_data(const struct ethnl_req_info *req_base,  		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);  	if (ret < 0)  		goto err_strset; @@ -304,7 +314,7 @@ static int strset_prepare_data(const struct ethnl_req_info *req_base,  		    !data->sets[i].per_dev)  			continue; -		ret = strset_prepare_set(&data->sets[i], dev, i, +		ret = strset_prepare_set(&data->sets[i], dev, phydev, i,  					 req_info->counts_only);  		if (ret < 0)  			goto err_ops;  | 
