Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/5] net: dsa: realtek: rtl8366rb: Use generic RTL83xx code
@ 2026-06-30 11:19 Linus Walleij
  2026-06-30 11:19 ` [PATCH net-next v2 1/5] net: dsa: realtek: rtl83xx: Make learning optional in join/leave Linus Walleij
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Linus Walleij @ 2026-06-30 11:19 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca, Alvin Šipraga, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: netdev, Linus Walleij

As a follow-up to Luiz's and Alvin's series improvining the
generic handling of the Realtek DSA switches, this small
series brings the RTL8366RB closer to the way things are done
in the RTL8365MB driver.

This patch series switches over to using the generic helpers
for:

- Bridge joining and leaving (isolation)
- STP handling
- Learning enable/disable

It would be appreciated if this doesn't lead to AI-automated
request to fix the entire universe (hi Sashiko, I'm looking
at you but I bet you will do you compulsive C3P0-style review
anyway) since I'm just moving code around so some helper
functions come before their new users. The code itself is
pretty straight-forward.

Signed-off-by: Linus Walleij <linusw@kernel.org>
---
Changes in v2:
- Rebase on v7.2-rc1
- Prepend a patch making the learning callbacks optional so we can add
  functionality one patch at a time.
- Link to v1: https://patch.msgid.link/20260612-rtl8366rb-improvements-v1-0-9232286fc20c@kernel.org

---
Linus Walleij (5):
      net: dsa: realtek: rtl83xx: Make learning optional in join/leave
      net: dsa: realtek: rtl8366rb: Switch to generic port_bridge* handlers
      net: dsa: realtek: rtl8366rb: Use DSA port iterators
      net: dsa: realtek: rtl8366rb: Disable STP learning on all ports in setup
      net: dsa: realtek: rtl8366rb: Switch to generic learning enablement

 drivers/net/dsa/realtek/rtl8366rb.c | 268 ++++++++++++++++++------------------
 drivers/net/dsa/realtek/rtl83xx.c   |  26 ++--
 2 files changed, 143 insertions(+), 151 deletions(-)
---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20260611-rtl8366rb-improvements-d69f2145219d

Best regards,
--  
Linus Walleij <linusw@kernel.org>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 1/5] net: dsa: realtek: rtl83xx: Make learning optional in join/leave
  2026-06-30 11:19 [PATCH net-next v2 0/5] net: dsa: realtek: rtl8366rb: Use generic RTL83xx code Linus Walleij
@ 2026-06-30 11:19 ` Linus Walleij
  2026-07-03 13:13   ` Luiz Angelo Daros de Luca
  2026-06-30 11:19 ` [PATCH net-next v2 2/5] net: dsa: realtek: rtl8366rb: Switch to generic port_bridge* handlers Linus Walleij
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Linus Walleij @ 2026-06-30 11:19 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca, Alvin Šipraga, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: netdev, Linus Walleij

Mostly to make it possible to add rtl83xx support piece by piece,
make the port learning callback optional in rtl83xx_port_bridge_join()
and rtl83xx_port_bridge_leave().

Signed-off-by: Linus Walleij <linusw@kernel.org>
---
 drivers/net/dsa/realtek/rtl83xx.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/net/dsa/realtek/rtl83xx.c b/drivers/net/dsa/realtek/rtl83xx.c
