@@ -1137,7 +1137,7 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
1137
1137
if (dsa_is_dsa_port (ds , i ) || dsa_is_cpu_port (ds , i ))
1138
1138
continue ;
1139
1139
1140
- if (!ds -> ports [port ].slave )
1140
+ if (!ds -> ports [i ].slave )
1141
1141
continue ;
1142
1142
1143
1143
if (vlan .member [i ] ==
@@ -1151,8 +1151,8 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
1151
1151
if (!dsa_to_port (ds , i )-> bridge_dev )
1152
1152
continue ;
1153
1153
1154
- dev_err (ds -> dev , "p%d: hw VLAN %d already used by %s\n" ,
1155
- port , vlan .vid ,
1154
+ dev_err (ds -> dev , "p%d: hw VLAN %d already used by port %d in %s\n" ,
1155
+ port , vlan .vid , i ,
1156
1156
netdev_name (dsa_to_port (ds , i )-> bridge_dev ));
1157
1157
err = - EOPNOTSUPP ;
1158
1158
goto unlock ;
@@ -1208,6 +1208,73 @@ mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
1208
1208
return 0 ;
1209
1209
}
1210
1210
1211
+ static int mv88e6xxx_port_db_load_purge (struct mv88e6xxx_chip * chip , int port ,
1212
+ const unsigned char * addr , u16 vid ,
1213
+ u8 state )
1214
+ {
1215
+ struct mv88e6xxx_vtu_entry vlan ;
1216
+ struct mv88e6xxx_atu_entry entry ;
1217
+ int err ;
1218
+
1219
+ /* Null VLAN ID corresponds to the port private database */
1220
+ if (vid == 0 )
1221
+ err = mv88e6xxx_port_get_fid (chip , port , & vlan .fid );
1222
+ else
1223
+ err = mv88e6xxx_vtu_get (chip , vid , & vlan , false);
1224
+ if (err )
1225
+ return err ;
1226
+
1227
+ entry .state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED ;
1228
+ ether_addr_copy (entry .mac , addr );
1229
+ eth_addr_dec (entry .mac );
1230
+
1231
+ err = mv88e6xxx_g1_atu_getnext (chip , vlan .fid , & entry );
1232
+ if (err )
1233
+ return err ;
1234
+
1235
+ /* Initialize a fresh ATU entry if it isn't found */
1236
+ if (entry .state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED ||
1237
+ !ether_addr_equal (entry .mac , addr )) {
1238
+ memset (& entry , 0 , sizeof (entry ));
1239
+ ether_addr_copy (entry .mac , addr );
1240
+ }
1241
+
1242
+ /* Purge the ATU entry only if no port is using it anymore */
1243
+ if (state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED ) {
1244
+ entry .portvec &= ~BIT (port );
1245
+ if (!entry .portvec )
1246
+ entry .state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED ;
1247
+ } else {
1248
+ entry .portvec |= BIT (port );
1249
+ entry .state = state ;
1250
+ }
1251
+
1252
+ return mv88e6xxx_g1_atu_loadpurge (chip , vlan .fid , & entry );
1253
+ }
1254
+
1255
+ static int mv88e6xxx_port_add_broadcast (struct mv88e6xxx_chip * chip , int port ,
1256
+ u16 vid )
1257
+ {
1258
+ const char broadcast [6 ] = { 0xff , 0xff , 0xff , 0xff , 0xff , 0xff };
1259
+ u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC ;
1260
+
1261
+ return mv88e6xxx_port_db_load_purge (chip , port , broadcast , vid , state );
1262
+ }
1263
+
1264
+ static int mv88e6xxx_broadcast_setup (struct mv88e6xxx_chip * chip , u16 vid )
1265
+ {
1266
+ int port ;
1267
+ int err ;
1268
+
1269
+ for (port = 0 ; port < mv88e6xxx_num_ports (chip ); port ++ ) {
1270
+ err = mv88e6xxx_port_add_broadcast (chip , port , vid );
1271
+ if (err )
1272
+ return err ;
1273
+ }
1274
+
1275
+ return 0 ;
1276
+ }
1277
+
1211
1278
static int _mv88e6xxx_port_vlan_add (struct mv88e6xxx_chip * chip , int port ,
1212
1279
u16 vid , u8 member )
1213
1280
{
@@ -1220,7 +1287,11 @@ static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
1220
1287
1221
1288
vlan .member [port ] = member ;
1222
1289
1223
- return mv88e6xxx_vtu_loadpurge (chip , & vlan );
1290
+ err = mv88e6xxx_vtu_loadpurge (chip , & vlan );
1291
+ if (err )
1292
+ return err ;
1293
+
1294
+ return mv88e6xxx_broadcast_setup (chip , vid );
1224
1295
}
1225
1296
1226
1297
static void mv88e6xxx_port_vlan_add (struct dsa_switch * ds , int port ,
@@ -1324,50 +1395,6 @@ static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
1324
1395
return err ;
1325
1396
}
1326
1397
1327
- static int mv88e6xxx_port_db_load_purge (struct mv88e6xxx_chip * chip , int port ,
1328
- const unsigned char * addr , u16 vid ,
1329
- u8 state )
1330
- {
1331
- struct mv88e6xxx_vtu_entry vlan ;
1332
- struct mv88e6xxx_atu_entry entry ;
1333
- int err ;
1334
-
1335
- /* Null VLAN ID corresponds to the port private database */
1336
- if (vid == 0 )
1337
- err = mv88e6xxx_port_get_fid (chip , port , & vlan .fid );
1338
- else
1339
- err = mv88e6xxx_vtu_get (chip , vid , & vlan , false);
1340
- if (err )
1341
- return err ;
1342
-
1343
- entry .state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED ;
1344
- ether_addr_copy (entry .mac , addr );
1345
- eth_addr_dec (entry .mac );
1346
-
1347
- err = mv88e6xxx_g1_atu_getnext (chip , vlan .fid , & entry );
1348
- if (err )
1349
- return err ;
1350
-
1351
- /* Initialize a fresh ATU entry if it isn't found */
1352
- if (entry .state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED ||
1353
- !ether_addr_equal (entry .mac , addr )) {
1354
- memset (& entry , 0 , sizeof (entry ));
1355
- ether_addr_copy (entry .mac , addr );
1356
- }
1357
-
1358
- /* Purge the ATU entry only if no port is using it anymore */
1359
- if (state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED ) {
1360
- entry .portvec &= ~BIT (port );
1361
- if (!entry .portvec )
1362
- entry .state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED ;
1363
- } else {
1364
- entry .portvec |= BIT (port );
1365
- entry .state = state ;
1366
- }
1367
-
1368
- return mv88e6xxx_g1_atu_loadpurge (chip , vlan .fid , & entry );
1369
- }
1370
-
1371
1398
static int mv88e6xxx_port_fdb_add (struct dsa_switch * ds , int port ,
1372
1399
const unsigned char * addr , u16 vid )
1373
1400
{
@@ -2049,6 +2076,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
2049
2076
if (err )
2050
2077
goto unlock ;
2051
2078
2079
+ err = mv88e6xxx_broadcast_setup (chip , 0 );
2080
+ if (err )
2081
+ goto unlock ;
2082
+
2052
2083
err = mv88e6xxx_pot_setup (chip );
2053
2084
if (err )
2054
2085
goto unlock ;
0 commit comments