[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <e499c226-7141-d5be-990c-b46b7dd048f8@gmail.com>
Date: Mon, 12 Aug 2019 23:20:07 +0200
From: Heiner Kallweit <hkallweit1@...il.com>
To: Andrew Lunn <andrew@...n.ch>,
Florian Fainelli <f.fainelli@...il.com>,
David Miller <davem@...emloft.net>
Cc: "netdev@...r.kernel.org" <netdev@...r.kernel.org>
Subject: [PATCH net-next 2/3] net: phy: add __phy_speed_down and
phy_resolve_min_speed
__phy_speed_down provides most of the functionality for phy_speed_down.
It makes use of new helper phy_resolve_min_speed that is based on the
sorting of the settings[] array.
In certain cases it may be helpful to be able to exclude legacy half
duplex modes, therefore prepare phy_resolve_min_speed() for it.
Signed-off-by: Heiner Kallweit <hkallweit1@...il.com>
---
drivers/net/phy/phy-core.c | 29 +++++++++++++++++++++++++++++
include/linux/phy.h | 1 +
2 files changed, 30 insertions(+)
diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
index de085f255..d7331875e 100644
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -316,6 +316,35 @@ void phy_resolve_aneg_linkmode(struct phy_device *phydev)
}
EXPORT_SYMBOL_GPL(phy_resolve_aneg_linkmode);
+static int phy_resolve_min_speed(struct phy_device *phydev, bool fdx_only)
+{
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
+ int i = ARRAY_SIZE(settings);
+
+ linkmode_and(common, phydev->lp_advertising, phydev->advertising);
+
+ while (i--) {
+ if (test_bit(settings[i].bit, common)) {
+ if (fdx_only && settings[i].duplex != DUPLEX_FULL)
+ continue;
+ return settings[i].speed;
+ }
+ }
+
+ return SPEED_UNKNOWN;
+}
+
+int __phy_speed_down(struct phy_device *phydev)
+{
+ int min_common_speed = phy_resolve_min_speed(phydev, true);
+
+ if (min_common_speed == SPEED_UNKNOWN)
+ return -EINVAL;
+
+ return __set_linkmode_max_speed(phydev, min_common_speed,
+ phydev->advertising);
+}
+
static void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,
u16 regnum)
{
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 781f4810c..4be6d3b47 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -665,6 +665,7 @@ size_t phy_speeds(unsigned int *speeds, size_t size,
unsigned long *mask);
void of_set_phy_supported(struct phy_device *phydev);
void of_set_phy_eee_broken(struct phy_device *phydev);
+int __phy_speed_down(struct phy_device *phydev);
/**
* phy_is_started - Convenience function to check whether PHY is started
--
2.22.0
Powered by blists - more mailing lists