[PATCH net 2/2] net: ti: icssg-prueth: re-apply rx_mode state after firmware reboot
Rishi Kumar
r-kumar12 at ti.com
Wed Oct 14 05:59:48 PDT 2026
prueth_emac_common_start() reboots the PRU/RTU/txPRU cores whenever
the first port opens, or on a full mode change via
icssg_change_mode(). Any icssg_set_port_state() command sent while a
core is stopped or still booting times out waiting for firmware to
ack it ("timeout waiting for command done"), and the write is lost
with no retry.
emac_ndo_set_rx_mode_work() sends exactly this kind of command to
enable/disable UC/MC flooding based on IFF_PROMISC/IFF_ALLMULTI. If
a port's rx_mode_work runs while firmware is being rebooted, the
flood-enable command can be dropped, leaving that port without
multicast flooding.
Re-queue rx_mode_work for every running port at the end of the
firmware start sequence in prueth_emac_common_start(), so the current
IFF_PROMISC/IFF_ALLMULTI state is re-applied after a reboot. Also
cancel the pending work in the stop_pruss error path so it cannot run
after the cores are stopped again.
prefix logs: https://gist.github.com/r-kumar12/91ee6fecd40ea3f22dcc65aba42705e1
postfix logs: https://gist.github.com/r-kumar12/4d5ade22d783020552b8a1e0c6d7102f
Fixes: 9facce84f406 ("net: ti: icssg-prueth: Fix firmware load sequence.")
Signed-off-by: Rishi Kumar <r-kumar12 at ti.com>
---
drivers/net/ethernet/ti/icssg/icssg_prueth.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index 745178fe7cf3..96ad6227f405 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -311,6 +311,18 @@ static int prueth_emac_common_start(struct prueth *prueth)
if (ret)
goto disable_class;
+ /* PRU/RTU/txPRU are up now: re-sync any port
+ * config (e.g. flood/promisc flags) that may have been
+ * dropped while firmware was still rebooting above.
+ */
+ for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
+ emac = prueth->emac[slice];
+ if (!emac)
+ continue;
+ if (netif_running(emac->ndev))
+ schedule_work(&emac->rx_mode_work);
+ }
+
emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
prueth->emac[ICSS_SLICE1];
ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
@@ -323,6 +335,11 @@ static int prueth_emac_common_start(struct prueth *prueth)
return 0;
stop_pruss:
+ for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
+ emac = prueth->emac[slice];
+ if (emac)
+ cancel_work_sync(&emac->rx_mode_work);
+ }
prueth_emac_stop(prueth);
disable_class:
--
2.53.0
More information about the linux-arm-kernel
mailing list