net: phy: phy_caps: Introduce phy_caps_valid
authorMaxime Chevallier <maxime.chevallier@bootlin.com>
Fri, 7 Mar 2025 17:36:02 +0000 (18:36 +0100)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 18 Mar 2025 08:03:11 +0000 (09:03 +0100)
With the link_capabilities array, it's trivial to validate a given mask
againts a <speed, duplex> tuple. Create a helper for that purpose, and
use it to replace a phy_settings lookup in phy_check_valid();

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

index 1bef9cc..1217686 100644 (file)
@@ -43,6 +43,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);
+bool phy_caps_valid(int speed, int duplex, const unsigned long *linkmodes);
 
 
 #endif /* __PHY_CAPS_H */
index 3128df0..8df37d2 100644 (file)
@@ -260,7 +260,7 @@ unsigned int phy_supported_speeds(struct phy_device *phy,
  */
 bool phy_check_valid(int speed, int duplex, unsigned long *features)
 {
-       return !!phy_lookup_setting(speed, duplex, features, true);
+       return phy_caps_valid(speed, duplex, features);
 }
 EXPORT_SYMBOL(phy_check_valid);
 
index d434938..4ee8c25 100644 (file)
@@ -140,3 +140,22 @@ void phy_caps_linkmode_max_speed(u32 max_speed, unsigned long *linkmodes)
                else
                        break;
 }
+
+/**
+ * phy_caps_valid() - Validate a linkmodes set agains given speed and duplex
+ * @speed: input speed to validate
+ * @duplex: input duplex to validate. Passing DUPLEX_UNKNOWN is always not valid
+ * @linkmodes: The linkmodes to validate
+ *
+ * Returns: True if at least one of the linkmodes in @linkmodes can function at
+ *          the given speed and duplex, false otherwise.
+ */
+bool phy_caps_valid(int speed, int duplex, const unsigned long *linkmodes)
+{
+       int capa = speed_duplex_to_capa(speed, duplex);
+
+       if (capa < 0)
+               return false;
+
+       return linkmode_intersects(link_caps[capa].linkmodes, linkmodes);
+}