diff options
Diffstat (limited to 'drivers/net/dsa/b53/b53_common.c')
-rw-r--r-- | drivers/net/dsa/b53/b53_common.c | 25 |
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 | ||
504 | static 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, ®); | ||
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 | |||
504 | static int b53_enable_port(struct dsa_switch *ds, int port, | 517 | static 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 | ||
556 | static void b53_enable_mib(struct b53_device *dev) | 573 | static 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 | } |
1347 | EXPORT_SYMBOL(b53_br_join); | 1366 | EXPORT_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 | } |
1396 | EXPORT_SYMBOL(b53_br_leave); | 1416 | EXPORT_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, |