aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/dsa
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r--drivers/net/dsa/b53/b53_common.c90
-rw-r--r--drivers/net/dsa/b53/b53_priv.h3
-rw-r--r--drivers/net/dsa/b53/b53_srab.c3
-rw-r--r--drivers/net/dsa/bcm_sf2.c12
-rw-r--r--drivers/net/dsa/microchip/ksz_common.c2
-rw-r--r--drivers/net/dsa/mt7530.c1
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c141
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.h5
-rw-r--r--drivers/net/dsa/mv88e6xxx/global1_atu.c21
-rw-r--r--drivers/net/dsa/mv88e6xxx/port.h10
-rw-r--r--drivers/net/dsa/mv88e6xxx/serdes.c2
-rw-r--r--drivers/net/dsa/realtek-smi.c18
12 files changed, 257 insertions, 51 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)) {
diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
index ec796482792d..4dc7ee38b258 100644
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -91,6 +91,7 @@ enum {
91struct b53_port { 91struct b53_port {
92 u16 vlan_ctl_mask; 92 u16 vlan_ctl_mask;
93 struct ethtool_eee eee; 93 struct ethtool_eee eee;
94 u16 pvid;
94}; 95};
95 96
96struct b53_vlan { 97struct b53_vlan {
@@ -137,6 +138,8 @@ struct b53_device {
137 138
138 unsigned int num_vlans; 139 unsigned int num_vlans;
139 struct b53_vlan *vlans; 140 struct b53_vlan *vlans;
141 bool vlan_enabled;
142 bool vlan_filtering_enabled;
140 unsigned int num_ports; 143 unsigned int num_ports;
141 struct b53_port *ports; 144 struct b53_port *ports;
142}; 145};
diff --git a/drivers/net/dsa/b53/b53_srab.c b/drivers/net/dsa/b53/b53_srab.c
index 90f514252987..d9c56a779c08 100644
--- a/drivers/net/dsa/b53/b53_srab.c
+++ b/drivers/net/dsa/b53/b53_srab.c
@@ -511,9 +511,6 @@ static void b53_srab_prepare_irq(struct platform_device *pdev)
511 /* Clear all pending interrupts */ 511 /* Clear all pending interrupts */
512 writel(0xffffffff, priv->regs + B53_SRAB_INTR); 512 writel(0xffffffff, priv->regs + B53_SRAB_INTR);
513 513
514 if (dev->pdata && dev->pdata->chip_id != BCM58XX_DEVICE_ID)
515 return;
516
517 for (i = 0; i < B53_N_PORTS; i++) { 514 for (i = 0; i < B53_N_PORTS; i++) {
518 port = &priv->port_intrs[i]; 515 port = &priv->port_intrs[i];
519 516
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 361fbde76654..14138d423cf1 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -690,7 +690,7 @@ static int bcm_sf2_sw_suspend(struct dsa_switch *ds)
690 * port, the other ones have already been disabled during 690 * port, the other ones have already been disabled during
691 * bcm_sf2_sw_setup 691 * bcm_sf2_sw_setup
692 */ 692 */
693 for (port = 0; port < DSA_MAX_PORTS; port++) { 693 for (port = 0; port < ds->num_ports; port++) {
694 if (dsa_is_user_port(ds, port) || dsa_is_cpu_port(ds, port)) 694 if (dsa_is_user_port(ds, port) || dsa_is_cpu_port(ds, port))
695 bcm_sf2_port_disable(ds, port, NULL); 695 bcm_sf2_port_disable(ds, port, NULL);
696 } 696 }
@@ -726,10 +726,11 @@ static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, int port,
726{ 726{
727 struct net_device *p = ds->ports[port].cpu_dp->master; 727 struct net_device *p = ds->ports[port].cpu_dp->master;
728 struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); 728 struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
729 struct ethtool_wolinfo pwol; 729 struct ethtool_wolinfo pwol = { };
730 730
731 /* Get the parent device WoL settings */ 731 /* Get the parent device WoL settings */
732 p->ethtool_ops->get_wol(p, &pwol); 732 if (p->ethtool_ops->get_wol)
733 p->ethtool_ops->get_wol(p, &pwol);
733 734
734 /* Advertise the parent device supported settings */ 735 /* Advertise the parent device supported settings */
735 wol->supported = pwol.supported; 736 wol->supported = pwol.supported;
@@ -750,9 +751,10 @@ static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port,
750 struct net_device *p = ds->ports[port].cpu_dp->master; 751 struct net_device *p = ds->ports[port].cpu_dp->master;
751 struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); 752 struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
752 s8 cpu_port = ds->ports[port].cpu_dp->index; 753 s8 cpu_port = ds->ports[port].cpu_dp->index;
753 struct ethtool_wolinfo pwol; 754 struct ethtool_wolinfo pwol = { };
754 755
755 p->ethtool_ops->get_wol(p, &pwol); 756 if (p->ethtool_ops->get_wol)
757 p->ethtool_ops->get_wol(p, &pwol);
756 if (wol->wolopts & ~pwol.supported) 758 if (wol->wolopts & ~pwol.supported)
757 return -EINVAL; 759 return -EINVAL;
758 760
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 3b12e2dcff31..8a5111f9414c 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -7,7 +7,6 @@
7 7
8#include <linux/delay.h> 8#include <linux/delay.h>
9#include <linux/export.h> 9#include <linux/export.h>
10#include <linux/gpio.h>
11#include <linux/gpio/consumer.h> 10#include <linux/gpio/consumer.h>
12#include <linux/kernel.h> 11#include <linux/kernel.h>
13#include <linux/module.h> 12#include <linux/module.h>
@@ -15,7 +14,6 @@
15#include <linux/phy.h> 14#include <linux/phy.h>
16#include <linux/etherdevice.h> 15#include <linux/etherdevice.h>
17#include <linux/if_bridge.h> 16#include <linux/if_bridge.h>
18#include <linux/of_gpio.h>
19#include <linux/of_net.h> 17#include <linux/of_net.h>
20#include <net/dsa.h> 18#include <net/dsa.h>
21#include <net/switchdev.h> 19#include <net/switchdev.h>
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 74547f43b938..a8a2c728afba 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -18,7 +18,6 @@
18#include <linux/mfd/syscon.h> 18#include <linux/mfd/syscon.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/netdevice.h> 20#include <linux/netdevice.h>
21#include <linux/of_gpio.h>
22#include <linux/of_mdio.h> 21#include <linux/of_mdio.h>
23#include <linux/of_net.h> 22#include <linux/of_net.h>
24#include <linux/of_platform.h> 23#include <linux/of_platform.h>
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 8a517d8fb9d1..12fd7ce3f1ff 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -261,6 +261,7 @@ static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct mv88e6xxx_chip *chip)
261 unsigned int sub_irq; 261 unsigned int sub_irq;
262 unsigned int n; 262 unsigned int n;
263 u16 reg; 263 u16 reg;
264 u16 ctl1;
264 int err; 265 int err;
265 266
266 mutex_lock(&chip->reg_lock); 267 mutex_lock(&chip->reg_lock);
@@ -270,13 +271,28 @@ static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct mv88e6xxx_chip *chip)
270 if (err) 271 if (err)
271 goto out; 272 goto out;
272 273
273 for (n = 0; n < chip->g1_irq.nirqs; ++n) { 274 do {
274 if (reg & (1 << n)) { 275 for (n = 0; n < chip->g1_irq.nirqs; ++n) {
275 sub_irq = irq_find_mapping(chip->g1_irq.domain, n); 276 if (reg & (1 << n)) {
276 handle_nested_irq(sub_irq); 277 sub_irq = irq_find_mapping(chip->g1_irq.domain,
277 ++nhandled; 278 n);
279 handle_nested_irq(sub_irq);
280 ++nhandled;
281 }
278 } 282 }
279 } 283
284 mutex_lock(&chip->reg_lock);
285 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &ctl1);
286 if (err)
287 goto unlock;
288 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
289unlock:
290 mutex_unlock(&chip->reg_lock);
291 if (err)
292 goto out;
293 ctl1 &= GENMASK(chip->g1_irq.nirqs, 0);
294 } while (reg & ctl1);
295
280out: 296out:
281 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE); 297 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
282} 298}
@@ -2403,6 +2419,107 @@ static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip)
2403 return mv88e6xxx_g1_stats_clear(chip); 2419 return mv88e6xxx_g1_stats_clear(chip);
2404} 2420}
2405 2421
2422/* The mv88e6390 has some hidden registers used for debug and
2423 * development. The errata also makes use of them.
2424 */
2425static int mv88e6390_hidden_write(struct mv88e6xxx_chip *chip, int port,
2426 int reg, u16 val)
2427{
2428 u16 ctrl;
2429 int err;
2430
2431 err = mv88e6xxx_port_write(chip, PORT_RESERVED_1A_DATA_PORT,
2432 PORT_RESERVED_1A, val);
2433 if (err)
2434 return err;
2435
2436 ctrl = PORT_RESERVED_1A_BUSY | PORT_RESERVED_1A_WRITE |
2437 PORT_RESERVED_1A_BLOCK | port << PORT_RESERVED_1A_PORT_SHIFT |
2438 reg;
2439
2440 return mv88e6xxx_port_write(chip, PORT_RESERVED_1A_CTRL_PORT,
2441 PORT_RESERVED_1A, ctrl);
2442}
2443
2444static int mv88e6390_hidden_wait(struct mv88e6xxx_chip *chip)
2445{
2446 return mv88e6xxx_wait(chip, PORT_RESERVED_1A_CTRL_PORT,
2447 PORT_RESERVED_1A, PORT_RESERVED_1A_BUSY);
2448}
2449
2450
2451static int mv88e6390_hidden_read(struct mv88e6xxx_chip *chip, int port,
2452 int reg, u16 *val)
2453{
2454 u16 ctrl;
2455 int err;
2456
2457 ctrl = PORT_RESERVED_1A_BUSY | PORT_RESERVED_1A_READ |
2458 PORT_RESERVED_1A_BLOCK | port << PORT_RESERVED_1A_PORT_SHIFT |
2459 reg;
2460
2461 err = mv88e6xxx_port_write(chip, PORT_RESERVED_1A_CTRL_PORT,
2462 PORT_RESERVED_1A, ctrl);
2463 if (err)
2464 return err;
2465
2466 err = mv88e6390_hidden_wait(chip);
2467 if (err)
2468 return err;
2469
2470 return mv88e6xxx_port_read(chip, PORT_RESERVED_1A_DATA_PORT,
2471 PORT_RESERVED_1A, val);
2472}
2473
2474/* Check if the errata has already been applied. */
2475static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip)
2476{
2477 int port;
2478 int err;
2479 u16 val;
2480
2481 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
2482 err = mv88e6390_hidden_read(chip, port, 0, &val);
2483 if (err) {
2484 dev_err(chip->dev,
2485 "Error reading hidden register: %d\n", err);
2486 return false;
2487 }
2488 if (val != 0x01c0)
2489 return false;
2490 }
2491
2492 return true;
2493}
2494
2495/* The 6390 copper ports have an errata which require poking magic
2496 * values into undocumented hidden registers and then performing a
2497 * software reset.
2498 */
2499static int mv88e6390_setup_errata(struct mv88e6xxx_chip *chip)
2500{
2501 int port;
2502 int err;
2503
2504 if (mv88e6390_setup_errata_applied(chip))
2505 return 0;
2506
2507 /* Set the ports into blocking mode */
2508 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
2509 err = mv88e6xxx_port_set_state(chip, port, BR_STATE_DISABLED);
2510 if (err)
2511 return err;
2512 }
2513
2514 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
2515 err = mv88e6390_hidden_write(chip, port, 0, 0x01c0);
2516 if (err)
2517 return err;
2518 }
2519
2520 return mv88e6xxx_software_reset(chip);
2521}
2522
2406static int mv88e6xxx_setup(struct dsa_switch *ds) 2523static int mv88e6xxx_setup(struct dsa_switch *ds)
2407{ 2524{
2408 struct mv88e6xxx_chip *chip = ds->priv; 2525 struct mv88e6xxx_chip *chip = ds->priv;
@@ -2415,6 +2532,12 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
2415 2532
2416 mutex_lock(&chip->reg_lock); 2533 mutex_lock(&chip->reg_lock);
2417 2534
2535 if (chip->info->ops->setup_errata) {
2536 err = chip->info->ops->setup_errata(chip);
2537 if (err)
2538 goto unlock;
2539 }
2540
2418 /* Cache the cmode of each port. */ 2541 /* Cache the cmode of each port. */
2419 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) { 2542 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
2420 if (chip->info->ops->port_get_cmode) { 2543 if (chip->info->ops->port_get_cmode) {
@@ -3226,6 +3349,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
3226 3349
3227static const struct mv88e6xxx_ops mv88e6190_ops = { 3350static const struct mv88e6xxx_ops mv88e6190_ops = {
3228 /* MV88E6XXX_FAMILY_6390 */ 3351 /* MV88E6XXX_FAMILY_6390 */
3352 .setup_errata = mv88e6390_setup_errata,
3229 .irl_init_all = mv88e6390_g2_irl_init_all, 3353 .irl_init_all = mv88e6390_g2_irl_init_all,
3230 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 3354 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
3231 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 3355 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
@@ -3269,6 +3393,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
3269 3393
3270static const struct mv88e6xxx_ops mv88e6190x_ops = { 3394static const struct mv88e6xxx_ops mv88e6190x_ops = {
3271 /* MV88E6XXX_FAMILY_6390 */ 3395 /* MV88E6XXX_FAMILY_6390 */
3396 .setup_errata = mv88e6390_setup_errata,
3272 .irl_init_all = mv88e6390_g2_irl_init_all, 3397 .irl_init_all = mv88e6390_g2_irl_init_all,
3273 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 3398 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
3274 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 3399 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
@@ -3312,6 +3437,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
3312 3437
3313static const struct mv88e6xxx_ops mv88e6191_ops = { 3438static const struct mv88e6xxx_ops mv88e6191_ops = {
3314 /* MV88E6XXX_FAMILY_6390 */ 3439 /* MV88E6XXX_FAMILY_6390 */
3440 .setup_errata = mv88e6390_setup_errata,
3315 .irl_init_all = mv88e6390_g2_irl_init_all, 3441 .irl_init_all = mv88e6390_g2_irl_init_all,
3316 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 3442 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
3317 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 3443 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
@@ -3404,6 +3530,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
3404 3530
3405static const struct mv88e6xxx_ops mv88e6290_ops = { 3531static const struct mv88e6xxx_ops mv88e6290_ops = {
3406 /* MV88E6XXX_FAMILY_6390 */ 3532 /* MV88E6XXX_FAMILY_6390 */
3533 .setup_errata = mv88e6390_setup_errata,
3407 .irl_init_all = mv88e6390_g2_irl_init_all, 3534 .irl_init_all = mv88e6390_g2_irl_init_all,
3408 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 3535 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
3409 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 3536 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
@@ -3709,6 +3836,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
3709 3836
3710static const struct mv88e6xxx_ops mv88e6390_ops = { 3837static const struct mv88e6xxx_ops mv88e6390_ops = {
3711 /* MV88E6XXX_FAMILY_6390 */ 3838 /* MV88E6XXX_FAMILY_6390 */
3839 .setup_errata = mv88e6390_setup_errata,
3712 .irl_init_all = mv88e6390_g2_irl_init_all, 3840 .irl_init_all = mv88e6390_g2_irl_init_all,
3713 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 3841 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
3714 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 3842 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
@@ -3756,6 +3884,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
3756 3884
3757static const struct mv88e6xxx_ops mv88e6390x_ops = { 3885static const struct mv88e6xxx_ops mv88e6390x_ops = {
3758 /* MV88E6XXX_FAMILY_6390 */ 3886 /* MV88E6XXX_FAMILY_6390 */
3887 .setup_errata = mv88e6390_setup_errata,
3759 .irl_init_all = mv88e6390_g2_irl_init_all, 3888 .irl_init_all = mv88e6390_g2_irl_init_all,
3760 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 3889 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
3761 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 3890 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index f9ecb7872d32..546651d8c3e1 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -300,6 +300,11 @@ struct mv88e6xxx_mdio_bus {
300}; 300};
301 301
302struct mv88e6xxx_ops { 302struct mv88e6xxx_ops {
303 /* Switch Setup Errata, called early in the switch setup to
304 * allow any errata actions to be performed
305 */
306 int (*setup_errata)(struct mv88e6xxx_chip *chip);
307
303 int (*ieee_pri_map)(struct mv88e6xxx_chip *chip); 308 int (*ieee_pri_map)(struct mv88e6xxx_chip *chip);
304 int (*ip_pri_map)(struct mv88e6xxx_chip *chip); 309 int (*ip_pri_map)(struct mv88e6xxx_chip *chip);
305 310
diff --git a/drivers/net/dsa/mv88e6xxx/global1_atu.c b/drivers/net/dsa/mv88e6xxx/global1_atu.c
index 5200e4bdce93..ea243840ee0f 100644
--- a/drivers/net/dsa/mv88e6xxx/global1_atu.c
+++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c
@@ -314,6 +314,7 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
314{ 314{
315 struct mv88e6xxx_chip *chip = dev_id; 315 struct mv88e6xxx_chip *chip = dev_id;
316 struct mv88e6xxx_atu_entry entry; 316 struct mv88e6xxx_atu_entry entry;
317 int spid;
317 int err; 318 int err;
318 u16 val; 319 u16 val;
319 320
@@ -336,6 +337,8 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
336 if (err) 337 if (err)
337 goto out; 338 goto out;
338 339
340 spid = entry.state;
341
339 if (val & MV88E6XXX_G1_ATU_OP_AGE_OUT_VIOLATION) { 342 if (val & MV88E6XXX_G1_ATU_OP_AGE_OUT_VIOLATION) {
340 dev_err_ratelimited(chip->dev, 343 dev_err_ratelimited(chip->dev,
341 "ATU age out violation for %pM\n", 344 "ATU age out violation for %pM\n",
@@ -344,23 +347,23 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
344 347
345 if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) { 348 if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) {
346 dev_err_ratelimited(chip->dev, 349 dev_err_ratelimited(chip->dev,
347 "ATU member violation for %pM portvec %x\n", 350 "ATU member violation for %pM portvec %x spid %d\n",
348 entry.mac, entry.portvec); 351 entry.mac, entry.portvec, spid);
349 chip->ports[entry.portvec].atu_member_violation++; 352 chip->ports[spid].atu_member_violation++;
350 } 353 }
351 354
352 if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) { 355 if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) {
353 dev_err_ratelimited(chip->dev, 356 dev_err_ratelimited(chip->dev,
354 "ATU miss violation for %pM portvec %x\n", 357 "ATU miss violation for %pM portvec %x spid %d\n",
355 entry.mac, entry.portvec); 358 entry.mac, entry.portvec, spid);
356 chip->ports[entry.portvec].atu_miss_violation++; 359 chip->ports[spid].atu_miss_violation++;
357 } 360 }
358 361
359 if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) { 362 if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) {
360 dev_err_ratelimited(chip->dev, 363 dev_err_ratelimited(chip->dev,
361 "ATU full violation for %pM portvec %x\n", 364 "ATU full violation for %pM portvec %x spid %d\n",
362 entry.mac, entry.portvec); 365 entry.mac, entry.portvec, spid);
363 chip->ports[entry.portvec].atu_full_violation++; 366 chip->ports[spid].atu_full_violation++;
364 } 367 }
365 mutex_unlock(&chip->reg_lock); 368 mutex_unlock(&chip->reg_lock);
366 369
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index 0d81866d0e4a..e583641de758 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -251,6 +251,16 @@
251/* Offset 0x19: Port IEEE Priority Remapping Registers (4-7) */ 251/* Offset 0x19: Port IEEE Priority Remapping Registers (4-7) */
252#define MV88E6095_PORT_IEEE_PRIO_REMAP_4567 0x19 252#define MV88E6095_PORT_IEEE_PRIO_REMAP_4567 0x19
253 253
254/* Offset 0x1a: Magic undocumented errata register */
255#define PORT_RESERVED_1A 0x1a
256#define PORT_RESERVED_1A_BUSY BIT(15)
257#define PORT_RESERVED_1A_WRITE BIT(14)
258#define PORT_RESERVED_1A_READ 0
259#define PORT_RESERVED_1A_PORT_SHIFT 5
260#define PORT_RESERVED_1A_BLOCK (0xf << 10)
261#define PORT_RESERVED_1A_CTRL_PORT 4
262#define PORT_RESERVED_1A_DATA_PORT 5
263
254int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg, 264int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
255 u16 *val); 265 u16 *val);
256int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg, 266int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
index 2caa8c8b4b55..1bfc5ff8d81d 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.c
+++ b/drivers/net/dsa/mv88e6xxx/serdes.c
@@ -664,7 +664,7 @@ int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
664 if (port < 9) 664 if (port < 9)
665 return 0; 665 return 0;
666 666
667 return mv88e6390_serdes_irq_setup(chip, port); 667 return mv88e6390x_serdes_irq_setup(chip, port);
668} 668}
669 669
670void mv88e6390x_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) 670void mv88e6390x_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
diff --git a/drivers/net/dsa/realtek-smi.c b/drivers/net/dsa/realtek-smi.c
index b4b839a1d095..ad41ec63cc9f 100644
--- a/drivers/net/dsa/realtek-smi.c
+++ b/drivers/net/dsa/realtek-smi.c
@@ -347,16 +347,17 @@ int realtek_smi_setup_mdio(struct realtek_smi *smi)
347 struct device_node *mdio_np; 347 struct device_node *mdio_np;
348 int ret; 348 int ret;
349 349
350 mdio_np = of_find_compatible_node(smi->dev->of_node, NULL, 350 mdio_np = of_get_compatible_child(smi->dev->of_node, "realtek,smi-mdio");
351 "realtek,smi-mdio");
352 if (!mdio_np) { 351 if (!mdio_np) {
353 dev_err(smi->dev, "no MDIO bus node\n"); 352 dev_err(smi->dev, "no MDIO bus node\n");
354 return -ENODEV; 353 return -ENODEV;
355 } 354 }
356 355
357 smi->slave_mii_bus = devm_mdiobus_alloc(smi->dev); 356 smi->slave_mii_bus = devm_mdiobus_alloc(smi->dev);
358 if (!smi->slave_mii_bus) 357 if (!smi->slave_mii_bus) {
359 return -ENOMEM; 358 ret = -ENOMEM;
359 goto err_put_node;
360 }
360 smi->slave_mii_bus->priv = smi; 361 smi->slave_mii_bus->priv = smi;
361 smi->slave_mii_bus->name = "SMI slave MII"; 362 smi->slave_mii_bus->name = "SMI slave MII";
362 smi->slave_mii_bus->read = realtek_smi_mdio_read; 363 smi->slave_mii_bus->read = realtek_smi_mdio_read;
@@ -371,10 +372,15 @@ int realtek_smi_setup_mdio(struct realtek_smi *smi)
371 if (ret) { 372 if (ret) {
372 dev_err(smi->dev, "unable to register MDIO bus %s\n", 373 dev_err(smi->dev, "unable to register MDIO bus %s\n",
373 smi->slave_mii_bus->id); 374 smi->slave_mii_bus->id);
374 of_node_put(mdio_np); 375 goto err_put_node;
375 } 376 }
376 377
377 return 0; 378 return 0;
379
380err_put_node:
381 of_node_put(mdio_np);
382
383 return ret;
378} 384}
379 385
380static int realtek_smi_probe(struct platform_device *pdev) 386static int realtek_smi_probe(struct platform_device *pdev)
@@ -457,6 +463,8 @@ static int realtek_smi_remove(struct platform_device *pdev)
457 struct realtek_smi *smi = dev_get_drvdata(&pdev->dev); 463 struct realtek_smi *smi = dev_get_drvdata(&pdev->dev);
458 464
459 dsa_unregister_switch(smi->ds); 465 dsa_unregister_switch(smi->ds);
466 if (smi->slave_mii_bus)
467 of_node_put(smi->slave_mii_bus->dev.of_node);
460 gpiod_set_value(smi->reset, 1); 468 gpiod_set_value(smi->reset, 1);
461 469
462 return 0; 470 return 0;