Skip to content

Commit

Permalink
Merge branch 'net-phy-Uninline-PHY-ethtool-statistics'
Browse files Browse the repository at this point in the history
Florian Fainelli says:

====================
net: phy: Uninline PHY ethtool statistics

Now that we have introduced ethtool_phy_ops we can uninline those
operations and move them back into phy.c where they belong. Since those
functions are used by DSA, we need to continue exporting those symbols.

It might be possible to remove ndo_get_ethtool_phy_stats in a subsequent
patch since we could have DSA register its own ethtool_phy_ops instance
instead of overloading the ethtool_ops.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jul 8, 2020
2 parents 5d75c04 + 1780951 commit 3d07ae5
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 57 deletions.
48 changes: 48 additions & 0 deletions drivers/net/phy/phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,54 @@ static void phy_abort_cable_test(struct phy_device *phydev)
phydev_err(phydev, "Error while aborting cable test");
}

int phy_ethtool_get_strings(struct phy_device *phydev, u8 *data)
{
if (!phydev->drv)
return -EIO;

mutex_lock(&phydev->lock);
phydev->drv->get_strings(phydev, data);
mutex_unlock(&phydev->lock);

return 0;
}
EXPORT_SYMBOL(phy_ethtool_get_strings);

int phy_ethtool_get_sset_count(struct phy_device *phydev)
{
int ret;

if (!phydev->drv)
return -EIO;

if (phydev->drv->get_sset_count &&
phydev->drv->get_strings &&
phydev->drv->get_stats) {
mutex_lock(&phydev->lock);
ret = phydev->drv->get_sset_count(phydev);
mutex_unlock(&phydev->lock);

return ret;
}

return -EOPNOTSUPP;
}
EXPORT_SYMBOL(phy_ethtool_get_sset_count);

int phy_ethtool_get_stats(struct phy_device *phydev,
struct ethtool_stats *stats, u64 *data)
{
if (!phydev->drv)
return -EIO;

mutex_lock(&phydev->lock);
phydev->drv->get_stats(phydev, stats, data);
mutex_unlock(&phydev->lock);

return 0;
}
EXPORT_SYMBOL(phy_ethtool_get_stats);

