net: phy: phy_caps: Move __set_linkmode_max_speed to phy_caps
authorMaxime Chevallier <maxime.chevallier@bootlin.com>
Fri, 7 Mar 2025 17:36:01 +0000 (18:36 +0100)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 18 Mar 2025 08:03:11 +0000 (09:03 +0100)
Convert the __set_linkmode_max_speed to use the link_capabilities array.
This makes it easy to clamp the linkmodes to a given max speed.
Introduce a new helper phy_caps_linkmode_max_speed to replace the
previous one that used phy_settings.

Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20250307173611.129125-5-maxime.chevallier@bootlin.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/phy/phy-caps.h
drivers/net/phy/phy-core.c
drivers/net/phy/phy_caps.c

index 5a5f4ee..1bef9cc 100644 (file)
@@ -42,5 +42,7 @@ int phy_caps_init(void);
 
 size_t phy_caps_speeds(unsigned int *speeds, size_t size,
                       unsigned long *linkmodes);
+void phy_caps_linkmode_max_speed(u32 max_speed, unsigned long *linkmodes);
+
 
 #endif /* __PHY_CAPS_H */
index 102834b..741350d 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "phylib.h"
 #include "phylib-internal.h"
+#include "phy-caps.h"
 
 /**
  * phy_speed_to_str - Return a string representing the PHY link speed
@@ -340,22 +341,9 @@ phy_lookup_setting(int speed, int duplex, const unsigned long *mask, bool exact)
 }
 EXPORT_SYMBOL_GPL(phy_lookup_setting);
 
-static void __set_linkmode_max_speed(u32 max_speed, unsigned long *addr)
-{
-       const struct phy_setting *p;
-       int i;
-
-       for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {
-               if (p->speed > max_speed)
-                       linkmode_clear_bit(p->bit, addr);
-               else
-                       break;
-       }
-}
-
 static void __set_phy_supported(struct phy_device *phydev, u32 max_speed)
 {
-       __set_linkmode_max_speed(max_speed, phydev->supported);
+       phy_caps_linkmode_max_speed(max_speed, phydev->supported);
 }
 
 /**
@@ -558,7 +546,7 @@ int phy_speed_down_core(struct phy_device *phydev)
        if (min_common_speed == SPEED_UNKNOWN)
                return -EINVAL;
 
-       __set_linkmode_max_speed(min_common_speed, phydev->advertising);
+       phy_caps_linkmode_max_speed(min_common_speed, phydev->advertising);
 
        return 0;
 }
index 8ce9125..d434938 100644 (file)
@@ -60,6 +60,9 @@ static int speed_duplex_to_capa(int speed, unsigned int duplex)
 #define for_each_link_caps_asc_speed(cap) \
        for (cap = link_caps; cap < &link_caps[__LINK_CAPA_MAX]; cap++)
 
+#define for_each_link_caps_desc_speed(cap) \
+       for (cap = &link_caps[__LINK_CAPA_MAX - 1]; cap >= link_caps; cap--)
+
 /**
  * phy_caps_init() - Initializes the link_caps array from the link_mode_params.
  *
@@ -121,3 +124,19 @@ size_t phy_caps_speeds(unsigned int *speeds, size_t size,
 
        return count;
 }
+
+/**
+ * phy_caps_linkmode_max_speed() - Clamp a linkmodes set to a max speed
+ * @max_speed: Speed limit for the linkmode set
+ * @linkmodes: Linkmodes to limit
+ */
+void phy_caps_linkmode_max_speed(u32 max_speed, unsigned long *linkmodes)
+{
+       struct link_capabilities *lcap;
+
+       for_each_link_caps_desc_speed(lcap)
+               if (lcap->speed > max_speed)
+                       linkmode_andnot(linkmodes, linkmodes, lcap->linkmodes);
+               else
+                       break;
+}