Skip to content

Commit d851798

Browse files
committed
Merge branch 'm7530-sw-fallback'
DENG Qingfang says: ==================== mt7530 software fallback bridging fix DSA core has gained software fallback support since commit 2f5dc00, but it does not work properly on mt7530. This patch series fixes the issues. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 8eceea4 + 73c447c commit d851798

File tree

2 files changed

+72
-30
lines changed

2 files changed

+72
-30
lines changed

drivers/net/dsa/mt7530.c

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,8 @@ mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,
366366
int i;
367367

368368
reg[1] |= vid & CVID_MASK;
369-
if (vid > 1)
370-
reg[1] |= ATA2_IVL;
369+
reg[1] |= ATA2_IVL;
370+
reg[1] |= ATA2_FID(FID_BRIDGED);
371371
reg[2] |= (aging & AGE_TIMER_MASK) << AGE_TIMER;
372372
reg[2] |= (port_mask & PORT_MAP_MASK) << PORT_MAP;
373373
/* STATIC_ENT indicate that entry is static wouldn't
@@ -1021,6 +1021,10 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
10211021
mt7530_write(priv, MT7530_PCR_P(port),
10221022
PCR_MATRIX(dsa_user_ports(priv->ds)));
10231023

1024+
/* Set to fallback mode for independent VLAN learning */
1025+
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
1026+
MT7530_PORT_FALLBACK_MODE);
1027+
10241028
return 0;
10251029
}
10261030

@@ -1143,7 +1147,8 @@ mt7530_stp_state_set(struct dsa_switch *ds, int port, u8 state)
11431147
break;
11441148
}
11451149

1146-
mt7530_rmw(priv, MT7530_SSP_P(port), FID_PST_MASK, stp_state);
1150+
mt7530_rmw(priv, MT7530_SSP_P(port), FID_PST_MASK(FID_BRIDGED),
1151+
FID_PST(FID_BRIDGED, stp_state));
11471152
}
11481153

11491154
static int
@@ -1229,6 +1234,10 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port,
12291234
PCR_MATRIX_MASK, PCR_MATRIX(port_bitmap));
12301235
priv->ports[port].pm |= PCR_MATRIX(port_bitmap);
12311236

1237+
/* Set to fallback mode for independent VLAN learning */
1238+
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
1239+
MT7530_PORT_FALLBACK_MODE);
1240+
12321241
mutex_unlock(&priv->reg_mutex);
12331242

12341243
return 0;
@@ -1241,16 +1250,21 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port)
12411250
bool all_user_ports_removed = true;
12421251
int i;
12431252

1244-
/* When a port is removed from the bridge, the port would be set up
1245-
* back to the default as is at initial boot which is a VLAN-unaware
1246-
* port.
1253+
/* This is called after .port_bridge_leave when leaving a VLAN-aware
1254+
* bridge. Don't set standalone ports to fallback mode.
12471255
*/
1248-
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
1249-
MT7530_PORT_MATRIX_MODE);
1256+
if (dsa_to_port(ds, port)->bridge_dev)
1257+
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
1258+
MT7530_PORT_FALLBACK_MODE);
1259+
12501260
mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK | PVC_EG_TAG_MASK,
12511261
VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |
12521262
PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
12531263

1264+
/* Set PVID to 0 */
1265+
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
1266+
G0_PORT_VID_DEF);
1267+
12541268
for (i = 0; i < MT7530_NUM_PORTS; i++) {
12551269
if (dsa_is_user_port(ds, i) &&
12561270
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)
12761290
struct mt7530_priv *priv = ds->priv;
12771291

12781292
/* Trapped into security mode allows packet forwarding through VLAN
1279-
* table lookup. CPU port is set to fallback mode to let untagged
1280-
* frames pass through.
1293+
* table lookup.
12811294
*/
1282-
if (dsa_is_cpu_port(ds, port))
1283-
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
1284-
MT7530_PORT_FALLBACK_MODE);
1285-
else
1295+
if (dsa_is_user_port(ds, port)) {
12861296
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
12871297
MT7530_PORT_SECURITY_MODE);
1298+
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
1299+
G0_PORT_VID(priv->ports[port].pvid));
1300+
}
12881301

