123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- From d00ac78e74e433109307f365ba90d34cd73aaf20 Mon Sep 17 00:00:00 2001
- From: Vladimir Oltean <[email protected]>
- Date: Sat, 9 Nov 2019 15:02:47 +0200
- Subject: [PATCH] net: mscc: ocelot: break apart ocelot_vlan_port_apply
- This patch transforms the ocelot_vlan_port_apply function ("apply
- what?") into 3 standalone functions:
- - ocelot_port_vlan_filtering
- - ocelot_port_set_native_vlan
- - ocelot_port_set_pvid
- These functions have a prototype that is better aligned to the DSA API.
- The function also had some static initialization (TPID, drop frames with
- multicast source MAC) which was not being changed from any place, so
- that was just moved to ocelot_probe_port (one of the 6 callers of
- ocelot_vlan_port_apply).
- Signed-off-by: Vladimir Oltean <[email protected]>
- Signed-off-by: David S. Miller <[email protected]>
- ---
- drivers/net/ethernet/mscc/ocelot.c | 168 ++++++++++++++++++++++---------------
- 1 file changed, 100 insertions(+), 68 deletions(-)
- --- a/drivers/net/ethernet/mscc/ocelot.c
- +++ b/drivers/net/ethernet/mscc/ocelot.c
- @@ -185,65 +185,97 @@ static void ocelot_vlan_mode(struct ocel
- ocelot_write(ocelot, val, ANA_VLANMASK);
- }
-
- -static void ocelot_vlan_port_apply(struct ocelot *ocelot,
- - struct ocelot_port *port)
- +static void ocelot_port_vlan_filtering(struct ocelot *ocelot, int port,
- + bool vlan_aware)
- {
- + struct ocelot_port *ocelot_port = ocelot->ports[port];
- u32 val;
-
- - /* Ingress clasification (ANA_PORT_VLAN_CFG) */
- - /* Default vlan to clasify for untagged frames (may be zero) */
- - val = ANA_PORT_VLAN_CFG_VLAN_VID(port->pvid);
- - if (port->vlan_aware)
- - val |= ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
- - ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1);
- -
- + if (vlan_aware)
- + val = ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
- + ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1);
- + else
- + val = 0;
- ocelot_rmw_gix(ocelot, val,
- - ANA_PORT_VLAN_CFG_VLAN_VID_M |
- ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
- ANA_PORT_VLAN_CFG_VLAN_POP_CNT_M,
- - ANA_PORT_VLAN_CFG, port->chip_port);
- + ANA_PORT_VLAN_CFG, port);
-
- - /* Drop frames with multicast source address */
- - val = ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA;
- - if (port->vlan_aware && !port->vid)
- + if (vlan_aware && !ocelot_port->vid)
- /* If port is vlan-aware and tagged, drop untagged and priority
- * tagged frames.
- */
- - val |= ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA |
- + val = ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA |
- + ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA |
- + ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA;
- + else
- + val = 0;
- + ocelot_rmw_gix(ocelot, val,
- + ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA |
- ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA |
- - ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA;
- - ocelot_write_gix(ocelot, val, ANA_PORT_DROP_CFG, port->chip_port);
- -
- - /* Egress configuration (REW_TAG_CFG): VLAN tag type to 8021Q. */
- - val = REW_TAG_CFG_TAG_TPID_CFG(0);
- + ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA,
- + ANA_PORT_DROP_CFG, port);
-
- - if (port->vlan_aware) {
- - if (port->vid)
- + if (vlan_aware) {
- + if (ocelot_port->vid)
- /* Tag all frames except when VID == DEFAULT_VLAN */
- val |= REW_TAG_CFG_TAG_CFG(1);
- else
- /* Tag all frames */
- val |= REW_TAG_CFG_TAG_CFG(3);
- + } else {
- + /* Port tagging disabled. */
- + val = REW_TAG_CFG_TAG_CFG(0);
- }
- ocelot_rmw_gix(ocelot, val,
- - REW_TAG_CFG_TAG_TPID_CFG_M |
- REW_TAG_CFG_TAG_CFG_M,
- - REW_TAG_CFG, port->chip_port);
- + REW_TAG_CFG, port);
-
- - /* Set default VLAN and tag type to 8021Q. */
- - val = REW_PORT_VLAN_CFG_PORT_TPID(ETH_P_8021Q) |
- - REW_PORT_VLAN_CFG_PORT_VID(port->vid);
- - ocelot_rmw_gix(ocelot, val,
- - REW_PORT_VLAN_CFG_PORT_TPID_M |
- + ocelot_port->vlan_aware = vlan_aware;
- +}
- +
- +static int ocelot_port_set_native_vlan(struct ocelot *ocelot, int port,
- + u16 vid)
- +{
- + struct ocelot_port *ocelot_port = ocelot->ports[port];
- +
- + if (ocelot_port->vid != vid) {
- + /* Always permit deleting the native VLAN (vid = 0) */
- + if (ocelot_port->vid && vid) {
- + dev_err(ocelot->dev,
- + "Port already has a native VLAN: %d\n",
- + ocelot_port->vid);
- + return -EBUSY;
- + }
- + ocelot_port->vid = vid;
- + }
- +
- + ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_VID(vid),
- REW_PORT_VLAN_CFG_PORT_VID_M,
- - REW_PORT_VLAN_CFG, port->chip_port);
- + REW_PORT_VLAN_CFG, port);
- +
- + return 0;
- +}
- +
- +/* Default vlan to clasify for untagged frames (may be zero) */
- +static void ocelot_port_set_pvid(struct ocelot *ocelot, int port, u16 pvid)
- +{
- + struct ocelot_port *ocelot_port = ocelot->ports[port];
- +
- + ocelot_rmw_gix(ocelot,
- + ANA_PORT_VLAN_CFG_VLAN_VID(pvid),
- + ANA_PORT_VLAN_CFG_VLAN_VID_M,
- + ANA_PORT_VLAN_CFG, port);
- +
- + ocelot_port->pvid = pvid;
- }
-
- static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid,
- bool untagged)
- {
- - struct ocelot_port *port = netdev_priv(dev);
- - struct ocelot *ocelot = port->ocelot;
- + 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 */
- @@ -251,35 +283,30 @@ static int ocelot_vlan_vid_add(struct ne
- ENTRYTYPE_LOCKED);
-
- /* Make the port a member of the VLAN */
- - ocelot->vlan_mask[vid] |= BIT(port->chip_port);
- + ocelot->vlan_mask[vid] |= BIT(port);
- ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]);
- if (ret)
- return ret;
-
- /* Default ingress vlan classification */
- if (pvid)
- - port->pvid = vid;
- + ocelot_port_set_pvid(ocelot, port, vid);
-
- /* Untagged egress vlan clasification */
- - if (untagged && port->vid != vid) {
- - if (port->vid) {
- - dev_err(ocelot->dev,
- - "Port already has a native VLAN: %d\n",
- - port->vid);
- - return -EBUSY;
- - }
- - port->vid = vid;
- + if (untagged) {
- + ret = ocelot_port_set_native_vlan(ocelot, port, vid);
- + if (ret)
- + return ret;
- }
-
- - ocelot_vlan_port_apply(ocelot, port);
- -
- return 0;
- }
-
- static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid)
- {
- - struct ocelot_port *port = netdev_priv(dev);
- - struct ocelot *ocelot = port->ocelot;
- + 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
- @@ -293,20 +320,18 @@ static int ocelot_vlan_vid_del(struct ne
- ocelot_mact_forget(ocelot, dev->dev_addr, vid);
-
- /* Stop the port from being a member of the vlan */
- - ocelot->vlan_mask[vid] &= ~BIT(port->chip_port);
- + ocelot->vlan_mask[vid] &= ~BIT(port);
- ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]);
- if (ret)
- return ret;
-
- /* Ingress */
- - if (port->pvid == vid)
- - port->pvid = 0;
- + if (ocelot_port->pvid == vid)
- + ocelot_port_set_pvid(ocelot, port, 0);
-
- /* Egress */
- - if (port->vid == vid)
- - port->vid = 0;
- -
- - ocelot_vlan_port_apply(ocelot, port);
- + if (ocelot_port->vid == vid)
- + ocelot_port_set_native_vlan(ocelot, port, 0);
-
- return 0;
- }
- @@ -1306,6 +1331,7 @@ static int ocelot_port_attr_set(struct n
- struct switchdev_trans *trans)
- {
- struct ocelot_port *ocelot_port = netdev_priv(dev);
- + struct ocelot *ocelot = ocelot_port->ocelot;
- int err = 0;
-
- switch (attr->id) {
- @@ -1317,8 +1343,8 @@ static int ocelot_port_attr_set(struct n
- ocelot_port_attr_ageing_set(ocelot_port, attr->u.ageing_time);
- break;
- case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
- - ocelot_port->vlan_aware = attr->u.vlan_filtering;
- - ocelot_vlan_port_apply(ocelot_port->ocelot, ocelot_port);
- + ocelot_port_vlan_filtering(ocelot, ocelot_port->chip_port,
- + attr->u.vlan_filtering);
- break;
- case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
- ocelot_port_attr_mc_set(ocelot_port, !attr->u.mc_disabled);
- @@ -1520,20 +1546,20 @@ static int ocelot_port_bridge_join(struc
- return 0;
- }
-
- -static void ocelot_port_bridge_leave(struct ocelot_port *ocelot_port,
- - struct net_device *bridge)
- +static int ocelot_port_bridge_leave(struct ocelot_port *ocelot_port,
- + struct net_device *bridge)
- {
- struct ocelot *ocelot = ocelot_port->ocelot;
- + int port = ocelot_port->chip_port;
-
- - ocelot->bridge_mask &= ~BIT(ocelot_port->chip_port);
- + ocelot->bridge_mask &= ~BIT(port);
-
- if (!ocelot->bridge_mask)
- ocelot->hw_bridge_dev = NULL;
-
- - /* Clear bridge vlan settings before calling ocelot_vlan_port_apply */
- - ocelot_port->vlan_aware = 0;
- - ocelot_port->pvid = 0;
- - ocelot_port->vid = 0;
- + ocelot_port_vlan_filtering(ocelot, port, 0);
- + ocelot_port_set_pvid(ocelot, port, 0);
- + return ocelot_port_set_native_vlan(ocelot, port, 0);
- }
-
- static void ocelot_set_aggr_pgids(struct ocelot *ocelot)
- @@ -1687,11 +1713,8 @@ static int ocelot_netdevice_port_event(s
- err = ocelot_port_bridge_join(ocelot_port,
- info->upper_dev);
- else
- - ocelot_port_bridge_leave(ocelot_port,
- - info->upper_dev);
- -
- - ocelot_vlan_port_apply(ocelot_port->ocelot,
- - ocelot_port);
- + err = ocelot_port_bridge_leave(ocelot_port,
- + info->upper_dev);
- }
- if (netif_is_lag_master(info->upper_dev)) {
- if (info->linking)
- @@ -2009,6 +2032,7 @@ int ocelot_probe_port(struct ocelot *oce
- {
- struct ocelot_port *ocelot_port;
- struct net_device *dev;
- + u32 val;
- int err;
-
- dev = alloc_etherdev(sizeof(struct ocelot_port));
- @@ -2044,7 +2068,15 @@ int ocelot_probe_port(struct ocelot *oce
- }
-
- /* Basic L2 initialization */
- - ocelot_vlan_port_apply(ocelot, ocelot_port);
- +
- + /* Drop frames with multicast source address */
- + val = ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA;
- + ocelot_rmw_gix(ocelot, val, val, ANA_PORT_DROP_CFG, port);
- +
- + /* Set default VLAN and tag type to 8021Q. */
- + ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_TPID(ETH_P_8021Q),
- + REW_PORT_VLAN_CFG_PORT_TPID_M,
- + REW_PORT_VLAN_CFG, port);
-
- /* Enable vcap lookups */
- ocelot_vcap_enable(ocelot, ocelot_port);
|