summaryrefslogtreecommitdiff
path: root/drivers/net/dsa/qca/qca8k-common.c
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-06-20 20:25:50 +0300
committerDavid S. Miller <davem@davemloft.net>2024-06-21 14:22:59 +0300
commit422b64025ec10981c48f9367311846bf4bd38042 (patch)
tree99ba54f1cbd974b2e30bcac0cd50c4a374467083 /drivers/net/dsa/qca/qca8k-common.c
parent412e1775f413c944b8c51bdadb675be957d83dc8 (diff)
downloadlinux-422b64025ec10981c48f9367311846bf4bd38042.tar.xz
net: dsa: qca8k: add support for bridge port isolation
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> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/qca/qca8k-common.c')
-rw-r--r--drivers/net/dsa/qca/qca8k-common.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c
index 09108fa99dbe..560c74c4ac3d 100644
--- a/drivers/net/dsa/qca/qca8k-common.c
+++ b/drivers/net/dsa/qca/qca8k-common.c
@@ -618,6 +618,7 @@ static int qca8k_update_port_member(struct qca8k_priv *priv, int port,
const struct net_device *bridge_dev,
bool join)
{
+ bool isolated = !!(priv->port_isolated_map & BIT(port)), other_isolated;
struct dsa_port *dp = dsa_to_port(priv->ds, port), *other_dp;
u32 port_mask = BIT(dp->cpu_dp->index);
int i, ret;
@@ -632,10 +633,12 @@ static int qca8k_update_port_member(struct qca8k_priv *priv, int port,
if (!dsa_port_offloads_bridge_dev(other_dp, bridge_dev))
continue;
+ other_isolated = !!(priv->port_isolated_map & BIT(i));
+
/* Add/remove this port to/from the portvlan mask of the other
* ports in the bridge
*/
- if (join) {
+ if (join && !(isolated && other_isolated)) {
port_mask |= BIT(i);
ret = regmap_set_bits(priv->regmap,
QCA8K_PORT_LOOKUP_CTRL(i),
@@ -661,7 +664,7 @@ int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
struct switchdev_brport_flags flags,
struct netlink_ext_ack *extack)
{
- if (flags.mask & ~BR_LEARNING)
+ if (flags.mask & ~(BR_LEARNING | BR_ISOLATED))
return -EINVAL;
return 0;
@@ -671,6 +674,7 @@ int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
struct switchdev_brport_flags flags,
struct netlink_ext_ack *extack)
{
+ struct qca8k_priv *priv = ds->priv;
int ret;
if (flags.mask & BR_LEARNING) {
@@ -680,6 +684,20 @@ int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
return ret;
}
+ 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);
+
+ if (flags.val & BR_ISOLATED)
+ priv->port_isolated_map |= BIT(port);
+ else
+ priv->port_isolated_map &= ~BIT(port);
+
+ ret = qca8k_update_port_member(priv, port, bridge_dev, true);
+ if (ret)
+ return ret;
+ }
+
return 0;
}