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