diff options
author | Grygorii Strashko <grygorii.strashko@ti.com> | 2019-04-26 20:12:33 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-04-27 17:11:49 -0400 |
commit | 06095f34f8a0a2c4c83a19514c272699edd5f80b (patch) | |
tree | a219665d9938d1d78a876e947cf491c70fa44de4 /drivers/net/ethernet/ti/cpsw_ale.c | |
parent | net: ethernet: ti: ale: use define for host port in cpsw_ale_set_allmulti() (diff) | |
download | wireguard-linux-06095f34f8a0a2c4c83a19514c272699edd5f80b.tar.xz wireguard-linux-06095f34f8a0a2c4c83a19514c272699edd5f80b.zip |
net: ethernet: ti: cpsw: fix allmulti cfg in dual_mac mode
Now CPSW ALE will set/clean Host port bit in Unregistered Multicast Flood
Mask (UNREG_MCAST_FLOOD_MASK) for every VLAN without checking if this port
belongs to VLAN or not when ALLMULTI mode flag is set for nedev. This is
working in non dual_mac mode, but in dual_mac - it causes
enabling/disabling ALLMULTI flag for both ports.
Hence fix it by adding additional parameter to cpsw_ale_set_allmulti() to
specify ALE port number for which ALLMULTI has to be enabled and check if
port belongs to VLAN before modifying UNREG_MCAST_FLOOD_MASK.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/ti/cpsw_ale.c')
-rw-r--r-- | drivers/net/ethernet/ti/cpsw_ale.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index 67dc769441ce..f77b5884c8db 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c @@ -468,24 +468,25 @@ int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask) return 0; } -void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti) +void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti, int port) { u32 ale_entry[ALE_ENTRY_WORDS]; - int type, idx; int unreg_mcast = 0; - - /* Only bother doing the work if the setting is actually changing */ - if (ale->allmulti == allmulti) - return; - - /* Remember the new setting to check against next time */ - ale->allmulti = allmulti; + int type, idx; for (idx = 0; idx < ale->params.ale_entries; idx++) { + int vlan_members; + cpsw_ale_read(ale, idx, ale_entry); type = cpsw_ale_get_entry_type(ale_entry); if (type != ALE_TYPE_VLAN) continue; + vlan_members = + cpsw_ale_get_vlan_member_list(ale_entry, + ale->vlan_field_bits); + + if (port != -1 && !(vlan_members & BIT(port))) + continue; unreg_mcast = cpsw_ale_get_vlan_unreg_mcast(ale_entry, |