summaryrefslogtreecommitdiff
path: root/drivers/net/dsa
diff options
context:
space:
mode:
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>2016-12-05 17:30:25 -0500
committerDavid S. Miller <davem@davemloft.net>2016-12-06 11:32:28 -0500
commit4ac4b5a623f808e64d4d17b14bc23e934eaed008 (patch)
tree2ff0f53e4f108ba2e7a9706aa4a3ace1617c3c64 /drivers/net/dsa
parent9f9ffdffe9112abae781e5f4b44e7d2bc96aa6d5 (diff)
net: dsa: mv88e6xxx: add helper to disable ports
Before resetting a switch, the ports should be set to the Disabled state and the transmit queues should be drained. Add an helper to explicit that. Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 7a6c58783914..7cbaff721318 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2356,17 +2356,11 @@ static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
mutex_unlock(&chip->reg_lock);
}
-static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
+static int mv88e6xxx_disable_ports(struct mv88e6xxx_chip *chip)
{
- bool ppu_active = mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU_ACTIVE);
- u16 is_reset = (ppu_active ? 0x8800 : 0xc800);
- struct gpio_desc *gpiod = chip->reset;
- unsigned long timeout;
- u16 reg;
- int err;
- int i;
+ int i, err;
- /* Set all ports to the disabled state. */
+ /* Set all ports to the Disabled state */
for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
err = mv88e6xxx_port_set_state(chip, i,
PORT_CONTROL_STATE_DISABLED);
@@ -2374,9 +2368,27 @@ static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
return err;
}
- /* Wait for transmit queues to drain. */
+ /* Wait for transmit queues to drain,
+ * i.e. 2ms for a maximum frame to be transmitted at 10 Mbps.
+ */
usleep_range(2000, 4000);
+ return 0;
+}
+
+static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
+{
+ bool ppu_active = mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU_ACTIVE);
+ u16 is_reset = (ppu_active ? 0x8800 : 0xc800);
+ struct gpio_desc *gpiod = chip->reset;
+ unsigned long timeout;
+ u16 reg;
+ int err;
+
+ err = mv88e6xxx_disable_ports(chip);
+ if (err)
+ return err;
+
/* If there is a gpio connected to the reset pin, toggle it */
if (gpiod) {
gpiod_set_value_cansleep(gpiod, 1);