diff options
author | Vladimir Oltean <vladimir.oltean@nxp.com> | 2019-11-09 15:02:48 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-11-11 12:59:09 -0800 |
commit | 9855934c27855002aa977bb879c6e1fe74ee5f03 (patch) | |
tree | 446ced278860455474491568d060b9a98003fa25 /drivers/net/ethernet/mscc | |
parent | 97bb69e1e36e960b0ecfa2be5ea75ec357a61c3f (diff) | |
download | linux-9855934c27855002aa977bb879c6e1fe74ee5f03.tar.bz2 |
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.c | 60 |
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; |