aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/dsa/b53/b53_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/dsa/b53/b53_common.c')
-rw-r--r--drivers/net/dsa/b53/b53_common.c90
1 files changed, 71 insertions, 19 deletions
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 0e4bbdcc614f..c76892ac4e69 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -344,7 +344,8 @@ static void b53_set_forwarding(struct b53_device *dev, int enable)
344 b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt); 344 b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt);
345} 345}
346 346
347static void b53_enable_vlan(struct b53_device *dev, bool enable) 347static void b53_enable_vlan(struct b53_device *dev, bool enable,
348 bool enable_filtering)
348{ 349{
349 u8 mgmt, vc0, vc1, vc4 = 0, vc5; 350 u8 mgmt, vc0, vc1, vc4 = 0, vc5;
350 351
@@ -369,8 +370,13 @@ static void b53_enable_vlan(struct b53_device *dev, bool enable)
369 vc0 |= VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID; 370 vc0 |= VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID;
370 vc1 |= VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN; 371 vc1 |= VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN;
371 vc4 &= ~VC4_ING_VID_CHECK_MASK; 372 vc4 &= ~VC4_ING_VID_CHECK_MASK;
372 vc4 |= VC4_ING_VID_VIO_DROP << VC4_ING_VID_CHECK_S; 373 if (enable_filtering) {
373 vc5 |= VC5_DROP_VTABLE_MISS; 374 vc4 |= VC4_ING_VID_VIO_DROP << VC4_ING_VID_CHECK_S;
375 vc5 |= VC5_DROP_VTABLE_MISS;
376 } else {
377 vc4 |= VC4_ING_VID_VIO_FWD << VC4_ING_VID_CHECK_S;
378 vc5 &= ~VC5_DROP_VTABLE_MISS;
379 }
374 380
375 if (is5325(dev)) 381 if (is5325(dev))
376 vc0 &= ~VC0_RESERVED_1; 382 vc0 &= ~VC0_RESERVED_1;
@@ -420,6 +426,9 @@ static void b53_enable_vlan(struct b53_device *dev, bool enable)
420 } 426 }
421 427
422 b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); 428 b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt);
429
430 dev->vlan_enabled = enable;
431 dev->vlan_filtering_enabled = enable_filtering;
423} 432}
424 433
425static int b53_set_jumbo(struct b53_device *dev, bool enable, bool allow_10_100) 434static int b53_set_jumbo(struct b53_device *dev, bool enable, bool allow_10_100)
@@ -632,25 +641,35 @@ static void b53_enable_mib(struct b53_device *dev)
632 b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc); 641 b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc);
633} 642}
634 643
644static u16 b53_default_pvid(struct b53_device *dev)
645{
646 if (is5325(dev) || is5365(dev))
647 return 1;
648 else
649 return 0;
650}
651
635int b53_configure_vlan(struct dsa_switch *ds) 652int b53_configure_vlan(struct dsa_switch *ds)
636{ 653{
637 struct b53_device *dev = ds->priv; 654 struct b53_device *dev = ds->priv;
638 struct b53_vlan vl = { 0 }; 655 struct b53_vlan vl = { 0 };
639 int i; 656 int i, def_vid;
657
658 def_vid = b53_default_pvid(dev);
640 659
641 /* clear all vlan entries */ 660 /* clear all vlan entries */
642 if (is5325(dev) || is5365(dev)) { 661 if (is5325(dev) || is5365(dev)) {
643 for (i = 1; i < dev->num_vlans; i++) 662 for (i = def_vid; i < dev->num_vlans; i++)
644 b53_set_vlan_entry(dev, i, &vl); 663 b53_set_vlan_entry(dev, i, &vl);
645 } else { 664 } else {
646 b53_do_vlan_op(dev, VTA_CMD_CLEAR); 665 b53_do_vlan_op(dev, VTA_CMD_CLEAR);
647 } 666 }
648 667
649 b53_enable_vlan(dev, false); 668 b53_enable_vlan(dev, false, dev->vlan_filtering_enabled);
650 669
651 b53_for_each_port(dev, i) 670 b53_for_each_port(dev, i)
652 b53_write16(dev, B53_VLAN_PAGE, 671 b53_write16(dev, B53_VLAN_PAGE,
653 B53_VLAN_PORT_DEF_TAG(i), 1); 672 B53_VLAN_PORT_DEF_TAG(i), def_vid);
654 673
655 if (!is5325(dev) && !is5365(dev)) 674 if (!is5325(dev) && !is5365(dev))
656 b53_set_jumbo(dev, dev->enable_jumbo, false); 675 b53_set_jumbo(dev, dev->enable_jumbo, false);
@@ -1255,6 +1274,46 @@ EXPORT_SYMBOL(b53_phylink_mac_link_up);
1255 1274
1256int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering) 1275int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering)
1257{ 1276{
1277 struct b53_device *dev = ds->priv;
1278 struct net_device *bridge_dev;
1279 unsigned int i;
1280 u16 pvid, new_pvid;
1281
1282 /* Handle the case were multiple bridges span the same switch device
1283 * and one of them has a different setting than what is being requested
1284 * which would be breaking filtering semantics for any of the other
1285 * bridge devices.
1286 */
1287 b53_for_each_port(dev, i) {
1288 bridge_dev = dsa_to_port(ds, i)->bridge_dev;
1289 if (bridge_dev &&
1290 bridge_dev != dsa_to_port(ds, port)->bridge_dev &&
1291 br_vlan_enabled(bridge_dev) != vlan_filtering) {
1292 netdev_err(bridge_dev,
1293 "VLAN filtering is global to the switch!\n");
1294 return -EINVAL;
1295 }
1296 }
1297
1298 b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &pvid);
1299 new_pvid = pvid;
1300 if (dev->vlan_filtering_enabled && !vlan_filtering) {
1301 /* Filtering is currently enabled, use the default PVID since
1302 * the bridge does not expect tagging anymore
1303 */
1304 dev->ports[port].pvid = pvid;
1305 new_pvid = b53_default_pvid(dev);
1306 } else if (!dev->vlan_filtering_enabled && vlan_filtering) {
1307 /* Filtering is currently disabled, restore the previous PVID */
1308 new_pvid = dev->ports[port].pvid;
1309 }
1310
1311 if (pvid != new_pvid)
1312 b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port),
1313 new_pvid);
1314
1315 b53_enable_vlan(dev, dev->vlan_enabled, vlan_filtering);
1316
1258 return 0; 1317 return 0;
1259} 1318}
1260EXPORT_SYMBOL(b53_vlan_filtering); 1319EXPORT_SYMBOL(b53_vlan_filtering);
@@ -1270,7 +1329,7 @@ int b53_vlan_prepare(struct dsa_switch *ds, int port,
1270 if (vlan->vid_end > dev->num_vlans) 1329 if (vlan->vid_end > dev->num_vlans)
1271 return -ERANGE; 1330 return -ERANGE;
1272 1331
1273 b53_enable_vlan(dev, true); 1332 b53_enable_vlan(dev, true, dev->vlan_filtering_enabled);
1274 1333
1275 return 0; 1334 return 0;
1276} 1335}
@@ -1300,7 +1359,7 @@ void b53_vlan_add(struct dsa_switch *ds, int port,
1300 b53_fast_age_vlan(dev, vid); 1359 b53_fast_age_vlan(dev, vid);
1301 } 1360 }
1302 1361
1303 if (pvid) { 1362 if (pvid && !dsa_is_cpu_port(ds, port)) {
1304 b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), 1363 b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port),
1305 vlan->vid_end); 1364 vlan->vid_end);
1306 b53_fast_age_vlan(dev, vid); 1365 b53_fast_age_vlan(dev, vid);
@@ -1326,12 +1385,8 @@ int b53_vlan_del(struct dsa_switch *ds, int port,
1326 1385
1327 vl->members &= ~BIT(port); 1386 vl->members &= ~BIT(port);
1328 1387
1329 if (pvid == vid) { 1388 if (pvid == vid)
1330 if (is5325(dev) || is5365(dev)) 1389 pvid = b53_default_pvid(dev);
1331 pvid = 1;
1332 else
1333 pvid = 0;
1334 }
1335 1390
1336 if (untagged && !dsa_is_cpu_port(ds, port)) 1391 if (untagged && !dsa_is_cpu_port(ds, port))
1337 vl->untag &= ~(BIT(port)); 1392 vl->untag &= ~(BIT(port));
@@ -1644,10 +1699,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br)
1644 b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); 1699 b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan);
1645 dev->ports[port].vlan_ctl_mask = pvlan; 1700 dev->ports[port].vlan_ctl_mask = pvlan;
1646 1701
1647 if (is5325(dev) || is5365(dev)) 1702 pvid = b53_default_pvid(dev);
1648 pvid = 1;
1649 else
1650 pvid = 0;
1651 1703
1652 /* Make this port join all VLANs without VLAN entries */ 1704 /* Make this port join all VLANs without VLAN entries */
1653 if (is58xx(dev)) { 1705 if (is58xx(dev)) {