Bridge formation only set port_vlan on the second emac, leaving the first without VLAN configuration; fixed by setting port_vlan on both emacs. Firmware restart in non-offload bridge mode cleared IFF_PROMISC-driven UC/MC flooding state, breaking unicast forwarding; fixed by tracking flooding state and restoring it after restart. Signed-off-by: Meghana Malladi --- drivers/net/ethernet/ti/icssg/icssg_prueth.c | 20 +++++++++++++++++++- drivers/net/ethernet/ti/icssg/icssg_prueth.h | 4 ++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c index 591be5c8056b..746afd5d00c9 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c @@ -241,6 +241,16 @@ static void icssg_enable_fw_offload(struct prueth *prueth) icssg_set_port_state(emac, ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE); } } + + /* Re-apply flooding state cleared by firmware restart. + * Not needed in switch mode; FDB handles forwarding there. + */ + if (!prueth->is_switch_mode && netif_running(emac->ndev)) { + if (emac->uc_flooding_enabled) + icssg_set_port_state(emac, ICSSG_EMAC_PORT_UC_FLOODING_ENABLE); + if (emac->mc_flooding_enabled) + icssg_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_ENABLE); + } } } @@ -1288,14 +1298,21 @@ static void emac_ndo_set_rx_mode_work(struct work_struct *work) if (promisc) { icssg_set_port_state(emac, ICSSG_EMAC_PORT_UC_FLOODING_ENABLE); icssg_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_ENABLE); + emac->uc_flooding_enabled = true; + emac->mc_flooding_enabled = true; return; } if (allmulti) { icssg_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_ENABLE); + emac->mc_flooding_enabled = true; + emac->uc_flooding_enabled = false; return; } + emac->uc_flooding_enabled = false; + emac->mc_flooding_enabled = false; + if (emac->prueth->is_hsr_offload_mode) { /* Track basic add/delete via callbacks */ __dev_mc_sync(ndev, icssg_prueth_hsr_add_mcast, @@ -1919,7 +1936,8 @@ static int prueth_netdevice_port_link(struct net_device *ndev, prueth->br_members & BIT(PRUETH_PORT_MII1)) { prueth->is_switch_mode = true; prueth->default_vlan = PRUETH_DFLT_VLAN_SW; - emac->port_vlan = prueth->default_vlan; + prueth->emac[PRUETH_MAC0]->port_vlan = prueth->default_vlan; + prueth->emac[PRUETH_MAC1]->port_vlan = prueth->default_vlan; icssg_change_mode(prueth); } } diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h index df93d15c5b78..832e654a102c 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h @@ -242,6 +242,10 @@ struct prueth_emac { bool offload_fwd_mark; int port_vlan; + /* UC/MC flooding state - preserved across firmware restarts */ + unsigned int uc_flooding_enabled : 1; + unsigned int mc_flooding_enabled : 1; + struct delayed_work stats_work; u64 stats[ICSSG_NUM_MIIG_STATS]; u64 pa_stats[ICSSG_NUM_PA_STATS]; -- 2.43.0