diff options
author | Vivien Didelot <vivien.didelot@savoirfairelinux.com> | 2017-03-12 00:12:55 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-03-13 09:54:06 +0300 |
commit | e606ca36bbf2e243171d42186573df254b33a123 (patch) | |
tree | 0a2e8f7aad970939a1adf26c1bebf0e4db655856 /drivers/net/dsa/mv88e6xxx/global1_atu.c | |
parent | daefc94321ee146df2a750a4575bfbde98bad2d9 (diff) | |
download | linux-e606ca36bbf2e243171d42186573df254b33a123.tar.xz |
net: dsa: mv88e6xxx: rework ATU Remove
Add a fresh documented implementation of the ATU Move operation, and use
it to replace the current ATU Remove operation.
Note that not all Marvell switch chip support the ATU Move operation.
For those supporting it, the number of bits used to mask the destination
port may vary. 6352 and such use 4-bit, while 6390 use 5-bit. Thus add a
new atu_move_port_mask member in the info structure to describe the
presence and variant of ATU Move operation.
Note that the ATU Move operation is not documented in the 6185 datasheet
but the chip does support the operation.
All remaining _mv88e6xxx_atu_* functions are now unused as well as the
MV88E6XXX_FLAG_G1_ATU_FID flag, thus remove them.
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/global1_atu.c')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/global1_atu.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/global1_atu.c b/drivers/net/dsa/mv88e6xxx/global1_atu.c index 7ec9b22feaee..d753e3eb1359 100644 --- a/drivers/net/dsa/mv88e6xxx/global1_atu.c +++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c @@ -269,3 +269,32 @@ int mv88e6xxx_g1_atu_flush(struct mv88e6xxx_chip *chip, u16 fid, bool all) return mv88e6xxx_g1_atu_flushmove(chip, fid, &entry, all); } + +static int mv88e6xxx_g1_atu_move(struct mv88e6xxx_chip *chip, u16 fid, + int from_port, int to_port, bool all) +{ + struct mv88e6xxx_atu_entry entry = { 0 }; + unsigned long mask; + int shift; + + if (!chip->info->atu_move_port_mask) + return -EOPNOTSUPP; + + mask = chip->info->atu_move_port_mask; + shift = bitmap_weight(&mask, 16); + + entry.state = 0xf, /* Full EntryState means Move */ + entry.portv_trunkid = from_port & mask; + entry.portv_trunkid |= (to_port & mask) << shift; + + return mv88e6xxx_g1_atu_flushmove(chip, fid, &entry, all); +} + +int mv88e6xxx_g1_atu_remove(struct mv88e6xxx_chip *chip, u16 fid, int port, + bool all) +{ + int from_port = port; + int to_port = chip->info->atu_move_port_mask; + + return mv88e6xxx_g1_atu_move(chip, fid, from_port, to_port, all); +} |