]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: dsa: lantiq_gswip: permit dynamic changes to VLAN filtering state
authorVladimir Oltean <vladimir.oltean@nxp.com>
Wed, 15 Oct 2025 22:32:58 +0000 (23:32 +0100)
committerJakub Kicinski <kuba@kernel.org>
Sat, 18 Oct 2025 00:54:59 +0000 (17:54 -0700)
The driver should now tolerate these changes, now that the PVID is
automatically recalculated on a VLAN awareness state change.

The VLAN-unaware PVID must be installed to hardware even if the
joined bridge is currently VLAN-aware. Otherwise, when the bridge VLAN
filtering state dynamically changes to VLAN-unaware later, this PVID
will be missing.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://patch.msgid.link/c58759074fb699581336dc2c2c6bf106257b134e.1760566491.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/dsa/lantiq/lantiq_gswip.c
drivers/net/dsa/lantiq/lantiq_gswip.h

index 30cff623bec0c6aa1332b84480f249eb84e175bc..58fdd54094d65f0d72772f29455322f8fd998208 100644 (file)
@@ -590,16 +590,8 @@ static int gswip_port_vlan_filtering(struct dsa_switch *ds, int port,
                                     bool vlan_filtering,
                                     struct netlink_ext_ack *extack)
 {
-       struct net_device *bridge = dsa_port_bridge_dev_get(dsa_to_port(ds, port));
        struct gswip_priv *priv = ds->priv;
 
-       /* Do not allow changing the VLAN filtering options while in bridge */
-       if (bridge && !!(priv->port_vlan_filter & BIT(port)) != vlan_filtering) {
-               NL_SET_ERR_MSG_MOD(extack,
-                                  "Dynamic toggling of vlan_filtering not supported");
-               return -EIO;
-       }
-
        if (vlan_filtering) {
                /* Use tag based VLAN */
                gswip_switch_mask(priv,
@@ -927,18 +919,15 @@ static int gswip_port_bridge_join(struct dsa_switch *ds, int port,
        struct gswip_priv *priv = ds->priv;
        int err;
 
-       /* When the bridge uses VLAN filtering we have to configure VLAN
-        * specific bridges. No bridge is configured here.
+       /* Set up the VLAN for VLAN-unaware bridging for this port, and remove
+        * it from the "single-port bridge" through which it was operating as
+        * standalone.
         */
-       if (!br_vlan_enabled(br)) {
-               err = gswip_vlan_add(priv, br, port, GSWIP_VLAN_UNAWARE_PVID,
-                                    true, true, false);
-               if (err)
-                       return err;
-               priv->port_vlan_filter &= ~BIT(port);
-       } else {
-               priv->port_vlan_filter |= BIT(port);
-       }
+       err = gswip_vlan_add(priv, br, port, GSWIP_VLAN_UNAWARE_PVID,
+                            true, true, false);
+       if (err)
+               return err;
+
        return gswip_add_single_port_br(priv, port, false);
 }
 
@@ -948,14 +937,11 @@ static void gswip_port_bridge_leave(struct dsa_switch *ds, int port,
        struct net_device *br = bridge.dev;
        struct gswip_priv *priv = ds->priv;
 
-       gswip_add_single_port_br(priv, port, true);
-
-       /* When the bridge uses VLAN filtering we have to configure VLAN
-        * specific bridges. No bridge is configured here.
+       /* Add the port back to the "single-port bridge", and remove it from
+        * the VLAN-unaware PVID created for this bridge.
         */
-       if (!br_vlan_enabled(br))
-               gswip_vlan_remove(priv, br, port, GSWIP_VLAN_UNAWARE_PVID, true,
-                                 false);
+       gswip_add_single_port_br(priv, port, true);
+       gswip_vlan_remove(priv, br, port, GSWIP_VLAN_UNAWARE_PVID, true, false);
 }
 
 static int gswip_port_vlan_prepare(struct dsa_switch *ds, int port,
index 6aae1ff2f130f95165e681ba4772c47c5cadc85e..4590a1a7dbd9b4e39480f7d9043fca12b29c5a42 100644 (file)
@@ -270,7 +270,6 @@ struct gswip_priv {
        struct gswip_vlan vlans[64];
        int num_gphy_fw;
        struct gswip_gphy_fw *gphy_fw;
-       u32 port_vlan_filter;
        struct mutex pce_table_lock;
        u16 version;
 };