[PATCH net v2 1/2] net: ti: icssg-prueth: Fix bridge port_vlan and flooding state

From: Meghana Malladi

Date: Tue Oct 27 2026 - 09:19:43 EST


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 <m-malladi@xxxxxx>
---
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