With every port fully isolated during chip setup, the CPU port already gets its one-way isolation (drop all packets without tag) there, so the dedicated handling in port_setup() is redundant. Skip the isolation write for CPU ports in yt921x_userport_standalone(), which port_setup() also runs for CPU ports, to keep it intact. Consequently the CPU ports no longer need to be excluded from the unknown unicast filtering: frames entering a CPU port without a tag are now dropped by the port isolation instead of the ACT_UNK action. Signed-off-by: David Yang --- drivers/net/dsa/motorcomm/chip.c | 46 ++++++-------------------------- 1 file changed, 8 insertions(+), 38 deletions(-) diff --git a/drivers/net/dsa/motorcomm/chip.c b/drivers/net/dsa/motorcomm/chip.c index e1fa82c6db95..fb993cc9607c 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; } @@ -2276,10 +2256,8 @@ static int yt921x_chip_reset(struct yt921x_priv *priv) static int yt921x_chip_setup_dsa(struct yt921x_priv *priv) { struct dsa_switch *ds = &priv->ds; - unsigned long cpu_ports_mask; u32 ctrls[2]; u32 ctrl; - int port; int res; /* Enable DSA */ @@ -2297,7 +2275,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; @@ -2320,14 +2298,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