hc
2024-09-20 cf4ce59b3b70238352c7f1729f0f7223214828ad
kernel/drivers/net/dsa/mv88e6xxx/chip.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Marvell 88e6xxx Ethernet switch single-chip support
34 *
....@@ -7,13 +8,9 @@
78 *
89 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
910 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
10
- *
11
- * This program is free software; you can redistribute it and/or modify
12
- * it under the terms of the GNU General Public License as published by
13
- * the Free Software Foundation; either version 2 of the License, or
14
- * (at your option) any later version.
1511 */
1612
13
+#include <linux/bitfield.h>
1714 #include <linux/delay.h>
1815 #include <linux/etherdevice.h>
1916 #include <linux/ethtool.h>
....@@ -31,11 +28,11 @@
3128 #include <linux/platform_data/mv88e6xxx.h>
3229 #include <linux/netdevice.h>
3330 #include <linux/gpio/consumer.h>
34
-#include <linux/phy.h>
3531 #include <linux/phylink.h>
3632 #include <net/dsa.h>
3733
3834 #include "chip.h"
35
+#include "devlink.h"
3936 #include "global1.h"
4037 #include "global2.h"
4138 #include "hwtstamp.h"
....@@ -43,6 +40,7 @@
4340 #include "port.h"
4441 #include "ptp.h"
4542 #include "serdes.h"
43
+#include "smi.h"
4644
4745 static void assert_reg_lock(struct mv88e6xxx_chip *chip)
4846 {
....@@ -51,149 +49,6 @@
5149 dump_stack();
5250 }
5351 }
54
-
55
-/* The switch ADDR[4:1] configuration pins define the chip SMI device address
56
- * (ADDR[0] is always zero, thus only even SMI addresses can be strapped).
57
- *
58
- * When ADDR is all zero, the chip uses Single-chip Addressing Mode, assuming it
59
- * is the only device connected to the SMI master. In this mode it responds to
60
- * all 32 possible SMI addresses, and thus maps directly the internal devices.
61
- *
62
- * When ADDR is non-zero, the chip uses Multi-chip Addressing Mode, allowing
63
- * multiple devices to share the SMI interface. In this mode it responds to only
64
- * 2 registers, used to indirectly access the internal SMI devices.
65
- */
66
-
67
-static int mv88e6xxx_smi_read(struct mv88e6xxx_chip *chip,
68
- int addr, int reg, u16 *val)
69
-{
70
- if (!chip->smi_ops)
71
- return -EOPNOTSUPP;
72
-
73
- return chip->smi_ops->read(chip, addr, reg, val);
74
-}
75
-
76
-static int mv88e6xxx_smi_write(struct mv88e6xxx_chip *chip,
77
- int addr, int reg, u16 val)
78
-{
79
- if (!chip->smi_ops)
80
- return -EOPNOTSUPP;
81
-
82
- return chip->smi_ops->write(chip, addr, reg, val);
83
-}
84
-
85
-static int mv88e6xxx_smi_single_chip_read(struct mv88e6xxx_chip *chip,
86
- int addr, int reg, u16 *val)
87
-{
88
- int ret;
89
-
90
- ret = mdiobus_read_nested(chip->bus, addr, reg);
91
- if (ret < 0)
92
- return ret;
93
-
94
- *val = ret & 0xffff;
95
-
96
- return 0;
97
-}
98
-
99
-static int mv88e6xxx_smi_single_chip_write(struct mv88e6xxx_chip *chip,
100
- int addr, int reg, u16 val)
101
-{
102
- int ret;
103
-
104
- ret = mdiobus_write_nested(chip->bus, addr, reg, val);
105
- if (ret < 0)
106
- return ret;
107
-
108
- return 0;
109
-}
110
-
111
-static const struct mv88e6xxx_bus_ops mv88e6xxx_smi_single_chip_ops = {
112
- .read = mv88e6xxx_smi_single_chip_read,
113
- .write = mv88e6xxx_smi_single_chip_write,
114
-};
115
-
116
-static int mv88e6xxx_smi_multi_chip_wait(struct mv88e6xxx_chip *chip)
117
-{
118
- int ret;
119
- int i;
120
-
121
- for (i = 0; i < 16; i++) {
122
- ret = mdiobus_read_nested(chip->bus, chip->sw_addr, SMI_CMD);
123
- if (ret < 0)
124
- return ret;
125
-
126
- if ((ret & SMI_CMD_BUSY) == 0)
127
- return 0;
128
- }
129
-
130
- return -ETIMEDOUT;
131
-}
132
-
133
-static int mv88e6xxx_smi_multi_chip_read(struct mv88e6xxx_chip *chip,
134
- int addr, int reg, u16 *val)
135
-{
136
- int ret;
137
-
138
- /* Wait for the bus to become free. */
139
- ret = mv88e6xxx_smi_multi_chip_wait(chip);
140
- if (ret < 0)
141
- return ret;
142
-
143
- /* Transmit the read command. */
144
- ret = mdiobus_write_nested(chip->bus, chip->sw_addr, SMI_CMD,
145
- SMI_CMD_OP_22_READ | (addr << 5) | reg);
146
- if (ret < 0)
147
- return ret;
148
-
149
- /* Wait for the read command to complete. */
150
- ret = mv88e6xxx_smi_multi_chip_wait(chip);
151
- if (ret < 0)
152
- return ret;
153
-
154
- /* Read the data. */
155
- ret = mdiobus_read_nested(chip->bus, chip->sw_addr, SMI_DATA);
156
- if (ret < 0)
157
- return ret;
158
-
159
- *val = ret & 0xffff;
160
-
161
- return 0;
162
-}
163
-
164
-static int mv88e6xxx_smi_multi_chip_write(struct mv88e6xxx_chip *chip,
165
- int addr, int reg, u16 val)
166
-{
167
- int ret;
168
-
169
- /* Wait for the bus to become free. */
170
- ret = mv88e6xxx_smi_multi_chip_wait(chip);
171
- if (ret < 0)
172
- return ret;
173
-
174
- /* Transmit the data to write. */
175
- ret = mdiobus_write_nested(chip->bus, chip->sw_addr, SMI_DATA, val);
176
- if (ret < 0)
177
- return ret;
178
-
179
- /* Transmit the write command. */
180
- ret = mdiobus_write_nested(chip->bus, chip->sw_addr, SMI_CMD,
181
- SMI_CMD_OP_22_WRITE | (addr << 5) | reg);
182
- if (ret < 0)
183
- return ret;
184
-
185
- /* Wait for the write command to complete. */
186
- ret = mv88e6xxx_smi_multi_chip_wait(chip);
187
- if (ret < 0)
188
- return ret;
189
-
190
- return 0;
191
-}
192
-
193
-static const struct mv88e6xxx_bus_ops mv88e6xxx_smi_multi_chip_ops = {
194
- .read = mv88e6xxx_smi_multi_chip_read,
195
- .write = mv88e6xxx_smi_multi_chip_write,
196
-};
19752
19853 int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val)
19954 {
....@@ -225,6 +80,36 @@
22580 addr, reg, val);
22681
22782 return 0;
83
+}
84
+
85
+int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
86
+ u16 mask, u16 val)
87
+{
88
+ u16 data;
89
+ int err;
90
+ int i;
91
+
92
+ /* There's no bus specific operation to wait for a mask */
93
+ for (i = 0; i < 16; i++) {
94
+ err = mv88e6xxx_read(chip, addr, reg, &data);
95
+ if (err)
96
+ return err;
97
+
98
+ if ((data & mask) == val)
99
+ return 0;
100
+
101
+ usleep_range(1000, 2000);
102
+ }
103
+
104
+ dev_err(chip->dev, "Timeout while waiting for switch\n");
105
+ return -ETIMEDOUT;
106
+}
107
+
108
+int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,
109
+ int bit, int val)
110
+{
111
+ return mv88e6xxx_wait_mask(chip, addr, reg, BIT(bit),
112
+ val ? BIT(bit) : 0x0000);
228113 }
229114
230115 struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip)
....@@ -264,9 +149,9 @@
264149 u16 ctl1;
265150 int err;
266151
267
- mutex_lock(&chip->reg_lock);
152
+ mv88e6xxx_reg_lock(chip);
268153 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
269
- mutex_unlock(&chip->reg_lock);
154
+ mv88e6xxx_reg_unlock(chip);
270155
271156 if (err)
272157 goto out;
....@@ -281,13 +166,13 @@
281166 }
282167 }
283168
284
- mutex_lock(&chip->reg_lock);
169
+ mv88e6xxx_reg_lock(chip);
285170 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &ctl1);
286171 if (err)
287172 goto unlock;
288173 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
289174 unlock:
290
- mutex_unlock(&chip->reg_lock);
175
+ mv88e6xxx_reg_unlock(chip);
291176 if (err)
292177 goto out;
293178 ctl1 &= GENMASK(chip->g1_irq.nirqs, 0);
....@@ -308,7 +193,7 @@
308193 {
309194 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
310195
311
- mutex_lock(&chip->reg_lock);
196
+ mv88e6xxx_reg_lock(chip);
312197 }
313198
314199 static void mv88e6xxx_g1_irq_bus_sync_unlock(struct irq_data *d)
....@@ -330,7 +215,7 @@
330215 goto out;
331216
332217 out:
333
- mutex_unlock(&chip->reg_lock);
218
+ mv88e6xxx_reg_unlock(chip);
334219 }
335220
336221 static const struct irq_chip mv88e6xxx_g1_irq_chip = {
....@@ -385,9 +270,9 @@
385270 */
386271 free_irq(chip->irq, chip);
387272
388
- mutex_lock(&chip->reg_lock);
273
+ mv88e6xxx_reg_lock(chip);
389274 mv88e6xxx_g1_irq_free_common(chip);
390
- mutex_unlock(&chip->reg_lock);
275
+ mv88e6xxx_reg_unlock(chip);
391276 }
392277
393278 static int mv88e6xxx_g1_irq_setup_common(struct mv88e6xxx_chip *chip)
....@@ -456,12 +341,15 @@
456341 */
457342 irq_set_lockdep_class(chip->irq, &lock_key, &request_key);
458343
459
- mutex_unlock(&chip->reg_lock);
344
+ snprintf(chip->irq_name, sizeof(chip->irq_name),
345
+ "mv88e6xxx-%s", dev_name(chip->dev));
346
+
347
+ mv88e6xxx_reg_unlock(chip);
460348 err = request_threaded_irq(chip->irq, NULL,
461349 mv88e6xxx_g1_irq_thread_fn,
462
- IRQF_ONESHOT,
463
- dev_name(chip->dev), chip);
464
- mutex_lock(&chip->reg_lock);
350
+ IRQF_ONESHOT | IRQF_SHARED,
351
+ chip->irq_name, chip);
352
+ mv88e6xxx_reg_lock(chip);
465353 if (err)
466354 mv88e6xxx_g1_irq_free_common(chip);
467355
....@@ -490,7 +378,7 @@
490378 kthread_init_delayed_work(&chip->irq_poll_work,
491379 mv88e6xxx_irq_poll);
492380
493
- chip->kworker = kthread_create_worker(0, dev_name(chip->dev));
381
+ chip->kworker = kthread_create_worker(0, "%s", dev_name(chip->dev));
494382 if (IS_ERR(chip->kworker))
495383 return PTR_ERR(chip->kworker);
496384
....@@ -505,48 +393,31 @@
505393 kthread_cancel_delayed_work_sync(&chip->irq_poll_work);
506394 kthread_destroy_worker(chip->kworker);
507395
508
- mutex_lock(&chip->reg_lock);
396
+ mv88e6xxx_reg_lock(chip);
509397 mv88e6xxx_g1_irq_free_common(chip);
510
- mutex_unlock(&chip->reg_lock);
398
+ mv88e6xxx_reg_unlock(chip);
511399 }
512400
513
-int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask)
401
+static int mv88e6xxx_port_config_interface(struct mv88e6xxx_chip *chip,
402
+ int port, phy_interface_t interface)
514403 {
515
- int i;
516
-
517
- for (i = 0; i < 16; i++) {
518
- u16 val;
519
- int err;
520
-
521
- err = mv88e6xxx_read(chip, addr, reg, &val);
522
- if (err)
523
- return err;
524
-
525
- if (!(val & mask))
526
- return 0;
527
-
528
- usleep_range(1000, 2000);
529
- }
530
-
531
- dev_err(chip->dev, "Timeout while waiting for switch\n");
532
- return -ETIMEDOUT;
533
-}
534
-
535
-/* Indirect write to single pointer-data register with an Update bit */
536
-int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg, u16 update)
537
-{
538
- u16 val;
539404 int err;
540405
541
- /* Wait until the previous operation is completed */
542
- err = mv88e6xxx_wait(chip, addr, reg, BIT(15));
543
- if (err)
544
- return err;
406
+ if (chip->info->ops->port_set_rgmii_delay) {
407
+ err = chip->info->ops->port_set_rgmii_delay(chip, port,
408
+ interface);
409
+ if (err && err != -EOPNOTSUPP)
410
+ return err;
411
+ }
545412
546
- /* Set the Update bit to trigger a write operation */
547
- val = BIT(15) | update;
413
+ if (chip->info->ops->port_set_cmode) {
414
+ err = chip->info->ops->port_set_cmode(chip, port,
415
+ interface);
416
+ if (err && err != -EOPNOTSUPP)
417
+ return err;
418
+ }
548419
549
- return mv88e6xxx_write(chip, addr, reg, val);
420
+ return 0;
550421 }
551422
552423 static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port,
....@@ -559,15 +430,19 @@
559430 return 0;
560431
561432 /* Port's MAC control must not be changed unless the link is down */
562
- err = chip->info->ops->port_set_link(chip, port, 0);
433
+ err = chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN);
563434 if (err)
564435 return err;
565436
566
- if (chip->info->ops->port_set_speed) {
567
- err = chip->info->ops->port_set_speed(chip, port, speed);
437
+ if (chip->info->ops->port_set_speed_duplex) {
438
+ err = chip->info->ops->port_set_speed_duplex(chip, port,
439
+ speed, duplex);
568440 if (err && err != -EOPNOTSUPP)
569441 goto restore_link;
570442 }
443
+
444
+ if (speed == SPEED_MAX && chip->info->ops->port_max_speed_mode)
445
+ mode = chip->info->ops->port_max_speed_mode(port);
571446
572447 if (chip->info->ops->port_set_pause) {
573448 err = chip->info->ops->port_set_pause(chip, port, pause);
....@@ -575,25 +450,7 @@
575450 goto restore_link;
576451 }
577452
578
- if (chip->info->ops->port_set_duplex) {
579
- err = chip->info->ops->port_set_duplex(chip, port, duplex);
580
- if (err && err != -EOPNOTSUPP)
581
- goto restore_link;
582
- }
583
-
584
- if (chip->info->ops->port_set_rgmii_delay) {
585
- err = chip->info->ops->port_set_rgmii_delay(chip, port, mode);
586
- if (err && err != -EOPNOTSUPP)
587
- goto restore_link;
588
- }
589
-
590
- if (chip->info->ops->port_set_cmode) {
591
- err = chip->info->ops->port_set_cmode(chip, port, mode);
592
- if (err && err != -EOPNOTSUPP)
593
- goto restore_link;
594
- }
595
-
596
- err = 0;
453
+ err = mv88e6xxx_port_config_interface(chip, port, mode);
597454 restore_link:
598455 if (chip->info->ops->port_set_link(chip, port, link))
599456 dev_err(chip->dev, "p%d: failed to restore MAC's link\n", port);
....@@ -601,27 +458,102 @@
601458 return err;
602459 }
603460
604
-/* We expect the switch to perform auto negotiation if there is a real
605
- * phy. However, in the case of a fixed link phy, we force the port
606
- * settings from the fixed link settings.
607
- */
608
-static void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
609
- struct phy_device *phydev)
461
+static int mv88e6xxx_phy_is_internal(struct dsa_switch *ds, int port)
610462 {
611463 struct mv88e6xxx_chip *chip = ds->priv;
464
+
465
+ return port < chip->info->num_internal_phys;
466
+}
467
+
468
+static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port)
469
+{
470
+ u16 reg;
612471 int err;
613472
614
- if (!phy_is_pseudo_fixed_link(phydev))
615
- return;
473
+ err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
474
+ if (err) {
475
+ dev_err(chip->dev,
476
+ "p%d: %s: failed to read port status\n",
477
+ port, __func__);
478
+ return err;
479
+ }
616480
617
- mutex_lock(&chip->reg_lock);
618
- err = mv88e6xxx_port_setup_mac(chip, port, phydev->link, phydev->speed,
619
- phydev->duplex, phydev->pause,
620
- phydev->interface);
621
- mutex_unlock(&chip->reg_lock);
481
+ return !!(reg & MV88E6XXX_PORT_STS_PHY_DETECT);
482
+}
622483
623
- if (err && err != -EOPNOTSUPP)
624
- dev_err(ds->dev, "p%d: failed to configure MAC\n", port);
484
+static int mv88e6xxx_serdes_pcs_get_state(struct dsa_switch *ds, int port,
485
+ struct phylink_link_state *state)
486
+{
487
+ struct mv88e6xxx_chip *chip = ds->priv;
488
+ u8 lane;
489
+ int err;
490
+
491
+ mv88e6xxx_reg_lock(chip);
492
+ lane = mv88e6xxx_serdes_get_lane(chip, port);
493
+ if (lane && chip->info->ops->serdes_pcs_get_state)
494
+ err = chip->info->ops->serdes_pcs_get_state(chip, port, lane,
495
+ state);
496
+ else
497
+ err = -EOPNOTSUPP;
498
+ mv88e6xxx_reg_unlock(chip);
499
+
500
+ return err;
501
+}
502
+
503
+static int mv88e6xxx_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
504
+ unsigned int mode,
505
+ phy_interface_t interface,
506
+ const unsigned long *advertise)
507
+{
508
+ const struct mv88e6xxx_ops *ops = chip->info->ops;
509
+ u8 lane;
510
+
511
+ if (ops->serdes_pcs_config) {
512
+ lane = mv88e6xxx_serdes_get_lane(chip, port);
513
+ if (lane)
514
+ return ops->serdes_pcs_config(chip, port, lane, mode,
515
+ interface, advertise);
516
+ }
517
+
518
+ return 0;
519
+}
520
+
521
+static void mv88e6xxx_serdes_pcs_an_restart(struct dsa_switch *ds, int port)
522
+{
523
+ struct mv88e6xxx_chip *chip = ds->priv;
524
+ const struct mv88e6xxx_ops *ops;
525
+ int err = 0;
526
+ u8 lane;
527
+
528
+ ops = chip->info->ops;
529
+
530
+ if (ops->serdes_pcs_an_restart) {
531
+ mv88e6xxx_reg_lock(chip);
532
+ lane = mv88e6xxx_serdes_get_lane(chip, port);
533
+ if (lane)
534
+ err = ops->serdes_pcs_an_restart(chip, port, lane);
535
+ mv88e6xxx_reg_unlock(chip);
536
+
537
+ if (err)
538
+ dev_err(ds->dev, "p%d: failed to restart AN\n", port);
539
+ }
540
+}
541
+
542
+static int mv88e6xxx_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
543
+ unsigned int mode,
544
+ int speed, int duplex)
545
+{
546
+ const struct mv88e6xxx_ops *ops = chip->info->ops;
547
+ u8 lane;
548
+
549
+ if (!phylink_autoneg_inband(mode) && ops->serdes_pcs_link_up) {
550
+ lane = mv88e6xxx_serdes_get_lane(chip, port);
551
+ if (lane)
552
+ return ops->serdes_pcs_link_up(chip, port, lane,
553
+ speed, duplex);
554
+ }
555
+
556
+ return 0;
625557 }
626558
627559 static void mv88e6065_phylink_validate(struct mv88e6xxx_chip *chip, int port,
....@@ -650,6 +582,20 @@
650582 mv88e6065_phylink_validate(chip, port, mask, state);
651583 }
652584
585
+static void mv88e6341_phylink_validate(struct mv88e6xxx_chip *chip, int port,
586
+ unsigned long *mask,
587
+ struct phylink_link_state *state)
588
+{
589
+ if (port >= 5)
590
+ phylink_set(mask, 2500baseX_Full);
591
+
592
+ /* No ethtool bits for 200Mbps */
593
+ phylink_set(mask, 1000baseT_Full);
594
+ phylink_set(mask, 1000baseX_Full);
595
+
596
+ mv88e6065_phylink_validate(chip, port, mask, state);
597
+}
598
+
653599 static void mv88e6352_phylink_validate(struct mv88e6xxx_chip *chip, int port,
654600 unsigned long *mask,
655601 struct phylink_link_state *state)
....@@ -665,8 +611,10 @@
665611 unsigned long *mask,
666612 struct phylink_link_state *state)
667613 {
668
- if (port >= 9)
614
+ if (port >= 9) {
669615 phylink_set(mask, 2500baseX_Full);
616
+ phylink_set(mask, 2500baseT_Full);
617
+ }
670618
671619 /* No ethtool bits for 200Mbps */
672620 phylink_set(mask, 1000baseT_Full);
....@@ -712,79 +660,136 @@
712660 phylink_helper_basex_speed(state);
713661 }
714662
715
-static int mv88e6xxx_link_state(struct dsa_switch *ds, int port,
716
- struct phylink_link_state *state)
717
-{
718
- struct mv88e6xxx_chip *chip = ds->priv;
719
- int err;
720
-
721
- mutex_lock(&chip->reg_lock);
722
- if (chip->info->ops->port_link_state)
723
- err = chip->info->ops->port_link_state(chip, port, state);
724
- else
725
- err = -EOPNOTSUPP;
726
- mutex_unlock(&chip->reg_lock);
727
-
728
- return err;
729
-}
730
-
731663 static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
732664 unsigned int mode,
733665 const struct phylink_link_state *state)
734666 {
735667 struct mv88e6xxx_chip *chip = ds->priv;
736
- int speed, duplex, link, pause, err;
668
+ struct mv88e6xxx_port *p;
669
+ int err = 0;
737670
738
- if (mode == MLO_AN_PHY)
739
- return;
671
+ p = &chip->ports[port];
740672
741
- if (mode == MLO_AN_FIXED) {
742
- link = LINK_FORCED_UP;
743
- speed = state->speed;
744
- duplex = state->duplex;
745
- } else {
746
- speed = SPEED_UNFORCED;
747
- duplex = DUPLEX_UNFORCED;
748
- link = LINK_UNFORCED;
673
+ mv88e6xxx_reg_lock(chip);
674
+
675
+ if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) {
676
+ /* In inband mode, the link may come up at any time while the
677
+ * link is not forced down. Force the link down while we
678
+ * reconfigure the interface mode.
679
+ */
680
+ if (mode == MLO_AN_INBAND &&
681
+ p->interface != state->interface &&
682
+ chip->info->ops->port_set_link)
683
+ chip->info->ops->port_set_link(chip, port,
684
+ LINK_FORCED_DOWN);
685
+
686
+ err = mv88e6xxx_port_config_interface(chip, port,
687
+ state->interface);
688
+ if (err && err != -EOPNOTSUPP)
689
+ goto err_unlock;
690
+
691
+ err = mv88e6xxx_serdes_pcs_config(chip, port, mode,
692
+ state->interface,
693
+ state->advertising);
694
+ /* FIXME: we should restart negotiation if something changed -
695
+ * which is something we get if we convert to using phylinks
696
+ * PCS operations.
697
+ */
698
+ if (err > 0)
699
+ err = 0;
749700 }
750
- pause = !!phylink_test(state->advertising, Pause);
751701
752
- mutex_lock(&chip->reg_lock);
753
- err = mv88e6xxx_port_setup_mac(chip, port, link, speed, duplex, pause,
754
- state->interface);
755
- mutex_unlock(&chip->reg_lock);
702
+ /* Undo the forced down state above after completing configuration
703
+ * irrespective of its state on entry, which allows the link to come
704
+ * up in the in-band case where there is no separate SERDES. Also
705
+ * ensure that the link can come up if the PPU is in use and we are
706
+ * in PHY mode (we treat the PPU as an effective in-band mechanism.)
707
+ */
708
+ if (chip->info->ops->port_set_link &&
709
+ ((mode == MLO_AN_INBAND && p->interface != state->interface) ||
710
+ (mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port))))
711
+ chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
712
+
713
+ p->interface = state->interface;
714
+
715
+err_unlock:
716
+ mv88e6xxx_reg_unlock(chip);
756717
757718 if (err && err != -EOPNOTSUPP)
758
- dev_err(ds->dev, "p%d: failed to configure MAC\n", port);
759
-}
760
-
761
-static void mv88e6xxx_mac_link_force(struct dsa_switch *ds, int port, int link)
762
-{
763
- struct mv88e6xxx_chip *chip = ds->priv;
764
- int err;
765
-
766
- mutex_lock(&chip->reg_lock);
767
- err = chip->info->ops->port_set_link(chip, port, link);
768
- mutex_unlock(&chip->reg_lock);
769
-
770
- if (err)
771
- dev_err(chip->dev, "p%d: failed to force MAC link\n", port);
719
+ dev_err(ds->dev, "p%d: failed to configure MAC/PCS\n", port);
772720 }
773721
774722 static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
775723 unsigned int mode,
776724 phy_interface_t interface)
777725 {
778
- if (mode == MLO_AN_FIXED)
779
- mv88e6xxx_mac_link_force(ds, port, LINK_FORCED_DOWN);
726
+ struct mv88e6xxx_chip *chip = ds->priv;
727
+ const struct mv88e6xxx_ops *ops;
728
+ int err = 0;
729
+
730
+ ops = chip->info->ops;
731
+
732
+ mv88e6xxx_reg_lock(chip);
733
+ /* Internal PHYs propagate their configuration directly to the MAC.
734
+ * External PHYs depend on whether the PPU is enabled for this port.
735
+ */
736
+ if (((!mv88e6xxx_phy_is_internal(ds, port) &&
737
+ !mv88e6xxx_port_ppu_updates(chip, port)) ||
738
+ mode == MLO_AN_FIXED) && ops->port_set_link)
739
+ err = ops->port_set_link(chip, port, LINK_FORCED_DOWN);
740
+ mv88e6xxx_reg_unlock(chip);
741
+
742
+ if (err)
743
+ dev_err(chip->dev,
744
+ "p%d: failed to force MAC link down\n", port);
780745 }
781746
782747 static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
783748 unsigned int mode, phy_interface_t interface,
784
- struct phy_device *phydev)
749
+ struct phy_device *phydev,
750
+ int speed, int duplex,
751
+ bool tx_pause, bool rx_pause)
785752 {
786
- if (mode == MLO_AN_FIXED)
787
- mv88e6xxx_mac_link_force(ds, port, LINK_FORCED_UP);
753
+ struct mv88e6xxx_chip *chip = ds->priv;
754
+ const struct mv88e6xxx_ops *ops;
755
+ int err = 0;
756
+
757
+ ops = chip->info->ops;
758
+
759
+ mv88e6xxx_reg_lock(chip);
760
+ /* Internal PHYs propagate their configuration directly to the MAC.
761
+ * External PHYs depend on whether the PPU is enabled for this port.
762
+ */
763
+ if ((!mv88e6xxx_phy_is_internal(ds, port) &&
764
+ !mv88e6xxx_port_ppu_updates(chip, port)) ||
765
+ mode == MLO_AN_FIXED) {
766
+ /* FIXME: for an automedia port, should we force the link
767
+ * down here - what if the link comes up due to "other" media
768
+ * while we're bringing the port up, how is the exclusivity
769
+ * handled in the Marvell hardware? E.g. port 2 on 88E6390
770
+ * shared between internal PHY and Serdes.
771
+ */
772
+ err = mv88e6xxx_serdes_pcs_link_up(chip, port, mode, speed,
773
+ duplex);
774
+ if (err)
775
+ goto error;
776
+
777
+ if (ops->port_set_speed_duplex) {
778
+ err = ops->port_set_speed_duplex(chip, port,
779
+ speed, duplex);
780
+ if (err && err != -EOPNOTSUPP)
781
+ goto error;
782
+ }
783
+
784
+ if (ops->port_set_link)
785
+ err = ops->port_set_link(chip, port, LINK_FORCED_UP);
786
+ }
787
+error:
788
+ mv88e6xxx_reg_unlock(chip);
789
+
790
+ if (err && err != -EOPNOTSUPP)
791
+ dev_err(ds->dev,
792
+ "p%d: failed to configure MAC link up\n", port);
788793 }
789794
790795 static int mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
....@@ -884,7 +889,7 @@
884889 break;
885890 case STATS_TYPE_BANK1:
886891 reg = bank1_select;
887
- /* fall through */
892
+ fallthrough;
888893 case STATS_TYPE_BANK0:
889894 reg |= s->reg | histogram;
890895 mv88e6xxx_g1_stats_read(chip, reg, &low);
....@@ -923,6 +928,12 @@
923928 STATS_TYPE_BANK0 | STATS_TYPE_PORT);
924929 }
925930
931
+static int mv88e6250_stats_get_strings(struct mv88e6xxx_chip *chip,
932
+ uint8_t *data)
933
+{
934
+ return mv88e6xxx_stats_get_strings(chip, data, STATS_TYPE_BANK0);
935
+}
936
+
926937 static int mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip,
927938 uint8_t *data)
928939 {
....@@ -957,7 +968,7 @@
957968 if (stringset != ETH_SS_STATS)
958969 return;
959970
960
- mutex_lock(&chip->reg_lock);
971
+ mv88e6xxx_reg_lock(chip);
961972
962973 if (chip->info->ops->stats_get_strings)
963974 count = chip->info->ops->stats_get_strings(chip, data);
....@@ -970,7 +981,7 @@
970981 data += count * ETH_GSTRING_LEN;
971982 mv88e6xxx_atu_vtu_get_strings(data);
972983
973
- mutex_unlock(&chip->reg_lock);
984
+ mv88e6xxx_reg_unlock(chip);
974985 }
975986
976987 static int mv88e6xxx_stats_get_sset_count(struct mv88e6xxx_chip *chip,
....@@ -993,6 +1004,11 @@
9931004 STATS_TYPE_PORT);
9941005 }
9951006
1007
+static int mv88e6250_stats_get_sset_count(struct mv88e6xxx_chip *chip)
1008
+{
1009
+ return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0);
1010
+}
1011
+
9961012 static int mv88e6320_stats_get_sset_count(struct mv88e6xxx_chip *chip)
9971013 {
9981014 return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 |
....@@ -1008,7 +1024,7 @@
10081024 if (sset != ETH_SS_STATS)
10091025 return 0;
10101026
1011
- mutex_lock(&chip->reg_lock);
1027
+ mv88e6xxx_reg_lock(chip);
10121028 if (chip->info->ops->stats_get_sset_count)
10131029 count = chip->info->ops->stats_get_sset_count(chip);
10141030 if (count < 0)
....@@ -1025,7 +1041,7 @@
10251041 count += ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings);
10261042
10271043 out:
1028
- mutex_unlock(&chip->reg_lock);
1044
+ mv88e6xxx_reg_unlock(chip);
10291045
10301046 return count;
10311047 }
....@@ -1040,11 +1056,11 @@
10401056 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
10411057 stat = &mv88e6xxx_hw_stats[i];
10421058 if (stat->type & types) {
1043
- mutex_lock(&chip->reg_lock);
1059
+ mv88e6xxx_reg_lock(chip);
10441060 data[j] = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
10451061 bank1_select,
10461062 histogram);
1047
- mutex_unlock(&chip->reg_lock);
1063
+ mv88e6xxx_reg_unlock(chip);
10481064
10491065 j++;
10501066 }
....@@ -1057,6 +1073,13 @@
10571073 {
10581074 return mv88e6xxx_stats_get_stats(chip, port, data,
10591075 STATS_TYPE_BANK0 | STATS_TYPE_PORT,
1076
+ 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
1077
+}
1078
+
1079
+static int mv88e6250_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
1080
+ uint64_t *data)
1081
+{
1082
+ return mv88e6xxx_stats_get_stats(chip, port, data, STATS_TYPE_BANK0,
10601083 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
10611084 }
10621085
....@@ -1096,14 +1119,14 @@
10961119 if (chip->info->ops->stats_get_stats)
10971120 count = chip->info->ops->stats_get_stats(chip, port, data);
10981121
1099
- mutex_lock(&chip->reg_lock);
1122
+ mv88e6xxx_reg_lock(chip);
11001123 if (chip->info->ops->serdes_get_stats) {
11011124 data += count;
11021125 count = chip->info->ops->serdes_get_stats(chip, port, data);
11031126 }
11041127 data += count;
11051128 mv88e6xxx_atu_vtu_get_stats(chip, port, data);
1106
- mutex_unlock(&chip->reg_lock);
1129
+ mv88e6xxx_reg_unlock(chip);
11071130 }
11081131
11091132 static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
....@@ -1112,10 +1135,10 @@
11121135 struct mv88e6xxx_chip *chip = ds->priv;
11131136 int ret;
11141137
1115
- mutex_lock(&chip->reg_lock);
1138
+ mv88e6xxx_reg_lock(chip);
11161139
11171140 ret = mv88e6xxx_stats_snapshot(chip, port);
1118
- mutex_unlock(&chip->reg_lock);
1141
+ mv88e6xxx_reg_unlock(chip);
11191142
11201143 if (ret < 0)
11211144 return;
....@@ -1126,7 +1149,14 @@
11261149
11271150 static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
11281151 {
1129
- return 32 * sizeof(u16);
1152
+ struct mv88e6xxx_chip *chip = ds->priv;
1153
+ int len;
1154
+
1155
+ len = 32 * sizeof(u16);
1156
+ if (chip->info->ops->serdes_get_regs_len)
1157
+ len += chip->info->ops->serdes_get_regs_len(chip, port);
1158
+
1159
+ return len;
11301160 }
11311161
11321162 static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
....@@ -1138,11 +1168,11 @@
11381168 u16 *p = _p;
11391169 int i;
11401170
1141
- regs->version = 0;
1171
+ regs->version = chip->info->prod_num;
11421172
11431173 memset(p, 0xff, 32 * sizeof(u16));
11441174
1145
- mutex_lock(&chip->reg_lock);
1175
+ mv88e6xxx_reg_lock(chip);
11461176
11471177 for (i = 0; i < 32; i++) {
11481178
....@@ -1151,7 +1181,10 @@
11511181 p[i] = reg;
11521182 }
11531183
1154
- mutex_unlock(&chip->reg_lock);
1184
+ if (chip->info->ops->serdes_get_regs)
1185
+ chip->info->ops->serdes_get_regs(chip, port, &p[i]);
1186
+
1187
+ mv88e6xxx_reg_unlock(chip);
11551188 }
11561189
11571190 static int mv88e6xxx_get_mac_eee(struct dsa_switch *ds, int port,
....@@ -1168,35 +1201,43 @@
11681201 return 0;
11691202 }
11701203
1204
+/* Mask of the local ports allowed to receive frames from a given fabric port */
11711205 static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port)
11721206 {
1173
- struct dsa_switch *ds = NULL;
1207
+ struct dsa_switch *ds = chip->ds;
1208
+ struct dsa_switch_tree *dst = ds->dst;
11741209 struct net_device *br;
1210
+ struct dsa_port *dp;
1211
+ bool found = false;
11751212 u16 pvlan;
1176
- int i;
11771213
1178
- if (dev < DSA_MAX_SWITCHES)
1179
- ds = chip->ds->dst->ds[dev];
1214
+ list_for_each_entry(dp, &dst->ports, list) {
1215
+ if (dp->ds->index == dev && dp->index == port) {
1216
+ found = true;
1217
+ break;
1218
+ }
1219
+ }
11801220
11811221 /* Prevent frames from unknown switch or port */
1182
- if (!ds || port >= ds->num_ports)
1222
+ if (!found)
11831223 return 0;
11841224
11851225 /* Frames from DSA links and CPU ports can egress any local port */
1186
- if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))
1226
+ if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA)
11871227 return mv88e6xxx_port_mask(chip);
11881228
1189
- br = ds->ports[port].bridge_dev;
1229
+ br = dp->bridge_dev;
11901230 pvlan = 0;
11911231
11921232 /* Frames from user ports can egress any local DSA links and CPU ports,
11931233 * as well as any local member of their bridge group.
11941234 */
1195
- for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
1196
- if (dsa_is_cpu_port(chip->ds, i) ||
1197
- dsa_is_dsa_port(chip->ds, i) ||
1198
- (br && dsa_to_port(chip->ds, i)->bridge_dev == br))
1199
- pvlan |= BIT(i);
1235
+ list_for_each_entry(dp, &dst->ports, list)
1236
+ if (dp->ds == ds &&
1237
+ (dp->type == DSA_PORT_TYPE_CPU ||
1238
+ dp->type == DSA_PORT_TYPE_DSA ||
1239
+ (br && dp->bridge_dev == br)))
1240
+ pvlan |= BIT(dp->index);
12001241
12011242 return pvlan;
12021243 }
....@@ -1217,9 +1258,9 @@
12171258 struct mv88e6xxx_chip *chip = ds->priv;
12181259 int err;
12191260
1220
- mutex_lock(&chip->reg_lock);
1261
+ mv88e6xxx_reg_lock(chip);
12211262 err = mv88e6xxx_port_set_state(chip, port, state);
1222
- mutex_unlock(&chip->reg_lock);
1263
+ mv88e6xxx_reg_unlock(chip);
12231264
12241265 if (err)
12251266 dev_err(ds->dev, "p%d: failed to update state\n", port);
....@@ -1246,6 +1287,7 @@
12461287
12471288 static int mv88e6xxx_devmap_setup(struct mv88e6xxx_chip *chip)
12481289 {
1290
+ struct dsa_switch *ds = chip->ds;
12491291 int target, port;
12501292 int err;
12511293
....@@ -1254,10 +1296,9 @@
12541296
12551297 /* Initialize the routing port to the 32 possible target devices */
12561298 for (target = 0; target < 32; target++) {
1257
- port = 0x1f;
1258
- if (target < DSA_MAX_SWITCHES)
1259
- if (chip->ds->rtable[target] != DSA_RTABLE_NONE)
1260
- port = chip->ds->rtable[target];
1299
+ port = dsa_routing_port(ds, target);
1300
+ if (port == ds->num_ports)
1301
+ port = 0x1f;
12611302
12621303 err = mv88e6xxx_g2_device_mapping_write(chip, target, port);
12631304 if (err)
....@@ -1364,7 +1405,7 @@
13641405 u16 pvlan = 0;
13651406
13661407 if (!mv88e6xxx_has_pvt(chip))
1367
- return -EOPNOTSUPP;
1408
+ return 0;
13681409
13691410 /* Skip the local source device, which uses in-chip port VLAN */
13701411 if (dev != chip->ds->index)
....@@ -1404,9 +1445,9 @@
14041445 struct mv88e6xxx_chip *chip = ds->priv;
14051446 int err;
14061447
1407
- mutex_lock(&chip->reg_lock);
1448
+ mv88e6xxx_reg_lock(chip);
14081449 err = mv88e6xxx_g1_atu_remove(chip, 0, port, false);
1409
- mutex_unlock(&chip->reg_lock);
1450
+ mv88e6xxx_reg_unlock(chip);
14101451
14111452 if (err)
14121453 dev_err(ds->dev, "p%d: failed to flush ATU\n", port);
....@@ -1438,26 +1479,27 @@
14381479 return chip->info->ops->vtu_loadpurge(chip, entry);
14391480 }
14401481
1441
-static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
1482
+int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *fid_bitmap)
14421483 {
1443
- DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID);
1444
- struct mv88e6xxx_vtu_entry vlan = {
1445
- .vid = chip->info->max_vid,
1446
- };
1484
+ struct mv88e6xxx_vtu_entry vlan;
14471485 int i, err;
1486
+ u16 fid;
14481487
14491488 bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);
14501489
14511490 /* Set every FID bit used by the (un)bridged ports */
14521491 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1453
- err = mv88e6xxx_port_get_fid(chip, i, fid);
1492
+ err = mv88e6xxx_port_get_fid(chip, i, &fid);
14541493 if (err)
14551494 return err;
14561495
1457
- set_bit(*fid, fid_bitmap);
1496
+ set_bit(fid, fid_bitmap);
14581497 }
14591498
14601499 /* Set every FID bit used by the VLAN entries */
1500
+ vlan.vid = chip->info->max_vid;
1501
+ vlan.valid = false;
1502
+
14611503 do {
14621504 err = mv88e6xxx_vtu_getnext(chip, &vlan);
14631505 if (err)
....@@ -1468,6 +1510,18 @@
14681510
14691511 set_bit(vlan.fid, fid_bitmap);
14701512 } while (vlan.vid < chip->info->max_vid);
1513
+
1514
+ return 0;
1515
+}
1516
+
1517
+static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
1518
+{
1519
+ DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID);
1520
+ int err;
1521
+
1522
+ err = mv88e6xxx_fid_map(chip, fid_bitmap);
1523
+ if (err)
1524
+ return err;
14711525
14721526 /* The reset value 0x000 is used to indicate that multiple address
14731527 * databases are not needed. Return the next positive available.
....@@ -1480,51 +1534,11 @@
14801534 return mv88e6xxx_g1_atu_flush(chip, *fid, true);
14811535 }
14821536
1483
-static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
1484
- struct mv88e6xxx_vtu_entry *entry, bool new)
1485
-{
1486
- int err;
1487
-
1488
- if (!vid)
1489
- return -EOPNOTSUPP;
1490
-
1491
- entry->vid = vid - 1;
1492
- entry->valid = false;
1493
-
1494
- err = mv88e6xxx_vtu_getnext(chip, entry);
1495
- if (err)
1496
- return err;
1497
-
1498
- if (entry->vid == vid && entry->valid)
1499
- return 0;
1500
-
1501
- if (new) {
1502
- int i;
1503
-
1504
- /* Initialize a fresh VLAN entry */
1505
- memset(entry, 0, sizeof(*entry));
1506
- entry->valid = true;
1507
- entry->vid = vid;
1508
-
1509
- /* Exclude all ports */
1510
- for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
1511
- entry->member[i] =
1512
- MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
1513
-
1514
- return mv88e6xxx_atu_new(chip, &entry->fid);
1515
- }
1516
-
1517
- /* switchdev expects -EOPNOTSUPP to honor software VLANs */
1518
- return -EOPNOTSUPP;
1519
-}
1520
-
15211537 static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
15221538 u16 vid_begin, u16 vid_end)
15231539 {
15241540 struct mv88e6xxx_chip *chip = ds->priv;
1525
- struct mv88e6xxx_vtu_entry vlan = {
1526
- .vid = vid_begin - 1,
1527
- };
1541
+ struct mv88e6xxx_vtu_entry vlan;
15281542 int i, err;
15291543
15301544 /* DSA and CPU ports have to be members of multiple vlans */
....@@ -1534,12 +1548,13 @@
15341548 if (!vid_begin)
15351549 return -EOPNOTSUPP;
15361550
1537
- mutex_lock(&chip->reg_lock);
1551
+ vlan.vid = vid_begin - 1;
1552
+ vlan.valid = false;
15381553
15391554 do {
15401555 err = mv88e6xxx_vtu_getnext(chip, &vlan);
15411556 if (err)
1542
- goto unlock;
1557
+ return err;
15431558
15441559 if (!vlan.valid)
15451560 break;
....@@ -1551,7 +1566,7 @@
15511566 if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
15521567 continue;
15531568
1554
- if (!ds->ports[i].slave)
1569
+ if (!dsa_to_port(ds, i)->slave)
15551570 continue;
15561571
15571572 if (vlan.member[i] ==
....@@ -1559,7 +1574,7 @@
15591574 continue;
15601575
15611576 if (dsa_to_port(ds, i)->bridge_dev ==
1562
- ds->ports[port].bridge_dev)
1577
+ dsa_to_port(ds, port)->bridge_dev)
15631578 break; /* same bridge, check next VLAN */
15641579
15651580 if (!dsa_to_port(ds, i)->bridge_dev)
....@@ -1568,31 +1583,28 @@
15681583 dev_err(ds->dev, "p%d: hw VLAN %d already used by port %d in %s\n",
15691584 port, vlan.vid, i,
15701585 netdev_name(dsa_to_port(ds, i)->bridge_dev));
1571
- err = -EOPNOTSUPP;
1572
- goto unlock;
1586
+ return -EOPNOTSUPP;
15731587 }
15741588 } while (vlan.vid < vid_end);
15751589
1576
-unlock:
1577
- mutex_unlock(&chip->reg_lock);
1578
-
1579
- return err;
1590
+ return 0;
15801591 }
15811592
15821593 static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
1583
- bool vlan_filtering)
1594
+ bool vlan_filtering,
1595
+ struct switchdev_trans *trans)
15841596 {
15851597 struct mv88e6xxx_chip *chip = ds->priv;
15861598 u16 mode = vlan_filtering ? MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE :
15871599 MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED;
15881600 int err;
15891601
1590
- if (!chip->info->max_vid)
1591
- return -EOPNOTSUPP;
1602
+ if (switchdev_trans_ph_prepare(trans))
1603
+ return chip->info->max_vid ? 0 : -EOPNOTSUPP;
15921604
1593
- mutex_lock(&chip->reg_lock);
1605
+ mv88e6xxx_reg_lock(chip);
15941606 err = mv88e6xxx_port_set_8021q_mode(chip, port, mode);
1595
- mutex_unlock(&chip->reg_lock);
1607
+ mv88e6xxx_reg_unlock(chip);
15961608
15971609 return err;
15981610 }
....@@ -1610,53 +1622,65 @@
16101622 /* If the requested port doesn't belong to the same bridge as the VLAN
16111623 * members, do not support it (yet) and fallback to software VLAN.
16121624 */
1625
+ mv88e6xxx_reg_lock(chip);
16131626 err = mv88e6xxx_port_check_hw_vlan(ds, port, vlan->vid_begin,
16141627 vlan->vid_end);
1615
- if (err)
1616
- return err;
1628
+ mv88e6xxx_reg_unlock(chip);
16171629
16181630 /* We don't need any dynamic resource from the kernel (yet),
16191631 * so skip the prepare phase.
16201632 */
1621
- return 0;
1633
+ return err;
16221634 }
16231635
16241636 static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
16251637 const unsigned char *addr, u16 vid,
16261638 u8 state)
16271639 {
1628
- struct mv88e6xxx_vtu_entry vlan;
16291640 struct mv88e6xxx_atu_entry entry;
1641
+ struct mv88e6xxx_vtu_entry vlan;
1642
+ u16 fid;
16301643 int err;
16311644
16321645 /* Null VLAN ID corresponds to the port private database */
1633
- if (vid == 0)
1634
- err = mv88e6xxx_port_get_fid(chip, port, &vlan.fid);
1635
- else
1636
- err = mv88e6xxx_vtu_get(chip, vid, &vlan, false);
1637
- if (err)
1638
- return err;
1646
+ if (vid == 0) {
1647
+ err = mv88e6xxx_port_get_fid(chip, port, &fid);
1648
+ if (err)
1649
+ return err;
1650
+ } else {
1651
+ vlan.vid = vid - 1;
1652
+ vlan.valid = false;
16391653
1640
- entry.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
1654
+ err = mv88e6xxx_vtu_getnext(chip, &vlan);
1655
+ if (err)
1656
+ return err;
1657
+
1658
+ /* switchdev expects -EOPNOTSUPP to honor software VLANs */
1659
+ if (vlan.vid != vid || !vlan.valid)
1660
+ return -EOPNOTSUPP;
1661
+
1662
+ fid = vlan.fid;
1663
+ }
1664
+
1665
+ entry.state = 0;
16411666 ether_addr_copy(entry.mac, addr);
16421667 eth_addr_dec(entry.mac);
16431668
1644
- err = mv88e6xxx_g1_atu_getnext(chip, vlan.fid, &entry);
1669
+ err = mv88e6xxx_g1_atu_getnext(chip, fid, &entry);
16451670 if (err)
16461671 return err;
16471672
16481673 /* Initialize a fresh ATU entry if it isn't found */
1649
- if (entry.state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED ||
1650
- !ether_addr_equal(entry.mac, addr)) {
1674
+ if (!entry.state || !ether_addr_equal(entry.mac, addr)) {
16511675 memset(&entry, 0, sizeof(entry));
16521676 ether_addr_copy(entry.mac, addr);
16531677 }
16541678
16551679 /* Purge the ATU entry only if no port is using it anymore */
1656
- if (state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED) {
1680
+ if (!state) {
16571681 entry.portvec &= ~BIT(port);
16581682 if (!entry.portvec)
1659
- entry.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
1683
+ entry.state = 0;
16601684 } else {
16611685 if (state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC)
16621686 entry.portvec = BIT(port);
....@@ -1666,7 +1690,217 @@
16661690 entry.state = state;
16671691 }
16681692
1669
- return mv88e6xxx_g1_atu_loadpurge(chip, vlan.fid, &entry);
1693
+ return mv88e6xxx_g1_atu_loadpurge(chip, fid, &entry);
1694
+}
1695
+
1696
+static int mv88e6xxx_policy_apply(struct mv88e6xxx_chip *chip, int port,
1697
+ const struct mv88e6xxx_policy *policy)
1698
+{
1699
+ enum mv88e6xxx_policy_mapping mapping = policy->mapping;
1700
+ enum mv88e6xxx_policy_action action = policy->action;
1701
+ const u8 *addr = policy->addr;
1702
+ u16 vid = policy->vid;
1703
+ u8 state;
1704
+ int err;
1705
+ int id;
1706
+
1707
+ if (!chip->info->ops->port_set_policy)
1708
+ return -EOPNOTSUPP;
1709
+
1710
+ switch (mapping) {
1711
+ case MV88E6XXX_POLICY_MAPPING_DA:
1712
+ case MV88E6XXX_POLICY_MAPPING_SA:
1713
+ if (action == MV88E6XXX_POLICY_ACTION_NORMAL)
1714
+ state = 0; /* Dissociate the port and address */
1715
+ else if (action == MV88E6XXX_POLICY_ACTION_DISCARD &&
1716
+ is_multicast_ether_addr(addr))
1717
+ state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_POLICY;
1718
+ else if (action == MV88E6XXX_POLICY_ACTION_DISCARD &&
1719
+ is_unicast_ether_addr(addr))
1720
+ state = MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_POLICY;
1721
+ else
1722
+ return -EOPNOTSUPP;
1723
+
1724
+ err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
1725
+ state);
1726
+ if (err)
1727
+ return err;
1728
+ break;
1729
+ default:
1730
+ return -EOPNOTSUPP;
1731
+ }
1732
+
1733
+ /* Skip the port's policy clearing if the mapping is still in use */
1734
+ if (action == MV88E6XXX_POLICY_ACTION_NORMAL)
1735
+ idr_for_each_entry(&chip->policies, policy, id)
1736
+ if (policy->port == port &&
1737
+ policy->mapping == mapping &&
1738
+ policy->action != action)
1739
+ return 0;
1740
+
1741
+ return chip->info->ops->port_set_policy(chip, port, mapping, action);
1742
+}
1743
+
1744
+static int mv88e6xxx_policy_insert(struct mv88e6xxx_chip *chip, int port,
1745
+ struct ethtool_rx_flow_spec *fs)
1746
+{
1747
+ struct ethhdr *mac_entry = &fs->h_u.ether_spec;
1748
+ struct ethhdr *mac_mask = &fs->m_u.ether_spec;
1749
+ enum mv88e6xxx_policy_mapping mapping;
1750
+ enum mv88e6xxx_policy_action action;
1751
+ struct mv88e6xxx_policy *policy;
1752
+ u16 vid = 0;
1753
+ u8 *addr;
1754
+ int err;
1755
+ int id;
1756
+
1757
+ if (fs->location != RX_CLS_LOC_ANY)
1758
+ return -EINVAL;
1759
+
1760
+ if (fs->ring_cookie == RX_CLS_FLOW_DISC)
1761
+ action = MV88E6XXX_POLICY_ACTION_DISCARD;
1762
+ else
1763
+ return -EOPNOTSUPP;
1764
+
1765
+ switch (fs->flow_type & ~FLOW_EXT) {
1766
+ case ETHER_FLOW:
1767
+ if (!is_zero_ether_addr(mac_mask->h_dest) &&
1768
+ is_zero_ether_addr(mac_mask->h_source)) {
1769
+ mapping = MV88E6XXX_POLICY_MAPPING_DA;
1770
+ addr = mac_entry->h_dest;
1771
+ } else if (is_zero_ether_addr(mac_mask->h_dest) &&
1772
+ !is_zero_ether_addr(mac_mask->h_source)) {
1773
+ mapping = MV88E6XXX_POLICY_MAPPING_SA;
1774
+ addr = mac_entry->h_source;
1775
+ } else {
1776
+ /* Cannot support DA and SA mapping in the same rule */
1777
+ return -EOPNOTSUPP;
1778
+ }
1779
+ break;
1780
+ default:
1781
+ return -EOPNOTSUPP;
1782
+ }
1783
+
1784
+ if ((fs->flow_type & FLOW_EXT) && fs->m_ext.vlan_tci) {
1785
+ if (fs->m_ext.vlan_tci != htons(0xffff))
1786
+ return -EOPNOTSUPP;
1787
+ vid = be16_to_cpu(fs->h_ext.vlan_tci) & VLAN_VID_MASK;
1788
+ }
1789
+
1790
+ idr_for_each_entry(&chip->policies, policy, id) {
1791
+ if (policy->port == port && policy->mapping == mapping &&
1792
+ policy->action == action && policy->vid == vid &&
1793
+ ether_addr_equal(policy->addr, addr))
1794
+ return -EEXIST;
1795
+ }
1796
+
1797
+ policy = devm_kzalloc(chip->dev, sizeof(*policy), GFP_KERNEL);
1798
+ if (!policy)
1799
+ return -ENOMEM;
1800
+
1801
+ fs->location = 0;
1802
+ err = idr_alloc_u32(&chip->policies, policy, &fs->location, 0xffffffff,
1803
+ GFP_KERNEL);
1804
+ if (err) {
1805
+ devm_kfree(chip->dev, policy);
1806
+ return err;
1807
+ }
1808
+
1809
+ memcpy(&policy->fs, fs, sizeof(*fs));
1810
+ ether_addr_copy(policy->addr, addr);
1811
+ policy->mapping = mapping;
1812
+ policy->action = action;
1813
+ policy->port = port;
1814
+ policy->vid = vid;
1815
+
1816
+ err = mv88e6xxx_policy_apply(chip, port, policy);
1817
+ if (err) {
1818
+ idr_remove(&chip->policies, fs->location);
1819
+ devm_kfree(chip->dev, policy);
1820
+ return err;
1821
+ }
1822
+
1823
+ return 0;
1824
+}
1825
+
1826
+static int mv88e6xxx_get_rxnfc(struct dsa_switch *ds, int port,
1827
+ struct ethtool_rxnfc *rxnfc, u32 *rule_locs)
1828
+{
1829
+ struct ethtool_rx_flow_spec *fs = &rxnfc->fs;
1830
+ struct mv88e6xxx_chip *chip = ds->priv;
1831
+ struct mv88e6xxx_policy *policy;
1832
+ int err;
1833
+ int id;
1834
+
1835
+ mv88e6xxx_reg_lock(chip);
1836
+
1837
+ switch (rxnfc->cmd) {
1838
+ case ETHTOOL_GRXCLSRLCNT:
1839
+ rxnfc->data = 0;
1840
+ rxnfc->data |= RX_CLS_LOC_SPECIAL;
1841
+ rxnfc->rule_cnt = 0;
1842
+ idr_for_each_entry(&chip->policies, policy, id)
1843
+ if (policy->port == port)
1844
+ rxnfc->rule_cnt++;
1845
+ err = 0;
1846
+ break;
1847
+ case ETHTOOL_GRXCLSRULE:
1848
+ err = -ENOENT;
1849
+ policy = idr_find(&chip->policies, fs->location);
1850
+ if (policy) {
1851
+ memcpy(fs, &policy->fs, sizeof(*fs));
1852
+ err = 0;
1853
+ }
1854
+ break;
1855
+ case ETHTOOL_GRXCLSRLALL:
1856
+ rxnfc->data = 0;
1857
+ rxnfc->rule_cnt = 0;
1858
+ idr_for_each_entry(&chip->policies, policy, id)
1859
+ if (policy->port == port)
1860
+ rule_locs[rxnfc->rule_cnt++] = id;
1861
+ err = 0;
1862
+ break;
1863
+ default:
1864
+ err = -EOPNOTSUPP;
1865
+ break;
1866
+ }
1867
+
1868
+ mv88e6xxx_reg_unlock(chip);
1869
+
1870
+ return err;
1871
+}
1872
+
1873
+static int mv88e6xxx_set_rxnfc(struct dsa_switch *ds, int port,
1874
+ struct ethtool_rxnfc *rxnfc)
1875
+{
1876
+ struct ethtool_rx_flow_spec *fs = &rxnfc->fs;
1877
+ struct mv88e6xxx_chip *chip = ds->priv;
1878
+ struct mv88e6xxx_policy *policy;
1879
+ int err;
1880
+
1881
+ mv88e6xxx_reg_lock(chip);
1882
+
1883
+ switch (rxnfc->cmd) {
1884
+ case ETHTOOL_SRXCLSRLINS:
1885
+ err = mv88e6xxx_policy_insert(chip, port, fs);
1886
+ break;
1887
+ case ETHTOOL_SRXCLSRLDEL:
1888
+ err = -ENOENT;
1889
+ policy = idr_remove(&chip->policies, fs->location);
1890
+ if (policy) {
1891
+ policy->action = MV88E6XXX_POLICY_ACTION_NORMAL;
1892
+ err = mv88e6xxx_policy_apply(chip, port, policy);
1893
+ devm_kfree(chip->dev, policy);
1894
+ }
1895
+ break;
1896
+ default:
1897
+ err = -EOPNOTSUPP;
1898
+ break;
1899
+ }
1900
+
1901
+ mv88e6xxx_reg_unlock(chip);
1902
+
1903
+ return err;
16701904 }
16711905
16721906 static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port,
....@@ -1692,23 +1926,58 @@
16921926 return 0;
16931927 }
16941928
1695
-static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
1696
- u16 vid, u8 member)
1929
+static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port,
1930
+ u16 vid, u8 member, bool warn)
16971931 {
1932
+ const u8 non_member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
16981933 struct mv88e6xxx_vtu_entry vlan;
1699
- int err;
1934
+ int i, err;
17001935
1701
- err = mv88e6xxx_vtu_get(chip, vid, &vlan, true);
1936
+ if (!vid)
1937
+ return -EOPNOTSUPP;
1938
+
1939
+ vlan.vid = vid - 1;
1940
+ vlan.valid = false;
1941
+
1942
+ err = mv88e6xxx_vtu_getnext(chip, &vlan);
17021943 if (err)
17031944 return err;
17041945
1705
- vlan.member[port] = member;
1946
+ if (vlan.vid != vid || !vlan.valid) {
1947
+ memset(&vlan, 0, sizeof(vlan));
17061948
1707
- err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
1708
- if (err)
1709
- return err;
1949
+ err = mv88e6xxx_atu_new(chip, &vlan.fid);
1950
+ if (err)
1951
+ return err;
17101952
1711
- return mv88e6xxx_broadcast_setup(chip, vid);
1953
+ for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
1954
+ if (i == port)
1955
+ vlan.member[i] = member;
1956
+ else
1957
+ vlan.member[i] = non_member;
1958
+
1959
+ vlan.vid = vid;
1960
+ vlan.valid = true;
1961
+
1962
+ err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
1963
+ if (err)
1964
+ return err;
1965
+
1966
+ err = mv88e6xxx_broadcast_setup(chip, vlan.vid);
1967
+ if (err)
1968
+ return err;
1969
+ } else if (vlan.member[port] != member) {
1970
+ vlan.member[port] = member;
1971
+
1972
+ err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
1973
+ if (err)
1974
+ return err;
1975
+ } else if (warn) {
1976
+ dev_info(chip->dev, "p%d: already a member of VLAN %d\n",
1977
+ port, vid);
1978
+ }
1979
+
1980
+ return 0;
17121981 }
17131982
17141983 static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
....@@ -1717,6 +1986,7 @@
17171986 struct mv88e6xxx_chip *chip = ds->priv;
17181987 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
17191988 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
1989
+ bool warn;
17201990 u8 member;
17211991 u16 vid;
17221992
....@@ -1730,10 +2000,15 @@
17302000 else
17312001 member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_TAGGED;
17322002
1733
- mutex_lock(&chip->reg_lock);
2003
+ /* net/dsa/slave.c will call dsa_port_vlan_add() for the affected port
2004
+ * and then the CPU port. Do not warn for duplicates for the CPU port.
2005
+ */
2006
+ warn = !dsa_is_cpu_port(ds, port) && !dsa_is_dsa_port(ds, port);
2007
+
2008
+ mv88e6xxx_reg_lock(chip);
17342009
17352010 for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid)
1736
- if (_mv88e6xxx_port_vlan_add(chip, port, vid, member))
2011
+ if (mv88e6xxx_port_vlan_join(chip, port, vid, member, warn))
17372012 dev_err(ds->dev, "p%d: failed to add VLAN %d%c\n", port,
17382013 vid, untagged ? 'u' : 't');
17392014
....@@ -1741,21 +2016,30 @@
17412016 dev_err(ds->dev, "p%d: failed to set PVID %d\n", port,
17422017 vlan->vid_end);
17432018
1744
- mutex_unlock(&chip->reg_lock);
2019
+ mv88e6xxx_reg_unlock(chip);
17452020 }
17462021
1747
-static int _mv88e6xxx_port_vlan_del(struct mv88e6xxx_chip *chip,
1748
- int port, u16 vid)
2022
+static int mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip *chip,
2023
+ int port, u16 vid)
17492024 {
17502025 struct mv88e6xxx_vtu_entry vlan;
17512026 int i, err;
17522027
1753
- err = mv88e6xxx_vtu_get(chip, vid, &vlan, false);
2028
+ if (!vid)
2029
+ return -EOPNOTSUPP;
2030
+
2031
+ vlan.vid = vid - 1;
2032
+ vlan.valid = false;
2033
+
2034
+ err = mv88e6xxx_vtu_getnext(chip, &vlan);
17542035 if (err)
17552036 return err;
17562037
1757
- /* Tell switchdev if this VLAN is handled in software */
1758
- if (vlan.member[port] == MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
2038
+ /* If the VLAN doesn't exist in hardware or the port isn't a member,
2039
+ * tell switchdev that this VLAN is likely handled in software.
2040
+ */
2041
+ if (vlan.vid != vid || !vlan.valid ||
2042
+ vlan.member[port] == MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
17592043 return -EOPNOTSUPP;
17602044
17612045 vlan.member[port] = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
....@@ -1787,14 +2071,14 @@
17872071 if (!chip->info->max_vid)
17882072 return -EOPNOTSUPP;
17892073
1790
- mutex_lock(&chip->reg_lock);
2074
+ mv88e6xxx_reg_lock(chip);
17912075
17922076 err = mv88e6xxx_port_get_pvid(chip, port, &pvid);
17932077 if (err)
17942078 goto unlock;
17952079
17962080 for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
1797
- err = _mv88e6xxx_port_vlan_del(chip, port, vid);
2081
+ err = mv88e6xxx_port_vlan_leave(chip, port, vid);
17982082 if (err)
17992083 goto unlock;
18002084
....@@ -1806,7 +2090,7 @@
18062090 }
18072091
18082092 unlock:
1809
- mutex_unlock(&chip->reg_lock);
2093
+ mv88e6xxx_reg_unlock(chip);
18102094
18112095 return err;
18122096 }
....@@ -1817,10 +2101,10 @@
18172101 struct mv88e6xxx_chip *chip = ds->priv;
18182102 int err;
18192103
1820
- mutex_lock(&chip->reg_lock);
2104
+ mv88e6xxx_reg_lock(chip);
18212105 err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
18222106 MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
1823
- mutex_unlock(&chip->reg_lock);
2107
+ mv88e6xxx_reg_unlock(chip);
18242108
18252109 return err;
18262110 }
....@@ -1831,10 +2115,9 @@
18312115 struct mv88e6xxx_chip *chip = ds->priv;
18322116 int err;
18332117
1834
- mutex_lock(&chip->reg_lock);
1835
- err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
1836
- MV88E6XXX_G1_ATU_DATA_STATE_UNUSED);
1837
- mutex_unlock(&chip->reg_lock);
2118
+ mv88e6xxx_reg_lock(chip);
2119
+ err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, 0);
2120
+ mv88e6xxx_reg_unlock(chip);
18382121
18392122 return err;
18402123 }
....@@ -1847,17 +2130,15 @@
18472130 bool is_static;
18482131 int err;
18492132
1850
- addr.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
2133
+ addr.state = 0;
18512134 eth_broadcast_addr(addr.mac);
18522135
18532136 do {
1854
- mutex_lock(&chip->reg_lock);
18552137 err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr);
1856
- mutex_unlock(&chip->reg_lock);
18572138 if (err)
18582139 return err;
18592140
1860
- if (addr.state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED)
2141
+ if (!addr.state)
18612142 break;
18622143
18632144 if (addr.trunk || (addr.portvec & BIT(port)) == 0)
....@@ -1879,17 +2160,12 @@
18792160 static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
18802161 dsa_fdb_dump_cb_t *cb, void *data)
18812162 {
1882
- struct mv88e6xxx_vtu_entry vlan = {
1883
- .vid = chip->info->max_vid,
1884
- };
2163
+ struct mv88e6xxx_vtu_entry vlan;
18852164 u16 fid;
18862165 int err;
18872166
18882167 /* Dump port's default Filtering Information Database (VLAN ID 0) */
1889
- mutex_lock(&chip->reg_lock);
18902168 err = mv88e6xxx_port_get_fid(chip, port, &fid);
1891
- mutex_unlock(&chip->reg_lock);
1892
-
18932169 if (err)
18942170 return err;
18952171
....@@ -1898,10 +2174,11 @@
18982174 return err;
18992175
19002176 /* Dump VLANs' Filtering Information Databases */
2177
+ vlan.vid = chip->info->max_vid;
2178
+ vlan.valid = false;
2179
+
19012180 do {
1902
- mutex_lock(&chip->reg_lock);
19032181 err = mv88e6xxx_vtu_getnext(chip, &vlan);
1904
- mutex_unlock(&chip->reg_lock);
19052182 if (err)
19062183 return err;
19072184
....@@ -1921,39 +2198,38 @@
19212198 dsa_fdb_dump_cb_t *cb, void *data)
19222199 {
19232200 struct mv88e6xxx_chip *chip = ds->priv;
2201
+ int err;
19242202
1925
- return mv88e6xxx_port_db_dump(chip, port, cb, data);
2203
+ mv88e6xxx_reg_lock(chip);
2204
+ err = mv88e6xxx_port_db_dump(chip, port, cb, data);
2205
+ mv88e6xxx_reg_unlock(chip);
2206
+
2207
+ return err;
19262208 }
19272209
19282210 static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip,
19292211 struct net_device *br)
19302212 {
1931
- struct dsa_switch *ds;
1932
- int port;
1933
- int dev;
2213
+ struct dsa_switch *ds = chip->ds;
2214
+ struct dsa_switch_tree *dst = ds->dst;
2215
+ struct dsa_port *dp;
19342216 int err;
19352217
1936
- /* Remap the Port VLAN of each local bridge group member */
1937
- for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) {
1938
- if (chip->ds->ports[port].bridge_dev == br) {
1939
- err = mv88e6xxx_port_vlan_map(chip, port);
1940
- if (err)
1941
- return err;
1942
- }
1943
- }
1944
-
1945
- if (!mv88e6xxx_has_pvt(chip))
1946
- return 0;
1947
-
1948
- /* Remap the Port VLAN of each cross-chip bridge group member */
1949
- for (dev = 0; dev < DSA_MAX_SWITCHES; ++dev) {
1950
- ds = chip->ds->dst->ds[dev];
1951
- if (!ds)
1952
- break;
1953
-
1954
- for (port = 0; port < ds->num_ports; ++port) {
1955
- if (ds->ports[port].bridge_dev == br) {
1956
- err = mv88e6xxx_pvt_map(chip, dev, port);
2218
+ list_for_each_entry(dp, &dst->ports, list) {
2219
+ if (dp->bridge_dev == br) {
2220
+ if (dp->ds == ds) {
2221
+ /* This is a local bridge group member,
2222
+ * remap its Port VLAN Map.
2223
+ */
2224
+ err = mv88e6xxx_port_vlan_map(chip, dp->index);
2225
+ if (err)
2226
+ return err;
2227
+ } else {
2228
+ /* This is an external bridge group member,
2229
+ * remap its cross-chip Port VLAN Table entry.
2230
+ */
2231
+ err = mv88e6xxx_pvt_map(chip, dp->ds->index,
2232
+ dp->index);
19572233 if (err)
19582234 return err;
19592235 }
....@@ -1969,9 +2245,9 @@
19692245 struct mv88e6xxx_chip *chip = ds->priv;
19702246 int err;
19712247
1972
- mutex_lock(&chip->reg_lock);
2248
+ mv88e6xxx_reg_lock(chip);
19732249 err = mv88e6xxx_bridge_map(chip, br);
1974
- mutex_unlock(&chip->reg_lock);
2250
+ mv88e6xxx_reg_unlock(chip);
19752251
19762252 return err;
19772253 }
....@@ -1981,41 +2257,43 @@
19812257 {
19822258 struct mv88e6xxx_chip *chip = ds->priv;
19832259
1984
- mutex_lock(&chip->reg_lock);
2260
+ mv88e6xxx_reg_lock(chip);
19852261 if (mv88e6xxx_bridge_map(chip, br) ||
19862262 mv88e6xxx_port_vlan_map(chip, port))
19872263 dev_err(ds->dev, "failed to remap in-chip Port VLAN\n");
1988
- mutex_unlock(&chip->reg_lock);
2264
+ mv88e6xxx_reg_unlock(chip);
19892265 }
19902266
1991
-static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds, int dev,
2267
+static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds,
2268
+ int tree_index, int sw_index,
19922269 int port, struct net_device *br)
19932270 {
19942271 struct mv88e6xxx_chip *chip = ds->priv;
19952272 int err;
19962273
1997
- if (!mv88e6xxx_has_pvt(chip))
2274
+ if (tree_index != ds->dst->index)
19982275 return 0;
19992276
2000
- mutex_lock(&chip->reg_lock);
2001
- err = mv88e6xxx_pvt_map(chip, dev, port);
2002
- mutex_unlock(&chip->reg_lock);
2277
+ mv88e6xxx_reg_lock(chip);
2278
+ err = mv88e6xxx_pvt_map(chip, sw_index, port);
2279
+ mv88e6xxx_reg_unlock(chip);
20032280
20042281 return err;
20052282 }
20062283
2007
-static void mv88e6xxx_crosschip_bridge_leave(struct dsa_switch *ds, int dev,
2284
+static void mv88e6xxx_crosschip_bridge_leave(struct dsa_switch *ds,
2285
+ int tree_index, int sw_index,
20082286 int port, struct net_device *br)
20092287 {
20102288 struct mv88e6xxx_chip *chip = ds->priv;
20112289
2012
- if (!mv88e6xxx_has_pvt(chip))
2290
+ if (tree_index != ds->dst->index)
20132291 return;
20142292
2015
- mutex_lock(&chip->reg_lock);
2016
- if (mv88e6xxx_pvt_map(chip, dev, port))
2293
+ mv88e6xxx_reg_lock(chip);
2294
+ if (mv88e6xxx_pvt_map(chip, sw_index, port))
20172295 dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n");
2018
- mutex_unlock(&chip->reg_lock);
2296
+ mv88e6xxx_reg_unlock(chip);
20192297 }
20202298
20212299 static int mv88e6xxx_software_reset(struct mv88e6xxx_chip *chip)
....@@ -2032,10 +2310,22 @@
20322310
20332311 /* If there is a GPIO connected to the reset pin, toggle it */
20342312 if (gpiod) {
2313
+ /* If the switch has just been reset and not yet completed
2314
+ * loading EEPROM, the reset may interrupt the I2C transaction
2315
+ * mid-byte, causing the first EEPROM read after the reset
2316
+ * from the wrong location resulting in the switch booting
2317
+ * to wrong mode and inoperable.
2318
+ */
2319
+ if (chip->info->ops->get_eeprom)
2320
+ mv88e6xxx_g2_eeprom_wait(chip);
2321
+
20352322 gpiod_set_value_cansleep(gpiod, 1);
20362323 usleep_range(10000, 20000);
20372324 gpiod_set_value_cansleep(gpiod, 0);
20382325 usleep_range(10000, 20000);
2326
+
2327
+ if (chip->info->ops->get_eeprom)
2328
+ mv88e6xxx_g2_eeprom_wait(chip);
20392329 }
20402330 }
20412331
....@@ -2155,13 +2445,100 @@
21552445 return 0;
21562446 }
21572447
2448
+static irqreturn_t mv88e6xxx_serdes_irq_thread_fn(int irq, void *dev_id)
2449
+{
2450
+ struct mv88e6xxx_port *mvp = dev_id;
2451
+ struct mv88e6xxx_chip *chip = mvp->chip;
2452
+ irqreturn_t ret = IRQ_NONE;
2453
+ int port = mvp->port;
2454
+ u8 lane;
2455
+
2456
+ mv88e6xxx_reg_lock(chip);
2457
+ lane = mv88e6xxx_serdes_get_lane(chip, port);
2458
+ if (lane)
2459
+ ret = mv88e6xxx_serdes_irq_status(chip, port, lane);
2460
+ mv88e6xxx_reg_unlock(chip);
2461
+
2462
+ return ret;
2463
+}
2464
+
2465
+static int mv88e6xxx_serdes_irq_request(struct mv88e6xxx_chip *chip, int port,
2466
+ u8 lane)
2467
+{
2468
+ struct mv88e6xxx_port *dev_id = &chip->ports[port];
2469
+ unsigned int irq;
2470
+ int err;
2471
+
2472
+ /* Nothing to request if this SERDES port has no IRQ */
2473
+ irq = mv88e6xxx_serdes_irq_mapping(chip, port);
2474
+ if (!irq)
2475
+ return 0;
2476
+
2477
+ snprintf(dev_id->serdes_irq_name, sizeof(dev_id->serdes_irq_name),
2478
+ "mv88e6xxx-%s-serdes-%d", dev_name(chip->dev), port);
2479
+
2480
+ /* Requesting the IRQ will trigger IRQ callbacks, so release the lock */
2481
+ mv88e6xxx_reg_unlock(chip);
2482
+ err = request_threaded_irq(irq, NULL, mv88e6xxx_serdes_irq_thread_fn,
2483
+ IRQF_ONESHOT, dev_id->serdes_irq_name,
2484
+ dev_id);
2485
+ mv88e6xxx_reg_lock(chip);
2486
+ if (err)
2487
+ return err;
2488
+
2489
+ dev_id->serdes_irq = irq;
2490
+
2491
+ return mv88e6xxx_serdes_irq_enable(chip, port, lane);
2492
+}
2493
+
2494
+static int mv88e6xxx_serdes_irq_free(struct mv88e6xxx_chip *chip, int port,
2495
+ u8 lane)
2496
+{
2497
+ struct mv88e6xxx_port *dev_id = &chip->ports[port];
2498
+ unsigned int irq = dev_id->serdes_irq;
2499
+ int err;
2500
+
2501
+ /* Nothing to free if no IRQ has been requested */
2502
+ if (!irq)
2503
+ return 0;
2504
+
2505
+ err = mv88e6xxx_serdes_irq_disable(chip, port, lane);
2506
+
2507
+ /* Freeing the IRQ will trigger IRQ callbacks, so release the lock */
2508
+ mv88e6xxx_reg_unlock(chip);
2509
+ free_irq(irq, dev_id);
2510
+ mv88e6xxx_reg_lock(chip);
2511
+
2512
+ dev_id->serdes_irq = 0;
2513
+
2514
+ return err;
2515
+}
2516
+
21582517 static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
21592518 bool on)
21602519 {
2161
- if (chip->info->ops->serdes_power)
2162
- return chip->info->ops->serdes_power(chip, port, on);
2520
+ u8 lane;
2521
+ int err;
21632522
2164
- return 0;
2523
+ lane = mv88e6xxx_serdes_get_lane(chip, port);
2524
+ if (!lane)
2525
+ return 0;
2526
+
2527
+ if (on) {
2528
+ err = mv88e6xxx_serdes_power_up(chip, port, lane);
2529
+ if (err)
2530
+ return err;
2531
+
2532
+ err = mv88e6xxx_serdes_irq_request(chip, port, lane);
2533
+ } else {
2534
+ err = mv88e6xxx_serdes_irq_free(chip, port, lane);
2535
+ if (err)
2536
+ return err;
2537
+
2538
+ err = mv88e6xxx_serdes_power_down(chip, port, lane);
2539
+ }
2540
+
2541
+ return err;
21652542 }
21662543
21672544 static int mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip *chip, int port)
....@@ -2188,7 +2565,14 @@
21882565
21892566 if (chip->info->ops->set_egress_port) {
21902567 err = chip->info->ops->set_egress_port(chip,
2191
- upstream_port);
2568
+ MV88E6XXX_EGRESS_DIR_INGRESS,
2569
+ upstream_port);
2570
+ if (err)
2571
+ return err;
2572
+
2573
+ err = chip->info->ops->set_egress_port(chip,
2574
+ MV88E6XXX_EGRESS_DIR_EGRESS,
2575
+ upstream_port);
21922576 if (err)
21932577 return err;
21942578 }
....@@ -2237,9 +2621,14 @@
22372621 * If this is the upstream port for this switch, enable
22382622 * forwarding of unknown unicasts and multicasts.
22392623 */
2240
- reg = MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP |
2241
- MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
2624
+ reg = MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
22422625 MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
2626
+ /* Forward any IPv4 IGMP or IPv6 MLD frames received
2627
+ * by a USER port to the CPU port to allow snooping.
2628
+ */
2629
+ if (dsa_is_user_port(ds, port))
2630
+ reg |= MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP;
2631
+
22432632 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
22442633 if (err)
22452634 return err;
....@@ -2252,18 +2641,8 @@
22522641 if (err)
22532642 return err;
22542643
2255
- /* Enable the SERDES interface for DSA and CPU ports. Normal
2256
- * ports SERDES are enabled when the port is enabled, thus
2257
- * saving a bit of power.
2258
- */
2259
- if ((dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))) {
2260
- err = mv88e6xxx_serdes_power(chip, port, true);
2261
- if (err)
2262
- return err;
2263
- }
2264
-
2265
- /* Port Control 2: don't force a good FCS, set the maximum frame size to
2266
- * 10240 bytes, disable 802.1q tags checking, don't discard tagged or
2644
+ /* Port Control 2: don't force a good FCS, set the MTU size to
2645
+ * 10222 bytes, disable 802.1q tags checking, don't discard tagged or
22672646 * untagged frames on this port, do a destination address lookup on all
22682647 * received packets as usual, disable ARP mirroring and don't send a
22692648 * copy of all transmitted/received frames on this port to the CPU.
....@@ -2282,7 +2661,7 @@
22822661 return err;
22832662
22842663 if (chip->info->ops->port_set_jumbo_size) {
2285
- err = chip->info->ops->port_set_jumbo_size(chip, port, 10240);
2664
+ err = chip->info->ops->port_set_jumbo_size(chip, port, 10218);
22862665 if (err)
22872666 return err;
22882667 }
....@@ -2338,9 +2717,11 @@
23382717 return err;
23392718 }
23402719
2341
- err = mv88e6xxx_setup_message_port(chip, port);
2342
- if (err)
2343
- return err;
2720
+ if (chip->info->ops->port_setup_message_port) {
2721
+ err = chip->info->ops->port_setup_message_port(chip, port);
2722
+ if (err)
2723
+ return err;
2724
+ }
23442725
23452726 /* Port based VLAN map: give each port the same default address
23462727 * database, and allow bidirectional communication between the
....@@ -2360,38 +2741,67 @@
23602741 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 0);
23612742 }
23622743
2744
+static int mv88e6xxx_get_max_mtu(struct dsa_switch *ds, int port)
2745
+{
2746
+ struct mv88e6xxx_chip *chip = ds->priv;
2747
+
2748
+ if (chip->info->ops->port_set_jumbo_size)
2749
+ return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
2750
+ else if (chip->info->ops->set_max_frame_size)
2751
+ return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
2752
+ return ETH_DATA_LEN;
2753
+}
2754
+
2755
+static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
2756
+{
2757
+ struct mv88e6xxx_chip *chip = ds->priv;
2758
+ int ret = 0;
2759
+
2760
+ /* For families where we don't know how to alter the MTU,
2761
+ * just accept any value up to ETH_DATA_LEN
2762
+ */
2763
+ if (!chip->info->ops->port_set_jumbo_size &&
2764
+ !chip->info->ops->set_max_frame_size) {
2765
+ if (new_mtu > ETH_DATA_LEN)
2766
+ return -EINVAL;
2767
+
2768
+ return 0;
2769
+ }
2770
+
2771
+ if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
2772
+ new_mtu += EDSA_HLEN;
2773
+
2774
+ mv88e6xxx_reg_lock(chip);
2775
+ if (chip->info->ops->port_set_jumbo_size)
2776
+ ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu);
2777
+ else if (chip->info->ops->set_max_frame_size)
2778
+ ret = chip->info->ops->set_max_frame_size(chip, new_mtu);
2779
+ mv88e6xxx_reg_unlock(chip);
2780
+
2781
+ return ret;
2782
+}
2783
+
23632784 static int mv88e6xxx_port_enable(struct dsa_switch *ds, int port,
23642785 struct phy_device *phydev)
23652786 {
23662787 struct mv88e6xxx_chip *chip = ds->priv;
23672788 int err;
23682789
2369
- mutex_lock(&chip->reg_lock);
2370
-
2790
+ mv88e6xxx_reg_lock(chip);
23712791 err = mv88e6xxx_serdes_power(chip, port, true);
2372
-
2373
- if (!err && chip->info->ops->serdes_irq_setup)
2374
- err = chip->info->ops->serdes_irq_setup(chip, port);
2375
-
2376
- mutex_unlock(&chip->reg_lock);
2792
+ mv88e6xxx_reg_unlock(chip);
23772793
23782794 return err;
23792795 }
23802796
2381
-static void mv88e6xxx_port_disable(struct dsa_switch *ds, int port,
2382
- struct phy_device *phydev)
2797
+static void mv88e6xxx_port_disable(struct dsa_switch *ds, int port)
23832798 {
23842799 struct mv88e6xxx_chip *chip = ds->priv;
23852800
2386
- mutex_lock(&chip->reg_lock);
2387
-
2388
- if (chip->info->ops->serdes_irq_free)
2389
- chip->info->ops->serdes_irq_free(chip, port);
2390
-
2801
+ mv88e6xxx_reg_lock(chip);
23912802 if (mv88e6xxx_serdes_power(chip, port, false))
23922803 dev_err(chip->dev, "failed to power off SERDES\n");
2393
-
2394
- mutex_unlock(&chip->reg_lock);
2804
+ mv88e6xxx_reg_unlock(chip);
23952805 }
23962806
23972807 static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds,
....@@ -2400,9 +2810,9 @@
24002810 struct mv88e6xxx_chip *chip = ds->priv;
24012811 int err;
24022812
2403
- mutex_lock(&chip->reg_lock);
2813
+ mv88e6xxx_reg_lock(chip);
24042814 err = mv88e6xxx_g1_atu_set_age_time(chip, ageing_time);
2405
- mutex_unlock(&chip->reg_lock);
2815
+ mv88e6xxx_reg_unlock(chip);
24062816
24072817 return err;
24082818 }
....@@ -2421,58 +2831,6 @@
24212831 return mv88e6xxx_g1_stats_clear(chip);
24222832 }
24232833
2424
-/* The mv88e6390 has some hidden registers used for debug and
2425
- * development. The errata also makes use of them.
2426
- */
2427
-static int mv88e6390_hidden_write(struct mv88e6xxx_chip *chip, int port,
2428
- int reg, u16 val)
2429
-{
2430
- u16 ctrl;
2431
- int err;
2432
-
2433
- err = mv88e6xxx_port_write(chip, PORT_RESERVED_1A_DATA_PORT,
2434
- PORT_RESERVED_1A, val);
2435
- if (err)
2436
- return err;
2437
-
2438
- ctrl = PORT_RESERVED_1A_BUSY | PORT_RESERVED_1A_WRITE |
2439
- PORT_RESERVED_1A_BLOCK | port << PORT_RESERVED_1A_PORT_SHIFT |
2440
- reg;
2441
-
2442
- return mv88e6xxx_port_write(chip, PORT_RESERVED_1A_CTRL_PORT,
2443
- PORT_RESERVED_1A, ctrl);
2444
-}
2445
-
2446
-static int mv88e6390_hidden_wait(struct mv88e6xxx_chip *chip)
2447
-{
2448
- return mv88e6xxx_wait(chip, PORT_RESERVED_1A_CTRL_PORT,
2449
- PORT_RESERVED_1A, PORT_RESERVED_1A_BUSY);
2450
-}
2451
-
2452
-
2453
-static int mv88e6390_hidden_read(struct mv88e6xxx_chip *chip, int port,
2454
- int reg, u16 *val)
2455
-{
2456
- u16 ctrl;
2457
- int err;
2458
-
2459
- ctrl = PORT_RESERVED_1A_BUSY | PORT_RESERVED_1A_READ |
2460
- PORT_RESERVED_1A_BLOCK | port << PORT_RESERVED_1A_PORT_SHIFT |
2461
- reg;
2462
-
2463
- err = mv88e6xxx_port_write(chip, PORT_RESERVED_1A_CTRL_PORT,
2464
- PORT_RESERVED_1A, ctrl);
2465
- if (err)
2466
- return err;
2467
-
2468
- err = mv88e6390_hidden_wait(chip);
2469
- if (err)
2470
- return err;
2471
-
2472
- return mv88e6xxx_port_read(chip, PORT_RESERVED_1A_DATA_PORT,
2473
- PORT_RESERVED_1A, val);
2474
-}
2475
-
24762834 /* Check if the errata has already been applied. */
24772835 static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip)
24782836 {
....@@ -2481,7 +2839,7 @@
24812839 u16 val;
24822840
24832841 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
2484
- err = mv88e6390_hidden_read(chip, port, 0, &val);
2842
+ err = mv88e6xxx_port_hidden_read(chip, 0xf, port, 0, &val);
24852843 if (err) {
24862844 dev_err(chip->dev,
24872845 "Error reading hidden register: %d\n", err);
....@@ -2514,12 +2872,19 @@
25142872 }
25152873
25162874 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
2517
- err = mv88e6390_hidden_write(chip, port, 0, 0x01c0);
2875
+ err = mv88e6xxx_port_hidden_write(chip, 0xf, port, 0, 0x01c0);
25182876 if (err)
25192877 return err;
25202878 }
25212879
25222880 return mv88e6xxx_software_reset(chip);
2881
+}
2882
+
2883
+static void mv88e6xxx_teardown(struct dsa_switch *ds)
2884
+{
2885
+ mv88e6xxx_teardown_devlink_params(ds);
2886
+ dsa_devlink_resources_unregister(ds);
2887
+ mv88e6xxx_teardown_devlink_regions(ds);
25232888 }
25242889
25252890 static int mv88e6xxx_setup(struct dsa_switch *ds)
....@@ -2532,7 +2897,7 @@
25322897 chip->ds = ds;
25332898 ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip);
25342899
2535
- mutex_lock(&chip->reg_lock);
2900
+ mv88e6xxx_reg_lock(chip);
25362901
25372902 if (chip->info->ops->setup_errata) {
25382903 err = chip->info->ops->setup_errata(chip);
....@@ -2555,6 +2920,13 @@
25552920 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
25562921 if (dsa_is_unused_port(ds, i))
25572922 continue;
2923
+
2924
+ /* Prevent the use of an invalid port. */
2925
+ if (mv88e6xxx_is_invalid_port(chip, i)) {
2926
+ dev_err(chip->dev, "port %d is invalid\n", i);
2927
+ err = -EINVAL;
2928
+ goto unlock;
2929
+ }
25582930
25592931 err = mv88e6xxx_setup_port(chip, i);
25602932 if (err)
....@@ -2629,7 +3001,34 @@
26293001 goto unlock;
26303002
26313003 unlock:
2632
- mutex_unlock(&chip->reg_lock);
3004
+ mv88e6xxx_reg_unlock(chip);
3005
+
3006
+ if (err)
3007
+ return err;
3008
+
3009
+ /* Have to be called without holding the register lock, since
3010
+ * they take the devlink lock, and we later take the locks in
3011
+ * the reverse order when getting/setting parameters or
3012
+ * resource occupancy.
3013
+ */
3014
+ err = mv88e6xxx_setup_devlink_resources(ds);
3015
+ if (err)
3016
+ return err;
3017
+
3018
+ err = mv88e6xxx_setup_devlink_params(ds);
3019
+ if (err)
3020
+ goto out_resources;
3021
+
3022
+ err = mv88e6xxx_setup_devlink_regions(ds);
3023
+ if (err)
3024
+ goto out_params;
3025
+
3026
+ return 0;
3027
+
3028
+out_params:
3029
+ mv88e6xxx_teardown_devlink_params(ds);
3030
+out_resources:
3031
+ dsa_devlink_resources_unregister(ds);
26333032
26343033 return err;
26353034 }
....@@ -2651,9 +3050,9 @@
26513050 if (!chip->info->ops->phy_read)
26523051 return -EOPNOTSUPP;
26533052
2654
- mutex_lock(&chip->reg_lock);
3053
+ mv88e6xxx_reg_lock(chip);
26553054 err = chip->info->ops->phy_read(chip, bus, phy, reg, &val);
2656
- mutex_unlock(&chip->reg_lock);
3055
+ mv88e6xxx_reg_unlock(chip);
26573056
26583057 /* Some internal PHYs don't have a model number. */
26593058 if (reg == MII_PHYSID2 && !(val & 0x3f0) &&
....@@ -2675,9 +3074,9 @@
26753074 if (!chip->info->ops->phy_write)
26763075 return -EOPNOTSUPP;
26773076
2678
- mutex_lock(&chip->reg_lock);
3077
+ mv88e6xxx_reg_lock(chip);
26793078 err = chip->info->ops->phy_write(chip, bus, phy, reg, val);
2680
- mutex_unlock(&chip->reg_lock);
3079
+ mv88e6xxx_reg_unlock(chip);
26813080
26823081 return err;
26833082 }
....@@ -2692,15 +3091,15 @@
26923091 int err;
26933092
26943093 if (external) {
2695
- mutex_lock(&chip->reg_lock);
3094
+ mv88e6xxx_reg_lock(chip);
26963095 err = mv88e6xxx_g2_scratch_gpio_set_smi(chip, true);
2697
- mutex_unlock(&chip->reg_lock);
3096
+ mv88e6xxx_reg_unlock(chip);
26983097
26993098 if (err)
27003099 return err;
27013100 }
27023101
2703
- bus = devm_mdiobus_alloc_size(chip->dev, sizeof(*mdio_bus));
3102
+ bus = mdiobus_alloc_size(sizeof(*mdio_bus));
27043103 if (!bus)
27053104 return -ENOMEM;
27063105
....@@ -2725,14 +3124,14 @@
27253124 if (!external) {
27263125 err = mv88e6xxx_g2_irq_mdio_setup(chip, bus);
27273126 if (err)
2728
- return err;
3127
+ goto out;
27293128 }
27303129
27313130 err = of_mdiobus_register(bus, np);
27323131 if (err) {
27333132 dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err);
27343133 mv88e6xxx_g2_irq_mdio_free(chip, bus);
2735
- return err;
3134
+ goto out;
27363135 }
27373136
27383137 if (external)
....@@ -2741,34 +3140,32 @@
27413140 list_add(&mdio_bus->list, &chip->mdios);
27423141
27433142 return 0;
2744
-}
27453143
2746
-static const struct of_device_id mv88e6xxx_mdio_external_match[] = {
2747
- { .compatible = "marvell,mv88e6xxx-mdio-external",
2748
- .data = (void *)true },
2749
- { },
2750
-};
3144
+out:
3145
+ mdiobus_free(bus);
3146
+ return err;
3147
+}
27513148
27523149 static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
27533150
27543151 {
2755
- struct mv88e6xxx_mdio_bus *mdio_bus;
3152
+ struct mv88e6xxx_mdio_bus *mdio_bus, *p;
27563153 struct mii_bus *bus;
27573154
2758
- list_for_each_entry(mdio_bus, &chip->mdios, list) {
3155
+ list_for_each_entry_safe(mdio_bus, p, &chip->mdios, list) {
27593156 bus = mdio_bus->bus;
27603157
27613158 if (!mdio_bus->external)
27623159 mv88e6xxx_g2_irq_mdio_free(chip, bus);
27633160
27643161 mdiobus_unregister(bus);
3162
+ mdiobus_free(bus);
27653163 }
27663164 }
27673165
27683166 static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip,
27693167 struct device_node *np)
27703168 {
2771
- const struct of_device_id *match;
27723169 struct device_node *child;
27733170 int err;
27743171
....@@ -2778,6 +3175,7 @@
27783175 */
27793176 child = of_get_child_by_name(np, "mdio");
27803177 err = mv88e6xxx_mdio_register(chip, child, false);
3178
+ of_node_put(child);
27813179 if (err)
27823180 return err;
27833181
....@@ -2786,11 +3184,12 @@
27863184 * bus.
27873185 */
27883186 for_each_available_child_of_node(np, child) {
2789
- match = of_match_node(mv88e6xxx_mdio_external_match, child);
2790
- if (match) {
3187
+ if (of_device_is_compatible(
3188
+ child, "marvell,mv88e6xxx-mdio-external")) {
27913189 err = mv88e6xxx_mdio_register(chip, child, true);
27923190 if (err) {
27933191 mv88e6xxx_mdios_unregister(chip);
3192
+ of_node_put(child);
27943193 return err;
27953194 }
27963195 }
....@@ -2815,9 +3214,9 @@
28153214 if (!chip->info->ops->get_eeprom)
28163215 return -EOPNOTSUPP;
28173216
2818
- mutex_lock(&chip->reg_lock);
3217
+ mv88e6xxx_reg_lock(chip);
28193218 err = chip->info->ops->get_eeprom(chip, eeprom, data);
2820
- mutex_unlock(&chip->reg_lock);
3219
+ mv88e6xxx_reg_unlock(chip);
28213220
28223221 if (err)
28233222 return err;
....@@ -2839,9 +3238,9 @@
28393238 if (eeprom->magic != 0xc3ec4951)
28403239 return -EINVAL;
28413240
2842
- mutex_lock(&chip->reg_lock);
3241
+ mv88e6xxx_reg_lock(chip);
28433242 err = chip->info->ops->set_eeprom(chip, eeprom, data);
2844
- mutex_unlock(&chip->reg_lock);
3243
+ mv88e6xxx_reg_unlock(chip);
28453244
28463245 return err;
28473246 }
....@@ -2855,8 +3254,7 @@
28553254 .phy_read = mv88e6185_phy_ppu_read,
28563255 .phy_write = mv88e6185_phy_ppu_write,
28573256 .port_set_link = mv88e6xxx_port_set_link,
2858
- .port_set_duplex = mv88e6xxx_port_set_duplex,
2859
- .port_set_speed = mv88e6185_port_set_speed,
3257
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
28603258 .port_tag_remap = mv88e6095_port_tag_remap,
28613259 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
28623260 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -2865,8 +3263,8 @@
28653263 .port_pause_limit = mv88e6097_port_pause_limit,
28663264 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
28673265 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2868
- .port_link_state = mv88e6352_port_link_state,
28693266 .port_get_cmode = mv88e6185_port_get_cmode,
3267
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
28703268 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
28713269 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
28723270 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -2884,6 +3282,7 @@
28843282 .vtu_getnext = mv88e6352_g1_vtu_getnext,
28853283 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
28863284 .phylink_validate = mv88e6185_phylink_validate,
3285
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
28873286 };
28883287
28893288 static const struct mv88e6xxx_ops mv88e6095_ops = {
....@@ -2894,13 +3293,12 @@
28943293 .phy_read = mv88e6185_phy_ppu_read,
28953294 .phy_write = mv88e6185_phy_ppu_write,
28963295 .port_set_link = mv88e6xxx_port_set_link,
2897
- .port_set_duplex = mv88e6xxx_port_set_duplex,
2898
- .port_set_speed = mv88e6185_port_set_speed,
3296
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
28993297 .port_set_frame_mode = mv88e6085_port_set_frame_mode,
29003298 .port_set_egress_floods = mv88e6185_port_set_egress_floods,
29013299 .port_set_upstream_port = mv88e6095_port_set_upstream_port,
2902
- .port_link_state = mv88e6185_port_link_state,
29033300 .port_get_cmode = mv88e6185_port_get_cmode,
3301
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
29043302 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
29053303 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
29063304 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -2913,6 +3311,7 @@
29133311 .vtu_getnext = mv88e6185_g1_vtu_getnext,
29143312 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
29153313 .phylink_validate = mv88e6185_phylink_validate,
3314
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
29163315 };
29173316
29183317 static const struct mv88e6xxx_ops mv88e6097_ops = {
....@@ -2924,9 +3323,9 @@
29243323 .phy_read = mv88e6xxx_g2_smi_phy_read,
29253324 .phy_write = mv88e6xxx_g2_smi_phy_write,
29263325 .port_set_link = mv88e6xxx_port_set_link,
2927
- .port_set_duplex = mv88e6xxx_port_set_duplex,
2928
- .port_set_speed = mv88e6185_port_set_speed,
3326
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
29293327 .port_tag_remap = mv88e6095_port_tag_remap,
3328
+ .port_set_policy = mv88e6352_port_set_policy,
29303329 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
29313330 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
29323331 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -2934,8 +3333,8 @@
29343333 .port_pause_limit = mv88e6097_port_pause_limit,
29353334 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
29363335 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2937
- .port_link_state = mv88e6352_port_link_state,
29383336 .port_get_cmode = mv88e6185_port_get_cmode,
3337
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
29393338 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
29403339 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
29413340 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -2951,6 +3350,7 @@
29513350 .vtu_getnext = mv88e6352_g1_vtu_getnext,
29523351 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
29533352 .phylink_validate = mv88e6185_phylink_validate,
3353
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
29543354 };
29553355
29563356 static const struct mv88e6xxx_ops mv88e6123_ops = {
....@@ -2962,14 +3362,13 @@
29623362 .phy_read = mv88e6xxx_g2_smi_phy_read,
29633363 .phy_write = mv88e6xxx_g2_smi_phy_write,
29643364 .port_set_link = mv88e6xxx_port_set_link,
2965
- .port_set_duplex = mv88e6xxx_port_set_duplex,
2966
- .port_set_speed = mv88e6185_port_set_speed,
3365
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
29673366 .port_set_frame_mode = mv88e6085_port_set_frame_mode,
29683367 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
29693368 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
29703369 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2971
- .port_link_state = mv88e6352_port_link_state,
29723370 .port_get_cmode = mv88e6185_port_get_cmode,
3371
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
29733372 .stats_snapshot = mv88e6320_g1_stats_snapshot,
29743373 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
29753374 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -2981,9 +3380,12 @@
29813380 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
29823381 .pot_clear = mv88e6xxx_g2_pot_clear,
29833382 .reset = mv88e6352_g1_reset,
3383
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3384
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
29843385 .vtu_getnext = mv88e6352_g1_vtu_getnext,
29853386 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
29863387 .phylink_validate = mv88e6185_phylink_validate,
3388
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
29873389 };
29883390
29893391 static const struct mv88e6xxx_ops mv88e6131_ops = {
....@@ -2994,8 +3396,7 @@
29943396 .phy_read = mv88e6185_phy_ppu_read,
29953397 .phy_write = mv88e6185_phy_ppu_write,
29963398 .port_set_link = mv88e6xxx_port_set_link,
2997
- .port_set_duplex = mv88e6xxx_port_set_duplex,
2998
- .port_set_speed = mv88e6185_port_set_speed,
3399
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
29993400 .port_tag_remap = mv88e6095_port_tag_remap,
30003401 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
30013402 .port_set_egress_floods = mv88e6185_port_set_egress_floods,
....@@ -3005,8 +3406,8 @@
30053406 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
30063407 .port_pause_limit = mv88e6097_port_pause_limit,
30073408 .port_set_pause = mv88e6185_port_set_pause,
3008
- .port_link_state = mv88e6352_port_link_state,
30093409 .port_get_cmode = mv88e6185_port_get_cmode,
3410
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
30103411 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
30113412 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
30123413 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3036,9 +3437,9 @@
30363437 .phy_read = mv88e6xxx_g2_smi_phy_read,
30373438 .phy_write = mv88e6xxx_g2_smi_phy_write,
30383439 .port_set_link = mv88e6xxx_port_set_link,
3039
- .port_set_duplex = mv88e6xxx_port_set_duplex,
30403440 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3041
- .port_set_speed = mv88e6341_port_set_speed,
3441
+ .port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
3442
+ .port_max_speed_mode = mv88e6341_port_max_speed_mode,
30423443 .port_tag_remap = mv88e6095_port_tag_remap,
30433444 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
30443445 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3048,8 +3449,9 @@
30483449 .port_pause_limit = mv88e6097_port_pause_limit,
30493450 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
30503451 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3051
- .port_link_state = mv88e6352_port_link_state,
30523452 .port_get_cmode = mv88e6352_port_get_cmode,
3453
+ .port_set_cmode = mv88e6341_port_set_cmode,
3454
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
30533455 .stats_snapshot = mv88e6390_g1_stats_snapshot,
30543456 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
30553457 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3061,11 +3463,28 @@
30613463 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
30623464 .pot_clear = mv88e6xxx_g2_pot_clear,
30633465 .reset = mv88e6352_g1_reset,
3466
+ .rmu_disable = mv88e6390_g1_rmu_disable,
3467
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3468
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
30643469 .vtu_getnext = mv88e6352_g1_vtu_getnext,
30653470 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3066
- .serdes_power = mv88e6341_serdes_power,
3471
+ .serdes_power = mv88e6390_serdes_power,
3472
+ .serdes_get_lane = mv88e6341_serdes_get_lane,
3473
+ /* Check status register pause & lpa register */
3474
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
3475
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
3476
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
3477
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
3478
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3479
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3480
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
30673481 .gpio_ops = &mv88e6352_gpio_ops,
3068
- .phylink_validate = mv88e6390_phylink_validate,
3482
+ .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
3483
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
3484
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
3485
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
3486
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
3487
+ .phylink_validate = mv88e6341_phylink_validate,
30693488 };
30703489
30713490 static const struct mv88e6xxx_ops mv88e6161_ops = {
....@@ -3077,19 +3496,17 @@
30773496 .phy_read = mv88e6xxx_g2_smi_phy_read,
30783497 .phy_write = mv88e6xxx_g2_smi_phy_write,
30793498 .port_set_link = mv88e6xxx_port_set_link,
3080
- .port_set_duplex = mv88e6xxx_port_set_duplex,
3081
- .port_set_speed = mv88e6185_port_set_speed,
3499
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
30823500 .port_tag_remap = mv88e6095_port_tag_remap,
30833501 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
30843502 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
30853503 .port_set_ether_type = mv88e6351_port_set_ether_type,
3086
- .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
30873504 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
30883505 .port_pause_limit = mv88e6097_port_pause_limit,
30893506 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
30903507 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3091
- .port_link_state = mv88e6352_port_link_state,
30923508 .port_get_cmode = mv88e6185_port_get_cmode,
3509
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
30933510 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
30943511 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
30953512 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3101,11 +3518,14 @@
31013518 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
31023519 .pot_clear = mv88e6xxx_g2_pot_clear,
31033520 .reset = mv88e6352_g1_reset,
3521
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3522
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
31043523 .vtu_getnext = mv88e6352_g1_vtu_getnext,
31053524 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
31063525 .avb_ops = &mv88e6165_avb_ops,
31073526 .ptp_ops = &mv88e6165_ptp_ops,
31083527 .phylink_validate = mv88e6185_phylink_validate,
3528
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
31093529 };
31103530
31113531 static const struct mv88e6xxx_ops mv88e6165_ops = {
....@@ -3117,12 +3537,11 @@
31173537 .phy_read = mv88e6165_phy_read,
31183538 .phy_write = mv88e6165_phy_write,
31193539 .port_set_link = mv88e6xxx_port_set_link,
3120
- .port_set_duplex = mv88e6xxx_port_set_duplex,
3121
- .port_set_speed = mv88e6185_port_set_speed,
3540
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
31223541 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
31233542 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3124
- .port_link_state = mv88e6352_port_link_state,
31253543 .port_get_cmode = mv88e6185_port_get_cmode,
3544
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
31263545 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
31273546 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
31283547 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3134,6 +3553,8 @@
31343553 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
31353554 .pot_clear = mv88e6xxx_g2_pot_clear,
31363555 .reset = mv88e6352_g1_reset,
3556
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3557
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
31373558 .vtu_getnext = mv88e6352_g1_vtu_getnext,
31383559 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
31393560 .avb_ops = &mv88e6165_avb_ops,
....@@ -3150,9 +3571,8 @@
31503571 .phy_read = mv88e6xxx_g2_smi_phy_read,
31513572 .phy_write = mv88e6xxx_g2_smi_phy_write,
31523573 .port_set_link = mv88e6xxx_port_set_link,
3153
- .port_set_duplex = mv88e6xxx_port_set_duplex,
31543574 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3155
- .port_set_speed = mv88e6185_port_set_speed,
3575
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
31563576 .port_tag_remap = mv88e6095_port_tag_remap,
31573577 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
31583578 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3162,8 +3582,8 @@
31623582 .port_pause_limit = mv88e6097_port_pause_limit,
31633583 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
31643584 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3165
- .port_link_state = mv88e6352_port_link_state,
31663585 .port_get_cmode = mv88e6352_port_get_cmode,
3586
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
31673587 .stats_snapshot = mv88e6320_g1_stats_snapshot,
31683588 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
31693589 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3175,6 +3595,8 @@
31753595 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
31763596 .pot_clear = mv88e6xxx_g2_pot_clear,
31773597 .reset = mv88e6352_g1_reset,
3598
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3599
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
31783600 .vtu_getnext = mv88e6352_g1_vtu_getnext,
31793601 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
31803602 .phylink_validate = mv88e6185_phylink_validate,
....@@ -3191,10 +3613,10 @@
31913613 .phy_read = mv88e6xxx_g2_smi_phy_read,
31923614 .phy_write = mv88e6xxx_g2_smi_phy_write,
31933615 .port_set_link = mv88e6xxx_port_set_link,
3194
- .port_set_duplex = mv88e6xxx_port_set_duplex,
31953616 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3196
- .port_set_speed = mv88e6352_port_set_speed,
3617
+ .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
31973618 .port_tag_remap = mv88e6095_port_tag_remap,
3619
+ .port_set_policy = mv88e6352_port_set_policy,
31983620 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
31993621 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
32003622 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -3203,8 +3625,8 @@
32033625 .port_pause_limit = mv88e6097_port_pause_limit,
32043626 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
32053627 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3206
- .port_link_state = mv88e6352_port_link_state,
32073628 .port_get_cmode = mv88e6352_port_get_cmode,
3629
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
32083630 .stats_snapshot = mv88e6320_g1_stats_snapshot,
32093631 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
32103632 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3217,9 +3639,18 @@
32173639 .pot_clear = mv88e6xxx_g2_pot_clear,
32183640 .reset = mv88e6352_g1_reset,
32193641 .rmu_disable = mv88e6352_g1_rmu_disable,
3642
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3643
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
32203644 .vtu_getnext = mv88e6352_g1_vtu_getnext,
32213645 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3646
+ .serdes_get_lane = mv88e6352_serdes_get_lane,
3647
+ .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
3648
+ .serdes_pcs_config = mv88e6352_serdes_pcs_config,
3649
+ .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
3650
+ .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
32223651 .serdes_power = mv88e6352_serdes_power,
3652
+ .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
3653
+ .serdes_get_regs = mv88e6352_serdes_get_regs,
32233654 .gpio_ops = &mv88e6352_gpio_ops,
32243655 .phylink_validate = mv88e6352_phylink_validate,
32253656 };
....@@ -3233,10 +3664,10 @@
32333664 .phy_read = mv88e6xxx_g2_smi_phy_read,
32343665 .phy_write = mv88e6xxx_g2_smi_phy_write,
32353666 .port_set_link = mv88e6xxx_port_set_link,
3236
- .port_set_duplex = mv88e6xxx_port_set_duplex,
32373667 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3238
- .port_set_speed = mv88e6185_port_set_speed,
3668
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
32393669 .port_tag_remap = mv88e6095_port_tag_remap,
3670
+ .port_set_policy = mv88e6352_port_set_policy,
32403671 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
32413672 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
32423673 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -3245,8 +3676,8 @@
32453676 .port_pause_limit = mv88e6097_port_pause_limit,
32463677 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
32473678 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3248
- .port_link_state = mv88e6352_port_link_state,
32493679 .port_get_cmode = mv88e6352_port_get_cmode,
3680
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
32503681 .stats_snapshot = mv88e6320_g1_stats_snapshot,
32513682 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
32523683 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3258,6 +3689,8 @@
32583689 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
32593690 .pot_clear = mv88e6xxx_g2_pot_clear,
32603691 .reset = mv88e6352_g1_reset,
3692
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3693
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
32613694 .vtu_getnext = mv88e6352_g1_vtu_getnext,
32623695 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
32633696 .phylink_validate = mv88e6185_phylink_validate,
....@@ -3274,10 +3707,10 @@
32743707 .phy_read = mv88e6xxx_g2_smi_phy_read,
32753708 .phy_write = mv88e6xxx_g2_smi_phy_write,
32763709 .port_set_link = mv88e6xxx_port_set_link,
3277
- .port_set_duplex = mv88e6xxx_port_set_duplex,
32783710 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3279
- .port_set_speed = mv88e6352_port_set_speed,
3711
+ .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
32803712 .port_tag_remap = mv88e6095_port_tag_remap,
3713
+ .port_set_policy = mv88e6352_port_set_policy,
32813714 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
32823715 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
32833716 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -3286,8 +3719,8 @@
32863719 .port_pause_limit = mv88e6097_port_pause_limit,
32873720 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
32883721 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3289
- .port_link_state = mv88e6352_port_link_state,
32903722 .port_get_cmode = mv88e6352_port_get_cmode,
3723
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
32913724 .stats_snapshot = mv88e6320_g1_stats_snapshot,
32923725 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
32933726 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3300,9 +3733,21 @@
33003733 .pot_clear = mv88e6xxx_g2_pot_clear,
33013734 .reset = mv88e6352_g1_reset,
33023735 .rmu_disable = mv88e6352_g1_rmu_disable,
3736
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3737
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
33033738 .vtu_getnext = mv88e6352_g1_vtu_getnext,
33043739 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3740
+ .serdes_get_lane = mv88e6352_serdes_get_lane,
3741
+ .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
3742
+ .serdes_pcs_config = mv88e6352_serdes_pcs_config,
3743
+ .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
3744
+ .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
33053745 .serdes_power = mv88e6352_serdes_power,
3746
+ .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
3747
+ .serdes_irq_enable = mv88e6352_serdes_irq_enable,
3748
+ .serdes_irq_status = mv88e6352_serdes_irq_status,
3749
+ .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
3750
+ .serdes_get_regs = mv88e6352_serdes_get_regs,
33063751 .gpio_ops = &mv88e6352_gpio_ops,
33073752 .phylink_validate = mv88e6352_phylink_validate,
33083753 };
....@@ -3315,15 +3760,14 @@
33153760 .phy_read = mv88e6185_phy_ppu_read,
33163761 .phy_write = mv88e6185_phy_ppu_write,
33173762 .port_set_link = mv88e6xxx_port_set_link,
3318
- .port_set_duplex = mv88e6xxx_port_set_duplex,
3319
- .port_set_speed = mv88e6185_port_set_speed,
3763
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
33203764 .port_set_frame_mode = mv88e6085_port_set_frame_mode,
33213765 .port_set_egress_floods = mv88e6185_port_set_egress_floods,
33223766 .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
33233767 .port_set_upstream_port = mv88e6095_port_set_upstream_port,
33243768 .port_set_pause = mv88e6185_port_set_pause,
3325
- .port_link_state = mv88e6185_port_link_state,
33263769 .port_get_cmode = mv88e6185_port_get_cmode,
3770
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
33273771 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
33283772 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
33293773 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3340,6 +3784,7 @@
33403784 .vtu_getnext = mv88e6185_g1_vtu_getnext,
33413785 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
33423786 .phylink_validate = mv88e6185_phylink_validate,
3787
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
33433788 };
33443789
33453790 static const struct mv88e6xxx_ops mv88e6190_ops = {
....@@ -3352,18 +3797,21 @@
33523797 .phy_read = mv88e6xxx_g2_smi_phy_read,
33533798 .phy_write = mv88e6xxx_g2_smi_phy_write,
33543799 .port_set_link = mv88e6xxx_port_set_link,
3355
- .port_set_duplex = mv88e6xxx_port_set_duplex,
33563800 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3357
- .port_set_speed = mv88e6390_port_set_speed,
3801
+ .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
3802
+ .port_max_speed_mode = mv88e6390_port_max_speed_mode,
33583803 .port_tag_remap = mv88e6390_port_tag_remap,
3804
+ .port_set_policy = mv88e6352_port_set_policy,
33593805 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
33603806 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
33613807 .port_set_ether_type = mv88e6351_port_set_ether_type,
3808
+ .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
33623809 .port_pause_limit = mv88e6390_port_pause_limit,
33633810 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
33643811 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3365
- .port_link_state = mv88e6352_port_link_state,
33663812 .port_get_cmode = mv88e6352_port_get_cmode,
3813
+ .port_set_cmode = mv88e6390_port_set_cmode,
3814
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
33673815 .stats_snapshot = mv88e6390_g1_stats_snapshot,
33683816 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
33693817 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3376,11 +3824,24 @@
33763824 .pot_clear = mv88e6xxx_g2_pot_clear,
33773825 .reset = mv88e6352_g1_reset,
33783826 .rmu_disable = mv88e6390_g1_rmu_disable,
3827
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3828
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
33793829 .vtu_getnext = mv88e6390_g1_vtu_getnext,
33803830 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
33813831 .serdes_power = mv88e6390_serdes_power,
3382
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3383
- .serdes_irq_free = mv88e6390_serdes_irq_free,
3832
+ .serdes_get_lane = mv88e6390_serdes_get_lane,
3833
+ /* Check status register pause & lpa register */
3834
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
3835
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
3836
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
3837
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
3838
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3839
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3840
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
3841
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
3842
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
3843
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
3844
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
33843845 .gpio_ops = &mv88e6352_gpio_ops,
33853846 .phylink_validate = mv88e6390_phylink_validate,
33863847 };
....@@ -3395,18 +3856,21 @@
33953856 .phy_read = mv88e6xxx_g2_smi_phy_read,
33963857 .phy_write = mv88e6xxx_g2_smi_phy_write,
33973858 .port_set_link = mv88e6xxx_port_set_link,
3398
- .port_set_duplex = mv88e6xxx_port_set_duplex,
33993859 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3400
- .port_set_speed = mv88e6390x_port_set_speed,
3860
+ .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
3861
+ .port_max_speed_mode = mv88e6390x_port_max_speed_mode,
34013862 .port_tag_remap = mv88e6390_port_tag_remap,
3863
+ .port_set_policy = mv88e6352_port_set_policy,
34023864 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
34033865 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
34043866 .port_set_ether_type = mv88e6351_port_set_ether_type,
3867
+ .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
34053868 .port_pause_limit = mv88e6390_port_pause_limit,
34063869 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
34073870 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3408
- .port_link_state = mv88e6352_port_link_state,
34093871 .port_get_cmode = mv88e6352_port_get_cmode,
3872
+ .port_set_cmode = mv88e6390x_port_set_cmode,
3873
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
34103874 .stats_snapshot = mv88e6390_g1_stats_snapshot,
34113875 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
34123876 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3419,11 +3883,24 @@
34193883 .pot_clear = mv88e6xxx_g2_pot_clear,
34203884 .reset = mv88e6352_g1_reset,
34213885 .rmu_disable = mv88e6390_g1_rmu_disable,
3886
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3887
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
34223888 .vtu_getnext = mv88e6390_g1_vtu_getnext,
34233889 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
3424
- .serdes_power = mv88e6390x_serdes_power,
3425
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3426
- .serdes_irq_free = mv88e6390_serdes_irq_free,
3890
+ .serdes_power = mv88e6390_serdes_power,
3891
+ .serdes_get_lane = mv88e6390x_serdes_get_lane,
3892
+ /* Check status register pause & lpa register */
3893
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
3894
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
3895
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
3896
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
3897
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3898
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3899
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
3900
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
3901
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
3902
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
3903
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
34273904 .gpio_ops = &mv88e6352_gpio_ops,
34283905 .phylink_validate = mv88e6390x_phylink_validate,
34293906 };
....@@ -3438,9 +3915,9 @@
34383915 .phy_read = mv88e6xxx_g2_smi_phy_read,
34393916 .phy_write = mv88e6xxx_g2_smi_phy_write,
34403917 .port_set_link = mv88e6xxx_port_set_link,
3441
- .port_set_duplex = mv88e6xxx_port_set_duplex,
34423918 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3443
- .port_set_speed = mv88e6390_port_set_speed,
3919
+ .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
3920
+ .port_max_speed_mode = mv88e6390_port_max_speed_mode,
34443921 .port_tag_remap = mv88e6390_port_tag_remap,
34453922 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
34463923 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3448,8 +3925,9 @@
34483925 .port_pause_limit = mv88e6390_port_pause_limit,
34493926 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
34503927 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3451
- .port_link_state = mv88e6352_port_link_state,
34523928 .port_get_cmode = mv88e6352_port_get_cmode,
3929
+ .port_set_cmode = mv88e6390_port_set_cmode,
3930
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
34533931 .stats_snapshot = mv88e6390_g1_stats_snapshot,
34543932 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
34553933 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3462,11 +3940,24 @@
34623940 .pot_clear = mv88e6xxx_g2_pot_clear,
34633941 .reset = mv88e6352_g1_reset,
34643942 .rmu_disable = mv88e6390_g1_rmu_disable,
3943
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3944
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
34653945 .vtu_getnext = mv88e6390_g1_vtu_getnext,
34663946 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
34673947 .serdes_power = mv88e6390_serdes_power,
3468
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3469
- .serdes_irq_free = mv88e6390_serdes_irq_free,
3948
+ .serdes_get_lane = mv88e6390_serdes_get_lane,
3949
+ /* Check status register pause & lpa register */
3950
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
3951
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
3952
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
3953
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
3954
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3955
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3956
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
3957
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
3958
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
3959
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
3960
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
34703961 .avb_ops = &mv88e6390_avb_ops,
34713962 .ptp_ops = &mv88e6352_ptp_ops,
34723963 .phylink_validate = mv88e6390_phylink_validate,
....@@ -3483,10 +3974,10 @@
34833974 .phy_read = mv88e6xxx_g2_smi_phy_read,
34843975 .phy_write = mv88e6xxx_g2_smi_phy_write,
34853976 .port_set_link = mv88e6xxx_port_set_link,
3486
- .port_set_duplex = mv88e6xxx_port_set_duplex,
34873977 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3488
- .port_set_speed = mv88e6352_port_set_speed,
3978
+ .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
34893979 .port_tag_remap = mv88e6095_port_tag_remap,
3980
+ .port_set_policy = mv88e6352_port_set_policy,
34903981 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
34913982 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
34923983 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -3495,8 +3986,8 @@
34953986 .port_pause_limit = mv88e6097_port_pause_limit,
34963987 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
34973988 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3498
- .port_link_state = mv88e6352_port_link_state,
34993989 .port_get_cmode = mv88e6352_port_get_cmode,
3990
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
35003991 .stats_snapshot = mv88e6320_g1_stats_snapshot,
35013992 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
35023993 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3509,13 +4000,63 @@
35094000 .pot_clear = mv88e6xxx_g2_pot_clear,
35104001 .reset = mv88e6352_g1_reset,
35114002 .rmu_disable = mv88e6352_g1_rmu_disable,
4003
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4004
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
35124005 .vtu_getnext = mv88e6352_g1_vtu_getnext,
35134006 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4007
+ .serdes_get_lane = mv88e6352_serdes_get_lane,
4008
+ .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
4009
+ .serdes_pcs_config = mv88e6352_serdes_pcs_config,
4010
+ .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
4011
+ .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
35144012 .serdes_power = mv88e6352_serdes_power,
4013
+ .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
4014
+ .serdes_irq_enable = mv88e6352_serdes_irq_enable,
4015
+ .serdes_irq_status = mv88e6352_serdes_irq_status,
4016
+ .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
4017
+ .serdes_get_regs = mv88e6352_serdes_get_regs,
35154018 .gpio_ops = &mv88e6352_gpio_ops,
35164019 .avb_ops = &mv88e6352_avb_ops,
35174020 .ptp_ops = &mv88e6352_ptp_ops,
35184021 .phylink_validate = mv88e6352_phylink_validate,
4022
+};
4023
+
4024
+static const struct mv88e6xxx_ops mv88e6250_ops = {
4025
+ /* MV88E6XXX_FAMILY_6250 */
4026
+ .ieee_pri_map = mv88e6250_g1_ieee_pri_map,
4027
+ .ip_pri_map = mv88e6085_g1_ip_pri_map,
4028
+ .irl_init_all = mv88e6352_g2_irl_init_all,
4029
+ .get_eeprom = mv88e6xxx_g2_get_eeprom16,
4030
+ .set_eeprom = mv88e6xxx_g2_set_eeprom16,
4031
+ .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4032
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
4033
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
4034
+ .port_set_link = mv88e6xxx_port_set_link,
4035
+ .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4036
+ .port_set_speed_duplex = mv88e6250_port_set_speed_duplex,
4037
+ .port_tag_remap = mv88e6095_port_tag_remap,
4038
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4039
+ .port_set_egress_floods = mv88e6352_port_set_egress_floods,
4040
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
4041
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4042
+ .port_pause_limit = mv88e6097_port_pause_limit,
4043
+ .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4044
+ .stats_snapshot = mv88e6320_g1_stats_snapshot,
4045
+ .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4046
+ .stats_get_sset_count = mv88e6250_stats_get_sset_count,
4047
+ .stats_get_strings = mv88e6250_stats_get_strings,
4048
+ .stats_get_stats = mv88e6250_stats_get_stats,
4049
+ .set_cpu_port = mv88e6095_g1_set_cpu_port,
4050
+ .set_egress_port = mv88e6095_g1_set_egress_port,
4051
+ .watchdog_ops = &mv88e6250_watchdog_ops,
4052
+ .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4053
+ .pot_clear = mv88e6xxx_g2_pot_clear,
4054
+ .reset = mv88e6250_g1_reset,
4055
+ .vtu_getnext = mv88e6250_g1_vtu_getnext,
4056
+ .vtu_loadpurge = mv88e6250_g1_vtu_loadpurge,
4057
+ .avb_ops = &mv88e6352_avb_ops,
4058
+ .ptp_ops = &mv88e6250_ptp_ops,
4059
+ .phylink_validate = mv88e6065_phylink_validate,
35194060 };
35204061
35214062 static const struct mv88e6xxx_ops mv88e6290_ops = {
....@@ -3528,19 +4069,20 @@
35284069 .phy_read = mv88e6xxx_g2_smi_phy_read,
35294070 .phy_write = mv88e6xxx_g2_smi_phy_write,
35304071 .port_set_link = mv88e6xxx_port_set_link,
3531
- .port_set_duplex = mv88e6xxx_port_set_duplex,
35324072 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3533
- .port_set_speed = mv88e6390_port_set_speed,
4073
+ .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
4074
+ .port_max_speed_mode = mv88e6390_port_max_speed_mode,
35344075 .port_tag_remap = mv88e6390_port_tag_remap,
4076
+ .port_set_policy = mv88e6352_port_set_policy,
35354077 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
35364078 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
35374079 .port_set_ether_type = mv88e6351_port_set_ether_type,
35384080 .port_pause_limit = mv88e6390_port_pause_limit,
3539
- .port_set_cmode = mv88e6390x_port_set_cmode,
35404081 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
35414082 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3542
- .port_link_state = mv88e6352_port_link_state,
35434083 .port_get_cmode = mv88e6352_port_get_cmode,
4084
+ .port_set_cmode = mv88e6390_port_set_cmode,
4085
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
35444086 .stats_snapshot = mv88e6390_g1_stats_snapshot,
35454087 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
35464088 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3553,11 +4095,24 @@
35534095 .pot_clear = mv88e6xxx_g2_pot_clear,
35544096 .reset = mv88e6352_g1_reset,
35554097 .rmu_disable = mv88e6390_g1_rmu_disable,
4098
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4099
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
35564100 .vtu_getnext = mv88e6390_g1_vtu_getnext,
35574101 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
35584102 .serdes_power = mv88e6390_serdes_power,
3559
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3560
- .serdes_irq_free = mv88e6390_serdes_irq_free,
4103
+ .serdes_get_lane = mv88e6390_serdes_get_lane,
4104
+ /* Check status register pause & lpa register */
4105
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4106
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
4107
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4108
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4109
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4110
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
4111
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
4112
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
4113
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
4114
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4115
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
35614116 .gpio_ops = &mv88e6352_gpio_ops,
35624117 .avb_ops = &mv88e6390_avb_ops,
35634118 .ptp_ops = &mv88e6352_ptp_ops,
....@@ -3575,8 +4130,7 @@
35754130 .phy_read = mv88e6xxx_g2_smi_phy_read,
35764131 .phy_write = mv88e6xxx_g2_smi_phy_write,
35774132 .port_set_link = mv88e6xxx_port_set_link,
3578
- .port_set_duplex = mv88e6xxx_port_set_duplex,
3579
- .port_set_speed = mv88e6185_port_set_speed,
4133
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
35804134 .port_tag_remap = mv88e6095_port_tag_remap,
35814135 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
35824136 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3586,8 +4140,8 @@
35864140 .port_pause_limit = mv88e6097_port_pause_limit,
35874141 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
35884142 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3589
- .port_link_state = mv88e6352_port_link_state,
35904143 .port_get_cmode = mv88e6352_port_get_cmode,
4144
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
35914145 .stats_snapshot = mv88e6320_g1_stats_snapshot,
35924146 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
35934147 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3595,6 +4149,7 @@
35954149 .stats_get_stats = mv88e6320_stats_get_stats,
35964150 .set_cpu_port = mv88e6095_g1_set_cpu_port,
35974151 .set_egress_port = mv88e6095_g1_set_egress_port,
4152
+ .watchdog_ops = &mv88e6390_watchdog_ops,
35984153 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
35994154 .pot_clear = mv88e6xxx_g2_pot_clear,
36004155 .reset = mv88e6352_g1_reset,
....@@ -3617,8 +4172,7 @@
36174172 .phy_read = mv88e6xxx_g2_smi_phy_read,
36184173 .phy_write = mv88e6xxx_g2_smi_phy_write,
36194174 .port_set_link = mv88e6xxx_port_set_link,
3620
- .port_set_duplex = mv88e6xxx_port_set_duplex,
3621
- .port_set_speed = mv88e6185_port_set_speed,
4175
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
36224176 .port_tag_remap = mv88e6095_port_tag_remap,
36234177 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
36244178 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3628,8 +4182,8 @@
36284182 .port_pause_limit = mv88e6097_port_pause_limit,
36294183 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
36304184 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3631
- .port_link_state = mv88e6352_port_link_state,
36324185 .port_get_cmode = mv88e6352_port_get_cmode,
4186
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
36334187 .stats_snapshot = mv88e6320_g1_stats_snapshot,
36344188 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
36354189 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3637,6 +4191,8 @@
36374191 .stats_get_stats = mv88e6320_stats_get_stats,
36384192 .set_cpu_port = mv88e6095_g1_set_cpu_port,
36394193 .set_egress_port = mv88e6095_g1_set_egress_port,
4194
+ .watchdog_ops = &mv88e6390_watchdog_ops,
4195
+ .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
36404196 .reset = mv88e6352_g1_reset,
36414197 .vtu_getnext = mv88e6185_g1_vtu_getnext,
36424198 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
....@@ -3657,9 +4213,9 @@
36574213 .phy_read = mv88e6xxx_g2_smi_phy_read,
36584214 .phy_write = mv88e6xxx_g2_smi_phy_write,
36594215 .port_set_link = mv88e6xxx_port_set_link,
3660
- .port_set_duplex = mv88e6xxx_port_set_duplex,
36614216 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3662
- .port_set_speed = mv88e6341_port_set_speed,
4217
+ .port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
4218
+ .port_max_speed_mode = mv88e6341_port_max_speed_mode,
36634219 .port_tag_remap = mv88e6095_port_tag_remap,
36644220 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
36654221 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3669,8 +4225,9 @@
36694225 .port_pause_limit = mv88e6097_port_pause_limit,
36704226 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
36714227 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3672
- .port_link_state = mv88e6352_port_link_state,
36734228 .port_get_cmode = mv88e6352_port_get_cmode,
4229
+ .port_set_cmode = mv88e6341_port_set_cmode,
4230
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
36744231 .stats_snapshot = mv88e6390_g1_stats_snapshot,
36754232 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
36764233 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3683,13 +4240,29 @@
36834240 .pot_clear = mv88e6xxx_g2_pot_clear,
36844241 .reset = mv88e6352_g1_reset,
36854242 .rmu_disable = mv88e6390_g1_rmu_disable,
4243
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4244
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
36864245 .vtu_getnext = mv88e6352_g1_vtu_getnext,
36874246 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3688
- .serdes_power = mv88e6341_serdes_power,
4247
+ .serdes_power = mv88e6390_serdes_power,
4248
+ .serdes_get_lane = mv88e6341_serdes_get_lane,
4249
+ /* Check status register pause & lpa register */
4250
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4251
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
4252
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4253
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4254
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4255
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
4256
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
36894257 .gpio_ops = &mv88e6352_gpio_ops,
36904258 .avb_ops = &mv88e6390_avb_ops,
36914259 .ptp_ops = &mv88e6352_ptp_ops,
3692
- .phylink_validate = mv88e6390_phylink_validate,
4260
+ .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
4261
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
4262
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
4263
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4264
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
4265
+ .phylink_validate = mv88e6341_phylink_validate,
36934266 };
36944267
36954268 static const struct mv88e6xxx_ops mv88e6350_ops = {
....@@ -3701,9 +4274,8 @@
37014274 .phy_read = mv88e6xxx_g2_smi_phy_read,
37024275 .phy_write = mv88e6xxx_g2_smi_phy_write,
37034276 .port_set_link = mv88e6xxx_port_set_link,
3704
- .port_set_duplex = mv88e6xxx_port_set_duplex,
37054277 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3706
- .port_set_speed = mv88e6185_port_set_speed,
4278
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
37074279 .port_tag_remap = mv88e6095_port_tag_remap,
37084280 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
37094281 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3713,8 +4285,8 @@
37134285 .port_pause_limit = mv88e6097_port_pause_limit,
37144286 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
37154287 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3716
- .port_link_state = mv88e6352_port_link_state,
37174288 .port_get_cmode = mv88e6352_port_get_cmode,
4289
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
37184290 .stats_snapshot = mv88e6320_g1_stats_snapshot,
37194291 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
37204292 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3726,6 +4298,8 @@
37264298 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
37274299 .pot_clear = mv88e6xxx_g2_pot_clear,
37284300 .reset = mv88e6352_g1_reset,
4301
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4302
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
37294303 .vtu_getnext = mv88e6352_g1_vtu_getnext,
37304304 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
37314305 .phylink_validate = mv88e6185_phylink_validate,
....@@ -3740,10 +4314,10 @@
37404314 .phy_read = mv88e6xxx_g2_smi_phy_read,
37414315 .phy_write = mv88e6xxx_g2_smi_phy_write,
37424316 .port_set_link = mv88e6xxx_port_set_link,
3743
- .port_set_duplex = mv88e6xxx_port_set_duplex,
37444317 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3745
- .port_set_speed = mv88e6185_port_set_speed,
4318
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
37464319 .port_tag_remap = mv88e6095_port_tag_remap,
4320
+ .port_set_policy = mv88e6352_port_set_policy,
37474321 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
37484322 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
37494323 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -3752,8 +4326,8 @@
37524326 .port_pause_limit = mv88e6097_port_pause_limit,
37534327 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
37544328 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3755
- .port_link_state = mv88e6352_port_link_state,
37564329 .port_get_cmode = mv88e6352_port_get_cmode,
4330
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
37574331 .stats_snapshot = mv88e6320_g1_stats_snapshot,
37584332 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
37594333 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3765,7 +4339,8 @@
37654339 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
37664340 .pot_clear = mv88e6xxx_g2_pot_clear,
37674341 .reset = mv88e6352_g1_reset,
3768
- .rmu_disable = mv88e6390_g1_rmu_disable,
4342
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4343
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
37694344 .vtu_getnext = mv88e6352_g1_vtu_getnext,
37704345 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
37714346 .avb_ops = &mv88e6352_avb_ops,
....@@ -3784,10 +4359,10 @@
37844359 .phy_read = mv88e6xxx_g2_smi_phy_read,
37854360 .phy_write = mv88e6xxx_g2_smi_phy_write,
37864361 .port_set_link = mv88e6xxx_port_set_link,
3787
- .port_set_duplex = mv88e6xxx_port_set_duplex,
37884362 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3789
- .port_set_speed = mv88e6352_port_set_speed,
4363
+ .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
37904364 .port_tag_remap = mv88e6095_port_tag_remap,
4365
+ .port_set_policy = mv88e6352_port_set_policy,
37914366 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
37924367 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
37934368 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -3796,8 +4371,8 @@
37964371 .port_pause_limit = mv88e6097_port_pause_limit,
37974372 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
37984373 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3799
- .port_link_state = mv88e6352_port_link_state,
38004374 .port_get_cmode = mv88e6352_port_get_cmode,
4375
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
38014376 .stats_snapshot = mv88e6320_g1_stats_snapshot,
38024377 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
38034378 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3810,15 +4385,27 @@
38104385 .pot_clear = mv88e6xxx_g2_pot_clear,
38114386 .reset = mv88e6352_g1_reset,
38124387 .rmu_disable = mv88e6352_g1_rmu_disable,
4388
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4389
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
38134390 .vtu_getnext = mv88e6352_g1_vtu_getnext,
38144391 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4392
+ .serdes_get_lane = mv88e6352_serdes_get_lane,
4393
+ .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
4394
+ .serdes_pcs_config = mv88e6352_serdes_pcs_config,
4395
+ .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
4396
+ .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
38154397 .serdes_power = mv88e6352_serdes_power,
4398
+ .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
4399
+ .serdes_irq_enable = mv88e6352_serdes_irq_enable,
4400
+ .serdes_irq_status = mv88e6352_serdes_irq_status,
38164401 .gpio_ops = &mv88e6352_gpio_ops,
38174402 .avb_ops = &mv88e6352_avb_ops,
38184403 .ptp_ops = &mv88e6352_ptp_ops,
38194404 .serdes_get_sset_count = mv88e6352_serdes_get_sset_count,
38204405 .serdes_get_strings = mv88e6352_serdes_get_strings,
38214406 .serdes_get_stats = mv88e6352_serdes_get_stats,
4407
+ .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
4408
+ .serdes_get_regs = mv88e6352_serdes_get_regs,
38224409 .phylink_validate = mv88e6352_phylink_validate,
38234410 };
38244411
....@@ -3832,21 +4419,22 @@
38324419 .phy_read = mv88e6xxx_g2_smi_phy_read,
38334420 .phy_write = mv88e6xxx_g2_smi_phy_write,
38344421 .port_set_link = mv88e6xxx_port_set_link,
3835
- .port_set_duplex = mv88e6xxx_port_set_duplex,
38364422 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3837
- .port_set_speed = mv88e6390_port_set_speed,
4423
+ .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
4424
+ .port_max_speed_mode = mv88e6390_port_max_speed_mode,
38384425 .port_tag_remap = mv88e6390_port_tag_remap,
4426
+ .port_set_policy = mv88e6352_port_set_policy,
38394427 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
38404428 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
38414429 .port_set_ether_type = mv88e6351_port_set_ether_type,
38424430 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
38434431 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
38444432 .port_pause_limit = mv88e6390_port_pause_limit,
3845
- .port_set_cmode = mv88e6390x_port_set_cmode,
38464433 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
38474434 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3848
- .port_link_state = mv88e6352_port_link_state,
38494435 .port_get_cmode = mv88e6352_port_get_cmode,
4436
+ .port_set_cmode = mv88e6390_port_set_cmode,
4437
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
38504438 .stats_snapshot = mv88e6390_g1_stats_snapshot,
38514439 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
38524440 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3859,14 +4447,28 @@
38594447 .pot_clear = mv88e6xxx_g2_pot_clear,
38604448 .reset = mv88e6352_g1_reset,
38614449 .rmu_disable = mv88e6390_g1_rmu_disable,
4450
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4451
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
38624452 .vtu_getnext = mv88e6390_g1_vtu_getnext,
38634453 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
38644454 .serdes_power = mv88e6390_serdes_power,
3865
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3866
- .serdes_irq_free = mv88e6390_serdes_irq_free,
4455
+ .serdes_get_lane = mv88e6390_serdes_get_lane,
4456
+ /* Check status register pause & lpa register */
4457
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4458
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
4459
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4460
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4461
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4462
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
4463
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
38674464 .gpio_ops = &mv88e6352_gpio_ops,
38684465 .avb_ops = &mv88e6390_avb_ops,
38694466 .ptp_ops = &mv88e6352_ptp_ops,
4467
+ .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
4468
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
4469
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
4470
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4471
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
38704472 .phylink_validate = mv88e6390_phylink_validate,
38714473 };
38724474
....@@ -3880,21 +4482,22 @@
38804482 .phy_read = mv88e6xxx_g2_smi_phy_read,
38814483 .phy_write = mv88e6xxx_g2_smi_phy_write,
38824484 .port_set_link = mv88e6xxx_port_set_link,
3883
- .port_set_duplex = mv88e6xxx_port_set_duplex,
38844485 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3885
- .port_set_speed = mv88e6390x_port_set_speed,
4486
+ .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
4487
+ .port_max_speed_mode = mv88e6390x_port_max_speed_mode,
38864488 .port_tag_remap = mv88e6390_port_tag_remap,
4489
+ .port_set_policy = mv88e6352_port_set_policy,
38874490 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
38884491 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
38894492 .port_set_ether_type = mv88e6351_port_set_ether_type,
38904493 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
38914494 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
38924495 .port_pause_limit = mv88e6390_port_pause_limit,
3893
- .port_set_cmode = mv88e6390x_port_set_cmode,
38944496 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
38954497 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3896
- .port_link_state = mv88e6352_port_link_state,
38974498 .port_get_cmode = mv88e6352_port_get_cmode,
4499
+ .port_set_cmode = mv88e6390x_port_set_cmode,
4500
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
38984501 .stats_snapshot = mv88e6390_g1_stats_snapshot,
38994502 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
39004503 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3907,11 +4510,24 @@
39074510 .pot_clear = mv88e6xxx_g2_pot_clear,
39084511 .reset = mv88e6352_g1_reset,
39094512 .rmu_disable = mv88e6390_g1_rmu_disable,
4513
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4514
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
39104515 .vtu_getnext = mv88e6390_g1_vtu_getnext,
39114516 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
3912
- .serdes_power = mv88e6390x_serdes_power,
3913
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3914
- .serdes_irq_free = mv88e6390_serdes_irq_free,
4517
+ .serdes_power = mv88e6390_serdes_power,
4518
+ .serdes_get_lane = mv88e6390x_serdes_get_lane,
4519
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4520
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
4521
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4522
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4523
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4524
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
4525
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
4526
+ .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
4527
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
4528
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
4529
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4530
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
39154531 .gpio_ops = &mv88e6352_gpio_ops,
39164532 .avb_ops = &mv88e6390_avb_ops,
39174533 .ptp_ops = &mv88e6352_ptp_ops,
....@@ -3924,6 +4540,7 @@
39244540 .family = MV88E6XXX_FAMILY_6097,
39254541 .name = "Marvell 88E6085",
39264542 .num_databases = 4096,
4543
+ .num_macs = 8192,
39274544 .num_ports = 10,
39284545 .num_internal_phys = 5,
39294546 .max_vid = 4095,
....@@ -3946,6 +4563,7 @@
39464563 .family = MV88E6XXX_FAMILY_6095,
39474564 .name = "Marvell 88E6095/88E6095F",
39484565 .num_databases = 256,
4566
+ .num_macs = 8192,
39494567 .num_ports = 11,
39504568 .num_internal_phys = 0,
39514569 .max_vid = 4095,
....@@ -3966,6 +4584,7 @@
39664584 .family = MV88E6XXX_FAMILY_6097,
39674585 .name = "Marvell 88E6097/88E6097F",
39684586 .num_databases = 4096,
4587
+ .num_macs = 8192,
39694588 .num_ports = 11,
39704589 .num_internal_phys = 8,
39714590 .max_vid = 4095,
....@@ -3988,6 +4607,7 @@
39884607 .family = MV88E6XXX_FAMILY_6165,
39894608 .name = "Marvell 88E6123",
39904609 .num_databases = 4096,
4610
+ .num_macs = 1024,
39914611 .num_ports = 3,
39924612 .num_internal_phys = 5,
39934613 .max_vid = 4095,
....@@ -4010,6 +4630,7 @@
40104630 .family = MV88E6XXX_FAMILY_6185,
40114631 .name = "Marvell 88E6131",
40124632 .num_databases = 256,
4633
+ .num_macs = 8192,
40134634 .num_ports = 8,
40144635 .num_internal_phys = 0,
40154636 .max_vid = 4095,
....@@ -4030,6 +4651,7 @@
40304651 .family = MV88E6XXX_FAMILY_6341,
40314652 .name = "Marvell 88E6141",
40324653 .num_databases = 4096,
4654
+ .num_macs = 2048,
40334655 .num_ports = 6,
40344656 .num_internal_phys = 5,
40354657 .num_gpio = 11,
....@@ -4053,6 +4675,7 @@
40534675 .family = MV88E6XXX_FAMILY_6165,
40544676 .name = "Marvell 88E6161",
40554677 .num_databases = 4096,
4678
+ .num_macs = 1024,
40564679 .num_ports = 6,
40574680 .num_internal_phys = 5,
40584681 .max_vid = 4095,
....@@ -4076,6 +4699,7 @@
40764699 .family = MV88E6XXX_FAMILY_6165,
40774700 .name = "Marvell 88E6165",
40784701 .num_databases = 4096,
4702
+ .num_macs = 8192,
40794703 .num_ports = 6,
40804704 .num_internal_phys = 0,
40814705 .max_vid = 4095,
....@@ -4099,6 +4723,7 @@
40994723 .family = MV88E6XXX_FAMILY_6351,
41004724 .name = "Marvell 88E6171",
41014725 .num_databases = 4096,
4726
+ .num_macs = 8192,
41024727 .num_ports = 7,
41034728 .num_internal_phys = 5,
41044729 .max_vid = 4095,
....@@ -4121,6 +4746,7 @@
41214746 .family = MV88E6XXX_FAMILY_6352,
41224747 .name = "Marvell 88E6172",
41234748 .num_databases = 4096,
4749
+ .num_macs = 8192,
41244750 .num_ports = 7,
41254751 .num_internal_phys = 5,
41264752 .num_gpio = 15,
....@@ -4144,6 +4770,7 @@
41444770 .family = MV88E6XXX_FAMILY_6351,
41454771 .name = "Marvell 88E6175",
41464772 .num_databases = 4096,
4773
+ .num_macs = 8192,
41474774 .num_ports = 7,
41484775 .num_internal_phys = 5,
41494776 .max_vid = 4095,
....@@ -4166,6 +4793,7 @@
41664793 .family = MV88E6XXX_FAMILY_6352,
41674794 .name = "Marvell 88E6176",
41684795 .num_databases = 4096,
4796
+ .num_macs = 8192,
41694797 .num_ports = 7,
41704798 .num_internal_phys = 5,
41714799 .num_gpio = 15,
....@@ -4189,6 +4817,7 @@
41894817 .family = MV88E6XXX_FAMILY_6185,
41904818 .name = "Marvell 88E6185",
41914819 .num_databases = 256,
4820
+ .num_macs = 8192,
41924821 .num_ports = 10,
41934822 .num_internal_phys = 0,
41944823 .max_vid = 4095,
....@@ -4209,6 +4838,7 @@
42094838 .family = MV88E6XXX_FAMILY_6390,
42104839 .name = "Marvell 88E6190",
42114840 .num_databases = 4096,
4841
+ .num_macs = 16384,
42124842 .num_ports = 11, /* 10 + Z80 */
42134843 .num_internal_phys = 9,
42144844 .num_gpio = 16,
....@@ -4232,6 +4862,7 @@
42324862 .family = MV88E6XXX_FAMILY_6390,
42334863 .name = "Marvell 88E6190X",
42344864 .num_databases = 4096,
4865
+ .num_macs = 16384,
42354866 .num_ports = 11, /* 10 + Z80 */
42364867 .num_internal_phys = 9,
42374868 .num_gpio = 16,
....@@ -4255,6 +4886,7 @@
42554886 .family = MV88E6XXX_FAMILY_6390,
42564887 .name = "Marvell 88E6191",
42574888 .num_databases = 4096,
4889
+ .num_macs = 16384,
42584890 .num_ports = 11, /* 10 + Z80 */
42594891 .num_internal_phys = 9,
42604892 .max_vid = 8191,
....@@ -4273,11 +4905,39 @@
42734905 .ops = &mv88e6191_ops,
42744906 },
42754907
4908
+ [MV88E6220] = {
4909
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6220,
4910
+ .family = MV88E6XXX_FAMILY_6250,
4911
+ .name = "Marvell 88E6220",
4912
+ .num_databases = 64,
4913
+
4914
+ /* Ports 2-4 are not routed to pins
4915
+ * => usable ports 0, 1, 5, 6
4916
+ */
4917
+ .num_ports = 7,
4918
+ .num_internal_phys = 2,
4919
+ .invalid_port_mask = BIT(2) | BIT(3) | BIT(4),
4920
+ .max_vid = 4095,
4921
+ .port_base_addr = 0x08,
4922
+ .phy_base_addr = 0x00,
4923
+ .global1_addr = 0x0f,
4924
+ .global2_addr = 0x07,
4925
+ .age_time_coeff = 15000,
4926
+ .g1_irqs = 9,
4927
+ .g2_irqs = 10,
4928
+ .atu_move_port_mask = 0xf,
4929
+ .dual_chip = true,
4930
+ .tag_protocol = DSA_TAG_PROTO_DSA,
4931
+ .ptp_support = true,
4932
+ .ops = &mv88e6250_ops,
4933
+ },
4934
+
42764935 [MV88E6240] = {
42774936 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6240,
42784937 .family = MV88E6XXX_FAMILY_6352,
42794938 .name = "Marvell 88E6240",
42804939 .num_databases = 4096,
4940
+ .num_macs = 8192,
42814941 .num_ports = 7,
42824942 .num_internal_phys = 5,
42834943 .num_gpio = 15,
....@@ -4295,6 +4955,28 @@
42954955 .tag_protocol = DSA_TAG_PROTO_EDSA,
42964956 .ptp_support = true,
42974957 .ops = &mv88e6240_ops,
4958
+ },
4959
+
4960
+ [MV88E6250] = {
4961
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6250,
4962
+ .family = MV88E6XXX_FAMILY_6250,
4963
+ .name = "Marvell 88E6250",
4964
+ .num_databases = 64,
4965
+ .num_ports = 7,
4966
+ .num_internal_phys = 5,
4967
+ .max_vid = 4095,
4968
+ .port_base_addr = 0x08,
4969
+ .phy_base_addr = 0x00,
4970
+ .global1_addr = 0x0f,
4971
+ .global2_addr = 0x07,
4972
+ .age_time_coeff = 15000,
4973
+ .g1_irqs = 9,
4974
+ .g2_irqs = 10,
4975
+ .atu_move_port_mask = 0xf,
4976
+ .dual_chip = true,
4977
+ .tag_protocol = DSA_TAG_PROTO_DSA,
4978
+ .ptp_support = true,
4979
+ .ops = &mv88e6250_ops,
42984980 },
42994981
43004982 [MV88E6290] = {
....@@ -4326,6 +5008,7 @@
43265008 .family = MV88E6XXX_FAMILY_6320,
43275009 .name = "Marvell 88E6320",
43285010 .num_databases = 4096,
5011
+ .num_macs = 8192,
43295012 .num_ports = 7,
43305013 .num_internal_phys = 5,
43315014 .num_gpio = 15,
....@@ -4350,6 +5033,7 @@
43505033 .family = MV88E6XXX_FAMILY_6320,
43515034 .name = "Marvell 88E6321",
43525035 .num_databases = 4096,
5036
+ .num_macs = 8192,
43535037 .num_ports = 7,
43545038 .num_internal_phys = 5,
43555039 .num_gpio = 15,
....@@ -4373,6 +5057,7 @@
43735057 .family = MV88E6XXX_FAMILY_6341,
43745058 .name = "Marvell 88E6341",
43755059 .num_databases = 4096,
5060
+ .num_macs = 2048,
43765061 .num_internal_phys = 5,
43775062 .num_ports = 6,
43785063 .num_gpio = 11,
....@@ -4397,6 +5082,7 @@
43975082 .family = MV88E6XXX_FAMILY_6351,
43985083 .name = "Marvell 88E6350",
43995084 .num_databases = 4096,
5085
+ .num_macs = 8192,
44005086 .num_ports = 7,
44015087 .num_internal_phys = 5,
44025088 .max_vid = 4095,
....@@ -4419,6 +5105,7 @@
44195105 .family = MV88E6XXX_FAMILY_6351,
44205106 .name = "Marvell 88E6351",
44215107 .num_databases = 4096,
5108
+ .num_macs = 8192,
44225109 .num_ports = 7,
44235110 .num_internal_phys = 5,
44245111 .max_vid = 4095,
....@@ -4441,6 +5128,7 @@
44415128 .family = MV88E6XXX_FAMILY_6352,
44425129 .name = "Marvell 88E6352",
44435130 .num_databases = 4096,
5131
+ .num_macs = 8192,
44445132 .num_ports = 7,
44455133 .num_internal_phys = 5,
44465134 .num_gpio = 15,
....@@ -4464,6 +5152,7 @@
44645152 .family = MV88E6XXX_FAMILY_6390,
44655153 .name = "Marvell 88E6390",
44665154 .num_databases = 4096,
5155
+ .num_macs = 16384,
44675156 .num_ports = 11, /* 10 + Z80 */
44685157 .num_internal_phys = 9,
44695158 .num_gpio = 16,
....@@ -4487,6 +5176,7 @@
44875176 .family = MV88E6XXX_FAMILY_6390,
44885177 .name = "Marvell 88E6390X",
44895178 .num_databases = 4096,
5179
+ .num_macs = 16384,
44905180 .num_ports = 11, /* 10 + Z80 */
44915181 .num_internal_phys = 9,
44925182 .num_gpio = 16,
....@@ -4525,9 +5215,9 @@
45255215 u16 id;
45265216 int err;
45275217
4528
- mutex_lock(&chip->reg_lock);
5218
+ mv88e6xxx_reg_lock(chip);
45295219 err = mv88e6xxx_port_read(chip, 0, MV88E6XXX_PORT_SWITCH_ID, &id);
4530
- mutex_unlock(&chip->reg_lock);
5220
+ mv88e6xxx_reg_unlock(chip);
45315221 if (err)
45325222 return err;
45335223
....@@ -4563,93 +5253,19 @@
45635253
45645254 mutex_init(&chip->reg_lock);
45655255 INIT_LIST_HEAD(&chip->mdios);
5256
+ idr_init(&chip->policies);
45665257
45675258 return chip;
45685259 }
45695260
4570
-static int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip,
4571
- struct mii_bus *bus, int sw_addr)
4572
-{
4573
- if (sw_addr == 0)
4574
- chip->smi_ops = &mv88e6xxx_smi_single_chip_ops;
4575
- else if (chip->info->multi_chip)
4576
- chip->smi_ops = &mv88e6xxx_smi_multi_chip_ops;
4577
- else
4578
- return -EINVAL;
4579
-
4580
- chip->bus = bus;
4581
- chip->sw_addr = sw_addr;
4582
-
4583
- return 0;
4584
-}
4585
-
4586
-static void mv88e6xxx_ports_cmode_init(struct mv88e6xxx_chip *chip)
4587
-{
4588
- int i;
4589
-
4590
- for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
4591
- chip->ports[i].cmode = MV88E6XXX_PORT_STS_CMODE_INVALID;
4592
-}
4593
-
45945261 static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds,
4595
- int port)
5262
+ int port,
5263
+ enum dsa_tag_protocol m)
45965264 {
45975265 struct mv88e6xxx_chip *chip = ds->priv;
45985266
45995267 return chip->info->tag_protocol;
46005268 }
4601
-
4602
-#if IS_ENABLED(CONFIG_NET_DSA_LEGACY)
4603
-static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
4604
- struct device *host_dev, int sw_addr,
4605
- void **priv)
4606
-{
4607
- struct mv88e6xxx_chip *chip;
4608
- struct mii_bus *bus;
4609
- int err;
4610
-
4611
- bus = dsa_host_dev_to_mii_bus(host_dev);
4612
- if (!bus)
4613
- return NULL;
4614
-
4615
- chip = mv88e6xxx_alloc_chip(dsa_dev);
4616
- if (!chip)
4617
- return NULL;
4618
-
4619
- /* Legacy SMI probing will only support chips similar to 88E6085 */
4620
- chip->info = &mv88e6xxx_table[MV88E6085];
4621
-
4622
- err = mv88e6xxx_smi_init(chip, bus, sw_addr);
4623
- if (err)
4624
- goto free;
4625
-
4626
- err = mv88e6xxx_detect(chip);
4627
- if (err)
4628
- goto free;
4629
-
4630
- mv88e6xxx_ports_cmode_init(chip);
4631
-
4632
- mutex_lock(&chip->reg_lock);
4633
- err = mv88e6xxx_switch_reset(chip);
4634
- mutex_unlock(&chip->reg_lock);
4635
- if (err)
4636
- goto free;
4637
-
4638
- mv88e6xxx_phy_init(chip);
4639
-
4640
- err = mv88e6xxx_mdios_register(chip, NULL);
4641
- if (err)
4642
- goto free;
4643
-
4644
- *priv = chip;
4645
-
4646
- return chip->info->name;
4647
-free:
4648
- devm_kfree(dsa_dev, chip);
4649
-
4650
- return NULL;
4651
-}
4652
-#endif
46535269
46545270 static int mv88e6xxx_port_mdb_prepare(struct dsa_switch *ds, int port,
46555271 const struct switchdev_obj_port_mdb *mdb)
....@@ -4666,12 +5282,12 @@
46665282 {
46675283 struct mv88e6xxx_chip *chip = ds->priv;
46685284
4669
- mutex_lock(&chip->reg_lock);
5285
+ mv88e6xxx_reg_lock(chip);
46705286 if (mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
46715287 MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC))
46725288 dev_err(ds->dev, "p%d: failed to load multicast MAC address\n",
46735289 port);
4674
- mutex_unlock(&chip->reg_lock);
5290
+ mv88e6xxx_reg_unlock(chip);
46755291 }
46765292
46775293 static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port,
....@@ -4680,24 +5296,111 @@
46805296 struct mv88e6xxx_chip *chip = ds->priv;
46815297 int err;
46825298
5299
+ mv88e6xxx_reg_lock(chip);
5300
+ err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid, 0);
5301
+ mv88e6xxx_reg_unlock(chip);
5302
+
5303
+ return err;
5304
+}
5305
+
5306
+static int mv88e6xxx_port_mirror_add(struct dsa_switch *ds, int port,
5307
+ struct dsa_mall_mirror_tc_entry *mirror,
5308
+ bool ingress)
5309
+{
5310
+ enum mv88e6xxx_egress_direction direction = ingress ?
5311
+ MV88E6XXX_EGRESS_DIR_INGRESS :
5312
+ MV88E6XXX_EGRESS_DIR_EGRESS;
5313
+ struct mv88e6xxx_chip *chip = ds->priv;
5314
+ bool other_mirrors = false;
5315
+ int i;
5316
+ int err;
5317
+
5318
+ if (!chip->info->ops->set_egress_port)
5319
+ return -EOPNOTSUPP;
5320
+
46835321 mutex_lock(&chip->reg_lock);
4684
- err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
4685
- MV88E6XXX_G1_ATU_DATA_STATE_UNUSED);
5322
+ if ((ingress ? chip->ingress_dest_port : chip->egress_dest_port) !=
5323
+ mirror->to_local_port) {
5324
+ for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
5325
+ other_mirrors |= ingress ?
5326
+ chip->ports[i].mirror_ingress :
5327
+ chip->ports[i].mirror_egress;
5328
+
5329
+ /* Can't change egress port when other mirror is active */
5330
+ if (other_mirrors) {
5331
+ err = -EBUSY;
5332
+ goto out;
5333
+ }
5334
+
5335
+ err = chip->info->ops->set_egress_port(chip,
5336
+ direction,
5337
+ mirror->to_local_port);
5338
+ if (err)
5339
+ goto out;
5340
+ }
5341
+
5342
+ err = mv88e6xxx_port_set_mirror(chip, port, direction, true);
5343
+out:
46865344 mutex_unlock(&chip->reg_lock);
46875345
46885346 return err;
46895347 }
46905348
5349
+static void mv88e6xxx_port_mirror_del(struct dsa_switch *ds, int port,
5350
+ struct dsa_mall_mirror_tc_entry *mirror)
5351
+{
5352
+ enum mv88e6xxx_egress_direction direction = mirror->ingress ?
5353
+ MV88E6XXX_EGRESS_DIR_INGRESS :
5354
+ MV88E6XXX_EGRESS_DIR_EGRESS;
5355
+ struct mv88e6xxx_chip *chip = ds->priv;
5356
+ bool other_mirrors = false;
5357
+ int i;
5358
+
5359
+ mutex_lock(&chip->reg_lock);
5360
+ if (mv88e6xxx_port_set_mirror(chip, port, direction, false))
5361
+ dev_err(ds->dev, "p%d: failed to disable mirroring\n", port);
5362
+
5363
+ for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
5364
+ other_mirrors |= mirror->ingress ?
5365
+ chip->ports[i].mirror_ingress :
5366
+ chip->ports[i].mirror_egress;
5367
+
5368
+ /* Reset egress port when no other mirror is active */
5369
+ if (!other_mirrors) {
5370
+ if (chip->info->ops->set_egress_port(chip,
5371
+ direction,
5372
+ dsa_upstream_port(ds,
5373
+ port)))
5374
+ dev_err(ds->dev, "failed to set egress port\n");
5375
+ }
5376
+
5377
+ mutex_unlock(&chip->reg_lock);
5378
+}
5379
+
5380
+static int mv88e6xxx_port_egress_floods(struct dsa_switch *ds, int port,
5381
+ bool unicast, bool multicast)
5382
+{
5383
+ struct mv88e6xxx_chip *chip = ds->priv;
5384
+ int err = -EOPNOTSUPP;
5385
+
5386
+ mv88e6xxx_reg_lock(chip);
5387
+ if (chip->info->ops->port_set_egress_floods)
5388
+ err = chip->info->ops->port_set_egress_floods(chip, port,
5389
+ unicast,
5390
+ multicast);
5391
+ mv88e6xxx_reg_unlock(chip);
5392
+
5393
+ return err;
5394
+}
5395
+
46915396 static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
4692
-#if IS_ENABLED(CONFIG_NET_DSA_LEGACY)
4693
- .probe = mv88e6xxx_drv_probe,
4694
-#endif
46955397 .get_tag_protocol = mv88e6xxx_get_tag_protocol,
46965398 .setup = mv88e6xxx_setup,
4697
- .adjust_link = mv88e6xxx_adjust_link,
5399
+ .teardown = mv88e6xxx_teardown,
46985400 .phylink_validate = mv88e6xxx_validate,
4699
- .phylink_mac_link_state = mv88e6xxx_link_state,
5401
+ .phylink_mac_link_state = mv88e6xxx_serdes_pcs_get_state,
47005402 .phylink_mac_config = mv88e6xxx_mac_config,
5403
+ .phylink_mac_an_restart = mv88e6xxx_serdes_pcs_an_restart,
47015404 .phylink_mac_link_down = mv88e6xxx_mac_link_down,
47025405 .phylink_mac_link_up = mv88e6xxx_mac_link_up,
47035406 .get_strings = mv88e6xxx_get_strings,
....@@ -4705,6 +5408,8 @@
47055408 .get_sset_count = mv88e6xxx_get_sset_count,
47065409 .port_enable = mv88e6xxx_port_enable,
47075410 .port_disable = mv88e6xxx_port_disable,
5411
+ .port_max_mtu = mv88e6xxx_get_max_mtu,
5412
+ .port_change_mtu = mv88e6xxx_change_mtu,
47085413 .get_mac_eee = mv88e6xxx_get_mac_eee,
47095414 .set_mac_eee = mv88e6xxx_set_mac_eee,
47105415 .get_eeprom_len = mv88e6xxx_get_eeprom_len,
....@@ -4712,9 +5417,12 @@
47125417 .set_eeprom = mv88e6xxx_set_eeprom,
47135418 .get_regs_len = mv88e6xxx_get_regs_len,
47145419 .get_regs = mv88e6xxx_get_regs,
5420
+ .get_rxnfc = mv88e6xxx_get_rxnfc,
5421
+ .set_rxnfc = mv88e6xxx_set_rxnfc,
47155422 .set_ageing_time = mv88e6xxx_set_ageing_time,
47165423 .port_bridge_join = mv88e6xxx_port_bridge_join,
47175424 .port_bridge_leave = mv88e6xxx_port_bridge_leave,
5425
+ .port_egress_floods = mv88e6xxx_port_egress_floods,
47185426 .port_stp_state_set = mv88e6xxx_port_stp_state_set,
47195427 .port_fast_age = mv88e6xxx_port_fast_age,
47205428 .port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
....@@ -4727,6 +5435,8 @@
47275435 .port_mdb_prepare = mv88e6xxx_port_mdb_prepare,
47285436 .port_mdb_add = mv88e6xxx_port_mdb_add,
47295437 .port_mdb_del = mv88e6xxx_port_mdb_del,
5438
+ .port_mirror_add = mv88e6xxx_port_mirror_add,
5439
+ .port_mirror_del = mv88e6xxx_port_mirror_del,
47305440 .crosschip_bridge_join = mv88e6xxx_crosschip_bridge_join,
47315441 .crosschip_bridge_leave = mv88e6xxx_crosschip_bridge_leave,
47325442 .port_hwtstamp_set = mv88e6xxx_port_hwtstamp_set,
....@@ -4734,10 +5444,9 @@
47345444 .port_txtstamp = mv88e6xxx_port_txtstamp,
47355445 .port_rxtstamp = mv88e6xxx_port_rxtstamp,
47365446 .get_ts_info = mv88e6xxx_get_ts_info,
4737
-};
4738
-
4739
-static struct dsa_switch_driver mv88e6xxx_switch_drv = {
4740
- .ops = &mv88e6xxx_switch_ops,
5447
+ .devlink_param_get = mv88e6xxx_devlink_param_get,
5448
+ .devlink_param_set = mv88e6xxx_devlink_param_set,
5449
+ .devlink_info_get = mv88e6xxx_devlink_info_get,
47415450 };
47425451
47435452 static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
....@@ -4745,10 +5454,12 @@
47455454 struct device *dev = chip->dev;
47465455 struct dsa_switch *ds;
47475456
4748
- ds = dsa_switch_alloc(dev, mv88e6xxx_num_ports(chip));
5457
+ ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
47495458 if (!ds)
47505459 return -ENOMEM;
47515460
5461
+ ds->dev = dev;
5462
+ ds->num_ports = mv88e6xxx_num_ports(chip);
47525463 ds->priv = chip;
47535464 ds->dev = dev;
47545465 ds->ops = &mv88e6xxx_switch_ops;
....@@ -4777,6 +5488,21 @@
47775488 }
47785489 return NULL;
47795490 }
5491
+
5492
+/* There is no suspend to RAM support at DSA level yet, the switch configuration
5493
+ * would be lost after a power cycle so prevent it to be suspended.
5494
+ */
5495
+static int __maybe_unused mv88e6xxx_suspend(struct device *dev)
5496
+{
5497
+ return -EOPNOTSUPP;
5498
+}
5499
+
5500
+static int __maybe_unused mv88e6xxx_resume(struct device *dev)
5501
+{
5502
+ return 0;
5503
+}
5504
+
5505
+static SIMPLE_DEV_PM_OPS(mv88e6xxx_pm_ops, mv88e6xxx_suspend, mv88e6xxx_resume);
47805506
47815507 static int mv88e6xxx_probe(struct mdio_device *mdiodev)
47825508 {
....@@ -4831,13 +5557,12 @@
48315557 goto out;
48325558 }
48335559 if (chip->reset)
4834
- usleep_range(1000, 2000);
5560
+ usleep_range(10000, 20000);
48355561
48365562 err = mv88e6xxx_detect(chip);
48375563 if (err)
48385564 goto out;
48395565
4840
- mv88e6xxx_ports_cmode_init(chip);
48415566 mv88e6xxx_phy_init(chip);
48425567
48435568 if (chip->info->ops->get_eeprom) {
....@@ -4848,28 +5573,33 @@
48485573 chip->eeprom_len = pdata->eeprom_len;
48495574 }
48505575
4851
- mutex_lock(&chip->reg_lock);
5576
+ mv88e6xxx_reg_lock(chip);
48525577 err = mv88e6xxx_switch_reset(chip);
4853
- mutex_unlock(&chip->reg_lock);
5578
+ mv88e6xxx_reg_unlock(chip);
48545579 if (err)
48555580 goto out;
48565581
4857
- chip->irq = of_irq_get(np, 0);
4858
- if (chip->irq == -EPROBE_DEFER) {
4859
- err = chip->irq;
4860
- goto out;
5582
+ if (np) {
5583
+ chip->irq = of_irq_get(np, 0);
5584
+ if (chip->irq == -EPROBE_DEFER) {
5585
+ err = chip->irq;
5586
+ goto out;
5587
+ }
48615588 }
5589
+
5590
+ if (pdata)
5591
+ chip->irq = pdata->irq;
48625592
48635593 /* Has to be performed before the MDIO bus is created, because
48645594 * the PHYs will link their interrupts to these interrupt
48655595 * controllers
48665596 */
4867
- mutex_lock(&chip->reg_lock);
5597
+ mv88e6xxx_reg_lock(chip);
48685598 if (chip->irq > 0)
48695599 err = mv88e6xxx_g1_irq_setup(chip);
48705600 else
48715601 err = mv88e6xxx_irq_poll_setup(chip);
4872
- mutex_unlock(&chip->reg_lock);
5602
+ mv88e6xxx_reg_unlock(chip);
48735603
48745604 if (err)
48755605 goto out;
....@@ -4954,6 +5684,10 @@
49545684 .compatible = "marvell,mv88e6190",
49555685 .data = &mv88e6xxx_table[MV88E6190],
49565686 },
5687
+ {
5688
+ .compatible = "marvell,mv88e6250",
5689
+ .data = &mv88e6xxx_table[MV88E6250],
5690
+ },
49575691 { /* sentinel */ },
49585692 };
49595693
....@@ -4965,22 +5699,11 @@
49655699 .mdiodrv.driver = {
49665700 .name = "mv88e6085",
49675701 .of_match_table = mv88e6xxx_of_match,
5702
+ .pm = &mv88e6xxx_pm_ops,
49685703 },
49695704 };
49705705
4971
-static int __init mv88e6xxx_init(void)
4972
-{
4973
- register_switch_driver(&mv88e6xxx_switch_drv);
4974
- return mdio_driver_register(&mv88e6xxx_driver);
4975
-}
4976
-module_init(mv88e6xxx_init);
4977
-
4978
-static void __exit mv88e6xxx_cleanup(void)
4979
-{
4980
- mdio_driver_unregister(&mv88e6xxx_driver);
4981
- unregister_switch_driver(&mv88e6xxx_switch_drv);
4982
-}
4983
-module_exit(mv88e6xxx_cleanup);
5706
+mdio_module_driver(mv88e6xxx_driver);
49845707
49855708 MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
49865709 MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");