]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: dsa: lantiq_gswip: store switch API version in priv
authorDaniel Golle <daniel@makrotopia.org>
Fri, 22 Aug 2025 16:12:21 +0000 (17:12 +0100)
committerJakub Kicinski <kuba@kernel.org>
Mon, 25 Aug 2025 22:15:46 +0000 (15:15 -0700)
Store the switch API version in struct gswip_priv. As the hardware has
the 'major/minor' version bytes in the wrong order preventing numerical
comparisons the version to be stored in gswip_priv is constructed in
such a way that the REV field is the most significant byte and the MOD
field the least significant byte. Also provide a conveniance macro to
allow comparing the stored version of the hardware against the already
defined GSWIP_VERSION_* macros.

This is done in order to prepare supporting newer features such as 4096
VLANs and per-port configurable learning which are only available
starting from specific hardware versions.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/eddb51ae8d0b2046ca91906e93daad7be5af56d7.1755878232.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/dsa/lantiq_gswip.c
drivers/net/dsa/lantiq_gswip.h

index 1a0ff1f88f22e27cf623ea1289fd14bca8305f46..67919c3935e463b7d2967d945fb2020a8371b8a9 100644 (file)
@@ -1907,6 +1907,16 @@ static int gswip_probe(struct platform_device *pdev)
        mutex_init(&priv->pce_table_lock);
        version = gswip_switch_r(priv, GSWIP_VERSION);
 
+       /* The hardware has the 'major/minor' version bytes in the wrong order
+        * preventing numerical comparisons. Construct a 16-bit unsigned integer
+        * having the REV field as most significant byte and the MOD field as
+        * least significant byte. This is effectively swapping the two bytes of
+        * the version variable, but other than using swab16 it doesn't affect
+        * the source variable.
+        */
+       priv->version = GSWIP_VERSION_REV(version) << 8 |
+                       GSWIP_VERSION_MOD(version);
+
        np = dev->of_node;
        switch (version) {
        case GSWIP_VERSION_2_0:
@@ -1955,8 +1965,7 @@ static int gswip_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, priv);
 
        dev_info(dev, "probed GSWIP version %lx mod %lx\n",
-                (version & GSWIP_VERSION_REV_MASK) >> GSWIP_VERSION_REV_SHIFT,
-                (version & GSWIP_VERSION_MOD_MASK) >> GSWIP_VERSION_MOD_SHIFT);
+                GSWIP_VERSION_REV(version), GSWIP_VERSION_MOD(version));
        return 0;
 
 disable_switch:
index 0b7b6db4eab95f046a7a7e80c9c225419b9dd72b..620c2d560cbe18732fe6dc5ed4b6480d71083f18 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
+#include <linux/swab.h>
 #include <net/dsa.h>
 
 /* GSWIP MDIO Registers */
 #define  GSWIP_SWRES_R1                        BIT(1)  /* GSWIP Software reset */
 #define  GSWIP_SWRES_R0                        BIT(0)  /* GSWIP Hardware reset */
 #define GSWIP_VERSION                  0x013
-#define  GSWIP_VERSION_REV_SHIFT       0
 #define  GSWIP_VERSION_REV_MASK                GENMASK(7, 0)
-#define  GSWIP_VERSION_MOD_SHIFT       8
 #define  GSWIP_VERSION_MOD_MASK                GENMASK(15, 8)
+#define  GSWIP_VERSION_REV(v)          FIELD_GET(GSWIP_VERSION_REV_MASK, v)
+#define  GSWIP_VERSION_MOD(v)          FIELD_GET(GSWIP_VERSION_MOD_MASK, v)
 #define   GSWIP_VERSION_2_0            0x100
 #define   GSWIP_VERSION_2_1            0x021
 #define   GSWIP_VERSION_2_2            0x122
 #define   GSWIP_VERSION_2_2_ETC                0x022
+/* The hardware has the 'major/minor' version bytes in the wrong order
+ * preventing numerical comparisons. Swap the bytes of the 16-bit value
+ * to end up with REV being the most significant byte and MOD being the
+ * least significant byte, which then allows comparing it with the
+ * value stored in struct gswip_priv.
+ */
+#define GSWIP_VERSION_GE(priv, ver)    ((priv)->version >= swab16(ver))
 
 #define GSWIP_BM_RAM_VAL(x)            (0x043 - (x))
 #define GSWIP_BM_RAM_ADDR              0x044
@@ -258,6 +266,7 @@ struct gswip_priv {
        struct gswip_gphy_fw *gphy_fw;
        u32 port_vlan_filter;
        struct mutex pce_table_lock;
+       u16 version;
 };
 
 #endif /* __LANTIQ_GSWIP_H */