index 71124ecca92f..90843d52c5a8 100644
--- a/drivers/net/dsa/realtek/rtl83xx.c
+++ b/drivers/net/dsa/realtek/rtl83xx.c
@@ -356,9 +356,6 @@ int rtl83xx_port_bridge_join(struct dsa_switch *ds, int port,
 	if (!priv->ops->port_add_isolation)
 		return -EOPNOTSUPP;
 
-	if (!priv->ops->port_set_learning)
-		return -EOPNOTSUPP;
-
 	dev_dbg(priv->dev, "bridge %d join port %d\n", bridge.num, port);
 
 	/* Add this port to the isolation group of every other port
@@ -396,9 +393,11 @@ int rtl83xx_port_bridge_join(struct dsa_switch *ds, int port,
 			goto undo_self_isolation;
 	}
 
-	ret = priv->ops->port_set_learning(priv, port, true);
-	if (ret)
-		goto undo_efid;
+	if (priv->ops->port_set_learning) {
+		ret = priv->ops->port_set_learning(priv, port, true);
+		if (ret)
+			goto undo_efid;
+	}
 
 	return 0;
 
@@ -443,9 +442,6 @@ void rtl83xx_port_bridge_leave(struct dsa_switch *ds, int port,
 	if (!priv->ops->port_remove_isolation)
 		return;
 
-	if (!priv->ops->port_set_learning)
-		return;
-
 	dev_dbg(priv->dev, "bridge %d leave port %d\n", bridge.num, port);
 
 	/* Remove this port from the isolation group of every other
@@ -474,11 +470,13 @@ void rtl83xx_port_bridge_leave(struct dsa_switch *ds, int port,
 	 * downstream DSA ports from the isolation group.
 	 */
 
-	ret = priv->ops->port_set_learning(priv, port, false);
-	if (ret)
-		dev_err(priv->dev,
-			"failed to disable learning on port %d: %pe\n",
-			port, ERR_PTR(ret));
+	if (priv->ops->port_set_learning) {
+		ret = priv->ops->port_set_learning(priv, port, false);
+		if (ret)
+			dev_err(priv->dev,
+				"failed to disable learning on port %d: %pe\n",
+				port, ERR_PTR(ret));
+	}
 
 	/* Remove those ports from the isolation group of this port */
 	ret = priv->ops->port_remove_isolation(priv, port, mask);

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 2/5] net: dsa: realtek: rtl8366rb: Switch to generic port_bridge* handlers
  2026-06-30 11:19 [PATCH net-next v2 0/5] net: dsa: realtek: rtl8366rb: Use generic RTL83xx code Linus Walleij
  2026-06-30 11:19 ` [PATCH net-next v2 1/5] net: dsa: realtek: rtl83xx: Make learning optional in join/leave Linus Walleij
@ 2026-06-30 11:19 ` Linus Walleij
  2026-07-03 13:15   ` Luiz Angelo Daros de Luca
  2026-07-03 13:24   ` Luiz Angelo Daros de Luca
  2026-06-30 11:19 ` [PATCH net-next v2 3/5] net: dsa: realtek: rtl8366rb: Use DSA port iterators Linus Walleij
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 13+ messages in thread
From: Linus Walleij @ 2026-06-30 11:19 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca, Alvin Šipraga, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: netdev, Linus Walleij

The RTL8366RB is using its own sub-standard port isolation code.

Implement the required isolation helpers, use these directly in
the port setup callback, and switch over to the standard port
isolation code.

Signed-off-by: Linus Walleij <linusw@kernel.org>
---
 drivers/net/dsa/realtek/rtl8366rb.c | 108 ++++++++++++------------------------
 1 file changed, 36 insertions(+), 72 deletions(-)

diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
index 103039fe3086..8b57ef3bf03a 100644
--- a/drivers/net/dsa/realtek/rtl8366rb.c
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
@@ -791,6 +791,35 @@ static int rtl8366rb_setup_all_leds_off(struct realtek_priv *priv)
 	return ret;
 }
 
+static int rtl8366rb_port_set_isolation(struct realtek_priv *priv, int port,
+					u32 mask)
+{
+	/* Bit 0 enables isolation so set this if we enable isolation
+	 * any of the ports an clear it if we disable on all of them.
+	 */
+	if (mask)
+		mask = RTL8366RB_PORT_ISO_PORTS(mask) | RTL8366RB_PORT_ISO_EN;
+
+	return regmap_write(priv->map, RTL8366RB_PORT_ISO(port),
+			    mask);
+}
+
+static int rtl8366rb_port_add_isolation(struct realtek_priv *priv, int port,
+					u32 mask)
+{
+	/* We assume isolation bit is on */
+	return regmap_update_bits(priv->map, RTL8366RB_PORT_ISO(port),
+				  RTL8366RB_PORT_ISO_PORTS(mask),
+				  RTL8366RB_PORT_ISO_PORTS(mask));
+}
+
+static int rtl8366rb_port_remove_isolation(struct realtek_priv *priv, int port,
+					   u32 mask)
+{
+	return regmap_update_bits(priv->map, RTL8366RB_PORT_ISO(port),
+				  RTL8366RB_PORT_ISO_PORTS(mask), 0);
+}
+
 static int rtl8366rb_setup(struct dsa_switch *ds)
 {
 	struct realtek_priv *priv = ds->priv;
@@ -868,16 +897,13 @@ static int rtl8366rb_setup(struct dsa_switch *ds)
 
 	/* Isolate all user ports so they can only send packets to itself and the CPU port */
 	for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) {
-		ret = regmap_write(priv->map, RTL8366RB_PORT_ISO(i),
-				   RTL8366RB_PORT_ISO_PORTS(BIT(RTL8366RB_PORT_NUM_CPU)) |
-				   RTL8366RB_PORT_ISO_EN);
+		ret = rtl8366rb_port_set_isolation(priv, i, BIT(RTL8366RB_PORT_NUM_CPU));
 		if (ret)
 			return ret;
 	}
 	/* CPU port can send packets to all ports */
-	ret = regmap_write(priv->map, RTL8366RB_PORT_ISO(RTL8366RB_PORT_NUM_CPU),
-			   RTL8366RB_PORT_ISO_PORTS(dsa_user_ports(ds)) |
-			   RTL8366RB_PORT_ISO_EN);
+	ret = rtl8366rb_port_set_isolation(priv, RTL8366RB_PORT_NUM_CPU,
+					   dsa_user_ports(ds));
 	if (ret)
 		return ret;
 
@@ -1184,70 +1210,6 @@ rtl8366rb_port_disable(struct dsa_switch *ds, int port)
 		return;
 }
 
-static int
-rtl8366rb_port_bridge_join(struct dsa_switch *ds, int port,
-			   struct dsa_bridge bridge,
-			   bool *tx_fwd_offload,
-			   struct netlink_ext_ack *extack)
-{
-	struct realtek_priv *priv = ds->priv;
-	unsigned int port_bitmap = 0;
-	int ret, i;
-
-	/* Loop over all other ports than the current one */
-	for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) {
-		/* Current port handled last */
-		if (i == port)
-			continue;
-		/* Not on this bridge */
-		if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge))
-			continue;
-		/* Join this port to each other port on the bridge */
-		ret = regmap_update_bits(priv->map, RTL8366RB_PORT_ISO(i),
-					 RTL8366RB_PORT_ISO_PORTS(BIT(port)),
-					 RTL8366RB_PORT_ISO_PORTS(BIT(port)));
-		if (ret)
-			dev_err(priv->dev, "failed to join port %d\n", port);
-
-		port_bitmap |= BIT(i);
-	}
-
-	/* Set the bits for the ports we can access */
-	return regmap_update_bits(priv->map, RTL8366RB_PORT_ISO(port),
-				  RTL8366RB_PORT_ISO_PORTS(port_bitmap),
-				  RTL8366RB_PORT_ISO_PORTS(port_bitmap));
-}
-
-static void
-rtl8366rb_port_bridge_leave(struct dsa_switch *ds, int port,
-			    struct dsa_bridge bridge)
-{
-	struct realtek_priv *priv = ds->priv;
-	unsigned int port_bitmap = 0;
-	int ret, i;
-
-	/* Loop over all other ports than this one */
-	for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) {
-		/* Current port handled last */
-		if (i == port)
-			continue;
-		/* Not on this bridge */
-		if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge))
-			continue;
-		/* Remove this port from any other port on the bridge */
-		ret = regmap_update_bits(priv->map, RTL8366RB_PORT_ISO(i),
-					 RTL8366RB_PORT_ISO_PORTS(BIT(port)), 0);
-		if (ret)
-			dev_err(priv->dev, "failed to leave port %d\n", port);
-
-		port_bitmap |= BIT(i);
-	}
-
-	/* Clear the bits for the ports we can not access, leave ourselves */
-	regmap_update_bits(priv->map, RTL8366RB_PORT_ISO(port),
-			   RTL8366RB_PORT_ISO_PORTS(port_bitmap), 0);
-}
-
 /**
  * rtl8366rb_drop_untagged() - make the switch drop untagged and C-tagged frames
  * @priv: SMI state container
@@ -1801,8 +1763,8 @@ static const struct dsa_switch_ops rtl8366rb_switch_ops = {
 	.get_strings = rtl8366_get_strings,
 	.get_ethtool_stats = rtl8366_get_ethtool_stats,
 	.get_sset_count = rtl8366_get_sset_count,
-	.port_bridge_join = rtl8366rb_port_bridge_join,
-	.port_bridge_leave = rtl8366rb_port_bridge_leave,
+	.port_bridge_join = rtl83xx_port_bridge_join,
+	.port_bridge_leave = rtl83xx_port_bridge_leave,
 	.port_vlan_filtering = rtl8366rb_vlan_filtering,
 	.port_vlan_add = rtl8366_vlan_add,
 	.port_vlan_del = rtl8366_vlan_del,
@@ -1830,6 +1792,8 @@ static const struct realtek_ops rtl8366rb_ops = {
 	.is_vlan_valid	= rtl8366rb_is_vlan_valid,
 	.enable_vlan	= rtl8366rb_enable_vlan,
 	.enable_vlan4k	= rtl8366rb_enable_vlan4k,
+	.port_add_isolation = rtl8366rb_port_add_isolation,
+	.port_remove_isolation = rtl8366rb_port_remove_isolation,
 	.phy_read	= rtl8366rb_phy_read,
 	.phy_write	= rtl8366rb_phy_write,
 };

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 3/5] net: dsa: realtek: rtl8366rb: Use DSA port iterators
  2026-06-30 11:19 [PATCH net-next v2 0/5] net: dsa: realtek: rtl8366rb: Use generic RTL83xx code Linus Walleij
  2026-06-30 11:19 ` [PATCH net-next v2 1/5] net: dsa: realtek: rtl83xx: Make learning optional in join/leave Linus Walleij
  2026-06-30 11:19 ` [PATCH net-next v2 2/5] net: dsa: realtek: rtl8366rb: Switch to generic port_bridge* handlers Linus Walleij
@ 2026-06-30 11:19 ` Linus Walleij
  2026-07-02  9:31   ` Paolo Abeni
  2026-06-30 11:19 ` [PATCH net-next v2 4/5] net: dsa: realtek: rtl8366rb: Disable STP learning on all ports in setup Linus Walleij
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Linus Walleij @ 2026-06-30 11:19 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca, Alvin Šipraga, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: netdev, Linus Walleij

