Merge branch 'dsa-mv88e6xxx-switch-factorization'
authorDavid S. Miller <davem@davemloft.net>
Sun, 17 Apr 2016 22:54:15 +0000 (18:54 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sun, 17 Apr 2016 22:54:15 +0000 (18:54 -0400)
Vivien Didelot says:

====================
net: dsa: mv88e6xxx: factorize switch info

This patchset factorizes the mv88e6xxx code by sharing a new extendable
info structure to store static data such as switch family, product
number, number of ports, number of databases and the name.

The next step is to add a "flags" bitmap member to the info structure in
order to simplify the shared code with a feature-based logic instead of
checking their family/ID.

This is a step forward having a single mv88e6xxx driver supporting many
similar devices, like any usual Linux driver.

Changes v3 -> v4:
  - constify probed name in DSA
  - rebase patchset above conflicting commit 48ace4e

Changes v2 -> v3:
  - update commit messages and add Andrew's tags
  - keep the info lookup code in a separated function
  - split the single switch ID reading in probe in a new commit

Changes v1 -> v2:
  - define PORT_SWITCH_ID_PROD_NUM_* values
  - use plain struct mv88e6xxx_info
  - remove non used yet ps->rev
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/bcm_sf2.c
drivers/net/dsa/mv88e6060.c
drivers/net/dsa/mv88e6123.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
include/net/dsa.h
net/dsa/dsa.c

index 7a5f0ef46bd6f909898dfee3cf20c3e2734a2e6b..448deb59b9a42dcbc2479a8e2ed3b522b471bc19 100644 (file)
@@ -135,9 +135,9 @@ static int bcm_sf2_sw_get_sset_count(struct dsa_switch *ds)
        return BCM_SF2_STATS_SIZE;
 }
 
-static char *bcm_sf2_sw_drv_probe(struct device *dsa_dev,
-                                 struct device *host_dev,
-                                 int sw_addr, void **_priv)
+static const char *bcm_sf2_sw_drv_probe(struct device *dsa_dev,
+                                       struct device *host_dev, int sw_addr,
+                                       void **_priv)
 {
        struct bcm_sf2_priv *priv;
 
index 92cebab9383e3190abb322c9695fcabf8d179d5c..e36b40886bd810c0c517b8ac3f2e320d9581ed9a 100644 (file)
@@ -51,7 +51,7 @@ static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
                        return __ret;                           \
        })
 
-static char *mv88e6060_get_name(struct mii_bus *bus, int sw_addr)
+static const char *mv88e6060_get_name(struct mii_bus *bus, int sw_addr)
 {
        int ret;
 
@@ -69,13 +69,13 @@ static char *mv88e6060_get_name(struct mii_bus *bus, int sw_addr)
        return NULL;
 }
 
