Changing the ATU hash algorithm invalidates existing entries: those
loaded under the previous algorithm end up in different bins and read
back corrupted.
Flush the ATU whenever the hash algorithm is changed through devlink
and reload the default broadcast entries. Per-VLAN ATU entries and
any static addresses are not replayed, so the hash must be selected
before the FDB or MDB are configured.
Fixes: 23e8b470c778 ("net: dsa: mv88e6xxx: Add devlink param for ATU hash algorithm.")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Luke Howard <redacted>
---
drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
drivers/net/dsa/mv88e6xxx/chip.h | 2 ++
drivers/net/dsa/mv88e6xxx/devlink.c | 6 ++++++
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 7938e50900ca8..6faae74de04a9 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2523,7 +2523,7 @@ static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port,
return mv88e6xxx_port_db_load_purge(chip, port, broadcast, vid, state);
}
-static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid)
+int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid)
{
int port;
int err;diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index aca64fd4cb95c..6fda3f83c8885 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -894,4 +894,6 @@ int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
void *priv),
void *priv);
+int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid);
+
#endif /* _MV88E6XXX_CHIP_H */
diff --git a/drivers/net/dsa/mv88e6xxx/devlink.c b/drivers/net/dsa/mv88e6xxx/devlink.c
index 6f034841883c6..5168335f52289 100644
--- a/drivers/net/dsa/mv88e6xxx/devlink.c
+++ b/drivers/net/dsa/mv88e6xxx/devlink.c
@@ -61,6 +61,12 @@ int mv88e6xxx_devlink_param_set(struct dsa_switch *ds, u32 id,
switch (id) {
case MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH:
err = mv88e6xxx_atu_set_hash(chip, ctx->val.vu8);
+ if (err)
+ break;
+ err = mv88e6xxx_g1_atu_flush(chip, 0, true);
+ if (err)
+ break;
+ err = mv88e6xxx_broadcast_setup(chip, 0);
break;
default:
err = -EOPNOTSUPP;
--
2.43.0