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