net: dsa: Centralize Marvell switch reset
authorAndrew Lunn <andrew@lunn.ch>
Thu, 2 Apr 2015 02:06:34 +0000 (04:06 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 2 Apr 2015 02:55:40 +0000 (22:55 -0400)
Marvell switches are all reset in nearly the same way. The only
difference is if the PPU should be enabled or not. Move this
code into the shared mv88x6xxx.c.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Guenter Roeck <linux@roeck-us.net>
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 6480f77829ef6301f14ba4a527d6865eb6eeed43..10228ad4815129fdf66f32735bb2a11ff1992fac 100644 (file)
@@ -52,40 +52,6 @@ static char *mv88e6123_61_65_probe(struct device *host_dev, int sw_addr)
        return NULL;
 }
 
-static int mv88e6123_61_65_switch_reset(struct dsa_switch *ds)
-{
-       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-       int i;
-       int ret;
-       unsigned long timeout;
-
-       /* Set all ports to the disabled state. */
-       for (i = 0; i < ps->num_ports; i++) {
-               ret = REG_READ(REG_PORT(i), 0x04);
-               REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
-       }
-
-       /* Wait for transmit queues to drain. */
-       usleep_range(2000, 4000);
-
-       /* Reset the switch. */
-       REG_WRITE(REG_GLOBAL, 0x04, 0xc400);
-
-       /* Wait up to one second for reset to complete. */
-       timeout = jiffies + 1 * HZ;
-       while (time_before(jiffies, timeout)) {
-               ret = REG_READ(REG_GLOBAL, 0x00);
-               if ((ret & 0xc800) == 0xc800)
-                       break;
-
-               usleep_range(1000, 2000);
-       }
-       if (time_after(jiffies, timeout))
-               return -ETIMEDOUT;
-
-       return 0;
-}
-
 static int mv88e6123_61_65_setup_global(struct dsa_switch *ds)
 {
        int ret;
@@ -292,7 +258,7 @@ static int mv88e6123_61_65_setup(struct dsa_switch *ds)
                return -ENODEV;
        }
 
-       ret = mv88e6123_61_65_switch_reset(ds);
+       ret = mv88e6xxx_switch_reset(ds, false);
        if (ret < 0)
                return ret;
 
index 6b818fde2216b17ecbe19057e0fde2e3038e48ae..534a8f0b1c28874ea3c345fb4af2e29e06e9f626 100644 (file)
@@ -42,40 +42,6 @@ static char *mv88e6131_probe(struct device *host_dev, int sw_addr)
        return NULL;
 }
 
-static int mv88e6131_switch_reset(struct dsa_switch *ds)
-{
-       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-       int i;
-       int ret;
-       unsigned long timeout;
-
-       /* Set all ports to the disabled state. */
-       for (i = 0; i < ps->num_ports; i++) {
-               ret = REG_READ(REG_PORT(i), 0x04);
-               REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
-       }
-
-       /* Wait for transmit queues to drain. */
-       usleep_range(2000, 4000);
-
-       /* Reset the switch. */
-       REG_WRITE(REG_GLOBAL, 0x04, 0xc400);
-
-       /* Wait up to one second for reset to complete. */
-       timeout = jiffies + 1 * HZ;
-       while (time_before(jiffies, timeout)) {
-               ret = REG_READ(REG_GLOBAL, 0x00);
-               if ((ret & 0xc800) == 0xc800)
-                       break;
-
-               usleep_range(1000, 2000);
-       }
-       if (time_after(jiffies, timeout))
-               return -ETIMEDOUT;
-
-       return 0;
-}
-
 static int mv88e6131_setup_global(struct dsa_switch *ds)
 {
        int ret;
@@ -281,7 +247,7 @@ static int mv88e6131_setup(struct dsa_switch *ds)
                return -ENODEV;
        }
 
-       ret = mv88e6131_switch_reset(ds);
+       ret = mv88e6xxx_switch_reset(ds, false);
        if (ret < 0)
                return ret;
 
index 5a295533ff20c73a6a7c4b6ebfd35f149f228d03..69b35d124de5b128ac2479e0cbef318349f93a82 100644 (file)
@@ -36,52 +36,6 @@ static char *mv88e6171_probe(struct device *host_dev, int sw_addr)
        return NULL;
 }
 