Instead of custom loops for intializing the ports (including the
CPU port) use the DSA helpers dsa_switch_for_each_port() and
dsa_switch_for_each_cpu_port() following the pattern in RTL8365MB by
accumulatong masks for the upstream and downstream ports.

This gives us similar enough code to the RTL8365MB that we
can start using more generic rtl83xx helpers.

Reviewed-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
Signed-off-by: Linus Walleij <linusw@kernel.org>
---
 drivers/net/dsa/realtek/rtl8366rb.c | 49 +++++++++++++++++++++++++++++++------
 1 file changed, 41 insertions(+), 8 deletions(-)

diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
index 8b57ef3bf03a..64215a0d5d6d 100644
--- a/drivers/net/dsa/realtek/rtl8366rb.c
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
@@ -824,7 +824,10 @@ static int rtl8366rb_setup(struct dsa_switch *ds)
 {
 	struct realtek_priv *priv = ds->priv;
 	const struct rtl8366rb_jam_tbl_entry *jam_table;
+	u32 downports_mask = 0;
 	struct rtl8366rb *rb;
+	u32 upports_mask = 0;
+	struct dsa_port *dp;
 	u32 chip_ver = 0;
 	u32 chip_id = 0;
 	int jam_size;
@@ -895,17 +898,47 @@ static int rtl8366rb_setup(struct dsa_switch *ds)
 	if (ret)
 		return ret;
 
-	/* Isolate all user ports so they can only send packets to itself and the CPU port */
-	for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) {
-		ret = rtl8366rb_port_set_isolation(priv, i, BIT(RTL8366RB_PORT_NUM_CPU));
+	/* Start with all ports blocked, including unused ports */
+	dsa_switch_for_each_port(dp, ds) {
+		/* Start with all ports completely isolated */
+		ret = rtl8366rb_port_set_isolation(priv, dp->index, 0);
+		if (ret)
+			return ret;
+
+		/* Collect CPU ports. If we support cascade switches, it should
+		 * also include the upstream DSA ports.
+		 */
+		if (!dsa_port_is_cpu(dp))
+			continue;
+
+		upports_mask |= BIT(dp->index);
+	}
+
+	/* Configure user ports */
+	dsa_switch_for_each_port(dp, ds) {
+		if (!dsa_port_is_user(dp))
+			continue;
+
+		/* Forward only to the CPU */
+		ret = rtl8366rb_port_set_isolation(priv, dp->index, upports_mask);
+		if (ret)
+			return ret;
+
+		/* If we support cascade switches, it should also include the
+		 * downstream DSA ports.
+		 */
+		downports_mask |= BIT(dp->index);
+	}
+
+	/* Configure CPU ports. If we support cascade switches, this will also
+	 * include DSA ports.
+	 */
+	dsa_switch_for_each_cpu_port(dp, ds) {
+		/* Forward to all user ports */
+		ret = rtl8366rb_port_set_isolation(priv, dp->index, downports_mask);
 		if (ret)
 			return ret;
 	}
-	/* CPU port can send packets to all ports */
-	ret = rtl8366rb_port_set_isolation(priv, RTL8366RB_PORT_NUM_CPU,
-					   dsa_user_ports(ds));
-	if (ret)
-		return ret;
 
 	/* Set up the "green ethernet" feature */
 	ret = rtl8366rb_jam_table(rtl8366rb_green_jam,

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 4/5] net: dsa: realtek: rtl8366rb: Disable STP learning on all ports in setup
  2026-06-30 11:19 [PATCH net-next v2 0/5] net: dsa: realtek: rtl8366rb: Use generic RTL83xx code Linus Walleij
                   ` (2 preceding siblings ...)
  2026-06-30 11:19 ` [PATCH net-next v2 3/5] net: dsa: realtek: rtl8366rb: Use DSA port iterators Linus Walleij
@ 2026-06-30 11:19 ` Linus Walleij
  2026-06-30 11:19 ` [PATCH net-next v2 5/5] net: dsa: realtek: rtl8366rb: Switch to generic learning enablement Linus Walleij
  2026-07-02  9:40 ` [PATCH net-next v2 0/5] net: dsa: realtek: rtl8366rb: Use generic RTL83xx code patchwork-bot+netdevbpf
  5 siblings, 0 replies; 13+ messages in thread
From: Linus Walleij @ 2026-06-30 11:19 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca, Alvin Šipraga, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: netdev, Linus Walleij

When we loop over all ports in the switch .setup() callback,
make sure to disable learning on all user ports. This is what
is normally expected and what the RTL8365MB is doing.

Move the code around to accommodate for the new call.

Reviewed-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
Signed-off-by: Linus Walleij <linusw@kernel.org>
---
 drivers/net/dsa/realtek/rtl8366rb.c | 74 ++++++++++++++++++++-----------------
 1 file changed, 40 insertions(+), 34 deletions(-)

diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
index 64215a0d5d6d..155bf0010d5f 100644
--- a/drivers/net/dsa/realtek/rtl8366rb.c
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
@@ -820,6 +820,40 @@ static int rtl8366rb_port_remove_isolation(struct realtek_priv *priv, int port,
 				  RTL8366RB_PORT_ISO_PORTS(mask), 0);
 }
 
+static void
+rtl8366rb_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+{
+	struct realtek_priv *priv = ds->priv;
+	u32 val;
+	int i;
+
+	switch (state) {
+	case BR_STATE_DISABLED:
+		val = RTL8366RB_STP_STATE_DISABLED;
+		break;
+	case BR_STATE_BLOCKING:
+	case BR_STATE_LISTENING:
+		val = RTL8366RB_STP_STATE_BLOCKING;
+		break;
+	case BR_STATE_LEARNING:
+		val = RTL8366RB_STP_STATE_LEARNING;
+		break;
+	case BR_STATE_FORWARDING:
+		val = RTL8366RB_STP_STATE_FORWARDING;
+		break;
+	default:
+		dev_err(priv->dev, "unknown bridge state requested\n");
+		return;
+	}
+
+	/* Set the same status for the port on all the FIDs */
+	for (i = 0; i < RTL8366RB_NUM_FIDS; i++) {
+		regmap_update_bits(priv->map, RTL8366RB_STP_STATE_BASE + i,
+				   RTL8366RB_STP_STATE_MASK(port),
+				   RTL8366RB_STP_STATE(port, val));
+	}
+}
+
 static int rtl8366rb_setup(struct dsa_switch *ds)
 {
 	struct realtek_priv *priv = ds->priv;
@@ -900,6 +934,12 @@ static int rtl8366rb_setup(struct dsa_switch *ds)
 
 	/* Start with all ports blocked, including unused ports */
 	dsa_switch_for_each_port(dp, ds) {
+		/* Set the initial STP state of all ports to DISABLED, otherwise
+		 * ports will still forward frames to the CPU despite being
+		 * administratively down by default.
+		 */
+		rtl8366rb_port_stp_state_set(ds, dp->index, BR_STATE_DISABLED);
+
 		/* Start with all ports completely isolated */
 		ret = rtl8366rb_port_set_isolation(priv, dp->index, 0);
 		if (ret)
@@ -1320,40 +1360,6 @@ rtl8366rb_port_bridge_flags(struct dsa_switch *ds, int port,
 	return 0;
 }
 
-static void
-rtl8366rb_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
-{
-	struct realtek_priv *priv = ds->priv;
-	u32 val;
-	int i;
-
-	switch (state) {
-	case BR_STATE_DISABLED:
-		val = RTL8366RB_STP_STATE_DISABLED;
-		break;
-	case BR_STATE_BLOCKING:
-	case BR_STATE_LISTENING:
-		val = RTL8366RB_STP_STATE_BLOCKING;
-		break;
-	case BR_STATE_LEARNING:
-		val = RTL8366RB_STP_STATE_LEARNING;
-		break;
-	case BR_STATE_FORWARDING:
-		val = RTL8366RB_STP_STATE_FORWARDING;
-		break;
-	default:
-		dev_err(priv->dev, "unknown bridge state requested\n");
-		return;
-	}
-
-	/* Set the same status for the port on all the FIDs */
-	for (i = 0; i < RTL8366RB_NUM_FIDS; i++) {
-		regmap_update_bits(priv->map, RTL8366RB_STP_STATE_BASE + i,
-				   RTL8366RB_STP_STATE_MASK(port),
-				   RTL8366RB_STP_STATE(port, val));
-	}
-}
-
 static void
 rtl8366rb_port_fast_age(struct dsa_switch *ds, int port)
 {

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 5/5] net: dsa: realtek: rtl8366rb: Switch to generic learning enablement
  2026-06-30 11:19 [PATCH net-next v2 0/5] net: dsa: realtek: rtl8366rb: Use generic RTL83xx code Linus Walleij
                   ` (3 preceding siblings ...)
  2026-06-30 11:19 ` [PATCH net-next v2 4/5] net: dsa: realtek: rtl8366rb: Disable STP learning on all ports in setup Linus Walleij
@ 2026-06-30 11:19 ` Linus Walleij
  2026-07-03 13:31   ` Luiz Angelo Daros de Luca
  2026-07-02  9:40 ` [PATCH net-next v2 0/5] net: dsa: realtek: rtl8366rb: Use generic RTL83xx code patchwork-bot+netdevbpf
  5 siblings, 1 reply; 13+ messages in thread
From: Linus Walleij @ 2026-06-30 11:19 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca, Alvin Šipraga, Andrew Lunn,
	Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: netdev, Linus Walleij

Instead of just writing the learning disablement register in setup
and a custom handling of BR_LEARNING, implement the generic RTL83xx
.port_set_learning() callback for setting learning on a port, and
call this in the per-port loop in .setup().

Instead of the custom rtl83366rb_port_bridge_flags() function for
setting learning mode on each port, use the RTL83xx generic
rtl83xx_port_bridge_flags() callback.

Signed-off-by: Linus Walleij <linusw@kernel.org>
---
 drivers/net/dsa/realtek/rtl8366rb.c | 43 +++++++++++++++----------------------
 1 file changed, 17 insertions(+), 26 deletions(-)

diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
index 155bf0010d5f..d2fa8ff6a5d0 100644
--- a/drivers/net/dsa/realtek/rtl8366rb.c
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
@@ -854,6 +854,16 @@ rtl8366rb_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
 	}
 }
 
