net: dsa: mv88e6xxx: lookup switch name
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>
Fri, 30 Oct 2015 23:39:48 +0000 (19:39 -0400)
committerDavid S. Miller <davem@davemloft.net>
Mon, 2 Nov 2015 20:54:13 +0000 (15:54 -0500)
All the mv88e6xxx drivers use the exact same code in their probe
function to lookup the switch name given its ID. Thus introduce a
mv88e6xxx_switch_id structure and a mv88e6xxx_lookup_name function in
the common mv88e6xxx code.

In the meantime make __mv88e6xxx_reg_{read,write} static since we do not
need to expose these low-level r/w routines anymore.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Acked-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/mv88e6123_61_65.c
drivers/net/dsa/mv88e6131.c
drivers/net/dsa/mv88e6171.c
drivers/net/dsa/mv88e6352.c
drivers/net/dsa/mv88e6xxx.c
drivers/net/dsa/mv88e6xxx.h

index 4bcfd683bbea0d2eb89e3be9246ee1bdc0c77def..d4fcf4570d955c5ee637870cfa5a276aab63a5a8 100644 (file)
 #include <net/dsa.h>
 #include "mv88e6xxx.h"
 
+static const struct mv88e6xxx_switch_id mv88e6123_61_65_table[] = {
+       { PORT_SWITCH_ID_6123, "Marvell 88E6123" },
+       { PORT_SWITCH_ID_6123_A1, "Marvell 88E6123 (A1)" },
+       { PORT_SWITCH_ID_6123_A2, "Marvell 88E6123 (A2)" },
+       { PORT_SWITCH_ID_6161, "Marvell 88E6161" },
+       { PORT_SWITCH_ID_6161_A1, "Marvell 88E6161 (A1)" },
+       { PORT_SWITCH_ID_6161_A2, "Marvell 88E6161 (A2)" },
+       { PORT_SWITCH_ID_6165, "Marvell 88E6165" },
+       { PORT_SWITCH_ID_6165_A1, "Marvell 88E6165 (A1)" },
+       { PORT_SWITCH_ID_6165_A2, "Marvell 88e6165 (A2)" },
+};
+
 static char *mv88e6123_61_65_probe(struct device *host_dev, int sw_addr)
 {
-       struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
-       int ret;
-
-       if (bus == NULL)
-               return NULL;
-
-       ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), PORT_SWITCH_ID);
-       if (ret >= 0) {
-               if (ret == PORT_SWITCH_ID_6123_A1)
-                       return "Marvell 88E6123 (A1)";
-               if (ret == PORT_SWITCH_ID_6123_A2)
-                       return "Marvell 88E6123 (A2)";
-               if ((ret & 0xfff0) == PORT_SWITCH_ID_6123)
-                       return "Marvell 88E6123";
-
-               if (ret == PORT_SWITCH_ID_6161_A1)
-                       return "Marvell 88E6161 (A1)";
-               if (ret == PORT_SWITCH_ID_6161_A2)
-                       return "Marvell 88E6161 (A2)";
-               if ((ret & 0xfff0) == PORT_SWITCH_ID_6161)
-                       return "Marvell 88E6161";
-
-               if (ret == PORT_SWITCH_ID_6165_A1)
-                       return "Marvell 88E6165 (A1)";
-               if (ret == PORT_SWITCH_ID_6165_A2)
-                       return "Marvell 88e6165 (A2)";
-               if ((ret & 0xfff0) == PORT_SWITCH_ID_6165)
-                       return "Marvell 88E6165";
-       }
-
-       return NULL;
+       return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6123_61_65_table,
+                                    ARRAY_SIZE(mv88e6123_61_65_table));
 }
 
 static int mv88e6123_61_65_setup_global(struct dsa_switch *ds)
index c73121c8f1551576a66007fa6484becc14b58a69..a92ca651c3990c1353922fadb242e57d8f7e0af9 100644 (file)
 #include <net/dsa.h>
 #include "mv88e6xxx.h"
 
