forked from openwrt/openwrt
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
generic: 6.6: mt7530: add support for bridge port isolation
Import patches accepted upstream introducing port isolation feature on MT7530 switches: - [net-next,v3,1/2] net: dsa: mt7530: factor out bridge join/leave logic https://git.kernel.org/netdev/net-next/c/c25c961fc7f3 - [net-next,v3,2/2] net: dsa: mt7530: add support for bridge port isolation https://git.kernel.org/netdev/net-next/c/3d49ee2127c2 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
- Loading branch information
Showing
2 changed files
with
255 additions
and
0 deletions.
There are no files selected for viewing
176 changes: 176 additions & 0 deletions
176
...generic/backport-6.6/790-55-v6.11-net-dsa-mt7530-factor-out-bridge-join-leave-logic.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
From c25c961fc7f36682f0a530150f1b7453ebc344cd Mon Sep 17 00:00:00 2001 | ||
From: Matthias Schiffer <mschiffer@universe-factory.net> | ||
Date: Tue, 18 Jun 2024 09:17:12 +0200 | ||
Subject: [PATCH 1/2] net: dsa: mt7530: factor out bridge join/leave logic | ||
MIME-Version: 1.0 | ||
Content-Type: text/plain; charset=UTF-8 | ||
Content-Transfer-Encoding: 8bit | ||
|
||
As preparation for implementing bridge port isolation, move the logic to | ||
add and remove bits in the port matrix into a new helper | ||
mt7530_update_port_member(), which is called from | ||
mt7530_port_bridge_join() and mt7530_port_bridge_leave(). | ||
|
||
Another part of the preparation is using dsa_port_offloads_bridge_dev() | ||
instead of dsa_port_offloads_bridge() to check for bridge membership, as | ||
we don't have a struct dsa_bridge in mt7530_port_bridge_flags(). | ||
|
||
The port matrix setting is slightly streamlined, now always first setting | ||
the mt7530_port's pm field and then writing the port matrix from that | ||
field into the hardware register, instead of duplicating the bit | ||
manipulation for both the struct field and the register. | ||
|
||
mt7530_port_bridge_join() was previously using |= to update the port | ||
matrix with the port bitmap, which was unnecessary, as pm would only | ||
have the CPU port set before joining a bridge; a simple assignment can | ||
be used for both joining and leaving (and will also work when individual | ||
bits are added/removed in port_bitmap with regard to the previous port | ||
matrix, which is what happens with port isolation). | ||
|
||
No functional change intended. | ||
|
||
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net> | ||
Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com> | ||
Reviewed-by: Arınç ÜNAL <arinc.unal@arinc9.com> | ||
Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com> | ||
Signed-off-by: David S. Miller <davem@davemloft.net> | ||
--- | ||
drivers/net/dsa/mt7530.c | 105 ++++++++++++++++++--------------------- | ||
1 file changed, 48 insertions(+), 57 deletions(-) | ||
|
||
--- a/drivers/net/dsa/mt7530.c | ||
+++ b/drivers/net/dsa/mt7530.c | ||
@@ -1302,6 +1302,52 @@ mt7530_stp_state_set(struct dsa_switch * | ||
FID_PST(FID_BRIDGED, stp_state)); | ||
} | ||
|
||
+static void mt7530_update_port_member(struct mt7530_priv *priv, int port, | ||
+ const struct net_device *bridge_dev, | ||
+ bool join) __must_hold(&priv->reg_mutex) | ||
+{ | ||
+ struct dsa_port *dp = dsa_to_port(priv->ds, port), *other_dp; | ||
+ struct mt7530_port *p = &priv->ports[port], *other_p; | ||
+ struct dsa_port *cpu_dp = dp->cpu_dp; | ||
+ u32 port_bitmap = BIT(cpu_dp->index); | ||
+ int other_port; | ||
+ | ||
+ dsa_switch_for_each_user_port(other_dp, priv->ds) { | ||
+ other_port = other_dp->index; | ||
+ other_p = &priv->ports[other_port]; | ||
+ | ||
+ if (dp == other_dp) | ||
+ continue; | ||
+ | ||
+ /* Add/remove this port to/from the port matrix of the other | ||
+ * ports in the same bridge. If the port is disabled, port | ||
+ * matrix is kept and not being setup until the port becomes | ||
+ * enabled. | ||
+ */ | ||
+ if (!dsa_port_offloads_bridge_dev(other_dp, bridge_dev)) | ||
+ continue; | ||
+ | ||
+ if (join) { | ||
+ other_p->pm |= PCR_MATRIX(BIT(port)); | ||
+ port_bitmap |= BIT(other_port); | ||
+ } else { | ||
+ other_p->pm &= ~PCR_MATRIX(BIT(port)); | ||
+ } | ||
+ | ||
+ if (other_p->enable) | ||
+ mt7530_rmw(priv, MT7530_PCR_P(other_port), | ||
+ PCR_MATRIX_MASK, other_p->pm); | ||
+ } | ||
+ | ||
+ /* Add/remove the all other ports to this port matrix. For !join | ||
+ * (leaving the bridge), only the CPU port will remain in the port matrix | ||
+ * of this port. | ||
+ */ | ||
+ p->pm = PCR_MATRIX(port_bitmap); | ||
+ if (priv->ports[port].enable) | ||
+ mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, p->pm); | ||
+} | ||
+ | ||
static int | ||
mt7530_port_pre_bridge_flags(struct dsa_switch *ds, int port, | ||
struct switchdev_brport_flags flags, | ||
@@ -1345,39 +1391,11 @@ mt7530_port_bridge_join(struct dsa_switc | ||
struct dsa_bridge bridge, bool *tx_fwd_offload, | ||
struct netlink_ext_ack *extack) | ||
{ | ||
- struct dsa_port *dp = dsa_to_port(ds, port), *other_dp; | ||
- struct dsa_port *cpu_dp = dp->cpu_dp; | ||
- u32 port_bitmap = BIT(cpu_dp->index); | ||
struct mt7530_priv *priv = ds->priv; | ||
|
||
mutex_lock(&priv->reg_mutex); | ||
|
||
- dsa_switch_for_each_user_port(other_dp, ds) { | ||
- int other_port = other_dp->index; | ||
- | ||
- if (dp == other_dp) | ||
- continue; | ||
- | ||
- /* Add this port to the port matrix of the other ports in the | ||
- * same bridge. If the port is disabled, port matrix is kept | ||
- * and not being setup until the port becomes enabled. | ||
- */ | ||
- if (!dsa_port_offloads_bridge(other_dp, &bridge)) | ||
- continue; | ||
- | ||
- if (priv->ports[other_port].enable) | ||
- mt7530_set(priv, MT7530_PCR_P(other_port), | ||
- PCR_MATRIX(BIT(port))); | ||
- priv->ports[other_port].pm |= PCR_MATRIX(BIT(port)); | ||
- | ||
- port_bitmap |= BIT(other_port); | ||
- } | ||
- | ||
- /* Add the all other ports to this port matrix. */ | ||
- if (priv->ports[port].enable) | ||
- mt7530_rmw(priv, MT7530_PCR_P(port), | ||
- PCR_MATRIX_MASK, PCR_MATRIX(port_bitmap)); | ||
- priv->ports[port].pm |= PCR_MATRIX(port_bitmap); | ||
+ mt7530_update_port_member(priv, port, bridge.dev, true); | ||
|
||
/* Set to fallback mode for independent VLAN learning */ | ||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK, | ||
@@ -1478,38 +1496,11 @@ static void | ||
mt7530_port_bridge_leave(struct dsa_switch *ds, int port, | ||
struct dsa_bridge bridge) | ||
{ | ||
- struct dsa_port *dp = dsa_to_port(ds, port), *other_dp; | ||
- struct dsa_port *cpu_dp = dp->cpu_dp; | ||
struct mt7530_priv *priv = ds->priv; | ||
|
||
mutex_lock(&priv->reg_mutex); | ||
|
||
- dsa_switch_for_each_user_port(other_dp, ds) { | ||
- int other_port = other_dp->index; | ||
- | ||
- if (dp == other_dp) | ||
- continue; | ||
- | ||
- /* Remove this port from the port matrix of the other ports | ||
- * in the same bridge. If the port is disabled, port matrix | ||
- * is kept and not being setup until the port becomes enabled. | ||
- */ | ||
- if (!dsa_port_offloads_bridge(other_dp, &bridge)) | ||
- continue; | ||
- | ||
- if (priv->ports[other_port].enable) | ||
- mt7530_clear(priv, MT7530_PCR_P(other_port), | ||
- PCR_MATRIX(BIT(port))); | ||
- priv->ports[other_port].pm &= ~PCR_MATRIX(BIT(port)); | ||
- } | ||
- | ||
- /* Set the cpu port to be the only one in the port matrix of | ||
- * this port. | ||
- */ | ||
- if (priv->ports[port].enable) | ||
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, | ||
- PCR_MATRIX(BIT(cpu_dp->index))); | ||
- priv->ports[port].pm = PCR_MATRIX(BIT(cpu_dp->index)); | ||
+ mt7530_update_port_member(priv, port, bridge.dev, false); | ||
|
||
/* When a port is removed from the bridge, the port would be set up | ||
* back to the default as is at initial boot which is a VLAN-unaware |
79 changes: 79 additions & 0 deletions
79
...eric/backport-6.6/790-56-v6.11-net-dsa-mt7530-add-support-for-bridge-port-isolation.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
From 3d49ee2127c26fd2c77944fd2e3168c057f99439 Mon Sep 17 00:00:00 2001 | ||
From: Matthias Schiffer <mschiffer@universe-factory.net> | ||
Date: Tue, 18 Jun 2024 09:17:13 +0200 | ||
Subject: [PATCH 2/2] net: dsa: mt7530: add support for bridge port isolation | ||
MIME-Version: 1.0 | ||
Content-Type: text/plain; charset=UTF-8 | ||
Content-Transfer-Encoding: 8bit | ||
|
||
Remove a pair of ports from the port matrix when both ports have the | ||
isolated flag set. | ||
|
||
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net> | ||
Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com> | ||
Reviewed-by: Arınç ÜNAL <arinc.unal@arinc9.com> | ||
Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com> | ||
Signed-off-by: David S. Miller <davem@davemloft.net> | ||
--- | ||
drivers/net/dsa/mt7530.c | 18 ++++++++++++++++-- | ||
drivers/net/dsa/mt7530.h | 1 + | ||
2 files changed, 17 insertions(+), 2 deletions(-) | ||
|
||
--- a/drivers/net/dsa/mt7530.c | ||
+++ b/drivers/net/dsa/mt7530.c | ||
@@ -1311,6 +1311,7 @@ static void mt7530_update_port_member(st | ||
struct dsa_port *cpu_dp = dp->cpu_dp; | ||
u32 port_bitmap = BIT(cpu_dp->index); | ||
int other_port; | ||
+ bool isolated; | ||
|
||
dsa_switch_for_each_user_port(other_dp, priv->ds) { | ||
other_port = other_dp->index; | ||
@@ -1327,7 +1328,9 @@ static void mt7530_update_port_member(st | ||
if (!dsa_port_offloads_bridge_dev(other_dp, bridge_dev)) | ||
continue; | ||
|
||
- if (join) { | ||
+ isolated = p->isolated && other_p->isolated; | ||
+ | ||
+ if (join && !isolated) { | ||
other_p->pm |= PCR_MATRIX(BIT(port)); | ||
port_bitmap |= BIT(other_port); | ||
} else { | ||
@@ -1354,7 +1357,7 @@ mt7530_port_pre_bridge_flags(struct dsa_ | ||
struct netlink_ext_ack *extack) | ||
{ | ||
if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | | ||
- BR_BCAST_FLOOD)) | ||
+ BR_BCAST_FLOOD | BR_ISOLATED)) | ||
return -EINVAL; | ||
|
||
return 0; | ||
@@ -1383,6 +1386,17 @@ mt7530_port_bridge_flags(struct dsa_swit | ||
mt7530_rmw(priv, MT753X_MFC, BC_FFP(BIT(port)), | ||
flags.val & BR_BCAST_FLOOD ? BC_FFP(BIT(port)) : 0); | ||
|
||
+ if (flags.mask & BR_ISOLATED) { | ||
+ struct dsa_port *dp = dsa_to_port(ds, port); | ||
+ struct net_device *bridge_dev = dsa_port_bridge_dev_get(dp); | ||
+ | ||
+ priv->ports[port].isolated = !!(flags.val & BR_ISOLATED); | ||
+ | ||
+ mutex_lock(&priv->reg_mutex); | ||
+ mt7530_update_port_member(priv, port, bridge_dev, true); | ||
+ mutex_unlock(&priv->reg_mutex); | ||
+ } | ||
+ | ||
return 0; | ||
} | ||
|
||
--- a/drivers/net/dsa/mt7530.h | ||
+++ b/drivers/net/dsa/mt7530.h | ||
@@ -721,6 +721,7 @@ struct mt7530_fdb { | ||
*/ | ||
struct mt7530_port { | ||
bool enable; | ||
+ bool isolated; | ||
u32 pm; | ||
u16 pvid; | ||
struct phylink_pcs *sgmii_pcs; |