+static int rtl8366rb_port_set_learning(struct realtek_priv *priv, int port,
+				       bool enable)
+{
+	/* Notice inverted semantics in this register: setting a bit disables
+	 * learning instead of enabling it.
+	 */
+	return regmap_update_bits(priv->map, RTL8366RB_PORT_LEARNDIS_CTRL,
+				  BIT(port), enable ? 0 : BIT(port));
+}
+
 static int rtl8366rb_setup(struct dsa_switch *ds)
 {
 	struct realtek_priv *priv = ds->priv;
@@ -945,6 +955,11 @@ static int rtl8366rb_setup(struct dsa_switch *ds)
 		if (ret)
 			return ret;
 
+		/* Disable learning */
+		ret = rtl8366rb_port_set_learning(priv, dp->index, false);
+		if (ret)
+			return ret;
+
 		/* Collect CPU ports. If we support cascade switches, it should
 		 * also include the upstream DSA ports.
 		 */
@@ -1037,12 +1052,6 @@ static int rtl8366rb_setup(struct dsa_switch *ds)
 			rb->max_mtu[i] = ETH_DATA_LEN;
 	}
 
-	/* Disable learning for all ports */
-	ret = regmap_write(priv->map, RTL8366RB_PORT_LEARNDIS_CTRL,
-			   RTL8366RB_PORT_ALL);
-	if (ret)
-		return ret;
-
 	/* Enable auto ageing for all ports */
 	ret = regmap_write(priv->map, RTL8366RB_SECURITY_CTRL, 0);
 	if (ret)