+static const struct mv88e6xxx_switch_id mv88e6131_table[] = {
+       { PORT_SWITCH_ID_6085, "Marvell 88E6085" },
+       { PORT_SWITCH_ID_6095, "Marvell 88E6095/88E6095F" },
+       { PORT_SWITCH_ID_6131, "Marvell 88E6131" },
+       { PORT_SWITCH_ID_6131_B2, "Marvell 88E6131 (B2)" },
+       { PORT_SWITCH_ID_6185, "Marvell 88E6185" },
+};
+
 static char *mv88e6131_probe(struct device *host_dev, int sw_addr)
 {
-       struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
-       int ret;
-
-       if (bus == NULL)
-               return NULL;
-
-       ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), PORT_SWITCH_ID);
-       if (ret >= 0) {
-               int ret_masked = ret & 0xfff0;
-
-               if (ret_masked == PORT_SWITCH_ID_6085)
-                       return "Marvell 88E6085";
-               if (ret_masked == PORT_SWITCH_ID_6095)
-                       return "Marvell 88E6095/88E6095F";
-               if (ret == PORT_SWITCH_ID_6131_B2)
-                       return "Marvell 88E6131 (B2)";
-               if (ret_masked == PORT_SWITCH_ID_6131)
-                       return "Marvell 88E6131";
-               if (ret_masked == PORT_SWITCH_ID_6185)
-                       return "Marvell 88E6185";
-       }
-
-       return NULL;
+       return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6131_table,
+                                    ARRAY_SIZE(mv88e6131_table));
 }
 
 static int mv88e6131_setup_global(struct dsa_switch *ds)
index 1bd876e3f9908809443e04f3224d5038d0b17b80..54aa00012dd0ce5ca36427c0cfb41f773ea47138 100644 (file)
 #include <net/dsa.h>
 #include "mv88e6xxx.h"
 
+static const struct mv88e6xxx_switch_id mv88e6171_table[] = {
+       { PORT_SWITCH_ID_6171, "Marvell 88E6171" },
+       { PORT_SWITCH_ID_6175, "Marvell 88E6175" },
+       { PORT_SWITCH_ID_6350, "Marvell 88E6350" },
+       { PORT_SWITCH_ID_6351, "Marvell 88E6351" },
+};
+
 static char *mv88e6171_probe(struct device *host_dev, int sw_addr)
 {
-       struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
-       int ret;
-
-       if (bus == NULL)
-               return NULL;
-
-       ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), PORT_SWITCH_ID);
-       if (ret >= 0) {
-               if ((ret & 0xfff0) == PORT_SWITCH_ID_6171)
-                       return "Marvell 88E6171";
-               if ((ret & 0xfff0) == PORT_SWITCH_ID_6175)
-                       return "Marvell 88E6175";
-               if ((ret & 0xfff0) == PORT_SWITCH_ID_6350)
-                       return "Marvell 88E6350";
-               if ((ret & 0xfff0) == PORT_SWITCH_ID_6351)
-                       return "Marvell 88E6351";
-       }
-
-       return NULL;
+       return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6171_table,
+                                    ARRAY_SIZE(mv88e6171_table));
 }
 
 static int mv88e6171_setup_global(struct dsa_switch *ds)
index 4458d6ae7b69d490e5b4e5982d49178237891e97..ff846d0cfcebeff1b332b8f8ae1ca48d106c667d 100644 (file)
 #include <net/dsa.h>
 #include "mv88e6xxx.h"
 
+static const struct mv88e6xxx_switch_id mv88e6352_table[] = {
+       { PORT_SWITCH_ID_6172, "Marvell 88E6172" },
+       { PORT_SWITCH_ID_6176, "Marvell 88E6176" },
+       { PORT_SWITCH_ID_6320, "Marvell 88E6320" },
+       { PORT_SWITCH_ID_6320_A1, "Marvell 88E6320 (A1)" },
+       { PORT_SWITCH_ID_6320_A2, "Marvell 88e6320 (A2)" },
+       { PORT_SWITCH_ID_6321, "Marvell 88E6321" },
+       { PORT_SWITCH_ID_6321_A1, "Marvell 88E6321 (A1)" },
+       { PORT_SWITCH_ID_6321_A2, "Marvell 88e6321 (A2)" },
+       { PORT_SWITCH_ID_6352, "Marvell 88E6352" },
+       { PORT_SWITCH_ID_6352_A0, "Marvell 88E6352 (A0)" },
+       { PORT_SWITCH_ID_6352_A1, "Marvell 88E6352 (A1)" },
+};
+
 static char *mv88e6352_probe(struct device *host_dev, int sw_addr)
 {
-       struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
-       int ret;
-
-       if (bus == NULL)
-               return NULL;
-
-       ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), PORT_SWITCH_ID);
-       if (ret >= 0) {
-               if ((ret & 0xfff0) == PORT_SWITCH_ID_6172)
-                       return "Marvell 88E6172";
-               if ((ret & 0xfff0) == PORT_SWITCH_ID_6176)
-                       return "Marvell 88E6176";
-               if (ret == PORT_SWITCH_ID_6320_A1)
-                       return "Marvell 88E6320 (A1)";
-               if (ret == PORT_SWITCH_ID_6320_A2)
-                       return "Marvell 88e6320 (A2)";
-               if ((ret & 0xfff0) == PORT_SWITCH_ID_6320)
-                       return "Marvell 88E6320";
-               if (ret == PORT_SWITCH_ID_6321_A1)
-                       return "Marvell 88E6321 (A1)";
-               if (ret == PORT_SWITCH_ID_6321_A2)
-                       return "Marvell 88e6321 (A2)";
-               if ((ret & 0xfff0) == PORT_SWITCH_ID_6321)
-                       return "Marvell 88E6321";
-               if (ret == PORT_SWITCH_ID_6352_A0)
-                       return "Marvell 88E6352 (A0)";
-               if (ret == PORT_SWITCH_ID_6352_A1)
-                       return "Marvell 88E6352 (A1)";
-               if ((ret & 0xfff0) == PORT_SWITCH_ID_6352)
-                       return "Marvell 88E6352";
-       }
-
-       return NULL;
+       return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6352_table,
+                                    ARRAY_SIZE(mv88e6352_table));
 }
 
 static int mv88e6352_setup_global(struct dsa_switch *ds)
