[net-next,v2,4/8] ethtool: eee: Rework get/set handler for SmartEEE-capable PHYs with non-EEE MACs

Message ID 20230327142202.3754446-5-o.rempel@pengutronix.de
State New
Headers
Series Make SmartEEE support controllable |

Commit Message

Oleksij Rempel March 27, 2023, 2:21 p.m. UTC
  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>
---
 net/ethtool/common.c | 38 ++++++++++++++++++++++++++++++++++++++
 net/ethtool/common.h |  2 ++
 net/ethtool/eee.c    | 17 +++++++++++------
 3 files changed, 51 insertions(+), 6 deletions(-)
  

Comments

kernel test robot March 27, 2023, 8:45 p.m. UTC | #1
Hi Oleksij,

I love your patch! Yet something to improve:

[auto build test ERROR on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Oleksij-Rempel/net-phy-Add-driver-specific-get-set_eee-support-for-non-standard-PHYs/20230327-222630
patch link:    https://lore.kernel.org/r/20230327142202.3754446-5-o.rempel%40pengutronix.de
patch subject: [PATCH net-next v2 4/8] ethtool: eee: Rework get/set handler for SmartEEE-capable PHYs with non-EEE MACs
config: um-i386_defconfig (https://download.01.org/0day-ci/archive/20230328/202303280408.Krp7V753-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/fcee3230c8abb824746744ba0fc39dfd626faa65
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Oleksij-Rempel/net-phy-Add-driver-specific-get-set_eee-support-for-non-standard-PHYs/20230327-222630
        git checkout fcee3230c8abb824746744ba0fc39dfd626faa65
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=um SUBARCH=i386 olddefconfig
        make W=1 O=build_dir ARCH=um SUBARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202303280408.Krp7V753-lkp@intel.com/

All errors (new ones prefixed by >>):

   /usr/bin/ld: net/ethtool/common.o: in function `__ethtool_get_eee':
>> net/ethtool/common.c:677: undefined reference to `phy_ethtool_get_eee'
   /usr/bin/ld: net/ethtool/common.o: in function `__ethtool_set_eee':
>> net/ethtool/common.c:696: undefined reference to `phy_ethtool_set_eee'
   collect2: error: ld returned 1 exit status


vim +677 net/ethtool/common.c

   663	
   664	int __ethtool_get_eee(struct net_device *dev, struct ethtool_eee *eee)
   665	{
   666		const struct ethtool_ops *ops = dev->ethtool_ops;
   667		struct phy_device *phydev = dev->phydev;
   668		int ret;
   669	
   670		if (ops->get_eee)
   671			ret = ops->get_eee(dev, eee);
   672		else
   673			ret = -EOPNOTSUPP;
   674	
   675		if (ret == -EOPNOTSUPP) {
   676			if (phydev && phydev->is_smart_eee_phy)
 > 677				ret = phy_ethtool_get_eee(phydev, eee);
   678		}
   679	
   680		return ret;
   681	}
   682	
   683	int __ethtool_set_eee(struct net_device *dev, struct ethtool_eee *eee)
   684	{
   685		const struct ethtool_ops *ops = dev->ethtool_ops;
   686		struct phy_device *phydev = dev->phydev;
   687		int ret;
   688	
   689		if (ops->set_eee)
   690			ret = ops->set_eee(dev, eee);
   691		else
   692			ret = -EOPNOTSUPP;
   693	
   694		if (ret == -EOPNOTSUPP) {
   695			if (phydev && phydev->is_smart_eee_phy)
 > 696				ret = phy_ethtool_set_eee(phydev, eee);
   697		}
   698	
   699		return ret;
   700	}
   701
  
kernel test robot March 28, 2023, 3:36 a.m. UTC | #2
Hi Oleksij,

I love your patch! Yet something to improve:

[auto build test ERROR on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Oleksij-Rempel/net-phy-Add-driver-specific-get-set_eee-support-for-non-standard-PHYs/20230327-222630
patch link:    https://lore.kernel.org/r/20230327142202.3754446-5-o.rempel%40pengutronix.de
patch subject: [PATCH net-next v2 4/8] ethtool: eee: Rework get/set handler for SmartEEE-capable PHYs with non-EEE MACs
config: csky-defconfig (https://download.01.org/0day-ci/archive/20230328/202303281117.3288i7kT-lkp@intel.com/config)
compiler: csky-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/fcee3230c8abb824746744ba0fc39dfd626faa65
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Oleksij-Rempel/net-phy-Add-driver-specific-get-set_eee-support-for-non-standard-PHYs/20230327-222630
        git checkout fcee3230c8abb824746744ba0fc39dfd626faa65
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=csky olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=csky SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202303281117.3288i7kT-lkp@intel.com/

All errors (new ones prefixed by >>):

   csky-linux-ld: net/ethtool/common.o: in function `__ethtool_get_eee':
   common.c:(.text+0x45c): undefined reference to `phy_ethtool_get_eee'
   csky-linux-ld: net/ethtool/common.o: in function `__ethtool_set_eee':
   common.c:(.text+0x49c): undefined reference to `phy_ethtool_set_eee'
>> csky-linux-ld: common.c:(.text+0x4b8): undefined reference to `phy_ethtool_get_eee'
>> csky-linux-ld: common.c:(.text+0x4bc): undefined reference to `phy_ethtool_set_eee'
  

Patch

diff --git a/net/ethtool/common.c b/net/ethtool/common.c
index 5fb19050991e..267fd3600f15 100644
--- a/net/ethtool/common.c
+++ b/net/ethtool/common.c
@@ -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)
diff --git a/net/ethtool/common.h b/net/ethtool/common.h
index 28b8aaaf9bcb..59c1906ec800 100644
--- a/net/ethtool/common.h
+++ b/net/ethtool/common.h
@@ -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;
diff --git a/net/ethtool/eee.c b/net/ethtool/eee.c
index 42104bcb0e47..43b866184297 100644
--- a/net/ethtool/eee.c
+++ b/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"
@@ -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;
@@ -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
@@ -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;
 
@@ -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;
 }