@@ -1341,25 +1350,6 @@ rtl8366rb_port_pre_bridge_flags(struct dsa_switch *ds, int port,
 	return 0;
 }
 
-static int
-rtl8366rb_port_bridge_flags(struct dsa_switch *ds, int port,
-			    struct switchdev_brport_flags flags,
-			    struct netlink_ext_ack *extack)
-{
-	struct realtek_priv *priv = ds->priv;
-	int ret;
-
-	if (flags.mask & BR_LEARNING) {
-		ret = regmap_update_bits(priv->map, RTL8366RB_PORT_LEARNDIS_CTRL,
-					 BIT(port),
-					 (flags.val & BR_LEARNING) ? 0 : BIT(port));
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
 static void
 rtl8366rb_port_fast_age(struct dsa_switch *ds, int port)
 {
@@ -1810,7 +1800,7 @@ static const struct dsa_switch_ops rtl8366rb_switch_ops = {
 	.port_enable = rtl8366rb_port_enable,
 	.port_disable = rtl8366rb_port_disable,
 	.port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags,
-	.port_bridge_flags = rtl8366rb_port_bridge_flags,
+	.port_bridge_flags = rtl83xx_port_bridge_flags,
 	.port_stp_state_set = rtl8366rb_port_stp_state_set,
 	.port_fast_age = rtl8366rb_port_fast_age,
 	.port_change_mtu = rtl8366rb_change_mtu,
@@ -1833,6 +1823,7 @@ static const struct realtek_ops rtl8366rb_ops = {
 	.enable_vlan4k	= rtl8366rb_enable_vlan4k,
 	.port_add_isolation = rtl8366rb_port_add_isolation,
 	.port_remove_isolation = rtl8366rb_port_remove_isolation,
+	.port_set_learning = rtl8366rb_port_set_learning,
 	.phy_read	= rtl8366rb_phy_read,
 	.phy_write	= rtl8366rb_phy_write,
 };

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH net-next v2 3/5] net: dsa: realtek: rtl8366rb: Use DSA port iterators
  2026-06-30 11:19 ` [PATCH net-next v2 3/5] net: dsa: realtek: rtl8366rb: Use DSA port iterators Linus Walleij
@ 2026-07-02  9:31   ` Paolo Abeni
  0 siblings, 0 replies; 13+ messages in thread
From: Paolo Abeni @ 2026-07-02  9:31 UTC (permalink / raw)
  To: Linus Walleij, Luiz Angelo Daros de Luca, Alvin Šipraga,
	Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
	Jakub Kicinski
  Cc: netdev

On 6/30/26 1:19 PM, Linus Walleij wrote:
> @@ -895,17 +898,47 @@ static int rtl8366rb_setup(struct dsa_switch *ds)
>  	if (ret)
>  		return ret;
>  
> -	/* Isolate all user ports so they can only send packets to itself and the CPU port */
> -	for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) {
> -		ret = rtl8366rb_port_set_isolation(priv, i, BIT(RTL8366RB_PORT_NUM_CPU));
> +	/* Start with all ports blocked, including unused ports */
> +	dsa_switch_for_each_port(dp, ds) {
> +		/* Start with all ports completely isolated */
> +		ret = rtl8366rb_port_set_isolation(priv, dp->index, 0);

Sashiko (sigh!) noted that the above actually disables isolation entirely.

Since I guess/think/hope there will be at least a CPU port and an user
port per DSA, and later loops will finalize the setup correctly in such
a case, I think this is better handled as a follow-up.

/P


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH net-next v2 0/5] net: dsa: realtek: rtl8366rb: Use generic RTL83xx code
  2026-06-30 11:19 [PATCH net-next v2 0/5] net: dsa: realtek: rtl8366rb: Use generic RTL83xx code Linus Walleij
                   ` (4 preceding siblings ...)
  2026-06-30 11:19 ` [PATCH net-next v2 5/5] net: dsa: realtek: rtl8366rb: Switch to generic learning enablement Linus Walleij
@ 2026-07-02  9:40 ` patchwork-bot+netdevbpf
  5 siblings, 0 replies; 13+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-07-02  9:40 UTC (permalink / raw)
  To: Linus Walleij
  Cc: luizluca, alsi, andrew, olteanv, davem, edumazet, kuba, pabeni,
	netdev

Hello:

This series was applied to netdev/net-next.git (main)
by Paolo Abeni <pabeni@redhat.com>:

On Tue, 30 Jun 2026 13:19:40 +0200 you wrote:
> As a follow-up to Luiz's and Alvin's series improvining the
> generic handling of the Realtek DSA switches, this small
> series brings the RTL8366RB closer to the way things are done
> in the RTL8365MB driver.
> 
> This patch series switches over to using the generic helpers
> for:
> 
> [...]

Here is the summary with links:
  - [net-next,v2,1/5] net: dsa: realtek: rtl83xx: Make learning optional in join/leave
    https://git.kernel.org/netdev/net-next/c/69bf497cfa79
  - [net-next,v2,2/5] net: dsa: realtek: rtl8366rb: Switch to generic port_bridge* handlers
    https://git.kernel.org/netdev/net-next/c/82ddf181448b
  - [net-next,v2,3/5] net: dsa: realtek: rtl8366rb: Use DSA port iterators
    https://git.kernel.org/netdev/net-next/c/cc61d5d7c205
  - [net-next,v2,4/5] net: dsa: realtek: rtl8366rb: Disable STP learning on all ports in setup
    https://git.kernel.org/netdev/net-next/c/e058ab0c4616
  - [net-next,v2,5/5] net: dsa: realtek: rtl8366rb: Switch to generic learning enablement
    https://git.kernel.org/netdev/net-next/c/b269a0596191

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH net-next v2 1/5] net: dsa: realtek: rtl83xx: Make learning optional in join/leave
  2026-06-30 11:19 ` [PATCH net-next v2 1/5] net: dsa: realtek: rtl83xx: Make learning optional in join/leave Linus Walleij
@ 2026-07-03 13:13   ` Luiz Angelo Daros de Luca
  0 siblings, 0 replies; 13+ messages in thread
From: Luiz Angelo Daros de Luca @ 2026-07-03 13:13 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Alvin Šipraga, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev

> Mostly to make it possible to add rtl83xx support piece by piece,
> make the port learning callback optional in rtl83xx_port_bridge_join()
> and rtl83xx_port_bridge_leave().
>
> Signed-off-by: Linus Walleij <linusw@kernel.org>

I know it was already merged. Anyway

Reviewed-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH net-next v2 2/5] net: dsa: realtek: rtl8366rb: Switch to generic port_bridge* handlers
  2026-06-30 11:19 ` [PATCH net-next v2 2/5] net: dsa: realtek: rtl8366rb: Switch to generic port_bridge* handlers Linus Walleij
@ 2026-07-03 13:15   ` Luiz Angelo Daros de Luca
  2026-07-03 13:24   ` Luiz Angelo Daros de Luca
  1 sibling, 0 replies; 13+ messages in thread
From: Luiz Angelo Daros de Luca @ 2026-07-03 13:15 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Alvin Šipraga, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev

Em ter., 30 de jun. de 2026 às 08:19, Linus Walleij
<linusw@kernel.org> escreveu:
>
> The RTL8366RB is using its own sub-standard port isolation code.
>
> Implement the required isolation helpers, use these directly in
> the port setup callback, and switch over to the standard port
> isolation code.
>
> Signed-off-by: Linus Walleij <linusw@kernel.org>

Reviewed-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH net-next v2 2/5] net: dsa: realtek: rtl8366rb: Switch to generic port_bridge* handlers
  2026-06-30 11:19 ` [PATCH net-next v2 2/5] net: dsa: realtek: rtl8366rb: Switch to generic port_bridge* handlers Linus Walleij
  2026-07-03 13:15   ` Luiz Angelo Daros de Luca
@ 2026-07-03 13:24   ` Luiz Angelo Daros de Luca
  2026-07-03 21:17     ` Linus Walleij
  1 sibling, 1 reply; 13+ messages in thread
From: Luiz Angelo Daros de Luca @ 2026-07-03 13:24 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Alvin Šipraga, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev

> +static int rtl8366rb_port_set_isolation(struct realtek_priv *priv, int port,
> +                                       u32 mask)
> +{
> +       /* Bit 0 enables isolation so set this if we enable isolation
> +        * any of the ports an clear it if we disable on all of them.
> +        */
> +       if (mask)
> +               mask = RTL8366RB_PORT_ISO_PORTS(mask) | RTL8366RB_PORT_ISO_EN;
> +
> +       return regmap_write(priv->map, RTL8366RB_PORT_ISO(port),
> +                           mask);
> +}

As sashiko pointed out, set_insolation(...,0) actually disables it
instead of completely isolating it.
I would unconditionally isolate the ports as we will never need to disable it.

Regards,

Luiz

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH net-next v2 5/5] net: dsa: realtek: rtl8366rb: Switch to generic learning enablement
  2026-06-30 11:19 ` [PATCH net-next v2 5/5] net: dsa: realtek: rtl8366rb: Switch to generic learning enablement Linus Walleij
@ 2026-07-03 13:31   ` Luiz Angelo Daros de Luca
  0 siblings, 0 replies; 13+ messages in thread
From: Luiz Angelo Daros de Luca @ 2026-07-03 13:31 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Alvin Šipraga, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev

> Instead of just writing the learning disablement register in setup
> and a custom handling of BR_LEARNING, implement the generic RTL83xx
> .port_set_learning() callback for setting learning on a port, and
> call this in the per-port loop in .setup().
>
> Instead of the custom rtl83366rb_port_bridge_flags() function for
> setting learning mode on each port, use the RTL83xx generic
> rtl83xx_port_bridge_flags() callback.
>
> Signed-off-by: Linus Walleij <linusw@kernel.org>

Reviewed-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH net-next v2 2/5] net: dsa: realtek: rtl8366rb: Switch to generic port_bridge* handlers
  2026-07-03 13:24   ` Luiz Angelo Daros de Luca
@ 2026-07-03 21:17     ` Linus Walleij
  0 siblings, 0 replies; 13+ messages in thread
