diff options
author | Vivien Didelot <vivien.didelot@savoirfairelinux.com> | 2015-09-04 14:34:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-09-15 12:04:21 -0700 |
commit | 7fb5e755153d7b40dd321f7c766dbd4e76c66711 (patch) | |
tree | e3e8914a2e82c2f16b3e147def3190e5074aa11d /drivers/net/dsa/mv88e6xxx.c | |
parent | 37705b731500b0ce9fb4ead21a7cdfc241a401fe (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.c | 49 |
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) |