summaryrefslogtreecommitdiff
path: root/drivers/net/dsa/mv88e6xxx.c
diff options
context:
space:
mode:
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>2015-09-04 14:34:12 -0400
committerDavid S. Miller <davem@davemloft.net>2015-09-15 12:04:21 -0700
commit7fb5e755153d7b40dd321f7c766dbd4e76c66711 (patch)
treee3e8914a2e82c2f16b3e147def3190e5074aa11d /drivers/net/dsa/mv88e6xxx.c
parent37705b731500b0ce9fb4ead21a7cdfc241a401fe (diff)
net: dsa: mv88e6xxx: rework ATU Flush operation
These Marvell switches have 4 operations to flush or (re)move, all or only non-static MAC addresses, from the entire set of databases or from just a particular one. The value of the EntryState bits will determine if the operation is either a Flush (0x0) or a Move (0xF). When moving entries from one port to another, entries will be removed if the destination port is 0xF. This patch renames these operations for consistency, add a new generic _mv88e6xxx_atu_flush_move function, and change _mv88e6xxx_flush_fid to use it. Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx.c')
-rw-r--r--drivers/net/dsa/mv88e6xxx.c49
1 files changed, 40 insertions, 9 deletions
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 25e103c5ed16..c67090f0814d 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -1070,19 +1070,50 @@ static int _mv88e6xxx_atu_data_write(struct dsa_switch *ds,
return _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_DATA, data);
}
-static int _mv88e6xxx_flush_fid(struct dsa_switch *ds, int fid)
+static int _mv88e6xxx_atu_flush_move(struct dsa_switch *ds,
+ struct mv88e6xxx_atu_entry *entry,
+ bool static_too)
{
- int ret;
+ int op;
+ int err;
- ret = _mv88e6xxx_atu_wait(ds);
- if (ret < 0)
- return ret;
+ err = _mv88e6xxx_atu_wait(ds);
+ if (err)
+ return err;
- ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_FID, fid);
- if (ret < 0)
- return ret;
+ err = _mv88e6xxx_atu_data_write(ds, entry);
+ if (err)
+ return err;
+
+ if (entry->fid) {
+ err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_FID,
+ entry->fid);
+ if (err)
+ return err;
+
+ op = static_too ? GLOBAL_ATU_OP_FLUSH_MOVE_ALL_DB :
+ GLOBAL_ATU_OP_FLUSH_MOVE_NON_STATIC_DB;
+ } else {
+ op = static_too ? GLOBAL_ATU_OP_FLUSH_MOVE_ALL :
+ GLOBAL_ATU_OP_FLUSH_MOVE_NON_STATIC;
+ }
+
+ return _mv88e6xxx_atu_cmd(ds, op);
+}
- return _mv88e6xxx_atu_cmd(ds, GLOBAL_ATU_OP_FLUSH_NON_STATIC_DB);
+static int _mv88e6xxx_atu_flush(struct dsa_switch *ds, u16 fid, bool static_too)
+{
+ struct mv88e6xxx_atu_entry entry = {
+ .fid = fid,
+ .state = 0, /* EntryState bits must be 0 */
+ };
+
+ return _mv88e6xxx_atu_flush_move(ds, &entry, static_too);
+}
+
+static int _mv88e6xxx_flush_fid(struct dsa_switch *ds, int fid)
+{
+ return _mv88e6xxx_atu_flush(ds, fid, false);
}
static int mv88e6xxx_set_port_state(struct dsa_switch *ds, int port, u8 state)