Merge branch 'm7530-sw-fallback'
DENG Qingfang says:
====================
mt7530 software fallback bridging fix
DSA core has gained software fallback support since commit 2f5dc00f7a
,
but it does not work properly on mt7530. This patch series fixes the
issues.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
d851798584
|
@ -366,8 +366,8 @@ mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,
|
|||
int i;
|
||||
|
||||
reg[1] |= vid & CVID_MASK;
|
||||
if (vid > 1)
|
||||
reg[1] |= ATA2_IVL;
|
||||
reg[1] |= ATA2_IVL;
|
||||
reg[1] |= ATA2_FID(FID_BRIDGED);
|
||||
reg[2] |= (aging & AGE_TIMER_MASK) << AGE_TIMER;
|
||||
reg[2] |= (port_mask & PORT_MAP_MASK) << PORT_MAP;
|
||||
/* STATIC_ENT indicate that entry is static wouldn't
|
||||
|
@ -1021,6 +1021,10 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
|
|||
mt7530_write(priv, MT7530_PCR_P(port),
|
||||
PCR_MATRIX(dsa_user_ports(priv->ds)));
|
||||
|
||||
/* Set to fallback mode for independent VLAN learning */
|
||||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
|
||||
MT7530_PORT_FALLBACK_MODE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1143,7 +1147,8 @@ mt7530_stp_state_set(struct dsa_switch *ds, int port, u8 state)
|
|||
break;
|
||||
}
|
||||
|
||||
mt7530_rmw(priv, MT7530_SSP_P(port), FID_PST_MASK, stp_state);
|
||||
mt7530_rmw(priv, MT7530_SSP_P(port), FID_PST_MASK(FID_BRIDGED),
|
||||
FID_PST(FID_BRIDGED, stp_state));
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1229,6 +1234,10 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port,
|
|||
PCR_MATRIX_MASK, PCR_MATRIX(port_bitmap));
|
||||
priv->ports[port].pm |= PCR_MATRIX(port_bitmap);
|
||||
|
||||
/* Set to fallback mode for independent VLAN learning */
|
||||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
|
||||
MT7530_PORT_FALLBACK_MODE);
|
||||
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
|
||||
return 0;
|
||||
|
@ -1241,16 +1250,21 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port)
|
|||
bool all_user_ports_removed = true;
|
||||
int i;
|
||||
|
||||
/* When a port is removed from the bridge, the port would be set up
|
||||
* back to the default as is at initial boot which is a VLAN-unaware
|
||||
* port.
|
||||
/* This is called after .port_bridge_leave when leaving a VLAN-aware
|
||||
* bridge. Don't set standalone ports to fallback mode.
|
||||
*/
|
||||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
|
||||
MT7530_PORT_MATRIX_MODE);
|
||||
if (dsa_to_port(ds, port)->bridge_dev)
|
||||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
|
||||
MT7530_PORT_FALLBACK_MODE);
|
||||
|
||||
mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK | PVC_EG_TAG_MASK,
|
||||
VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |
|
||||
PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
|
||||
|
||||
/* Set PVID to 0 */
|
||||
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
|
||||
G0_PORT_VID_DEF);
|
||||
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
if (dsa_is_user_port(ds, i) &&
|
||||
dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) {
|
||||
|
@ -1276,15 +1290,14 @@ mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port)
|
|||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
/* Trapped into security mode allows packet forwarding through VLAN
|
||||
* table lookup. CPU port is set to fallback mode to let untagged
|
||||
* frames pass through.
|
||||
* table lookup.
|
||||
*/
|
||||
if (dsa_is_cpu_port(ds, port))
|
||||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
|
||||
MT7530_PORT_FALLBACK_MODE);
|
||||
else
|
||||
if (dsa_is_user_port(ds, port)) {
|
||||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
|
||||
MT7530_PORT_SECURITY_MODE);
|
||||
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
|
||||
G0_PORT_VID(priv->ports[port].pvid));
|
||||
}
|
||||
|
||||
/* Set the port as a user port which is to be able to recognize VID
|
||||
* from incoming packets before fetching entry within the VLAN table.
|
||||
|
@ -1329,6 +1342,13 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
|
|||
PCR_MATRIX(BIT(MT7530_CPU_PORT)));
|
||||
priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
|
||||
|
||||
/* When a port is removed from the bridge, the port would be set up
|
||||
* back to the default as is at initial boot which is a VLAN-unaware
|
||||
* port.
|
||||
*/
|
||||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
|
||||
MT7530_PORT_MATRIX_MODE);
|
||||
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
}
|
||||
|
||||
|
@ -1511,7 +1531,8 @@ mt7530_hw_vlan_add(struct mt7530_priv *priv,
|
|||
/* Validate the entry with independent learning, create egress tag per
|
||||
* VLAN and joining the port as one of the port members.
|
||||
*/
|
||||
val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | VLAN_VALID;
|
||||
val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | FID(FID_BRIDGED) |
|
||||
VLAN_VALID;
|
||||
mt7530_write(priv, MT7530_VAWD1, val);
|
||||
|
||||
/* Decide whether adding tag or not for those outgoing packets from the
|
||||
|
@ -1601,9 +1622,13 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port,
|
|||
mt7530_hw_vlan_update(priv, vlan->vid, &new_entry, mt7530_hw_vlan_add);
|
||||
|
||||
if (pvid) {
|
||||
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
|
||||
G0_PORT_VID(vlan->vid));
|
||||
priv->ports[port].pvid = vlan->vid;
|
||||
|
||||
/* Only configure PVID if VLAN filtering is enabled */
|
||||
if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
|
||||
mt7530_rmw(priv, MT7530_PPBV1_P(port),
|
||||
G0_PORT_VID_MASK,
|
||||
G0_PORT_VID(vlan->vid));
|
||||
}
|
||||
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
|
@ -1617,11 +1642,9 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
|
|||
{
|
||||
struct mt7530_hw_vlan_entry target_entry;
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
u16 pvid;
|
||||
|
||||
mutex_lock(&priv->reg_mutex);
|
||||
|
||||
pvid = priv->ports[port].pvid;
|
||||
mt7530_hw_vlan_entry_init(&target_entry, port, 0);
|
||||
mt7530_hw_vlan_update(priv, vlan->vid, &target_entry,
|
||||
mt7530_hw_vlan_del);
|
||||
|
@ -1629,11 +1652,12 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
|
|||
/* PVID is being restored to the default whenever the PVID port
|
||||
* is being removed from the VLAN.
|
||||
*/
|
||||
if (pvid == vlan->vid)
|
||||
pvid = G0_PORT_VID_DEF;
|
||||
if (priv->ports[port].pvid == vlan->vid) {
|
||||
priv->ports[port].pvid = G0_PORT_VID_DEF;
|
||||
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
|
||||
G0_PORT_VID_DEF);
|
||||
}
|
||||
|
||||
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, pvid);
|
||||
priv->ports[port].pvid = pvid;
|
||||
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
|
||||
|
@ -2046,6 +2070,7 @@ mt7530_setup(struct dsa_switch *ds)
|
|||
* as two netdev instances.
|
||||
*/
|
||||
dn = dsa_to_port(ds, MT7530_CPU_PORT)->master->dev.of_node->parent;
|
||||
ds->assisted_learning_on_cpu_port = true;
|
||||
ds->mtu_enforcement_ingress = true;
|
||||
|
||||
if (priv->id == ID_MT7530) {
|
||||
|
@ -2116,6 +2141,9 @@ mt7530_setup(struct dsa_switch *ds)
|
|||
mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
|
||||
PCR_MATRIX_CLR);
|
||||
|
||||
/* Disable learning by default on all ports */
|
||||
mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
|
||||
|
||||
if (dsa_is_cpu_port(ds, i)) {
|
||||
ret = mt753x_cpu_port_enable(ds, i);
|
||||
if (ret)
|
||||
|
@ -2123,8 +2151,9 @@ mt7530_setup(struct dsa_switch *ds)
|
|||
} else {
|
||||
mt7530_port_disable(ds, i);
|
||||
|
||||
/* Disable learning by default on all user ports */
|
||||
mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
|
||||
/* Set default PVID to 0 on all user ports */
|
||||
mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
|
||||
G0_PORT_VID_DEF);
|
||||
}
|
||||
/* Enable consistent egress tag */
|
||||
mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
|
||||
|
@ -2281,6 +2310,9 @@ mt7531_setup(struct dsa_switch *ds)
|
|||
mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
|
||||
PCR_MATRIX_CLR);
|
||||
|
||||
/* Disable learning by default on all ports */
|
||||
mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
|
||||
|
||||
mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
|
||||
|
||||
if (dsa_is_cpu_port(ds, i)) {
|
||||
|
@ -2290,8 +2322,9 @@ mt7531_setup(struct dsa_switch *ds)
|
|||
} else {
|
||||
mt7530_port_disable(ds, i);
|
||||
|
||||
/* Disable learning by default on all user ports */
|
||||
mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
|
||||
/* Set default PVID to 0 on all user ports */
|
||||
mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
|
||||
G0_PORT_VID_DEF);
|
||||
}
|
||||
|
||||
/* Enable consistent egress tag */
|
||||
|
@ -2299,6 +2332,7 @@ mt7531_setup(struct dsa_switch *ds)
|
|||
PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
|
||||
}
|
||||
|
||||
ds->assisted_learning_on_cpu_port = true;
|
||||
ds->mtu_enforcement_ingress = true;
|
||||
|
||||
/* Flush the FDB table */
|
||||
|
|
|
@ -80,6 +80,7 @@ enum mt753x_bpdu_port_fw {
|
|||
#define STATIC_ENT 3
|
||||
#define MT7530_ATA2 0x78
|
||||
#define ATA2_IVL BIT(15)
|
||||
#define ATA2_FID(x) (((x) & 0x7) << 12)
|
||||
|
||||
/* Register for address table write data */
|
||||
#define MT7530_ATWD 0x7c
|
||||
|
@ -148,11 +149,18 @@ enum mt7530_vlan_cmd {
|
|||
#define VTAG_EN BIT(28)
|
||||
/* VLAN Member Control */
|
||||
#define PORT_MEM(x) (((x) & 0xff) << 16)
|
||||
/* Filter ID */
|
||||
#define FID(x) (((x) & 0x7) << 1)
|
||||
/* VLAN Entry Valid */
|
||||
#define VLAN_VALID BIT(0)
|
||||
#define PORT_MEM_SHFT 16
|
||||
#define PORT_MEM_MASK 0xff
|
||||
|
||||
enum mt7530_fid {
|
||||
FID_STANDALONE = 0,
|
||||
FID_BRIDGED = 1,
|
||||
};
|
||||
|
||||
#define MT7530_VAWD2 0x98
|
||||
/* Egress Tag Control */
|
||||
#define ETAG_CTRL_P(p, x) (((x) & 0x3) << ((p) << 1))
|
||||
|
@ -179,8 +187,8 @@ enum mt7530_vlan_egress_attr {
|
|||
|
||||
/* Register for port STP state control */
|
||||
#define MT7530_SSP_P(x) (0x2000 + ((x) * 0x100))
|
||||
#define FID_PST(x) ((x) & 0x3)
|
||||
#define FID_PST_MASK FID_PST(0x3)
|
||||
#define FID_PST(fid, state) (((state) & 0x3) << ((fid) * 2))
|
||||
#define FID_PST_MASK(fid) FID_PST(fid, 0x3)
|
||||
|
||||
enum mt7530_stp_state {
|
||||
MT7530_STP_DISABLED = 0,
|
||||
|
@ -247,7 +255,7 @@ enum mt7530_vlan_port_attr {
|
|||
#define MT7530_PPBV1_P(x) (0x2014 + ((x) * 0x100))
|
||||
#define G0_PORT_VID(x) (((x) & 0xfff) << 0)
|
||||
#define G0_PORT_VID_MASK G0_PORT_VID(0xfff)
|
||||
#define G0_PORT_VID_DEF G0_PORT_VID(1)
|
||||
#define G0_PORT_VID_DEF G0_PORT_VID(0)
|
||||
|
||||
/* Register for port MAC control register */
|
||||
#define MT7530_PMCR_P(x) (0x3000 + ((x) * 0x100))
|
||||
|
|
Loading…
Reference in New Issue