generic: 6.1: sync mt7530 DSA driver with upstream
[openwrt/openwrt.git] / target / linux / generic / backport-6.1 / 789-STABLE-03-net-dsa-mt7530-fix-handling-of-all-link-local-frames.patch
diff --git a/target/linux/generic/backport-6.1/789-STABLE-03-net-dsa-mt7530-fix-handling-of-all-link-local-frames.patch b/target/linux/generic/backport-6.1/789-STABLE-03-net-dsa-mt7530-fix-handling-of-all-link-local-frames.patch
new file mode 100644 (file)
index 0000000..cf7a3c1
--- /dev/null
@@ -0,0 +1,133 @@
+From 86c0c154a759f2af9612a04bdf29110f02dce956 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
+Date: Thu, 14 Mar 2024 12:33:42 +0300
+Subject: [PATCH 3/3] net: dsa: mt7530: fix handling of all link-local frames
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+[ Upstream commit 69ddba9d170bdaee1dc0eb4ced38d7e4bb7b92af ]
+
+Currently, the MT753X switches treat frames with :01-0D and :0F MAC DAs as
+regular multicast frames, therefore flooding them to user ports.
+
+On page 205, section "8.6.3 Frame filtering" of the active standard, IEEE
+Std 802.1Q™-2022, it is stated that frames with 01:80:C2:00:00:00-0F as MAC
+DA must only be propagated to C-VLAN and MAC Bridge components. That means
+VLAN-aware and VLAN-unaware bridges. On the switch designs with CPU ports,
+these frames are supposed to be processed by the CPU (software). So we make
+the switch only forward them to the CPU port. And if received from a CPU
+port, forward to a single port. The software is responsible of making the
+switch conform to the latter by setting a single port as destination port
+on the special tag.
+
+This switch intellectual property cannot conform to this part of the
+standard fully. Whilst the REV_UN frame tag covers the remaining :04-0D and
+:0F MAC DAs, it also includes :22-FF which the scope of propagation is not
+supposed to be restricted for these MAC DAs.
+
+Set frames with :01-03 MAC DAs to be trapped to the CPU port(s). Add a
+comment for the remaining MAC DAs.
+
+Note that the ingress port must have a PVID assigned to it for the switch
+to forward untagged frames. A PVID is set by default on VLAN-aware and
+VLAN-unaware ports. However, when the network interface that pertains to
+the ingress port is attached to a vlan_filtering enabled bridge, the user
+can remove the PVID assignment from it which would prevent the link-local
+frames from being trapped to the CPU port. I am yet to see a way to forward
+link-local frames while preventing other untagged frames from being
+forwarded too.
+
+Fixes: b8f126a8d543 ("net-next: dsa: add dsa support for Mediatek MT7530 switch")
+Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mt7530.c | 37 +++++++++++++++++++++++++++++++++----
+ drivers/net/dsa/mt7530.h | 13 +++++++++++++
+ 2 files changed, 46 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -998,6 +998,21 @@ unlock_exit:
+       mutex_unlock(&priv->reg_mutex);
+ }
++/* On page 205, section "8.6.3 Frame filtering" of the active standard, IEEE Std
++ * 802.1Q™-2022, it is stated that frames with 01:80:C2:00:00:00-0F as MAC DA
++ * must only be propagated to C-VLAN and MAC Bridge components. That means
++ * VLAN-aware and VLAN-unaware bridges. On the switch designs with CPU ports,
++ * these frames are supposed to be processed by the CPU (software). So we make
++ * the switch only forward them to the CPU port. And if received from a CPU
++ * port, forward to a single port. The software is responsible of making the
++ * switch conform to the latter by setting a single port as destination port on
++ * the special tag.
++ *
++ * This switch intellectual property cannot conform to this part of the standard
++ * fully. Whilst the REV_UN frame tag covers the remaining :04-0D and :0F MAC
++ * DAs, it also includes :22-FF which the scope of propagation is not supposed
++ * to be restricted for these MAC DAs.
++ */
+ static void
+ mt753x_trap_frames(struct mt7530_priv *priv)
+ {
+@@ -1012,13 +1027,27 @@ mt753x_trap_frames(struct mt7530_priv *p
+                  MT753X_BPDU_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
+                  MT753X_BPDU_CPU_ONLY);
+-      /* Trap LLDP frames with :0E MAC DA to the CPU port(s) and egress them
+-       * VLAN-untagged.
++      /* Trap frames with :01 and :02 MAC DAs to the CPU port(s) and egress
++       * them VLAN-untagged.
++       */
++      mt7530_rmw(priv, MT753X_RGAC1, MT753X_R02_EG_TAG_MASK |
++                 MT753X_R02_PORT_FW_MASK | MT753X_R01_EG_TAG_MASK |
++                 MT753X_R01_PORT_FW_MASK,
++                 MT753X_R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
++                 MT753X_R02_PORT_FW(MT753X_BPDU_CPU_ONLY) |
++                 MT753X_R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
++                 MT753X_BPDU_CPU_ONLY);
++
++      /* Trap frames with :03 and :0E MAC DAs to the CPU port(s) and egress
++       * them VLAN-untagged.
+        */
+       mt7530_rmw(priv, MT753X_RGAC2, MT753X_R0E_EG_TAG_MASK |
+-                 MT753X_R0E_PORT_FW_MASK,
++                 MT753X_R0E_PORT_FW_MASK | MT753X_R03_EG_TAG_MASK |
++                 MT753X_R03_PORT_FW_MASK,
+                  MT753X_R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
+-                 MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY));
++                 MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY) |
++                 MT753X_R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
++                 MT753X_BPDU_CPU_ONLY);
+ }
+ static int
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -71,12 +71,25 @@ enum mt753x_id {
+ #define  MT753X_BPDU_EG_TAG(x)                FIELD_PREP(MT753X_BPDU_EG_TAG_MASK, x)
+ #define  MT753X_BPDU_PORT_FW_MASK     GENMASK(2, 0)
++/* Register for :01 and :02 MAC DA frame control */
++#define MT753X_RGAC1                  0x28
++#define  MT753X_R02_EG_TAG_MASK               GENMASK(24, 22)
++#define  MT753X_R02_EG_TAG(x)         FIELD_PREP(MT753X_R02_EG_TAG_MASK, x)
++#define  MT753X_R02_PORT_FW_MASK      GENMASK(18, 16)
++#define  MT753X_R02_PORT_FW(x)                FIELD_PREP(MT753X_R02_PORT_FW_MASK, x)
++#define  MT753X_R01_EG_TAG_MASK               GENMASK(8, 6)
++#define  MT753X_R01_EG_TAG(x)         FIELD_PREP(MT753X_R01_EG_TAG_MASK, x)
++#define  MT753X_R01_PORT_FW_MASK      GENMASK(2, 0)
++
+ /* Register for :03 and :0E MAC DA frame control */
+ #define MT753X_RGAC2                  0x2c
+ #define  MT753X_R0E_EG_TAG_MASK               GENMASK(24, 22)
+ #define  MT753X_R0E_EG_TAG(x)         FIELD_PREP(MT753X_R0E_EG_TAG_MASK, x)
+ #define  MT753X_R0E_PORT_FW_MASK      GENMASK(18, 16)
+ #define  MT753X_R0E_PORT_FW(x)                FIELD_PREP(MT753X_R0E_PORT_FW_MASK, x)
++#define  MT753X_R03_EG_TAG_MASK               GENMASK(8, 6)
++#define  MT753X_R03_EG_TAG(x)         FIELD_PREP(MT753X_R03_EG_TAG_MASK, x)
++#define  MT753X_R03_PORT_FW_MASK      GENMASK(2, 0)
+ enum mt753x_bpdu_port_fw {
+       MT753X_BPDU_FOLLOW_MFC,