* [PATCH net] net: dsa: motorcomm: Isolate all ports during chip setup
@ 2026-10-24 14:40 David Yang
0 siblings, 0 replies; only message in thread
From: David Yang @ 2026-10-24 14:40 UTC (permalink / raw)
To: netdev
Cc: David Yang, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, linux-kernel
The chip setup only blocked unknown unicast and unknown multicast
frames, known multicast and broadcast were left open (though the former
cannot appear while the FDB is still empty). Before port_setup() runs,
this leaks in two ways: frames pumped untagged into the conduit port
reach the fabric and loop back to the CPU, where the tag driver warns
about and drops them; and broadcast frames received on a user port flood
out of the other user ports.
Close the window by fully isolating every port right after the hardware
reset. The CPU port one-way isolation is also applied during chip setup
instead of port_setup(), and yt921x_userport_standalone(), which
port_setup() also runs for CPU ports, keeps it intact.
Fixes: 186623f4aa72 ("net: dsa: yt921x: Add support for Motorcomm YT921x")
Signed-off-by: David Yang <mmyangfl@gmail.com>
---
drivers/net/dsa/motorcomm/chip.c | 56 ++++++++++++--------------------
1 file changed, 20 insertions(+), 36 deletions(-)
diff --git a/drivers/net/dsa/motorcomm/chip.c b/drivers/net/dsa/motorcomm/chip.c
index d4fc20c52a58..f1762273dd6a 100644
--- a/drivers/net/dsa/motorcomm/chip.c
+++ b/drivers/net/dsa/motorcomm/chip.c
@@ -1164,10 +1164,13 @@ static int yt921x_userport_standalone(struct yt921x_priv *priv, int port)
u32 ctrl;
int res;
- ctrl = ~priv->cpu_ports_mask;
- res = yt921x_reg_write(priv, YT921X_PORTn_ISOLATION(port), ctrl);
- if (res)
- return res;
+ if (!(BIT(port) & priv->cpu_ports_mask)) {
+ ctrl = ~priv->cpu_ports_mask;
+ res = yt921x_reg_write(priv, YT921X_PORTn_ISOLATION(port),
+ ctrl);
+ if (res)
+ return res;
+ }
/* Turn off FDB learning to prevent FDB pollution */
mask = YT921X_PORT_LEARN_DIS;
@@ -1942,8 +1945,6 @@ yt921x_dsa_phylink_get_caps(struct dsa_switch *ds, int port,
static int yt921x_port_setup(struct yt921x_priv *priv, int port)
{
- struct dsa_switch *ds = &priv->ds;
- u32 ctrl;
int res;
res = yt921x_userport_standalone(priv, port);
@@ -1957,27 +1958,6 @@ static int yt921x_port_setup(struct yt921x_priv *priv, int port)
if (res)
return res;
- if (dsa_is_cpu_port(ds, port)) {
- /* Egress of CPU port is supposed to be completely controlled
- * via tagging, so set to oneway isolated (drop all packets
- * without tag).
- */
- ctrl = ~(u32)0;
- res = yt921x_reg_write(priv, YT921X_PORTn_ISOLATION(port),
- ctrl);
- if (res)
- return res;
-
- /* To simplify FDB "isolation" simulation, we also disable
- * learning on the CPU port, and let software identify packets
- * towarding CPU (either trapped or a static FDB entry is
- * matched, no matter which bridge that entry is for), which is
- * already done by yt921x_userport_standalone(). As a result,
- * VLAN-awareness becomes unrelated on the CPU port (set to
- * VLAN-unaware by the way).
- */
- }
-
return 0;
}
@@ -2221,6 +2201,7 @@ static int yt921x_chip_reset(struct yt921x_priv *priv)
{
struct device *dev = yt921x_priv_to_device(priv);
u16 eth_p_tag;
+ u32 ctrl;
u32 val;
int res;
@@ -2258,6 +2239,17 @@ static int yt921x_chip_reset(struct yt921x_priv *priv)
return -EINVAL;
}
+ /* Block all traffic as soon as we reset the hardware since it now acts
+ * as a dump switch.
+ */
+ for (int port = 0; port < YT921X_PORT_NUM; port++) {
+ ctrl = ~(u32)0;
+ res = yt921x_reg_write(priv, YT921X_PORTn_ISOLATION(port),
+ ctrl);
+ if (res)
+ return res;
+ }
+
return 0;
}
@@ -2285,7 +2277,7 @@ static int yt921x_chip_setup_dsa(struct yt921x_priv *priv)
if (res)
return res;
- ctrl = GENMASK(10, 0);
+ ctrl = GENMASK(10, 0) & ~priv->cpu_ports_mask;
res = yt921x_reg_write(priv, YT921X_FILTER_UNK_UCAST, ctrl);
if (res)
return res;
@@ -2308,14 +2300,6 @@ static int yt921x_chip_setup_dsa(struct yt921x_priv *priv)
ctrl = 0;
for (int i = 0; i < YT921X_PORT_NUM; i++)
ctrl |= YT921X_ACT_UNK_ACTn_TRAP(i);
- /* Except for CPU ports, if any packets are sent via CPU ports without
- * tag, they should be dropped.
- */
- cpu_ports_mask = priv->cpu_ports_mask;
- for_each_set_bit(port, &cpu_ports_mask, YT921X_PORT_NUM) {
- ctrl &= ~YT921X_ACT_UNK_ACTn_M(port);
- ctrl |= YT921X_ACT_UNK_ACTn_DROP(port);
- }
res = yt921x_reg_write(priv, YT921X_ACT_UNK_UCAST, ctrl);
if (res)
return res;
--
2.53.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-24 14:40 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-24 14:40 [PATCH net] net: dsa: motorcomm: Isolate all ports during chip setup David Yang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®