index d8866988a88a09ac348d504db153353ab4403155..85228f44c2b5be29777015afc3501e72f1c752e8 100644 (file)
@@ -59,7 +59,8 @@ static int mv88e6xxx_reg_wait_ready(struct mii_bus *bus, int sw_addr)
        return -ETIMEDOUT;
 }
 
-int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg)
+static int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr,
+                               int reg)
 {
        int ret;
 
@@ -122,8 +123,8 @@ int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
        return ret;
 }
 
-int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
-                         int reg, u16 val)
+static int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
+                                int reg, u16 val)
 {
        int ret;
 
@@ -2546,6 +2547,38 @@ int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
 }
 #endif /* CONFIG_NET_DSA_HWMON */
 
+char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr,
+                           const struct mv88e6xxx_switch_id *table,
+                           unsigned int num)
+{
+       struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
+       int i, ret;
+
+       if (!bus)
+               return NULL;
+
+       ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), PORT_SWITCH_ID);
+       if (ret < 0)
+               return NULL;
+
+       /* Look up the exact switch ID */
+       for (i = 0; i < num; ++i)
+               if (table[i].id == ret)
+                       return table[i].name;
+
+       /* Look up only the product number */
+       for (i = 0; i < num; ++i) {
+               if (table[i].id == (ret & PORT_SWITCH_ID_PROD_NUM_MASK)) {
+                       dev_warn(host_dev, "unknown revision %d, using base switch 0x%x\n",
+                                ret & PORT_SWITCH_ID_REV_MASK,
+                                ret & PORT_SWITCH_ID_PROD_NUM_MASK);
+                       return table[i].name;
+               }
+       }
+
+       return NULL;
+}
+
 static int __init mv88e6xxx_init(void)
 {
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
index e0692b95b2c96854e4c84d7aa4d7ba66cdc6d835..ad9958f09aa7fa28a9b271c7500e053b48e921ab 100644 (file)
@@ -60,6 +60,8 @@
 #define PORT_PCS_CTRL_UNFORCED         0x03
 #define PORT_PAUSE_CTRL                0x02
 #define PORT_SWITCH_ID         0x03
+#define PORT_SWITCH_ID_PROD_NUM_MASK   0xfff0
+#define PORT_SWITCH_ID_REV_MASK                0x000f
 #define PORT_SWITCH_ID_6031    0x0310
 #define PORT_SWITCH_ID_6035    0x0350
 #define PORT_SWITCH_ID_6046    0x0480
 #define GLOBAL2_QOS_WEIGHT     0x1c
 #define GLOBAL2_MISC           0x1d
 
+struct mv88e6xxx_switch_id {
+       u16 id;
+       char *name;
+};
+
 struct mv88e6xxx_atu_entry {
        u16     fid;
        u8      state;
@@ -415,13 +422,13 @@ struct mv88e6xxx_hw_stat {
 };
 
 int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active);
+char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr,
+                           const struct mv88e6xxx_switch_id *table,
+                           unsigned int num);
 int mv88e6xxx_setup_ports(struct dsa_switch *ds);
 int mv88e6xxx_setup_common(struct dsa_switch *ds);
 int mv88e6xxx_setup_global(struct dsa_switch *ds);
-int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg);
 int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg);
-int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
-                         int reg, u16 val);
 int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val);
 int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr);
 int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr);