Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: ethernet: ti: am65-cpsw-nuss/cpsw-ale: Fix multicast entry handling in ALE table

In the current implementation, flushing multicast entries in MAC mode
incorrectly deletes entries for all ports instead of only the target port,
disrupting multicast traffic on other ports. The cause is adding multicast
entries by setting only host port bit, and not setting the MAC port bits.

Fix this by setting the MAC port's bit in the port mask while adding the
multicast entry. Also fix the flush logic to preserve the host port bit
during removal of MAC port and free ALE entries when mask contains only
host port.

Fixes: 5c50a856d550 ("drivers: net: ethernet: cpsw: add multicast address to ALE table")
Signed-off-by: Chintan Vankar <c-vankar@ti.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260224181359.2055322-1-c-vankar@ti.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Chintan Vankar and committed by
Jakub Kicinski
be11a537 7e5b450c

+5 -6
+1 -1
drivers/net/ethernet/ti/am65-cpsw-nuss.c
··· 391 391 cpsw_ale_set_allmulti(common->ale, 392 392 ndev->flags & IFF_ALLMULTI, port->port_id); 393 393 394 - port_mask = ALE_PORT_HOST; 394 + port_mask = BIT(port->port_id) | ALE_PORT_HOST; 395 395 /* Clear all mcast from ALE */ 396 396 cpsw_ale_flush_multicast(common->ale, port_mask, -1); 397 397
+4 -5
drivers/net/ethernet/ti/cpsw_ale.c
··· 450 450 ale->port_mask_bits); 451 451 if ((mask & port_mask) == 0) 452 452 return; /* ports dont intersect, not interested */ 453 - mask &= ~port_mask; 453 + mask &= (~port_mask | ALE_PORT_HOST); 454 454 455 - /* free if only remaining port is host port */ 456 - if (mask) 455 + if (mask == 0x0 || mask == ALE_PORT_HOST) 456 + cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); 457 + else 457 458 cpsw_ale_set_port_mask(ale_entry, mask, 458 459 ale->port_mask_bits); 459 - else 460 - cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); 461 460 } 462 461 463 462 int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid)