lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 27 Mar 2023 16:21:58 +0200
From:   Oleksij Rempel <o.rempel@...gutronix.de>
To:     Wei Fang <wei.fang@....com>,
        "David S. Miller" <davem@...emloft.net>,
        Eric Dumazet <edumazet@...gle.com>,
        Jakub Kicinski <kuba@...nel.org>,
        Paolo Abeni <pabeni@...hat.com>, Andrew Lunn <andrew@...n.ch>,
        Heiner Kallweit <hkallweit1@...il.com>,
        Russell King <linux@...linux.org.uk>
Cc:     Oleksij Rempel <o.rempel@...gutronix.de>, kernel@...gutronix.de,
        linux-kernel@...r.kernel.org, netdev@...r.kernel.org,
        Shenwei Wang <shenwei.wang@....com>,
        Clark Wang <xiaoning.wang@....com>,
        NXP Linux Team <linux-imx@....com>,
        Amit Cohen <amcohen@...dia.com>, Gal Pressman <gal@...dia.com>,
        Alexandru Tachici <alexandru.tachici@...log.com>,
        Piergiorgio Beruto <piergiorgio.beruto@...il.com>,
        Willem de Bruijn <willemb@...gle.com>,
        Vladimir Oltean <vladimir.oltean@....com>
Subject: [PATCH net-next v2 4/8] ethtool: eee: Rework get/set handler for SmartEEE-capable PHYs with non-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@...gutronix.de>
---
 net/ethtool/common.c | 38 ++++++++++++++++++++++++++++++++++++++
 net/ethtool/common.h |  2 ++
 net/ethtool/eee.c    | 17 +++++++++++------
 3 files changed, 51 insertions(+), 6 deletions(-)

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;
 }
 
-- 
2.30.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