aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Oltean2021-07-29 00:54:27 +0300
committerDavid S. Miller2021-07-29 15:35:01 +0100
commitcde8078e83e32022e30a4f670c2c8179f2f08991 (patch)
treeac1703ec8d6c265772803f67f03ab3469fe1dbb4
parente5fe3a5fe333b9967eeb99966bcf3ec710318554 (diff)
net: dsa: sja1105: reset the port pvid when leaving a VLAN-aware bridge
Now that we no longer have the ultra-central sja1105_build_vlan_table(), we need to be more careful about checking all corner cases manually. For example, when a port leaves a VLAN-aware bridge, it becomes standalone so its pvid should become a tag_8021q RX VLAN again. However, sja1105_commit_pvid() only gets called from sja1105_bridge_vlan_add() and from sja1105_vlan_filtering(), and no VLAN awareness change takes place (VLAN filtering is a global setting for sja1105, so the switch remains VLAN-aware overall). This means that we need to put another sja1105_commit_pvid() call in sja1105_bridge_member(). Fixes: 6dfd23d35e75 ("net: dsa: sja1105: delete vlan delta save/restore logic") Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/dsa/sja1105/sja1105_main.c62
1 files changed, 33 insertions, 29 deletions
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 3047704c24d3..293c77622657 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -57,6 +57,35 @@ static bool sja1105_can_forward(struct sja1105_l2_forwarding_entry *l2_fwd,
return !!(l2_fwd[from].reach_port & BIT(to));
}
+static int sja1105_pvid_apply(struct sja1105_private *priv, int port, u16 pvid)
+{
+ struct sja1105_mac_config_entry *mac;
+
+ mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
+
+ if (mac[port].vlanid == pvid)
+ return 0;
+
+ mac[port].vlanid = pvid;
+
+ return sja1105_dynamic_config_write(priv, BLK_IDX_MAC_CONFIG, port,
+ &mac[port], true);
+}
+
+static int sja1105_commit_pvid(struct dsa_switch *ds, int port)
+{
+ struct dsa_port *dp = dsa_to_port(ds, port);
+ struct sja1105_private *priv = ds->priv;
+ u16 pvid;
+
+ if (dp->bridge_dev && br_vlan_enabled(dp->bridge_dev))
+ pvid = priv->bridge_pvid[port];
+ else
+ pvid = priv->tag_8021q_pvid[port];
+
+ return sja1105_pvid_apply(priv, port, pvid);
+}
+
static int sja1105_init_mac_settings(struct sja1105_private *priv)
{
struct sja1105_mac_config_entry default_mac = {
@@ -1656,6 +1685,10 @@ static int sja1105_bridge_member(struct dsa_switch *ds, int port,
if (rc)
return rc;
+ rc = sja1105_commit_pvid(ds, port);
+ if (rc)
+ return rc;
+
return sja1105_manage_flood_domains(priv);
}
@@ -1955,35 +1988,6 @@ out:
return rc;
}
-static int sja1105_pvid_apply(struct sja1105_private *priv, int port, u16 pvid)
-{
- struct sja1105_mac_config_entry *mac;
-
- mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
-
- if (mac[port].vlanid == pvid)
- return 0;
-
- mac[port].vlanid = pvid;
-
- return sja1105_dynamic_config_write(priv, BLK_IDX_MAC_CONFIG, port,
- &mac[port], true);
-}
-
-static int sja1105_commit_pvid(struct dsa_switch *ds, int port)
-{
- struct dsa_port *dp = dsa_to_port(ds, port);
- struct sja1105_private *priv = ds->priv;
- u16 pvid;
-
- if (dp->bridge_dev && br_vlan_enabled(dp->bridge_dev))
- pvid = priv->bridge_pvid[port];
- else
- pvid = priv->tag_8021q_pvid[port];
-
- return sja1105_pvid_apply(priv, port, pvid);
-}
-
static enum dsa_tag_protocol
sja1105_get_tag_protocol(struct dsa_switch *ds, int port,
enum dsa_tag_protocol mp)