net: ethernet: ti: ale: fix allmulti for nu type ale

On AM65xx MCU CPSW2G NUSS and 66AK2E/L NUSS allmulti setting does not allow
unregistered mcast packets to pass.

This happens, because ALE VLAN entries on these SoCs do not contain port
masks for reg/unreg mcast packets, but instead store indexes of
ALE_VLAN_MASK_MUXx_REG registers which intended for store port masks for
reg/unreg mcast packets.
This path was missed by commit 9d1f644727 ("net: ethernet: ti: ale: fix
seeing unreg mcast packets with promisc and allmulti disabled").

Hence, fix it by taking into account ALE type in cpsw_ale_set_allmulti().

Fixes: 9d1f644727 ("net: ethernet: ti: ale: fix seeing unreg mcast packets with promisc and allmulti disabled")
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Grygorii Strashko 2020-06-13 17:54:14 +03:00 committed by David S. Miller
parent 2074f9eaa5
commit bc139119a1
1 changed files with 40 additions and 9 deletions

View File

@ -604,10 +604,44 @@ void cpsw_ale_set_unreg_mcast(struct cpsw_ale *ale, int unreg_mcast_mask,
} }
} }
static void cpsw_ale_vlan_set_unreg_mcast(struct cpsw_ale *ale, u32 *ale_entry,
int allmulti)
{
int unreg_mcast;
unreg_mcast =
cpsw_ale_get_vlan_unreg_mcast(ale_entry,
ale->vlan_field_bits);
if (allmulti)
unreg_mcast |= ALE_PORT_HOST;
else
unreg_mcast &= ~ALE_PORT_HOST;
cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast,
ale->vlan_field_bits);
}
static void
cpsw_ale_vlan_set_unreg_mcast_idx(struct cpsw_ale *ale, u32 *ale_entry,
int allmulti)
{
int unreg_mcast;
int idx;
idx = cpsw_ale_get_vlan_unreg_mcast_idx(ale_entry);
unreg_mcast = readl(ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
if (allmulti)
unreg_mcast |= ALE_PORT_HOST;
else
unreg_mcast &= ~ALE_PORT_HOST;
writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
}
void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti, int port) void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti, int port)
{ {
u32 ale_entry[ALE_ENTRY_WORDS]; u32 ale_entry[ALE_ENTRY_WORDS];
int unreg_mcast = 0;
int type, idx; int type, idx;
for (idx = 0; idx < ale->params.ale_entries; idx++) { for (idx = 0; idx < ale->params.ale_entries; idx++) {
@ -624,15 +658,12 @@ void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti, int port)
if (port != -1 && !(vlan_members & BIT(port))) if (port != -1 && !(vlan_members & BIT(port)))
continue; continue;
unreg_mcast = if (!ale->params.nu_switch_ale)
cpsw_ale_get_vlan_unreg_mcast(ale_entry, cpsw_ale_vlan_set_unreg_mcast(ale, ale_entry, allmulti);
ale->vlan_field_bits);
if (allmulti)
unreg_mcast |= ALE_PORT_HOST;
else else
unreg_mcast &= ~ALE_PORT_HOST; cpsw_ale_vlan_set_unreg_mcast_idx(ale, ale_entry,
cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast, allmulti);
ale->vlan_field_bits);
cpsw_ale_write(ale, idx, ale_entry); cpsw_ale_write(ale, idx, ale_entry);
} }
} }