Skip to content

Commit

Permalink
ethtool: eee: Rework get/set handler for SmartEEE-capable PHYs with n…
Browse files Browse the repository at this point in the history
…on-EEE MACs

This patch reworks the ethtool handler to allow accessing set/get EEE
properties of SmartEEE-capable PHYs, even when the associated MAC does
not provide EEE support. Previously, the handler would not allow
configuration or management of EEE properties for such PHYs, limiting
their functionality and energy efficiency.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
  • Loading branch information
olerem authored and intel-lab-lkp committed Mar 27, 2023
1 parent 899e48b commit fcee323
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 6 deletions.
38 changes: 38 additions & 0 deletions net/ethtool/common.c
Expand Up @@ -661,6 +661,44 @@ int ethtool_get_phc_vclocks(struct net_device *dev, int **vclock_index)
}
EXPORT_SYMBOL(ethtool_get_phc_vclocks);

int __ethtool_get_eee(struct net_device *dev, struct ethtool_eee *eee)
{
const struct ethtool_ops *ops = dev->ethtool_ops;
struct phy_device *phydev = dev->phydev;
int ret;

if (ops->get_eee)
ret = ops->get_eee(dev, eee);
else
ret = -EOPNOTSUPP;

if (ret == -EOPNOTSUPP) {
if (phydev && phydev->is_smart_eee_phy)
ret = phy_ethtool_get_eee(phydev, eee);
}

return ret;
}

int __ethtool_set_eee(struct net_device *dev, struct ethtool_eee *eee)
{
const struct ethtool_ops *ops = dev->ethtool_ops;
struct phy_device *phydev = dev->phydev;
int ret;

if (ops->set_eee)
ret = ops->set_eee(dev, eee);
else
ret = -EOPNOTSUPP;

if (ret == -EOPNOTSUPP) {
if (phydev && phydev->is_smart_eee_phy)
ret = phy_ethtool_set_eee(phydev, eee);
}

return ret;
}

const struct ethtool_phy_ops *ethtool_phy_ops;

void ethtool_set_ethtool_phy_ops(const struct ethtool_phy_ops *ops)
Expand Down
2 changes: 2 additions & 0 deletions net/ethtool/common.h
Expand Up @@ -45,6 +45,8 @@ bool convert_legacy_settings_to_link_ksettings(
int ethtool_get_max_rxfh_channel(struct net_device *dev, u32 *max);
int ethtool_get_max_rxnfc_channel(struct net_device *dev, u64 *max);
int __ethtool_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);
int __ethtool_get_eee(struct net_device *dev, struct ethtool_eee *eee);
int __ethtool_set_eee(struct net_device *dev, struct ethtool_eee *eee);

extern const struct ethtool_phy_ops *ethtool_phy_ops;
extern const struct ethtool_pse_ops *ethtool_pse_ops;
Expand Down
17 changes: 11 additions & 6 deletions net/ethtool/eee.c
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only

#include <linux/phy.h>

#include "netlink.h"
#include "common.h"
#include "bitset.h"
Expand Down Expand Up @@ -32,12 +34,10 @@ static int eee_prepare_data(const struct ethnl_req_info *req_base,
struct net_device *dev = reply_base->dev;
int ret;

if (!dev->ethtool_ops->get_eee)
return -EOPNOTSUPP;
ret = ethnl_ops_begin(dev);
if (ret < 0)
return ret;
ret = dev->ethtool_ops->get_eee(dev, &data->eee);
ret = __ethtool_get_eee(dev, &data->eee);
ethnl_ops_complete(dev);

return ret;
Expand Down Expand Up @@ -123,8 +123,13 @@ static int
ethnl_set_eee_validate(struct ethnl_req_info *req_info, struct genl_info *info)
{
const struct ethtool_ops *ops = req_info->dev->ethtool_ops;
struct net_device *dev = req_info->dev;

if ((ops->get_eee && ops->set_eee) ||
(dev->phydev && dev->phydev->is_smart_eee_phy))
return 1;

return ops->get_eee && ops->set_eee ? 1 : -EOPNOTSUPP;
return -EOPNOTSUPP;
}

static int
Expand All @@ -136,7 +141,7 @@ ethnl_set_eee(struct ethnl_req_info *req_info, struct genl_info *info)
bool mod = false;
int ret;

ret = dev->ethtool_ops->get_eee(dev, &eee);
ret = __ethtool_get_eee(dev, &eee);
if (ret < 0)
return ret;

Expand All @@ -153,7 +158,7 @@ ethnl_set_eee(struct ethnl_req_info *req_info, struct genl_info *info)
if (!mod)
return 0;

ret = dev->ethtool_ops->set_eee(dev, &eee);
ret = __ethtool_set_eee(dev, &eee);
return ret < 0 ? ret : 1;
}

Expand Down

0 comments on commit fcee323

Please sign in to comment.