-static int mv88e6171_switch_reset(struct dsa_switch *ds)
-{
-       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-       int i;
-       int ret;
-       unsigned long timeout;
-
-       /* Set all ports to the disabled state. */
-       for (i = 0; i < ps->num_ports; i++) {
-               ret = REG_READ(REG_PORT(i), 0x04);
-               REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
-       }
-
-       /* Wait for transmit queues to drain. */
-       usleep_range(2000, 4000);
-
-       /* Reset the switch. Keep PPU active.  The PPU needs to be
-        * active to support indirect phy register accesses through
-        * global registers 0x18 and 0x19.
-        */
-       REG_WRITE(REG_GLOBAL, 0x04, 0xc000);
-
-       /* Wait up to one second for reset to complete. */
-       timeout = jiffies + 1 * HZ;
-       while (time_before(jiffies, timeout)) {
-               ret = REG_READ(REG_GLOBAL, 0x00);
-               if ((ret & 0xc800) == 0xc800)
-                       break;
-
-               usleep_range(1000, 2000);
-       }
-       if (time_after(jiffies, timeout))
-               return -ETIMEDOUT;
-
-       /* Enable ports not under DSA, e.g. WAN port */
-       for (i = 0; i < ps->num_ports; i++) {
-               if (dsa_is_cpu_port(ds, i) || ds->phys_port_mask & (1 << i))
-                       continue;
-
-               ret = REG_READ(REG_PORT(i), 0x04);
-               REG_WRITE(REG_PORT(i), 0x04, ret | 0x03);
-       }
-
-       return 0;
-}
-
 static int mv88e6171_setup_global(struct dsa_switch *ds)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -282,7 +236,7 @@ static int mv88e6171_setup(struct dsa_switch *ds)
 
        ps->num_ports = 7;
 
-       ret = mv88e6171_switch_reset(ds);
+       ret = mv88e6xxx_switch_reset(ds, true);
        if (ret < 0)
                return ret;
 
index 040027fcd01394af5fae7081b003cdf262ef64b5..214bdbc8a5b19e96361e93bcd422a381f5ce2d89 100644 (file)
@@ -45,42 +45,6 @@ static char *mv88e6352_probe(struct device *host_dev, int sw_addr)
        return NULL;
 }
 
-static int mv88e6352_switch_reset(struct dsa_switch *ds)
-{
-       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-       unsigned long timeout;
-       int ret;
-       int i;
-
-       /* Set all ports to the disabled state. */
-       for (i = 0; i < ps->num_ports; i++) {
-               ret = REG_READ(REG_PORT(i), 0x04);
-               REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
-       }
-
-       /* Wait for transmit queues to drain. */
-       usleep_range(2000, 4000);
-
-       /* Reset the switch. Keep PPU active (bit 14, undocumented).
-        * The PPU needs to be active to support indirect phy register
-        * accesses through global registers 0x18 and 0x19.
-        */
-       REG_WRITE(REG_GLOBAL, 0x04, 0xc000);
-
-       /* Wait up to one second for reset to complete. */
-       timeout = jiffies + 1 * HZ;
-       while (time_before(jiffies, timeout)) {
-               ret = REG_READ(REG_GLOBAL, 0x00);
-               if ((ret & 0x8800) == 0x8800)
-                       break;
-               usleep_range(1000, 2000);
-       }
-       if (time_after(jiffies, timeout))
-               return -ETIMEDOUT;
-
-       return 0;
-}
-
 static int mv88e6352_setup_global(struct dsa_switch *ds)
 {
        struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -373,7 +337,7 @@ static int mv88e6352_setup(struct dsa_switch *ds)
 
        mutex_init(&ps->eeprom_mutex);
 
-       ret = mv88e6352_switch_reset(ds);
+       ret = mv88e6xxx_switch_reset(ds, true);
        if (ret < 0)
                return ret;
 
index 13572cc24c6dc42a308e4bc0b660f3c0f673e48d..9db5b40d78ea047716876465a26920e321ab2ff6 100644 (file)
@@ -1161,6 +1161,46 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds)
        return 0;
 }
 
+int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active)
+{
+       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+       u16 is_reset = (ppu_active ? 0x8800 : 0xc800);
+       unsigned long timeout;
+       int ret;
+       int i;
+
+       /* Set all ports to the disabled state. */
+       for (i = 0; i < ps->num_ports; i++) {
+               ret = REG_READ(REG_PORT(i), 0x04);
+               REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
+       }
+
+       /* Wait for transmit queues to drain. */
+       usleep_range(2000, 4000);
+
+       /* Reset the switch. Keep the PPU active if requested. The PPU
+        * needs to be active to support indirect phy register access
+        * through global registers 0x18 and 0x19.
+        */
+       if (ppu_active)
+               REG_WRITE(REG_GLOBAL, 0x04, 0xc000);
+       else
+               REG_WRITE(REG_GLOBAL, 0x04, 0xc400);
+
+       /* Wait up to one second for reset to complete. */
+       timeout = jiffies + 1 * HZ;
+       while (time_before(jiffies, timeout)) {
+               ret = REG_READ(REG_GLOBAL, 0x00);
+               if ((ret & is_reset) == is_reset)
+                       break;
+               usleep_range(1000, 2000);
+       }
+       if (time_after(jiffies, timeout))
+               return -ETIMEDOUT;
+
+       return 0;
+}
+
 static int __init mv88e6xxx_init(void)
 {
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
index ef058444bdb7d736bfd0b9b64cc5d059dd92c2de..f84d3d5178b90ecb9f6a7231fc45cee8df01c2bc 100644 (file)
@@ -129,6 +129,7 @@ struct mv88e6xxx_hw_stat {
        int reg;
 };
 
+int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active);
 int mv88e6xxx_setup_port_common(struct dsa_switch *ds, int port);
 int mv88e6xxx_setup_common(struct dsa_switch *ds);
 int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg);