aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/dsa/b53/b53_common.c')
-rw-r--r--drivers/net/dsa/b53/b53_common.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 5c3fa0be8844..9fff49229435 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -501,6 +501,19 @@ static void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port)
501 } 501 }
502} 502}
503 503
504static void b53_port_set_learning(struct b53_device *dev, int port,
505 bool learning)
506{
507 u16 reg;
508
509 b53_read16(dev, B53_CTRL_PAGE, B53_DIS_LEARNING, &reg);
510 if (learning)
511 reg &= ~BIT(port);
512 else
513 reg |= BIT(port);
514 b53_write16(dev, B53_CTRL_PAGE, B53_DIS_LEARNING, reg);
515}
516
504static int b53_enable_port(struct dsa_switch *ds, int port, 517static int b53_enable_port(struct dsa_switch *ds, int port,
505 struct phy_device *phy) 518 struct phy_device *phy)
506{ 519{
@@ -508,6 +521,8 @@ static int b53_enable_port(struct dsa_switch *ds, int port,
508 unsigned int cpu_port = dev->cpu_port; 521 unsigned int cpu_port = dev->cpu_port;
509 u16 pvlan; 522 u16 pvlan;
510 523
524 b53_port_set_learning(dev, port, false);
525
511 /* Clear the Rx and Tx disable bits and set to no spanning tree */ 526 /* Clear the Rx and Tx disable bits and set to no spanning tree */
512 b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), 0); 527 b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), 0);
513 528
@@ -551,6 +566,8 @@ static void b53_enable_cpu_port(struct b53_device *dev)
551 PORT_CTRL_RX_MCST_EN | 566 PORT_CTRL_RX_MCST_EN |
552 PORT_CTRL_RX_UCST_EN; 567 PORT_CTRL_RX_UCST_EN;
553 b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(cpu_port), port_ctrl); 568 b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(cpu_port), port_ctrl);
569
570 b53_port_set_learning(dev, cpu_port, false);
554} 571}
555 572
556static void b53_enable_mib(struct b53_device *dev) 573static void b53_enable_mib(struct b53_device *dev)
@@ -970,7 +987,7 @@ int b53_vlan_prepare(struct dsa_switch *ds, int port,
970 if ((is5325(dev) || is5365(dev)) && vlan->vid_begin == 0) 987 if ((is5325(dev) || is5365(dev)) && vlan->vid_begin == 0)
971 return -EOPNOTSUPP; 988 return -EOPNOTSUPP;
972 989
973 if (vlan->vid_end > dev->num_vlans) 990 if (vlan->vid_end >= dev->num_vlans)
974 return -ERANGE; 991 return -ERANGE;
975 992
976 b53_enable_vlan(dev, true); 993 b53_enable_vlan(dev, true);
@@ -1342,6 +1359,8 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br)
1342 b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); 1359 b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan);
1343 dev->ports[port].vlan_ctl_mask = pvlan; 1360 dev->ports[port].vlan_ctl_mask = pvlan;
1344 1361
1362 b53_port_set_learning(dev, port, true);
1363
1345 return 0; 1364 return 0;
1346} 1365}
1347EXPORT_SYMBOL(b53_br_join); 1366EXPORT_SYMBOL(b53_br_join);
@@ -1392,6 +1411,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br)
1392 vl->untag |= BIT(port) | BIT(dev->cpu_port); 1411 vl->untag |= BIT(port) | BIT(dev->cpu_port);
1393 b53_set_vlan_entry(dev, pvid, vl); 1412 b53_set_vlan_entry(dev, pvid, vl);
1394 } 1413 }
1414 b53_port_set_learning(dev, port, false);
1395} 1415}
1396EXPORT_SYMBOL(b53_br_leave); 1416EXPORT_SYMBOL(b53_br_leave);
1397 1417
@@ -1823,9 +1843,8 @@ static int b53_switch_init(struct b53_device *dev)
1823 dev->cpu_port = 5; 1843 dev->cpu_port = 5;
1824 } 1844 }
1825 1845
1826 /* cpu port is always last */
1827 dev->num_ports = dev->cpu_port + 1;
1828 dev->enabled_ports |= BIT(dev->cpu_port); 1846 dev->enabled_ports |= BIT(dev->cpu_port);
1847 dev->num_ports = fls(dev->enabled_ports);
1829 1848
1830 dev->ports = devm_kzalloc(dev->dev, 1849 dev->ports = devm_kzalloc(dev->dev,
1831 sizeof(struct b53_port) * dev->num_ports, 1850 sizeof(struct b53_port) * dev->num_ports,