* [PATCH net v2 0/2] Fix switch mode for offload and non-offload cases
@ 2026-10-27 13:17 Meghana Malladi
2026-10-27 13:17 ` [PATCH net v2 1/2] net: ti: icssg-prueth: Fix bridge port_vlan and flooding state Meghana Malladi
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Meghana Malladi @ 2026-10-27 13:17 UTC (permalink / raw)
To: haokexin, jacob.e.keller, m-malladi, pabeni, kuba, edumazet,
davem, andrew+netdev
Cc: linux-kernel, netdev, linux-arm-kernel, srk, Vignesh Raghavendra,
danishanwar
Non-offloaded switch mode is failing to forward packets. This patch series
introduces fixes to ensure smooth operation of switch mode in both offload
and non-offload cases.
patch(1/2): Fixes port_vlan for both the ports in bridge mode and adds
non-volatile uc/mc flooding flags
patch(2/2): Fixes R30 command timing and a NULL emac dereference
v1: https://lore.kernel.org/all/20260930124356.3083743-1-m-malladi@ti.com/
logs: https://gist.github.com/MeghanaMalladiTI/7841307d5222ae11192d86e7a0c42535
Changes(v2-v1):
- Split the patch into two separate fixes patch with appropriate commit
messages as suggested by Andrew Lunn <andrew@lunn.ch>
Meghana Malladi (2):
net: ti: icssg-prueth: Fix bridge port_vlan and flooding state
net: ti: icssg-prueth: Fix R30 command timing and NULL emac
dereference
drivers/net/ethernet/ti/icssg/icssg_prueth.c | 47 +++++++++++++++-----
drivers/net/ethernet/ti/icssg/icssg_prueth.h | 4 ++
2 files changed, 40 insertions(+), 11 deletions(-)
base-commit: 4dca97647a3e70eb6446966db8aff4e099775833
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH net v2 1/2] net: ti: icssg-prueth: Fix bridge port_vlan and flooding state 2026-10-27 13:17 [PATCH net v2 0/2] Fix switch mode for offload and non-offload cases Meghana Malladi @ 2026-10-27 13:17 ` Meghana Malladi 2026-10-31 13:38 ` netdev-bot+sashiko 2026-10-27 13:17 ` [PATCH net v2 2/2] net: ti: icssg-prueth: Fix R30 command timing and NULL emac dereference Meghana Malladi 2026-10-27 13:22 ` [PATCH net v2 0/2] Fix switch mode for offload and non-offload cases netdev-bot+sinfo 2 siblings, 1 reply; 6+ messages in thread From: Meghana Malladi @ 2026-10-27 13:17 UTC (permalink / raw) To: haokexin, jacob.e.keller, m-malladi, pabeni, kuba, edumazet, davem, andrew+netdev Cc: linux-kernel, netdev, linux-arm-kernel, srk, Vignesh Raghavendra, danishanwar 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@ti.com> --- 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 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH net v2 1/2] net: ti: icssg-prueth: Fix bridge port_vlan and flooding state 2026-10-27 13:17 ` [PATCH net v2 1/2] net: ti: icssg-prueth: Fix bridge port_vlan and flooding state Meghana Malladi @ 2026-10-31 13:38 ` netdev-bot+sashiko 0 siblings, 0 replies; 6+ messages in thread From: netdev-bot+sashiko @ 2026-10-31 13:38 UTC (permalink / raw) To: m-malladi Cc: haokexin, jacob.e.keller, pabeni, kuba, edumazet, davem, andrew+netdev, linux-kernel, netdev, linux-arm-kernel, srk, vigneshr, danishanwar Thank you for your contribution! Sashiko AI review found 7 potential issue(s) to consider. Critical: 0 · High: 2 · Medium: 1 · Low: 4 If you believe none of the issues are legitimate, please reply to each issue of Medium severity or higher and explain why the AI is wrong. If any of them are legitimate and you plan to respin, please let patchwork know by including "pw-bot: cr" as a separate line at the end of your reply (one such reply per series is enough). - [High] The flooding restore misses the restart path the commit message is about. - [High] At this commit, icssg_enable_fw_offload() has no NULL check on `emac = prueth->emac[mac]` (line 215). - [Medium] The new flooding flags are written without any synchronization against the restore. - [Low] Concern: the `!prueth->is_switch_mode` guard in icssg_enable_fw_offload() also covers HSR/PRP offload mode, so the… - [Low] The commit fixes two user-visible bugs but has no Fixes: tag, and it bundles two unrelated fixes in one patch. - [Low] The patch treats switch-mode flooding inconsistently. - [Low] Concern: mc_flooding_enabled is updated only by emac_ndo_set_rx_mode_work(), while… -- net: ti: icssg-prueth: Fix bridge port_vlan and flooding state This patch sets port_vlan on both emacs when the driver enters switch mode. It also records the UC/MC flooding state that IFF_PROMISC and IFF_ALLMULTI set up in emac_ndo_set_rx_mode_work(). The recorded state is reapplied from icssg_enable_fw_offload() after a firmware restart when the driver is not in switch mode. > diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c > index 591be5c8056b4..746afd5d00c9e 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. > + */ [Severity: Low] This isn't a bug, but does this comment match the rest of the driver? It says flooding is not needed in switch mode. However, emac_ndo_set_rx_mode_work() has no mode check, so in switch mode it still enables UC/MC flooding and sets the tracked flags. prueth_switchdev_attr_br_flags_set() also programs ICSSG_EMAC_PORT_MC_FLOODING_ENABLE/DISABLE from BR_MCAST_FLOOD, and that flag only applies while the port is bridged. As a result, right after icssg_change_mode() enters switch mode, the firmware has flooding off while uc/mc_flooding_enabled still say on. A later promiscuity change then turns flooding back on. Should the comment or the switch-mode handling be changed so the two agree? > + if (!prueth->is_switch_mode && netif_running(emac->ndev)) { [Severity: High] Can this dereference a NULL emac in the single-port configuration? At this commit, icssg_enable_fw_offload() does not check for NULL after: emac = prueth->emac[mac]; Before this patch, nothing in the loop body touched emac in plain EMAC mode. The new block evaluates netif_running(emac->ndev) whenever is_switch_mode is false. prueth_probe() only sets up netdevs for DT nodes that exist (the "single EMAC mode" case), so one prueth->emac[] slot stays NULL. The first open of the remaining port would then go: emac_ndo_open() icssg_enable_fw_offload() netif_running(emac->ndev) <- emac == NULL The next patch in the series ("net: ti: icssg-prueth: Fix R30 command timing and NULL emac dereference") adds "if (!emac) continue;". Even so, this commit on its own breaks bisection on single-port boards. Could the NULL check be moved into this patch? > + 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); > + } [Severity: High] Does this restore reach the restart path that the commit message describes? icssg_enable_fw_offload() has two callers: emac_ndo_open() on first open, and icssg_change_mode(). On the bridge-link restart, icssg_change_mode() runs after is_switch_mode has already been set to true, so this block is skipped. The restart that leaves a running, promiscuous port in non-offload bridge mode is the switch to EMAC transition in prueth_netdevice_port_unlink(). It calls prueth_emac_restart() directly: if (prueth->is_switch_mode) { prueth->is_switch_mode = false; emac->port_vlan = 0; ret = prueth_emac_restart(prueth); ... } prueth_emac_restart() only reissues the forward state: ret = icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD); ret |= icssg_set_port_state(emac1, ICSSG_EMAC_PORT_FORWARD); prueth_hsr_port_unlink() also calls prueth_emac_restart() directly. For example, put eth1 and eth2 in br0 and then run "ip link set eth2 nomaster": 1. del_nbp()->br_manage_promisc() runs. br_port_set_promisc() returns early for eth1 because eth1 is already promiscuous. 2. prueth_netdevice_port_unlink() reloads the EMAC firmware and returns. eth1 is still a bridge port with IFF_PROMISC set, and its uc/mc_flooding_enabled flags are still true. The firmware, however, now has flooding disabled, and nothing calls ndo_set_rx_mode again. Wouldn't unicast forwarding through eth1 stay broken? Could the restore be done in prueth_emac_restart(), or from every restart path? The "preserved across firmware restarts" comment on the new fields in struct prueth_emac is also not true for these unlink paths. > } > } > > @@ -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; > } [Severity: Medium] Can these flag updates race with the restore in icssg_enable_fw_offload()? emac_ndo_set_rx_mode_work() runs from schedule_work() without RTNL. It sends the firmware commands first and stores the flags afterwards. Each command holds emac->cmd_lock only for itself and can wait up to 10ms. icssg_change_mode()->prueth_emac_restart()->icssg_enable_fw_offload() reads the flags under RTNL. Nothing on that path cancels or flushes rx_mode_work. hsr_portdev_setup() opens this window when forwarding is not offloaded. It calls dev_set_promiscuity(dev, 1), which queues rx_mode_work. It then calls netdev_master_upper_dev_link(), which runs NETDEV_CHANGEUPPER-> prueth_hsr_port_link()->icssg_change_mode(). One possible interleaving: rx_mode_work icssg_change_mode() icssg_set_port_state(UC_FLOODING_ENABLE) (times out while PRUs restart) icssg_enable_fw_offload() uc_flooding_enabled false, skip emac->uc_flooding_enabled = true; The flags then say flooding is on while the firmware has it off. That is the state this patch is meant to fix. The reverse case, where promisc is being cleared, can leave flooding enabled with IFF_PROMISC clear. netif_device_detach() in prueth_emac_restart() does not clear __LINK_STATE_START, so the queued work still passes its netif_running() check. > > if (allmulti) { > icssg_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_ENABLE); > + emac->mc_flooding_enabled = true; > + emac->uc_flooding_enabled = false; > return; > } [ ... ] > @@ -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); > } > } [Severity: Low] This patch fixes two separate user-visible bugs, but it has no Fixes: tags. Could it be split into two patches, each with its own Fixes: tag? The single-emac port_vlan assignment appears to come from commit abd5576b9c57 ("net: ti: icssg-prueth: Add support for ICSSG switch firmware"). The flooding loss on restart comes from the restart-based mode change in icssg_change_mode()/prueth_emac_restart(). That was added by commit 95540ad6747c ("net: ti: icssg-prueth: Add support for HSR frame forward offload"). -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261027131732.3411403-1-m-malladi%40ti.com ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH net v2 2/2] net: ti: icssg-prueth: Fix R30 command timing and NULL emac dereference 2026-10-27 13:17 [PATCH net v2 0/2] Fix switch mode for offload and non-offload cases Meghana Malladi 2026-10-27 13:17 ` [PATCH net v2 1/2] net: ti: icssg-prueth: Fix bridge port_vlan and flooding state Meghana Malladi @ 2026-10-27 13:17 ` Meghana Malladi 2026-10-31 13:38 ` netdev-bot+sashiko 2026-10-27 13:22 ` [PATCH net v2 0/2] Fix switch mode for offload and non-offload cases netdev-bot+sinfo 2 siblings, 1 reply; 6+ messages in thread From: Meghana Malladi @ 2026-10-27 13:17 UTC (permalink / raw) To: haokexin, jacob.e.keller, m-malladi, pabeni, kuba, edumazet, davem, andrew+netdev Cc: linux-kernel, netdev, linux-arm-kernel, srk, Vignesh Raghavendra, danishanwar emac_adjust_link() called before prueth_emac_start() caused R30 FORWARD commands to time out (PRU not running), leaving stale R30 values that made prueth_emac_restart() fail; fixed by deferring adjust_link until after PRU starts. icssg_enable_fw_offload() dereferences a NULL second emac slot when the first port opens before the second is initialized; fixed by checking emac existence before accessing. Signed-off-by: Meghana Malladi <m-malladi@ti.com> --- drivers/net/ethernet/ti/icssg/icssg_prueth.c | 27 ++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c index 746afd5d00c9..9afda5da3ca3 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c @@ -213,6 +213,8 @@ static void icssg_enable_fw_offload(struct prueth *prueth) for (mac = PRUETH_MAC0; mac < PRUETH_NUM_MACS; mac++) { emac = prueth->emac[mac]; + if (!emac) + continue; if (prueth->is_hsr_offload_mode) { if (emac->ndev->features & NETIF_F_HW_HSR_TAG_RM) icssg_set_port_state(emac, ICSSG_EMAC_HSR_RX_OFFLOAD_ENABLE); @@ -288,13 +290,22 @@ static int prueth_emac_common_start(struct prueth *prueth) ret = icssg_config(prueth, emac, slice); if (ret) goto disable_class; + } + + ret = prueth_emac_start(prueth); + if (ret) + goto disable_class; + + /* Reset link state and reconfigure after firmware is running. + * Must be done after prueth_emac_start() so that R30 commands + * (e.g. ICSSG_EMAC_PORT_FORWARD from emac_adjust_link) reach + * the PRU firmware instead of timing out with stale R30 values. + */ + for (slice = 0; slice < PRUETH_NUM_MACS; slice++) { + emac = prueth->emac[slice]; + if (!emac) + continue; - /* Reset link state to force reconfiguration in - * emac_adjust_link(). Without this, if the link was already up - * before restart, emac_adjust_link() won't detect any state - * change and will skip critical configuration like writing - * speed to firmware. - */ emac->link = 0; mutex_lock(&emac->ndev->phydev->lock); @@ -302,10 +313,6 @@ static int prueth_emac_common_start(struct prueth *prueth) mutex_unlock(&emac->ndev->phydev->lock); } - ret = prueth_emac_start(prueth); - if (ret) - goto disable_class; - emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] : prueth->emac[ICSS_SLICE1]; ret = icss_iep_init(emac->iep, &prueth_iep_clockops, -- 2.43.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH net v2 2/2] net: ti: icssg-prueth: Fix R30 command timing and NULL emac dereference 2026-10-27 13:17 ` [PATCH net v2 2/2] net: ti: icssg-prueth: Fix R30 command timing and NULL emac dereference Meghana Malladi @ 2026-10-31 13:38 ` netdev-bot+sashiko 0 siblings, 0 replies; 6+ messages in thread From: netdev-bot+sashiko @ 2026-10-31 13:38 UTC (permalink / raw) To: m-malladi Cc: haokexin, jacob.e.keller, pabeni, kuba, edumazet, davem, andrew+netdev, linux-kernel, netdev, linux-arm-kernel, srk, vigneshr, danishanwar Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider. Critical: 0 · High: 1 (1) · Medium: 3 · Low: 0 If you believe none of the issues are legitimate, please reply to each issue of Medium severity or higher and explain why the AI is wrong. If any of them are legitimate and you plan to respin, please let patchwork know by including "pw-bot: cr" as a separate line at the end of your reply (one such reply per series is enough). - [High] The commit message describes the crash as happening when "the first port opens before the second is initialized". - [Medium] The NULL-emac guard this patch adds to icssg_enable_fw_offload() fixes a crash introduced by the previous… - [Medium] The patch fixes a user-visible regression but has no Fixes: tag. - [Medium] prueth_emac_restart() (line 1858) stops and restarts the PRU firmware while phylib is still running for the active ports. Pre-existing issues: - [High] This problem wasn't introduced by this patch, but prueth_cleanup_tx_ts() (icssg_common.c:1424-1434) frees every non-NULL… -- net: ti: icssg-prueth: Fix R30 command timing and NULL emac dereference This patch moves the per-port emac_adjust_link() reconfiguration in prueth_emac_common_start() so it runs after prueth_emac_start() has booted the PRU firmware. The goal is to stop R30 commands from timing out. It also adds a NULL check for the prueth->emac[] slots in icssg_enable_fw_offload(). > diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c > index 746afd5d00c9e..9afda5da3ca3a 100644 > --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c > +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c > @@ -213,6 +213,8 @@ static void icssg_enable_fw_offload(struct prueth *prueth) > > for (mac = PRUETH_MAC0; mac < PRUETH_NUM_MACS; mac++) { > emac = prueth->emac[mac]; > + if (!emac) > + continue; [Severity: Medium] The commit message says icssg_enable_fw_offload() "dereferences a NULL second emac slot when the first port opens before the second is initialized". Is that what actually triggers it? prueth_probe() calls prueth_netdev_init() for both ports, which fills both prueth->emac[] slots, before the first register_netdev(). So at ndo_open time a slot is only NULL when the port is missing from DT or disabled there. In the baseline, every emac dereference in icssg_enable_fw_offload() was under is_hsr_offload_mode or is_switch_mode, and both of those modes need two ports. The dereference that plain EMAC mode can reach seems to come from the previous patch in this series, commit 12b7fbafdb45 ("net: ti: icssg-prueth: Fix bridge port_vlan and flooding state"): if (!prueth->is_switch_mode && netif_running(emac->ndev)) { Take a single-port board with that commit applied but not this one. The first emac_ndo_open()->icssg_enable_fw_offload() would then dereference a NULL emac, so a bisect would land on the intermediate commit. Could this guard be folded into that patch, with the R30 ordering change kept as its own patch? > if (prueth->is_hsr_offload_mode) { > if (emac->ndev->features & NETIF_F_HW_HSR_TAG_RM) > icssg_set_port_state(emac, ICSSG_EMAC_HSR_RX_OFFLOAD_ENABLE); > @@ -288,13 +290,22 @@ static int prueth_emac_common_start(struct prueth *prueth) > ret = icssg_config(prueth, emac, slice); > if (ret) > goto disable_class; > + } > + > + ret = prueth_emac_start(prueth); > + if (ret) > + goto disable_class; > + [Severity: Medium] This fixes a user-visible regression: R30 FORWARD commands time out, and prueth_emac_restart() then fails when ports with link up join or leave a bridge or HSR. The commit has no Fixes: tag, though. The emac_adjust_link() call ahead of prueth_emac_start() came from 06feac15406f ("net: ti: icssg-prueth: Fix emac link speed handling"). The emac->link = 0 reset, which makes adjust_link send FORWARD on every restart while the link is up, came from 147792c395db ("net: ti: icssg-prueth: Fix ping failure after offload mode setup when link speed is not 1G"). Should this carry Fixes: tags for one or both of those, so that stable trees containing them also pick up this fix? > + /* Reset link state and reconfigure after firmware is running. > + * Must be done after prueth_emac_start() so that R30 commands > + * (e.g. ICSSG_EMAC_PORT_FORWARD from emac_adjust_link) reach > + * the PRU firmware instead of timing out with stale R30 values. > + */ [Severity: Medium] Does this close the R30 timeout window completely? prueth_emac_restart() stops and restarts the firmware without calling phy_stop() and without holding phydev->lock. That means phylib can still call emac_adjust_link() on its own while the PRU is halted: prueth_emac_restart() prueth_emac_common_stop() <- PRU halted prueth_emac_common_start() icssg_config() emac_r30_cmd_init() prueth_emac_start() Suppose the link changes (autoneg completes, or the link flaps) after prueth_emac_common_stop(), or between emac_r30_cmd_init() and prueth_emac_start(). The phylib state machine then calls emac_adjust_link()->icssg_set_port_state(). That writes the R30 command words to a halted PRU, times out in read_poll_timeout(), and leaves the words in place. This looks like the same failure the commit message describes. There is also a data race on the link fields. icssg_config() writes emac->speed and emac->duplex, and this loop writes emac->link = 0, all without phydev->lock. The phylib callback updates the same fields while holding phydev->lock. Should the restart path quiesce phylib, or hold phydev->lock, across the stop/start window? > + for (slice = 0; slice < PRUETH_NUM_MACS; slice++) { > + emac = prueth->emac[slice]; > + if (!emac) > + continue; > > - /* Reset link state to force reconfiguration in > - * emac_adjust_link(). Without this, if the link was already up > - * before restart, emac_adjust_link() won't detect any state > - * change and will skip critical configuration like writing > - * speed to firmware. > - */ > emac->link = 0; > > mutex_lock(&emac->ndev->phydev->lock); [Severity: High] The loop only checks emac. Can emac->ndev->phydev still be NULL at this point? prueth_probe() fills both prueth->emac[] slots and then does: prueth_probe() register_netdev(prueth->emac[PRUETH_MAC0]->ndev); emac_phy_connect(prueth->emac[PRUETH_MAC0]); register_netdev(prueth->emac[PRUETH_MAC1]->ndev); emac_phy_connect(prueth->emac[PRUETH_MAC1]); Userspace can open eth0 as soon as it is registered, for example via udev or a network manager. emac_ndo_open() sees emacs_initialized == 0 and calls prueth_emac_common_start(). This loop then reaches slice 1, where emac[1] is non-NULL but its ndev->phydev has not been set yet. So mutex_lock(&emac->ndev->phydev->lock) dereferences NULL. prueth_remove() has a similar window: phy_disconnect(prueth->emac[i]->ndev->phydev); prueth->emac[i]->ndev->phydev = NULL; unregister_netdev(prueth->registered_netdevs[i]); emac[0] stays non-NULL here. If eth1 is opened during this window, the loop walks slice 0 with a NULL phydev. emac_ndo_stop() already checks if (ndev->phydev) before phy_stop(). The dereference itself existed before this patch. However, the commit message describes this exact scenario, "the first port opens before the second is initialized", and that scenario still crashes. Should this loop also skip slices that have no phydev? [Severity: High] This is a pre-existing issue, not one introduced by this patch. On link down, the emac_adjust_link() call made from this loop (and from the phylib state machine) reaches prueth_cleanup_tx_ts(): } else { netif_tx_stop_all_queues(ndev); prueth_cleanup_tx_ts(emac); } prueth_cleanup_tx_ts() frees every non-NULL emac->tx_ts_skb[] slot. No lock synchronizes it with the TX path or the tx_ts IRQ thread. Also, netif_tx_stop_all_queues() does not wait for an icssg_ndo_start_xmit() that is already running on another CPU. Can this end up freeing an ERR_PTR? The xmit path reserves a slot in prueth_tx_ts_cookie_get() first: emac->tx_ts_skb[i] = ERR_PTR(-EBUSY); /* reserve slot */ and stores the skb in icssg_ndo_start_xmit() only later: emac->tx_ts_skb[tx_ts_cookie] = skb_get(skb); If cleanup runs between those two stores, it calls dev_kfree_skb_any(ERR_PTR(-EBUSY)). The xmit error paths also free the slot and set it to NULL. And tx_ts_work() does: skb = emac->tx_ts_skb[tsr.cookie]; emac->tx_ts_skb[tsr.cookie] = NULL; /* free slot */ and uses and frees skb later on. Could a concurrent prueth_cleanup_tx_ts() free the same skb in between, causing a double free or a use-after-free? [ ... ] -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261027131732.3411403-1-m-malladi%40ti.com ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net v2 0/2] Fix switch mode for offload and non-offload cases 2026-10-27 13:17 [PATCH net v2 0/2] Fix switch mode for offload and non-offload cases Meghana Malladi 2026-10-27 13:17 ` [PATCH net v2 1/2] net: ti: icssg-prueth: Fix bridge port_vlan and flooding state Meghana Malladi 2026-10-27 13:17 ` [PATCH net v2 2/2] net: ti: icssg-prueth: Fix R30 command timing and NULL emac dereference Meghana Malladi @ 2026-10-27 13:22 ` netdev-bot+sinfo 2 siblings, 0 replies; 6+ messages in thread From: netdev-bot+sinfo @ 2026-10-27 13:22 UTC (permalink / raw) To: Meghana Malladi Cc: haokexin, jacob.e.keller, pabeni, kuba, edumazet, davem, andrew+netdev, linux-kernel, netdev, linux-arm-kernel, srk, Vignesh Raghavendra, danishanwar Hi! This is an automated message. This series looks like a fix, but its commit messages seem to be missing some information: - How the issue was discovered, e.g. hit in production, hit during development, syzbot report, manual code inspection, LLM or static analysis tool scan. - What hardware the change was tested on. For driver fixes please mention the device (and if relevant firmware version) used for testing, or say that the change was not tested on real hardware. Please do not repost the series just to address the above. Instead, reply to this email with the missing information, so that reviewers can take it into account. If the series needs another revision for other reasons, please include the information in the commit messages then. The evaluation is done by an LLM so it may be wrong, if you think that is the case please reply and explain. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-10-31 13:38 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-27 13:17 [PATCH net v2 0/2] Fix switch mode for offload and non-offload cases Meghana Malladi 2026-10-27 13:17 ` [PATCH net v2 1/2] net: ti: icssg-prueth: Fix bridge port_vlan and flooding state Meghana Malladi 2026-10-31 13:38 ` netdev-bot+sashiko 2026-10-27 13:17 ` [PATCH net v2 2/2] net: ti: icssg-prueth: Fix R30 command timing and NULL emac dereference Meghana Malladi 2026-10-31 13:38 ` netdev-bot+sashiko 2026-10-27 13:22 ` [PATCH net v2 0/2] Fix switch mode for offload and non-offload cases netdev-bot+sinfo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox