summaryrefslogtreecommitdiff
path: root/drivers/net/dsa/mv88e6xxx/global1_atu.c
diff options
context:
space:
mode:
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>2017-03-12 00:12:55 +0300
committerDavid S. Miller <davem@davemloft.net>2017-03-13 09:54:06 +0300
commite606ca36bbf2e243171d42186573df254b33a123 (patch)
tree0a2e8f7aad970939a1adf26c1bebf0e4db655856 /drivers/net/dsa/mv88e6xxx/global1_atu.c
parentdaefc94321ee146df2a750a4575bfbde98bad2d9 (diff)
downloadlinux-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.c29
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);
+}