12891302
/* Set the port as a user port which is to be able to recognize VID
12901303
* from incoming packets before fetching entry within the VLAN table.
@@ -1329,6 +1342,13 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
13291342
PCR_MATRIX(BIT(MT7530_CPU_PORT)));
13301343
priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
13311344

1345+
/* When a port is removed from the bridge, the port would be set up
1346+
* back to the default as is at initial boot which is a VLAN-unaware
1347+
* port.
1348+
*/
1349+
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
1350+
MT7530_PORT_MATRIX_MODE);
1351+
13321352
mutex_unlock(&priv->reg_mutex);
13331353
}
13341354

@@ -1511,7 +1531,8 @@ mt7530_hw_vlan_add(struct mt7530_priv *priv,
15111531
/* Validate the entry with independent learning, create egress tag per
15121532
* VLAN and joining the port as one of the port members.
15131533
*/
1514-
val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | VLAN_VALID;
1534+
val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | FID(FID_BRIDGED) |
1535+
VLAN_VALID;
15151536
mt7530_write(priv, MT7530_VAWD1, val);
15161537

15171538
/* 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,
16011622
mt7530_hw_vlan_update(priv, vlan->vid, &new_entry, mt7530_hw_vlan_add);
16021623

16031624
if (pvid) {
1604-
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
1605-
G0_PORT_VID(vlan->vid));
16061625
priv->ports[port].pvid = vlan->vid;
1626+
1627+
/* Only configure PVID if VLAN filtering is enabled */
1628+
if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
1629+
mt7530_rmw(priv, MT7530_PPBV1_P(port),
1630+
G0_PORT_VID_MASK,
1631+
G0_PORT_VID(vlan->vid));
16071632
}
16081633

16091634
mutex_unlock(&priv->reg_mutex);
@@ -1617,23 +1642,22 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
16171642
{
16181643
struct mt7530_hw_vlan_entry target_entry;
16191644
struct mt7530_priv *priv = ds->priv;
1620-
u16 pvid;
16211645

16221646
mutex_lock(&priv->reg_mutex);
16231647

1624-
pvid = priv->ports[port].pvid;
16251648
mt7530_hw_vlan_entry_init(&target_entry, port, 0);
16261649
mt7530_hw_vlan_update(priv, vlan->vid, &target_entry,
16271650
mt7530_hw_vlan_del);
16281651

16291652
/* PVID is being restored to the default whenever the PVID port
16301653
* is being removed from the VLAN.
16311654
*/
1632-
if (pvid == vlan->vid)
1633-
pvid = G0_PORT_VID_DEF;
1655+
if (priv->ports[port].pvid == vlan->vid) {
1656+
priv->ports[port].pvid = G0_PORT_VID_DEF;
1657+
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
1658+
G0_PORT_VID_DEF);
1659+
}
16341660

1635-
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, pvid);
1636-
priv->ports[port].pvid = pvid;
16371661

16381662
mutex_unlock(&priv->reg_mutex);
16391663

@@ -2046,6 +2070,7 @@ mt7530_setup(struct dsa_switch *ds)
20462070
* as two netdev instances.
20472071
*/
20482072
dn = dsa_to_port(ds, MT7530_CPU_PORT)->master->dev.of_node->parent;
2073+
ds->assisted_learning_on_cpu_port = true;
20492074
ds->mtu_enforcement_ingress = true;
20502075

20512076
if (priv->id == ID_MT7530) {
@@ -2116,15 +2141,19 @@ mt7530_setup(struct dsa_switch *ds)
21162141
mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
21172142
PCR_MATRIX_CLR);
21182143

