hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
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)
....@@ -2036,6 +2314,8 @@
20362314 usleep_range(10000, 20000);
20372315 gpiod_set_value_cansleep(gpiod, 0);
20382316 usleep_range(10000, 20000);
2317
+
2318
+ mv88e6xxx_g1_wait_eeprom_done(chip);
20392319 }
20402320 }
20412321
....@@ -2155,13 +2435,100 @@
21552435 return 0;
21562436 }
21572437
2438
+static irqreturn_t mv88e6xxx_serdes_irq_thread_fn(int irq, void *dev_id)
2439
+{
2440
+ struct mv88e6xxx_port *mvp = dev_id;
2441
+ struct mv88e6xxx_chip *chip = mvp->chip;
2442
+ irqreturn_t ret = IRQ_NONE;
2443
+ int port = mvp->port;
2444
+ u8 lane;
2445
+
2446
+ mv88e6xxx_reg_lock(chip);
2447
+ lane = mv88e6xxx_serdes_get_lane(chip, port);
2448
+ if (lane)
2449
+ ret = mv88e6xxx_serdes_irq_status(chip, port, lane);
2450
+ mv88e6xxx_reg_unlock(chip);
2451
+
2452
+ return ret;
2453
+}
2454
+
2455
+static int mv88e6xxx_serdes_irq_request(struct mv88e6xxx_chip *chip, int port,
2456
+ u8 lane)
2457
+{
2458
+ struct mv88e6xxx_port *dev_id = &chip->ports[port];
2459
+ unsigned int irq;
2460
+ int err;
2461
+
2462
+ /* Nothing to request if this SERDES port has no IRQ */
2463
+ irq = mv88e6xxx_serdes_irq_mapping(chip, port);
2464
+ if (!irq)
2465
+ return 0;
2466
+
2467
+ snprintf(dev_id->serdes_irq_name, sizeof(dev_id->serdes_irq_name),
2468
+ "mv88e6xxx-%s-serdes-%d", dev_name(chip->dev), port);
2469
+
2470
+ /* Requesting the IRQ will trigger IRQ callbacks, so release the lock */
2471
+ mv88e6xxx_reg_unlock(chip);
2472
+ err = request_threaded_irq(irq, NULL, mv88e6xxx_serdes_irq_thread_fn,
2473
+ IRQF_ONESHOT, dev_id->serdes_irq_name,
2474
+ dev_id);
2475
+ mv88e6xxx_reg_lock(chip);
2476
+ if (err)
2477
+ return err;
2478
+
2479
+ dev_id->serdes_irq = irq;
2480
+
2481
+ return mv88e6xxx_serdes_irq_enable(chip, port, lane);
2482
+}
2483
+
2484
+static int mv88e6xxx_serdes_irq_free(struct mv88e6xxx_chip *chip, int port,
2485
+ u8 lane)
2486
+{
2487
+ struct mv88e6xxx_port *dev_id = &chip->ports[port];
2488
+ unsigned int irq = dev_id->serdes_irq;
2489
+ int err;
2490
+
2491
+ /* Nothing to free if no IRQ has been requested */
2492
+ if (!irq)
2493
+ return 0;
2494
+
2495
+ err = mv88e6xxx_serdes_irq_disable(chip, port, lane);
2496
+
2497
+ /* Freeing the IRQ will trigger IRQ callbacks, so release the lock */
2498
+ mv88e6xxx_reg_unlock(chip);
2499
+ free_irq(irq, dev_id);
2500
+ mv88e6xxx_reg_lock(chip);
2501
+
2502
+ dev_id->serdes_irq = 0;
2503
+
2504
+ return err;
2505
+}
2506
+
21582507 static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
21592508 bool on)
21602509 {
2161
- if (chip->info->ops->serdes_power)
2162
- return chip->info->ops->serdes_power(chip, port, on);
2510
+ u8 lane;
2511
+ int err;
21632512
2164
- return 0;
2513
+ lane = mv88e6xxx_serdes_get_lane(chip, port);
2514
+ if (!lane)
2515
+ return 0;
2516
+
2517
+ if (on) {
2518
+ err = mv88e6xxx_serdes_power_up(chip, port, lane);
2519
+ if (err)
2520
+ return err;
2521
+
2522
+ err = mv88e6xxx_serdes_irq_request(chip, port, lane);
2523
+ } else {
2524
+ err = mv88e6xxx_serdes_irq_free(chip, port, lane);
2525
+ if (err)
2526
+ return err;
2527
+
2528
+ err = mv88e6xxx_serdes_power_down(chip, port, lane);
2529
+ }
2530
+
2531
+ return err;
21652532 }
21662533
21672534 static int mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip *chip, int port)
....@@ -2188,7 +2555,14 @@
21882555
21892556 if (chip->info->ops->set_egress_port) {
21902557 err = chip->info->ops->set_egress_port(chip,
2191
- upstream_port);
2558
+ MV88E6XXX_EGRESS_DIR_INGRESS,
2559
+ upstream_port);
2560
+ if (err)
2561
+ return err;
2562
+
2563
+ err = chip->info->ops->set_egress_port(chip,
2564
+ MV88E6XXX_EGRESS_DIR_EGRESS,
2565
+ upstream_port);
21922566 if (err)
21932567 return err;
21942568 }
....@@ -2252,18 +2626,8 @@
22522626 if (err)
22532627 return err;
22542628
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
2629
+ /* Port Control 2: don't force a good FCS, set the MTU size to
2630
+ * 10222 bytes, disable 802.1q tags checking, don't discard tagged or
22672631 * untagged frames on this port, do a destination address lookup on all
22682632 * received packets as usual, disable ARP mirroring and don't send a
22692633 * copy of all transmitted/received frames on this port to the CPU.
....@@ -2282,7 +2646,7 @@
22822646 return err;
22832647
22842648 if (chip->info->ops->port_set_jumbo_size) {
2285
- err = chip->info->ops->port_set_jumbo_size(chip, port, 10240);
2649
+ err = chip->info->ops->port_set_jumbo_size(chip, port, 10218);
22862650 if (err)
22872651 return err;
22882652 }
....@@ -2338,9 +2702,11 @@
23382702 return err;
23392703 }
23402704
2341
- err = mv88e6xxx_setup_message_port(chip, port);
2342
- if (err)
2343
- return err;
2705
+ if (chip->info->ops->port_setup_message_port) {
2706
+ err = chip->info->ops->port_setup_message_port(chip, port);
2707
+ if (err)
2708
+ return err;
2709
+ }
23442710
23452711 /* Port based VLAN map: give each port the same default address
23462712 * database, and allow bidirectional communication between the
....@@ -2360,38 +2726,59 @@
23602726 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 0);
23612727 }
23622728
2729
+static int mv88e6xxx_get_max_mtu(struct dsa_switch *ds, int port)
2730
+{
2731
+ struct mv88e6xxx_chip *chip = ds->priv;
2732
+
2733
+ if (chip->info->ops->port_set_jumbo_size)
2734
+ return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
2735
+ else if (chip->info->ops->set_max_frame_size)
2736
+ return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
2737
+ return 1522 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
2738
+}
2739
+
2740
+static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
2741
+{
2742
+ struct mv88e6xxx_chip *chip = ds->priv;
2743
+ int ret = 0;
2744
+
2745
+ if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
2746
+ new_mtu += EDSA_HLEN;
2747
+
2748
+ mv88e6xxx_reg_lock(chip);
2749
+ if (chip->info->ops->port_set_jumbo_size)
2750
+ ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu);
2751
+ else if (chip->info->ops->set_max_frame_size)
2752
+ ret = chip->info->ops->set_max_frame_size(chip, new_mtu);
2753
+ else
2754
+ if (new_mtu > 1522)
2755
+ ret = -EINVAL;
2756
+ mv88e6xxx_reg_unlock(chip);
2757
+
2758
+ return ret;
2759
+}
2760
+
23632761 static int mv88e6xxx_port_enable(struct dsa_switch *ds, int port,
23642762 struct phy_device *phydev)
23652763 {
23662764 struct mv88e6xxx_chip *chip = ds->priv;
23672765 int err;
23682766
2369
- mutex_lock(&chip->reg_lock);
2370
-
2767
+ mv88e6xxx_reg_lock(chip);
23712768 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);
2769
+ mv88e6xxx_reg_unlock(chip);
23772770
23782771 return err;
23792772 }
23802773
2381
-static void mv88e6xxx_port_disable(struct dsa_switch *ds, int port,
2382
- struct phy_device *phydev)
2774
+static void mv88e6xxx_port_disable(struct dsa_switch *ds, int port)
23832775 {
23842776 struct mv88e6xxx_chip *chip = ds->priv;
23852777
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
-
2778
+ mv88e6xxx_reg_lock(chip);
23912779 if (mv88e6xxx_serdes_power(chip, port, false))
23922780 dev_err(chip->dev, "failed to power off SERDES\n");
2393
-
2394
- mutex_unlock(&chip->reg_lock);
2781
+ mv88e6xxx_reg_unlock(chip);
23952782 }
23962783
23972784 static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds,
....@@ -2400,9 +2787,9 @@
24002787 struct mv88e6xxx_chip *chip = ds->priv;
24012788 int err;
24022789
2403
- mutex_lock(&chip->reg_lock);
2790
+ mv88e6xxx_reg_lock(chip);
24042791 err = mv88e6xxx_g1_atu_set_age_time(chip, ageing_time);
2405
- mutex_unlock(&chip->reg_lock);
2792
+ mv88e6xxx_reg_unlock(chip);
24062793
24072794 return err;
24082795 }
....@@ -2421,58 +2808,6 @@
24212808 return mv88e6xxx_g1_stats_clear(chip);
24222809 }
24232810
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
-
24762811 /* Check if the errata has already been applied. */
24772812 static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip)
24782813 {
....@@ -2481,7 +2816,7 @@
24812816 u16 val;
24822817
24832818 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
2484
- err = mv88e6390_hidden_read(chip, port, 0, &val);
2819
+ err = mv88e6xxx_port_hidden_read(chip, 0xf, port, 0, &val);
24852820 if (err) {
24862821 dev_err(chip->dev,
24872822 "Error reading hidden register: %d\n", err);
....@@ -2514,12 +2849,19 @@
25142849 }
25152850
25162851 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
2517
- err = mv88e6390_hidden_write(chip, port, 0, 0x01c0);
2852
+ err = mv88e6xxx_port_hidden_write(chip, 0xf, port, 0, 0x01c0);
25182853 if (err)
25192854 return err;
25202855 }
25212856
25222857 return mv88e6xxx_software_reset(chip);
2858
+}
2859
+
2860
+static void mv88e6xxx_teardown(struct dsa_switch *ds)
2861
+{
2862
+ mv88e6xxx_teardown_devlink_params(ds);
2863
+ dsa_devlink_resources_unregister(ds);
2864
+ mv88e6xxx_teardown_devlink_regions(ds);
25232865 }
25242866
25252867 static int mv88e6xxx_setup(struct dsa_switch *ds)
....@@ -2532,7 +2874,7 @@
25322874 chip->ds = ds;
25332875 ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip);
25342876
2535
- mutex_lock(&chip->reg_lock);
2877
+ mv88e6xxx_reg_lock(chip);
25362878
25372879 if (chip->info->ops->setup_errata) {
25382880 err = chip->info->ops->setup_errata(chip);
....@@ -2555,6 +2897,13 @@
25552897 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
25562898 if (dsa_is_unused_port(ds, i))
25572899 continue;
2900
+
2901
+ /* Prevent the use of an invalid port. */
2902
+ if (mv88e6xxx_is_invalid_port(chip, i)) {
2903
+ dev_err(chip->dev, "port %d is invalid\n", i);
2904
+ err = -EINVAL;
2905
+ goto unlock;
2906
+ }
25582907
25592908 err = mv88e6xxx_setup_port(chip, i);
25602909 if (err)
....@@ -2629,7 +2978,34 @@
26292978 goto unlock;
26302979
26312980 unlock:
2632
- mutex_unlock(&chip->reg_lock);
2981
+ mv88e6xxx_reg_unlock(chip);
2982
+
2983
+ if (err)
2984
+ return err;
2985
+
2986
+ /* Have to be called without holding the register lock, since
2987
+ * they take the devlink lock, and we later take the locks in
2988
+ * the reverse order when getting/setting parameters or
2989
+ * resource occupancy.
2990
+ */
2991
+ err = mv88e6xxx_setup_devlink_resources(ds);
2992
+ if (err)
2993
+ return err;
2994
+
2995
+ err = mv88e6xxx_setup_devlink_params(ds);
2996
+ if (err)
2997
+ goto out_resources;
2998
+
2999
+ err = mv88e6xxx_setup_devlink_regions(ds);
3000
+ if (err)
3001
+ goto out_params;
3002
+
3003
+ return 0;
3004
+
3005
+out_params:
3006
+ mv88e6xxx_teardown_devlink_params(ds);
3007
+out_resources:
3008
+ dsa_devlink_resources_unregister(ds);
26333009
26343010 return err;
26353011 }
....@@ -2651,9 +3027,9 @@
26513027 if (!chip->info->ops->phy_read)
26523028 return -EOPNOTSUPP;
26533029
2654
- mutex_lock(&chip->reg_lock);
3030
+ mv88e6xxx_reg_lock(chip);
26553031 err = chip->info->ops->phy_read(chip, bus, phy, reg, &val);
2656
- mutex_unlock(&chip->reg_lock);
3032
+ mv88e6xxx_reg_unlock(chip);
26573033
26583034 /* Some internal PHYs don't have a model number. */
26593035 if (reg == MII_PHYSID2 && !(val & 0x3f0) &&
....@@ -2675,9 +3051,9 @@
26753051 if (!chip->info->ops->phy_write)
26763052 return -EOPNOTSUPP;
26773053
2678
- mutex_lock(&chip->reg_lock);
3054
+ mv88e6xxx_reg_lock(chip);
26793055 err = chip->info->ops->phy_write(chip, bus, phy, reg, val);
2680
- mutex_unlock(&chip->reg_lock);
3056
+ mv88e6xxx_reg_unlock(chip);
26813057
26823058 return err;
26833059 }
....@@ -2692,15 +3068,15 @@
26923068 int err;
26933069
26943070 if (external) {
2695
- mutex_lock(&chip->reg_lock);
3071
+ mv88e6xxx_reg_lock(chip);
26963072 err = mv88e6xxx_g2_scratch_gpio_set_smi(chip, true);
2697
- mutex_unlock(&chip->reg_lock);
3073
+ mv88e6xxx_reg_unlock(chip);
26983074
26993075 if (err)
27003076 return err;
27013077 }
27023078
2703
- bus = devm_mdiobus_alloc_size(chip->dev, sizeof(*mdio_bus));
3079
+ bus = mdiobus_alloc_size(sizeof(*mdio_bus));
27043080 if (!bus)
27053081 return -ENOMEM;
27063082
....@@ -2725,14 +3101,14 @@
27253101 if (!external) {
27263102 err = mv88e6xxx_g2_irq_mdio_setup(chip, bus);
27273103 if (err)
2728
- return err;
3104
+ goto out;
27293105 }
27303106
27313107 err = of_mdiobus_register(bus, np);
27323108 if (err) {
27333109 dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err);
27343110 mv88e6xxx_g2_irq_mdio_free(chip, bus);
2735
- return err;
3111
+ goto out;
27363112 }
27373113
27383114 if (external)
....@@ -2741,34 +3117,32 @@
27413117 list_add(&mdio_bus->list, &chip->mdios);
27423118
27433119 return 0;
2744
-}
27453120
2746
-static const struct of_device_id mv88e6xxx_mdio_external_match[] = {
2747
- { .compatible = "marvell,mv88e6xxx-mdio-external",
2748
- .data = (void *)true },
2749
- { },
2750
-};
3121
+out:
3122
+ mdiobus_free(bus);
3123
+ return err;
3124
+}
27513125
27523126 static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
27533127
27543128 {
2755
- struct mv88e6xxx_mdio_bus *mdio_bus;
3129
+ struct mv88e6xxx_mdio_bus *mdio_bus, *p;
27563130 struct mii_bus *bus;
27573131
2758
- list_for_each_entry(mdio_bus, &chip->mdios, list) {
3132
+ list_for_each_entry_safe(mdio_bus, p, &chip->mdios, list) {
27593133 bus = mdio_bus->bus;
27603134
27613135 if (!mdio_bus->external)
27623136 mv88e6xxx_g2_irq_mdio_free(chip, bus);
27633137
27643138 mdiobus_unregister(bus);
3139
+ mdiobus_free(bus);
27653140 }
27663141 }
27673142
27683143 static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip,
27693144 struct device_node *np)
27703145 {
2771
- const struct of_device_id *match;
27723146 struct device_node *child;
27733147 int err;
27743148
....@@ -2778,6 +3152,7 @@
27783152 */
27793153 child = of_get_child_by_name(np, "mdio");
27803154 err = mv88e6xxx_mdio_register(chip, child, false);
3155
+ of_node_put(child);
27813156 if (err)
27823157 return err;
27833158
....@@ -2786,11 +3161,12 @@
27863161 * bus.
27873162 */
27883163 for_each_available_child_of_node(np, child) {
2789
- match = of_match_node(mv88e6xxx_mdio_external_match, child);
2790
- if (match) {
3164
+ if (of_device_is_compatible(
3165
+ child, "marvell,mv88e6xxx-mdio-external")) {
27913166 err = mv88e6xxx_mdio_register(chip, child, true);
27923167 if (err) {
27933168 mv88e6xxx_mdios_unregister(chip);
3169
+ of_node_put(child);
27943170 return err;
27953171 }
27963172 }
....@@ -2815,9 +3191,9 @@
28153191 if (!chip->info->ops->get_eeprom)
28163192 return -EOPNOTSUPP;
28173193
2818
- mutex_lock(&chip->reg_lock);
3194
+ mv88e6xxx_reg_lock(chip);
28193195 err = chip->info->ops->get_eeprom(chip, eeprom, data);
2820
- mutex_unlock(&chip->reg_lock);
3196
+ mv88e6xxx_reg_unlock(chip);
28213197
28223198 if (err)
28233199 return err;
....@@ -2839,9 +3215,9 @@
28393215 if (eeprom->magic != 0xc3ec4951)
28403216 return -EINVAL;
28413217
2842
- mutex_lock(&chip->reg_lock);
3218
+ mv88e6xxx_reg_lock(chip);
28433219 err = chip->info->ops->set_eeprom(chip, eeprom, data);
2844
- mutex_unlock(&chip->reg_lock);
3220
+ mv88e6xxx_reg_unlock(chip);
28453221
28463222 return err;
28473223 }
....@@ -2855,8 +3231,7 @@
28553231 .phy_read = mv88e6185_phy_ppu_read,
28563232 .phy_write = mv88e6185_phy_ppu_write,
28573233 .port_set_link = mv88e6xxx_port_set_link,
2858
- .port_set_duplex = mv88e6xxx_port_set_duplex,
2859
- .port_set_speed = mv88e6185_port_set_speed,
3234
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
28603235 .port_tag_remap = mv88e6095_port_tag_remap,
28613236 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
28623237 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -2865,8 +3240,8 @@
28653240 .port_pause_limit = mv88e6097_port_pause_limit,
28663241 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
28673242 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2868
- .port_link_state = mv88e6352_port_link_state,
28693243 .port_get_cmode = mv88e6185_port_get_cmode,
3244
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
28703245 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
28713246 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
28723247 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -2884,6 +3259,7 @@
28843259 .vtu_getnext = mv88e6352_g1_vtu_getnext,
28853260 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
28863261 .phylink_validate = mv88e6185_phylink_validate,
3262
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
28873263 };
28883264
28893265 static const struct mv88e6xxx_ops mv88e6095_ops = {
....@@ -2894,13 +3270,12 @@
28943270 .phy_read = mv88e6185_phy_ppu_read,
28953271 .phy_write = mv88e6185_phy_ppu_write,
28963272 .port_set_link = mv88e6xxx_port_set_link,
2897
- .port_set_duplex = mv88e6xxx_port_set_duplex,
2898
- .port_set_speed = mv88e6185_port_set_speed,
3273
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
28993274 .port_set_frame_mode = mv88e6085_port_set_frame_mode,
29003275 .port_set_egress_floods = mv88e6185_port_set_egress_floods,
29013276 .port_set_upstream_port = mv88e6095_port_set_upstream_port,
2902
- .port_link_state = mv88e6185_port_link_state,
29033277 .port_get_cmode = mv88e6185_port_get_cmode,
3278
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
29043279 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
29053280 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
29063281 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -2913,6 +3288,7 @@
29133288 .vtu_getnext = mv88e6185_g1_vtu_getnext,
29143289 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
29153290 .phylink_validate = mv88e6185_phylink_validate,
3291
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
29163292 };
29173293
29183294 static const struct mv88e6xxx_ops mv88e6097_ops = {
....@@ -2924,9 +3300,9 @@
29243300 .phy_read = mv88e6xxx_g2_smi_phy_read,
29253301 .phy_write = mv88e6xxx_g2_smi_phy_write,
29263302 .port_set_link = mv88e6xxx_port_set_link,
2927
- .port_set_duplex = mv88e6xxx_port_set_duplex,
2928
- .port_set_speed = mv88e6185_port_set_speed,
3303
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
29293304 .port_tag_remap = mv88e6095_port_tag_remap,
3305
+ .port_set_policy = mv88e6352_port_set_policy,
29303306 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
29313307 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
29323308 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -2934,8 +3310,8 @@
29343310 .port_pause_limit = mv88e6097_port_pause_limit,
29353311 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
29363312 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2937
- .port_link_state = mv88e6352_port_link_state,
29383313 .port_get_cmode = mv88e6185_port_get_cmode,
3314
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
29393315 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
29403316 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
29413317 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -2951,6 +3327,7 @@
29513327 .vtu_getnext = mv88e6352_g1_vtu_getnext,
29523328 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
29533329 .phylink_validate = mv88e6185_phylink_validate,
3330
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
29543331 };
29553332
29563333 static const struct mv88e6xxx_ops mv88e6123_ops = {
....@@ -2962,14 +3339,13 @@
29623339 .phy_read = mv88e6xxx_g2_smi_phy_read,
29633340 .phy_write = mv88e6xxx_g2_smi_phy_write,
29643341 .port_set_link = mv88e6xxx_port_set_link,
2965
- .port_set_duplex = mv88e6xxx_port_set_duplex,
2966
- .port_set_speed = mv88e6185_port_set_speed,
3342
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
29673343 .port_set_frame_mode = mv88e6085_port_set_frame_mode,
29683344 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
29693345 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
29703346 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2971
- .port_link_state = mv88e6352_port_link_state,
29723347 .port_get_cmode = mv88e6185_port_get_cmode,
3348
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
29733349 .stats_snapshot = mv88e6320_g1_stats_snapshot,
29743350 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
29753351 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -2981,9 +3357,12 @@
29813357 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
29823358 .pot_clear = mv88e6xxx_g2_pot_clear,
29833359 .reset = mv88e6352_g1_reset,
3360
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3361
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
29843362 .vtu_getnext = mv88e6352_g1_vtu_getnext,
29853363 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
29863364 .phylink_validate = mv88e6185_phylink_validate,
3365
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
29873366 };
29883367
29893368 static const struct mv88e6xxx_ops mv88e6131_ops = {
....@@ -2994,8 +3373,7 @@
29943373 .phy_read = mv88e6185_phy_ppu_read,
29953374 .phy_write = mv88e6185_phy_ppu_write,
29963375 .port_set_link = mv88e6xxx_port_set_link,
2997
- .port_set_duplex = mv88e6xxx_port_set_duplex,
2998
- .port_set_speed = mv88e6185_port_set_speed,
3376
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
29993377 .port_tag_remap = mv88e6095_port_tag_remap,
30003378 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
30013379 .port_set_egress_floods = mv88e6185_port_set_egress_floods,
....@@ -3005,8 +3383,8 @@
30053383 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
30063384 .port_pause_limit = mv88e6097_port_pause_limit,
30073385 .port_set_pause = mv88e6185_port_set_pause,
3008
- .port_link_state = mv88e6352_port_link_state,
30093386 .port_get_cmode = mv88e6185_port_get_cmode,
3387
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
30103388 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
30113389 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
30123390 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3036,9 +3414,9 @@
30363414 .phy_read = mv88e6xxx_g2_smi_phy_read,
30373415 .phy_write = mv88e6xxx_g2_smi_phy_write,
30383416 .port_set_link = mv88e6xxx_port_set_link,
3039
- .port_set_duplex = mv88e6xxx_port_set_duplex,
30403417 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3041
- .port_set_speed = mv88e6341_port_set_speed,
3418
+ .port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
3419
+ .port_max_speed_mode = mv88e6341_port_max_speed_mode,
30423420 .port_tag_remap = mv88e6095_port_tag_remap,
30433421 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
30443422 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3048,8 +3426,9 @@
30483426 .port_pause_limit = mv88e6097_port_pause_limit,
30493427 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
30503428 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3051
- .port_link_state = mv88e6352_port_link_state,
30523429 .port_get_cmode = mv88e6352_port_get_cmode,
3430
+ .port_set_cmode = mv88e6341_port_set_cmode,
3431
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
30533432 .stats_snapshot = mv88e6390_g1_stats_snapshot,
30543433 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
30553434 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3061,11 +3440,28 @@
30613440 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
30623441 .pot_clear = mv88e6xxx_g2_pot_clear,
30633442 .reset = mv88e6352_g1_reset,
3443
+ .rmu_disable = mv88e6390_g1_rmu_disable,
3444
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3445
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
30643446 .vtu_getnext = mv88e6352_g1_vtu_getnext,
30653447 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3066
- .serdes_power = mv88e6341_serdes_power,
3448
+ .serdes_power = mv88e6390_serdes_power,
3449
+ .serdes_get_lane = mv88e6341_serdes_get_lane,
3450
+ /* Check status register pause & lpa register */
3451
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
3452
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
3453
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
3454
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
3455
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3456
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3457
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
30673458 .gpio_ops = &mv88e6352_gpio_ops,
3068
- .phylink_validate = mv88e6390_phylink_validate,
3459
+ .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
3460
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
3461
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
3462
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
3463
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
3464
+ .phylink_validate = mv88e6341_phylink_validate,
30693465 };
30703466
30713467 static const struct mv88e6xxx_ops mv88e6161_ops = {
....@@ -3077,19 +3473,17 @@
30773473 .phy_read = mv88e6xxx_g2_smi_phy_read,
30783474 .phy_write = mv88e6xxx_g2_smi_phy_write,
30793475 .port_set_link = mv88e6xxx_port_set_link,
3080
- .port_set_duplex = mv88e6xxx_port_set_duplex,
3081
- .port_set_speed = mv88e6185_port_set_speed,
3476
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
30823477 .port_tag_remap = mv88e6095_port_tag_remap,
30833478 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
30843479 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
30853480 .port_set_ether_type = mv88e6351_port_set_ether_type,
3086
- .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
30873481 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
30883482 .port_pause_limit = mv88e6097_port_pause_limit,
30893483 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
30903484 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3091
- .port_link_state = mv88e6352_port_link_state,
30923485 .port_get_cmode = mv88e6185_port_get_cmode,
3486
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
30933487 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
30943488 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
30953489 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3101,11 +3495,14 @@
31013495 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
31023496 .pot_clear = mv88e6xxx_g2_pot_clear,
31033497 .reset = mv88e6352_g1_reset,
3498
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3499
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
31043500 .vtu_getnext = mv88e6352_g1_vtu_getnext,
31053501 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
31063502 .avb_ops = &mv88e6165_avb_ops,
31073503 .ptp_ops = &mv88e6165_ptp_ops,
31083504 .phylink_validate = mv88e6185_phylink_validate,
3505
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
31093506 };
31103507
31113508 static const struct mv88e6xxx_ops mv88e6165_ops = {
....@@ -3117,12 +3514,11 @@
31173514 .phy_read = mv88e6165_phy_read,
31183515 .phy_write = mv88e6165_phy_write,
31193516 .port_set_link = mv88e6xxx_port_set_link,
3120
- .port_set_duplex = mv88e6xxx_port_set_duplex,
3121
- .port_set_speed = mv88e6185_port_set_speed,
3517
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
31223518 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
31233519 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3124
- .port_link_state = mv88e6352_port_link_state,
31253520 .port_get_cmode = mv88e6185_port_get_cmode,
3521
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
31263522 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
31273523 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
31283524 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3134,6 +3530,8 @@
31343530 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
31353531 .pot_clear = mv88e6xxx_g2_pot_clear,
31363532 .reset = mv88e6352_g1_reset,
3533
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3534
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
31373535 .vtu_getnext = mv88e6352_g1_vtu_getnext,
31383536 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
31393537 .avb_ops = &mv88e6165_avb_ops,
....@@ -3150,9 +3548,8 @@
31503548 .phy_read = mv88e6xxx_g2_smi_phy_read,
31513549 .phy_write = mv88e6xxx_g2_smi_phy_write,
31523550 .port_set_link = mv88e6xxx_port_set_link,
3153
- .port_set_duplex = mv88e6xxx_port_set_duplex,
31543551 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3155
- .port_set_speed = mv88e6185_port_set_speed,
3552
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
31563553 .port_tag_remap = mv88e6095_port_tag_remap,
31573554 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
31583555 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3162,8 +3559,8 @@
31623559 .port_pause_limit = mv88e6097_port_pause_limit,
31633560 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
31643561 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3165
- .port_link_state = mv88e6352_port_link_state,
31663562 .port_get_cmode = mv88e6352_port_get_cmode,
3563
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
31673564 .stats_snapshot = mv88e6320_g1_stats_snapshot,
31683565 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
31693566 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3175,6 +3572,8 @@
31753572 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
31763573 .pot_clear = mv88e6xxx_g2_pot_clear,
31773574 .reset = mv88e6352_g1_reset,
3575
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3576
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
31783577 .vtu_getnext = mv88e6352_g1_vtu_getnext,
31793578 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
31803579 .phylink_validate = mv88e6185_phylink_validate,
....@@ -3191,10 +3590,10 @@
31913590 .phy_read = mv88e6xxx_g2_smi_phy_read,
31923591 .phy_write = mv88e6xxx_g2_smi_phy_write,
31933592 .port_set_link = mv88e6xxx_port_set_link,
3194
- .port_set_duplex = mv88e6xxx_port_set_duplex,
31953593 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3196
- .port_set_speed = mv88e6352_port_set_speed,
3594
+ .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
31973595 .port_tag_remap = mv88e6095_port_tag_remap,
3596
+ .port_set_policy = mv88e6352_port_set_policy,
31983597 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
31993598 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
32003599 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -3203,8 +3602,8 @@
32033602 .port_pause_limit = mv88e6097_port_pause_limit,
32043603 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
32053604 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3206
- .port_link_state = mv88e6352_port_link_state,
32073605 .port_get_cmode = mv88e6352_port_get_cmode,
3606
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
32083607 .stats_snapshot = mv88e6320_g1_stats_snapshot,
32093608 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
32103609 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3217,9 +3616,18 @@
32173616 .pot_clear = mv88e6xxx_g2_pot_clear,
32183617 .reset = mv88e6352_g1_reset,
32193618 .rmu_disable = mv88e6352_g1_rmu_disable,
3619
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3620
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
32203621 .vtu_getnext = mv88e6352_g1_vtu_getnext,
32213622 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3623
+ .serdes_get_lane = mv88e6352_serdes_get_lane,
3624
+ .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
3625
+ .serdes_pcs_config = mv88e6352_serdes_pcs_config,
3626
+ .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
3627
+ .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
32223628 .serdes_power = mv88e6352_serdes_power,
3629
+ .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
3630
+ .serdes_get_regs = mv88e6352_serdes_get_regs,
32233631 .gpio_ops = &mv88e6352_gpio_ops,
32243632 .phylink_validate = mv88e6352_phylink_validate,
32253633 };
....@@ -3233,10 +3641,10 @@
32333641 .phy_read = mv88e6xxx_g2_smi_phy_read,
32343642 .phy_write = mv88e6xxx_g2_smi_phy_write,
32353643 .port_set_link = mv88e6xxx_port_set_link,
3236
- .port_set_duplex = mv88e6xxx_port_set_duplex,
32373644 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3238
- .port_set_speed = mv88e6185_port_set_speed,
3645
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
32393646 .port_tag_remap = mv88e6095_port_tag_remap,
3647
+ .port_set_policy = mv88e6352_port_set_policy,
32403648 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
32413649 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
32423650 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -3245,8 +3653,8 @@
32453653 .port_pause_limit = mv88e6097_port_pause_limit,
32463654 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
32473655 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3248
- .port_link_state = mv88e6352_port_link_state,
32493656 .port_get_cmode = mv88e6352_port_get_cmode,
3657
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
32503658 .stats_snapshot = mv88e6320_g1_stats_snapshot,
32513659 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
32523660 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3258,6 +3666,8 @@
32583666 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
32593667 .pot_clear = mv88e6xxx_g2_pot_clear,
32603668 .reset = mv88e6352_g1_reset,
3669
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3670
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
32613671 .vtu_getnext = mv88e6352_g1_vtu_getnext,
32623672 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
32633673 .phylink_validate = mv88e6185_phylink_validate,
....@@ -3274,10 +3684,10 @@
32743684 .phy_read = mv88e6xxx_g2_smi_phy_read,
32753685 .phy_write = mv88e6xxx_g2_smi_phy_write,
32763686 .port_set_link = mv88e6xxx_port_set_link,
3277
- .port_set_duplex = mv88e6xxx_port_set_duplex,
32783687 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3279
- .port_set_speed = mv88e6352_port_set_speed,
3688
+ .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
32803689 .port_tag_remap = mv88e6095_port_tag_remap,
3690
+ .port_set_policy = mv88e6352_port_set_policy,
32813691 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
32823692 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
32833693 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -3286,8 +3696,8 @@
32863696 .port_pause_limit = mv88e6097_port_pause_limit,
32873697 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
32883698 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3289
- .port_link_state = mv88e6352_port_link_state,
32903699 .port_get_cmode = mv88e6352_port_get_cmode,
3700
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
32913701 .stats_snapshot = mv88e6320_g1_stats_snapshot,
32923702 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
32933703 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3300,9 +3710,21 @@
33003710 .pot_clear = mv88e6xxx_g2_pot_clear,
33013711 .reset = mv88e6352_g1_reset,
33023712 .rmu_disable = mv88e6352_g1_rmu_disable,
3713
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3714
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
33033715 .vtu_getnext = mv88e6352_g1_vtu_getnext,
33043716 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3717
+ .serdes_get_lane = mv88e6352_serdes_get_lane,
3718
+ .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
3719
+ .serdes_pcs_config = mv88e6352_serdes_pcs_config,
3720
+ .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
3721
+ .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
33053722 .serdes_power = mv88e6352_serdes_power,
3723
+ .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
3724
+ .serdes_irq_enable = mv88e6352_serdes_irq_enable,
3725
+ .serdes_irq_status = mv88e6352_serdes_irq_status,
3726
+ .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
3727
+ .serdes_get_regs = mv88e6352_serdes_get_regs,
33063728 .gpio_ops = &mv88e6352_gpio_ops,
33073729 .phylink_validate = mv88e6352_phylink_validate,
33083730 };
....@@ -3315,15 +3737,14 @@
33153737 .phy_read = mv88e6185_phy_ppu_read,
33163738 .phy_write = mv88e6185_phy_ppu_write,
33173739 .port_set_link = mv88e6xxx_port_set_link,
3318
- .port_set_duplex = mv88e6xxx_port_set_duplex,
3319
- .port_set_speed = mv88e6185_port_set_speed,
3740
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
33203741 .port_set_frame_mode = mv88e6085_port_set_frame_mode,
33213742 .port_set_egress_floods = mv88e6185_port_set_egress_floods,
33223743 .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
33233744 .port_set_upstream_port = mv88e6095_port_set_upstream_port,
33243745 .port_set_pause = mv88e6185_port_set_pause,
3325
- .port_link_state = mv88e6185_port_link_state,
33263746 .port_get_cmode = mv88e6185_port_get_cmode,
3747
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
33273748 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
33283749 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
33293750 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3340,6 +3761,7 @@
33403761 .vtu_getnext = mv88e6185_g1_vtu_getnext,
33413762 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
33423763 .phylink_validate = mv88e6185_phylink_validate,
3764
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
33433765 };
33443766
33453767 static const struct mv88e6xxx_ops mv88e6190_ops = {
....@@ -3352,18 +3774,21 @@
33523774 .phy_read = mv88e6xxx_g2_smi_phy_read,
33533775 .phy_write = mv88e6xxx_g2_smi_phy_write,
33543776 .port_set_link = mv88e6xxx_port_set_link,
3355
- .port_set_duplex = mv88e6xxx_port_set_duplex,
33563777 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3357
- .port_set_speed = mv88e6390_port_set_speed,
3778
+ .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
3779
+ .port_max_speed_mode = mv88e6390_port_max_speed_mode,
33583780 .port_tag_remap = mv88e6390_port_tag_remap,
3781
+ .port_set_policy = mv88e6352_port_set_policy,
33593782 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
33603783 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
33613784 .port_set_ether_type = mv88e6351_port_set_ether_type,
3785
+ .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
33623786 .port_pause_limit = mv88e6390_port_pause_limit,
33633787 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
33643788 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3365
- .port_link_state = mv88e6352_port_link_state,
33663789 .port_get_cmode = mv88e6352_port_get_cmode,
3790
+ .port_set_cmode = mv88e6390_port_set_cmode,
3791
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
33673792 .stats_snapshot = mv88e6390_g1_stats_snapshot,
33683793 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
33693794 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3376,11 +3801,24 @@
33763801 .pot_clear = mv88e6xxx_g2_pot_clear,
33773802 .reset = mv88e6352_g1_reset,
33783803 .rmu_disable = mv88e6390_g1_rmu_disable,
3804
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3805
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
33793806 .vtu_getnext = mv88e6390_g1_vtu_getnext,
33803807 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
33813808 .serdes_power = mv88e6390_serdes_power,
3382
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3383
- .serdes_irq_free = mv88e6390_serdes_irq_free,
3809
+ .serdes_get_lane = mv88e6390_serdes_get_lane,
3810
+ /* Check status register pause & lpa register */
3811
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
3812
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
3813
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
3814
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
3815
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3816
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3817
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
3818
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
3819
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
3820
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
3821
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
33843822 .gpio_ops = &mv88e6352_gpio_ops,
33853823 .phylink_validate = mv88e6390_phylink_validate,
33863824 };
....@@ -3395,18 +3833,21 @@
33953833 .phy_read = mv88e6xxx_g2_smi_phy_read,
33963834 .phy_write = mv88e6xxx_g2_smi_phy_write,
33973835 .port_set_link = mv88e6xxx_port_set_link,
3398
- .port_set_duplex = mv88e6xxx_port_set_duplex,
33993836 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3400
- .port_set_speed = mv88e6390x_port_set_speed,
3837
+ .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
3838
+ .port_max_speed_mode = mv88e6390x_port_max_speed_mode,
34013839 .port_tag_remap = mv88e6390_port_tag_remap,
3840
+ .port_set_policy = mv88e6352_port_set_policy,
34023841 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
34033842 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
34043843 .port_set_ether_type = mv88e6351_port_set_ether_type,
3844
+ .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
34053845 .port_pause_limit = mv88e6390_port_pause_limit,
34063846 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
34073847 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3408
- .port_link_state = mv88e6352_port_link_state,
34093848 .port_get_cmode = mv88e6352_port_get_cmode,
3849
+ .port_set_cmode = mv88e6390x_port_set_cmode,
3850
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
34103851 .stats_snapshot = mv88e6390_g1_stats_snapshot,
34113852 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
34123853 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3419,11 +3860,24 @@
34193860 .pot_clear = mv88e6xxx_g2_pot_clear,
34203861 .reset = mv88e6352_g1_reset,
34213862 .rmu_disable = mv88e6390_g1_rmu_disable,
3863
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3864
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
34223865 .vtu_getnext = mv88e6390_g1_vtu_getnext,
34233866 .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,
3867
+ .serdes_power = mv88e6390_serdes_power,
3868
+ .serdes_get_lane = mv88e6390x_serdes_get_lane,
3869
+ /* Check status register pause & lpa register */
3870
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
3871
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
3872
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
3873
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
3874
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3875
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3876
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
3877
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
3878
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
3879
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
3880
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
34273881 .gpio_ops = &mv88e6352_gpio_ops,
34283882 .phylink_validate = mv88e6390x_phylink_validate,
34293883 };
....@@ -3438,9 +3892,9 @@
34383892 .phy_read = mv88e6xxx_g2_smi_phy_read,
34393893 .phy_write = mv88e6xxx_g2_smi_phy_write,
34403894 .port_set_link = mv88e6xxx_port_set_link,
3441
- .port_set_duplex = mv88e6xxx_port_set_duplex,
34423895 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3443
- .port_set_speed = mv88e6390_port_set_speed,
3896
+ .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
3897
+ .port_max_speed_mode = mv88e6390_port_max_speed_mode,
34443898 .port_tag_remap = mv88e6390_port_tag_remap,
34453899 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
34463900 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3448,8 +3902,9 @@
34483902 .port_pause_limit = mv88e6390_port_pause_limit,
34493903 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
34503904 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3451
- .port_link_state = mv88e6352_port_link_state,
34523905 .port_get_cmode = mv88e6352_port_get_cmode,
3906
+ .port_set_cmode = mv88e6390_port_set_cmode,
3907
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
34533908 .stats_snapshot = mv88e6390_g1_stats_snapshot,
34543909 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
34553910 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3462,11 +3917,24 @@
34623917 .pot_clear = mv88e6xxx_g2_pot_clear,
34633918 .reset = mv88e6352_g1_reset,
34643919 .rmu_disable = mv88e6390_g1_rmu_disable,
3920
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3921
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
34653922 .vtu_getnext = mv88e6390_g1_vtu_getnext,
34663923 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
34673924 .serdes_power = mv88e6390_serdes_power,
3468
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3469
- .serdes_irq_free = mv88e6390_serdes_irq_free,
3925
+ .serdes_get_lane = mv88e6390_serdes_get_lane,
3926
+ /* Check status register pause & lpa register */
3927
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
3928
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
3929
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
3930
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
3931
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3932
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3933
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
3934
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
3935
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
3936
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
3937
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
34703938 .avb_ops = &mv88e6390_avb_ops,
34713939 .ptp_ops = &mv88e6352_ptp_ops,
34723940 .phylink_validate = mv88e6390_phylink_validate,
....@@ -3483,10 +3951,10 @@
34833951 .phy_read = mv88e6xxx_g2_smi_phy_read,
34843952 .phy_write = mv88e6xxx_g2_smi_phy_write,
34853953 .port_set_link = mv88e6xxx_port_set_link,
3486
- .port_set_duplex = mv88e6xxx_port_set_duplex,
34873954 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3488
- .port_set_speed = mv88e6352_port_set_speed,
3955
+ .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
34893956 .port_tag_remap = mv88e6095_port_tag_remap,
3957
+ .port_set_policy = mv88e6352_port_set_policy,
34903958 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
34913959 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
34923960 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -3495,8 +3963,8 @@
34953963 .port_pause_limit = mv88e6097_port_pause_limit,
34963964 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
34973965 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3498
- .port_link_state = mv88e6352_port_link_state,
34993966 .port_get_cmode = mv88e6352_port_get_cmode,
3967
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
35003968 .stats_snapshot = mv88e6320_g1_stats_snapshot,
35013969 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
35023970 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3509,13 +3977,63 @@
35093977 .pot_clear = mv88e6xxx_g2_pot_clear,
35103978 .reset = mv88e6352_g1_reset,
35113979 .rmu_disable = mv88e6352_g1_rmu_disable,
3980
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
3981
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
35123982 .vtu_getnext = mv88e6352_g1_vtu_getnext,
35133983 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3984
+ .serdes_get_lane = mv88e6352_serdes_get_lane,
3985
+ .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
3986
+ .serdes_pcs_config = mv88e6352_serdes_pcs_config,
3987
+ .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
3988
+ .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
35143989 .serdes_power = mv88e6352_serdes_power,
3990
+ .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
3991
+ .serdes_irq_enable = mv88e6352_serdes_irq_enable,
3992
+ .serdes_irq_status = mv88e6352_serdes_irq_status,
3993
+ .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
3994
+ .serdes_get_regs = mv88e6352_serdes_get_regs,
35153995 .gpio_ops = &mv88e6352_gpio_ops,
35163996 .avb_ops = &mv88e6352_avb_ops,
35173997 .ptp_ops = &mv88e6352_ptp_ops,
35183998 .phylink_validate = mv88e6352_phylink_validate,
3999
+};
4000
+
4001
+static const struct mv88e6xxx_ops mv88e6250_ops = {
4002
+ /* MV88E6XXX_FAMILY_6250 */
4003
+ .ieee_pri_map = mv88e6250_g1_ieee_pri_map,
4004
+ .ip_pri_map = mv88e6085_g1_ip_pri_map,
4005
+ .irl_init_all = mv88e6352_g2_irl_init_all,
4006
+ .get_eeprom = mv88e6xxx_g2_get_eeprom16,
4007
+ .set_eeprom = mv88e6xxx_g2_set_eeprom16,
4008
+ .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4009
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
4010
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
4011
+ .port_set_link = mv88e6xxx_port_set_link,
4012
+ .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4013
+ .port_set_speed_duplex = mv88e6250_port_set_speed_duplex,
4014
+ .port_tag_remap = mv88e6095_port_tag_remap,
4015
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4016
+ .port_set_egress_floods = mv88e6352_port_set_egress_floods,
4017
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
4018
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4019
+ .port_pause_limit = mv88e6097_port_pause_limit,
4020
+ .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4021
+ .stats_snapshot = mv88e6320_g1_stats_snapshot,
4022
+ .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4023
+ .stats_get_sset_count = mv88e6250_stats_get_sset_count,
4024
+ .stats_get_strings = mv88e6250_stats_get_strings,
4025
+ .stats_get_stats = mv88e6250_stats_get_stats,
4026
+ .set_cpu_port = mv88e6095_g1_set_cpu_port,
4027
+ .set_egress_port = mv88e6095_g1_set_egress_port,
4028
+ .watchdog_ops = &mv88e6250_watchdog_ops,
4029
+ .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4030
+ .pot_clear = mv88e6xxx_g2_pot_clear,
4031
+ .reset = mv88e6250_g1_reset,
4032
+ .vtu_getnext = mv88e6250_g1_vtu_getnext,
4033
+ .vtu_loadpurge = mv88e6250_g1_vtu_loadpurge,
4034
+ .avb_ops = &mv88e6352_avb_ops,
4035
+ .ptp_ops = &mv88e6250_ptp_ops,
4036
+ .phylink_validate = mv88e6065_phylink_validate,
35194037 };
35204038
35214039 static const struct mv88e6xxx_ops mv88e6290_ops = {
....@@ -3528,19 +4046,20 @@
35284046 .phy_read = mv88e6xxx_g2_smi_phy_read,
35294047 .phy_write = mv88e6xxx_g2_smi_phy_write,
35304048 .port_set_link = mv88e6xxx_port_set_link,
3531
- .port_set_duplex = mv88e6xxx_port_set_duplex,
35324049 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3533
- .port_set_speed = mv88e6390_port_set_speed,
4050
+ .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
4051
+ .port_max_speed_mode = mv88e6390_port_max_speed_mode,
35344052 .port_tag_remap = mv88e6390_port_tag_remap,
4053
+ .port_set_policy = mv88e6352_port_set_policy,
35354054 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
35364055 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
35374056 .port_set_ether_type = mv88e6351_port_set_ether_type,
35384057 .port_pause_limit = mv88e6390_port_pause_limit,
3539
- .port_set_cmode = mv88e6390x_port_set_cmode,
35404058 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
35414059 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3542
- .port_link_state = mv88e6352_port_link_state,
35434060 .port_get_cmode = mv88e6352_port_get_cmode,
4061
+ .port_set_cmode = mv88e6390_port_set_cmode,
4062
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
35444063 .stats_snapshot = mv88e6390_g1_stats_snapshot,
35454064 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
35464065 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3553,11 +4072,24 @@
35534072 .pot_clear = mv88e6xxx_g2_pot_clear,
35544073 .reset = mv88e6352_g1_reset,
35554074 .rmu_disable = mv88e6390_g1_rmu_disable,
4075
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4076
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
35564077 .vtu_getnext = mv88e6390_g1_vtu_getnext,
35574078 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
35584079 .serdes_power = mv88e6390_serdes_power,
3559
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3560
- .serdes_irq_free = mv88e6390_serdes_irq_free,
4080
+ .serdes_get_lane = mv88e6390_serdes_get_lane,
4081
+ /* Check status register pause & lpa register */
4082
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4083
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
4084
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4085
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4086
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4087
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
4088
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
4089
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
4090
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
4091
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4092
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
35614093 .gpio_ops = &mv88e6352_gpio_ops,
35624094 .avb_ops = &mv88e6390_avb_ops,
35634095 .ptp_ops = &mv88e6352_ptp_ops,
....@@ -3575,8 +4107,7 @@
35754107 .phy_read = mv88e6xxx_g2_smi_phy_read,
35764108 .phy_write = mv88e6xxx_g2_smi_phy_write,
35774109 .port_set_link = mv88e6xxx_port_set_link,
3578
- .port_set_duplex = mv88e6xxx_port_set_duplex,
3579
- .port_set_speed = mv88e6185_port_set_speed,
4110
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
35804111 .port_tag_remap = mv88e6095_port_tag_remap,
35814112 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
35824113 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3586,8 +4117,8 @@
35864117 .port_pause_limit = mv88e6097_port_pause_limit,
35874118 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
35884119 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3589
- .port_link_state = mv88e6352_port_link_state,
35904120 .port_get_cmode = mv88e6352_port_get_cmode,
4121
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
35914122 .stats_snapshot = mv88e6320_g1_stats_snapshot,
35924123 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
35934124 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3595,6 +4126,7 @@
35954126 .stats_get_stats = mv88e6320_stats_get_stats,
35964127 .set_cpu_port = mv88e6095_g1_set_cpu_port,
35974128 .set_egress_port = mv88e6095_g1_set_egress_port,
4129
+ .watchdog_ops = &mv88e6390_watchdog_ops,
35984130 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
35994131 .pot_clear = mv88e6xxx_g2_pot_clear,
36004132 .reset = mv88e6352_g1_reset,
....@@ -3617,8 +4149,7 @@
36174149 .phy_read = mv88e6xxx_g2_smi_phy_read,
36184150 .phy_write = mv88e6xxx_g2_smi_phy_write,
36194151 .port_set_link = mv88e6xxx_port_set_link,
3620
- .port_set_duplex = mv88e6xxx_port_set_duplex,
3621
- .port_set_speed = mv88e6185_port_set_speed,
4152
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
36224153 .port_tag_remap = mv88e6095_port_tag_remap,
36234154 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
36244155 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3628,8 +4159,8 @@
36284159 .port_pause_limit = mv88e6097_port_pause_limit,
36294160 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
36304161 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3631
- .port_link_state = mv88e6352_port_link_state,
36324162 .port_get_cmode = mv88e6352_port_get_cmode,
4163
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
36334164 .stats_snapshot = mv88e6320_g1_stats_snapshot,
36344165 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
36354166 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3637,6 +4168,7 @@
36374168 .stats_get_stats = mv88e6320_stats_get_stats,
36384169 .set_cpu_port = mv88e6095_g1_set_cpu_port,
36394170 .set_egress_port = mv88e6095_g1_set_egress_port,
4171
+ .watchdog_ops = &mv88e6390_watchdog_ops,
36404172 .reset = mv88e6352_g1_reset,
36414173 .vtu_getnext = mv88e6185_g1_vtu_getnext,
36424174 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
....@@ -3657,9 +4189,9 @@
36574189 .phy_read = mv88e6xxx_g2_smi_phy_read,
36584190 .phy_write = mv88e6xxx_g2_smi_phy_write,
36594191 .port_set_link = mv88e6xxx_port_set_link,
3660
- .port_set_duplex = mv88e6xxx_port_set_duplex,
36614192 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3662
- .port_set_speed = mv88e6341_port_set_speed,
4193
+ .port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
4194
+ .port_max_speed_mode = mv88e6341_port_max_speed_mode,
36634195 .port_tag_remap = mv88e6095_port_tag_remap,
36644196 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
36654197 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3669,8 +4201,9 @@
36694201 .port_pause_limit = mv88e6097_port_pause_limit,
36704202 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
36714203 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3672
- .port_link_state = mv88e6352_port_link_state,
36734204 .port_get_cmode = mv88e6352_port_get_cmode,
4205
+ .port_set_cmode = mv88e6341_port_set_cmode,
4206
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
36744207 .stats_snapshot = mv88e6390_g1_stats_snapshot,
36754208 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
36764209 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3683,13 +4216,29 @@
36834216 .pot_clear = mv88e6xxx_g2_pot_clear,
36844217 .reset = mv88e6352_g1_reset,
36854218 .rmu_disable = mv88e6390_g1_rmu_disable,
4219
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4220
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
36864221 .vtu_getnext = mv88e6352_g1_vtu_getnext,
36874222 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3688
- .serdes_power = mv88e6341_serdes_power,
4223
+ .serdes_power = mv88e6390_serdes_power,
4224
+ .serdes_get_lane = mv88e6341_serdes_get_lane,
4225
+ /* Check status register pause & lpa register */
4226
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4227
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
4228
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4229
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4230
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4231
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
4232
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
36894233 .gpio_ops = &mv88e6352_gpio_ops,
36904234 .avb_ops = &mv88e6390_avb_ops,
36914235 .ptp_ops = &mv88e6352_ptp_ops,
3692
- .phylink_validate = mv88e6390_phylink_validate,
4236
+ .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
4237
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
4238
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
4239
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4240
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
4241
+ .phylink_validate = mv88e6341_phylink_validate,
36934242 };
36944243
36954244 static const struct mv88e6xxx_ops mv88e6350_ops = {
....@@ -3701,9 +4250,8 @@
37014250 .phy_read = mv88e6xxx_g2_smi_phy_read,
37024251 .phy_write = mv88e6xxx_g2_smi_phy_write,
37034252 .port_set_link = mv88e6xxx_port_set_link,
3704
- .port_set_duplex = mv88e6xxx_port_set_duplex,
37054253 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3706
- .port_set_speed = mv88e6185_port_set_speed,
4254
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
37074255 .port_tag_remap = mv88e6095_port_tag_remap,
37084256 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
37094257 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
....@@ -3713,8 +4261,8 @@
37134261 .port_pause_limit = mv88e6097_port_pause_limit,
37144262 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
37154263 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3716
- .port_link_state = mv88e6352_port_link_state,
37174264 .port_get_cmode = mv88e6352_port_get_cmode,
4265
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
37184266 .stats_snapshot = mv88e6320_g1_stats_snapshot,
37194267 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
37204268 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3726,6 +4274,8 @@
37264274 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
37274275 .pot_clear = mv88e6xxx_g2_pot_clear,
37284276 .reset = mv88e6352_g1_reset,
4277
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4278
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
37294279 .vtu_getnext = mv88e6352_g1_vtu_getnext,
37304280 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
37314281 .phylink_validate = mv88e6185_phylink_validate,
....@@ -3740,10 +4290,10 @@
37404290 .phy_read = mv88e6xxx_g2_smi_phy_read,
37414291 .phy_write = mv88e6xxx_g2_smi_phy_write,
37424292 .port_set_link = mv88e6xxx_port_set_link,
3743
- .port_set_duplex = mv88e6xxx_port_set_duplex,
37444293 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3745
- .port_set_speed = mv88e6185_port_set_speed,
4294
+ .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
37464295 .port_tag_remap = mv88e6095_port_tag_remap,
4296
+ .port_set_policy = mv88e6352_port_set_policy,
37474297 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
37484298 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
37494299 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -3752,8 +4302,8 @@
37524302 .port_pause_limit = mv88e6097_port_pause_limit,
37534303 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
37544304 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3755
- .port_link_state = mv88e6352_port_link_state,
37564305 .port_get_cmode = mv88e6352_port_get_cmode,
4306
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
37574307 .stats_snapshot = mv88e6320_g1_stats_snapshot,
37584308 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
37594309 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3765,7 +4315,8 @@
37654315 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
37664316 .pot_clear = mv88e6xxx_g2_pot_clear,
37674317 .reset = mv88e6352_g1_reset,
3768
- .rmu_disable = mv88e6390_g1_rmu_disable,
4318
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4319
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
37694320 .vtu_getnext = mv88e6352_g1_vtu_getnext,
37704321 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
37714322 .avb_ops = &mv88e6352_avb_ops,
....@@ -3784,10 +4335,10 @@
37844335 .phy_read = mv88e6xxx_g2_smi_phy_read,
37854336 .phy_write = mv88e6xxx_g2_smi_phy_write,
37864337 .port_set_link = mv88e6xxx_port_set_link,
3787
- .port_set_duplex = mv88e6xxx_port_set_duplex,
37884338 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3789
- .port_set_speed = mv88e6352_port_set_speed,
4339
+ .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
37904340 .port_tag_remap = mv88e6095_port_tag_remap,
4341
+ .port_set_policy = mv88e6352_port_set_policy,
37914342 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
37924343 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
37934344 .port_set_ether_type = mv88e6351_port_set_ether_type,
....@@ -3796,8 +4347,8 @@
37964347 .port_pause_limit = mv88e6097_port_pause_limit,
37974348 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
37984349 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3799
- .port_link_state = mv88e6352_port_link_state,
38004350 .port_get_cmode = mv88e6352_port_get_cmode,
4351
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
38014352 .stats_snapshot = mv88e6320_g1_stats_snapshot,
38024353 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
38034354 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
....@@ -3810,15 +4361,27 @@
38104361 .pot_clear = mv88e6xxx_g2_pot_clear,
38114362 .reset = mv88e6352_g1_reset,
38124363 .rmu_disable = mv88e6352_g1_rmu_disable,
4364
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4365
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
38134366 .vtu_getnext = mv88e6352_g1_vtu_getnext,
38144367 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4368
+ .serdes_get_lane = mv88e6352_serdes_get_lane,
4369
+ .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
4370
+ .serdes_pcs_config = mv88e6352_serdes_pcs_config,
4371
+ .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
4372
+ .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
38154373 .serdes_power = mv88e6352_serdes_power,
4374
+ .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
4375
+ .serdes_irq_enable = mv88e6352_serdes_irq_enable,
4376
+ .serdes_irq_status = mv88e6352_serdes_irq_status,
38164377 .gpio_ops = &mv88e6352_gpio_ops,
38174378 .avb_ops = &mv88e6352_avb_ops,
38184379 .ptp_ops = &mv88e6352_ptp_ops,
38194380 .serdes_get_sset_count = mv88e6352_serdes_get_sset_count,
38204381 .serdes_get_strings = mv88e6352_serdes_get_strings,
38214382 .serdes_get_stats = mv88e6352_serdes_get_stats,
4383
+ .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
4384
+ .serdes_get_regs = mv88e6352_serdes_get_regs,
38224385 .phylink_validate = mv88e6352_phylink_validate,
38234386 };
38244387
....@@ -3832,21 +4395,22 @@
38324395 .phy_read = mv88e6xxx_g2_smi_phy_read,
38334396 .phy_write = mv88e6xxx_g2_smi_phy_write,
38344397 .port_set_link = mv88e6xxx_port_set_link,
3835
- .port_set_duplex = mv88e6xxx_port_set_duplex,
38364398 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3837
- .port_set_speed = mv88e6390_port_set_speed,
4399
+ .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
4400
+ .port_max_speed_mode = mv88e6390_port_max_speed_mode,
38384401 .port_tag_remap = mv88e6390_port_tag_remap,
4402
+ .port_set_policy = mv88e6352_port_set_policy,
38394403 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
38404404 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
38414405 .port_set_ether_type = mv88e6351_port_set_ether_type,
38424406 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
38434407 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
38444408 .port_pause_limit = mv88e6390_port_pause_limit,
3845
- .port_set_cmode = mv88e6390x_port_set_cmode,
38464409 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
38474410 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3848
- .port_link_state = mv88e6352_port_link_state,
38494411 .port_get_cmode = mv88e6352_port_get_cmode,
4412
+ .port_set_cmode = mv88e6390_port_set_cmode,
4413
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
38504414 .stats_snapshot = mv88e6390_g1_stats_snapshot,
38514415 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
38524416 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3859,14 +4423,28 @@
38594423 .pot_clear = mv88e6xxx_g2_pot_clear,
38604424 .reset = mv88e6352_g1_reset,
38614425 .rmu_disable = mv88e6390_g1_rmu_disable,
4426
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4427
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
38624428 .vtu_getnext = mv88e6390_g1_vtu_getnext,
38634429 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
38644430 .serdes_power = mv88e6390_serdes_power,
3865
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3866
- .serdes_irq_free = mv88e6390_serdes_irq_free,
4431
+ .serdes_get_lane = mv88e6390_serdes_get_lane,
4432
+ /* Check status register pause & lpa register */
4433
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4434
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
4435
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4436
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4437
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4438
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
4439
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
38674440 .gpio_ops = &mv88e6352_gpio_ops,
38684441 .avb_ops = &mv88e6390_avb_ops,
38694442 .ptp_ops = &mv88e6352_ptp_ops,
4443
+ .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
4444
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
4445
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
4446
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4447
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
38704448 .phylink_validate = mv88e6390_phylink_validate,
38714449 };
38724450
....@@ -3880,21 +4458,22 @@
38804458 .phy_read = mv88e6xxx_g2_smi_phy_read,
38814459 .phy_write = mv88e6xxx_g2_smi_phy_write,
38824460 .port_set_link = mv88e6xxx_port_set_link,
3883
- .port_set_duplex = mv88e6xxx_port_set_duplex,
38844461 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3885
- .port_set_speed = mv88e6390x_port_set_speed,
4462
+ .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
4463
+ .port_max_speed_mode = mv88e6390x_port_max_speed_mode,
38864464 .port_tag_remap = mv88e6390_port_tag_remap,
4465
+ .port_set_policy = mv88e6352_port_set_policy,
38874466 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
38884467 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
38894468 .port_set_ether_type = mv88e6351_port_set_ether_type,
38904469 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
38914470 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
38924471 .port_pause_limit = mv88e6390_port_pause_limit,
3893
- .port_set_cmode = mv88e6390x_port_set_cmode,
38944472 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
38954473 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3896
- .port_link_state = mv88e6352_port_link_state,
38974474 .port_get_cmode = mv88e6352_port_get_cmode,
4475
+ .port_set_cmode = mv88e6390x_port_set_cmode,
4476
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
38984477 .stats_snapshot = mv88e6390_g1_stats_snapshot,
38994478 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
39004479 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
....@@ -3907,11 +4486,24 @@
39074486 .pot_clear = mv88e6xxx_g2_pot_clear,
39084487 .reset = mv88e6352_g1_reset,
39094488 .rmu_disable = mv88e6390_g1_rmu_disable,
4489
+ .atu_get_hash = mv88e6165_g1_atu_get_hash,
4490
+ .atu_set_hash = mv88e6165_g1_atu_set_hash,
39104491 .vtu_getnext = mv88e6390_g1_vtu_getnext,
39114492 .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,
4493
+ .serdes_power = mv88e6390_serdes_power,
4494
+ .serdes_get_lane = mv88e6390x_serdes_get_lane,
4495
+ .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4496
+ .serdes_pcs_config = mv88e6390_serdes_pcs_config,
4497
+ .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4498
+ .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4499
+ .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4500
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
4501
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
4502
+ .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
4503
+ .serdes_get_strings = mv88e6390_serdes_get_strings,
4504
+ .serdes_get_stats = mv88e6390_serdes_get_stats,
4505
+ .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4506
+ .serdes_get_regs = mv88e6390_serdes_get_regs,
39154507 .gpio_ops = &mv88e6352_gpio_ops,
39164508 .avb_ops = &mv88e6390_avb_ops,
39174509 .ptp_ops = &mv88e6352_ptp_ops,
....@@ -3924,6 +4516,7 @@
39244516 .family = MV88E6XXX_FAMILY_6097,
39254517 .name = "Marvell 88E6085",
39264518 .num_databases = 4096,
4519
+ .num_macs = 8192,
39274520 .num_ports = 10,
39284521 .num_internal_phys = 5,
39294522 .max_vid = 4095,
....@@ -3946,6 +4539,7 @@
39464539 .family = MV88E6XXX_FAMILY_6095,
39474540 .name = "Marvell 88E6095/88E6095F",
39484541 .num_databases = 256,
4542
+ .num_macs = 8192,
39494543 .num_ports = 11,
39504544 .num_internal_phys = 0,
39514545 .max_vid = 4095,
....@@ -3966,6 +4560,7 @@
39664560 .family = MV88E6XXX_FAMILY_6097,
39674561 .name = "Marvell 88E6097/88E6097F",
39684562 .num_databases = 4096,
4563
+ .num_macs = 8192,
39694564 .num_ports = 11,
39704565 .num_internal_phys = 8,
39714566 .max_vid = 4095,
....@@ -3988,6 +4583,7 @@
39884583 .family = MV88E6XXX_FAMILY_6165,
39894584 .name = "Marvell 88E6123",
39904585 .num_databases = 4096,
4586
+ .num_macs = 1024,
39914587 .num_ports = 3,
39924588 .num_internal_phys = 5,
39934589 .max_vid = 4095,
....@@ -4010,6 +4606,7 @@
40104606 .family = MV88E6XXX_FAMILY_6185,
40114607 .name = "Marvell 88E6131",
40124608 .num_databases = 256,
4609
+ .num_macs = 8192,
40134610 .num_ports = 8,
40144611 .num_internal_phys = 0,
40154612 .max_vid = 4095,
....@@ -4030,6 +4627,7 @@
40304627 .family = MV88E6XXX_FAMILY_6341,
40314628 .name = "Marvell 88E6141",
40324629 .num_databases = 4096,
4630
+ .num_macs = 2048,
40334631 .num_ports = 6,
40344632 .num_internal_phys = 5,
40354633 .num_gpio = 11,
....@@ -4053,6 +4651,7 @@
40534651 .family = MV88E6XXX_FAMILY_6165,
40544652 .name = "Marvell 88E6161",
40554653 .num_databases = 4096,
4654
+ .num_macs = 1024,
40564655 .num_ports = 6,
40574656 .num_internal_phys = 5,
40584657 .max_vid = 4095,
....@@ -4076,6 +4675,7 @@
40764675 .family = MV88E6XXX_FAMILY_6165,
40774676 .name = "Marvell 88E6165",
40784677 .num_databases = 4096,
4678
+ .num_macs = 8192,
40794679 .num_ports = 6,
40804680 .num_internal_phys = 0,
40814681 .max_vid = 4095,
....@@ -4099,6 +4699,7 @@
40994699 .family = MV88E6XXX_FAMILY_6351,
41004700 .name = "Marvell 88E6171",
41014701 .num_databases = 4096,
4702
+ .num_macs = 8192,
41024703 .num_ports = 7,
41034704 .num_internal_phys = 5,
41044705 .max_vid = 4095,
....@@ -4121,6 +4722,7 @@
41214722 .family = MV88E6XXX_FAMILY_6352,
41224723 .name = "Marvell 88E6172",
41234724 .num_databases = 4096,
4725
+ .num_macs = 8192,
41244726 .num_ports = 7,
41254727 .num_internal_phys = 5,
41264728 .num_gpio = 15,
....@@ -4144,6 +4746,7 @@
41444746 .family = MV88E6XXX_FAMILY_6351,
41454747 .name = "Marvell 88E6175",
41464748 .num_databases = 4096,
4749
+ .num_macs = 8192,
41474750 .num_ports = 7,
41484751 .num_internal_phys = 5,
41494752 .max_vid = 4095,
....@@ -4166,6 +4769,7 @@
41664769 .family = MV88E6XXX_FAMILY_6352,
41674770 .name = "Marvell 88E6176",
41684771 .num_databases = 4096,
4772
+ .num_macs = 8192,
41694773 .num_ports = 7,
41704774 .num_internal_phys = 5,
41714775 .num_gpio = 15,
....@@ -4189,6 +4793,7 @@
41894793 .family = MV88E6XXX_FAMILY_6185,
41904794 .name = "Marvell 88E6185",
41914795 .num_databases = 256,
4796
+ .num_macs = 8192,
41924797 .num_ports = 10,
41934798 .num_internal_phys = 0,
41944799 .max_vid = 4095,
....@@ -4209,6 +4814,7 @@
42094814 .family = MV88E6XXX_FAMILY_6390,
42104815 .name = "Marvell 88E6190",
42114816 .num_databases = 4096,
4817
+ .num_macs = 16384,
42124818 .num_ports = 11, /* 10 + Z80 */
42134819 .num_internal_phys = 9,
42144820 .num_gpio = 16,
....@@ -4232,6 +4838,7 @@
42324838 .family = MV88E6XXX_FAMILY_6390,
42334839 .name = "Marvell 88E6190X",
42344840 .num_databases = 4096,
4841
+ .num_macs = 16384,
42354842 .num_ports = 11, /* 10 + Z80 */
42364843 .num_internal_phys = 9,
42374844 .num_gpio = 16,
....@@ -4255,6 +4862,7 @@
42554862 .family = MV88E6XXX_FAMILY_6390,
42564863 .name = "Marvell 88E6191",
42574864 .num_databases = 4096,
4865
+ .num_macs = 16384,
42584866 .num_ports = 11, /* 10 + Z80 */
42594867 .num_internal_phys = 9,
42604868 .max_vid = 8191,
....@@ -4273,11 +4881,39 @@
42734881 .ops = &mv88e6191_ops,
42744882 },
42754883
4884
+ [MV88E6220] = {
4885
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6220,
4886
+ .family = MV88E6XXX_FAMILY_6250,
4887
+ .name = "Marvell 88E6220",
4888
+ .num_databases = 64,
4889
+
4890
+ /* Ports 2-4 are not routed to pins
4891
+ * => usable ports 0, 1, 5, 6
4892
+ */
4893
+ .num_ports = 7,
4894
+ .num_internal_phys = 2,
4895
+ .invalid_port_mask = BIT(2) | BIT(3) | BIT(4),
4896
+ .max_vid = 4095,
4897
+ .port_base_addr = 0x08,
4898
+ .phy_base_addr = 0x00,
4899
+ .global1_addr = 0x0f,
4900
+ .global2_addr = 0x07,
4901
+ .age_time_coeff = 15000,
4902
+ .g1_irqs = 9,
4903
+ .g2_irqs = 10,
4904
+ .atu_move_port_mask = 0xf,
4905
+ .dual_chip = true,
4906
+ .tag_protocol = DSA_TAG_PROTO_DSA,
4907
+ .ptp_support = true,
4908
+ .ops = &mv88e6250_ops,
4909
+ },
4910
+
42764911 [MV88E6240] = {
42774912 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6240,
42784913 .family = MV88E6XXX_FAMILY_6352,
42794914 .name = "Marvell 88E6240",
42804915 .num_databases = 4096,
4916
+ .num_macs = 8192,
42814917 .num_ports = 7,
42824918 .num_internal_phys = 5,
42834919 .num_gpio = 15,
....@@ -4295,6 +4931,28 @@
42954931 .tag_protocol = DSA_TAG_PROTO_EDSA,
42964932 .ptp_support = true,
42974933 .ops = &mv88e6240_ops,
4934
+ },
4935
+
4936
+ [MV88E6250] = {
4937
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6250,
4938
+ .family = MV88E6XXX_FAMILY_6250,
4939
+ .name = "Marvell 88E6250",
4940
+ .num_databases = 64,
4941
+ .num_ports = 7,
4942
+ .num_internal_phys = 5,
4943
+ .max_vid = 4095,
4944
+ .port_base_addr = 0x08,
4945
+ .phy_base_addr = 0x00,
4946
+ .global1_addr = 0x0f,
4947
+ .global2_addr = 0x07,
4948
+ .age_time_coeff = 15000,
4949
+ .g1_irqs = 9,
4950
+ .g2_irqs = 10,
4951
+ .atu_move_port_mask = 0xf,
4952
+ .dual_chip = true,
4953
+ .tag_protocol = DSA_TAG_PROTO_DSA,
4954
+ .ptp_support = true,
4955
+ .ops = &mv88e6250_ops,
42984956 },
42994957
43004958 [MV88E6290] = {
....@@ -4326,6 +4984,7 @@
43264984 .family = MV88E6XXX_FAMILY_6320,
43274985 .name = "Marvell 88E6320",
43284986 .num_databases = 4096,
4987
+ .num_macs = 8192,
43294988 .num_ports = 7,
43304989 .num_internal_phys = 5,
43314990 .num_gpio = 15,
....@@ -4350,6 +5009,7 @@
43505009 .family = MV88E6XXX_FAMILY_6320,
43515010 .name = "Marvell 88E6321",
43525011 .num_databases = 4096,
5012
+ .num_macs = 8192,
43535013 .num_ports = 7,
43545014 .num_internal_phys = 5,
43555015 .num_gpio = 15,
....@@ -4373,6 +5033,7 @@
43735033 .family = MV88E6XXX_FAMILY_6341,
43745034 .name = "Marvell 88E6341",
43755035 .num_databases = 4096,
5036
+ .num_macs = 2048,
43765037 .num_internal_phys = 5,
43775038 .num_ports = 6,
43785039 .num_gpio = 11,
....@@ -4397,6 +5058,7 @@
43975058 .family = MV88E6XXX_FAMILY_6351,
43985059 .name = "Marvell 88E6350",
43995060 .num_databases = 4096,
5061
+ .num_macs = 8192,
44005062 .num_ports = 7,
44015063 .num_internal_phys = 5,
44025064 .max_vid = 4095,
....@@ -4419,6 +5081,7 @@
44195081 .family = MV88E6XXX_FAMILY_6351,
44205082 .name = "Marvell 88E6351",
44215083 .num_databases = 4096,
5084
+ .num_macs = 8192,
44225085 .num_ports = 7,
44235086 .num_internal_phys = 5,
44245087 .max_vid = 4095,
....@@ -4441,6 +5104,7 @@
44415104 .family = MV88E6XXX_FAMILY_6352,
44425105 .name = "Marvell 88E6352",
44435106 .num_databases = 4096,
5107
+ .num_macs = 8192,
44445108 .num_ports = 7,
44455109 .num_internal_phys = 5,
44465110 .num_gpio = 15,
....@@ -4464,6 +5128,7 @@
44645128 .family = MV88E6XXX_FAMILY_6390,
44655129 .name = "Marvell 88E6390",
44665130 .num_databases = 4096,
5131
+ .num_macs = 16384,
44675132 .num_ports = 11, /* 10 + Z80 */
44685133 .num_internal_phys = 9,
44695134 .num_gpio = 16,
....@@ -4487,6 +5152,7 @@
44875152 .family = MV88E6XXX_FAMILY_6390,
44885153 .name = "Marvell 88E6390X",
44895154 .num_databases = 4096,
5155
+ .num_macs = 16384,
44905156 .num_ports = 11, /* 10 + Z80 */
44915157 .num_internal_phys = 9,
44925158 .num_gpio = 16,
....@@ -4525,9 +5191,9 @@
45255191 u16 id;
45265192 int err;
45275193
4528
- mutex_lock(&chip->reg_lock);
5194
+ mv88e6xxx_reg_lock(chip);
45295195 err = mv88e6xxx_port_read(chip, 0, MV88E6XXX_PORT_SWITCH_ID, &id);
4530
- mutex_unlock(&chip->reg_lock);
5196
+ mv88e6xxx_reg_unlock(chip);
45315197 if (err)
45325198 return err;
45335199
....@@ -4563,93 +5229,19 @@
45635229
45645230 mutex_init(&chip->reg_lock);
45655231 INIT_LIST_HEAD(&chip->mdios);
5232
+ idr_init(&chip->policies);
45665233
45675234 return chip;
45685235 }
45695236
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
-
45945237 static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds,
4595
- int port)
5238
+ int port,
5239
+ enum dsa_tag_protocol m)
45965240 {
45975241 struct mv88e6xxx_chip *chip = ds->priv;
45985242
45995243 return chip->info->tag_protocol;
46005244 }
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
46535245
46545246 static int mv88e6xxx_port_mdb_prepare(struct dsa_switch *ds, int port,
46555247 const struct switchdev_obj_port_mdb *mdb)
....@@ -4666,12 +5258,12 @@
46665258 {
46675259 struct mv88e6xxx_chip *chip = ds->priv;
46685260
4669
- mutex_lock(&chip->reg_lock);
5261
+ mv88e6xxx_reg_lock(chip);
46705262 if (mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
46715263 MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC))
46725264 dev_err(ds->dev, "p%d: failed to load multicast MAC address\n",
46735265 port);
4674
- mutex_unlock(&chip->reg_lock);
5266
+ mv88e6xxx_reg_unlock(chip);
46755267 }
46765268
46775269 static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port,
....@@ -4680,24 +5272,111 @@
46805272 struct mv88e6xxx_chip *chip = ds->priv;
46815273 int err;
46825274
5275
+ mv88e6xxx_reg_lock(chip);
5276
+ err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid, 0);
5277
+ mv88e6xxx_reg_unlock(chip);
5278
+
5279
+ return err;
5280
+}
5281
+
5282
+static int mv88e6xxx_port_mirror_add(struct dsa_switch *ds, int port,
5283
+ struct dsa_mall_mirror_tc_entry *mirror,
5284
+ bool ingress)
5285
+{
5286
+ enum mv88e6xxx_egress_direction direction = ingress ?
5287
+ MV88E6XXX_EGRESS_DIR_INGRESS :
5288
+ MV88E6XXX_EGRESS_DIR_EGRESS;
5289
+ struct mv88e6xxx_chip *chip = ds->priv;
5290
+ bool other_mirrors = false;
5291
+ int i;
5292
+ int err;
5293
+
5294
+ if (!chip->info->ops->set_egress_port)
5295
+ return -EOPNOTSUPP;
5296
+
46835297 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);
5298
+ if ((ingress ? chip->ingress_dest_port : chip->egress_dest_port) !=
5299
+ mirror->to_local_port) {
5300
+ for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
5301
+ other_mirrors |= ingress ?
5302
+ chip->ports[i].mirror_ingress :
5303
+ chip->ports[i].mirror_egress;
5304
+
5305
+ /* Can't change egress port when other mirror is active */
5306
+ if (other_mirrors) {
5307
+ err = -EBUSY;
5308
+ goto out;
5309
+ }
5310
+
5311
+ err = chip->info->ops->set_egress_port(chip,
5312
+ direction,
5313
+ mirror->to_local_port);
5314
+ if (err)
5315
+ goto out;
5316
+ }
5317
+
5318
+ err = mv88e6xxx_port_set_mirror(chip, port, direction, true);
5319
+out:
46865320 mutex_unlock(&chip->reg_lock);
46875321
46885322 return err;
46895323 }
46905324
5325
+static void mv88e6xxx_port_mirror_del(struct dsa_switch *ds, int port,
5326
+ struct dsa_mall_mirror_tc_entry *mirror)
5327
+{
5328
+ enum mv88e6xxx_egress_direction direction = mirror->ingress ?
5329
+ MV88E6XXX_EGRESS_DIR_INGRESS :
5330
+ MV88E6XXX_EGRESS_DIR_EGRESS;
5331
+ struct mv88e6xxx_chip *chip = ds->priv;
5332
+ bool other_mirrors = false;
5333
+ int i;
5334
+
5335
+ mutex_lock(&chip->reg_lock);
5336
+ if (mv88e6xxx_port_set_mirror(chip, port, direction, false))
5337
+ dev_err(ds->dev, "p%d: failed to disable mirroring\n", port);
5338
+
5339
+ for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
5340
+ other_mirrors |= mirror->ingress ?
5341
+ chip->ports[i].mirror_ingress :
5342
+ chip->ports[i].mirror_egress;
5343
+
5344
+ /* Reset egress port when no other mirror is active */
5345
+ if (!other_mirrors) {
5346
+ if (chip->info->ops->set_egress_port(chip,
5347
+ direction,
5348
+ dsa_upstream_port(ds,
5349
+ port)))
5350
+ dev_err(ds->dev, "failed to set egress port\n");
5351
+ }
5352
+
5353
+ mutex_unlock(&chip->reg_lock);
5354
+}
5355
+
5356
+static int mv88e6xxx_port_egress_floods(struct dsa_switch *ds, int port,
5357
+ bool unicast, bool multicast)
5358
+{
5359
+ struct mv88e6xxx_chip *chip = ds->priv;
5360
+ int err = -EOPNOTSUPP;
5361
+
5362
+ mv88e6xxx_reg_lock(chip);
5363
+ if (chip->info->ops->port_set_egress_floods)
5364
+ err = chip->info->ops->port_set_egress_floods(chip, port,
5365
+ unicast,
5366
+ multicast);
5367
+ mv88e6xxx_reg_unlock(chip);
5368
+
5369
+ return err;
5370
+}
5371
+
46915372 static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
4692
-#if IS_ENABLED(CONFIG_NET_DSA_LEGACY)
4693
- .probe = mv88e6xxx_drv_probe,
4694
-#endif
46955373 .get_tag_protocol = mv88e6xxx_get_tag_protocol,
46965374 .setup = mv88e6xxx_setup,
4697
- .adjust_link = mv88e6xxx_adjust_link,
5375
+ .teardown = mv88e6xxx_teardown,
46985376 .phylink_validate = mv88e6xxx_validate,
4699
- .phylink_mac_link_state = mv88e6xxx_link_state,
5377
+ .phylink_mac_link_state = mv88e6xxx_serdes_pcs_get_state,
47005378 .phylink_mac_config = mv88e6xxx_mac_config,
5379
+ .phylink_mac_an_restart = mv88e6xxx_serdes_pcs_an_restart,
47015380 .phylink_mac_link_down = mv88e6xxx_mac_link_down,
47025381 .phylink_mac_link_up = mv88e6xxx_mac_link_up,
47035382 .get_strings = mv88e6xxx_get_strings,
....@@ -4705,6 +5384,8 @@
47055384 .get_sset_count = mv88e6xxx_get_sset_count,
47065385 .port_enable = mv88e6xxx_port_enable,
47075386 .port_disable = mv88e6xxx_port_disable,
5387
+ .port_max_mtu = mv88e6xxx_get_max_mtu,
5388
+ .port_change_mtu = mv88e6xxx_change_mtu,
47085389 .get_mac_eee = mv88e6xxx_get_mac_eee,
47095390 .set_mac_eee = mv88e6xxx_set_mac_eee,
47105391 .get_eeprom_len = mv88e6xxx_get_eeprom_len,
....@@ -4712,9 +5393,12 @@
47125393 .set_eeprom = mv88e6xxx_set_eeprom,
47135394 .get_regs_len = mv88e6xxx_get_regs_len,
47145395 .get_regs = mv88e6xxx_get_regs,
5396
+ .get_rxnfc = mv88e6xxx_get_rxnfc,
5397
+ .set_rxnfc = mv88e6xxx_set_rxnfc,
47155398 .set_ageing_time = mv88e6xxx_set_ageing_time,
47165399 .port_bridge_join = mv88e6xxx_port_bridge_join,
47175400 .port_bridge_leave = mv88e6xxx_port_bridge_leave,
5401
+ .port_egress_floods = mv88e6xxx_port_egress_floods,
47185402 .port_stp_state_set = mv88e6xxx_port_stp_state_set,
47195403 .port_fast_age = mv88e6xxx_port_fast_age,
47205404 .port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
....@@ -4727,6 +5411,8 @@
47275411 .port_mdb_prepare = mv88e6xxx_port_mdb_prepare,
47285412 .port_mdb_add = mv88e6xxx_port_mdb_add,
47295413 .port_mdb_del = mv88e6xxx_port_mdb_del,
5414
+ .port_mirror_add = mv88e6xxx_port_mirror_add,
5415
+ .port_mirror_del = mv88e6xxx_port_mirror_del,
47305416 .crosschip_bridge_join = mv88e6xxx_crosschip_bridge_join,
47315417 .crosschip_bridge_leave = mv88e6xxx_crosschip_bridge_leave,
47325418 .port_hwtstamp_set = mv88e6xxx_port_hwtstamp_set,
....@@ -4734,10 +5420,9 @@
47345420 .port_txtstamp = mv88e6xxx_port_txtstamp,
47355421 .port_rxtstamp = mv88e6xxx_port_rxtstamp,
47365422 .get_ts_info = mv88e6xxx_get_ts_info,
4737
-};
4738
-
4739
-static struct dsa_switch_driver mv88e6xxx_switch_drv = {
4740
- .ops = &mv88e6xxx_switch_ops,
5423
+ .devlink_param_get = mv88e6xxx_devlink_param_get,
5424
+ .devlink_param_set = mv88e6xxx_devlink_param_set,
5425
+ .devlink_info_get = mv88e6xxx_devlink_info_get,
47415426 };
47425427
47435428 static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
....@@ -4745,10 +5430,12 @@
47455430 struct device *dev = chip->dev;
47465431 struct dsa_switch *ds;
47475432
4748
- ds = dsa_switch_alloc(dev, mv88e6xxx_num_ports(chip));
5433
+ ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
47495434 if (!ds)
47505435 return -ENOMEM;
47515436
5437
+ ds->dev = dev;
5438
+ ds->num_ports = mv88e6xxx_num_ports(chip);
47525439 ds->priv = chip;
47535440 ds->dev = dev;
47545441 ds->ops = &mv88e6xxx_switch_ops;
....@@ -4777,6 +5464,21 @@
47775464 }
47785465 return NULL;
47795466 }
5467
+
5468
+/* There is no suspend to RAM support at DSA level yet, the switch configuration
5469
+ * would be lost after a power cycle so prevent it to be suspended.
5470
+ */
5471
+static int __maybe_unused mv88e6xxx_suspend(struct device *dev)
5472
+{
5473
+ return -EOPNOTSUPP;
5474
+}
5475
+
5476
+static int __maybe_unused mv88e6xxx_resume(struct device *dev)
5477
+{
5478
+ return 0;
5479
+}
5480
+
5481
+static SIMPLE_DEV_PM_OPS(mv88e6xxx_pm_ops, mv88e6xxx_suspend, mv88e6xxx_resume);
47805482
47815483 static int mv88e6xxx_probe(struct mdio_device *mdiodev)
47825484 {
....@@ -4837,7 +5539,6 @@
48375539 if (err)
48385540 goto out;
48395541
4840
- mv88e6xxx_ports_cmode_init(chip);
48415542 mv88e6xxx_phy_init(chip);
48425543
48435544 if (chip->info->ops->get_eeprom) {
....@@ -4848,28 +5549,33 @@
48485549 chip->eeprom_len = pdata->eeprom_len;
48495550 }
48505551
4851
- mutex_lock(&chip->reg_lock);
5552
+ mv88e6xxx_reg_lock(chip);
48525553 err = mv88e6xxx_switch_reset(chip);
4853
- mutex_unlock(&chip->reg_lock);
5554
+ mv88e6xxx_reg_unlock(chip);
48545555 if (err)
48555556 goto out;
48565557
4857
- chip->irq = of_irq_get(np, 0);
4858
- if (chip->irq == -EPROBE_DEFER) {
4859
- err = chip->irq;
4860
- goto out;
5558
+ if (np) {
5559
+ chip->irq = of_irq_get(np, 0);
5560
+ if (chip->irq == -EPROBE_DEFER) {
5561
+ err = chip->irq;
5562
+ goto out;
5563
+ }
48615564 }
5565
+
5566
+ if (pdata)
5567
+ chip->irq = pdata->irq;
48625568
48635569 /* Has to be performed before the MDIO bus is created, because
48645570 * the PHYs will link their interrupts to these interrupt
48655571 * controllers
48665572 */
4867
- mutex_lock(&chip->reg_lock);
5573
+ mv88e6xxx_reg_lock(chip);
48685574 if (chip->irq > 0)
48695575 err = mv88e6xxx_g1_irq_setup(chip);
48705576 else
48715577 err = mv88e6xxx_irq_poll_setup(chip);
4872
- mutex_unlock(&chip->reg_lock);
5578
+ mv88e6xxx_reg_unlock(chip);
48735579
48745580 if (err)
48755581 goto out;
....@@ -4954,6 +5660,10 @@
49545660 .compatible = "marvell,mv88e6190",
49555661 .data = &mv88e6xxx_table[MV88E6190],
49565662 },
5663
+ {
5664
+ .compatible = "marvell,mv88e6250",
5665
+ .data = &mv88e6xxx_table[MV88E6250],
5666
+ },
49575667 { /* sentinel */ },
49585668 };
49595669
....@@ -4965,22 +5675,11 @@
49655675 .mdiodrv.driver = {
49665676 .name = "mv88e6085",
49675677 .of_match_table = mv88e6xxx_of_match,
5678
+ .pm = &mv88e6xxx_pm_ops,
49685679 },
49695680 };
49705681
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);
5682
+mdio_module_driver(mv88e6xxx_driver);
49845683
49855684 MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
49865685 MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");