cddd459140
Add patches for linux-5.4. The patches are from NXP LSDK-20.04 release which was tagged LSDK-20.04-V5.4. https://source.codeaurora.org/external/qoriq/qoriq-components/linux/ For boards LS1021A-IOT, and Traverse-LS1043 which are not involved in LSDK, port the dts patches from 4.14. The patches are sorted into the following categories: 301-arch-xxxx 302-dts-xxxx 303-core-xxxx 701-net-xxxx 801-audio-xxxx 802-can-xxxx 803-clock-xxxx 804-crypto-xxxx 805-display-xxxx 806-dma-xxxx 807-gpio-xxxx 808-i2c-xxxx 809-jailhouse-xxxx 810-keys-xxxx 811-kvm-xxxx 812-pcie-xxxx 813-pm-xxxx 814-qe-xxxx 815-sata-xxxx 816-sdhc-xxxx 817-spi-xxxx 818-thermal-xxxx 819-uart-xxxx 820-usb-xxxx 821-vfio-xxxx Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
315 lines
9.8 KiB
Diff
315 lines
9.8 KiB
Diff
From d00ac78e74e433109307f365ba90d34cd73aaf20 Mon Sep 17 00:00:00 2001
|
|
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
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 <vladimir.oltean@nxp.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
---
|
|
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)
|
|
@@ -2011,6 +2034,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));
|
|
@@ -2046,7 +2070,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);
|