]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - drivers/net/dsa/mv88e6xxx/chip.c
Merge branch 'PTP-support-for-DSA-and-mv88e6xxx-driver'
[mirror_ubuntu-jammy-kernel.git] / drivers / net / dsa / mv88e6xxx / chip.c
1 /*
2 * Marvell 88e6xxx Ethernet switch single-chip support
3 *
4 * Copyright (c) 2008 Marvell Semiconductor
5 *
6 * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch>
7 *
8 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
9 * 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.
15 */
16
17 #include <linux/delay.h>
18 #include <linux/etherdevice.h>
19 #include <linux/ethtool.h>
20 #include <linux/if_bridge.h>
21 #include <linux/interrupt.h>
22 #include <linux/irq.h>
23 #include <linux/irqdomain.h>
24 #include <linux/jiffies.h>
25 #include <linux/list.h>
26 #include <linux/mdio.h>
27 #include <linux/module.h>
28 #include <linux/of_device.h>
29 #include <linux/of_irq.h>
30 #include <linux/of_mdio.h>
31 #include <linux/netdevice.h>
32 #include <linux/gpio/consumer.h>
33 #include <linux/phy.h>
34 #include <net/dsa.h>
35
36 #include "chip.h"
37 #include "global1.h"
38 #include "global2.h"
39 #include "hwtstamp.h"
40 #include "phy.h"
41 #include "port.h"
42 #include "ptp.h"
43 #include "serdes.h"
44
45 static void assert_reg_lock(struct mv88e6xxx_chip *chip)
46 {
47 if (unlikely(!mutex_is_locked(&chip->reg_lock))) {
48 dev_err(chip->dev, "Switch registers lock not held!\n");
49 dump_stack();
50 }
51 }
52
53 /* The switch ADDR[4:1] configuration pins define the chip SMI device address
54 * (ADDR[0] is always zero, thus only even SMI addresses can be strapped).
55 *
56 * When ADDR is all zero, the chip uses Single-chip Addressing Mode, assuming it
57 * is the only device connected to the SMI master. In this mode it responds to
58 * all 32 possible SMI addresses, and thus maps directly the internal devices.
59 *
60 * When ADDR is non-zero, the chip uses Multi-chip Addressing Mode, allowing
61 * multiple devices to share the SMI interface. In this mode it responds to only
62 * 2 registers, used to indirectly access the internal SMI devices.
63 */
64
65 static int mv88e6xxx_smi_read(struct mv88e6xxx_chip *chip,
66 int addr, int reg, u16 *val)
67 {
68 if (!chip->smi_ops)
69 return -EOPNOTSUPP;
70
71 return chip->smi_ops->read(chip, addr, reg, val);
72 }
73
74 static int mv88e6xxx_smi_write(struct mv88e6xxx_chip *chip,
75 int addr, int reg, u16 val)
76 {
77 if (!chip->smi_ops)
78 return -EOPNOTSUPP;
79
80 return chip->smi_ops->write(chip, addr, reg, val);
81 }
82
83 static int mv88e6xxx_smi_single_chip_read(struct mv88e6xxx_chip *chip,
84 int addr, int reg, u16 *val)
85 {
86 int ret;
87
88 ret = mdiobus_read_nested(chip->bus, addr, reg);
89 if (ret < 0)
90 return ret;
91
92 *val = ret & 0xffff;
93
94 return 0;
95 }
96
97 static int mv88e6xxx_smi_single_chip_write(struct mv88e6xxx_chip *chip,
98 int addr, int reg, u16 val)
99 {
100 int ret;
101
102 ret = mdiobus_write_nested(chip->bus, addr, reg, val);
103 if (ret < 0)
104 return ret;
105
106 return 0;
107 }
108
109 static const struct mv88e6xxx_bus_ops mv88e6xxx_smi_single_chip_ops = {
110 .read = mv88e6xxx_smi_single_chip_read,
111 .write = mv88e6xxx_smi_single_chip_write,
112 };
113
114 static int mv88e6xxx_smi_multi_chip_wait(struct mv88e6xxx_chip *chip)
115 {
116 int ret;
117 int i;
118
119 for (i = 0; i < 16; i++) {
120 ret = mdiobus_read_nested(chip->bus, chip->sw_addr, SMI_CMD);
121 if (ret < 0)
122 return ret;
123
124 if ((ret & SMI_CMD_BUSY) == 0)
125 return 0;
126 }
127
128 return -ETIMEDOUT;
129 }
130
131 static int mv88e6xxx_smi_multi_chip_read(struct mv88e6xxx_chip *chip,
132 int addr, int reg, u16 *val)
133 {
134 int ret;
135
136 /* Wait for the bus to become free. */
137 ret = mv88e6xxx_smi_multi_chip_wait(chip);
138 if (ret < 0)
139 return ret;
140
141 /* Transmit the read command. */
142 ret = mdiobus_write_nested(chip->bus, chip->sw_addr, SMI_CMD,
143 SMI_CMD_OP_22_READ | (addr << 5) | reg);
144 if (ret < 0)
145 return ret;
146
147 /* Wait for the read command to complete. */
148 ret = mv88e6xxx_smi_multi_chip_wait(chip);
149 if (ret < 0)
150 return ret;
151
152 /* Read the data. */
153 ret = mdiobus_read_nested(chip->bus, chip->sw_addr, SMI_DATA);
154 if (ret < 0)
155 return ret;
156
157 *val = ret & 0xffff;
158
159 return 0;
160 }
161
162 static int mv88e6xxx_smi_multi_chip_write(struct mv88e6xxx_chip *chip,
163 int addr, int reg, u16 val)
164 {
165 int ret;
166
167 /* Wait for the bus to become free. */
168 ret = mv88e6xxx_smi_multi_chip_wait(chip);
169 if (ret < 0)
170 return ret;
171
172 /* Transmit the data to write. */
173 ret = mdiobus_write_nested(chip->bus, chip->sw_addr, SMI_DATA, val);
174 if (ret < 0)
175 return ret;
176
177 /* Transmit the write command. */
178 ret = mdiobus_write_nested(chip->bus, chip->sw_addr, SMI_CMD,
179 SMI_CMD_OP_22_WRITE | (addr << 5) | reg);
180 if (ret < 0)
181 return ret;
182
183 /* Wait for the write command to complete. */
184 ret = mv88e6xxx_smi_multi_chip_wait(chip);
185 if (ret < 0)
186 return ret;
187
188 return 0;
189 }
190
191 static const struct mv88e6xxx_bus_ops mv88e6xxx_smi_multi_chip_ops = {
192 .read = mv88e6xxx_smi_multi_chip_read,
193 .write = mv88e6xxx_smi_multi_chip_write,
194 };
195
196 int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val)
197 {
198 int err;
199
200 assert_reg_lock(chip);
201
202 err = mv88e6xxx_smi_read(chip, addr, reg, val);
203 if (err)
204 return err;
205
206 dev_dbg(chip->dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
207 addr, reg, *val);
208
209 return 0;
210 }
211
212 int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val)
213 {
214 int err;
215
216 assert_reg_lock(chip);
217
218 err = mv88e6xxx_smi_write(chip, addr, reg, val);
219 if (err)
220 return err;
221
222 dev_dbg(chip->dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
223 addr, reg, val);
224
225 return 0;
226 }
227
228 struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip)
229 {
230 struct mv88e6xxx_mdio_bus *mdio_bus;
231
232 mdio_bus = list_first_entry(&chip->mdios, struct mv88e6xxx_mdio_bus,
233 list);
234 if (!mdio_bus)
235 return NULL;
236
237 return mdio_bus->bus;
238 }
239
240 static void mv88e6xxx_g1_irq_mask(struct irq_data *d)
241 {
242 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
243 unsigned int n = d->hwirq;
244
245 chip->g1_irq.masked |= (1 << n);
246 }
247
248 static void mv88e6xxx_g1_irq_unmask(struct irq_data *d)
249 {
250 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
251 unsigned int n = d->hwirq;
252
253 chip->g1_irq.masked &= ~(1 << n);
254 }
255
256 static irqreturn_t mv88e6xxx_g1_irq_thread_fn(int irq, void *dev_id)
257 {
258 struct mv88e6xxx_chip *chip = dev_id;
259 unsigned int nhandled = 0;
260 unsigned int sub_irq;
261 unsigned int n;
262 u16 reg;
263 int err;
264
265 mutex_lock(&chip->reg_lock);
266 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
267 mutex_unlock(&chip->reg_lock);
268
269 if (err)
270 goto out;
271
272 for (n = 0; n < chip->g1_irq.nirqs; ++n) {
273 if (reg & (1 << n)) {
274 sub_irq = irq_find_mapping(chip->g1_irq.domain, n);
275 handle_nested_irq(sub_irq);
276 ++nhandled;
277 }
278 }
279 out:
280 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
281 }
282
283 static void mv88e6xxx_g1_irq_bus_lock(struct irq_data *d)
284 {
285 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
286
287 mutex_lock(&chip->reg_lock);
288 }
289
290 static void mv88e6xxx_g1_irq_bus_sync_unlock(struct irq_data *d)
291 {
292 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
293 u16 mask = GENMASK(chip->g1_irq.nirqs, 0);
294 u16 reg;
295 int err;
296
297 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &reg);
298 if (err)
299 goto out;
300
301 reg &= ~mask;
302 reg |= (~chip->g1_irq.masked & mask);
303
304 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, reg);
305 if (err)
306 goto out;
307
308 out:
309 mutex_unlock(&chip->reg_lock);
310 }
311
312 static const struct irq_chip mv88e6xxx_g1_irq_chip = {
313 .name = "mv88e6xxx-g1",
314 .irq_mask = mv88e6xxx_g1_irq_mask,
315 .irq_unmask = mv88e6xxx_g1_irq_unmask,
316 .irq_bus_lock = mv88e6xxx_g1_irq_bus_lock,
317 .irq_bus_sync_unlock = mv88e6xxx_g1_irq_bus_sync_unlock,
318 };
319
320 static int mv88e6xxx_g1_irq_domain_map(struct irq_domain *d,
321 unsigned int irq,
322 irq_hw_number_t hwirq)
323 {
324 struct mv88e6xxx_chip *chip = d->host_data;
325
326 irq_set_chip_data(irq, d->host_data);
327 irq_set_chip_and_handler(irq, &chip->g1_irq.chip, handle_level_irq);
328 irq_set_noprobe(irq);
329
330 return 0;
331 }
332
333 static const struct irq_domain_ops mv88e6xxx_g1_irq_domain_ops = {
334 .map = mv88e6xxx_g1_irq_domain_map,
335 .xlate = irq_domain_xlate_twocell,
336 };
337
338 static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip)
339 {
340 int irq, virq;
341 u16 mask;
342
343 mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
344 mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
345 mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
346
347 free_irq(chip->irq, chip);
348
349 for (irq = 0; irq < chip->g1_irq.nirqs; irq++) {
350 virq = irq_find_mapping(chip->g1_irq.domain, irq);
351 irq_dispose_mapping(virq);
352 }
353
354 irq_domain_remove(chip->g1_irq.domain);
355 }
356
357 static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip)
358 {
359 int err, irq, virq;
360 u16 reg, mask;
361
362 chip->g1_irq.nirqs = chip->info->g1_irqs;
363 chip->g1_irq.domain = irq_domain_add_simple(
364 NULL, chip->g1_irq.nirqs, 0,
365 &mv88e6xxx_g1_irq_domain_ops, chip);
366 if (!chip->g1_irq.domain)
367 return -ENOMEM;
368
369 for (irq = 0; irq < chip->g1_irq.nirqs; irq++)
370 irq_create_mapping(chip->g1_irq.domain, irq);
371
372 chip->g1_irq.chip = mv88e6xxx_g1_irq_chip;
373 chip->g1_irq.masked = ~0;
374
375 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
376 if (err)
377 goto out_mapping;
378
379 mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
380
381 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
382 if (err)
383 goto out_disable;
384
385 /* Reading the interrupt status clears (most of) them */
386 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
387 if (err)
388 goto out_disable;
389
390 err = request_threaded_irq(chip->irq, NULL,
391 mv88e6xxx_g1_irq_thread_fn,
392 IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
393 dev_name(chip->dev), chip);
394 if (err)
395 goto out_disable;
396
397 return 0;
398
399 out_disable:
400 mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
401 mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
402
403 out_mapping:
404 for (irq = 0; irq < 16; irq++) {
405 virq = irq_find_mapping(chip->g1_irq.domain, irq);
406 irq_dispose_mapping(virq);
407 }
408
409 irq_domain_remove(chip->g1_irq.domain);
410
411 return err;
412 }
413
414 int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask)
415 {
416 int i;
417
418 for (i = 0; i < 16; i++) {
419 u16 val;
420 int err;
421
422 err = mv88e6xxx_read(chip, addr, reg, &val);
423 if (err)
424 return err;
425
426 if (!(val & mask))
427 return 0;
428
429 usleep_range(1000, 2000);
430 }
431
432 dev_err(chip->dev, "Timeout while waiting for switch\n");
433 return -ETIMEDOUT;
434 }
435
436 /* Indirect write to single pointer-data register with an Update bit */
437 int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg, u16 update)
438 {
439 u16 val;
440 int err;
441
442 /* Wait until the previous operation is completed */
443 err = mv88e6xxx_wait(chip, addr, reg, BIT(15));
444 if (err)
445 return err;
446
447 /* Set the Update bit to trigger a write operation */
448 val = BIT(15) | update;
449
450 return mv88e6xxx_write(chip, addr, reg, val);
451 }
452
453 static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port,
454 int link, int speed, int duplex,
455 phy_interface_t mode)
456 {
457 int err;
458
459 if (!chip->info->ops->port_set_link)
460 return 0;
461
462 /* Port's MAC control must not be changed unless the link is down */
463 err = chip->info->ops->port_set_link(chip, port, 0);
464 if (err)
465 return err;
466
467 if (chip->info->ops->port_set_speed) {
468 err = chip->info->ops->port_set_speed(chip, port, speed);
469 if (err && err != -EOPNOTSUPP)
470 goto restore_link;
471 }
472
473 if (chip->info->ops->port_set_duplex) {
474 err = chip->info->ops->port_set_duplex(chip, port, duplex);
475 if (err && err != -EOPNOTSUPP)
476 goto restore_link;
477 }
478
479 if (chip->info->ops->port_set_rgmii_delay) {
480 err = chip->info->ops->port_set_rgmii_delay(chip, port, mode);
481 if (err && err != -EOPNOTSUPP)
482 goto restore_link;
483 }
484
485 if (chip->info->ops->port_set_cmode) {
486 err = chip->info->ops->port_set_cmode(chip, port, mode);
487 if (err && err != -EOPNOTSUPP)
488 goto restore_link;
489 }
490
491 err = 0;
492 restore_link:
493 if (chip->info->ops->port_set_link(chip, port, link))
494 dev_err(chip->dev, "p%d: failed to restore MAC's link\n", port);
495
496 return err;
497 }
498
499 /* We expect the switch to perform auto negotiation if there is a real
500 * phy. However, in the case of a fixed link phy, we force the port
501 * settings from the fixed link settings.
502 */
503 static void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
504 struct phy_device *phydev)
505 {
506 struct mv88e6xxx_chip *chip = ds->priv;
507 int err;
508
509 if (!phy_is_pseudo_fixed_link(phydev))
510 return;
511
512 mutex_lock(&chip->reg_lock);
513 err = mv88e6xxx_port_setup_mac(chip, port, phydev->link, phydev->speed,
514 phydev->duplex, phydev->interface);
515 mutex_unlock(&chip->reg_lock);
516
517 if (err && err != -EOPNOTSUPP)
518 dev_err(ds->dev, "p%d: failed to configure MAC\n", port);
519 }
520
521 static int mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
522 {
523 if (!chip->info->ops->stats_snapshot)
524 return -EOPNOTSUPP;
525
526 return chip->info->ops->stats_snapshot(chip, port);
527 }
528
529 static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
530 { "in_good_octets", 8, 0x00, STATS_TYPE_BANK0, },
531 { "in_bad_octets", 4, 0x02, STATS_TYPE_BANK0, },
532 { "in_unicast", 4, 0x04, STATS_TYPE_BANK0, },
533 { "in_broadcasts", 4, 0x06, STATS_TYPE_BANK0, },
534 { "in_multicasts", 4, 0x07, STATS_TYPE_BANK0, },
535 { "in_pause", 4, 0x16, STATS_TYPE_BANK0, },
536 { "in_undersize", 4, 0x18, STATS_TYPE_BANK0, },
537 { "in_fragments", 4, 0x19, STATS_TYPE_BANK0, },
538 { "in_oversize", 4, 0x1a, STATS_TYPE_BANK0, },
539 { "in_jabber", 4, 0x1b, STATS_TYPE_BANK0, },
540 { "in_rx_error", 4, 0x1c, STATS_TYPE_BANK0, },
541 { "in_fcs_error", 4, 0x1d, STATS_TYPE_BANK0, },
542 { "out_octets", 8, 0x0e, STATS_TYPE_BANK0, },
543 { "out_unicast", 4, 0x10, STATS_TYPE_BANK0, },
544 { "out_broadcasts", 4, 0x13, STATS_TYPE_BANK0, },
545 { "out_multicasts", 4, 0x12, STATS_TYPE_BANK0, },
546 { "out_pause", 4, 0x15, STATS_TYPE_BANK0, },
547 { "excessive", 4, 0x11, STATS_TYPE_BANK0, },
548 { "collisions", 4, 0x1e, STATS_TYPE_BANK0, },
549 { "deferred", 4, 0x05, STATS_TYPE_BANK0, },
550 { "single", 4, 0x14, STATS_TYPE_BANK0, },
551 { "multiple", 4, 0x17, STATS_TYPE_BANK0, },
552 { "out_fcs_error", 4, 0x03, STATS_TYPE_BANK0, },
553 { "late", 4, 0x1f, STATS_TYPE_BANK0, },
554 { "hist_64bytes", 4, 0x08, STATS_TYPE_BANK0, },
555 { "hist_65_127bytes", 4, 0x09, STATS_TYPE_BANK0, },
556 { "hist_128_255bytes", 4, 0x0a, STATS_TYPE_BANK0, },
557 { "hist_256_511bytes", 4, 0x0b, STATS_TYPE_BANK0, },
558 { "hist_512_1023bytes", 4, 0x0c, STATS_TYPE_BANK0, },
559 { "hist_1024_max_bytes", 4, 0x0d, STATS_TYPE_BANK0, },
560 { "sw_in_discards", 4, 0x10, STATS_TYPE_PORT, },
561 { "sw_in_filtered", 2, 0x12, STATS_TYPE_PORT, },
562 { "sw_out_filtered", 2, 0x13, STATS_TYPE_PORT, },
563 { "in_discards", 4, 0x00, STATS_TYPE_BANK1, },
564 { "in_filtered", 4, 0x01, STATS_TYPE_BANK1, },
565 { "in_accepted", 4, 0x02, STATS_TYPE_BANK1, },
566 { "in_bad_accepted", 4, 0x03, STATS_TYPE_BANK1, },
567 { "in_good_avb_class_a", 4, 0x04, STATS_TYPE_BANK1, },
568 { "in_good_avb_class_b", 4, 0x05, STATS_TYPE_BANK1, },
569 { "in_bad_avb_class_a", 4, 0x06, STATS_TYPE_BANK1, },
570 { "in_bad_avb_class_b", 4, 0x07, STATS_TYPE_BANK1, },
571 { "tcam_counter_0", 4, 0x08, STATS_TYPE_BANK1, },
572 { "tcam_counter_1", 4, 0x09, STATS_TYPE_BANK1, },
573 { "tcam_counter_2", 4, 0x0a, STATS_TYPE_BANK1, },
574 { "tcam_counter_3", 4, 0x0b, STATS_TYPE_BANK1, },
575 { "in_da_unknown", 4, 0x0e, STATS_TYPE_BANK1, },
576 { "in_management", 4, 0x0f, STATS_TYPE_BANK1, },
577 { "out_queue_0", 4, 0x10, STATS_TYPE_BANK1, },
578 { "out_queue_1", 4, 0x11, STATS_TYPE_BANK1, },
579 { "out_queue_2", 4, 0x12, STATS_TYPE_BANK1, },
580 { "out_queue_3", 4, 0x13, STATS_TYPE_BANK1, },
581 { "out_queue_4", 4, 0x14, STATS_TYPE_BANK1, },
582 { "out_queue_5", 4, 0x15, STATS_TYPE_BANK1, },
583 { "out_queue_6", 4, 0x16, STATS_TYPE_BANK1, },
584 { "out_queue_7", 4, 0x17, STATS_TYPE_BANK1, },
585 { "out_cut_through", 4, 0x18, STATS_TYPE_BANK1, },
586 { "out_octets_a", 4, 0x1a, STATS_TYPE_BANK1, },
587 { "out_octets_b", 4, 0x1b, STATS_TYPE_BANK1, },
588 { "out_management", 4, 0x1f, STATS_TYPE_BANK1, },
589 };
590
591 static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
592 struct mv88e6xxx_hw_stat *s,
593 int port, u16 bank1_select,
594 u16 histogram)
595 {
596 u32 low;
597 u32 high = 0;
598 u16 reg = 0;
599 int err;
600 u64 value;
601
602 switch (s->type) {
603 case STATS_TYPE_PORT:
604 err = mv88e6xxx_port_read(chip, port, s->reg, &reg);
605 if (err)
606 return UINT64_MAX;
607
608 low = reg;
609 if (s->sizeof_stat == 4) {
610 err = mv88e6xxx_port_read(chip, port, s->reg + 1, &reg);
611 if (err)
612 return UINT64_MAX;
613 high = reg;
614 }
615 break;
616 case STATS_TYPE_BANK1:
617 reg = bank1_select;
618 /* fall through */
619 case STATS_TYPE_BANK0:
620 reg |= s->reg | histogram;
621 mv88e6xxx_g1_stats_read(chip, reg, &low);
622 if (s->sizeof_stat == 8)
623 mv88e6xxx_g1_stats_read(chip, reg + 1, &high);
624 break;
625 default:
626 return UINT64_MAX;
627 }
628 value = (((u64)high) << 16) | low;
629 return value;
630 }
631
632 static void mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip,
633 uint8_t *data, int types)
634 {
635 struct mv88e6xxx_hw_stat *stat;
636 int i, j;
637
638 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
639 stat = &mv88e6xxx_hw_stats[i];
640 if (stat->type & types) {
641 memcpy(data + j * ETH_GSTRING_LEN, stat->string,
642 ETH_GSTRING_LEN);
643 j++;
644 }
645 }
646 }
647
648 static void mv88e6095_stats_get_strings(struct mv88e6xxx_chip *chip,
649 uint8_t *data)
650 {
651 mv88e6xxx_stats_get_strings(chip, data,
652 STATS_TYPE_BANK0 | STATS_TYPE_PORT);
653 }
654
655 static void mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip,
656 uint8_t *data)
657 {
658 mv88e6xxx_stats_get_strings(chip, data,
659 STATS_TYPE_BANK0 | STATS_TYPE_BANK1);
660 }
661
662 static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
663 uint8_t *data)
664 {
665 struct mv88e6xxx_chip *chip = ds->priv;
666
667 if (chip->info->ops->stats_get_strings)
668 chip->info->ops->stats_get_strings(chip, data);
669 }
670
671 static int mv88e6xxx_stats_get_sset_count(struct mv88e6xxx_chip *chip,
672 int types)
673 {
674 struct mv88e6xxx_hw_stat *stat;
675 int i, j;
676
677 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
678 stat = &mv88e6xxx_hw_stats[i];
679 if (stat->type & types)
680 j++;
681 }
682 return j;
683 }
684
685 static int mv88e6095_stats_get_sset_count(struct mv88e6xxx_chip *chip)
686 {
687 return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 |
688 STATS_TYPE_PORT);
689 }
690
691 static int mv88e6320_stats_get_sset_count(struct mv88e6xxx_chip *chip)
692 {
693 return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 |
694 STATS_TYPE_BANK1);
695 }
696
697 static int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
698 {
699 struct mv88e6xxx_chip *chip = ds->priv;
700
701 if (chip->info->ops->stats_get_sset_count)
702 return chip->info->ops->stats_get_sset_count(chip);
703
704 return 0;
705 }
706
707 static void mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
708 uint64_t *data, int types,
709 u16 bank1_select, u16 histogram)
710 {
711 struct mv88e6xxx_hw_stat *stat;
712 int i, j;
713
714 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
715 stat = &mv88e6xxx_hw_stats[i];
716 if (stat->type & types) {
717 data[j] = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
718 bank1_select,
719 histogram);
720 j++;
721 }
722 }
723 }
724
725 static void mv88e6095_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
726 uint64_t *data)
727 {
728 return mv88e6xxx_stats_get_stats(chip, port, data,
729 STATS_TYPE_BANK0 | STATS_TYPE_PORT,
730 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
731 }
732
733 static void mv88e6320_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
734 uint64_t *data)
735 {
736 return mv88e6xxx_stats_get_stats(chip, port, data,
737 STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
738 MV88E6XXX_G1_STATS_OP_BANK_1_BIT_9,
739 MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
740 }
741
742 static void mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
743 uint64_t *data)
744 {
745 return mv88e6xxx_stats_get_stats(chip, port, data,
746 STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
747 MV88E6XXX_G1_STATS_OP_BANK_1_BIT_10,
748 0);
749 }
750
751 static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
752 uint64_t *data)
753 {
754 if (chip->info->ops->stats_get_stats)
755 chip->info->ops->stats_get_stats(chip, port, data);
756 }
757
758 static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
759 uint64_t *data)
760 {
761 struct mv88e6xxx_chip *chip = ds->priv;
762 int ret;
763
764 mutex_lock(&chip->reg_lock);
765
766 ret = mv88e6xxx_stats_snapshot(chip, port);
767 if (ret < 0) {
768 mutex_unlock(&chip->reg_lock);
769 return;
770 }
771
772 mv88e6xxx_get_stats(chip, port, data);
773
774 mutex_unlock(&chip->reg_lock);
775 }
776
777 static int mv88e6xxx_stats_set_histogram(struct mv88e6xxx_chip *chip)
778 {
779 if (chip->info->ops->stats_set_histogram)
780 return chip->info->ops->stats_set_histogram(chip);
781
782 return 0;
783 }
784
785 static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
786 {
787 return 32 * sizeof(u16);
788 }
789
790 static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
791 struct ethtool_regs *regs, void *_p)
792 {
793 struct mv88e6xxx_chip *chip = ds->priv;
794 int err;
795 u16 reg;
796 u16 *p = _p;
797 int i;
798
799 regs->version = 0;
800
801 memset(p, 0xff, 32 * sizeof(u16));
802
803 mutex_lock(&chip->reg_lock);
804
805 for (i = 0; i < 32; i++) {
806
807 err = mv88e6xxx_port_read(chip, port, i, &reg);
808 if (!err)
809 p[i] = reg;
810 }
811
812 mutex_unlock(&chip->reg_lock);
813 }
814
815 static int mv88e6xxx_get_mac_eee(struct dsa_switch *ds, int port,
816 struct ethtool_eee *e)
817 {
818 /* Nothing to do on the port's MAC */
819 return 0;
820 }
821
822 static int mv88e6xxx_set_mac_eee(struct dsa_switch *ds, int port,
823 struct ethtool_eee *e)
824 {
825 /* Nothing to do on the port's MAC */
826 return 0;
827 }
828
829 static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port)
830 {
831 struct dsa_switch *ds = NULL;
832 struct net_device *br;
833 u16 pvlan;
834 int i;
835
836 if (dev < DSA_MAX_SWITCHES)
837 ds = chip->ds->dst->ds[dev];
838
839 /* Prevent frames from unknown switch or port */
840 if (!ds || port >= ds->num_ports)
841 return 0;
842
843 /* Frames from DSA links and CPU ports can egress any local port */
844 if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))
845 return mv88e6xxx_port_mask(chip);
846
847 br = ds->ports[port].bridge_dev;
848 pvlan = 0;
849
850 /* Frames from user ports can egress any local DSA links and CPU ports,
851 * as well as any local member of their bridge group.
852 */
853 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
854 if (dsa_is_cpu_port(chip->ds, i) ||
855 dsa_is_dsa_port(chip->ds, i) ||
856 (br && dsa_to_port(chip->ds, i)->bridge_dev == br))
857 pvlan |= BIT(i);
858
859 return pvlan;
860 }
861
862 static int mv88e6xxx_port_vlan_map(struct mv88e6xxx_chip *chip, int port)
863 {
864 u16 output_ports = mv88e6xxx_port_vlan(chip, chip->ds->index, port);
865
866 /* prevent frames from going back out of the port they came in on */
867 output_ports &= ~BIT(port);
868
869 return mv88e6xxx_port_set_vlan_map(chip, port, output_ports);
870 }
871
872 static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
873 u8 state)
874 {
875 struct mv88e6xxx_chip *chip = ds->priv;
876 int err;
877
878 mutex_lock(&chip->reg_lock);
879 err = mv88e6xxx_port_set_state(chip, port, state);
880 mutex_unlock(&chip->reg_lock);
881
882 if (err)
883 dev_err(ds->dev, "p%d: failed to update state\n", port);
884 }
885
886 static int mv88e6xxx_pot_setup(struct mv88e6xxx_chip *chip)
887 {
888 if (chip->info->ops->pot_clear)
889 return chip->info->ops->pot_clear(chip);
890
891 return 0;
892 }
893
894 static int mv88e6xxx_rsvd2cpu_setup(struct mv88e6xxx_chip *chip)
895 {
896 if (chip->info->ops->mgmt_rsvd2cpu)
897 return chip->info->ops->mgmt_rsvd2cpu(chip);
898
899 return 0;
900 }
901
902 static int mv88e6xxx_atu_setup(struct mv88e6xxx_chip *chip)
903 {
904 int err;
905
906 err = mv88e6xxx_g1_atu_flush(chip, 0, true);
907 if (err)
908 return err;
909
910 err = mv88e6xxx_g1_atu_set_learn2all(chip, true);
911 if (err)
912 return err;
913
914 return mv88e6xxx_g1_atu_set_age_time(chip, 300000);
915 }
916
917 static int mv88e6xxx_irl_setup(struct mv88e6xxx_chip *chip)
918 {
919 int port;
920 int err;
921
922 if (!chip->info->ops->irl_init_all)
923 return 0;
924
925 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
926 /* Disable ingress rate limiting by resetting all per port
927 * ingress rate limit resources to their initial state.
928 */
929 err = chip->info->ops->irl_init_all(chip, port);
930 if (err)
931 return err;
932 }
933
934 return 0;
935 }
936
937 static int mv88e6xxx_mac_setup(struct mv88e6xxx_chip *chip)
938 {
939 if (chip->info->ops->set_switch_mac) {
940 u8 addr[ETH_ALEN];
941
942 eth_random_addr(addr);
943
944 return chip->info->ops->set_switch_mac(chip, addr);
945 }
946
947 return 0;
948 }
949
950 static int mv88e6xxx_pvt_map(struct mv88e6xxx_chip *chip, int dev, int port)
951 {
952 u16 pvlan = 0;
953
954 if (!mv88e6xxx_has_pvt(chip))
955 return -EOPNOTSUPP;
956
957 /* Skip the local source device, which uses in-chip port VLAN */
958 if (dev != chip->ds->index)
959 pvlan = mv88e6xxx_port_vlan(chip, dev, port);
960
961 return mv88e6xxx_g2_pvt_write(chip, dev, port, pvlan);
962 }
963
964 static int mv88e6xxx_pvt_setup(struct mv88e6xxx_chip *chip)
965 {
966 int dev, port;
967 int err;
968
969 if (!mv88e6xxx_has_pvt(chip))
970 return 0;
971
972 /* Clear 5 Bit Port for usage with Marvell Link Street devices:
973 * use 4 bits for the Src_Port/Src_Trunk and 5 bits for the Src_Dev.
974 */
975 err = mv88e6xxx_g2_misc_4_bit_port(chip);
976 if (err)
977 return err;
978
979 for (dev = 0; dev < MV88E6XXX_MAX_PVT_SWITCHES; ++dev) {
980 for (port = 0; port < MV88E6XXX_MAX_PVT_PORTS; ++port) {
981 err = mv88e6xxx_pvt_map(chip, dev, port);
982 if (err)
983 return err;
984 }
985 }
986
987 return 0;
988 }
989
990 static void mv88e6xxx_port_fast_age(struct dsa_switch *ds, int port)
991 {
992 struct mv88e6xxx_chip *chip = ds->priv;
993 int err;
994
995 mutex_lock(&chip->reg_lock);
996 err = mv88e6xxx_g1_atu_remove(chip, 0, port, false);
997 mutex_unlock(&chip->reg_lock);
998
999 if (err)
1000 dev_err(ds->dev, "p%d: failed to flush ATU\n", port);
1001 }
1002
1003 static int mv88e6xxx_vtu_setup(struct mv88e6xxx_chip *chip)
1004 {
1005 if (!chip->info->max_vid)
1006 return 0;
1007
1008 return mv88e6xxx_g1_vtu_flush(chip);
1009 }
1010
1011 static int mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip,
1012 struct mv88e6xxx_vtu_entry *entry)
1013 {
1014 if (!chip->info->ops->vtu_getnext)
1015 return -EOPNOTSUPP;
1016
1017 return chip->info->ops->vtu_getnext(chip, entry);
1018 }
1019
1020 static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
1021 struct mv88e6xxx_vtu_entry *entry)
1022 {
1023 if (!chip->info->ops->vtu_loadpurge)
1024 return -EOPNOTSUPP;
1025
1026 return chip->info->ops->vtu_loadpurge(chip, entry);
1027 }
1028
1029 static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
1030 {
1031 DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID);
1032 struct mv88e6xxx_vtu_entry vlan = {
1033 .vid = chip->info->max_vid,
1034 };
1035 int i, err;
1036
1037 bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);
1038
1039 /* Set every FID bit used by the (un)bridged ports */
1040 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1041 err = mv88e6xxx_port_get_fid(chip, i, fid);
1042 if (err)
1043 return err;
1044
1045 set_bit(*fid, fid_bitmap);
1046 }
1047
1048 /* Set every FID bit used by the VLAN entries */
1049 do {
1050 err = mv88e6xxx_vtu_getnext(chip, &vlan);
1051 if (err)
1052 return err;
1053
1054 if (!vlan.valid)
1055 break;
1056
1057 set_bit(vlan.fid, fid_bitmap);
1058 } while (vlan.vid < chip->info->max_vid);
1059
1060 /* The reset value 0x000 is used to indicate that multiple address
1061 * databases are not needed. Return the next positive available.
1062 */
1063 *fid = find_next_zero_bit(fid_bitmap, MV88E6XXX_N_FID, 1);
1064 if (unlikely(*fid >= mv88e6xxx_num_databases(chip)))
1065 return -ENOSPC;
1066
1067 /* Clear the database */
1068 return mv88e6xxx_g1_atu_flush(chip, *fid, true);
1069 }
1070
1071 static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
1072 struct mv88e6xxx_vtu_entry *entry, bool new)
1073 {
1074 int err;
1075
1076 if (!vid)
1077 return -EINVAL;
1078
1079 entry->vid = vid - 1;
1080 entry->valid = false;
1081
1082 err = mv88e6xxx_vtu_getnext(chip, entry);
1083 if (err)
1084 return err;
1085
1086 if (entry->vid == vid && entry->valid)
1087 return 0;
1088
1089 if (new) {
1090 int i;
1091
1092 /* Initialize a fresh VLAN entry */
1093 memset(entry, 0, sizeof(*entry));
1094 entry->valid = true;
1095 entry->vid = vid;
1096
1097 /* Exclude all ports */
1098 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
1099 entry->member[i] =
1100 MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
1101
1102 return mv88e6xxx_atu_new(chip, &entry->fid);
1103 }
1104
1105 /* switchdev expects -EOPNOTSUPP to honor software VLANs */
1106 return -EOPNOTSUPP;
1107 }
1108
1109 static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
1110 u16 vid_begin, u16 vid_end)
1111 {
1112 struct mv88e6xxx_chip *chip = ds->priv;
1113 struct mv88e6xxx_vtu_entry vlan = {
1114 .vid = vid_begin - 1,
1115 };
1116 int i, err;
1117
1118 /* DSA and CPU ports have to be members of multiple vlans */
1119 if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
1120 return 0;
1121
1122 if (!vid_begin)
1123 return -EOPNOTSUPP;
1124
1125 mutex_lock(&chip->reg_lock);
1126
1127 do {
1128 err = mv88e6xxx_vtu_getnext(chip, &vlan);
1129 if (err)
1130 goto unlock;
1131
1132 if (!vlan.valid)
1133 break;
1134
1135 if (vlan.vid > vid_end)
1136 break;
1137
1138 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1139 if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
1140 continue;
1141
1142 if (!ds->ports[i].slave)
1143 continue;
1144
1145 if (vlan.member[i] ==
1146 MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
1147 continue;
1148
1149 if (dsa_to_port(ds, i)->bridge_dev ==
1150 ds->ports[port].bridge_dev)
1151 break; /* same bridge, check next VLAN */
1152
1153 if (!dsa_to_port(ds, i)->bridge_dev)
1154 continue;
1155
1156 dev_err(ds->dev, "p%d: hw VLAN %d already used by port %d in %s\n",
1157 port, vlan.vid, i,
1158 netdev_name(dsa_to_port(ds, i)->bridge_dev));
1159 err = -EOPNOTSUPP;
1160 goto unlock;
1161 }
1162 } while (vlan.vid < vid_end);
1163
1164 unlock:
1165 mutex_unlock(&chip->reg_lock);
1166
1167 return err;
1168 }
1169
1170 static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
1171 bool vlan_filtering)
1172 {
1173 struct mv88e6xxx_chip *chip = ds->priv;
1174 u16 mode = vlan_filtering ? MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE :
1175 MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED;
1176 int err;
1177
1178 if (!chip->info->max_vid)
1179 return -EOPNOTSUPP;
1180
1181 mutex_lock(&chip->reg_lock);
1182 err = mv88e6xxx_port_set_8021q_mode(chip, port, mode);
1183 mutex_unlock(&chip->reg_lock);
1184
1185 return err;
1186 }
1187
1188 static int
1189 mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
1190 const struct switchdev_obj_port_vlan *vlan)
1191 {
1192 struct mv88e6xxx_chip *chip = ds->priv;
1193 int err;
1194
1195 if (!chip->info->max_vid)
1196 return -EOPNOTSUPP;
1197
1198 /* If the requested port doesn't belong to the same bridge as the VLAN
1199 * members, do not support it (yet) and fallback to software VLAN.
1200 */
1201 err = mv88e6xxx_port_check_hw_vlan(ds, port, vlan->vid_begin,
1202 vlan->vid_end);
1203 if (err)
1204 return err;
1205
1206 /* We don't need any dynamic resource from the kernel (yet),
1207 * so skip the prepare phase.
1208 */
1209 return 0;
1210 }
1211
1212 static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
1213 const unsigned char *addr, u16 vid,
1214 u8 state)
1215 {
1216 struct mv88e6xxx_vtu_entry vlan;
1217 struct mv88e6xxx_atu_entry entry;
1218 int err;
1219
1220 /* Null VLAN ID corresponds to the port private database */
1221 if (vid == 0)
1222 err = mv88e6xxx_port_get_fid(chip, port, &vlan.fid);
1223 else
1224 err = mv88e6xxx_vtu_get(chip, vid, &vlan, false);
1225 if (err)
1226 return err;
1227
1228 entry.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
1229 ether_addr_copy(entry.mac, addr);
1230 eth_addr_dec(entry.mac);
1231
1232 err = mv88e6xxx_g1_atu_getnext(chip, vlan.fid, &entry);
1233 if (err)
1234 return err;
1235
1236 /* Initialize a fresh ATU entry if it isn't found */
1237 if (entry.state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED ||
1238 !ether_addr_equal(entry.mac, addr)) {
1239 memset(&entry, 0, sizeof(entry));
1240 ether_addr_copy(entry.mac, addr);
1241 }
1242
1243 /* Purge the ATU entry only if no port is using it anymore */
1244 if (state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED) {
1245 entry.portvec &= ~BIT(port);
1246 if (!entry.portvec)
1247 entry.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
1248 } else {
1249 entry.portvec |= BIT(port);
1250 entry.state = state;
1251 }
1252
1253 return mv88e6xxx_g1_atu_loadpurge(chip, vlan.fid, &entry);
1254 }
1255
1256 static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port,
1257 u16 vid)
1258 {
1259 const char broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1260 u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC;
1261
1262 return mv88e6xxx_port_db_load_purge(chip, port, broadcast, vid, state);
1263 }
1264
1265 static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid)
1266 {
1267 int port;
1268 int err;
1269
1270 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
1271 err = mv88e6xxx_port_add_broadcast(chip, port, vid);
1272 if (err)
1273 return err;
1274 }
1275
1276 return 0;
1277 }
1278
1279 static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
1280 u16 vid, u8 member)
1281 {
1282 struct mv88e6xxx_vtu_entry vlan;
1283 int err;
1284
1285 err = mv88e6xxx_vtu_get(chip, vid, &vlan, true);
1286 if (err)
1287 return err;
1288
1289 vlan.member[port] = member;
1290
1291 err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
1292 if (err)
1293 return err;
1294
1295 return mv88e6xxx_broadcast_setup(chip, vid);
1296 }
1297
1298 static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
1299 const struct switchdev_obj_port_vlan *vlan)
1300 {
1301 struct mv88e6xxx_chip *chip = ds->priv;
1302 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
1303 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
1304 u8 member;
1305 u16 vid;
1306
1307 if (!chip->info->max_vid)
1308 return;
1309
1310 if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
1311 member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED;
1312 else if (untagged)
1313 member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNTAGGED;
1314 else
1315 member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_TAGGED;
1316
1317 mutex_lock(&chip->reg_lock);
1318
1319 for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid)
1320 if (_mv88e6xxx_port_vlan_add(chip, port, vid, member))
1321 dev_err(ds->dev, "p%d: failed to add VLAN %d%c\n", port,
1322 vid, untagged ? 'u' : 't');
1323
1324 if (pvid && mv88e6xxx_port_set_pvid(chip, port, vlan->vid_end))
1325 dev_err(ds->dev, "p%d: failed to set PVID %d\n", port,
1326 vlan->vid_end);
1327
1328 mutex_unlock(&chip->reg_lock);
1329 }
1330
1331 static int _mv88e6xxx_port_vlan_del(struct mv88e6xxx_chip *chip,
1332 int port, u16 vid)
1333 {
1334 struct mv88e6xxx_vtu_entry vlan;
1335 int i, err;
1336
1337 err = mv88e6xxx_vtu_get(chip, vid, &vlan, false);
1338 if (err)
1339 return err;
1340
1341 /* Tell switchdev if this VLAN is handled in software */
1342 if (vlan.member[port] == MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
1343 return -EOPNOTSUPP;
1344
1345 vlan.member[port] = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
1346
1347 /* keep the VLAN unless all ports are excluded */
1348 vlan.valid = false;
1349 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1350 if (vlan.member[i] !=
1351 MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
1352 vlan.valid = true;
1353 break;
1354 }
1355 }
1356
1357 err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
1358 if (err)
1359 return err;
1360
1361 return mv88e6xxx_g1_atu_remove(chip, vlan.fid, port, false);
1362 }
1363
1364 static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
1365 const struct switchdev_obj_port_vlan *vlan)
1366 {
1367 struct mv88e6xxx_chip *chip = ds->priv;
1368 u16 pvid, vid;
1369 int err = 0;
1370
1371 if (!chip->info->max_vid)
1372 return -EOPNOTSUPP;
1373
1374 mutex_lock(&chip->reg_lock);
1375
1376 err = mv88e6xxx_port_get_pvid(chip, port, &pvid);
1377 if (err)
1378 goto unlock;
1379
1380 for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
1381 err = _mv88e6xxx_port_vlan_del(chip, port, vid);
1382 if (err)
1383 goto unlock;
1384
1385 if (vid == pvid) {
1386 err = mv88e6xxx_port_set_pvid(chip, port, 0);
1387 if (err)
1388 goto unlock;
1389 }
1390 }
1391
1392 unlock:
1393 mutex_unlock(&chip->reg_lock);
1394
1395 return err;
1396 }
1397
1398 static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
1399 const unsigned char *addr, u16 vid)
1400 {
1401 struct mv88e6xxx_chip *chip = ds->priv;
1402 int err;
1403
1404 mutex_lock(&chip->reg_lock);
1405 err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
1406 MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
1407 mutex_unlock(&chip->reg_lock);
1408
1409 return err;
1410 }
1411
1412 static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
1413 const unsigned char *addr, u16 vid)
1414 {
1415 struct mv88e6xxx_chip *chip = ds->priv;
1416 int err;
1417
1418 mutex_lock(&chip->reg_lock);
1419 err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
1420 MV88E6XXX_G1_ATU_DATA_STATE_UNUSED);
1421 mutex_unlock(&chip->reg_lock);
1422
1423 return err;
1424 }
1425
1426 static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
1427 u16 fid, u16 vid, int port,
1428 dsa_fdb_dump_cb_t *cb, void *data)
1429 {
1430 struct mv88e6xxx_atu_entry addr;
1431 bool is_static;
1432 int err;
1433
1434 addr.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
1435 eth_broadcast_addr(addr.mac);
1436
1437 do {
1438 err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr);
1439 if (err)
1440 return err;
1441
1442 if (addr.state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED)
1443 break;
1444
1445 if (addr.trunk || (addr.portvec & BIT(port)) == 0)
1446 continue;
1447
1448 if (!is_unicast_ether_addr(addr.mac))
1449 continue;
1450
1451 is_static = (addr.state ==
1452 MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
1453 err = cb(addr.mac, vid, is_static, data);
1454 if (err)
1455 return err;
1456 } while (!is_broadcast_ether_addr(addr.mac));
1457
1458 return err;
1459 }
1460
1461 static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
1462 dsa_fdb_dump_cb_t *cb, void *data)
1463 {
1464 struct mv88e6xxx_vtu_entry vlan = {
1465 .vid = chip->info->max_vid,
1466 };
1467 u16 fid;
1468 int err;
1469
1470 /* Dump port's default Filtering Information Database (VLAN ID 0) */
1471 err = mv88e6xxx_port_get_fid(chip, port, &fid);
1472 if (err)
1473 return err;
1474
1475 err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, cb, data);
1476 if (err)
1477 return err;
1478
1479 /* Dump VLANs' Filtering Information Databases */
1480 do {
1481 err = mv88e6xxx_vtu_getnext(chip, &vlan);
1482 if (err)
1483 return err;
1484
1485 if (!vlan.valid)
1486 break;
1487
1488 err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,
1489 cb, data);
1490 if (err)
1491 return err;
1492 } while (vlan.vid < chip->info->max_vid);
1493
1494 return err;
1495 }
1496
1497 static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
1498 dsa_fdb_dump_cb_t *cb, void *data)
1499 {
1500 struct mv88e6xxx_chip *chip = ds->priv;
1501 int err;
1502
1503 mutex_lock(&chip->reg_lock);
1504 err = mv88e6xxx_port_db_dump(chip, port, cb, data);
1505 mutex_unlock(&chip->reg_lock);
1506
1507 return err;
1508 }
1509
1510 static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip,
1511 struct net_device *br)
1512 {
1513 struct dsa_switch *ds;
1514 int port;
1515 int dev;
1516 int err;
1517
1518 /* Remap the Port VLAN of each local bridge group member */
1519 for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) {
1520 if (chip->ds->ports[port].bridge_dev == br) {
1521 err = mv88e6xxx_port_vlan_map(chip, port);
1522 if (err)
1523 return err;
1524 }
1525 }
1526
1527 if (!mv88e6xxx_has_pvt(chip))
1528 return 0;
1529
1530 /* Remap the Port VLAN of each cross-chip bridge group member */
1531 for (dev = 0; dev < DSA_MAX_SWITCHES; ++dev) {
1532 ds = chip->ds->dst->ds[dev];
1533 if (!ds)
1534 break;
1535
1536 for (port = 0; port < ds->num_ports; ++port) {
1537 if (ds->ports[port].bridge_dev == br) {
1538 err = mv88e6xxx_pvt_map(chip, dev, port);
1539 if (err)
1540 return err;
1541 }
1542 }
1543 }
1544
1545 return 0;
1546 }
1547
1548 static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
1549 struct net_device *br)
1550 {
1551 struct mv88e6xxx_chip *chip = ds->priv;
1552 int err;
1553
1554 mutex_lock(&chip->reg_lock);
1555 err = mv88e6xxx_bridge_map(chip, br);
1556 mutex_unlock(&chip->reg_lock);
1557
1558 return err;
1559 }
1560
1561 static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port,
1562 struct net_device *br)
1563 {
1564 struct mv88e6xxx_chip *chip = ds->priv;
1565
1566 mutex_lock(&chip->reg_lock);
1567 if (mv88e6xxx_bridge_map(chip, br) ||
1568 mv88e6xxx_port_vlan_map(chip, port))
1569 dev_err(ds->dev, "failed to remap in-chip Port VLAN\n");
1570 mutex_unlock(&chip->reg_lock);
1571 }
1572
1573 static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds, int dev,
1574 int port, struct net_device *br)
1575 {
1576 struct mv88e6xxx_chip *chip = ds->priv;
1577 int err;
1578
1579 if (!mv88e6xxx_has_pvt(chip))
1580 return 0;
1581
1582 mutex_lock(&chip->reg_lock);
1583 err = mv88e6xxx_pvt_map(chip, dev, port);
1584 mutex_unlock(&chip->reg_lock);
1585
1586 return err;
1587 }
1588
1589 static void mv88e6xxx_crosschip_bridge_leave(struct dsa_switch *ds, int dev,
1590 int port, struct net_device *br)
1591 {
1592 struct mv88e6xxx_chip *chip = ds->priv;
1593
1594 if (!mv88e6xxx_has_pvt(chip))
1595 return;
1596
1597 mutex_lock(&chip->reg_lock);
1598 if (mv88e6xxx_pvt_map(chip, dev, port))
1599 dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n");
1600 mutex_unlock(&chip->reg_lock);
1601 }
1602
1603 static int mv88e6xxx_software_reset(struct mv88e6xxx_chip *chip)
1604 {
1605 if (chip->info->ops->reset)
1606 return chip->info->ops->reset(chip);
1607
1608 return 0;
1609 }
1610
1611 static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
1612 {
1613 struct gpio_desc *gpiod = chip->reset;
1614
1615 /* If there is a GPIO connected to the reset pin, toggle it */
1616 if (gpiod) {
1617 gpiod_set_value_cansleep(gpiod, 1);
1618 usleep_range(10000, 20000);
1619 gpiod_set_value_cansleep(gpiod, 0);
1620 usleep_range(10000, 20000);
1621 }
1622 }
1623
1624 static int mv88e6xxx_disable_ports(struct mv88e6xxx_chip *chip)
1625 {
1626 int i, err;
1627
1628 /* Set all ports to the Disabled state */
1629 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
1630 err = mv88e6xxx_port_set_state(chip, i, BR_STATE_DISABLED);
1631 if (err)
1632 return err;
1633 }
1634
1635 /* Wait for transmit queues to drain,
1636 * i.e. 2ms for a maximum frame to be transmitted at 10 Mbps.
1637 */
1638 usleep_range(2000, 4000);
1639
1640 return 0;
1641 }
1642
1643 static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
1644 {
1645 int err;
1646
1647 err = mv88e6xxx_disable_ports(chip);
1648 if (err)
1649 return err;
1650
1651 mv88e6xxx_hardware_reset(chip);
1652
1653 return mv88e6xxx_software_reset(chip);
1654 }
1655
1656 static int mv88e6xxx_set_port_mode(struct mv88e6xxx_chip *chip, int port,
1657 enum mv88e6xxx_frame_mode frame,
1658 enum mv88e6xxx_egress_mode egress, u16 etype)
1659 {
1660 int err;
1661
1662 if (!chip->info->ops->port_set_frame_mode)
1663 return -EOPNOTSUPP;
1664
1665 err = mv88e6xxx_port_set_egress_mode(chip, port, egress);
1666 if (err)
1667 return err;
1668
1669 err = chip->info->ops->port_set_frame_mode(chip, port, frame);
1670 if (err)
1671 return err;
1672
1673 if (chip->info->ops->port_set_ether_type)
1674 return chip->info->ops->port_set_ether_type(chip, port, etype);
1675
1676 return 0;
1677 }
1678
1679 static int mv88e6xxx_set_port_mode_normal(struct mv88e6xxx_chip *chip, int port)
1680 {
1681 return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_NORMAL,
1682 MV88E6XXX_EGRESS_MODE_UNMODIFIED,
1683 MV88E6XXX_PORT_ETH_TYPE_DEFAULT);
1684 }
1685
1686 static int mv88e6xxx_set_port_mode_dsa(struct mv88e6xxx_chip *chip, int port)
1687 {
1688 return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_DSA,
1689 MV88E6XXX_EGRESS_MODE_UNMODIFIED,
1690 MV88E6XXX_PORT_ETH_TYPE_DEFAULT);
1691 }
1692
1693 static int mv88e6xxx_set_port_mode_edsa(struct mv88e6xxx_chip *chip, int port)
1694 {
1695 return mv88e6xxx_set_port_mode(chip, port,
1696 MV88E6XXX_FRAME_MODE_ETHERTYPE,
1697 MV88E6XXX_EGRESS_MODE_ETHERTYPE,
1698 ETH_P_EDSA);
1699 }
1700
1701 static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)
1702 {
1703 if (dsa_is_dsa_port(chip->ds, port))
1704 return mv88e6xxx_set_port_mode_dsa(chip, port);
1705
1706 if (dsa_is_user_port(chip->ds, port))
1707 return mv88e6xxx_set_port_mode_normal(chip, port);
1708
1709 /* Setup CPU port mode depending on its supported tag format */
1710 if (chip->info->tag_protocol == DSA_TAG_PROTO_DSA)
1711 return mv88e6xxx_set_port_mode_dsa(chip, port);
1712
1713 if (chip->info->tag_protocol == DSA_TAG_PROTO_EDSA)
1714 return mv88e6xxx_set_port_mode_edsa(chip, port);
1715
1716 return -EINVAL;
1717 }
1718
1719 static int mv88e6xxx_setup_message_port(struct mv88e6xxx_chip *chip, int port)
1720 {
1721 bool message = dsa_is_dsa_port(chip->ds, port);
1722
1723 return mv88e6xxx_port_set_message_port(chip, port, message);
1724 }
1725
1726 static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
1727 {
1728 struct dsa_switch *ds = chip->ds;
1729 bool flood;
1730
1731 /* Upstream ports flood frames with unknown unicast or multicast DA */
1732 flood = dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port);
1733 if (chip->info->ops->port_set_egress_floods)
1734 return chip->info->ops->port_set_egress_floods(chip, port,
1735 flood, flood);
1736
1737 return 0;
1738 }
1739
1740 static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
1741 bool on)
1742 {
1743 if (chip->info->ops->serdes_power)
1744 return chip->info->ops->serdes_power(chip, port, on);
1745
1746 return 0;
1747 }
1748
1749 static int mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip *chip, int port)
1750 {
1751 struct dsa_switch *ds = chip->ds;
1752 int upstream_port;
1753 int err;
1754
1755 upstream_port = dsa_upstream_port(ds, port);
1756 if (chip->info->ops->port_set_upstream_port) {
1757 err = chip->info->ops->port_set_upstream_port(chip, port,
1758 upstream_port);
1759 if (err)
1760 return err;
1761 }
1762
1763 if (port == upstream_port) {
1764 if (chip->info->ops->set_cpu_port) {
1765 err = chip->info->ops->set_cpu_port(chip,
1766 upstream_port);
1767 if (err)
1768 return err;
1769 }
1770
1771 if (chip->info->ops->set_egress_port) {
1772 err = chip->info->ops->set_egress_port(chip,
1773 upstream_port);
1774 if (err)
1775 return err;
1776 }
1777 }
1778
1779 return 0;
1780 }
1781
1782 static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
1783 {
1784 struct dsa_switch *ds = chip->ds;
1785 int err;
1786 u16 reg;
1787
1788 /* MAC Forcing register: don't force link, speed, duplex or flow control
1789 * state to any particular values on physical ports, but force the CPU
1790 * port and all DSA ports to their maximum bandwidth and full duplex.
1791 */
1792 if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))
1793 err = mv88e6xxx_port_setup_mac(chip, port, LINK_FORCED_UP,
1794 SPEED_MAX, DUPLEX_FULL,
1795 PHY_INTERFACE_MODE_NA);
1796 else
1797 err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED,
1798 SPEED_UNFORCED, DUPLEX_UNFORCED,
1799 PHY_INTERFACE_MODE_NA);
1800 if (err)
1801 return err;
1802
1803 /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
1804 * disable Header mode, enable IGMP/MLD snooping, disable VLAN
1805 * tunneling, determine priority by looking at 802.1p and IP
1806 * priority fields (IP prio has precedence), and set STP state
1807 * to Forwarding.
1808 *
1809 * If this is the CPU link, use DSA or EDSA tagging depending
1810 * on which tagging mode was configured.
1811 *
1812 * If this is a link to another switch, use DSA tagging mode.
1813 *
1814 * If this is the upstream port for this switch, enable
1815 * forwarding of unknown unicasts and multicasts.
1816 */
1817 reg = MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP |
1818 MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
1819 MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
1820 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
1821 if (err)
1822 return err;
1823
1824 err = mv88e6xxx_setup_port_mode(chip, port);
1825 if (err)
1826 return err;
1827
1828 err = mv88e6xxx_setup_egress_floods(chip, port);
1829 if (err)
1830 return err;
1831
1832 /* Enable the SERDES interface for DSA and CPU ports. Normal
1833 * ports SERDES are enabled when the port is enabled, thus
1834 * saving a bit of power.
1835 */
1836 if ((dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))) {
1837 err = mv88e6xxx_serdes_power(chip, port, true);
1838 if (err)
1839 return err;
1840 }
1841
1842 /* Port Control 2: don't force a good FCS, set the maximum frame size to
1843 * 10240 bytes, disable 802.1q tags checking, don't discard tagged or
1844 * untagged frames on this port, do a destination address lookup on all
1845 * received packets as usual, disable ARP mirroring and don't send a
1846 * copy of all transmitted/received frames on this port to the CPU.
1847 */
1848 err = mv88e6xxx_port_set_map_da(chip, port);
1849 if (err)
1850 return err;
1851
1852 err = mv88e6xxx_setup_upstream_port(chip, port);
1853 if (err)
1854 return err;
1855
1856 err = mv88e6xxx_port_set_8021q_mode(chip, port,
1857 MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED);
1858 if (err)
1859 return err;
1860
1861 if (chip->info->ops->port_set_jumbo_size) {
1862 err = chip->info->ops->port_set_jumbo_size(chip, port, 10240);
1863 if (err)
1864 return err;
1865 }
1866
1867 /* Port Association Vector: when learning source addresses
1868 * of packets, add the address to the address database using
1869 * a port bitmap that has only the bit for this port set and
1870 * the other bits clear.
1871 */
1872 reg = 1 << port;
1873 /* Disable learning for CPU port */
1874 if (dsa_is_cpu_port(ds, port))
1875 reg = 0;
1876
1877 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
1878 reg);
1879 if (err)
1880 return err;
1881
1882 /* Egress rate control 2: disable egress rate control. */
1883 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL2,
1884 0x0000);
1885 if (err)
1886 return err;
1887
1888 if (chip->info->ops->port_pause_limit) {
1889 err = chip->info->ops->port_pause_limit(chip, port, 0, 0);
1890 if (err)
1891 return err;
1892 }
1893
1894 if (chip->info->ops->port_disable_learn_limit) {
1895 err = chip->info->ops->port_disable_learn_limit(chip, port);
1896 if (err)
1897 return err;
1898 }
1899
1900 if (chip->info->ops->port_disable_pri_override) {
1901 err = chip->info->ops->port_disable_pri_override(chip, port);
1902 if (err)
1903 return err;
1904 }
1905
1906 if (chip->info->ops->port_tag_remap) {
1907 err = chip->info->ops->port_tag_remap(chip, port);
1908 if (err)
1909 return err;
1910 }
1911
1912 if (chip->info->ops->port_egress_rate_limiting) {
1913 err = chip->info->ops->port_egress_rate_limiting(chip, port);
1914 if (err)
1915 return err;
1916 }
1917
1918 err = mv88e6xxx_setup_message_port(chip, port);
1919 if (err)
1920 return err;
1921
1922 /* Port based VLAN map: give each port the same default address
1923 * database, and allow bidirectional communication between the
1924 * CPU and DSA port(s), and the other ports.
1925 */
1926 err = mv88e6xxx_port_set_fid(chip, port, 0);
1927 if (err)
1928 return err;
1929
1930 err = mv88e6xxx_port_vlan_map(chip, port);
1931 if (err)
1932 return err;
1933
1934 /* Default VLAN ID and priority: don't set a default VLAN
1935 * ID, and set the default packet priority to zero.
1936 */
1937 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 0);
1938 }
1939
1940 static int mv88e6xxx_port_enable(struct dsa_switch *ds, int port,
1941 struct phy_device *phydev)
1942 {
1943 struct mv88e6xxx_chip *chip = ds->priv;
1944 int err;
1945
1946 mutex_lock(&chip->reg_lock);
1947 err = mv88e6xxx_serdes_power(chip, port, true);
1948 mutex_unlock(&chip->reg_lock);
1949
1950 return err;
1951 }
1952
1953 static void mv88e6xxx_port_disable(struct dsa_switch *ds, int port,
1954 struct phy_device *phydev)
1955 {
1956 struct mv88e6xxx_chip *chip = ds->priv;
1957
1958 mutex_lock(&chip->reg_lock);
1959 if (mv88e6xxx_serdes_power(chip, port, false))
1960 dev_err(chip->dev, "failed to power off SERDES\n");
1961 mutex_unlock(&chip->reg_lock);
1962 }
1963
1964 static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds,
1965 unsigned int ageing_time)
1966 {
1967 struct mv88e6xxx_chip *chip = ds->priv;
1968 int err;
1969
1970 mutex_lock(&chip->reg_lock);
1971 err = mv88e6xxx_g1_atu_set_age_time(chip, ageing_time);
1972 mutex_unlock(&chip->reg_lock);
1973
1974 return err;
1975 }
1976
1977 static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip)
1978 {
1979 struct dsa_switch *ds = chip->ds;
1980 int err;
1981
1982 /* Disable remote management, and set the switch's DSA device number. */
1983 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL2,
1984 MV88E6XXX_G1_CTL2_MULTIPLE_CASCADE |
1985 (ds->index & 0x1f));
1986 if (err)
1987 return err;
1988
1989 /* Configure the IP ToS mapping registers. */
1990 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_0, 0x0000);
1991 if (err)
1992 return err;
1993 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_1, 0x0000);
1994 if (err)
1995 return err;
1996 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_2, 0x5555);
1997 if (err)
1998 return err;
1999 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_3, 0x5555);
2000 if (err)
2001 return err;
2002 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_4, 0xaaaa);
2003 if (err)
2004 return err;
2005 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_5, 0xaaaa);
2006 if (err)
2007 return err;
2008 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_6, 0xffff);
2009 if (err)
2010 return err;
2011 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_7, 0xffff);
2012 if (err)
2013 return err;
2014
2015 /* Configure the IEEE 802.1p priority mapping register. */
2016 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IEEE_PRI, 0xfa41);
2017 if (err)
2018 return err;
2019
2020 /* Initialize the statistics unit */
2021 err = mv88e6xxx_stats_set_histogram(chip);
2022 if (err)
2023 return err;
2024
2025 return mv88e6xxx_g1_stats_clear(chip);
2026 }
2027
2028 static int mv88e6xxx_setup(struct dsa_switch *ds)
2029 {
2030 struct mv88e6xxx_chip *chip = ds->priv;
2031 int err;
2032 int i;
2033
2034 chip->ds = ds;
2035 ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip);
2036
2037 mutex_lock(&chip->reg_lock);
2038
2039 /* Setup Switch Port Registers */
2040 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
2041 if (dsa_is_unused_port(ds, i))
2042 continue;
2043
2044 err = mv88e6xxx_setup_port(chip, i);
2045 if (err)
2046 goto unlock;
2047 }
2048
2049 /* Setup Switch Global 1 Registers */
2050 err = mv88e6xxx_g1_setup(chip);
2051 if (err)
2052 goto unlock;
2053
2054 /* Setup Switch Global 2 Registers */
2055 if (chip->info->global2_addr) {
2056 err = mv88e6xxx_g2_setup(chip);
2057 if (err)
2058 goto unlock;
2059 }
2060
2061 err = mv88e6xxx_irl_setup(chip);
2062 if (err)
2063 goto unlock;
2064
2065 err = mv88e6xxx_mac_setup(chip);
2066 if (err)
2067 goto unlock;
2068
2069 err = mv88e6xxx_phy_setup(chip);
2070 if (err)
2071 goto unlock;
2072
2073 err = mv88e6xxx_vtu_setup(chip);
2074 if (err)
2075 goto unlock;
2076
2077 err = mv88e6xxx_pvt_setup(chip);
2078 if (err)
2079 goto unlock;
2080
2081 err = mv88e6xxx_atu_setup(chip);
2082 if (err)
2083 goto unlock;
2084
2085 err = mv88e6xxx_broadcast_setup(chip, 0);
2086 if (err)
2087 goto unlock;
2088
2089 err = mv88e6xxx_pot_setup(chip);
2090 if (err)
2091 goto unlock;
2092
2093 err = mv88e6xxx_rsvd2cpu_setup(chip);
2094 if (err)
2095 goto unlock;
2096
2097 /* Setup PTP Hardware Clock and timestamping */
2098 if (chip->info->ptp_support) {
2099 err = mv88e6xxx_ptp_setup(chip);
2100 if (err)
2101 goto unlock;
2102
2103 err = mv88e6xxx_hwtstamp_setup(chip);
2104 if (err)
2105 goto unlock;
2106 }
2107
2108 unlock:
2109 mutex_unlock(&chip->reg_lock);
2110
2111 return err;
2112 }
2113
2114 static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
2115 {
2116 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
2117 struct mv88e6xxx_chip *chip = mdio_bus->chip;
2118 u16 val;
2119 int err;
2120
2121 if (!chip->info->ops->phy_read)
2122 return -EOPNOTSUPP;
2123
2124 mutex_lock(&chip->reg_lock);
2125 err = chip->info->ops->phy_read(chip, bus, phy, reg, &val);
2126 mutex_unlock(&chip->reg_lock);
2127
2128 if (reg == MII_PHYSID2) {
2129 /* Some internal PHYS don't have a model number. Use
2130 * the mv88e6390 family model number instead.
2131 */
2132 if (!(val & 0x3f0))
2133 val |= MV88E6XXX_PORT_SWITCH_ID_PROD_6390 >> 4;
2134 }
2135
2136 return err ? err : val;
2137 }
2138
2139 static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
2140 {
2141 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
2142 struct mv88e6xxx_chip *chip = mdio_bus->chip;
2143 int err;
2144
2145 if (!chip->info->ops->phy_write)
2146 return -EOPNOTSUPP;
2147
2148 mutex_lock(&chip->reg_lock);
2149 err = chip->info->ops->phy_write(chip, bus, phy, reg, val);
2150 mutex_unlock(&chip->reg_lock);
2151
2152 return err;
2153 }
2154
2155 static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
2156 struct device_node *np,
2157 bool external)
2158 {
2159 static int index;
2160 struct mv88e6xxx_mdio_bus *mdio_bus;
2161 struct mii_bus *bus;
2162 int err;
2163
2164 bus = devm_mdiobus_alloc_size(chip->dev, sizeof(*mdio_bus));
2165 if (!bus)
2166 return -ENOMEM;
2167
2168 mdio_bus = bus->priv;
2169 mdio_bus->bus = bus;
2170 mdio_bus->chip = chip;
2171 INIT_LIST_HEAD(&mdio_bus->list);
2172 mdio_bus->external = external;
2173
2174 if (np) {
2175 bus->name = np->full_name;
2176 snprintf(bus->id, MII_BUS_ID_SIZE, "%pOF", np);
2177 } else {
2178 bus->name = "mv88e6xxx SMI";
2179 snprintf(bus->id, MII_BUS_ID_SIZE, "mv88e6xxx-%d", index++);
2180 }
2181
2182 bus->read = mv88e6xxx_mdio_read;
2183 bus->write = mv88e6xxx_mdio_write;
2184 bus->parent = chip->dev;
2185
2186 if (np)
2187 err = of_mdiobus_register(bus, np);
2188 else
2189 err = mdiobus_register(bus);
2190 if (err) {
2191 dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err);
2192 return err;
2193 }
2194
2195 if (external)
2196 list_add_tail(&mdio_bus->list, &chip->mdios);
2197 else
2198 list_add(&mdio_bus->list, &chip->mdios);
2199
2200 return 0;
2201 }
2202
2203 static const struct of_device_id mv88e6xxx_mdio_external_match[] = {
2204 { .compatible = "marvell,mv88e6xxx-mdio-external",
2205 .data = (void *)true },
2206 { },
2207 };
2208
2209 static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
2210
2211 {
2212 struct mv88e6xxx_mdio_bus *mdio_bus;
2213 struct mii_bus *bus;
2214
2215 list_for_each_entry(mdio_bus, &chip->mdios, list) {
2216 bus = mdio_bus->bus;
2217
2218 mdiobus_unregister(bus);
2219 }
2220 }
2221
2222 static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip,
2223 struct device_node *np)
2224 {
2225 const struct of_device_id *match;
2226 struct device_node *child;
2227 int err;
2228
2229 /* Always register one mdio bus for the internal/default mdio
2230 * bus. This maybe represented in the device tree, but is
2231 * optional.
2232 */
2233 child = of_get_child_by_name(np, "mdio");
2234 err = mv88e6xxx_mdio_register(chip, child, false);
2235 if (err)
2236 return err;
2237
2238 /* Walk the device tree, and see if there are any other nodes
2239 * which say they are compatible with the external mdio
2240 * bus.
2241 */
2242 for_each_available_child_of_node(np, child) {
2243 match = of_match_node(mv88e6xxx_mdio_external_match, child);
2244 if (match) {
2245 err = mv88e6xxx_mdio_register(chip, child, true);
2246 if (err) {
2247 mv88e6xxx_mdios_unregister(chip);
2248 return err;
2249 }
2250 }
2251 }
2252
2253 return 0;
2254 }
2255
2256 static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
2257 {
2258 struct mv88e6xxx_chip *chip = ds->priv;
2259
2260 return chip->eeprom_len;
2261 }
2262
2263 static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
2264 struct ethtool_eeprom *eeprom, u8 *data)
2265 {
2266 struct mv88e6xxx_chip *chip = ds->priv;
2267 int err;
2268
2269 if (!chip->info->ops->get_eeprom)
2270 return -EOPNOTSUPP;
2271
2272 mutex_lock(&chip->reg_lock);
2273 err = chip->info->ops->get_eeprom(chip, eeprom, data);
2274 mutex_unlock(&chip->reg_lock);
2275
2276 if (err)
2277 return err;
2278
2279 eeprom->magic = 0xc3ec4951;
2280
2281 return 0;
2282 }
2283
2284 static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
2285 struct ethtool_eeprom *eeprom, u8 *data)
2286 {
2287 struct mv88e6xxx_chip *chip = ds->priv;
2288 int err;
2289
2290 if (!chip->info->ops->set_eeprom)
2291 return -EOPNOTSUPP;
2292
2293 if (eeprom->magic != 0xc3ec4951)
2294 return -EINVAL;
2295
2296 mutex_lock(&chip->reg_lock);
2297 err = chip->info->ops->set_eeprom(chip, eeprom, data);
2298 mutex_unlock(&chip->reg_lock);
2299
2300 return err;
2301 }
2302
2303 static const struct mv88e6xxx_ops mv88e6085_ops = {
2304 /* MV88E6XXX_FAMILY_6097 */
2305 .irl_init_all = mv88e6352_g2_irl_init_all,
2306 .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
2307 .phy_read = mv88e6185_phy_ppu_read,
2308 .phy_write = mv88e6185_phy_ppu_write,
2309 .port_set_link = mv88e6xxx_port_set_link,
2310 .port_set_duplex = mv88e6xxx_port_set_duplex,
2311 .port_set_speed = mv88e6185_port_set_speed,
2312 .port_tag_remap = mv88e6095_port_tag_remap,
2313 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2314 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2315 .port_set_ether_type = mv88e6351_port_set_ether_type,
2316 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
2317 .port_pause_limit = mv88e6097_port_pause_limit,
2318 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2319 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2320 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
2321 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2322 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
2323 .stats_get_strings = mv88e6095_stats_get_strings,
2324 .stats_get_stats = mv88e6095_stats_get_stats,
2325 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2326 .set_egress_port = mv88e6095_g1_set_egress_port,
2327 .watchdog_ops = &mv88e6097_watchdog_ops,
2328 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
2329 .pot_clear = mv88e6xxx_g2_pot_clear,
2330 .ppu_enable = mv88e6185_g1_ppu_enable,
2331 .ppu_disable = mv88e6185_g1_ppu_disable,
2332 .reset = mv88e6185_g1_reset,
2333 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2334 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2335 };
2336
2337 static const struct mv88e6xxx_ops mv88e6095_ops = {
2338 /* MV88E6XXX_FAMILY_6095 */
2339 .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
2340 .phy_read = mv88e6185_phy_ppu_read,
2341 .phy_write = mv88e6185_phy_ppu_write,
2342 .port_set_link = mv88e6xxx_port_set_link,
2343 .port_set_duplex = mv88e6xxx_port_set_duplex,
2344 .port_set_speed = mv88e6185_port_set_speed,
2345 .port_set_frame_mode = mv88e6085_port_set_frame_mode,
2346 .port_set_egress_floods = mv88e6185_port_set_egress_floods,
2347 .port_set_upstream_port = mv88e6095_port_set_upstream_port,
2348 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
2349 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2350 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
2351 .stats_get_strings = mv88e6095_stats_get_strings,
2352 .stats_get_stats = mv88e6095_stats_get_stats,
2353 .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
2354 .ppu_enable = mv88e6185_g1_ppu_enable,
2355 .ppu_disable = mv88e6185_g1_ppu_disable,
2356 .reset = mv88e6185_g1_reset,
2357 .vtu_getnext = mv88e6185_g1_vtu_getnext,
2358 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
2359 };
2360
2361 static const struct mv88e6xxx_ops mv88e6097_ops = {
2362 /* MV88E6XXX_FAMILY_6097 */
2363 .irl_init_all = mv88e6352_g2_irl_init_all,
2364 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2365 .phy_read = mv88e6xxx_g2_smi_phy_read,
2366 .phy_write = mv88e6xxx_g2_smi_phy_write,
2367 .port_set_link = mv88e6xxx_port_set_link,
2368 .port_set_duplex = mv88e6xxx_port_set_duplex,
2369 .port_set_speed = mv88e6185_port_set_speed,
2370 .port_tag_remap = mv88e6095_port_tag_remap,
2371 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2372 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2373 .port_set_ether_type = mv88e6351_port_set_ether_type,
2374 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
2375 .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
2376 .port_pause_limit = mv88e6097_port_pause_limit,
2377 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2378 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2379 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
2380 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2381 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
2382 .stats_get_strings = mv88e6095_stats_get_strings,
2383 .stats_get_stats = mv88e6095_stats_get_stats,
2384 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2385 .set_egress_port = mv88e6095_g1_set_egress_port,
2386 .watchdog_ops = &mv88e6097_watchdog_ops,
2387 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
2388 .pot_clear = mv88e6xxx_g2_pot_clear,
2389 .reset = mv88e6352_g1_reset,
2390 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2391 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2392 };
2393
2394 static const struct mv88e6xxx_ops mv88e6123_ops = {
2395 /* MV88E6XXX_FAMILY_6165 */
2396 .irl_init_all = mv88e6352_g2_irl_init_all,
2397 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2398 .phy_read = mv88e6xxx_g2_smi_phy_read,
2399 .phy_write = mv88e6xxx_g2_smi_phy_write,
2400 .port_set_link = mv88e6xxx_port_set_link,
2401 .port_set_duplex = mv88e6xxx_port_set_duplex,
2402 .port_set_speed = mv88e6185_port_set_speed,
2403 .port_set_frame_mode = mv88e6085_port_set_frame_mode,
2404 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2405 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2406 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2407 .stats_snapshot = mv88e6320_g1_stats_snapshot,
2408 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2409 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
2410 .stats_get_strings = mv88e6095_stats_get_strings,
2411 .stats_get_stats = mv88e6095_stats_get_stats,
2412 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2413 .set_egress_port = mv88e6095_g1_set_egress_port,
2414 .watchdog_ops = &mv88e6097_watchdog_ops,
2415 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
2416 .pot_clear = mv88e6xxx_g2_pot_clear,
2417 .reset = mv88e6352_g1_reset,
2418 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2419 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2420 };
2421
2422 static const struct mv88e6xxx_ops mv88e6131_ops = {
2423 /* MV88E6XXX_FAMILY_6185 */
2424 .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
2425 .phy_read = mv88e6185_phy_ppu_read,
2426 .phy_write = mv88e6185_phy_ppu_write,
2427 .port_set_link = mv88e6xxx_port_set_link,
2428 .port_set_duplex = mv88e6xxx_port_set_duplex,
2429 .port_set_speed = mv88e6185_port_set_speed,
2430 .port_tag_remap = mv88e6095_port_tag_remap,
2431 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2432 .port_set_egress_floods = mv88e6185_port_set_egress_floods,
2433 .port_set_ether_type = mv88e6351_port_set_ether_type,
2434 .port_set_upstream_port = mv88e6095_port_set_upstream_port,
2435 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
2436 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
2437 .port_pause_limit = mv88e6097_port_pause_limit,
2438 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
2439 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2440 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
2441 .stats_get_strings = mv88e6095_stats_get_strings,
2442 .stats_get_stats = mv88e6095_stats_get_stats,
2443 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2444 .set_egress_port = mv88e6095_g1_set_egress_port,
2445 .watchdog_ops = &mv88e6097_watchdog_ops,
2446 .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
2447 .ppu_enable = mv88e6185_g1_ppu_enable,
2448 .ppu_disable = mv88e6185_g1_ppu_disable,
2449 .reset = mv88e6185_g1_reset,
2450 .vtu_getnext = mv88e6185_g1_vtu_getnext,
2451 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
2452 };
2453
2454 static const struct mv88e6xxx_ops mv88e6141_ops = {
2455 /* MV88E6XXX_FAMILY_6341 */
2456 .irl_init_all = mv88e6352_g2_irl_init_all,
2457 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
2458 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
2459 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2460 .phy_read = mv88e6xxx_g2_smi_phy_read,
2461 .phy_write = mv88e6xxx_g2_smi_phy_write,
2462 .port_set_link = mv88e6xxx_port_set_link,
2463 .port_set_duplex = mv88e6xxx_port_set_duplex,
2464 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
2465 .port_set_speed = mv88e6390_port_set_speed,
2466 .port_tag_remap = mv88e6095_port_tag_remap,
2467 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2468 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2469 .port_set_ether_type = mv88e6351_port_set_ether_type,
2470 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
2471 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
2472 .port_pause_limit = mv88e6097_port_pause_limit,
2473 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2474 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2475 .stats_snapshot = mv88e6390_g1_stats_snapshot,
2476 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2477 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
2478 .stats_get_strings = mv88e6320_stats_get_strings,
2479 .stats_get_stats = mv88e6390_stats_get_stats,
2480 .set_cpu_port = mv88e6390_g1_set_cpu_port,
2481 .set_egress_port = mv88e6390_g1_set_egress_port,
2482 .watchdog_ops = &mv88e6390_watchdog_ops,
2483 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
2484 .pot_clear = mv88e6xxx_g2_pot_clear,
2485 .reset = mv88e6352_g1_reset,
2486 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2487 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2488 .gpio_ops = &mv88e6352_gpio_ops,
2489 };
2490
2491 static const struct mv88e6xxx_ops mv88e6161_ops = {
2492 /* MV88E6XXX_FAMILY_6165 */
2493 .irl_init_all = mv88e6352_g2_irl_init_all,
2494 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2495 .phy_read = mv88e6xxx_g2_smi_phy_read,
2496 .phy_write = mv88e6xxx_g2_smi_phy_write,
2497 .port_set_link = mv88e6xxx_port_set_link,
2498 .port_set_duplex = mv88e6xxx_port_set_duplex,
2499 .port_set_speed = mv88e6185_port_set_speed,
2500 .port_tag_remap = mv88e6095_port_tag_remap,
2501 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2502 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2503 .port_set_ether_type = mv88e6351_port_set_ether_type,
2504 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
2505 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
2506 .port_pause_limit = mv88e6097_port_pause_limit,
2507 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2508 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2509 .stats_snapshot = mv88e6320_g1_stats_snapshot,
2510 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2511 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
2512 .stats_get_strings = mv88e6095_stats_get_strings,
2513 .stats_get_stats = mv88e6095_stats_get_stats,
2514 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2515 .set_egress_port = mv88e6095_g1_set_egress_port,
2516 .watchdog_ops = &mv88e6097_watchdog_ops,
2517 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
2518 .pot_clear = mv88e6xxx_g2_pot_clear,
2519 .reset = mv88e6352_g1_reset,
2520 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2521 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2522 };
2523
2524 static const struct mv88e6xxx_ops mv88e6165_ops = {
2525 /* MV88E6XXX_FAMILY_6165 */
2526 .irl_init_all = mv88e6352_g2_irl_init_all,
2527 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2528 .phy_read = mv88e6165_phy_read,
2529 .phy_write = mv88e6165_phy_write,
2530 .port_set_link = mv88e6xxx_port_set_link,
2531 .port_set_duplex = mv88e6xxx_port_set_duplex,
2532 .port_set_speed = mv88e6185_port_set_speed,
2533 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2534 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2535 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
2536 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2537 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
2538 .stats_get_strings = mv88e6095_stats_get_strings,
2539 .stats_get_stats = mv88e6095_stats_get_stats,
2540 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2541 .set_egress_port = mv88e6095_g1_set_egress_port,
2542 .watchdog_ops = &mv88e6097_watchdog_ops,
2543 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
2544 .pot_clear = mv88e6xxx_g2_pot_clear,
2545 .reset = mv88e6352_g1_reset,
2546 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2547 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2548 };
2549
2550 static const struct mv88e6xxx_ops mv88e6171_ops = {
2551 /* MV88E6XXX_FAMILY_6351 */
2552 .irl_init_all = mv88e6352_g2_irl_init_all,
2553 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2554 .phy_read = mv88e6xxx_g2_smi_phy_read,
2555 .phy_write = mv88e6xxx_g2_smi_phy_write,
2556 .port_set_link = mv88e6xxx_port_set_link,
2557 .port_set_duplex = mv88e6xxx_port_set_duplex,
2558 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
2559 .port_set_speed = mv88e6185_port_set_speed,
2560 .port_tag_remap = mv88e6095_port_tag_remap,
2561 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2562 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2563 .port_set_ether_type = mv88e6351_port_set_ether_type,
2564 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
2565 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
2566 .port_pause_limit = mv88e6097_port_pause_limit,
2567 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2568 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2569 .stats_snapshot = mv88e6320_g1_stats_snapshot,
2570 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2571 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
2572 .stats_get_strings = mv88e6095_stats_get_strings,
2573 .stats_get_stats = mv88e6095_stats_get_stats,
2574 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2575 .set_egress_port = mv88e6095_g1_set_egress_port,
2576 .watchdog_ops = &mv88e6097_watchdog_ops,
2577 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
2578 .pot_clear = mv88e6xxx_g2_pot_clear,
2579 .reset = mv88e6352_g1_reset,
2580 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2581 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2582 };
2583
2584 static const struct mv88e6xxx_ops mv88e6172_ops = {
2585 /* MV88E6XXX_FAMILY_6352 */
2586 .irl_init_all = mv88e6352_g2_irl_init_all,
2587 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
2588 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
2589 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2590 .phy_read = mv88e6xxx_g2_smi_phy_read,
2591 .phy_write = mv88e6xxx_g2_smi_phy_write,
2592 .port_set_link = mv88e6xxx_port_set_link,
2593 .port_set_duplex = mv88e6xxx_port_set_duplex,
2594 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
2595 .port_set_speed = mv88e6352_port_set_speed,
2596 .port_tag_remap = mv88e6095_port_tag_remap,
2597 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2598 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2599 .port_set_ether_type = mv88e6351_port_set_ether_type,
2600 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
2601 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
2602 .port_pause_limit = mv88e6097_port_pause_limit,
2603 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2604 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2605 .stats_snapshot = mv88e6320_g1_stats_snapshot,
2606 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2607 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
2608 .stats_get_strings = mv88e6095_stats_get_strings,
2609 .stats_get_stats = mv88e6095_stats_get_stats,
2610 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2611 .set_egress_port = mv88e6095_g1_set_egress_port,
2612 .watchdog_ops = &mv88e6097_watchdog_ops,
2613 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
2614 .pot_clear = mv88e6xxx_g2_pot_clear,
2615 .reset = mv88e6352_g1_reset,
2616 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2617 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2618 .serdes_power = mv88e6352_serdes_power,
2619 .gpio_ops = &mv88e6352_gpio_ops,
2620 };
2621
2622 static const struct mv88e6xxx_ops mv88e6175_ops = {
2623 /* MV88E6XXX_FAMILY_6351 */
2624 .irl_init_all = mv88e6352_g2_irl_init_all,
2625 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2626 .phy_read = mv88e6xxx_g2_smi_phy_read,
2627 .phy_write = mv88e6xxx_g2_smi_phy_write,
2628 .port_set_link = mv88e6xxx_port_set_link,
2629 .port_set_duplex = mv88e6xxx_port_set_duplex,
2630 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
2631 .port_set_speed = mv88e6185_port_set_speed,
2632 .port_tag_remap = mv88e6095_port_tag_remap,
2633 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2634 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2635 .port_set_ether_type = mv88e6351_port_set_ether_type,
2636 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
2637 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
2638 .port_pause_limit = mv88e6097_port_pause_limit,
2639 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2640 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2641 .stats_snapshot = mv88e6320_g1_stats_snapshot,
2642 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2643 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
2644 .stats_get_strings = mv88e6095_stats_get_strings,
2645 .stats_get_stats = mv88e6095_stats_get_stats,
2646 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2647 .set_egress_port = mv88e6095_g1_set_egress_port,
2648 .watchdog_ops = &mv88e6097_watchdog_ops,
2649 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
2650 .pot_clear = mv88e6xxx_g2_pot_clear,
2651 .reset = mv88e6352_g1_reset,
2652 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2653 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2654 };
2655
2656 static const struct mv88e6xxx_ops mv88e6176_ops = {
2657 /* MV88E6XXX_FAMILY_6352 */
2658 .irl_init_all = mv88e6352_g2_irl_init_all,
2659 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
2660 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
2661 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2662 .phy_read = mv88e6xxx_g2_smi_phy_read,
2663 .phy_write = mv88e6xxx_g2_smi_phy_write,
2664 .port_set_link = mv88e6xxx_port_set_link,
2665 .port_set_duplex = mv88e6xxx_port_set_duplex,
2666 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
2667 .port_set_speed = mv88e6352_port_set_speed,
2668 .port_tag_remap = mv88e6095_port_tag_remap,
2669 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2670 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2671 .port_set_ether_type = mv88e6351_port_set_ether_type,
2672 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
2673 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
2674 .port_pause_limit = mv88e6097_port_pause_limit,
2675 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2676 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2677 .stats_snapshot = mv88e6320_g1_stats_snapshot,
2678 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2679 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
2680 .stats_get_strings = mv88e6095_stats_get_strings,
2681 .stats_get_stats = mv88e6095_stats_get_stats,
2682 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2683 .set_egress_port = mv88e6095_g1_set_egress_port,
2684 .watchdog_ops = &mv88e6097_watchdog_ops,
2685 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
2686 .pot_clear = mv88e6xxx_g2_pot_clear,
2687 .reset = mv88e6352_g1_reset,
2688 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2689 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2690 .serdes_power = mv88e6352_serdes_power,
2691 .gpio_ops = &mv88e6352_gpio_ops,
2692 };
2693
2694 static const struct mv88e6xxx_ops mv88e6185_ops = {
2695 /* MV88E6XXX_FAMILY_6185 */
2696 .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
2697 .phy_read = mv88e6185_phy_ppu_read,
2698 .phy_write = mv88e6185_phy_ppu_write,
2699 .port_set_link = mv88e6xxx_port_set_link,
2700 .port_set_duplex = mv88e6xxx_port_set_duplex,
2701 .port_set_speed = mv88e6185_port_set_speed,
2702 .port_set_frame_mode = mv88e6085_port_set_frame_mode,
2703 .port_set_egress_floods = mv88e6185_port_set_egress_floods,
2704 .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
2705 .port_set_upstream_port = mv88e6095_port_set_upstream_port,
2706 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
2707 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2708 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
2709 .stats_get_strings = mv88e6095_stats_get_strings,
2710 .stats_get_stats = mv88e6095_stats_get_stats,
2711 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2712 .set_egress_port = mv88e6095_g1_set_egress_port,
2713 .watchdog_ops = &mv88e6097_watchdog_ops,
2714 .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
2715 .ppu_enable = mv88e6185_g1_ppu_enable,
2716 .ppu_disable = mv88e6185_g1_ppu_disable,
2717 .reset = mv88e6185_g1_reset,
2718 .vtu_getnext = mv88e6185_g1_vtu_getnext,
2719 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
2720 };
2721
2722 static const struct mv88e6xxx_ops mv88e6190_ops = {
2723 /* MV88E6XXX_FAMILY_6390 */
2724 .irl_init_all = mv88e6390_g2_irl_init_all,
2725 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
2726 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
2727 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2728 .phy_read = mv88e6xxx_g2_smi_phy_read,
2729 .phy_write = mv88e6xxx_g2_smi_phy_write,
2730 .port_set_link = mv88e6xxx_port_set_link,
2731 .port_set_duplex = mv88e6xxx_port_set_duplex,
2732 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
2733 .port_set_speed = mv88e6390_port_set_speed,
2734 .port_tag_remap = mv88e6390_port_tag_remap,
2735 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2736 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2737 .port_set_ether_type = mv88e6351_port_set_ether_type,
2738 .port_pause_limit = mv88e6390_port_pause_limit,
2739 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2740 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2741 .stats_snapshot = mv88e6390_g1_stats_snapshot,
2742 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
2743 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
2744 .stats_get_strings = mv88e6320_stats_get_strings,
2745 .stats_get_stats = mv88e6390_stats_get_stats,
2746 .set_cpu_port = mv88e6390_g1_set_cpu_port,
2747 .set_egress_port = mv88e6390_g1_set_egress_port,
2748 .watchdog_ops = &mv88e6390_watchdog_ops,
2749 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
2750 .pot_clear = mv88e6xxx_g2_pot_clear,
2751 .reset = mv88e6352_g1_reset,
2752 .vtu_getnext = mv88e6390_g1_vtu_getnext,
2753 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
2754 .serdes_power = mv88e6390_serdes_power,
2755 .gpio_ops = &mv88e6352_gpio_ops,
2756 };
2757
2758 static const struct mv88e6xxx_ops mv88e6190x_ops = {
2759 /* MV88E6XXX_FAMILY_6390 */
2760 .irl_init_all = mv88e6390_g2_irl_init_all,
2761 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
2762 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
2763 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2764 .phy_read = mv88e6xxx_g2_smi_phy_read,
2765 .phy_write = mv88e6xxx_g2_smi_phy_write,
2766 .port_set_link = mv88e6xxx_port_set_link,
2767 .port_set_duplex = mv88e6xxx_port_set_duplex,
2768 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
2769 .port_set_speed = mv88e6390x_port_set_speed,
2770 .port_tag_remap = mv88e6390_port_tag_remap,
2771 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2772 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2773 .port_set_ether_type = mv88e6351_port_set_ether_type,
2774 .port_pause_limit = mv88e6390_port_pause_limit,
2775 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2776 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2777 .stats_snapshot = mv88e6390_g1_stats_snapshot,
2778 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
2779 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
2780 .stats_get_strings = mv88e6320_stats_get_strings,
2781 .stats_get_stats = mv88e6390_stats_get_stats,
2782 .set_cpu_port = mv88e6390_g1_set_cpu_port,
2783 .set_egress_port = mv88e6390_g1_set_egress_port,
2784 .watchdog_ops = &mv88e6390_watchdog_ops,
2785 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
2786 .pot_clear = mv88e6xxx_g2_pot_clear,
2787 .reset = mv88e6352_g1_reset,
2788 .vtu_getnext = mv88e6390_g1_vtu_getnext,
2789 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
2790 .serdes_power = mv88e6390_serdes_power,
2791 .gpio_ops = &mv88e6352_gpio_ops,
2792 };
2793
2794 static const struct mv88e6xxx_ops mv88e6191_ops = {
2795 /* MV88E6XXX_FAMILY_6390 */
2796 .irl_init_all = mv88e6390_g2_irl_init_all,
2797 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
2798 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
2799 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2800 .phy_read = mv88e6xxx_g2_smi_phy_read,
2801 .phy_write = mv88e6xxx_g2_smi_phy_write,
2802 .port_set_link = mv88e6xxx_port_set_link,
2803 .port_set_duplex = mv88e6xxx_port_set_duplex,
2804 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
2805 .port_set_speed = mv88e6390_port_set_speed,
2806 .port_tag_remap = mv88e6390_port_tag_remap,
2807 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2808 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2809 .port_set_ether_type = mv88e6351_port_set_ether_type,
2810 .port_pause_limit = mv88e6390_port_pause_limit,
2811 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2812 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2813 .stats_snapshot = mv88e6390_g1_stats_snapshot,
2814 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
2815 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
2816 .stats_get_strings = mv88e6320_stats_get_strings,
2817 .stats_get_stats = mv88e6390_stats_get_stats,
2818 .set_cpu_port = mv88e6390_g1_set_cpu_port,
2819 .set_egress_port = mv88e6390_g1_set_egress_port,
2820 .watchdog_ops = &mv88e6390_watchdog_ops,
2821 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
2822 .pot_clear = mv88e6xxx_g2_pot_clear,
2823 .reset = mv88e6352_g1_reset,
2824 .vtu_getnext = mv88e6390_g1_vtu_getnext,
2825 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
2826 .serdes_power = mv88e6390_serdes_power,
2827 };
2828
2829 static const struct mv88e6xxx_ops mv88e6240_ops = {
2830 /* MV88E6XXX_FAMILY_6352 */
2831 .irl_init_all = mv88e6352_g2_irl_init_all,
2832 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
2833 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
2834 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2835 .phy_read = mv88e6xxx_g2_smi_phy_read,
2836 .phy_write = mv88e6xxx_g2_smi_phy_write,
2837 .port_set_link = mv88e6xxx_port_set_link,
2838 .port_set_duplex = mv88e6xxx_port_set_duplex,
2839 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
2840 .port_set_speed = mv88e6352_port_set_speed,
2841 .port_tag_remap = mv88e6095_port_tag_remap,
2842 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2843 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2844 .port_set_ether_type = mv88e6351_port_set_ether_type,
2845 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
2846 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
2847 .port_pause_limit = mv88e6097_port_pause_limit,
2848 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2849 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2850 .stats_snapshot = mv88e6320_g1_stats_snapshot,
2851 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2852 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
2853 .stats_get_strings = mv88e6095_stats_get_strings,
2854 .stats_get_stats = mv88e6095_stats_get_stats,
2855 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2856 .set_egress_port = mv88e6095_g1_set_egress_port,
2857 .watchdog_ops = &mv88e6097_watchdog_ops,
2858 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
2859 .pot_clear = mv88e6xxx_g2_pot_clear,
2860 .reset = mv88e6352_g1_reset,
2861 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2862 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2863 .serdes_power = mv88e6352_serdes_power,
2864 .gpio_ops = &mv88e6352_gpio_ops,
2865 .avb_ops = &mv88e6352_avb_ops,
2866 };
2867
2868 static const struct mv88e6xxx_ops mv88e6290_ops = {
2869 /* MV88E6XXX_FAMILY_6390 */
2870 .irl_init_all = mv88e6390_g2_irl_init_all,
2871 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
2872 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
2873 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2874 .phy_read = mv88e6xxx_g2_smi_phy_read,
2875 .phy_write = mv88e6xxx_g2_smi_phy_write,
2876 .port_set_link = mv88e6xxx_port_set_link,
2877 .port_set_duplex = mv88e6xxx_port_set_duplex,
2878 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
2879 .port_set_speed = mv88e6390_port_set_speed,
2880 .port_tag_remap = mv88e6390_port_tag_remap,
2881 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2882 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2883 .port_set_ether_type = mv88e6351_port_set_ether_type,
2884 .port_pause_limit = mv88e6390_port_pause_limit,
2885 .port_set_cmode = mv88e6390x_port_set_cmode,
2886 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2887 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2888 .stats_snapshot = mv88e6390_g1_stats_snapshot,
2889 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
2890 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
2891 .stats_get_strings = mv88e6320_stats_get_strings,
2892 .stats_get_stats = mv88e6390_stats_get_stats,
2893 .set_cpu_port = mv88e6390_g1_set_cpu_port,
2894 .set_egress_port = mv88e6390_g1_set_egress_port,
2895 .watchdog_ops = &mv88e6390_watchdog_ops,
2896 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
2897 .pot_clear = mv88e6xxx_g2_pot_clear,
2898 .reset = mv88e6352_g1_reset,
2899 .vtu_getnext = mv88e6390_g1_vtu_getnext,
2900 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
2901 .serdes_power = mv88e6390_serdes_power,
2902 .gpio_ops = &mv88e6352_gpio_ops,
2903 .avb_ops = &mv88e6390_avb_ops,
2904 };
2905
2906 static const struct mv88e6xxx_ops mv88e6320_ops = {
2907 /* MV88E6XXX_FAMILY_6320 */
2908 .irl_init_all = mv88e6352_g2_irl_init_all,
2909 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
2910 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
2911 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2912 .phy_read = mv88e6xxx_g2_smi_phy_read,
2913 .phy_write = mv88e6xxx_g2_smi_phy_write,
2914 .port_set_link = mv88e6xxx_port_set_link,
2915 .port_set_duplex = mv88e6xxx_port_set_duplex,
2916 .port_set_speed = mv88e6185_port_set_speed,
2917 .port_tag_remap = mv88e6095_port_tag_remap,
2918 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2919 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2920 .port_set_ether_type = mv88e6351_port_set_ether_type,
2921 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
2922 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
2923 .port_pause_limit = mv88e6097_port_pause_limit,
2924 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2925 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2926 .stats_snapshot = mv88e6320_g1_stats_snapshot,
2927 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2928 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
2929 .stats_get_strings = mv88e6320_stats_get_strings,
2930 .stats_get_stats = mv88e6320_stats_get_stats,
2931 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2932 .set_egress_port = mv88e6095_g1_set_egress_port,
2933 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
2934 .pot_clear = mv88e6xxx_g2_pot_clear,
2935 .reset = mv88e6352_g1_reset,
2936 .vtu_getnext = mv88e6185_g1_vtu_getnext,
2937 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
2938 .gpio_ops = &mv88e6352_gpio_ops,
2939 .avb_ops = &mv88e6352_avb_ops,
2940 };
2941
2942 static const struct mv88e6xxx_ops mv88e6321_ops = {
2943 /* MV88E6XXX_FAMILY_6320 */
2944 .irl_init_all = mv88e6352_g2_irl_init_all,
2945 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
2946 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
2947 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2948 .phy_read = mv88e6xxx_g2_smi_phy_read,
2949 .phy_write = mv88e6xxx_g2_smi_phy_write,
2950 .port_set_link = mv88e6xxx_port_set_link,
2951 .port_set_duplex = mv88e6xxx_port_set_duplex,
2952 .port_set_speed = mv88e6185_port_set_speed,
2953 .port_tag_remap = mv88e6095_port_tag_remap,
2954 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2955 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2956 .port_set_ether_type = mv88e6351_port_set_ether_type,
2957 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
2958 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
2959 .port_pause_limit = mv88e6097_port_pause_limit,
2960 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2961 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2962 .stats_snapshot = mv88e6320_g1_stats_snapshot,
2963 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2964 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
2965 .stats_get_strings = mv88e6320_stats_get_strings,
2966 .stats_get_stats = mv88e6320_stats_get_stats,
2967 .set_cpu_port = mv88e6095_g1_set_cpu_port,
2968 .set_egress_port = mv88e6095_g1_set_egress_port,
2969 .reset = mv88e6352_g1_reset,
2970 .vtu_getnext = mv88e6185_g1_vtu_getnext,
2971 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
2972 .gpio_ops = &mv88e6352_gpio_ops,
2973 .avb_ops = &mv88e6352_avb_ops,
2974 };
2975
2976 static const struct mv88e6xxx_ops mv88e6341_ops = {
2977 /* MV88E6XXX_FAMILY_6341 */
2978 .irl_init_all = mv88e6352_g2_irl_init_all,
2979 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
2980 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
2981 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
2982 .phy_read = mv88e6xxx_g2_smi_phy_read,
2983 .phy_write = mv88e6xxx_g2_smi_phy_write,
2984 .port_set_link = mv88e6xxx_port_set_link,
2985 .port_set_duplex = mv88e6xxx_port_set_duplex,
2986 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
2987 .port_set_speed = mv88e6390_port_set_speed,
2988 .port_tag_remap = mv88e6095_port_tag_remap,
2989 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
2990 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
2991 .port_set_ether_type = mv88e6351_port_set_ether_type,
2992 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
2993 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
2994 .port_pause_limit = mv88e6097_port_pause_limit,
2995 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
2996 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
2997 .stats_snapshot = mv88e6390_g1_stats_snapshot,
2998 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
2999 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
3000 .stats_get_strings = mv88e6320_stats_get_strings,
3001 .stats_get_stats = mv88e6390_stats_get_stats,
3002 .set_cpu_port = mv88e6390_g1_set_cpu_port,
3003 .set_egress_port = mv88e6390_g1_set_egress_port,
3004 .watchdog_ops = &mv88e6390_watchdog_ops,
3005 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
3006 .pot_clear = mv88e6xxx_g2_pot_clear,
3007 .reset = mv88e6352_g1_reset,
3008 .vtu_getnext = mv88e6352_g1_vtu_getnext,
3009 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3010 .gpio_ops = &mv88e6352_gpio_ops,
3011 .avb_ops = &mv88e6390_avb_ops,
3012 };
3013
3014 static const struct mv88e6xxx_ops mv88e6350_ops = {
3015 /* MV88E6XXX_FAMILY_6351 */
3016 .irl_init_all = mv88e6352_g2_irl_init_all,
3017 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3018 .phy_read = mv88e6xxx_g2_smi_phy_read,
3019 .phy_write = mv88e6xxx_g2_smi_phy_write,
3020 .port_set_link = mv88e6xxx_port_set_link,
3021 .port_set_duplex = mv88e6xxx_port_set_duplex,
3022 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3023 .port_set_speed = mv88e6185_port_set_speed,
3024 .port_tag_remap = mv88e6095_port_tag_remap,
3025 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
3026 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
3027 .port_set_ether_type = mv88e6351_port_set_ether_type,
3028 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3029 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3030 .port_pause_limit = mv88e6097_port_pause_limit,
3031 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3032 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3033 .stats_snapshot = mv88e6320_g1_stats_snapshot,
3034 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3035 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
3036 .stats_get_strings = mv88e6095_stats_get_strings,
3037 .stats_get_stats = mv88e6095_stats_get_stats,
3038 .set_cpu_port = mv88e6095_g1_set_cpu_port,
3039 .set_egress_port = mv88e6095_g1_set_egress_port,
3040 .watchdog_ops = &mv88e6097_watchdog_ops,
3041 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
3042 .pot_clear = mv88e6xxx_g2_pot_clear,
3043 .reset = mv88e6352_g1_reset,
3044 .vtu_getnext = mv88e6352_g1_vtu_getnext,
3045 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3046 };
3047
3048 static const struct mv88e6xxx_ops mv88e6351_ops = {
3049 /* MV88E6XXX_FAMILY_6351 */
3050 .irl_init_all = mv88e6352_g2_irl_init_all,
3051 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3052 .phy_read = mv88e6xxx_g2_smi_phy_read,
3053 .phy_write = mv88e6xxx_g2_smi_phy_write,
3054 .port_set_link = mv88e6xxx_port_set_link,
3055 .port_set_duplex = mv88e6xxx_port_set_duplex,
3056 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3057 .port_set_speed = mv88e6185_port_set_speed,
3058 .port_tag_remap = mv88e6095_port_tag_remap,
3059 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
3060 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
3061 .port_set_ether_type = mv88e6351_port_set_ether_type,
3062 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3063 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3064 .port_pause_limit = mv88e6097_port_pause_limit,
3065 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3066 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3067 .stats_snapshot = mv88e6320_g1_stats_snapshot,
3068 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3069 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
3070 .stats_get_strings = mv88e6095_stats_get_strings,
3071 .stats_get_stats = mv88e6095_stats_get_stats,
3072 .set_cpu_port = mv88e6095_g1_set_cpu_port,
3073 .set_egress_port = mv88e6095_g1_set_egress_port,
3074 .watchdog_ops = &mv88e6097_watchdog_ops,
3075 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
3076 .pot_clear = mv88e6xxx_g2_pot_clear,
3077 .reset = mv88e6352_g1_reset,
3078 .vtu_getnext = mv88e6352_g1_vtu_getnext,
3079 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3080 .avb_ops = &mv88e6352_avb_ops,
3081 };
3082
3083 static const struct mv88e6xxx_ops mv88e6352_ops = {
3084 /* MV88E6XXX_FAMILY_6352 */
3085 .irl_init_all = mv88e6352_g2_irl_init_all,
3086 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
3087 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
3088 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3089 .phy_read = mv88e6xxx_g2_smi_phy_read,
3090 .phy_write = mv88e6xxx_g2_smi_phy_write,
3091 .port_set_link = mv88e6xxx_port_set_link,
3092 .port_set_duplex = mv88e6xxx_port_set_duplex,
3093 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3094 .port_set_speed = mv88e6352_port_set_speed,
3095 .port_tag_remap = mv88e6095_port_tag_remap,
3096 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
3097 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
3098 .port_set_ether_type = mv88e6351_port_set_ether_type,
3099 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3100 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3101 .port_pause_limit = mv88e6097_port_pause_limit,
3102 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3103 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3104 .stats_snapshot = mv88e6320_g1_stats_snapshot,
3105 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3106 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
3107 .stats_get_strings = mv88e6095_stats_get_strings,
3108 .stats_get_stats = mv88e6095_stats_get_stats,
3109 .set_cpu_port = mv88e6095_g1_set_cpu_port,
3110 .set_egress_port = mv88e6095_g1_set_egress_port,
3111 .watchdog_ops = &mv88e6097_watchdog_ops,
3112 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
3113 .pot_clear = mv88e6xxx_g2_pot_clear,
3114 .reset = mv88e6352_g1_reset,
3115 .vtu_getnext = mv88e6352_g1_vtu_getnext,
3116 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3117 .serdes_power = mv88e6352_serdes_power,
3118 .gpio_ops = &mv88e6352_gpio_ops,
3119 .avb_ops = &mv88e6352_avb_ops,
3120 };
3121
3122 static const struct mv88e6xxx_ops mv88e6390_ops = {
3123 /* MV88E6XXX_FAMILY_6390 */
3124 .irl_init_all = mv88e6390_g2_irl_init_all,
3125 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
3126 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
3127 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3128 .phy_read = mv88e6xxx_g2_smi_phy_read,
3129 .phy_write = mv88e6xxx_g2_smi_phy_write,
3130 .port_set_link = mv88e6xxx_port_set_link,
3131 .port_set_duplex = mv88e6xxx_port_set_duplex,
3132 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3133 .port_set_speed = mv88e6390_port_set_speed,
3134 .port_tag_remap = mv88e6390_port_tag_remap,
3135 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
3136 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
3137 .port_set_ether_type = mv88e6351_port_set_ether_type,
3138 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3139 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3140 .port_pause_limit = mv88e6390_port_pause_limit,
3141 .port_set_cmode = mv88e6390x_port_set_cmode,
3142 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3143 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3144 .stats_snapshot = mv88e6390_g1_stats_snapshot,
3145 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
3146 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
3147 .stats_get_strings = mv88e6320_stats_get_strings,
3148 .stats_get_stats = mv88e6390_stats_get_stats,
3149 .set_cpu_port = mv88e6390_g1_set_cpu_port,
3150 .set_egress_port = mv88e6390_g1_set_egress_port,
3151 .watchdog_ops = &mv88e6390_watchdog_ops,
3152 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
3153 .pot_clear = mv88e6xxx_g2_pot_clear,
3154 .reset = mv88e6352_g1_reset,
3155 .vtu_getnext = mv88e6390_g1_vtu_getnext,
3156 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
3157 .serdes_power = mv88e6390_serdes_power,
3158 .gpio_ops = &mv88e6352_gpio_ops,
3159 .avb_ops = &mv88e6390_avb_ops,
3160 };
3161
3162 static const struct mv88e6xxx_ops mv88e6390x_ops = {
3163 /* MV88E6XXX_FAMILY_6390 */
3164 .irl_init_all = mv88e6390_g2_irl_init_all,
3165 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
3166 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
3167 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3168 .phy_read = mv88e6xxx_g2_smi_phy_read,
3169 .phy_write = mv88e6xxx_g2_smi_phy_write,
3170 .port_set_link = mv88e6xxx_port_set_link,
3171 .port_set_duplex = mv88e6xxx_port_set_duplex,
3172 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3173 .port_set_speed = mv88e6390x_port_set_speed,
3174 .port_tag_remap = mv88e6390_port_tag_remap,
3175 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
3176 .port_set_egress_floods = mv88e6352_port_set_egress_floods,
3177 .port_set_ether_type = mv88e6351_port_set_ether_type,
3178 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3179 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3180 .port_pause_limit = mv88e6390_port_pause_limit,
3181 .port_set_cmode = mv88e6390x_port_set_cmode,
3182 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3183 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3184 .stats_snapshot = mv88e6390_g1_stats_snapshot,
3185 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
3186 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
3187 .stats_get_strings = mv88e6320_stats_get_strings,
3188 .stats_get_stats = mv88e6390_stats_get_stats,
3189 .set_cpu_port = mv88e6390_g1_set_cpu_port,
3190 .set_egress_port = mv88e6390_g1_set_egress_port,
3191 .watchdog_ops = &mv88e6390_watchdog_ops,
3192 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
3193 .pot_clear = mv88e6xxx_g2_pot_clear,
3194 .reset = mv88e6352_g1_reset,
3195 .vtu_getnext = mv88e6390_g1_vtu_getnext,
3196 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
3197 .serdes_power = mv88e6390_serdes_power,
3198 .gpio_ops = &mv88e6352_gpio_ops,
3199 .avb_ops = &mv88e6390_avb_ops,
3200 };
3201
3202 static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3203 [MV88E6085] = {
3204 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6085,
3205 .family = MV88E6XXX_FAMILY_6097,
3206 .name = "Marvell 88E6085",
3207 .num_databases = 4096,
3208 .num_ports = 10,
3209 .max_vid = 4095,
3210 .port_base_addr = 0x10,
3211 .global1_addr = 0x1b,
3212 .global2_addr = 0x1c,
3213 .age_time_coeff = 15000,
3214 .g1_irqs = 8,
3215 .g2_irqs = 10,
3216 .atu_move_port_mask = 0xf,
3217 .pvt = true,
3218 .multi_chip = true,
3219 .tag_protocol = DSA_TAG_PROTO_DSA,
3220 .ops = &mv88e6085_ops,
3221 },
3222
3223 [MV88E6095] = {
3224 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6095,
3225 .family = MV88E6XXX_FAMILY_6095,
3226 .name = "Marvell 88E6095/88E6095F",
3227 .num_databases = 256,
3228 .num_ports = 11,
3229 .max_vid = 4095,
3230 .port_base_addr = 0x10,
3231 .global1_addr = 0x1b,
3232 .global2_addr = 0x1c,
3233 .age_time_coeff = 15000,
3234 .g1_irqs = 8,
3235 .atu_move_port_mask = 0xf,
3236 .multi_chip = true,
3237 .tag_protocol = DSA_TAG_PROTO_DSA,
3238 .ops = &mv88e6095_ops,
3239 },
3240
3241 [MV88E6097] = {
3242 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6097,
3243 .family = MV88E6XXX_FAMILY_6097,
3244 .name = "Marvell 88E6097/88E6097F",
3245 .num_databases = 4096,
3246 .num_ports = 11,
3247 .max_vid = 4095,
3248 .port_base_addr = 0x10,
3249 .global1_addr = 0x1b,
3250 .global2_addr = 0x1c,
3251 .age_time_coeff = 15000,
3252 .g1_irqs = 8,
3253 .g2_irqs = 10,
3254 .atu_move_port_mask = 0xf,
3255 .pvt = true,
3256 .multi_chip = true,
3257 .tag_protocol = DSA_TAG_PROTO_EDSA,
3258 .ops = &mv88e6097_ops,
3259 },
3260
3261 [MV88E6123] = {
3262 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6123,
3263 .family = MV88E6XXX_FAMILY_6165,
3264 .name = "Marvell 88E6123",
3265 .num_databases = 4096,
3266 .num_ports = 3,
3267 .max_vid = 4095,
3268 .port_base_addr = 0x10,
3269 .global1_addr = 0x1b,
3270 .global2_addr = 0x1c,
3271 .age_time_coeff = 15000,
3272 .g1_irqs = 9,
3273 .g2_irqs = 10,
3274 .atu_move_port_mask = 0xf,
3275 .pvt = true,
3276 .multi_chip = true,
3277 .tag_protocol = DSA_TAG_PROTO_EDSA,
3278 .ops = &mv88e6123_ops,
3279 },
3280
3281 [MV88E6131] = {
3282 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6131,
3283 .family = MV88E6XXX_FAMILY_6185,
3284 .name = "Marvell 88E6131",
3285 .num_databases = 256,
3286 .num_ports = 8,
3287 .max_vid = 4095,
3288 .port_base_addr = 0x10,
3289 .global1_addr = 0x1b,
3290 .global2_addr = 0x1c,
3291 .age_time_coeff = 15000,
3292 .g1_irqs = 9,
3293 .atu_move_port_mask = 0xf,
3294 .multi_chip = true,
3295 .tag_protocol = DSA_TAG_PROTO_DSA,
3296 .ops = &mv88e6131_ops,
3297 },
3298
3299 [MV88E6141] = {
3300 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
3301 .family = MV88E6XXX_FAMILY_6341,
3302 .name = "Marvell 88E6341",
3303 .num_databases = 4096,
3304 .num_ports = 6,
3305 .num_gpio = 11,
3306 .max_vid = 4095,
3307 .port_base_addr = 0x10,
3308 .global1_addr = 0x1b,
3309 .global2_addr = 0x1c,
3310 .age_time_coeff = 3750,
3311 .atu_move_port_mask = 0x1f,
3312 .g2_irqs = 10,
3313 .pvt = true,
3314 .multi_chip = true,
3315 .tag_protocol = DSA_TAG_PROTO_EDSA,
3316 .ops = &mv88e6141_ops,
3317 },
3318
3319 [MV88E6161] = {
3320 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6161,
3321 .family = MV88E6XXX_FAMILY_6165,
3322 .name = "Marvell 88E6161",
3323 .num_databases = 4096,
3324 .num_ports = 6,
3325 .max_vid = 4095,
3326 .port_base_addr = 0x10,
3327 .global1_addr = 0x1b,
3328 .global2_addr = 0x1c,
3329 .age_time_coeff = 15000,
3330 .g1_irqs = 9,
3331 .g2_irqs = 10,
3332 .atu_move_port_mask = 0xf,
3333 .pvt = true,
3334 .multi_chip = true,
3335 .tag_protocol = DSA_TAG_PROTO_EDSA,
3336 .ops = &mv88e6161_ops,
3337 },
3338
3339 [MV88E6165] = {
3340 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6165,
3341 .family = MV88E6XXX_FAMILY_6165,
3342 .name = "Marvell 88E6165",
3343 .num_databases = 4096,
3344 .num_ports = 6,
3345 .max_vid = 4095,
3346 .port_base_addr = 0x10,
3347 .global1_addr = 0x1b,
3348 .global2_addr = 0x1c,
3349 .age_time_coeff = 15000,
3350 .g1_irqs = 9,
3351 .g2_irqs = 10,
3352 .atu_move_port_mask = 0xf,
3353 .pvt = true,
3354 .multi_chip = true,
3355 .tag_protocol = DSA_TAG_PROTO_DSA,
3356 .ops = &mv88e6165_ops,
3357 },
3358
3359 [MV88E6171] = {
3360 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6171,
3361 .family = MV88E6XXX_FAMILY_6351,
3362 .name = "Marvell 88E6171",
3363 .num_databases = 4096,
3364 .num_ports = 7,
3365 .max_vid = 4095,
3366 .port_base_addr = 0x10,
3367 .global1_addr = 0x1b,
3368 .global2_addr = 0x1c,
3369 .age_time_coeff = 15000,
3370 .g1_irqs = 9,
3371 .g2_irqs = 10,
3372 .atu_move_port_mask = 0xf,
3373 .pvt = true,
3374 .multi_chip = true,
3375 .tag_protocol = DSA_TAG_PROTO_EDSA,
3376 .ops = &mv88e6171_ops,
3377 },
3378
3379 [MV88E6172] = {
3380 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6172,
3381 .family = MV88E6XXX_FAMILY_6352,
3382 .name = "Marvell 88E6172",
3383 .num_databases = 4096,
3384 .num_ports = 7,
3385 .num_gpio = 15,
3386 .max_vid = 4095,
3387 .port_base_addr = 0x10,
3388 .global1_addr = 0x1b,
3389 .global2_addr = 0x1c,
3390 .age_time_coeff = 15000,
3391 .g1_irqs = 9,
3392 .g2_irqs = 10,
3393 .atu_move_port_mask = 0xf,
3394 .pvt = true,
3395 .multi_chip = true,
3396 .tag_protocol = DSA_TAG_PROTO_EDSA,
3397 .ops = &mv88e6172_ops,
3398 },
3399
3400 [MV88E6175] = {
3401 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6175,
3402 .family = MV88E6XXX_FAMILY_6351,
3403 .name = "Marvell 88E6175",
3404 .num_databases = 4096,
3405 .num_ports = 7,
3406 .max_vid = 4095,
3407 .port_base_addr = 0x10,
3408 .global1_addr = 0x1b,
3409 .global2_addr = 0x1c,
3410 .age_time_coeff = 15000,
3411 .g1_irqs = 9,
3412 .g2_irqs = 10,
3413 .atu_move_port_mask = 0xf,
3414 .pvt = true,
3415 .multi_chip = true,
3416 .tag_protocol = DSA_TAG_PROTO_EDSA,
3417 .ops = &mv88e6175_ops,
3418 },
3419
3420 [MV88E6176] = {
3421 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6176,
3422 .family = MV88E6XXX_FAMILY_6352,
3423 .name = "Marvell 88E6176",
3424 .num_databases = 4096,
3425 .num_ports = 7,
3426 .num_gpio = 15,
3427 .max_vid = 4095,
3428 .port_base_addr = 0x10,
3429 .global1_addr = 0x1b,
3430 .global2_addr = 0x1c,
3431 .age_time_coeff = 15000,
3432 .g1_irqs = 9,
3433 .g2_irqs = 10,
3434 .atu_move_port_mask = 0xf,
3435 .pvt = true,
3436 .multi_chip = true,
3437 .tag_protocol = DSA_TAG_PROTO_EDSA,
3438 .ops = &mv88e6176_ops,
3439 },
3440
3441 [MV88E6185] = {
3442 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6185,
3443 .family = MV88E6XXX_FAMILY_6185,
3444 .name = "Marvell 88E6185",
3445 .num_databases = 256,
3446 .num_ports = 10,
3447 .max_vid = 4095,
3448 .port_base_addr = 0x10,
3449 .global1_addr = 0x1b,
3450 .global2_addr = 0x1c,
3451 .age_time_coeff = 15000,
3452 .g1_irqs = 8,
3453 .atu_move_port_mask = 0xf,
3454 .multi_chip = true,
3455 .tag_protocol = DSA_TAG_PROTO_EDSA,
3456 .ops = &mv88e6185_ops,
3457 },
3458
3459 [MV88E6190] = {
3460 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190,
3461 .family = MV88E6XXX_FAMILY_6390,
3462 .name = "Marvell 88E6190",
3463 .num_databases = 4096,
3464 .num_ports = 11, /* 10 + Z80 */
3465 .num_gpio = 16,
3466 .max_vid = 8191,
3467 .port_base_addr = 0x0,
3468 .global1_addr = 0x1b,
3469 .global2_addr = 0x1c,
3470 .tag_protocol = DSA_TAG_PROTO_DSA,
3471 .age_time_coeff = 3750,
3472 .g1_irqs = 9,
3473 .g2_irqs = 14,
3474 .pvt = true,
3475 .multi_chip = true,
3476 .atu_move_port_mask = 0x1f,
3477 .ops = &mv88e6190_ops,
3478 },
3479
3480 [MV88E6190X] = {
3481 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190X,
3482 .family = MV88E6XXX_FAMILY_6390,
3483 .name = "Marvell 88E6190X",
3484 .num_databases = 4096,
3485 .num_ports = 11, /* 10 + Z80 */
3486 .num_gpio = 16,
3487 .max_vid = 8191,
3488 .port_base_addr = 0x0,
3489 .global1_addr = 0x1b,
3490 .global2_addr = 0x1c,
3491 .age_time_coeff = 3750,
3492 .g1_irqs = 9,
3493 .g2_irqs = 14,
3494 .atu_move_port_mask = 0x1f,
3495 .pvt = true,
3496 .multi_chip = true,
3497 .tag_protocol = DSA_TAG_PROTO_DSA,
3498 .ops = &mv88e6190x_ops,
3499 },
3500
3501 [MV88E6191] = {
3502 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6191,
3503 .family = MV88E6XXX_FAMILY_6390,
3504 .name = "Marvell 88E6191",
3505 .num_databases = 4096,
3506 .num_ports = 11, /* 10 + Z80 */
3507 .max_vid = 8191,
3508 .port_base_addr = 0x0,
3509 .global1_addr = 0x1b,
3510 .global2_addr = 0x1c,
3511 .age_time_coeff = 3750,
3512 .g1_irqs = 9,
3513 .g2_irqs = 14,
3514 .atu_move_port_mask = 0x1f,
3515 .pvt = true,
3516 .multi_chip = true,
3517 .tag_protocol = DSA_TAG_PROTO_DSA,
3518 .ptp_support = true,
3519 .ops = &mv88e6191_ops,
3520 },
3521
3522 [MV88E6240] = {
3523 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6240,
3524 .family = MV88E6XXX_FAMILY_6352,
3525 .name = "Marvell 88E6240",
3526 .num_databases = 4096,
3527 .num_ports = 7,
3528 .num_gpio = 15,
3529 .max_vid = 4095,
3530 .port_base_addr = 0x10,
3531 .global1_addr = 0x1b,
3532 .global2_addr = 0x1c,
3533 .age_time_coeff = 15000,
3534 .g1_irqs = 9,
3535 .g2_irqs = 10,
3536 .atu_move_port_mask = 0xf,
3537 .pvt = true,
3538 .multi_chip = true,
3539 .tag_protocol = DSA_TAG_PROTO_EDSA,
3540 .ptp_support = true,
3541 .ops = &mv88e6240_ops,
3542 },
3543
3544 [MV88E6290] = {
3545 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6290,
3546 .family = MV88E6XXX_FAMILY_6390,
3547 .name = "Marvell 88E6290",
3548 .num_databases = 4096,
3549 .num_ports = 11, /* 10 + Z80 */
3550 .num_gpio = 16,
3551 .max_vid = 8191,
3552 .port_base_addr = 0x0,
3553 .global1_addr = 0x1b,
3554 .global2_addr = 0x1c,
3555 .age_time_coeff = 3750,
3556 .g1_irqs = 9,
3557 .g2_irqs = 14,
3558 .atu_move_port_mask = 0x1f,
3559 .pvt = true,
3560 .multi_chip = true,
3561 .tag_protocol = DSA_TAG_PROTO_DSA,
3562 .ptp_support = true,
3563 .ops = &mv88e6290_ops,
3564 },
3565
3566 [MV88E6320] = {
3567 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6320,
3568 .family = MV88E6XXX_FAMILY_6320,
3569 .name = "Marvell 88E6320",
3570 .num_databases = 4096,
3571 .num_ports = 7,
3572 .num_gpio = 15,
3573 .max_vid = 4095,
3574 .port_base_addr = 0x10,
3575 .global1_addr = 0x1b,
3576 .global2_addr = 0x1c,
3577 .age_time_coeff = 15000,
3578 .g1_irqs = 8,
3579 .atu_move_port_mask = 0xf,
3580 .pvt = true,
3581 .multi_chip = true,
3582 .tag_protocol = DSA_TAG_PROTO_EDSA,
3583 .ptp_support = true,
3584 .ops = &mv88e6320_ops,
3585 },
3586
3587 [MV88E6321] = {
3588 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6321,
3589 .family = MV88E6XXX_FAMILY_6320,
3590 .name = "Marvell 88E6321",
3591 .num_databases = 4096,
3592 .num_ports = 7,
3593 .num_gpio = 15,
3594 .max_vid = 4095,
3595 .port_base_addr = 0x10,
3596 .global1_addr = 0x1b,
3597 .global2_addr = 0x1c,
3598 .age_time_coeff = 15000,
3599 .g1_irqs = 8,
3600 .atu_move_port_mask = 0xf,
3601 .multi_chip = true,
3602 .tag_protocol = DSA_TAG_PROTO_EDSA,
3603 .ptp_support = true,
3604 .ops = &mv88e6321_ops,
3605 },
3606
3607 [MV88E6341] = {
3608 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
3609 .family = MV88E6XXX_FAMILY_6341,
3610 .name = "Marvell 88E6341",
3611 .num_databases = 4096,
3612 .num_ports = 6,
3613 .num_gpio = 11,
3614 .max_vid = 4095,
3615 .port_base_addr = 0x10,
3616 .global1_addr = 0x1b,
3617 .global2_addr = 0x1c,
3618 .age_time_coeff = 3750,
3619 .atu_move_port_mask = 0x1f,
3620 .g2_irqs = 10,
3621 .pvt = true,
3622 .multi_chip = true,
3623 .tag_protocol = DSA_TAG_PROTO_EDSA,
3624 .ptp_support = true,
3625 .ops = &mv88e6341_ops,
3626 },
3627
3628 [MV88E6350] = {
3629 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6350,
3630 .family = MV88E6XXX_FAMILY_6351,
3631 .name = "Marvell 88E6350",
3632 .num_databases = 4096,
3633 .num_ports = 7,
3634 .max_vid = 4095,
3635 .port_base_addr = 0x10,
3636 .global1_addr = 0x1b,
3637 .global2_addr = 0x1c,
3638 .age_time_coeff = 15000,
3639 .g1_irqs = 9,
3640 .g2_irqs = 10,
3641 .atu_move_port_mask = 0xf,
3642 .pvt = true,
3643 .multi_chip = true,
3644 .tag_protocol = DSA_TAG_PROTO_EDSA,
3645 .ops = &mv88e6350_ops,
3646 },
3647
3648 [MV88E6351] = {
3649 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6351,
3650 .family = MV88E6XXX_FAMILY_6351,
3651 .name = "Marvell 88E6351",
3652 .num_databases = 4096,
3653 .num_ports = 7,
3654 .max_vid = 4095,
3655 .port_base_addr = 0x10,
3656 .global1_addr = 0x1b,
3657 .global2_addr = 0x1c,
3658 .age_time_coeff = 15000,
3659 .g1_irqs = 9,
3660 .g2_irqs = 10,
3661 .atu_move_port_mask = 0xf,
3662 .pvt = true,
3663 .multi_chip = true,
3664 .tag_protocol = DSA_TAG_PROTO_EDSA,
3665 .ops = &mv88e6351_ops,
3666 },
3667
3668 [MV88E6352] = {
3669 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6352,
3670 .family = MV88E6XXX_FAMILY_6352,
3671 .name = "Marvell 88E6352",
3672 .num_databases = 4096,
3673 .num_ports = 7,
3674 .num_gpio = 15,
3675 .max_vid = 4095,
3676 .port_base_addr = 0x10,
3677 .global1_addr = 0x1b,
3678 .global2_addr = 0x1c,
3679 .age_time_coeff = 15000,
3680 .g1_irqs = 9,
3681 .g2_irqs = 10,
3682 .atu_move_port_mask = 0xf,
3683 .pvt = true,
3684 .multi_chip = true,
3685 .tag_protocol = DSA_TAG_PROTO_EDSA,
3686 .ptp_support = true,
3687 .ops = &mv88e6352_ops,
3688 },
3689 [MV88E6390] = {
3690 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
3691 .family = MV88E6XXX_FAMILY_6390,
3692 .name = "Marvell 88E6390",
3693 .num_databases = 4096,
3694 .num_ports = 11, /* 10 + Z80 */
3695 .num_gpio = 16,
3696 .max_vid = 8191,
3697 .port_base_addr = 0x0,
3698 .global1_addr = 0x1b,
3699 .global2_addr = 0x1c,
3700 .age_time_coeff = 3750,
3701 .g1_irqs = 9,
3702 .g2_irqs = 14,
3703 .atu_move_port_mask = 0x1f,
3704 .pvt = true,
3705 .multi_chip = true,
3706 .tag_protocol = DSA_TAG_PROTO_DSA,
3707 .ptp_support = true,
3708 .ops = &mv88e6390_ops,
3709 },
3710 [MV88E6390X] = {
3711 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390X,
3712 .family = MV88E6XXX_FAMILY_6390,
3713 .name = "Marvell 88E6390X",
3714 .num_databases = 4096,
3715 .num_ports = 11, /* 10 + Z80 */
3716 .num_gpio = 16,
3717 .max_vid = 8191,
3718 .port_base_addr = 0x0,
3719 .global1_addr = 0x1b,
3720 .global2_addr = 0x1c,
3721 .age_time_coeff = 3750,
3722 .g1_irqs = 9,
3723 .g2_irqs = 14,
3724 .atu_move_port_mask = 0x1f,
3725 .pvt = true,
3726 .multi_chip = true,
3727 .tag_protocol = DSA_TAG_PROTO_DSA,
3728 .ptp_support = true,
3729 .ops = &mv88e6390x_ops,
3730 },
3731 };
3732
3733 static const struct mv88e6xxx_info *mv88e6xxx_lookup_info(unsigned int prod_num)
3734 {
3735 int i;
3736
3737 for (i = 0; i < ARRAY_SIZE(mv88e6xxx_table); ++i)
3738 if (mv88e6xxx_table[i].prod_num == prod_num)
3739 return &mv88e6xxx_table[i];
3740
3741 return NULL;
3742 }
3743
3744 static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip)
3745 {
3746 const struct mv88e6xxx_info *info;
3747 unsigned int prod_num, rev;
3748 u16 id;
3749 int err;
3750
3751 mutex_lock(&chip->reg_lock);
3752 err = mv88e6xxx_port_read(chip, 0, MV88E6XXX_PORT_SWITCH_ID, &id);
3753 mutex_unlock(&chip->reg_lock);
3754 if (err)
3755 return err;
3756
3757 prod_num = id & MV88E6XXX_PORT_SWITCH_ID_PROD_MASK;
3758 rev = id & MV88E6XXX_PORT_SWITCH_ID_REV_MASK;
3759
3760 info = mv88e6xxx_lookup_info(prod_num);
3761 if (!info)
3762 return -ENODEV;
3763
3764 /* Update the compatible info with the probed one */
3765 chip->info = info;
3766
3767 err = mv88e6xxx_g2_require(chip);
3768 if (err)
3769 return err;
3770
3771 dev_info(chip->dev, "switch 0x%x detected: %s, revision %u\n",
3772 chip->info->prod_num, chip->info->name, rev);
3773
3774 return 0;
3775 }
3776
3777 static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev)
3778 {
3779 struct mv88e6xxx_chip *chip;
3780
3781 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
3782 if (!chip)
3783 return NULL;
3784
3785 chip->dev = dev;
3786
3787 mutex_init(&chip->reg_lock);
3788 INIT_LIST_HEAD(&chip->mdios);
3789
3790 return chip;
3791 }
3792
3793 static int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip,
3794 struct mii_bus *bus, int sw_addr)
3795 {
3796 if (sw_addr == 0)
3797 chip->smi_ops = &mv88e6xxx_smi_single_chip_ops;
3798 else if (chip->info->multi_chip)
3799 chip->smi_ops = &mv88e6xxx_smi_multi_chip_ops;
3800 else
3801 return -EINVAL;
3802
3803 chip->bus = bus;
3804 chip->sw_addr = sw_addr;
3805
3806 return 0;
3807 }
3808
3809 static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds,
3810 int port)
3811 {
3812 struct mv88e6xxx_chip *chip = ds->priv;
3813
3814 return chip->info->tag_protocol;
3815 }
3816
3817 #if IS_ENABLED(CONFIG_NET_DSA_LEGACY)
3818 static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
3819 struct device *host_dev, int sw_addr,
3820 void **priv)
3821 {
3822 struct mv88e6xxx_chip *chip;
3823 struct mii_bus *bus;
3824 int err;
3825
3826 bus = dsa_host_dev_to_mii_bus(host_dev);
3827 if (!bus)
3828 return NULL;
3829
3830 chip = mv88e6xxx_alloc_chip(dsa_dev);
3831 if (!chip)
3832 return NULL;
3833
3834 /* Legacy SMI probing will only support chips similar to 88E6085 */
3835 chip->info = &mv88e6xxx_table[MV88E6085];
3836
3837 err = mv88e6xxx_smi_init(chip, bus, sw_addr);
3838 if (err)
3839 goto free;
3840
3841 err = mv88e6xxx_detect(chip);
3842 if (err)
3843 goto free;
3844
3845 mutex_lock(&chip->reg_lock);
3846 err = mv88e6xxx_switch_reset(chip);
3847 mutex_unlock(&chip->reg_lock);
3848 if (err)
3849 goto free;
3850
3851 mv88e6xxx_phy_init(chip);
3852
3853 err = mv88e6xxx_mdios_register(chip, NULL);
3854 if (err)
3855 goto free;
3856
3857 *priv = chip;
3858
3859 return chip->info->name;
3860 free:
3861 devm_kfree(dsa_dev, chip);
3862
3863 return NULL;
3864 }
3865 #endif
3866
3867 static int mv88e6xxx_port_mdb_prepare(struct dsa_switch *ds, int port,
3868 const struct switchdev_obj_port_mdb *mdb)
3869 {
3870 /* We don't need any dynamic resource from the kernel (yet),
3871 * so skip the prepare phase.
3872 */
3873
3874 return 0;
3875 }
3876
3877 static void mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port,
3878 const struct switchdev_obj_port_mdb *mdb)
3879 {
3880 struct mv88e6xxx_chip *chip = ds->priv;
3881
3882 mutex_lock(&chip->reg_lock);
3883 if (mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
3884 MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC))
3885 dev_err(ds->dev, "p%d: failed to load multicast MAC address\n",
3886 port);
3887 mutex_unlock(&chip->reg_lock);
3888 }
3889
3890 static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port,
3891 const struct switchdev_obj_port_mdb *mdb)
3892 {
3893 struct mv88e6xxx_chip *chip = ds->priv;
3894 int err;
3895
3896 mutex_lock(&chip->reg_lock);
3897 err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
3898 MV88E6XXX_G1_ATU_DATA_STATE_UNUSED);
3899 mutex_unlock(&chip->reg_lock);
3900
3901 return err;
3902 }
3903
3904 static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
3905 #if IS_ENABLED(CONFIG_NET_DSA_LEGACY)
3906 .probe = mv88e6xxx_drv_probe,
3907 #endif
3908 .get_tag_protocol = mv88e6xxx_get_tag_protocol,
3909 .setup = mv88e6xxx_setup,
3910 .adjust_link = mv88e6xxx_adjust_link,
3911 .get_strings = mv88e6xxx_get_strings,
3912 .get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
3913 .get_sset_count = mv88e6xxx_get_sset_count,
3914 .port_enable = mv88e6xxx_port_enable,
3915 .port_disable = mv88e6xxx_port_disable,
3916 .get_mac_eee = mv88e6xxx_get_mac_eee,
3917 .set_mac_eee = mv88e6xxx_set_mac_eee,
3918 .get_eeprom_len = mv88e6xxx_get_eeprom_len,
3919 .get_eeprom = mv88e6xxx_get_eeprom,
3920 .set_eeprom = mv88e6xxx_set_eeprom,
3921 .get_regs_len = mv88e6xxx_get_regs_len,
3922 .get_regs = mv88e6xxx_get_regs,
3923 .set_ageing_time = mv88e6xxx_set_ageing_time,
3924 .port_bridge_join = mv88e6xxx_port_bridge_join,
3925 .port_bridge_leave = mv88e6xxx_port_bridge_leave,
3926 .port_stp_state_set = mv88e6xxx_port_stp_state_set,
3927 .port_fast_age = mv88e6xxx_port_fast_age,
3928 .port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
3929 .port_vlan_prepare = mv88e6xxx_port_vlan_prepare,
3930 .port_vlan_add = mv88e6xxx_port_vlan_add,
3931 .port_vlan_del = mv88e6xxx_port_vlan_del,
3932 .port_fdb_add = mv88e6xxx_port_fdb_add,
3933 .port_fdb_del = mv88e6xxx_port_fdb_del,
3934 .port_fdb_dump = mv88e6xxx_port_fdb_dump,
3935 .port_mdb_prepare = mv88e6xxx_port_mdb_prepare,
3936 .port_mdb_add = mv88e6xxx_port_mdb_add,
3937 .port_mdb_del = mv88e6xxx_port_mdb_del,
3938 .crosschip_bridge_join = mv88e6xxx_crosschip_bridge_join,
3939 .crosschip_bridge_leave = mv88e6xxx_crosschip_bridge_leave,
3940 .port_hwtstamp_set = mv88e6xxx_port_hwtstamp_set,
3941 .port_hwtstamp_get = mv88e6xxx_port_hwtstamp_get,
3942 .port_txtstamp = mv88e6xxx_port_txtstamp,
3943 .port_rxtstamp = mv88e6xxx_port_rxtstamp,
3944 .get_ts_info = mv88e6xxx_get_ts_info,
3945 };
3946
3947 static struct dsa_switch_driver mv88e6xxx_switch_drv = {
3948 .ops = &mv88e6xxx_switch_ops,
3949 };
3950
3951 static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
3952 {
3953 struct device *dev = chip->dev;
3954 struct dsa_switch *ds;
3955
3956 ds = dsa_switch_alloc(dev, mv88e6xxx_num_ports(chip));
3957 if (!ds)
3958 return -ENOMEM;
3959
3960 ds->priv = chip;
3961 ds->ops = &mv88e6xxx_switch_ops;
3962 ds->ageing_time_min = chip->info->age_time_coeff;
3963 ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
3964
3965 dev_set_drvdata(dev, ds);
3966
3967 return dsa_register_switch(ds);
3968 }
3969
3970 static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip)
3971 {
3972 dsa_unregister_switch(chip->ds);
3973 }
3974
3975 static int mv88e6xxx_probe(struct mdio_device *mdiodev)
3976 {
3977 struct device *dev = &mdiodev->dev;
3978 struct device_node *np = dev->of_node;
3979 const struct mv88e6xxx_info *compat_info;
3980 struct mv88e6xxx_chip *chip;
3981 u32 eeprom_len;
3982 int err;
3983
3984 compat_info = of_device_get_match_data(dev);
3985 if (!compat_info)
3986 return -EINVAL;
3987
3988 chip = mv88e6xxx_alloc_chip(dev);
3989 if (!chip)
3990 return -ENOMEM;
3991
3992 chip->info = compat_info;
3993
3994 err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
3995 if (err)
3996 return err;
3997
3998 chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
3999 if (IS_ERR(chip->reset))
4000 return PTR_ERR(chip->reset);
4001
4002 err = mv88e6xxx_detect(chip);
4003 if (err)
4004 return err;
4005
4006 mv88e6xxx_phy_init(chip);
4007
4008 if (chip->info->ops->get_eeprom &&
4009 !of_property_read_u32(np, "eeprom-length", &eeprom_len))
4010 chip->eeprom_len = eeprom_len;
4011
4012 mutex_lock(&chip->reg_lock);
4013 err = mv88e6xxx_switch_reset(chip);
4014 mutex_unlock(&chip->reg_lock);
4015 if (err)
4016 goto out;
4017
4018 chip->irq = of_irq_get(np, 0);
4019 if (chip->irq == -EPROBE_DEFER) {
4020 err = chip->irq;
4021 goto out;
4022 }
4023
4024 if (chip->irq > 0) {
4025 /* Has to be performed before the MDIO bus is created,
4026 * because the PHYs will link there interrupts to these
4027 * interrupt controllers
4028 */
4029 mutex_lock(&chip->reg_lock);
4030 err = mv88e6xxx_g1_irq_setup(chip);
4031 mutex_unlock(&chip->reg_lock);
4032
4033 if (err)
4034 goto out;
4035
4036 if (chip->info->g2_irqs > 0) {
4037 err = mv88e6xxx_g2_irq_setup(chip);
4038 if (err)
4039 goto out_g1_irq;
4040 }
4041
4042 err = mv88e6xxx_g1_atu_prob_irq_setup(chip);
4043 if (err)
4044 goto out_g2_irq;
4045
4046 err = mv88e6xxx_g1_vtu_prob_irq_setup(chip);
4047 if (err)
4048 goto out_g1_atu_prob_irq;
4049 }
4050
4051 err = mv88e6xxx_mdios_register(chip, np);
4052 if (err)
4053 goto out_g1_vtu_prob_irq;
4054
4055 err = mv88e6xxx_register_switch(chip);
4056 if (err)
4057 goto out_mdio;
4058
4059 return 0;
4060
4061 out_mdio:
4062 mv88e6xxx_mdios_unregister(chip);
4063 out_g1_vtu_prob_irq:
4064 if (chip->irq > 0)
4065 mv88e6xxx_g1_vtu_prob_irq_free(chip);
4066 out_g1_atu_prob_irq:
4067 if (chip->irq > 0)
4068 mv88e6xxx_g1_atu_prob_irq_free(chip);
4069 out_g2_irq:
4070 if (chip->info->g2_irqs > 0 && chip->irq > 0)
4071 mv88e6xxx_g2_irq_free(chip);
4072 out_g1_irq:
4073 if (chip->irq > 0) {
4074 mutex_lock(&chip->reg_lock);
4075 mv88e6xxx_g1_irq_free(chip);
4076 mutex_unlock(&chip->reg_lock);
4077 }
4078 out:
4079 return err;
4080 }
4081
4082 static void mv88e6xxx_remove(struct mdio_device *mdiodev)
4083 {
4084 struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
4085 struct mv88e6xxx_chip *chip = ds->priv;
4086
4087 if (chip->info->ptp_support) {
4088 mv88e6xxx_hwtstamp_free(chip);
4089 mv88e6xxx_ptp_free(chip);
4090 }
4091
4092 mv88e6xxx_phy_destroy(chip);
4093 mv88e6xxx_unregister_switch(chip);
4094 mv88e6xxx_mdios_unregister(chip);
4095
4096 if (chip->irq > 0) {
4097 mv88e6xxx_g1_vtu_prob_irq_free(chip);
4098 mv88e6xxx_g1_atu_prob_irq_free(chip);
4099 if (chip->info->g2_irqs > 0)
4100 mv88e6xxx_g2_irq_free(chip);
4101 mutex_lock(&chip->reg_lock);
4102 mv88e6xxx_g1_irq_free(chip);
4103 mutex_unlock(&chip->reg_lock);
4104 }
4105 }
4106
4107 static const struct of_device_id mv88e6xxx_of_match[] = {
4108 {
4109 .compatible = "marvell,mv88e6085",
4110 .data = &mv88e6xxx_table[MV88E6085],
4111 },
4112 {
4113 .compatible = "marvell,mv88e6190",
4114 .data = &mv88e6xxx_table[MV88E6190],
4115 },
4116 { /* sentinel */ },
4117 };
4118
4119 MODULE_DEVICE_TABLE(of, mv88e6xxx_of_match);
4120
4121 static struct mdio_driver mv88e6xxx_driver = {
4122 .probe = mv88e6xxx_probe,
4123 .remove = mv88e6xxx_remove,
4124 .mdiodrv.driver = {
4125 .name = "mv88e6085",
4126 .of_match_table = mv88e6xxx_of_match,
4127 },
4128 };
4129
4130 static int __init mv88e6xxx_init(void)
4131 {
4132 register_switch_driver(&mv88e6xxx_switch_drv);
4133 return mdio_driver_register(&mv88e6xxx_driver);
4134 }
4135 module_init(mv88e6xxx_init);
4136
4137 static void __exit mv88e6xxx_cleanup(void)
4138 {
4139 mdio_driver_unregister(&mv88e6xxx_driver);
4140 unregister_switch_driver(&mv88e6xxx_switch_drv);
4141 }
4142 module_exit(mv88e6xxx_cleanup);
4143
4144 MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
4145 MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
4146 MODULE_LICENSE("GPL");