-static char *mv88e6060_drv_probe(struct device *dsa_dev,
-                                struct device *host_dev,
-                                int sw_addr, void **_priv)
+static const char *mv88e6060_drv_probe(struct device *dsa_dev,
+                                      struct device *host_dev, int sw_addr,
+                                      void **_priv)
 {
        struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
        struct mv88e6060_priv *priv;
-       char *name;
+       const char *name;
 
        name = mv88e6060_get_name(bus, sw_addr);
        if (name) {
index 140e44e50e8a0743f6cd6146c8051efb83a51be6..534ebc84de84078c7e3c33ad56edb0260d6f39fe 100644 (file)
 #include <net/dsa.h>
 #include "mv88e6xxx.h"
 
-static const struct mv88e6xxx_switch_id mv88e6123_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 const struct mv88e6xxx_info mv88e6123_table[] = {
+       {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6123,
+               .family = MV88E6XXX_FAMILY_6165,
+               .name = "Marvell 88E6123",
+               .num_databases = 4096,
+               .num_ports = 3,
+       }, {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
+               .family = MV88E6XXX_FAMILY_6165,
+               .name = "Marvell 88E6161",
+               .num_databases = 4096,
+               .num_ports = 6,
+       }, {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
+               .family = MV88E6XXX_FAMILY_6165,
+               .name = "Marvell 88E6165",
+               .num_databases = 4096,
+               .num_ports = 6,
+       }
 };
 
-static char *mv88e6123_drv_probe(struct device *dsa_dev,
-                                struct device *host_dev,
-                                int sw_addr, void **priv)
+static const char *mv88e6123_drv_probe(struct device *dsa_dev,
+                                      struct device *host_dev, int sw_addr,
+                                      void **priv)
 {
        return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
                                   mv88e6123_table,
@@ -76,27 +86,12 @@ static int mv88e6123_setup_global(struct dsa_switch *ds)
 
 static int mv88e6123_setup(struct dsa_switch *ds)
 {
-       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
        int ret;
 
-       ps->ds = ds;
-
        ret = mv88e6xxx_setup_common(ds);
        if (ret < 0)
                return ret;
 
-       switch (ps->id) {
-       case PORT_SWITCH_ID_6123:
-               ps->num_ports = 3;
-               break;
-       case PORT_SWITCH_ID_6161:
-       case PORT_SWITCH_ID_6165:
-               ps->num_ports = 6;
-               break;
-       default:
-               return -ENODEV;
-       }
-
        ret = mv88e6xxx_switch_reset(ds, false);
        if (ret < 0)
                return ret;
index 34d297b650400f83545e00f4139426ad239ed09b..c3eb9a884cfda7cc03a68d45b888d394ed1b4705 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 const struct mv88e6xxx_info mv88e6131_table[] = {
+       {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6095,
+               .family = MV88E6XXX_FAMILY_6095,
+               .name = "Marvell 88E6095/88E6095F",
+               .num_databases = 256,
+               .num_ports = 11,
+       }, {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
+               .family = MV88E6XXX_FAMILY_6097,
+               .name = "Marvell 88E6085",
+               .num_databases = 4096,
+               .num_ports = 10,
+       }, {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
+               .family = MV88E6XXX_FAMILY_6185,
+               .name = "Marvell 88E6131",
+               .num_databases = 256,
+               .num_ports = 8,
+       }, {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
+               .family = MV88E6XXX_FAMILY_6185,
+               .name = "Marvell 88E6185",
+               .num_databases = 256,
+               .num_ports = 10,
+       }
 };
 
-static char *mv88e6131_drv_probe(struct device *dsa_dev,
-                                struct device *host_dev,
-                                int sw_addr, void **priv)
+static const char *mv88e6131_drv_probe(struct device *dsa_dev,
+                                      struct device *host_dev, int sw_addr,
+                                      void **priv)
 {
        return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
                                   mv88e6131_table,
@@ -98,33 +118,14 @@ static int mv88e6131_setup_global(struct dsa_switch *ds)
 
 static int mv88e6131_setup(struct dsa_switch *ds)
 {
-       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
        int ret;
 
-       ps->ds = ds;
-
        ret = mv88e6xxx_setup_common(ds);
        if (ret < 0)
                return ret;
 
        mv88e6xxx_ppu_state_init(ds);
 
-       switch (ps->id) {
-       case PORT_SWITCH_ID_6085:
-       case PORT_SWITCH_ID_6185:
-               ps->num_ports = 10;
-               break;
-       case PORT_SWITCH_ID_6095:
-               ps->num_ports = 11;
-               break;
-       case PORT_SWITCH_ID_6131:
-       case PORT_SWITCH_ID_6131_B2:
-               ps->num_ports = 8;
-               break;
-       default:
-               return -ENODEV;
-       }
-
        ret = mv88e6xxx_switch_reset(ds, false);
        if (ret < 0)
                return ret;
@@ -140,7 +141,7 @@ static int mv88e6131_port_to_phy_addr(struct dsa_switch *ds, int port)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-       if (port >= 0 && port < ps->num_ports)
+       if (port >= 0 && port < ps->info->num_ports)
                return port;
 
        return -EINVAL;
index b7af2b78f8ee8129d568bdb72018114816abc9c4..841ffe14ef7567b76df3403e5989276ff6b68c7b 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 const struct mv88e6xxx_info mv88e6171_table[] = {
+       {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6171,
+               .family = MV88E6XXX_FAMILY_6351,
+               .name = "Marvell 88E6171",
+               .num_databases = 4096,
+               .num_ports = 7,
+       }, {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
+               .family = MV88E6XXX_FAMILY_6351,
+               .name = "Marvell 88E6175",
+               .num_databases = 4096,
+               .num_ports = 7,
+       }, {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
+               .family = MV88E6XXX_FAMILY_6351,
+               .name = "Marvell 88E6350",
+               .num_databases = 4096,
+               .num_ports = 7,
+       }, {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
+               .family = MV88E6XXX_FAMILY_6351,
+               .name = "Marvell 88E6351",
+               .num_databases = 4096,
+               .num_ports = 7,
+       }
 };
 
-static char *mv88e6171_drv_probe(struct device *dsa_dev,
-                                struct device *host_dev,
-                                int sw_addr, void **priv)
+static const char *mv88e6171_drv_probe(struct device *dsa_dev,
+                                      struct device *host_dev, int sw_addr,
+                                      void **priv)
 {
        return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
                                   mv88e6171_table,
@@ -73,17 +94,12 @@ static int mv88e6171_setup_global(struct dsa_switch *ds)
 
 static int mv88e6171_setup(struct dsa_switch *ds)
 {
-       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
        int ret;
 
-       ps->ds = ds;
-
        ret = mv88e6xxx_setup_common(ds);
        if (ret < 0)
                return ret;
 
-       ps->num_ports = 7;
-
        ret = mv88e6xxx_switch_reset(ds, true);
        if (ret < 0)
                return ret;
index e8cb03fad21a32b5433f9f5eed2964d83fde720d..4afc24df56b85ced1dde5cf31998089b3f471e38 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_6240, "Marvell 88E6240" },
-       { 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 const struct mv88e6xxx_info mv88e6352_table[] = {
+       {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6320,
+               .family = MV88E6XXX_FAMILY_6320,
+               .name = "Marvell 88E6320",
+               .num_databases = 4096,
+               .num_ports = 7,
+       }, {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
+               .family = MV88E6XXX_FAMILY_6320,
+               .name = "Marvell 88E6321",
+               .num_databases = 4096,
+               .num_ports = 7,
+       }, {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
+               .family = MV88E6XXX_FAMILY_6352,
+               .name = "Marvell 88E6172",
+               .num_databases = 4096,
+               .num_ports = 7,
+       }, {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
+               .family = MV88E6XXX_FAMILY_6352,
+               .name = "Marvell 88E6176",
+               .num_databases = 4096,
+               .num_ports = 7,
+       }, {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
+               .family = MV88E6XXX_FAMILY_6352,
+               .name = "Marvell 88E6240",
+               .num_databases = 4096,
+               .num_ports = 7,
+       }, {
+               .prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
+               .family = MV88E6XXX_FAMILY_6352,
+               .name = "Marvell 88E6352",
+               .num_databases = 4096,
+               .num_ports = 7,
+       }
 };
 
-static char *mv88e6352_drv_probe(struct device *dsa_dev,
-                                struct device *host_dev,
-                                int sw_addr, void **priv)
+static const char *mv88e6352_drv_probe(struct device *dsa_dev,
+                                      struct device *host_dev, int sw_addr,
+                                      void **priv)
 {
        return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
                                   mv88e6352_table,
@@ -87,14 +112,10 @@ static int mv88e6352_setup(struct dsa_switch *ds)
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
        int ret;
 
-       ps->ds = ds;
-
        ret = mv88e6xxx_setup_common(ds);
        if (ret < 0)
                return ret;
 
-       ps->num_ports = 7;
-
        mutex_init(&ps->eeprom_mutex);
 
        ret = mv88e6xxx_switch_reset(ds, true);
index b018f20829fb1d5385e0680f92b1a05dc3f64efc..1dd525d8dc0a6f7e9a6d1de56f9799502170671a 100644 (file)
@@ -402,135 +402,63 @@ static bool mv88e6xxx_6065_family(struct dsa_switch *ds)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-       switch (ps->id) {
-       case PORT_SWITCH_ID_6031:
-       case PORT_SWITCH_ID_6061:
-       case PORT_SWITCH_ID_6035:
-       case PORT_SWITCH_ID_6065:
-               return true;
-       }
-       return false;
+       return ps->info->family == MV88E6XXX_FAMILY_6065;
 }
 
 static bool mv88e6xxx_6095_family(struct dsa_switch *ds)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-       switch (ps->id) {
-       case PORT_SWITCH_ID_6092:
-       case PORT_SWITCH_ID_6095:
-               return true;
-       }
-       return false;
+       return ps->info->family == MV88E6XXX_FAMILY_6095;
 }
 
 static bool mv88e6xxx_6097_family(struct dsa_switch *ds)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-       switch (ps->id) {
-       case PORT_SWITCH_ID_6046:
-       case PORT_SWITCH_ID_6085:
-       case PORT_SWITCH_ID_6096:
-       case PORT_SWITCH_ID_6097:
-               return true;
-       }
-       return false;
+       return ps->info->family == MV88E6XXX_FAMILY_6097;
 }
 
 static bool mv88e6xxx_6165_family(struct dsa_switch *ds)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-       switch (ps->id) {
-       case PORT_SWITCH_ID_6123:
-       case PORT_SWITCH_ID_6161:
-       case PORT_SWITCH_ID_6165:
-               return true;
-       }
-       return false;
+       return ps->info->family == MV88E6XXX_FAMILY_6165;
 }
 
 static bool mv88e6xxx_6185_family(struct dsa_switch *ds)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-       switch (ps->id) {
-       case PORT_SWITCH_ID_6121:
-       case PORT_SWITCH_ID_6122:
-       case PORT_SWITCH_ID_6152:
-       case PORT_SWITCH_ID_6155:
-       case PORT_SWITCH_ID_6182:
-       case PORT_SWITCH_ID_6185:
-       case PORT_SWITCH_ID_6108:
-       case PORT_SWITCH_ID_6131:
-               return true;
-       }
-       return false;
+       return ps->info->family == MV88E6XXX_FAMILY_6185;
 }
 
 static bool mv88e6xxx_6320_family(struct dsa_switch *ds)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-       switch (ps->id) {
-       case PORT_SWITCH_ID_6320:
-       case PORT_SWITCH_ID_6321:
-               return true;
-       }
-       return false;
+       return ps->info->family == MV88E6XXX_FAMILY_6320;
 }
 
 static bool mv88e6xxx_6351_family(struct dsa_switch *ds)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-       switch (ps->id) {
-       case PORT_SWITCH_ID_6171:
-       case PORT_SWITCH_ID_6175:
-       case PORT_SWITCH_ID_6350:
-       case PORT_SWITCH_ID_6351:
-               return true;
-       }
-       return false;
+       return ps->info->family == MV88E6XXX_FAMILY_6351;
 }
 
 static bool mv88e6xxx_6352_family(struct dsa_switch *ds)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-       switch (ps->id) {
-       case PORT_SWITCH_ID_6172:
-       case PORT_SWITCH_ID_6176:
-       case PORT_SWITCH_ID_6240:
-       case PORT_SWITCH_ID_6352:
-               return true;
-       }
-       return false;
+       return ps->info->family == MV88E6XXX_FAMILY_6352;
 }
 
 static unsigned int mv88e6xxx_num_databases(struct dsa_switch *ds)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-       /* The following devices have 4-bit identifiers for 16 databases */
-       if (ps->id == PORT_SWITCH_ID_6061)
-               return 16;
-
-       /* The following devices have 6-bit identifiers for 64 databases */
-       if (ps->id == PORT_SWITCH_ID_6065)
-               return 64;
-
-       /* The following devices have 8-bit identifiers for 256 databases */
-       if (mv88e6xxx_6095_family(ds) || mv88e6xxx_6185_family(ds))
-               return 256;
-
-       /* The following devices have 12-bit identifiers for 4096 databases */
-       if (mv88e6xxx_6097_family(ds) || mv88e6xxx_6165_family(ds) ||
-           mv88e6xxx_6351_family(ds) || mv88e6xxx_6352_family(ds))
-               return 4096;
-
-       return 0;
+       return ps->info->num_databases;
 }
 
 static bool mv88e6xxx_has_fid_reg(struct dsa_switch *ds)
