mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-29 16:25:42 -04:00
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: 6dfd23d35e ("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>
This commit is contained in:
committed by
David S. Miller
parent
e5fe3a5fe3
commit
cde8078e83
@@ -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 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user