net: dsa: lantiq_gswip: permit dynamic changes to VLAN filtering state

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>
This commit is contained in:
Vladimir Oltean 2025-10-15 23:32:58 +01:00 committed by Jakub Kicinski
parent 21c3237c60
commit ab3ce58559
2 changed files with 12 additions and 27 deletions

View 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,

View 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;
};