@@ -606,7 +534,7 @@ void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
                reg |= PORT_PCS_CTRL_DUPLEX_FULL;
 
        if ((mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds)) &&
-           (port >= ps->num_ports - 2)) {
+           (port >= ps->info->num_ports - 2)) {
                if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
                        reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK;
                if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
@@ -1187,7 +1115,7 @@ static int _mv88e6xxx_port_based_vlan_map(struct dsa_switch *ds, int port)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
        struct net_device *bridge = ps->ports[port].bridge_dev;
-       const u16 mask = (1 << ps->num_ports) - 1;
+       const u16 mask = (1 << ps->info->num_ports) - 1;
        u16 output_ports = 0;
        int reg;
        int i;
@@ -1196,7 +1124,7 @@ static int _mv88e6xxx_port_based_vlan_map(struct dsa_switch *ds, int port)
        if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
                output_ports = mask;
        } else {
-               for (i = 0; i < ps->num_ports; ++i) {
+               for (i = 0; i < ps->info->num_ports; ++i) {
                        /* allow sending frames to every group member */
                        if (bridge && ps->ports[i].bridge_dev == bridge)
                                output_ports |= BIT(i);
@@ -1337,7 +1265,7 @@ static int _mv88e6xxx_vtu_stu_data_read(struct dsa_switch *ds,
                regs[i] = ret;
        }
 
-       for (i = 0; i < ps->num_ports; ++i) {
+       for (i = 0; i < ps->info->num_ports; ++i) {
                unsigned int shift = (i % 4) * 4 + nibble_offset;
                u16 reg = regs[i / 4];
 
@@ -1356,7 +1284,7 @@ static int _mv88e6xxx_vtu_stu_data_write(struct dsa_switch *ds,
        int i;
        int ret;
 
-       for (i = 0; i < ps->num_ports; ++i) {
+       for (i = 0; i < ps->info->num_ports; ++i) {
                unsigned int shift = (i % 4) * 4 + nibble_offset;
                u8 data = entry->data[i];
 
@@ -1688,7 +1616,7 @@ static int _mv88e6xxx_fid_new(struct dsa_switch *ds, u16 *fid)
        bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);
 
        /* Set every FID bit used by the (un)bridged ports */
-       for (i = 0; i < ps->num_ports; ++i) {
+       for (i = 0; i < ps->info->num_ports; ++i) {
                err = _mv88e6xxx_port_fid_get(ds, i, fid);
                if (err)
                        return err;
@@ -1738,7 +1666,7 @@ static int _mv88e6xxx_vtu_new(struct dsa_switch *ds, u16 vid,
                return err;
 
        /* exclude all ports except the CPU and DSA ports */
-       for (i = 0; i < ps->num_ports; ++i)
+       for (i = 0; i < ps->info->num_ports; ++i)
                vlan.data[i] = dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i)
                        ? GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED
                        : GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
@@ -1827,7 +1755,7 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
                if (vlan.vid > vid_end)
                        break;
 
-               for (i = 0; i < ps->num_ports; ++i) {
+               for (i = 0; i < ps->info->num_ports; ++i) {
                        if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
                                continue;
 
@@ -1976,7 +1904,7 @@ static int _mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
 
        /* keep the VLAN unless all ports are excluded */
        vlan.valid = false;
-       for (i = 0; i < ps->num_ports; ++i) {
+       for (i = 0; i < ps->info->num_ports; ++i) {
                if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
                        continue;
 
@@ -2285,11 +2213,11 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
        mutex_lock(&ps->smi_mutex);
 
        /* Get or create the bridge FID and assign it to the port */
-       for (i = 0; i < ps->num_ports; ++i)
+       for (i = 0; i < ps->info->num_ports; ++i)
                if (ps->ports[i].bridge_dev == bridge)
                        break;
 
-       if (i < ps->num_ports)
+       if (i < ps->info->num_ports)
                err = _mv88e6xxx_port_fid_get(ds, i, &fid);
        else
                err = _mv88e6xxx_fid_new(ds, &fid);
@@ -2303,7 +2231,7 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
        /* Assign the bridge and remap each port's VLANTable */
        ps->ports[port].bridge_dev = bridge;
 
-       for (i = 0; i < ps->num_ports; ++i) {
+       for (i = 0; i < ps->info->num_ports; ++i) {
                if (ps->ports[i].bridge_dev == bridge) {
                        err = _mv88e6xxx_port_based_vlan_map(ds, i);
                        if (err)
@@ -2334,7 +2262,7 @@ void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
        /* Unassign the bridge and remap each port's VLANTable */
        ps->ports[port].bridge_dev = NULL;
 
-       for (i = 0; i < ps->num_ports; ++i)
+       for (i = 0; i < ps->info->num_ports; ++i)
                if (i == port || ps->ports[i].bridge_dev == bridge)
                        if (_mv88e6xxx_port_based_vlan_map(ds, i))
                                netdev_warn(ds->ports[i], "failed to remap\n");
@@ -2353,7 +2281,7 @@ static void mv88e6xxx_bridge_work(struct work_struct *work)
 
        mutex_lock(&ps->smi_mutex);
 
-       for (port = 0; port < ps->num_ports; ++port)
+       for (port = 0; port < ps->info->num_ports; ++port)
                if (test_and_clear_bit(port, ps->port_state_update_mask) &&
                    _mv88e6xxx_port_state(ds, port, ps->ports[port].state))
                        netdev_warn(ds->ports[port], "failed to update state to %s\n",
@@ -2685,7 +2613,7 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
        int ret;
        int i;
 
-       for (i = 0; i < ps->num_ports; i++) {
+       for (i = 0; i < ps->info->num_ports; i++) {
                ret = mv88e6xxx_setup_port(ds, i);
                if (ret < 0)
                        return ret;
@@ -2700,10 +2628,6 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds)
        ps->ds = ds;
        mutex_init(&ps->smi_mutex);
 
-       ps->id = mv88e6xxx_reg_read(ds, REG_PORT(0), PORT_SWITCH_ID) & 0xfff0;
-       if (ps->id < 0)
-               return ps->id;
-
        INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
 
        return 0;
@@ -2796,7 +2720,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
                err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_TRUNK_MASK,
                                           0x8000 |
                                           (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) |
-                                          ((1 << ps->num_ports) - 1));
+                                          ((1 << ps->info->num_ports) - 1));
                if (err)
                        goto unlock;
        }
@@ -2849,7 +2773,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
                 * ingress rate limit registers to their initial
                 * state.
                 */
-               for (i = 0; i < ps->num_ports; i++) {
+               for (i = 0; i < ps->info->num_ports; i++) {
                        err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2,
                                                   GLOBAL2_INGRESS_OP,
                                                   0x9000 | (i << 8));
@@ -2894,7 +2818,7 @@ int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active)
        mutex_lock(&ps->smi_mutex);
 
        /* Set all ports to the disabled state. */
-       for (i = 0; i < ps->num_ports; i++) {
+       for (i = 0; i < ps->info->num_ports; i++) {
                ret = _mv88e6xxx_reg_read(ds, REG_PORT(i), PORT_CONTROL);
                if (ret < 0)
                        goto unlock;
@@ -2977,7 +2901,7 @@ static int mv88e6xxx_port_to_phy_addr(struct dsa_switch *ds, int port)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-       if (port >= 0 && port < ps->num_ports)
+       if (port >= 0 && port < ps->info->num_ports)
                return port;
        return -EINVAL;
 }
@@ -3173,61 +3097,60 @@ int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
 }
 #endif /* CONFIG_NET_DSA_HWMON */
 
-static char *mv88e6xxx_lookup_name(struct mii_bus *bus, int sw_addr,
-                                  const struct mv88e6xxx_switch_id *table,
-                                  unsigned int num)
+static const struct mv88e6xxx_info *
+mv88e6xxx_lookup_info(unsigned int prod_num, const struct mv88e6xxx_info *table,
+                     unsigned int num)
 {
-       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;
+       int i;
 
-       /* 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(&bus->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;
-               }
-       }
+               if (table[i].prod_num == prod_num)
+                       return &table[i];
 
        return NULL;
 }
 
-char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
-                         int sw_addr, void **priv,
-                         const struct mv88e6xxx_switch_id *table,
-                         unsigned int num)
+const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
+                               int sw_addr, void **priv,
+                               const struct mv88e6xxx_info *table,
+                               unsigned int num)
 {
+       const struct mv88e6xxx_info *info;
        struct mv88e6xxx_priv_state *ps;
-       struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
-       char *name;
+       struct mii_bus *bus;
+       const char *name;
+       int id, prod_num, rev;
 
+       bus = dsa_host_dev_to_mii_bus(host_dev);
        if (!bus)
                return NULL;
 
-       name = mv88e6xxx_lookup_name(bus, sw_addr, table, num);
-       if (name) {
-               ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL);
-               if (!ps)
-                       return NULL;
-               *priv = ps;
-               ps->bus = dsa_host_dev_to_mii_bus(host_dev);
-               if (!ps->bus)
-                       return NULL;
-               ps->sw_addr = sw_addr;
-       }
+       id = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), PORT_SWITCH_ID);
+       if (id < 0)
+               return NULL;
+
+       prod_num = (id & 0xfff0) >> 4;
+       rev = id & 0x000f;
+
+       info = mv88e6xxx_lookup_info(prod_num, table, num);
+       if (!info)
+               return NULL;
+
+       name = info->name;
+
+       ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL);
+       if (!ps)
+               return NULL;
+
+       ps->bus = bus;
+       ps->sw_addr = sw_addr;
+       ps->info = info;
+
+       *priv = ps;
+
+       dev_info(&ps->bus->dev, "switch 0x%x probed: %s, revision %u\n",
+                prod_num, name, rev);
+
        return name;
 }
 
index 0debb9f3cf0a0663dba203f8f22db6eee47265b0..0dbe2d1779dd46928d5e700ad1e2987de27c7163 100644 (file)
 #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 PORT_SWITCH_ID_6061    0x0610
-#define PORT_SWITCH_ID_6065    0x0650
-#define PORT_SWITCH_ID_6085    0x04a0
-#define PORT_SWITCH_ID_6092    0x0970
-#define PORT_SWITCH_ID_6095    0x0950
-#define PORT_SWITCH_ID_6096    0x0980
-#define PORT_SWITCH_ID_6097    0x0990
-#define PORT_SWITCH_ID_6108    0x1070
-#define PORT_SWITCH_ID_6121    0x1040
-#define PORT_SWITCH_ID_6122    0x1050
-#define PORT_SWITCH_ID_6123    0x1210
-#define PORT_SWITCH_ID_6123_A1 0x1212
-#define PORT_SWITCH_ID_6123_A2 0x1213
-#define PORT_SWITCH_ID_6131    0x1060
-#define PORT_SWITCH_ID_6131_B2 0x1066
-#define PORT_SWITCH_ID_6152    0x1a40
-#define PORT_SWITCH_ID_6155    0x1a50
-#define PORT_SWITCH_ID_6161    0x1610
-#define PORT_SWITCH_ID_6161_A1 0x1612
-#define PORT_SWITCH_ID_6161_A2 0x1613
-#define PORT_SWITCH_ID_6165    0x1650
-#define PORT_SWITCH_ID_6165_A1 0x1652
-#define PORT_SWITCH_ID_6165_A2 0x1653
-#define PORT_SWITCH_ID_6171    0x1710
-#define PORT_SWITCH_ID_6172    0x1720
-#define PORT_SWITCH_ID_6175    0x1750
-#define PORT_SWITCH_ID_6176    0x1760
-#define PORT_SWITCH_ID_6182    0x1a60
-#define PORT_SWITCH_ID_6185    0x1a70
-#define PORT_SWITCH_ID_6240    0x2400
-#define PORT_SWITCH_ID_6320    0x1150
-#define PORT_SWITCH_ID_6320_A1 0x1151
-#define PORT_SWITCH_ID_6320_A2 0x1152
-#define PORT_SWITCH_ID_6321    0x3100
-#define PORT_SWITCH_ID_6321_A1 0x3101
-#define PORT_SWITCH_ID_6321_A2 0x3102
-#define PORT_SWITCH_ID_6350    0x3710
-#define PORT_SWITCH_ID_6351    0x3750
-#define PORT_SWITCH_ID_6352    0x3520
-#define PORT_SWITCH_ID_6352_A0 0x3521
-#define PORT_SWITCH_ID_6352_A1 0x3522
+#define PORT_SWITCH_ID_PROD_NUM_6085   0x04a
+#define PORT_SWITCH_ID_PROD_NUM_6095   0x095
+#define PORT_SWITCH_ID_PROD_NUM_6131   0x106
+#define PORT_SWITCH_ID_PROD_NUM_6320   0x115
+#define PORT_SWITCH_ID_PROD_NUM_6123   0x121
+#define PORT_SWITCH_ID_PROD_NUM_6161   0x161
+#define PORT_SWITCH_ID_PROD_NUM_6165   0x165
+#define PORT_SWITCH_ID_PROD_NUM_6171   0x171
+#define PORT_SWITCH_ID_PROD_NUM_6172   0x172
+#define PORT_SWITCH_ID_PROD_NUM_6175   0x175
+#define PORT_SWITCH_ID_PROD_NUM_6176   0x176
+#define PORT_SWITCH_ID_PROD_NUM_6185   0x1a7
+#define PORT_SWITCH_ID_PROD_NUM_6240   0x240
+#define PORT_SWITCH_ID_PROD_NUM_6321   0x310
+#define PORT_SWITCH_ID_PROD_NUM_6352   0x352
+#define PORT_SWITCH_ID_PROD_NUM_6350   0x371
+#define PORT_SWITCH_ID_PROD_NUM_6351   0x375
 #define PORT_CONTROL           0x04
 #define PORT_CONTROL_USE_CORE_TAG      BIT(15)
 #define PORT_CONTROL_DROP_ON_LOCK      BIT(14)
 
 #define MV88E6XXX_N_FID                4096
 
-struct mv88e6xxx_switch_id {
-       u16 id;
-       char *name;
+enum mv88e6xxx_family {
+       MV88E6XXX_FAMILY_NONE,
+       MV88E6XXX_FAMILY_6065,  /* 6031 6035 6061 6065 */
+       MV88E6XXX_FAMILY_6095,  /* 6092 6095 */
+       MV88E6XXX_FAMILY_6097,  /* 6046 6085 6096 6097 */
+       MV88E6XXX_FAMILY_6165,  /* 6123 6161 6165 */
+       MV88E6XXX_FAMILY_6185,  /* 6108 6121 6122 6131 6152 6155 6182 6185 */
+       MV88E6XXX_FAMILY_6320,  /* 6320 6321 */
+       MV88E6XXX_FAMILY_6351,  /* 6171 6175 6350 6351 */
+       MV88E6XXX_FAMILY_6352,  /* 6172 6176 6240 6352 */
+};
+
+struct mv88e6xxx_info {
+       enum mv88e6xxx_family family;
+       u16 prod_num;
+       const char *name;
+       unsigned int num_databases;
+       unsigned int num_ports;
 };
 
 struct mv88e6xxx_atu_entry {
@@ -397,6 +383,8 @@ struct mv88e6xxx_priv_port {
 };
 
 struct mv88e6xxx_priv_state {
+       const struct mv88e6xxx_info *info;
+
        /* The dsa_switch this private structure is related to */
        struct dsa_switch *ds;
 
@@ -438,9 +426,6 @@ struct mv88e6xxx_priv_state {
         */
        struct mutex eeprom_mutex;
 
-       int             id; /* switch product id */
-       int             num_ports;      /* number of switch ports */
-
        struct mv88e6xxx_priv_port      ports[DSA_MAX_PORTS];
 
        DECLARE_BITMAP(port_state_update_mask, DSA_MAX_PORTS);
@@ -462,10 +447,10 @@ struct mv88e6xxx_hw_stat {
 };
 
 int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active);
-char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
-                         int sw_addr, void **priv,
-                         const struct mv88e6xxx_switch_id *table,
-                         unsigned int num);
+const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
+                               int sw_addr, void **priv,
+                               const struct mv88e6xxx_info *table,
+                               unsigned int num);
 
 int mv88e6xxx_setup_ports(struct dsa_switch *ds);
 int mv88e6xxx_setup_common(struct dsa_switch *ds);
index 689ebd3542ba9e4aa96e7d9d31e2231dfd0e88ca..c4bc42bd3538c7add51861bdddf30f16663b31f9 100644 (file)
@@ -217,8 +217,9 @@ struct dsa_switch_driver {
        /*
         * Probing and setup.
         */
-       char    *(*probe)(struct device *dsa_dev, struct device *host_dev,
-                         int sw_addr, void **priv);
+       const char      *(*probe)(struct device *dsa_dev,
+                                 struct device *host_dev, int sw_addr,
+                                 void **priv);
        int     (*setup)(struct dsa_switch *ds);
        int     (*set_addr)(struct dsa_switch *ds, u8 *addr);
        u32     (*get_phy_flags)(struct dsa_switch *ds, int port);
index 60ea98481806f361a09025344e48663c5a1c9b70..efa612f0ab9b16f140f4dbdefc5f3d0f74b2efba 100644 (file)
@@ -52,11 +52,11 @@ EXPORT_SYMBOL_GPL(unregister_switch_driver);
 
 static struct dsa_switch_driver *
 dsa_switch_probe(struct device *parent, struct device *host_dev, int sw_addr,
-                char **_name, void **priv)
+                const char **_name, void **priv)
 {
        struct dsa_switch_driver *ret;
        struct list_head *list;
-       char *name;
+       const char *name;
 
        ret = NULL;
        name = NULL;
@@ -383,7 +383,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
        struct dsa_switch_driver *drv;
        struct dsa_switch *ds;
        int ret;
-       char *name;
+       const char *name;
        void *priv;
 
        /*
This page took 0.044966 seconds and 5 git commands to generate.