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