summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/mscc
diff options
context:
space:
mode:
authorVladimir Oltean <vladimir.oltean@nxp.com>2019-11-09 15:02:48 +0200
committerDavid S. Miller <davem@davemloft.net>2019-11-11 12:59:09 -0800
commit9855934c27855002aa977bb879c6e1fe74ee5f03 (patch)
tree446ced278860455474491568d060b9a98003fa25 /drivers/net/ethernet/mscc
parent97bb69e1e36e960b0ecfa2be5ea75ec357a61c3f (diff)
net: mscc: ocelot: break apart vlan operations into ocelot_vlan_{add, del}
We need an implementation of these functions that is agnostic to the higher layer (switchdev or dsa). Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mscc')
-rw-r--r--drivers/net/ethernet/mscc/ocelot.c60
1 files changed, 42 insertions, 18 deletions
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 029c5ea59e35..5b9cde6d3e38 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -270,18 +270,11 @@ static void ocelot_port_set_pvid(struct ocelot *ocelot, int port, u16 pvid)
ocelot_port->pvid = pvid;
}
-static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid,
- bool untagged)
+static int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
+ bool untagged)
{
- struct ocelot_port *ocelot_port = netdev_priv(dev);
- struct ocelot *ocelot = ocelot_port->ocelot;
- int port = ocelot_port->chip_port;
int ret;
- /* Add the port MAC address to with the right VLAN information */
- ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, vid,
- ENTRYTYPE_LOCKED);
-
/* Make the port a member of the VLAN */
ocelot->vlan_mask[vid] |= BIT(port);
ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]);
@@ -302,22 +295,29 @@ static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid,
return 0;
}
-static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid)
+static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid,
+ bool untagged)
{
struct ocelot_port *ocelot_port = netdev_priv(dev);
struct ocelot *ocelot = ocelot_port->ocelot;
int port = ocelot_port->chip_port;
int ret;
- /* 8021q removes VID 0 on module unload for all interfaces
- * with VLAN filtering feature. We need to keep it to receive
- * untagged traffic.
- */
- if (vid == 0)
- return 0;
+ ret = ocelot_vlan_add(ocelot, port, vid, pvid, untagged);
+ if (ret)
+ return ret;
- /* Del the port MAC address to with the right VLAN information */
- ocelot_mact_forget(ocelot, dev->dev_addr, vid);
+ /* Add the port MAC address to with the right VLAN information */
+ ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, vid,
+ ENTRYTYPE_LOCKED);
+
+ return 0;
+}
+
+static int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid)
+{
+ struct ocelot_port *ocelot_port = ocelot->ports[port];
+ int ret;
/* Stop the port from being a member of the vlan */
ocelot->vlan_mask[vid] &= ~BIT(port);
@@ -336,6 +336,30 @@ static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid)
return 0;
}
+static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid)
+{
+ struct ocelot_port *ocelot_port = netdev_priv(dev);
+ struct ocelot *ocelot = ocelot_port->ocelot;
+ int port = ocelot_port->chip_port;
+ int ret;
+
+ /* 8021q removes VID 0 on module unload for all interfaces
+ * with VLAN filtering feature. We need to keep it to receive
+ * untagged traffic.
+ */
+ if (vid == 0)
+ return 0;
+
+ ret = ocelot_vlan_del(ocelot, port, vid);
+ if (ret)
+ return ret;
+
+ /* Del the port MAC address to with the right VLAN information */
+ ocelot_mact_forget(ocelot, dev->dev_addr, vid);
+
+ return 0;
+}
+
static void ocelot_vlan_init(struct ocelot *ocelot)
{
u16 port, vid;