The default 88E6341/88E6141 ATU hash algorithm appears to result in frequent collisions, evicting permanent registrations (including the broadcast address) out of the ATU. This workaround disables hasing in the ATU control register. It may have a performance impact (the data sheet notes this is for testing only), but it also enables correctness, at least in local testing. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Luke Howard --- drivers/net/dsa/mv88e6xxx/chip.c | 12 ++++++++++++ drivers/net/dsa/mv88e6xxx/global1.h | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 60d46680fb50e..53ed2b9e30979 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -1699,6 +1699,18 @@ static int mv88e6xxx_atu_setup(struct mv88e6xxx_chip *chip) { int err; + /* Avoid collisions on the 6341 family by disabling hashing. */ + if (chip->info->family == MV88E6XXX_FAMILY_6341 && + chip->info->ops->atu_set_hash) { + u8 hash = MV88E6161_G1_ATU_CTL_HASH_DIRECT; + + err = chip->info->ops->atu_set_hash(chip, hash); + if (err) + return err; + + dev_info(chip->dev, "ATU hash mode set to 0x%x\n", hash); + } + err = mv88e6xxx_g1_atu_flush(chip, 0, true); if (err) return err; diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h index 3dbb7a1b8fe11..e2a54eac64832 100644 --- a/drivers/net/dsa/mv88e6xxx/global1.h +++ b/drivers/net/dsa/mv88e6xxx/global1.h @@ -112,7 +112,11 @@ /* Offset 0x0A: ATU Control Register */ #define MV88E6XXX_G1_ATU_CTL 0x0a #define MV88E6XXX_G1_ATU_CTL_LEARN2ALL 0x0008 -#define MV88E6161_G1_ATU_CTL_HASH_MASK 0x0003 +#define MV88E6161_G1_ATU_CTL_HASH_MASK 0x0003 +#define MV88E6161_G1_ATU_CTL_HASH_RESERVED_0 0x0000 +#define MV88E6161_G1_ATU_CTL_HASH_DEFAULT 0x0001 +#define MV88E6161_G1_ATU_CTL_HASH_RESERVED_1 0x0002 +#define MV88E6161_G1_ATU_CTL_HASH_DIRECT 0x0003 /* Offset 0x0B: ATU Operation Register */ #define MV88E6XXX_G1_ATU_OP 0x0b -- 2.43.0