summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mscc/ocelot.c27
-rw-r--r--include/soc/mscc/ocelot.h1
2 files changed, 15 insertions, 13 deletions
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index a7e724ae01f7..d49e34430e23 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -153,22 +153,22 @@ static int ocelot_port_set_native_vlan(struct ocelot *ocelot, int port,
struct ocelot_port *ocelot_port = ocelot->ports[port];
u32 val = 0;
- if (ocelot_port->native_vlan.vid != native_vlan.vid) {
- /* Always permit deleting the native VLAN (vid = 0) */
- if (ocelot_port->native_vlan.vid && native_vlan.vid) {
- dev_err(ocelot->dev,
- "Port already has a native VLAN: %d\n",
- ocelot_port->native_vlan.vid);
- return -EBUSY;
- }
- ocelot_port->native_vlan = native_vlan;
+ /* Deny changing the native VLAN, but always permit deleting it */
+ if (ocelot_port->native_vlan.vid != native_vlan.vid &&
+ ocelot_port->native_vlan.valid && native_vlan.valid) {
+ dev_err(ocelot->dev,
+ "Port already has a native VLAN: %d\n",
+ ocelot_port->native_vlan.vid);
+ return -EBUSY;
}
+ ocelot_port->native_vlan = native_vlan;
+
ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_VID(native_vlan.vid),
REW_PORT_VLAN_CFG_PORT_VID_M,
REW_PORT_VLAN_CFG, port);
- if (ocelot_port->vlan_aware && !ocelot_port->native_vlan.vid)
+ if (ocelot_port->vlan_aware && !ocelot_port->native_vlan.valid)
/* If port is vlan-aware and tagged, drop untagged and priority
* tagged frames.
*/
@@ -182,7 +182,7 @@ static int ocelot_port_set_native_vlan(struct ocelot *ocelot, int port,
ANA_PORT_DROP_CFG, port);
if (ocelot_port->vlan_aware) {
- if (ocelot_port->native_vlan.vid)
+ if (native_vlan.valid)
/* Tag all frames except when VID == DEFAULT_VLAN */
val = REW_TAG_CFG_TAG_CFG(1);
else
@@ -273,6 +273,7 @@ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
struct ocelot_vlan pvid_vlan;
pvid_vlan.vid = vid;
+ pvid_vlan.valid = true;
ocelot_port_set_pvid(ocelot, port, pvid_vlan);
}
@@ -281,6 +282,7 @@ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
struct ocelot_vlan native_vlan;
native_vlan.vid = vid;
+ native_vlan.valid = true;
ret = ocelot_port_set_native_vlan(ocelot, port, native_vlan);
if (ret)
return ret;
@@ -303,9 +305,8 @@ int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid)
/* Egress */
if (ocelot_port->native_vlan.vid == vid) {
- struct ocelot_vlan native_vlan;
+ struct ocelot_vlan native_vlan = {0};
- native_vlan.vid = 0;
ocelot_port_set_native_vlan(ocelot, port, native_vlan);
}
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index baf6a498f7d1..67c2af1c4c5c 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -572,6 +572,7 @@ struct ocelot_vcap_block {
};
struct ocelot_vlan {
+ bool valid;
u16 vid;
};