int phy_start_cable_test(struct phy_device *phydev,
struct netlink_ext_ack *extack)
{
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/phy/phy_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -3028,6 +3028,9 @@ static struct phy_driver genphy_driver = {
};

static const struct ethtool_phy_ops phy_ethtool_phy_ops = {
.get_sset_count = phy_ethtool_get_sset_count,
.get_strings = phy_ethtool_get_strings,
.get_stats = phy_ethtool_get_stats,
.start_cable_test = phy_start_cable_test,
.start_cable_test_tdr = phy_start_cable_test_tdr,
};
Expand Down
7 changes: 7 additions & 0 deletions include/linux/ethtool.h
Original file line number Diff line number Diff line change
Expand Up @@ -508,13 +508,20 @@ struct phy_tdr_config;

/**
* struct ethtool_phy_ops - Optional PHY device options
* @get_sset_count: Get number of strings that @get_strings will write.
* @get_strings: Return a set of strings that describe the requested objects
* @get_stats: Return extended statistics about the PHY device.
* @start_cable_test - Start a cable test
* @start_cable_test_tdr - Start a Time Domain Reflectometry cable test
*
* All operations are optional (i.e. the function pointer may be set to %NULL)
* and callers must take this into account. Callers must hold the RTNL lock.
*/
struct ethtool_phy_ops {
int (*get_sset_count)(struct phy_device *dev);
int (*get_strings)(struct phy_device *dev, u8 *data);
int (*get_stats)(struct phy_device *dev,
struct ethtool_stats *stats, u64 *data);
int (*start_cable_test)(struct phy_device *phydev,
struct netlink_ext_ack *extack);
int (*start_cable_test_tdr)(struct phy_device *phydev,
Expand Down
49 changes: 4 additions & 45 deletions include/linux/phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -1474,51 +1474,10 @@ int __init mdio_bus_init(void);
void mdio_bus_exit(void);
#endif

/* Inline function for use within net/core/ethtool.c (built-in) */
static inline int phy_ethtool_get_strings(struct phy_device *phydev, u8 *data)
{
if (!phydev->drv)
return -EIO;

mutex_lock(&phydev->lock);
phydev->drv->get_strings(phydev, data);
mutex_unlock(&phydev->lock);

return 0;
}

static inline int phy_ethtool_get_sset_count(struct phy_device *phydev)
{
int ret;

if (!phydev->drv)
return -EIO;

if (phydev->drv->get_sset_count &&
phydev->drv->get_strings &&
phydev->drv->get_stats) {
mutex_lock(&phydev->lock);
ret = phydev->drv->get_sset_count(phydev);
mutex_unlock(&phydev->lock);

return ret;
}

return -EOPNOTSUPP;
}

static inline int phy_ethtool_get_stats(struct phy_device *phydev,
struct ethtool_stats *stats, u64 *data)
{
if (!phydev->drv)
return -EIO;

mutex_lock(&phydev->lock);
phydev->drv->get_stats(phydev, stats, data);
mutex_unlock(&phydev->lock);

return 0;
}
int phy_ethtool_get_strings(struct phy_device *phydev, u8 *data);
int phy_ethtool_get_sset_count(struct phy_device *phydev);
int phy_ethtool_get_stats(struct phy_device *phydev,
struct ethtool_stats *stats, u64 *data);

static inline int phy_package_read(struct phy_device *phydev, u32 regnum)
{
Expand Down
23 changes: 15 additions & 8 deletions net/ethtool/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)

static int __ethtool_get_sset_count(struct net_device *dev, int sset)
{
const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
const struct ethtool_ops *ops = dev->ethtool_ops;

if (sset == ETH_SS_FEATURES)
Expand All @@ -150,8 +151,9 @@ static int __ethtool_get_sset_count(struct net_device *dev, int sset)
return ARRAY_SIZE(phy_tunable_strings);

if (sset == ETH_SS_PHY_STATS && dev->phydev &&
!ops->get_ethtool_phy_stats)
return phy_ethtool_get_sset_count(dev->phydev);
!ops->get_ethtool_phy_stats &&
phy_ops && phy_ops->get_sset_count)
return phy_ops->get_sset_count(dev->phydev);

if (sset == ETH_SS_LINK_MODES)
return __ETHTOOL_LINK_MODE_MASK_NBITS;
Expand All @@ -165,6 +167,7 @@ static int __ethtool_get_sset_count(struct net_device *dev, int sset)
static void __ethtool_get_strings(struct net_device *dev,
u32 stringset, u8 *data)
{
const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
const struct ethtool_ops *ops = dev->ethtool_ops;

if (stringset == ETH_SS_FEATURES)
Expand All @@ -178,8 +181,9 @@ static void __ethtool_get_strings(struct net_device *dev,
else if (stringset == ETH_SS_PHY_TUNABLES)
memcpy(data, phy_tunable_strings, sizeof(phy_tunable_strings));
else if (stringset == ETH_SS_PHY_STATS && dev->phydev &&
!ops->get_ethtool_phy_stats)
phy_ethtool_get_strings(dev->phydev, data);
!ops->get_ethtool_phy_stats && phy_ops &&
phy_ops->get_strings)
phy_ops->get_strings(dev->phydev, data);
else if (stringset == ETH_SS_LINK_MODES)
memcpy(data, link_mode_names,
__ETHTOOL_LINK_MODE_MASK_NBITS * ETH_GSTRING_LEN);
Expand Down Expand Up @@ -1929,6 +1933,7 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)

static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
{
const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
const struct ethtool_ops *ops = dev->ethtool_ops;
struct phy_device *phydev = dev->phydev;
struct ethtool_stats stats;
Expand All @@ -1938,8 +1943,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
if (!phydev && (!ops->get_ethtool_phy_stats || !ops->get_sset_count))
return -EOPNOTSUPP;

if (dev->phydev && !ops->get_ethtool_phy_stats)
n_stats = phy_ethtool_get_sset_count(dev->phydev);
if (dev->phydev && !ops->get_ethtool_phy_stats &&
phy_ops && phy_ops->get_sset_count)
n_stats = phy_ops->get_sset_count(dev->phydev);
else
n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
if (n_stats < 0)
Expand All @@ -1958,8 +1964,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
if (!data)
return -ENOMEM;

if (dev->phydev && !ops->get_ethtool_phy_stats) {
ret = phy_ethtool_get_stats(dev->phydev, &stats, data);
if (dev->phydev && !ops->get_ethtool_phy_stats &&
phy_ops && phy_ops->get_stats) {
ret = phy_ops->get_stats(dev->phydev, &stats, data);
if (ret < 0)
goto out;
} else {
Expand Down
11 changes: 7 additions & 4 deletions net/ethtool/strset.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,15 @@ 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)
{
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 &&
!ops->get_ethtool_phy_stats)
ret = phy_ethtool_get_sset_count(dev->phydev);
!ops->get_ethtool_phy_stats && phy_ops &&
phy_ops->get_sset_count)
ret = phy_ops->get_sset_count(dev->phydev);
else if (ops->get_sset_count && ops->get_strings)
ret = ops->get_sset_count(dev, id);
else
Expand All @@ -231,8 +233,9 @@ static int strset_prepare_set(struct strset_info *info, struct net_device *dev,
if (!strings)
return -ENOMEM;
if (id == ETH_SS_PHY_STATS && dev->phydev &&
!ops->get_ethtool_phy_stats)
phy_ethtool_get_strings(dev->phydev, strings);
!ops->get_ethtool_phy_stats && phy_ops &&
phy_ops->get_strings)
phy_ops->get_strings(dev->phydev, strings);
else
ops->get_strings(dev, id, strings);
info->strings = strings;
Expand Down

0 comments on commit 3d07ae5

Please sign in to comment.