2144+
/* Disable learning by default on all ports */
2145+
mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
2146+
21192147
if (dsa_is_cpu_port(ds, i)) {
21202148
ret = mt753x_cpu_port_enable(ds, i);
21212149
if (ret)
21222150
return ret;
21232151
} else {
21242152
mt7530_port_disable(ds, i);
21252153

2126-
/* Disable learning by default on all user ports */
2127-
mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
2154+
/* Set default PVID to 0 on all user ports */
2155+
mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
2156+
G0_PORT_VID_DEF);
21282157
}
21292158
/* Enable consistent egress tag */
21302159
mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
@@ -2281,6 +2310,9 @@ mt7531_setup(struct dsa_switch *ds)
22812310
mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
22822311
PCR_MATRIX_CLR);
22832312

2313+
/* Disable learning by default on all ports */
2314+
mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
2315+
22842316
mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
22852317

22862318
if (dsa_is_cpu_port(ds, i)) {
@@ -2290,15 +2322,17 @@ mt7531_setup(struct dsa_switch *ds)
22902322
} else {
22912323
mt7530_port_disable(ds, i);
22922324

2293-
/* Disable learning by default on all user ports */
2294-
mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
2325+
/* Set default PVID to 0 on all user ports */
2326+
mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
2327+
G0_PORT_VID_DEF);
22952328
}
22962329

22972330
/* Enable consistent egress tag */
22982331
mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
22992332
PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
23002333
}
23012334

2335+
ds->assisted_learning_on_cpu_port = true;
23022336
ds->mtu_enforcement_ingress = true;
23032337

23042338
/* Flush the FDB table */

drivers/net/dsa/mt7530.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ enum mt753x_bpdu_port_fw {
8080
#define STATIC_ENT 3
8181
#define MT7530_ATA2 0x78
8282
#define ATA2_IVL BIT(15)
83+
#define ATA2_FID(x) (((x) & 0x7) << 12)
8384

8485
/* Register for address table write data */
8586
#define MT7530_ATWD 0x7c
@@ -148,11 +149,18 @@ enum mt7530_vlan_cmd {
148149
#define VTAG_EN BIT(28)
149150
/* VLAN Member Control */
150151
#define PORT_MEM(x) (((x) & 0xff) << 16)
152+
/* Filter ID */
153+
#define FID(x) (((x) & 0x7) << 1)
151154
/* VLAN Entry Valid */
152155
#define VLAN_VALID BIT(0)
153156
#define PORT_MEM_SHFT 16
154157
#define PORT_MEM_MASK 0xff
155158

159+
enum mt7530_fid {
160+
FID_STANDALONE = 0,
161+
FID_BRIDGED = 1,
162+
};
163+
156164
#define MT7530_VAWD2 0x98
157165
/* Egress Tag Control */
158166
#define ETAG_CTRL_P(p, x) (((x) & 0x3) << ((p) << 1))
@@ -179,8 +187,8 @@ enum mt7530_vlan_egress_attr {
179187

180188
/* Register for port STP state control */
181189
#define MT7530_SSP_P(x) (0x2000 + ((x) * 0x100))
182-
#define FID_PST(x) ((x) & 0x3)
183-
#define FID_PST_MASK FID_PST(0x3)
190+
#define FID_PST(fid, state) (((state) & 0x3) << ((fid) * 2))
191+
#define FID_PST_MASK(fid) FID_PST(fid, 0x3)
184192

185193
enum mt7530_stp_state {
186194
MT7530_STP_DISABLED = 0,
@@ -247,7 +255,7 @@ enum mt7530_vlan_port_attr {
247255
#define MT7530_PPBV1_P(x) (0x2014 + ((x) * 0x100))
248256
#define G0_PORT_VID(x) (((x) & 0xfff) << 0)
249257
#define G0_PORT_VID_MASK G0_PORT_VID(0xfff)
250-
#define G0_PORT_VID_DEF G0_PORT_VID(1)
258+
#define G0_PORT_VID_DEF G0_PORT_VID(0)
251259

252260
/* Register for port MAC control register */
253261
#define MT7530_PMCR_P(x) (0x3000 + ((x) * 0x100))

0 commit comments

Comments
 (0)