net: dsa: mv88e6xxx: flush VTU and STU entries
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>
Thu, 13 Aug 2015 16:52:18 +0000 (12:52 -0400)
committerDavid S. Miller <davem@davemloft.net>
Fri, 14 Aug 2015 04:31:13 +0000 (21:31 -0700)
Implement the VTU Flush operation (which also flushes the STU), so that
warm boots won't preserved old entries.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/mv88e6xxx.c
drivers/net/dsa/mv88e6xxx.h

index 9978245..175353a 100644 (file)
@@ -1182,6 +1182,34 @@ int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state)
        return 0;
 }
 
+static int _mv88e6xxx_vtu_wait(struct dsa_switch *ds)
+{
+       return _mv88e6xxx_wait(ds, REG_GLOBAL, GLOBAL_VTU_OP,
+                              GLOBAL_VTU_OP_BUSY);
+}
+
+static int _mv88e6xxx_vtu_cmd(struct dsa_switch *ds, u16 op)
+{
+       int ret;
+
+       ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_OP, op);
+       if (ret < 0)
+               return ret;
+
+       return _mv88e6xxx_vtu_wait(ds);
+}
+
+static int _mv88e6xxx_vtu_stu_flush(struct dsa_switch *ds)
+{
+       int ret;
+
+       ret = _mv88e6xxx_vtu_wait(ds);
+       if (ret < 0)
+               return ret;
+
+       return _mv88e6xxx_vtu_cmd(ds, GLOBAL_VTU_OP_FLUSH_ALL);
+}
+
 static int _mv88e6xxx_atu_mac_write(struct dsa_switch *ds,
                                    const unsigned char *addr)
 {
@@ -2071,6 +2099,12 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
        /* Wait for the flush to complete. */
        mutex_lock(&ps->smi_mutex);
        ret = _mv88e6xxx_stats_wait(ds);
+       if (ret < 0)
+               goto unlock;
+
+       /* Clear all the VTU and STU entries */
+       ret = _mv88e6xxx_vtu_stu_flush(ds);
+unlock:
        mutex_unlock(&ps->smi_mutex);
 
        return ret;
index 10fae32..76139ea 100644 (file)
 #define GLOBAL_CONTROL_TCAM_EN         BIT(1)
 #define GLOBAL_CONTROL_EEPROM_DONE_EN  BIT(0)
 #define GLOBAL_VTU_OP          0x05
+#define GLOBAL_VTU_OP_BUSY     BIT(15)
+#define GLOBAL_VTU_OP_FLUSH_ALL                ((0x01 << 12) | GLOBAL_VTU_OP_BUSY)
 #define GLOBAL_VTU_VID         0x06
 #define GLOBAL_VTU_DATA_0_3    0x07
 #define GLOBAL_VTU_DATA_4_7    0x08