OSDN Git Service

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