From: Linus Walleij @ 2026-07-03 21:17 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca
  Cc: Alvin Šipraga, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev

On Fri, Jul 3, 2026 at 3:24 PM Luiz Angelo Daros de Luca
<luizluca@gmail.com> wrote:

> > +static int rtl8366rb_port_set_isolation(struct realtek_priv *priv, int port,
> > +                                       u32 mask)
> > +{
> > +       /* Bit 0 enables isolation so set this if we enable isolation
> > +        * any of the ports an clear it if we disable on all of them.
> > +        */
> > +       if (mask)
> > +               mask = RTL8366RB_PORT_ISO_PORTS(mask) | RTL8366RB_PORT_ISO_EN;
> > +
> > +       return regmap_write(priv->map, RTL8366RB_PORT_ISO(port),
> > +                           mask);
> > +}
>
> As sashiko pointed out, set_insolation(...,0) actually disables it
> instead of completely isolating it.
> I would unconditionally isolate the ports as we will never need to disable it.

Yeah, I'm working on a follow-up patch to fix this!

Thanks,
Linus Walleij

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-07-03 21:17 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-30 11:19 [PATCH net-next v2 0/5] net: dsa: realtek: rtl8366rb: Use generic RTL83xx code Linus Walleij
2026-06-30 11:19 ` [PATCH net-next v2 1/5] net: dsa: realtek: rtl83xx: Make learning optional in join/leave Linus Walleij
2026-07-03 13:13   ` Luiz Angelo Daros de Luca
2026-06-30 11:19 ` [PATCH net-next v2 2/5] net: dsa: realtek: rtl8366rb: Switch to generic port_bridge* handlers Linus Walleij
2026-07-03 13:15   ` Luiz Angelo Daros de Luca
2026-07-03 13:24   ` Luiz Angelo Daros de Luca
2026-07-03 21:17     ` Linus Walleij
2026-06-30 11:19 ` [PATCH net-next v2 3/5] net: dsa: realtek: rtl8366rb: Use DSA port iterators Linus Walleij
2026-07-02  9:31   ` Paolo Abeni
2026-06-30 11:19 ` [PATCH net-next v2 4/5] net: dsa: realtek: rtl8366rb: Disable STP learning on all ports in setup Linus Walleij
2026-06-30 11:19 ` [PATCH net-next v2 5/5] net: dsa: realtek: rtl8366rb: Switch to generic learning enablement Linus Walleij
2026-07-03 13:31   ` Luiz Angelo Daros de Luca
2026-07-02  9:40 ` [PATCH net-next v2 0/5] net: dsa: realtek: rtl8366rb: Use generic RTL83xx code patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox