From nobody Wed Apr 1 09:44:30 2026 Received: from mail-vk1-f170.google.com (mail-vk1-f170.google.com [209.85.221.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D9C04611CE for ; Tue, 31 Mar 2026 23:00:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774998053; cv=none; b=udl0+C4JqOrXyJedJ26RQCH9xhjiL975Wmc09Gvp3ujiF9UPXy8a4HqpOwu4fcO3sEtn0+vFxJ3f6bgzTt5fdrEmfuaPE6IDbU+F7bPt37Kd2xeyRcgb4LSaHqI//BZVk4Ahk178tT2sEWnTFu/72BWxlQlkRXrjWX1Oa3+vOck= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774998053; c=relaxed/simple; bh=tN8N0/Pfy9DaP4Rgpo4ivkxeOwe/BNzpIiyJBucuD/0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZZR9LGkZEKh2fpqxg0mziqQn+IgnIJmFZjOXI2SQZjrXburAUbpQZLPzUBa/laj4yGLaHrDEAW9b7744dd3te8Ob17O8EmNG946bZbgZiNUOaNO4znRFJcniQ7rQOYcuepUQEKh+qBPukt6iMEYMhwAonabOA3KmPOw5XFuNcss= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=C/Uwdjtq; arc=none smtp.client-ip=209.85.221.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="C/Uwdjtq" Received: by mail-vk1-f170.google.com with SMTP id 71dfb90a1353d-56d85e76d73so602738e0c.2 for ; Tue, 31 Mar 2026 16:00:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774998051; x=1775602851; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=pJDO8dNemPTipqN+44lXNB8MtKgUhVoWcKpvwCy+p/c=; b=C/UwdjtqPZwwBslKS0bh73EBRmsI1Up8v24uvDO3cRMWaqYl3RADT3SzeXfnjLv/3t LdIwnTsgF8/6jVfd4EVCaz5sqOdgjPZYwF4LV1fp6R7MHlQ/QaPckbyLH9SOzNHnjdsn U2/mYcwMKmYry73XwogR3p/66akfsaJfMlasHrqNkoHzO61sEcFeR5prdY+KjPO8gJff 9MZMk8cAVkyGTrVfqAw1JCt8cfgouexpyPpTbKQP/TvC+MY0KLO9asCjCRsuoqNTkFBB F2p6gDlKfDGsqnFBRZ1myetyS/ThnQPMTdm+300YNy3Ex9Lb2xXzmR8l3RmXi/028q6V oWOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774998051; x=1775602851; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=pJDO8dNemPTipqN+44lXNB8MtKgUhVoWcKpvwCy+p/c=; b=GhTgIb6Vc4lU6TxBqxOseoxNKF0DVk1C/WloFMMabu7mILGovkl7cGKa3NFEv3uakE WRkdrN9jzCNlrAuFWMlS4vLlWFqQedKDOev1K1Lv36jX0QvP2IG5Y0Hc6E/AP7YXnzRf n+z6SZZgwGH3cEixoyadEYJZCMbEm9bgNWiSLpNQ4o9PxHP3afQ4q80pE34Xvpqz5JcO KyCX1GjAzh8uH6i9st9rTR5jBIVqum5EN+bv16gjE6IMmjdzcY0cIPS5WQxm9PUUrfwJ gdpZR4DhRhTUrwhhVUmevldQwJBjzfG92Zd1dx/MC9DSw1Cci53UhT7oURyv7XmU97Kw kXag== X-Forwarded-Encrypted: i=1; AJvYcCWlgRRCBHiIWNCAjBXafGs92D3wfFyWkoXZIbi0//RrUIU402jqexQ7KwzYohr+/rhCI7F96awhPZ+H5bg=@vger.kernel.org X-Gm-Message-State: AOJu0YxUDHlLNfyOr2oYDHESmqgvO6Pnhw6MW0AxTG+rE5c4cgAQjBTe Vveswt4CoFQugsL1opsliTfkAM+lhAaSEigNjjlhOh4Lgo6jx27orMQ7 X-Gm-Gg: ATEYQzxxa3+GiwUnvxb46ElmC8a3oGqtSEFDvgd+g+IN8giuNASLp+uBVwciG9BLpBM U8VSmFRky4Q4A1dNADk7uVdwSV3Fpr9kVK71Qp6ylTzzcGr4cSiXFaRmwWEyOIxlfhKPcpyPnfH icERkMLTH6JwMx6dMe3rvmNJysnqROgrHX9c4rYBXrQaL1LBfBq5C33TJcIl8a2D8KphI6bCLu3 Bd+syweOEpRHw260BC5jwlw/ozaPAt+qIeBSHTrbWfJ79C/T/9ufO2WtXsbSbyzCiWTwwwRvQS/ S2SnPjjMylJwS0chP0yzkZ3tmbjCfNBWQwX/x58ozQ88LQmkTXGvAKV7Z7WN0VUh3iR6mxZTS/j 92YiShJQXSy4zhIEXWMi1yRA7I5BNT67RVJuBdTCmTMOjeWdRd1VpdTNbvNEs9AxR8GyphNmKye H8MBE/IaIiHUV0JH3kL3pI1lvQAxbhlYy/wIadNw== X-Received: by 2002:a05:6122:e170:b0:56b:579c:82e with SMTP id 71dfb90a1353d-56d8a843538mr792707e0c.5.1774998050757; Tue, 31 Mar 2026 16:00:50 -0700 (PDT) Received: from tresc054937.tre-sc.gov.br ([187.65.210.13]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-56d58a7ba96sm13948214e0c.17.2026.03.31.16.00.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Mar 2026 16:00:49 -0700 (PDT) From: Luiz Angelo Daros de Luca Date: Tue, 31 Mar 2026 20:00:07 -0300 Subject: [net-next PATCH 07/10] net: dsa: realtek: rtl8365mb: add port_bridge_{join,leave} Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260331-realtek_forward-v1-7-44fb63033b7e@gmail.com> References: <20260331-realtek_forward-v1-0-44fb63033b7e@gmail.com> In-Reply-To: <20260331-realtek_forward-v1-0-44fb63033b7e@gmail.com> To: Andrew Lunn , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Linus Walleij , =?utf-8?q?Alvin_=C5=A0ipraga?= , Yury Norov , Rasmus Villemoes , Russell King Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Luiz Angelo Daros de Luca X-Mailer: b4 0.15.1 From: Alvin =C5=A0ipraga Implement hardware offloading of bridge functionality. This is achieved by using the per-port isolation registers, which contain a forwarding port mask. The switch will refuse to forward packets ingressed on a given port to a port which is not in its forwarding mask. For each bridge that is offloaded, use the DSA-provided bridge number for the Extended Filtering ID (EFID). When using Independent VLAN Learning (IVL), the forwarding database is keyed with the tuple {VID, MAC, EFID}. There are 8 EFIDs available (0~7), but we reserve the default EFID 0 for standalone ports where learning is disabled. This fits nicely because DSA indexes the bridge number starting from 1. Because of the limited number of EFIDs, we have to set the max_num_bridges property of our switch to 7: we can't offload more than that or we will fail to offer IVL as at least two bridges would end up having to share an EFID. Co-developed-by: Alvin =C5=A0ipraga Signed-off-by: Alvin =C5=A0ipraga Signed-off-by: Luiz Angelo Daros de Luca --- drivers/net/dsa/realtek/rtl8365mb_main.c | 123 +++++++++++++++++++++++++++= +++- 1 file changed, 122 insertions(+), 1 deletion(-) diff --git a/drivers/net/dsa/realtek/rtl8365mb_main.c b/drivers/net/dsa/rea= ltek/rtl8365mb_main.c index c604bd744d38..c955864f17b3 100644 --- a/drivers/net/dsa/realtek/rtl8365mb_main.c +++ b/drivers/net/dsa/realtek/rtl8365mb_main.c @@ -285,6 +285,15 @@ (RTL8365MB_PORT_ISOLATION_REG_BASE + (_physport)) #define RTL8365MB_PORT_ISOLATION_MASK 0x07FF =20 +/* Extended filter ID registers - used to key forwarding database with IVL= */ +#define RTL8365MB_EFID_MASK GENMASK(2, 0) +#define RTL8365MB_PORT_EFID_REG_BASE 0x0A32 +#define RTL8365MB_PORT_EFID_REG(_p) \ + (RTL8365MB_PORT_EFID_REG_BASE + ((_p) >> 2)) +#define RTL8365MB_PORT_EFID_OFFSET(_p) (((_p) & 0x3) << 2) +#define RTL8365MB_PORT_EFID_MASK(_p) \ + (RTL8365MB_EFID_MASK << RTL8365MB_PORT_EFID_OFFSET(_p)) + /* MSTP port state registers - indexed by tree instance */ #define RTL8365MB_MSTI_CTRL_BASE 0x0A00 #define RTL8365MB_MSTI_CTRL_REG(_msti, _physport) \ @@ -1447,10 +1456,117 @@ static int rtl8365mb_port_set_learning(struct real= tek_priv *priv, int port, enable ? RTL8365MB_LEARN_LIMIT_MAX : 0); } =20 +static int rtl8365mb_port_set_efid(struct realtek_priv *priv, int port, + u32 efid) +{ + return regmap_update_bits(priv->map, RTL8365MB_PORT_EFID_REG(port), + RTL8365MB_PORT_EFID_MASK(port), + efid << RTL8365MB_PORT_EFID_OFFSET(port)); +} + +/* Port isolation manipulation functions. + * + * The port isolation register controls the forwarding mask of a given + * port. The switch will not forward packets ingressed on a given port + * to ports which are not enabled in its forwarding mask. + * + * The port forwarding mask has the highest priority in forwarding + * decisions. The only exception to this rule is when the switch + * receives a packet on its CPU port with ALLOW=3D0. In that case the TX + * field of the CPU tag will override the forwarding port mask. + */ static int rtl8365mb_port_set_isolation(struct realtek_priv *priv, int por= t, u32 mask) { - return regmap_write(priv->map, RTL8365MB_PORT_ISOLATION_REG(port), mask); + return regmap_write(priv->map, RTL8365MB_PORT_ISOLATION_REG(port), + mask); +} + +static int rtl8365mb_port_add_isolation(struct realtek_priv *priv, int por= t, + u32 mask) +{ + return regmap_update_bits(priv->map, RTL8365MB_PORT_ISOLATION_REG(port), + mask, mask); +} + +static int rtl8365mb_port_remove_isolation(struct realtek_priv *priv, int = port, + u32 mask) +{ + return regmap_update_bits(priv->map, RTL8365MB_PORT_ISOLATION_REG(port), + mask, 0); +} + +static int rtl8365mb_port_bridge_join(struct dsa_switch *ds, int port, + struct dsa_bridge bridge, + bool *tx_forward_offload, + struct netlink_ext_ack *extack) +{ + struct realtek_priv *priv =3D ds->priv; + u32 mask =3D 0; + int ret; + int i; + + /* Add this port to the isolation group of every other port + * offloading this bridge. + */ + for (i =3D 0; i < priv->num_ports; i++) { + /* Handle this port after */ + if (i =3D=3D port) + continue; + + /* Skip ports that are not in this bridge */ + if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge)) + continue; + + ret =3D rtl8365mb_port_add_isolation(priv, i, BIT(port)); + if (ret) + return ret; + + mask |=3D BIT(i); + } + + /* Add those ports to the isolation group of this port */ + ret =3D rtl8365mb_port_add_isolation(priv, port, mask); + if (ret) + return ret; + + /* Use the bridge number as the EFID for this port */ + ret =3D rtl8365mb_port_set_efid(priv, port, bridge.num); + if (ret) + return ret; + + return 0; +} + +static void rtl8365mb_port_bridge_leave(struct dsa_switch *ds, int port, + struct dsa_bridge bridge) +{ + struct realtek_priv *priv =3D ds->priv; + u32 mask =3D 0; + int i; + + /* Remove this port from the isolation group of every other + * port offloading this bridge. + */ + for (i =3D 0; i < priv->num_ports; i++) { + /* Handle this port after */ + if (i =3D=3D port) + continue; + + /* Skip ports that are not in this bridge */ + if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge)) + continue; + + rtl8365mb_port_remove_isolation(priv, i, BIT(port)); + + mask |=3D BIT(i); + } + + /* Remove those ports from the isolation group of this port */ + rtl8365mb_port_remove_isolation(priv, port, mask); + + /* Revert to the default EFID 0 for standalone mode */ + rtl8365mb_port_set_efid(priv, port, 0); } =20 static int rtl8365mb_mib_counter_read(struct realtek_priv *priv, int port, @@ -2253,6 +2369,9 @@ static int rtl8365mb_setup(struct dsa_switch *ds) if (ret) goto out_teardown_irq; =20 + /* The EFID is 3 bits, but EFID 0 is reserved for standalone ports */ + ds->max_num_bridges =3D FIELD_MAX(RTL8365MB_EFID_MASK); + /* vlan config will only be effective for ports with vlan filtering */ ds->configure_vlan_while_not_filtering =3D true; /* Set up VLAN */ @@ -2376,6 +2495,8 @@ static const struct dsa_switch_ops rtl8365mb_switch_o= ps =3D { .setup =3D rtl8365mb_setup, .teardown =3D rtl8365mb_teardown, .phylink_get_caps =3D rtl8365mb_phylink_get_caps, + .port_bridge_join =3D rtl8365mb_port_bridge_join, + .port_bridge_leave =3D rtl8365mb_port_bridge_leave, .port_stp_state_set =3D rtl8365mb_port_stp_state_set, .port_vlan_add =3D rtl8365mb_port_vlan_add, .port_vlan_del =3D rtl8365mb_port_vlan_del, --=20 2.53.0