1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Marvell 88e6xxx Ethernet switch single-chip support
4 *
5 * Copyright (c) 2008 Marvell Semiconductor
6 *
7 * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch>
8 *
9 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
10 *	Vivien Didelot <vivien.didelot@savoirfairelinux.com>
11 */
12
13#include <linux/bitfield.h>
14#include <linux/delay.h>
15#include <linux/etherdevice.h>
16#include <linux/ethtool.h>
17#include <linux/if_bridge.h>
18#include <linux/interrupt.h>
19#include <linux/irq.h>
20#include <linux/irqdomain.h>
21#include <linux/jiffies.h>
22#include <linux/list.h>
23#include <linux/mdio.h>
24#include <linux/module.h>
25#include <linux/of_device.h>
26#include <linux/of_irq.h>
27#include <linux/of_mdio.h>
28#include <linux/platform_data/mv88e6xxx.h>
29#include <linux/netdevice.h>
30#include <linux/gpio/consumer.h>
31#include <linux/phylink.h>
32#include <net/dsa.h>
33
34#include "chip.h"
35#include "devlink.h"
36#include "global1.h"
37#include "global2.h"
38#include "hwtstamp.h"
39#include "phy.h"
40#include "port.h"
41#include "ptp.h"
42#include "serdes.h"
43#include "smi.h"
44
45static 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
53int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val)
54{
55	int err;
56
57	assert_reg_lock(chip);
58
59	err = mv88e6xxx_smi_read(chip, addr, reg, val);
60	if (err)
61		return err;
62
63	dev_dbg(chip->dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
64		addr, reg, *val);
65
66	return 0;
67}
68
69int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val)
70{
71	int err;
72
73	assert_reg_lock(chip);
74
75	err = mv88e6xxx_smi_write(chip, addr, reg, val);
76	if (err)
77		return err;
78
79	dev_dbg(chip->dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
80		addr, reg, val);
81
82	return 0;
83}
84
85int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
86			u16 mask, u16 val)
87{
88	u16 data;
89	int err;
90	int i;
91
92	/* There's no bus specific operation to wait for a mask */
93	for (i = 0; i < 16; i++) {
94		err = mv88e6xxx_read(chip, addr, reg, &data);
95		if (err)
96			return err;
97
98		if ((data & mask) == val)
99			return 0;
100
101		usleep_range(1000, 2000);
102	}
103
104	dev_err(chip->dev, "Timeout while waiting for switch\n");
105	return -ETIMEDOUT;
106}
107
108int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,
109		       int bit, int val)
110{
111	return mv88e6xxx_wait_mask(chip, addr, reg, BIT(bit),
112				   val ? BIT(bit) : 0x0000);
113}
114
115struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip)
116{
117	struct mv88e6xxx_mdio_bus *mdio_bus;
118
119	mdio_bus = list_first_entry(&chip->mdios, struct mv88e6xxx_mdio_bus,
120				    list);
121	if (!mdio_bus)
122		return NULL;
123
124	return mdio_bus->bus;
125}
126
127static void mv88e6xxx_g1_irq_mask(struct irq_data *d)
128{
129	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
130	unsigned int n = d->hwirq;
131
132	chip->g1_irq.masked |= (1 << n);
133}
134
135static void mv88e6xxx_g1_irq_unmask(struct irq_data *d)
136{
137	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
138	unsigned int n = d->hwirq;
139
140	chip->g1_irq.masked &= ~(1 << n);
141}
142
143static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct mv88e6xxx_chip *chip)
144{
145	unsigned int nhandled = 0;
146	unsigned int sub_irq;
147	unsigned int n;
148	u16 reg;
149	u16 ctl1;
150	int err;
151
152	mv88e6xxx_reg_lock(chip);
153	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
154	mv88e6xxx_reg_unlock(chip);
155
156	if (err)
157		goto out;
158
159	do {
160		for (n = 0; n < chip->g1_irq.nirqs; ++n) {
161			if (reg & (1 << n)) {
162				sub_irq = irq_find_mapping(chip->g1_irq.domain,
163							   n);
164				handle_nested_irq(sub_irq);
165				++nhandled;
166			}
167		}
168
169		mv88e6xxx_reg_lock(chip);
170		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &ctl1);
171		if (err)
172			goto unlock;
173		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
174unlock:
175		mv88e6xxx_reg_unlock(chip);
176		if (err)
177			goto out;
178		ctl1 &= GENMASK(chip->g1_irq.nirqs, 0);
179	} while (reg & ctl1);
180
181out:
182	return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
183}
184
185static irqreturn_t mv88e6xxx_g1_irq_thread_fn(int irq, void *dev_id)
186{
187	struct mv88e6xxx_chip *chip = dev_id;
188
189	return mv88e6xxx_g1_irq_thread_work(chip);
190}
191
192static void mv88e6xxx_g1_irq_bus_lock(struct irq_data *d)
193{
194	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
195
196	mv88e6xxx_reg_lock(chip);
197}
198
199static void mv88e6xxx_g1_irq_bus_sync_unlock(struct irq_data *d)
200{
201	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
202	u16 mask = GENMASK(chip->g1_irq.nirqs, 0);
203	u16 reg;
204	int err;
205
206	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &reg);
207	if (err)
208		goto out;
209
210	reg &= ~mask;
211	reg |= (~chip->g1_irq.masked & mask);
212
213	err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, reg);
214	if (err)
215		goto out;
216
217out:
218	mv88e6xxx_reg_unlock(chip);
219}
220
221static const struct irq_chip mv88e6xxx_g1_irq_chip = {
222	.name			= "mv88e6xxx-g1",
223	.irq_mask		= mv88e6xxx_g1_irq_mask,
224	.irq_unmask		= mv88e6xxx_g1_irq_unmask,
225	.irq_bus_lock		= mv88e6xxx_g1_irq_bus_lock,
226	.irq_bus_sync_unlock	= mv88e6xxx_g1_irq_bus_sync_unlock,
227};
228
229static int mv88e6xxx_g1_irq_domain_map(struct irq_domain *d,
230				       unsigned int irq,
231				       irq_hw_number_t hwirq)
232{
233	struct mv88e6xxx_chip *chip = d->host_data;
234
235	irq_set_chip_data(irq, d->host_data);
236	irq_set_chip_and_handler(irq, &chip->g1_irq.chip, handle_level_irq);
237	irq_set_noprobe(irq);
238
239	return 0;
240}
241
242static const struct irq_domain_ops mv88e6xxx_g1_irq_domain_ops = {
243	.map	= mv88e6xxx_g1_irq_domain_map,
244	.xlate	= irq_domain_xlate_twocell,
245};
246
247/* To be called with reg_lock held */
248static void mv88e6xxx_g1_irq_free_common(struct mv88e6xxx_chip *chip)
249{
250	int irq, virq;
251	u16 mask;
252
253	mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
254	mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
255	mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
256
257	for (irq = 0; irq < chip->g1_irq.nirqs; irq++) {
258		virq = irq_find_mapping(chip->g1_irq.domain, irq);
259		irq_dispose_mapping(virq);
260	}
261
262	irq_domain_remove(chip->g1_irq.domain);
263}
264
265static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip)
266{
267	/*
268	 * free_irq must be called without reg_lock taken because the irq
269	 * handler takes this lock, too.
270	 */
271	free_irq(chip->irq, chip);
272
273	mv88e6xxx_reg_lock(chip);
274	mv88e6xxx_g1_irq_free_common(chip);
275	mv88e6xxx_reg_unlock(chip);
276}
277
278static int mv88e6xxx_g1_irq_setup_common(struct mv88e6xxx_chip *chip)
279{
280	int err, irq, virq;
281	u16 reg, mask;
282
283	chip->g1_irq.nirqs = chip->info->g1_irqs;
284	chip->g1_irq.domain = irq_domain_add_simple(
285		NULL, chip->g1_irq.nirqs, 0,
286		&mv88e6xxx_g1_irq_domain_ops, chip);
287	if (!chip->g1_irq.domain)
288		return -ENOMEM;
289
290	for (irq = 0; irq < chip->g1_irq.nirqs; irq++)
291		irq_create_mapping(chip->g1_irq.domain, irq);
292
293	chip->g1_irq.chip = mv88e6xxx_g1_irq_chip;
294	chip->g1_irq.masked = ~0;
295
296	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
297	if (err)
298		goto out_mapping;
299
300	mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
301
302	err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
303	if (err)
304		goto out_disable;
305
306	/* Reading the interrupt status clears (most of) them */
307	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
308	if (err)
309		goto out_disable;
310
311	return 0;
312
313out_disable:
314	mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
315	mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
316
317out_mapping:
318	for (irq = 0; irq < 16; irq++) {
319		virq = irq_find_mapping(chip->g1_irq.domain, irq);
320		irq_dispose_mapping(virq);
321	}
322
323	irq_domain_remove(chip->g1_irq.domain);
324
325	return err;
326}
327
328static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip)
329{
330	static struct lock_class_key lock_key;
331	static struct lock_class_key request_key;
332	int err;
333
334	err = mv88e6xxx_g1_irq_setup_common(chip);
335	if (err)
336		return err;
337
338	/* These lock classes tells lockdep that global 1 irqs are in
339	 * a different category than their parent GPIO, so it won't
340	 * report false recursion.
341	 */
342	irq_set_lockdep_class(chip->irq, &lock_key, &request_key);
343
344	snprintf(chip->irq_name, sizeof(chip->irq_name),
345		 "mv88e6xxx-%s", dev_name(chip->dev));
346
347	mv88e6xxx_reg_unlock(chip);
348	err = request_threaded_irq(chip->irq, NULL,
349				   mv88e6xxx_g1_irq_thread_fn,
350				   IRQF_ONESHOT | IRQF_SHARED,
351				   chip->irq_name, chip);
352	mv88e6xxx_reg_lock(chip);
353	if (err)
354		mv88e6xxx_g1_irq_free_common(chip);
355
356	return err;
357}
358
359static void mv88e6xxx_irq_poll(struct kthread_work *work)
360{
361	struct mv88e6xxx_chip *chip = container_of(work,
362						   struct mv88e6xxx_chip,
363						   irq_poll_work.work);
364	mv88e6xxx_g1_irq_thread_work(chip);
365
366	kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work,
367				   msecs_to_jiffies(100));
368}
369
370static int mv88e6xxx_irq_poll_setup(struct mv88e6xxx_chip *chip)
371{
372	int err;
373
374	err = mv88e6xxx_g1_irq_setup_common(chip);
375	if (err)
376		return err;
377
378	kthread_init_delayed_work(&chip->irq_poll_work,
379				  mv88e6xxx_irq_poll);
380
381	chip->kworker = kthread_create_worker(0, "%s", dev_name(chip->dev));
382	if (IS_ERR(chip->kworker))
383		return PTR_ERR(chip->kworker);
384
385	kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work,
386				   msecs_to_jiffies(100));
387
388	return 0;
389}
390
391static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip)
392{
393	kthread_cancel_delayed_work_sync(&chip->irq_poll_work);
394	kthread_destroy_worker(chip->kworker);
395
396	mv88e6xxx_reg_lock(chip);
397	mv88e6xxx_g1_irq_free_common(chip);
398	mv88e6xxx_reg_unlock(chip);
399}
400
401static int mv88e6xxx_port_config_interface(struct mv88e6xxx_chip *chip,
402					   int port, phy_interface_t interface)
403{
404	int err;
405
406	if (chip->info->ops->port_set_rgmii_delay) {
407		err = chip->info->ops->port_set_rgmii_delay(chip, port,
408							    interface);
409		if (err && err != -EOPNOTSUPP)
410			return err;
411	}
412
413	if (chip->info->ops->port_set_cmode) {
414		err = chip->info->ops->port_set_cmode(chip, port,
415						      interface);
416		if (err && err != -EOPNOTSUPP)
417			return err;
418	}
419
420	return 0;
421}
422
423static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port,
424				    int link, int speed, int duplex, int pause,
425				    phy_interface_t mode)
426{
427	int err;
428
429	if (!chip->info->ops->port_set_link)
430		return 0;
431
432	/* Port's MAC control must not be changed unless the link is down */
433	err = chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN);
434	if (err)
435		return err;
436
437	if (chip->info->ops->port_set_speed_duplex) {
438		err = chip->info->ops->port_set_speed_duplex(chip, port,
439							     speed, duplex);
440		if (err && err != -EOPNOTSUPP)
441			goto restore_link;
442	}
443
444	if (speed == SPEED_MAX && chip->info->ops->port_max_speed_mode)
445		mode = chip->info->ops->port_max_speed_mode(port);
446
447	if (chip->info->ops->port_set_pause) {
448		err = chip->info->ops->port_set_pause(chip, port, pause);
449		if (err)
450			goto restore_link;
451	}
452
453	err = mv88e6xxx_port_config_interface(chip, port, mode);
454restore_link:
455	if (chip->info->ops->port_set_link(chip, port, link))
456		dev_err(chip->dev, "p%d: failed to restore MAC's link\n", port);
457
458	return err;
459}
460
461static int mv88e6xxx_phy_is_internal(struct dsa_switch *ds, int port)
462{
463	struct mv88e6xxx_chip *chip = ds->priv;
464
465	return port < chip->info->num_internal_phys;
466}
467
468static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port)
469{
470	u16 reg;
471	int err;
472
473	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
474	if (err) {
475		dev_err(chip->dev,
476			"p%d: %s: failed to read port status\n",
477			port, __func__);
478		return err;
479	}
480
481	return !!(reg & MV88E6XXX_PORT_STS_PHY_DETECT);
482}
483
484static int mv88e6xxx_serdes_pcs_get_state(struct dsa_switch *ds, int port,
485					  struct phylink_link_state *state)
486{
487	struct mv88e6xxx_chip *chip = ds->priv;
488	u8 lane;
489	int err;
490
491	mv88e6xxx_reg_lock(chip);
492	lane = mv88e6xxx_serdes_get_lane(chip, port);
493	if (lane && chip->info->ops->serdes_pcs_get_state)
494		err = chip->info->ops->serdes_pcs_get_state(chip, port, lane,
495							    state);
496	else
497		err = -EOPNOTSUPP;
498	mv88e6xxx_reg_unlock(chip);
499
500	return err;
501}
502
503static int mv88e6xxx_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
504				       unsigned int mode,
505				       phy_interface_t interface,
506				       const unsigned long *advertise)
507{
508	const struct mv88e6xxx_ops *ops = chip->info->ops;
509	u8 lane;
510
511	if (ops->serdes_pcs_config) {
512		lane = mv88e6xxx_serdes_get_lane(chip, port);
513		if (lane)
514			return ops->serdes_pcs_config(chip, port, lane, mode,
515						      interface, advertise);
516	}
517
518	return 0;
519}
520
521static void mv88e6xxx_serdes_pcs_an_restart(struct dsa_switch *ds, int port)
522{
523	struct mv88e6xxx_chip *chip = ds->priv;
524	const struct mv88e6xxx_ops *ops;
525	int err = 0;
526	u8 lane;
527
528	ops = chip->info->ops;
529
530	if (ops->serdes_pcs_an_restart) {
531		mv88e6xxx_reg_lock(chip);
532		lane = mv88e6xxx_serdes_get_lane(chip, port);
533		if (lane)
534			err = ops->serdes_pcs_an_restart(chip, port, lane);
535		mv88e6xxx_reg_unlock(chip);
536
537		if (err)
538			dev_err(ds->dev, "p%d: failed to restart AN\n", port);
539	}
540}
541
542static int mv88e6xxx_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
543					unsigned int mode,
544					int speed, int duplex)
545{
546	const struct mv88e6xxx_ops *ops = chip->info->ops;
547	u8 lane;
548
549	if (!phylink_autoneg_inband(mode) && ops->serdes_pcs_link_up) {
550		lane = mv88e6xxx_serdes_get_lane(chip, port);
551		if (lane)
552			return ops->serdes_pcs_link_up(chip, port, lane,
553						       speed, duplex);
554	}
555
556	return 0;
557}
558
559static void mv88e6065_phylink_validate(struct mv88e6xxx_chip *chip, int port,
560				       unsigned long *mask,
561				       struct phylink_link_state *state)
562{
563	if (!phy_interface_mode_is_8023z(state->interface)) {
564		/* 10M and 100M are only supported in non-802.3z mode */
565		phylink_set(mask, 10baseT_Half);
566		phylink_set(mask, 10baseT_Full);
567		phylink_set(mask, 100baseT_Half);
568		phylink_set(mask, 100baseT_Full);
569	}
570}
571
572static void mv88e6185_phylink_validate(struct mv88e6xxx_chip *chip, int port,
573				       unsigned long *mask,
574				       struct phylink_link_state *state)
575{
576	/* FIXME: if the port is in 1000Base-X mode, then it only supports
577	 * 1000M FD speeds.  In this case, CMODE will indicate 5.
578	 */
579	phylink_set(mask, 1000baseT_Full);
580	phylink_set(mask, 1000baseX_Full);
581
582	mv88e6065_phylink_validate(chip, port, mask, state);
583}
584
585static void mv88e6341_phylink_validate(struct mv88e6xxx_chip *chip, int port,
586				       unsigned long *mask,
587				       struct phylink_link_state *state)
588{
589	if (port >= 5)
590		phylink_set(mask, 2500baseX_Full);
591
592	/* No ethtool bits for 200Mbps */
593	phylink_set(mask, 1000baseT_Full);
594	phylink_set(mask, 1000baseX_Full);
595
596	mv88e6065_phylink_validate(chip, port, mask, state);
597}
598
599static void mv88e6352_phylink_validate(struct mv88e6xxx_chip *chip, int port,
600				       unsigned long *mask,
601				       struct phylink_link_state *state)
602{
603	/* No ethtool bits for 200Mbps */
604	phylink_set(mask, 1000baseT_Full);
605	phylink_set(mask, 1000baseX_Full);
606
607	mv88e6065_phylink_validate(chip, port, mask, state);
608}
609
610static void mv88e6390_phylink_validate(struct mv88e6xxx_chip *chip, int port,
611				       unsigned long *mask,
612				       struct phylink_link_state *state)
613{
614	if (port >= 9) {
615		phylink_set(mask, 2500baseX_Full);
616		phylink_set(mask, 2500baseT_Full);
617	}
618
619	/* No ethtool bits for 200Mbps */
620	phylink_set(mask, 1000baseT_Full);
621	phylink_set(mask, 1000baseX_Full);
622
623	mv88e6065_phylink_validate(chip, port, mask, state);
624}
625
626static void mv88e6390x_phylink_validate(struct mv88e6xxx_chip *chip, int port,
627					unsigned long *mask,
628					struct phylink_link_state *state)
629{
630	if (port >= 9) {
631		phylink_set(mask, 10000baseT_Full);
632		phylink_set(mask, 10000baseKR_Full);
633	}
634
635	mv88e6390_phylink_validate(chip, port, mask, state);
636}
637
638static void mv88e6xxx_validate(struct dsa_switch *ds, int port,
639			       unsigned long *supported,
640			       struct phylink_link_state *state)
641{
642	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
643	struct mv88e6xxx_chip *chip = ds->priv;
644
645	/* Allow all the expected bits */
646	phylink_set(mask, Autoneg);
647	phylink_set(mask, Pause);
648	phylink_set_port_modes(mask);
649
650	if (chip->info->ops->phylink_validate)
651		chip->info->ops->phylink_validate(chip, port, mask, state);
652
653	bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
654	bitmap_and(state->advertising, state->advertising, mask,
655		   __ETHTOOL_LINK_MODE_MASK_NBITS);
656
657	/* We can only operate at 2500BaseX or 1000BaseX.  If requested
658	 * to advertise both, only report advertising at 2500BaseX.
659	 */
660	phylink_helper_basex_speed(state);
661}
662
663static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
664				 unsigned int mode,
665				 const struct phylink_link_state *state)
666{
667	struct mv88e6xxx_chip *chip = ds->priv;
668	struct mv88e6xxx_port *p;
669	int err = 0;
670
671	p = &chip->ports[port];
672
673	mv88e6xxx_reg_lock(chip);
674
675	if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) {
676		/* In inband mode, the link may come up at any time while the
677		 * link is not forced down. Force the link down while we
678		 * reconfigure the interface mode.
679		 */
680		if (mode == MLO_AN_INBAND &&
681		    p->interface != state->interface &&
682		    chip->info->ops->port_set_link)
683			chip->info->ops->port_set_link(chip, port,
684						       LINK_FORCED_DOWN);
685
686		err = mv88e6xxx_port_config_interface(chip, port,
687						      state->interface);
688		if (err && err != -EOPNOTSUPP)
689			goto err_unlock;
690
691		err = mv88e6xxx_serdes_pcs_config(chip, port, mode,
692						  state->interface,
693						  state->advertising);
694		/* FIXME: we should restart negotiation if something changed -
695		 * which is something we get if we convert to using phylinks
696		 * PCS operations.
697		 */
698		if (err > 0)
699			err = 0;
700	}
701
702	/* Undo the forced down state above after completing configuration
703	 * irrespective of its state on entry, which allows the link to come
704	 * up in the in-band case where there is no separate SERDES. Also
705	 * ensure that the link can come up if the PPU is in use and we are
706	 * in PHY mode (we treat the PPU as an effective in-band mechanism.)
707	 */
708	if (chip->info->ops->port_set_link &&
709	    ((mode == MLO_AN_INBAND && p->interface != state->interface) ||
710	     (mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port))))
711		chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
712
713	p->interface = state->interface;
714
715err_unlock:
716	mv88e6xxx_reg_unlock(chip);
717
718	if (err && err != -EOPNOTSUPP)
719		dev_err(ds->dev, "p%d: failed to configure MAC/PCS\n", port);
720}
721
722static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
723				    unsigned int mode,
724				    phy_interface_t interface)
725{
726	struct mv88e6xxx_chip *chip = ds->priv;
727	const struct mv88e6xxx_ops *ops;
728	int err = 0;
729
730	ops = chip->info->ops;
731
732	mv88e6xxx_reg_lock(chip);
733	/* Internal PHYs propagate their configuration directly to the MAC.
734	 * External PHYs depend on whether the PPU is enabled for this port.
735	 */
736	if (((!mv88e6xxx_phy_is_internal(ds, port) &&
737	      !mv88e6xxx_port_ppu_updates(chip, port)) ||
738	     mode == MLO_AN_FIXED) && ops->port_set_link)
739		err = ops->port_set_link(chip, port, LINK_FORCED_DOWN);
740	mv88e6xxx_reg_unlock(chip);
741
742	if (err)
743		dev_err(chip->dev,
744			"p%d: failed to force MAC link down\n", port);
745}
746
747static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
748				  unsigned int mode, phy_interface_t interface,
749				  struct phy_device *phydev,
750				  int speed, int duplex,
751				  bool tx_pause, bool rx_pause)
752{
753	struct mv88e6xxx_chip *chip = ds->priv;
754	const struct mv88e6xxx_ops *ops;
755	int err = 0;
756
757	ops = chip->info->ops;
758
759	mv88e6xxx_reg_lock(chip);
760	/* Internal PHYs propagate their configuration directly to the MAC.
761	 * External PHYs depend on whether the PPU is enabled for this port.
762	 */
763	if ((!mv88e6xxx_phy_is_internal(ds, port) &&
764	     !mv88e6xxx_port_ppu_updates(chip, port)) ||
765	    mode == MLO_AN_FIXED) {
766		/* FIXME: for an automedia port, should we force the link
767		 * down here - what if the link comes up due to "other" media
768		 * while we're bringing the port up, how is the exclusivity
769		 * handled in the Marvell hardware? E.g. port 2 on 88E6390
770		 * shared between internal PHY and Serdes.
771		 */
772		err = mv88e6xxx_serdes_pcs_link_up(chip, port, mode, speed,
773						   duplex);
774		if (err)
775			goto error;
776
777		if (ops->port_set_speed_duplex) {
778			err = ops->port_set_speed_duplex(chip, port,
779							 speed, duplex);
780			if (err && err != -EOPNOTSUPP)
781				goto error;
782		}
783
784		if (ops->port_set_link)
785			err = ops->port_set_link(chip, port, LINK_FORCED_UP);
786	}
787error:
788	mv88e6xxx_reg_unlock(chip);
789
790	if (err && err != -EOPNOTSUPP)
791		dev_err(ds->dev,
792			"p%d: failed to configure MAC link up\n", port);
793}
794
795static int mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
796{
797	if (!chip->info->ops->stats_snapshot)
798		return -EOPNOTSUPP;
799
800	return chip->info->ops->stats_snapshot(chip, port);
801}
802
803static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
804	{ "in_good_octets",		8, 0x00, STATS_TYPE_BANK0, },
805	{ "in_bad_octets",		4, 0x02, STATS_TYPE_BANK0, },
806	{ "in_unicast",			4, 0x04, STATS_TYPE_BANK0, },
807	{ "in_broadcasts",		4, 0x06, STATS_TYPE_BANK0, },
808	{ "in_multicasts",		4, 0x07, STATS_TYPE_BANK0, },
809	{ "in_pause",			4, 0x16, STATS_TYPE_BANK0, },
810	{ "in_undersize",		4, 0x18, STATS_TYPE_BANK0, },
811	{ "in_fragments",		4, 0x19, STATS_TYPE_BANK0, },
812	{ "in_oversize",		4, 0x1a, STATS_TYPE_BANK0, },
813	{ "in_jabber",			4, 0x1b, STATS_TYPE_BANK0, },
814	{ "in_rx_error",		4, 0x1c, STATS_TYPE_BANK0, },
815	{ "in_fcs_error",		4, 0x1d, STATS_TYPE_BANK0, },
816	{ "out_octets",			8, 0x0e, STATS_TYPE_BANK0, },
817	{ "out_unicast",		4, 0x10, STATS_TYPE_BANK0, },
818	{ "out_broadcasts",		4, 0x13, STATS_TYPE_BANK0, },
819	{ "out_multicasts",		4, 0x12, STATS_TYPE_BANK0, },
820	{ "out_pause",			4, 0x15, STATS_TYPE_BANK0, },
821	{ "excessive",			4, 0x11, STATS_TYPE_BANK0, },
822	{ "collisions",			4, 0x1e, STATS_TYPE_BANK0, },
823	{ "deferred",			4, 0x05, STATS_TYPE_BANK0, },
824	{ "single",			4, 0x14, STATS_TYPE_BANK0, },
825	{ "multiple",			4, 0x17, STATS_TYPE_BANK0, },
826	{ "out_fcs_error",		4, 0x03, STATS_TYPE_BANK0, },
827	{ "late",			4, 0x1f, STATS_TYPE_BANK0, },
828	{ "hist_64bytes",		4, 0x08, STATS_TYPE_BANK0, },
829	{ "hist_65_127bytes",		4, 0x09, STATS_TYPE_BANK0, },
830	{ "hist_128_255bytes",		4, 0x0a, STATS_TYPE_BANK0, },
831	{ "hist_256_511bytes",		4, 0x0b, STATS_TYPE_BANK0, },
832	{ "hist_512_1023bytes",		4, 0x0c, STATS_TYPE_BANK0, },
833	{ "hist_1024_max_bytes",	4, 0x0d, STATS_TYPE_BANK0, },
834	{ "sw_in_discards",		4, 0x10, STATS_TYPE_PORT, },
835	{ "sw_in_filtered",		2, 0x12, STATS_TYPE_PORT, },
836	{ "sw_out_filtered",		2, 0x13, STATS_TYPE_PORT, },
837	{ "in_discards",		4, 0x00, STATS_TYPE_BANK1, },
838	{ "in_filtered",		4, 0x01, STATS_TYPE_BANK1, },
839	{ "in_accepted",		4, 0x02, STATS_TYPE_BANK1, },
840	{ "in_bad_accepted",		4, 0x03, STATS_TYPE_BANK1, },
841	{ "in_good_avb_class_a",	4, 0x04, STATS_TYPE_BANK1, },
842	{ "in_good_avb_class_b",	4, 0x05, STATS_TYPE_BANK1, },
843	{ "in_bad_avb_class_a",		4, 0x06, STATS_TYPE_BANK1, },
844	{ "in_bad_avb_class_b",		4, 0x07, STATS_TYPE_BANK1, },
845	{ "tcam_counter_0",		4, 0x08, STATS_TYPE_BANK1, },
846	{ "tcam_counter_1",		4, 0x09, STATS_TYPE_BANK1, },
847	{ "tcam_counter_2",		4, 0x0a, STATS_TYPE_BANK1, },
848	{ "tcam_counter_3",		4, 0x0b, STATS_TYPE_BANK1, },
849	{ "in_da_unknown",		4, 0x0e, STATS_TYPE_BANK1, },
850	{ "in_management",		4, 0x0f, STATS_TYPE_BANK1, },
851	{ "out_queue_0",		4, 0x10, STATS_TYPE_BANK1, },
852	{ "out_queue_1",		4, 0x11, STATS_TYPE_BANK1, },
853	{ "out_queue_2",		4, 0x12, STATS_TYPE_BANK1, },
854	{ "out_queue_3",		4, 0x13, STATS_TYPE_BANK1, },
855	{ "out_queue_4",		4, 0x14, STATS_TYPE_BANK1, },
856	{ "out_queue_5",		4, 0x15, STATS_TYPE_BANK1, },
857	{ "out_queue_6",		4, 0x16, STATS_TYPE_BANK1, },
858	{ "out_queue_7",		4, 0x17, STATS_TYPE_BANK1, },
859	{ "out_cut_through",		4, 0x18, STATS_TYPE_BANK1, },
860	{ "out_octets_a",		4, 0x1a, STATS_TYPE_BANK1, },
861	{ "out_octets_b",		4, 0x1b, STATS_TYPE_BANK1, },
862	{ "out_management",		4, 0x1f, STATS_TYPE_BANK1, },
863};
864
865static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
866					    struct mv88e6xxx_hw_stat *s,
867					    int port, u16 bank1_select,
868					    u16 histogram)
869{
870	u32 low;
871	u32 high = 0;
872	u16 reg = 0;
873	int err;
874	u64 value;
875
876	switch (s->type) {
877	case STATS_TYPE_PORT:
878		err = mv88e6xxx_port_read(chip, port, s->reg, &reg);
879		if (err)
880			return U64_MAX;
881
882		low = reg;
883		if (s->size == 4) {
884			err = mv88e6xxx_port_read(chip, port, s->reg + 1, &reg);
885			if (err)
886				return U64_MAX;
887			low |= ((u32)reg) << 16;
888		}
889		break;
890	case STATS_TYPE_BANK1:
891		reg = bank1_select;
892		fallthrough;
893	case STATS_TYPE_BANK0:
894		reg |= s->reg | histogram;
895		mv88e6xxx_g1_stats_read(chip, reg, &low);
896		if (s->size == 8)
897			mv88e6xxx_g1_stats_read(chip, reg + 1, &high);
898		break;
899	default:
900		return U64_MAX;
901	}
902	value = (((u64)high) << 32) | low;
903	return value;
904}
905
906static int mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip,
907				       uint8_t *data, int types)
908{
909	struct mv88e6xxx_hw_stat *stat;
910	int i, j;
911
912	for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
913		stat = &mv88e6xxx_hw_stats[i];
914		if (stat->type & types) {
915			memcpy(data + j * ETH_GSTRING_LEN, stat->string,
916			       ETH_GSTRING_LEN);
917			j++;
918		}
919	}
920
921	return j;
922}
923
924static int mv88e6095_stats_get_strings(struct mv88e6xxx_chip *chip,
925				       uint8_t *data)
926{
927	return mv88e6xxx_stats_get_strings(chip, data,
928					   STATS_TYPE_BANK0 | STATS_TYPE_PORT);
929}
930
931static int mv88e6250_stats_get_strings(struct mv88e6xxx_chip *chip,
932				       uint8_t *data)
933{
934	return mv88e6xxx_stats_get_strings(chip, data, STATS_TYPE_BANK0);
935}
936
937static int mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip,
938				       uint8_t *data)
939{
940	return mv88e6xxx_stats_get_strings(chip, data,
941					   STATS_TYPE_BANK0 | STATS_TYPE_BANK1);
942}
943
944static const uint8_t *mv88e6xxx_atu_vtu_stats_strings[] = {
945	"atu_member_violation",
946	"atu_miss_violation",
947	"atu_full_violation",
948	"vtu_member_violation",
949	"vtu_miss_violation",
950};
951
952static void mv88e6xxx_atu_vtu_get_strings(uint8_t *data)
953{
954	unsigned int i;
955
956	for (i = 0; i < ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings); i++)
957		strlcpy(data + i * ETH_GSTRING_LEN,
958			mv88e6xxx_atu_vtu_stats_strings[i],
959			ETH_GSTRING_LEN);
960}
961
962static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
963				  u32 stringset, uint8_t *data)
964{
965	struct mv88e6xxx_chip *chip = ds->priv;
966	int count = 0;
967
968	if (stringset != ETH_SS_STATS)
969		return;
970
971	mv88e6xxx_reg_lock(chip);
972
973	if (chip->info->ops->stats_get_strings)
974		count = chip->info->ops->stats_get_strings(chip, data);
975
976	if (chip->info->ops->serdes_get_strings) {
977		data += count * ETH_GSTRING_LEN;
978		count = chip->info->ops->serdes_get_strings(chip, port, data);
979	}
980
981	data += count * ETH_GSTRING_LEN;
982	mv88e6xxx_atu_vtu_get_strings(data);
983
984	mv88e6xxx_reg_unlock(chip);
985}
986
987static int mv88e6xxx_stats_get_sset_count(struct mv88e6xxx_chip *chip,
988					  int types)
989{
990	struct mv88e6xxx_hw_stat *stat;
991	int i, j;
992
993	for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
994		stat = &mv88e6xxx_hw_stats[i];
995		if (stat->type & types)
996			j++;
997	}
998	return j;
999}
1000
1001static int mv88e6095_stats_get_sset_count(struct mv88e6xxx_chip *chip)
1002{
1003	return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 |
1004					      STATS_TYPE_PORT);
1005}
1006
1007static int mv88e6250_stats_get_sset_count(struct mv88e6xxx_chip *chip)
1008{
1009	return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0);
1010}
1011
1012static int mv88e6320_stats_get_sset_count(struct mv88e6xxx_chip *chip)
1013{
1014	return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 |
1015					      STATS_TYPE_BANK1);
1016}
1017
1018static int mv88e6xxx_get_sset_count(struct dsa_switch *ds, int port, int sset)
1019{
1020	struct mv88e6xxx_chip *chip = ds->priv;
1021	int serdes_count = 0;
1022	int count = 0;
1023
1024	if (sset != ETH_SS_STATS)
1025		return 0;
1026
1027	mv88e6xxx_reg_lock(chip);
1028	if (chip->info->ops->stats_get_sset_count)
1029		count = chip->info->ops->stats_get_sset_count(chip);
1030	if (count < 0)
1031		goto out;
1032
1033	if (chip->info->ops->serdes_get_sset_count)
1034		serdes_count = chip->info->ops->serdes_get_sset_count(chip,
1035								      port);
1036	if (serdes_count < 0) {
1037		count = serdes_count;
1038		goto out;
1039	}
1040	count += serdes_count;
1041	count += ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings);
1042
1043out:
1044	mv88e6xxx_reg_unlock(chip);
1045
1046	return count;
1047}
1048
1049static int mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
1050				     uint64_t *data, int types,
1051				     u16 bank1_select, u16 histogram)
1052{
1053	struct mv88e6xxx_hw_stat *stat;
1054	int i, j;
1055
1056	for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
1057		stat = &mv88e6xxx_hw_stats[i];
1058		if (stat->type & types) {
1059			mv88e6xxx_reg_lock(chip);
1060			data[j] = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
1061							      bank1_select,
1062							      histogram);
1063			mv88e6xxx_reg_unlock(chip);
1064
1065			j++;
1066		}
1067	}
1068	return j;
1069}
1070
1071static int mv88e6095_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
1072				     uint64_t *data)
1073{
1074	return mv88e6xxx_stats_get_stats(chip, port, data,
1075					 STATS_TYPE_BANK0 | STATS_TYPE_PORT,
1076					 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
1077}
1078
1079static int mv88e6250_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
1080				     uint64_t *data)
1081{
1082	return mv88e6xxx_stats_get_stats(chip, port, data, STATS_TYPE_BANK0,
1083					 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
1084}
1085
1086static int mv88e6320_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
1087				     uint64_t *data)
1088{
1089	return mv88e6xxx_stats_get_stats(chip, port, data,
1090					 STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
1091					 MV88E6XXX_G1_STATS_OP_BANK_1_BIT_9,
1092					 MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
1093}
1094
1095static int mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
1096				     uint64_t *data)
1097{
1098	return mv88e6xxx_stats_get_stats(chip, port, data,
1099					 STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
1100					 MV88E6XXX_G1_STATS_OP_BANK_1_BIT_10,
1101					 0);
1102}
1103
1104static void mv88e6xxx_atu_vtu_get_stats(struct mv88e6xxx_chip *chip, int port,
1105					uint64_t *data)
1106{
1107	*data++ = chip->ports[port].atu_member_violation;
1108	*data++ = chip->ports[port].atu_miss_violation;
1109	*data++ = chip->ports[port].atu_full_violation;
1110	*data++ = chip->ports[port].vtu_member_violation;
1111	*data++ = chip->ports[port].vtu_miss_violation;
1112}
1113
1114static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
1115				uint64_t *data)
1116{
1117	int count = 0;
1118
1119	if (chip->info->ops->stats_get_stats)
1120		count = chip->info->ops->stats_get_stats(chip, port, data);
1121
1122	mv88e6xxx_reg_lock(chip);
1123	if (chip->info->ops->serdes_get_stats) {
1124		data += count;
1125		count = chip->info->ops->serdes_get_stats(chip, port, data);
1126	}
1127	data += count;
1128	mv88e6xxx_atu_vtu_get_stats(chip, port, data);
1129	mv88e6xxx_reg_unlock(chip);
1130}
1131
1132static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
1133					uint64_t *data)
1134{
1135	struct mv88e6xxx_chip *chip = ds->priv;
1136	int ret;
1137
1138	mv88e6xxx_reg_lock(chip);
1139
1140	ret = mv88e6xxx_stats_snapshot(chip, port);
1141	mv88e6xxx_reg_unlock(chip);
1142
1143	if (ret < 0)
1144		return;
1145
1146	mv88e6xxx_get_stats(chip, port, data);
1147
1148}
1149
1150static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
1151{
1152	struct mv88e6xxx_chip *chip = ds->priv;
1153	int len;
1154
1155	len = 32 * sizeof(u16);
1156	if (chip->info->ops->serdes_get_regs_len)
1157		len += chip->info->ops->serdes_get_regs_len(chip, port);
1158
1159	return len;
1160}
1161
1162static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
1163			       struct ethtool_regs *regs, void *_p)
1164{
1165	struct mv88e6xxx_chip *chip = ds->priv;
1166	int err;
1167	u16 reg;
1168	u16 *p = _p;
1169	int i;
1170
1171	regs->version = chip->info->prod_num;
1172
1173	memset(p, 0xff, 32 * sizeof(u16));
1174
1175	mv88e6xxx_reg_lock(chip);
1176
1177	for (i = 0; i < 32; i++) {
1178
1179		err = mv88e6xxx_port_read(chip, port, i, &reg);
1180		if (!err)
1181			p[i] = reg;
1182	}
1183
1184	if (chip->info->ops->serdes_get_regs)
1185		chip->info->ops->serdes_get_regs(chip, port, &p[i]);
1186
1187	mv88e6xxx_reg_unlock(chip);
1188}
1189
1190static int mv88e6xxx_get_mac_eee(struct dsa_switch *ds, int port,
1191				 struct ethtool_eee *e)
1192{
1193	/* Nothing to do on the port's MAC */
1194	return 0;
1195}
1196
1197static int mv88e6xxx_set_mac_eee(struct dsa_switch *ds, int port,
1198				 struct ethtool_eee *e)
1199{
1200	/* Nothing to do on the port's MAC */
1201	return 0;
1202}
1203
1204/* Mask of the local ports allowed to receive frames from a given fabric port */
1205static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port)
1206{
1207	struct dsa_switch *ds = chip->ds;
1208	struct dsa_switch_tree *dst = ds->dst;
1209	struct net_device *br;
1210	struct dsa_port *dp;
1211	bool found = false;
1212	u16 pvlan;
1213
1214	list_for_each_entry(dp, &dst->ports, list) {
1215		if (dp->ds->index == dev && dp->index == port) {
1216			found = true;
1217			break;
1218		}
1219	}
1220
1221	/* Prevent frames from unknown switch or port */
1222	if (!found)
1223		return 0;
1224
1225	/* Frames from DSA links and CPU ports can egress any local port */
1226	if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA)
1227		return mv88e6xxx_port_mask(chip);
1228
1229	br = dp->bridge_dev;
1230	pvlan = 0;
1231
1232	/* Frames from user ports can egress any local DSA links and CPU ports,
1233	 * as well as any local member of their bridge group.
1234	 */
1235	list_for_each_entry(dp, &dst->ports, list)
1236		if (dp->ds == ds &&
1237		    (dp->type == DSA_PORT_TYPE_CPU ||
1238		     dp->type == DSA_PORT_TYPE_DSA ||
1239		     (br && dp->bridge_dev == br)))
1240			pvlan |= BIT(dp->index);
1241
1242	return pvlan;
1243}
1244
1245static int mv88e6xxx_port_vlan_map(struct mv88e6xxx_chip *chip, int port)
1246{
1247	u16 output_ports = mv88e6xxx_port_vlan(chip, chip->ds->index, port);
1248
1249	/* prevent frames from going back out of the port they came in on */
1250	output_ports &= ~BIT(port);
1251
1252	return mv88e6xxx_port_set_vlan_map(chip, port, output_ports);
1253}
1254
1255static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
1256					 u8 state)
1257{
1258	struct mv88e6xxx_chip *chip = ds->priv;
1259	int err;
1260
1261	mv88e6xxx_reg_lock(chip);
1262	err = mv88e6xxx_port_set_state(chip, port, state);
1263	mv88e6xxx_reg_unlock(chip);
1264
1265	if (err)
1266		dev_err(ds->dev, "p%d: failed to update state\n", port);
1267}
1268
1269static int mv88e6xxx_pri_setup(struct mv88e6xxx_chip *chip)
1270{
1271	int err;
1272
1273	if (chip->info->ops->ieee_pri_map) {
1274		err = chip->info->ops->ieee_pri_map(chip);
1275		if (err)
1276			return err;
1277	}
1278
1279	if (chip->info->ops->ip_pri_map) {
1280		err = chip->info->ops->ip_pri_map(chip);
1281		if (err)
1282			return err;
1283	}
1284
1285	return 0;
1286}
1287
1288static int mv88e6xxx_devmap_setup(struct mv88e6xxx_chip *chip)
1289{
1290	struct dsa_switch *ds = chip->ds;
1291	int target, port;
1292	int err;
1293
1294	if (!chip->info->global2_addr)
1295		return 0;
1296
1297	/* Initialize the routing port to the 32 possible target devices */
1298	for (target = 0; target < 32; target++) {
1299		port = dsa_routing_port(ds, target);
1300		if (port == ds->num_ports)
1301			port = 0x1f;
1302
1303		err = mv88e6xxx_g2_device_mapping_write(chip, target, port);
1304		if (err)
1305			return err;
1306	}
1307
1308	if (chip->info->ops->set_cascade_port) {
1309		port = MV88E6XXX_CASCADE_PORT_MULTIPLE;
1310		err = chip->info->ops->set_cascade_port(chip, port);
1311		if (err)
1312			return err;
1313	}
1314
1315	err = mv88e6xxx_g1_set_device_number(chip, chip->ds->index);
1316	if (err)
1317		return err;
1318
1319	return 0;
1320}
1321
1322static int mv88e6xxx_trunk_setup(struct mv88e6xxx_chip *chip)
1323{
1324	/* Clear all trunk masks and mapping */
1325	if (chip->info->global2_addr)
1326		return mv88e6xxx_g2_trunk_clear(chip);
1327
1328	return 0;
1329}
1330
1331static int mv88e6xxx_rmu_setup(struct mv88e6xxx_chip *chip)
1332{
1333	if (chip->info->ops->rmu_disable)
1334		return chip->info->ops->rmu_disable(chip);
1335
1336	return 0;
1337}
1338
1339static int mv88e6xxx_pot_setup(struct mv88e6xxx_chip *chip)
1340{
1341	if (chip->info->ops->pot_clear)
1342		return chip->info->ops->pot_clear(chip);
1343
1344	return 0;
1345}
1346
1347static int mv88e6xxx_rsvd2cpu_setup(struct mv88e6xxx_chip *chip)
1348{
1349	if (chip->info->ops->mgmt_rsvd2cpu)
1350		return chip->info->ops->mgmt_rsvd2cpu(chip);
1351
1352	return 0;
1353}
1354
1355static int mv88e6xxx_atu_setup(struct mv88e6xxx_chip *chip)
1356{
1357	int err;
1358
1359	err = mv88e6xxx_g1_atu_flush(chip, 0, true);
1360	if (err)
1361		return err;
1362
1363	err = mv88e6xxx_g1_atu_set_learn2all(chip, true);
1364	if (err)
1365		return err;
1366
1367	return mv88e6xxx_g1_atu_set_age_time(chip, 300000);
1368}
1369
1370static int mv88e6xxx_irl_setup(struct mv88e6xxx_chip *chip)
1371{
1372	int port;
1373	int err;
1374
1375	if (!chip->info->ops->irl_init_all)
1376		return 0;
1377
1378	for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
1379		/* Disable ingress rate limiting by resetting all per port
1380		 * ingress rate limit resources to their initial state.
1381		 */
1382		err = chip->info->ops->irl_init_all(chip, port);
1383		if (err)
1384			return err;
1385	}
1386
1387	return 0;
1388}
1389
1390static int mv88e6xxx_mac_setup(struct mv88e6xxx_chip *chip)
1391{
1392	if (chip->info->ops->set_switch_mac) {
1393		u8 addr[ETH_ALEN];
1394
1395		eth_random_addr(addr);
1396
1397		return chip->info->ops->set_switch_mac(chip, addr);
1398	}
1399
1400	return 0;
1401}
1402
1403static int mv88e6xxx_pvt_map(struct mv88e6xxx_chip *chip, int dev, int port)
1404{
1405	u16 pvlan = 0;
1406
1407	if (!mv88e6xxx_has_pvt(chip))
1408		return 0;
1409
1410	/* Skip the local source device, which uses in-chip port VLAN */
1411	if (dev != chip->ds->index)
1412		pvlan = mv88e6xxx_port_vlan(chip, dev, port);
1413
1414	return mv88e6xxx_g2_pvt_write(chip, dev, port, pvlan);
1415}
1416
1417static int mv88e6xxx_pvt_setup(struct mv88e6xxx_chip *chip)
1418{
1419	int dev, port;
1420	int err;
1421
1422	if (!mv88e6xxx_has_pvt(chip))
1423		return 0;
1424
1425	/* Clear 5 Bit Port for usage with Marvell Link Street devices:
1426	 * use 4 bits for the Src_Port/Src_Trunk and 5 bits for the Src_Dev.
1427	 */
1428	err = mv88e6xxx_g2_misc_4_bit_port(chip);
1429	if (err)
1430		return err;
1431
1432	for (dev = 0; dev < MV88E6XXX_MAX_PVT_SWITCHES; ++dev) {
1433		for (port = 0; port < MV88E6XXX_MAX_PVT_PORTS; ++port) {
1434			err = mv88e6xxx_pvt_map(chip, dev, port);
1435			if (err)
1436				return err;
1437		}
1438	}
1439
1440	return 0;
1441}
1442
1443static void mv88e6xxx_port_fast_age(struct dsa_switch *ds, int port)
1444{
1445	struct mv88e6xxx_chip *chip = ds->priv;
1446	int err;
1447
1448	mv88e6xxx_reg_lock(chip);
1449	err = mv88e6xxx_g1_atu_remove(chip, 0, port, false);
1450	mv88e6xxx_reg_unlock(chip);
1451
1452	if (err)
1453		dev_err(ds->dev, "p%d: failed to flush ATU\n", port);
1454}
1455
1456static int mv88e6xxx_vtu_setup(struct mv88e6xxx_chip *chip)
1457{
1458	if (!chip->info->max_vid)
1459		return 0;
1460
1461	return mv88e6xxx_g1_vtu_flush(chip);
1462}
1463
1464static int mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip,
1465				 struct mv88e6xxx_vtu_entry *entry)
1466{
1467	if (!chip->info->ops->vtu_getnext)
1468		return -EOPNOTSUPP;
1469
1470	return chip->info->ops->vtu_getnext(chip, entry);
1471}
1472
1473static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
1474				   struct mv88e6xxx_vtu_entry *entry)
1475{
1476	if (!chip->info->ops->vtu_loadpurge)
1477		return -EOPNOTSUPP;
1478
1479	return chip->info->ops->vtu_loadpurge(chip, entry);
1480}
1481
1482int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *fid_bitmap)
1483{
1484	struct mv88e6xxx_vtu_entry vlan;
1485	int i, err;
1486	u16 fid;
1487
1488	bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);
1489
1490	/* Set every FID bit used by the (un)bridged ports */
1491	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1492		err = mv88e6xxx_port_get_fid(chip, i, &fid);
1493		if (err)
1494			return err;
1495
1496		set_bit(fid, fid_bitmap);
1497	}
1498
1499	/* Set every FID bit used by the VLAN entries */
1500	vlan.vid = chip->info->max_vid;
1501	vlan.valid = false;
1502
1503	do {
1504		err = mv88e6xxx_vtu_getnext(chip, &vlan);
1505		if (err)
1506			return err;
1507
1508		if (!vlan.valid)
1509			break;
1510
1511		set_bit(vlan.fid, fid_bitmap);
1512	} while (vlan.vid < chip->info->max_vid);
1513
1514	return 0;
1515}
1516
1517static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
1518{
1519	DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID);
1520	int err;
1521
1522	err = mv88e6xxx_fid_map(chip, fid_bitmap);
1523	if (err)
1524		return err;
1525
1526	/* The reset value 0x000 is used to indicate that multiple address
1527	 * databases are not needed. Return the next positive available.
1528	 */
1529	*fid = find_next_zero_bit(fid_bitmap, MV88E6XXX_N_FID, 1);
1530	if (unlikely(*fid >= mv88e6xxx_num_databases(chip)))
1531		return -ENOSPC;
1532
1533	/* Clear the database */
1534	return mv88e6xxx_g1_atu_flush(chip, *fid, true);
1535}
1536
1537static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
1538					u16 vid_begin, u16 vid_end)
1539{
1540	struct mv88e6xxx_chip *chip = ds->priv;
1541	struct mv88e6xxx_vtu_entry vlan;
1542	int i, err;
1543
1544	/* DSA and CPU ports have to be members of multiple vlans */
1545	if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
1546		return 0;
1547
1548	if (!vid_begin)
1549		return -EOPNOTSUPP;
1550
1551	vlan.vid = vid_begin - 1;
1552	vlan.valid = false;
1553
1554	do {
1555		err = mv88e6xxx_vtu_getnext(chip, &vlan);
1556		if (err)
1557			return err;
1558
1559		if (!vlan.valid)
1560			break;
1561
1562		if (vlan.vid > vid_end)
1563			break;
1564
1565		for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1566			if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
1567				continue;
1568
1569			if (!dsa_to_port(ds, i)->slave)
1570				continue;
1571
1572			if (vlan.member[i] ==
1573			    MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
1574				continue;
1575
1576			if (dsa_to_port(ds, i)->bridge_dev ==
1577			    dsa_to_port(ds, port)->bridge_dev)
1578				break; /* same bridge, check next VLAN */
1579
1580			if (!dsa_to_port(ds, i)->bridge_dev)
1581				continue;
1582
1583			dev_err(ds->dev, "p%d: hw VLAN %d already used by port %d in %s\n",
1584				port, vlan.vid, i,
1585				netdev_name(dsa_to_port(ds, i)->bridge_dev));
1586			return -EOPNOTSUPP;
1587		}
1588	} while (vlan.vid < vid_end);
1589
1590	return 0;
1591}
1592
1593static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
1594					 bool vlan_filtering,
1595					 struct switchdev_trans *trans)
1596{
1597	struct mv88e6xxx_chip *chip = ds->priv;
1598	u16 mode = vlan_filtering ? MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE :
1599		MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED;
1600	int err;
1601
1602	if (switchdev_trans_ph_prepare(trans))
1603		return chip->info->max_vid ? 0 : -EOPNOTSUPP;
1604
1605	mv88e6xxx_reg_lock(chip);
1606	err = mv88e6xxx_port_set_8021q_mode(chip, port, mode);
1607	mv88e6xxx_reg_unlock(chip);
1608
1609	return err;
1610}
1611
1612static int
1613mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
1614			    const struct switchdev_obj_port_vlan *vlan)
1615{
1616	struct mv88e6xxx_chip *chip = ds->priv;
1617	int err;
1618
1619	if (!chip->info->max_vid)
1620		return -EOPNOTSUPP;
1621
1622	/* If the requested port doesn't belong to the same bridge as the VLAN
1623	 * members, do not support it (yet) and fallback to software VLAN.
1624	 */
1625	mv88e6xxx_reg_lock(chip);
1626	err = mv88e6xxx_port_check_hw_vlan(ds, port, vlan->vid_begin,
1627					   vlan->vid_end);
1628	mv88e6xxx_reg_unlock(chip);
1629
1630	/* We don't need any dynamic resource from the kernel (yet),
1631	 * so skip the prepare phase.
1632	 */
1633	return err;
1634}
1635
1636static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
1637					const unsigned char *addr, u16 vid,
1638					u8 state)
1639{
1640	struct mv88e6xxx_atu_entry entry;
1641	struct mv88e6xxx_vtu_entry vlan;
1642	u16 fid;
1643	int err;
1644
1645	/* Null VLAN ID corresponds to the port private database */
1646	if (vid == 0) {
1647		err = mv88e6xxx_port_get_fid(chip, port, &fid);
1648		if (err)
1649			return err;
1650	} else {
1651		vlan.vid = vid - 1;
1652		vlan.valid = false;
1653
1654		err = mv88e6xxx_vtu_getnext(chip, &vlan);
1655		if (err)
1656			return err;
1657
1658		/* switchdev expects -EOPNOTSUPP to honor software VLANs */
1659		if (vlan.vid != vid || !vlan.valid)
1660			return -EOPNOTSUPP;
1661
1662		fid = vlan.fid;
1663	}
1664
1665	entry.state = 0;
1666	ether_addr_copy(entry.mac, addr);
1667	eth_addr_dec(entry.mac);
1668
1669	err = mv88e6xxx_g1_atu_getnext(chip, fid, &entry);
1670	if (err)
1671		return err;
1672
1673	/* Initialize a fresh ATU entry if it isn't found */
1674	if (!entry.state || !ether_addr_equal(entry.mac, addr)) {
1675		memset(&entry, 0, sizeof(entry));
1676		ether_addr_copy(entry.mac, addr);
1677	}
1678
1679	/* Purge the ATU entry only if no port is using it anymore */
1680	if (!state) {
1681		entry.portvec &= ~BIT(port);
1682		if (!entry.portvec)
1683			entry.state = 0;
1684	} else {
1685		if (state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC)
1686			entry.portvec = BIT(port);
1687		else
1688			entry.portvec |= BIT(port);
1689
1690		entry.state = state;
1691	}
1692
1693	return mv88e6xxx_g1_atu_loadpurge(chip, fid, &entry);
1694}
1695
1696static int mv88e6xxx_policy_apply(struct mv88e6xxx_chip *chip, int port,
1697				  const struct mv88e6xxx_policy *policy)
1698{
1699	enum mv88e6xxx_policy_mapping mapping = policy->mapping;
1700	enum mv88e6xxx_policy_action action = policy->action;
1701	const u8 *addr = policy->addr;
1702	u16 vid = policy->vid;
1703	u8 state;
1704	int err;
1705	int id;
1706
1707	if (!chip->info->ops->port_set_policy)
1708		return -EOPNOTSUPP;
1709
1710	switch (mapping) {
1711	case MV88E6XXX_POLICY_MAPPING_DA:
1712	case MV88E6XXX_POLICY_MAPPING_SA:
1713		if (action == MV88E6XXX_POLICY_ACTION_NORMAL)
1714			state = 0; /* Dissociate the port and address */
1715		else if (action == MV88E6XXX_POLICY_ACTION_DISCARD &&
1716			 is_multicast_ether_addr(addr))
1717			state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_POLICY;
1718		else if (action == MV88E6XXX_POLICY_ACTION_DISCARD &&
1719			 is_unicast_ether_addr(addr))
1720			state = MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_POLICY;
1721		else
1722			return -EOPNOTSUPP;
1723
1724		err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
1725						   state);
1726		if (err)
1727			return err;
1728		break;
1729	default:
1730		return -EOPNOTSUPP;
1731	}
1732
1733	/* Skip the port's policy clearing if the mapping is still in use */
1734	if (action == MV88E6XXX_POLICY_ACTION_NORMAL)
1735		idr_for_each_entry(&chip->policies, policy, id)
1736			if (policy->port == port &&
1737			    policy->mapping == mapping &&
1738			    policy->action != action)
1739				return 0;
1740
1741	return chip->info->ops->port_set_policy(chip, port, mapping, action);
1742}
1743
1744static int mv88e6xxx_policy_insert(struct mv88e6xxx_chip *chip, int port,
1745				   struct ethtool_rx_flow_spec *fs)
1746{
1747	struct ethhdr *mac_entry = &fs->h_u.ether_spec;
1748	struct ethhdr *mac_mask = &fs->m_u.ether_spec;
1749	enum mv88e6xxx_policy_mapping mapping;
1750	enum mv88e6xxx_policy_action action;
1751	struct mv88e6xxx_policy *policy;
1752	u16 vid = 0;
1753	u8 *addr;
1754	int err;
1755	int id;
1756
1757	if (fs->location != RX_CLS_LOC_ANY)
1758		return -EINVAL;
1759
1760	if (fs->ring_cookie == RX_CLS_FLOW_DISC)
1761		action = MV88E6XXX_POLICY_ACTION_DISCARD;
1762	else
1763		return -EOPNOTSUPP;
1764
1765	switch (fs->flow_type & ~FLOW_EXT) {
1766	case ETHER_FLOW:
1767		if (!is_zero_ether_addr(mac_mask->h_dest) &&
1768		    is_zero_ether_addr(mac_mask->h_source)) {
1769			mapping = MV88E6XXX_POLICY_MAPPING_DA;
1770			addr = mac_entry->h_dest;
1771		} else if (is_zero_ether_addr(mac_mask->h_dest) &&
1772		    !is_zero_ether_addr(mac_mask->h_source)) {
1773			mapping = MV88E6XXX_POLICY_MAPPING_SA;
1774			addr = mac_entry->h_source;
1775		} else {
1776			/* Cannot support DA and SA mapping in the same rule */
1777			return -EOPNOTSUPP;
1778		}
1779		break;
1780	default:
1781		return -EOPNOTSUPP;
1782	}
1783
1784	if ((fs->flow_type & FLOW_EXT) && fs->m_ext.vlan_tci) {
1785		if (fs->m_ext.vlan_tci != htons(0xffff))
1786			return -EOPNOTSUPP;
1787		vid = be16_to_cpu(fs->h_ext.vlan_tci) & VLAN_VID_MASK;
1788	}
1789
1790	idr_for_each_entry(&chip->policies, policy, id) {
1791		if (policy->port == port && policy->mapping == mapping &&
1792		    policy->action == action && policy->vid == vid &&
1793		    ether_addr_equal(policy->addr, addr))
1794			return -EEXIST;
1795	}
1796
1797	policy = devm_kzalloc(chip->dev, sizeof(*policy), GFP_KERNEL);
1798	if (!policy)
1799		return -ENOMEM;
1800
1801	fs->location = 0;
1802	err = idr_alloc_u32(&chip->policies, policy, &fs->location, 0xffffffff,
1803			    GFP_KERNEL);
1804	if (err) {
1805		devm_kfree(chip->dev, policy);
1806		return err;
1807	}
1808
1809	memcpy(&policy->fs, fs, sizeof(*fs));
1810	ether_addr_copy(policy->addr, addr);
1811	policy->mapping = mapping;
1812	policy->action = action;
1813	policy->port = port;
1814	policy->vid = vid;
1815
1816	err = mv88e6xxx_policy_apply(chip, port, policy);
1817	if (err) {
1818		idr_remove(&chip->policies, fs->location);
1819		devm_kfree(chip->dev, policy);
1820		return err;
1821	}
1822
1823	return 0;
1824}
1825
1826static int mv88e6xxx_get_rxnfc(struct dsa_switch *ds, int port,
1827			       struct ethtool_rxnfc *rxnfc, u32 *rule_locs)
1828{
1829	struct ethtool_rx_flow_spec *fs = &rxnfc->fs;
1830	struct mv88e6xxx_chip *chip = ds->priv;
1831	struct mv88e6xxx_policy *policy;
1832	int err;
1833	int id;
1834
1835	mv88e6xxx_reg_lock(chip);
1836
1837	switch (rxnfc->cmd) {
1838	case ETHTOOL_GRXCLSRLCNT:
1839		rxnfc->data = 0;
1840		rxnfc->data |= RX_CLS_LOC_SPECIAL;
1841		rxnfc->rule_cnt = 0;
1842		idr_for_each_entry(&chip->policies, policy, id)
1843			if (policy->port == port)
1844				rxnfc->rule_cnt++;
1845		err = 0;
1846		break;
1847	case ETHTOOL_GRXCLSRULE:
1848		err = -ENOENT;
1849		policy = idr_find(&chip->policies, fs->location);
1850		if (policy) {
1851			memcpy(fs, &policy->fs, sizeof(*fs));
1852			err = 0;
1853		}
1854		break;
1855	case ETHTOOL_GRXCLSRLALL:
1856		rxnfc->data = 0;
1857		rxnfc->rule_cnt = 0;
1858		idr_for_each_entry(&chip->policies, policy, id)
1859			if (policy->port == port)
1860				rule_locs[rxnfc->rule_cnt++] = id;
1861		err = 0;
1862		break;
1863	default:
1864		err = -EOPNOTSUPP;
1865		break;
1866	}
1867
1868	mv88e6xxx_reg_unlock(chip);
1869
1870	return err;
1871}
1872
1873static int mv88e6xxx_set_rxnfc(struct dsa_switch *ds, int port,
1874			       struct ethtool_rxnfc *rxnfc)
1875{
1876	struct ethtool_rx_flow_spec *fs = &rxnfc->fs;
1877	struct mv88e6xxx_chip *chip = ds->priv;
1878	struct mv88e6xxx_policy *policy;
1879	int err;
1880
1881	mv88e6xxx_reg_lock(chip);
1882
1883	switch (rxnfc->cmd) {
1884	case ETHTOOL_SRXCLSRLINS:
1885		err = mv88e6xxx_policy_insert(chip, port, fs);
1886		break;
1887	case ETHTOOL_SRXCLSRLDEL:
1888		err = -ENOENT;
1889		policy = idr_remove(&chip->policies, fs->location);
1890		if (policy) {
1891			policy->action = MV88E6XXX_POLICY_ACTION_NORMAL;
1892			err = mv88e6xxx_policy_apply(chip, port, policy);
1893			devm_kfree(chip->dev, policy);
1894		}
1895		break;
1896	default:
1897		err = -EOPNOTSUPP;
1898		break;
1899	}
1900
1901	mv88e6xxx_reg_unlock(chip);
1902
1903	return err;
1904}
1905
1906static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port,
1907					u16 vid)
1908{
1909	const char broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1910	u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC;
1911
1912	return mv88e6xxx_port_db_load_purge(chip, port, broadcast, vid, state);
1913}
1914
1915static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid)
1916{
1917	int port;
1918	int err;
1919
1920	for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
1921		err = mv88e6xxx_port_add_broadcast(chip, port, vid);
1922		if (err)
1923			return err;
1924	}
1925
1926	return 0;
1927}
1928
1929static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port,
1930				    u16 vid, u8 member, bool warn)
1931{
1932	const u8 non_member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
1933	struct mv88e6xxx_vtu_entry vlan;
1934	int i, err;
1935
1936	if (!vid)
1937		return -EOPNOTSUPP;
1938
1939	vlan.vid = vid - 1;
1940	vlan.valid = false;
1941
1942	err = mv88e6xxx_vtu_getnext(chip, &vlan);
1943	if (err)
1944		return err;
1945
1946	if (vlan.vid != vid || !vlan.valid) {
1947		memset(&vlan, 0, sizeof(vlan));
1948
1949		err = mv88e6xxx_atu_new(chip, &vlan.fid);
1950		if (err)
1951			return err;
1952
1953		for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
1954			if (i == port)
1955				vlan.member[i] = member;
1956			else
1957				vlan.member[i] = non_member;
1958
1959		vlan.vid = vid;
1960		vlan.valid = true;
1961
1962		err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
1963		if (err)
1964			return err;
1965
1966		err = mv88e6xxx_broadcast_setup(chip, vlan.vid);
1967		if (err)
1968			return err;
1969	} else if (vlan.member[port] != member) {
1970		vlan.member[port] = member;
1971
1972		err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
1973		if (err)
1974			return err;
1975	} else if (warn) {
1976		dev_info(chip->dev, "p%d: already a member of VLAN %d\n",
1977			 port, vid);
1978	}
1979
1980	return 0;
1981}
1982
1983static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
1984				    const struct switchdev_obj_port_vlan *vlan)
1985{
1986	struct mv88e6xxx_chip *chip = ds->priv;
1987	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
1988	bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
1989	bool warn;
1990	u8 member;
1991	u16 vid;
1992
1993	if (!chip->info->max_vid)
1994		return;
1995
1996	if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
1997		member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED;
1998	else if (untagged)
1999		member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNTAGGED;
2000	else
2001		member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_TAGGED;
2002
2003	/* net/dsa/slave.c will call dsa_port_vlan_add() for the affected port
2004	 * and then the CPU port. Do not warn for duplicates for the CPU port.
2005	 */
2006	warn = !dsa_is_cpu_port(ds, port) && !dsa_is_dsa_port(ds, port);
2007
2008	mv88e6xxx_reg_lock(chip);
2009
2010	for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid)
2011		if (mv88e6xxx_port_vlan_join(chip, port, vid, member, warn))
2012			dev_err(ds->dev, "p%d: failed to add VLAN %d%c\n", port,
2013				vid, untagged ? 'u' : 't');
2014
2015	if (pvid && mv88e6xxx_port_set_pvid(chip, port, vlan->vid_end))
2016		dev_err(ds->dev, "p%d: failed to set PVID %d\n", port,
2017			vlan->vid_end);
2018
2019	mv88e6xxx_reg_unlock(chip);
2020}
2021
2022static int mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip *chip,
2023				     int port, u16 vid)
2024{
2025	struct mv88e6xxx_vtu_entry vlan;
2026	int i, err;
2027
2028	if (!vid)
2029		return -EOPNOTSUPP;
2030
2031	vlan.vid = vid - 1;
2032	vlan.valid = false;
2033
2034	err = mv88e6xxx_vtu_getnext(chip, &vlan);
2035	if (err)
2036		return err;
2037
2038	/* If the VLAN doesn't exist in hardware or the port isn't a member,
2039	 * tell switchdev that this VLAN is likely handled in software.
2040	 */
2041	if (vlan.vid != vid || !vlan.valid ||
2042	    vlan.member[port] == MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
2043		return -EOPNOTSUPP;
2044
2045	vlan.member[port] = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
2046
2047	/* keep the VLAN unless all ports are excluded */
2048	vlan.valid = false;
2049	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
2050		if (vlan.member[i] !=
2051		    MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
2052			vlan.valid = true;
2053			break;
2054		}
2055	}
2056
2057	err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
2058	if (err)
2059		return err;
2060
2061	return mv88e6xxx_g1_atu_remove(chip, vlan.fid, port, false);
2062}
2063
2064static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
2065				   const struct switchdev_obj_port_vlan *vlan)
2066{
2067	struct mv88e6xxx_chip *chip = ds->priv;
2068	u16 pvid, vid;
2069	int err = 0;
2070
2071	if (!chip->info->max_vid)
2072		return -EOPNOTSUPP;
2073
2074	mv88e6xxx_reg_lock(chip);
2075
2076	err = mv88e6xxx_port_get_pvid(chip, port, &pvid);
2077	if (err)
2078		goto unlock;
2079
2080	for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
2081		err = mv88e6xxx_port_vlan_leave(chip, port, vid);
2082		if (err)
2083			goto unlock;
2084
2085		if (vid == pvid) {
2086			err = mv88e6xxx_port_set_pvid(chip, port, 0);
2087			if (err)
2088				goto unlock;
2089		}
2090	}
2091
2092unlock:
2093	mv88e6xxx_reg_unlock(chip);
2094
2095	return err;
2096}
2097
2098static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
2099				  const unsigned char *addr, u16 vid)
2100{
2101	struct mv88e6xxx_chip *chip = ds->priv;
2102	int err;
2103
2104	mv88e6xxx_reg_lock(chip);
2105	err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
2106					   MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
2107	mv88e6xxx_reg_unlock(chip);
2108
2109	return err;
2110}
2111
2112static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
2113				  const unsigned char *addr, u16 vid)
2114{
2115	struct mv88e6xxx_chip *chip = ds->priv;
2116	int err;
2117
2118	mv88e6xxx_reg_lock(chip);
2119	err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, 0);
2120	mv88e6xxx_reg_unlock(chip);
2121
2122	return err;
2123}
2124
2125static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
2126				      u16 fid, u16 vid, int port,
2127				      dsa_fdb_dump_cb_t *cb, void *data)
2128{
2129	struct mv88e6xxx_atu_entry addr;
2130	bool is_static;
2131	int err;
2132
2133	addr.state = 0;
2134	eth_broadcast_addr(addr.mac);
2135
2136	do {
2137		err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr);
2138		if (err)
2139			return err;
2140
2141		if (!addr.state)
2142			break;
2143
2144		if (addr.trunk || (addr.portvec & BIT(port)) == 0)
2145			continue;
2146
2147		if (!is_unicast_ether_addr(addr.mac))
2148			continue;
2149
2150		is_static = (addr.state ==
2151			     MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
2152		err = cb(addr.mac, vid, is_static, data);
2153		if (err)
2154			return err;
2155	} while (!is_broadcast_ether_addr(addr.mac));
2156
2157	return err;
2158}
2159
2160static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
2161				  dsa_fdb_dump_cb_t *cb, void *data)
2162{
2163	struct mv88e6xxx_vtu_entry vlan;
2164	u16 fid;
2165	int err;
2166
2167	/* Dump port's default Filtering Information Database (VLAN ID 0) */
2168	err = mv88e6xxx_port_get_fid(chip, port, &fid);
2169	if (err)
2170		return err;
2171
2172	err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, cb, data);
2173	if (err)
2174		return err;
2175
2176	/* Dump VLANs' Filtering Information Databases */
2177	vlan.vid = chip->info->max_vid;
2178	vlan.valid = false;
2179
2180	do {
2181		err = mv88e6xxx_vtu_getnext(chip, &vlan);
2182		if (err)
2183			return err;
2184
2185		if (!vlan.valid)
2186			break;
2187
2188		err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,
2189						 cb, data);
2190		if (err)
2191			return err;
2192	} while (vlan.vid < chip->info->max_vid);
2193
2194	return err;
2195}
2196
2197static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
2198				   dsa_fdb_dump_cb_t *cb, void *data)
2199{
2200	struct mv88e6xxx_chip *chip = ds->priv;
2201	int err;
2202
2203	mv88e6xxx_reg_lock(chip);
2204	err = mv88e6xxx_port_db_dump(chip, port, cb, data);
2205	mv88e6xxx_reg_unlock(chip);
2206
2207	return err;
2208}
2209
2210static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip,
2211				struct net_device *br)
2212{
2213	struct dsa_switch *ds = chip->ds;
2214	struct dsa_switch_tree *dst = ds->dst;
2215	struct dsa_port *dp;
2216	int err;
2217
2218	list_for_each_entry(dp, &dst->ports, list) {
2219		if (dp->bridge_dev == br) {
2220			if (dp->ds == ds) {
2221				/* This is a local bridge group member,
2222				 * remap its Port VLAN Map.
2223				 */
2224				err = mv88e6xxx_port_vlan_map(chip, dp->index);
2225				if (err)
2226					return err;
2227			} else {
2228				/* This is an external bridge group member,
2229				 * remap its cross-chip Port VLAN Table entry.
2230				 */
2231				err = mv88e6xxx_pvt_map(chip, dp->ds->index,
2232							dp->index);
2233				if (err)
2234					return err;
2235			}
2236		}
2237	}
2238
2239	return 0;
2240}
2241
2242static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
2243				      struct net_device *br)
2244{
2245	struct mv88e6xxx_chip *chip = ds->priv;
2246	int err;
2247
2248	mv88e6xxx_reg_lock(chip);
2249	err = mv88e6xxx_bridge_map(chip, br);
2250	mv88e6xxx_reg_unlock(chip);
2251
2252	return err;
2253}
2254
2255static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port,
2256					struct net_device *br)
2257{
2258	struct mv88e6xxx_chip *chip = ds->priv;
2259
2260	mv88e6xxx_reg_lock(chip);
2261	if (mv88e6xxx_bridge_map(chip, br) ||
2262	    mv88e6xxx_port_vlan_map(chip, port))
2263		dev_err(ds->dev, "failed to remap in-chip Port VLAN\n");
2264	mv88e6xxx_reg_unlock(chip);
2265}
2266
2267static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds,
2268					   int tree_index, int sw_index,
2269					   int port, struct net_device *br)
2270{
2271	struct mv88e6xxx_chip *chip = ds->priv;
2272	int err;
2273
2274	if (tree_index != ds->dst->index)
2275		return 0;
2276
2277	mv88e6xxx_reg_lock(chip);
2278	err = mv88e6xxx_pvt_map(chip, sw_index, port);
2279	mv88e6xxx_reg_unlock(chip);
2280
2281	return err;
2282}
2283
2284static void mv88e6xxx_crosschip_bridge_leave(struct dsa_switch *ds,
2285					     int tree_index, int sw_index,
2286					     int port, struct net_device *br)
2287{
2288	struct mv88e6xxx_chip *chip = ds->priv;
2289
2290	if (tree_index != ds->dst->index)
2291		return;
2292
2293	mv88e6xxx_reg_lock(chip);
2294	if (mv88e6xxx_pvt_map(chip, sw_index, port))
2295		dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n");
2296	mv88e6xxx_reg_unlock(chip);
2297}
2298
2299static int mv88e6xxx_software_reset(struct mv88e6xxx_chip *chip)
2300{
2301	if (chip->info->ops->reset)
2302		return chip->info->ops->reset(chip);
2303
2304	return 0;
2305}
2306
2307static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
2308{
2309	struct gpio_desc *gpiod = chip->reset;
2310
2311	/* If there is a GPIO connected to the reset pin, toggle it */
2312	if (gpiod) {
2313		/* If the switch has just been reset and not yet completed
2314		 * loading EEPROM, the reset may interrupt the I2C transaction
2315		 * mid-byte, causing the first EEPROM read after the reset
2316		 * from the wrong location resulting in the switch booting
2317		 * to wrong mode and inoperable.
2318		 */
2319		if (chip->info->ops->get_eeprom)
2320			mv88e6xxx_g2_eeprom_wait(chip);
2321
2322		gpiod_set_value_cansleep(gpiod, 1);
2323		usleep_range(10000, 20000);
2324		gpiod_set_value_cansleep(gpiod, 0);
2325		usleep_range(10000, 20000);
2326
2327		if (chip->info->ops->get_eeprom)
2328			mv88e6xxx_g2_eeprom_wait(chip);
2329	}
2330}
2331
2332static int mv88e6xxx_disable_ports(struct mv88e6xxx_chip *chip)
2333{
2334	int i, err;
2335
2336	/* Set all ports to the Disabled state */
2337	for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
2338		err = mv88e6xxx_port_set_state(chip, i, BR_STATE_DISABLED);
2339		if (err)
2340			return err;
2341	}
2342
2343	/* Wait for transmit queues to drain,
2344	 * i.e. 2ms for a maximum frame to be transmitted at 10 Mbps.
2345	 */
2346	usleep_range(2000, 4000);
2347
2348	return 0;
2349}
2350
2351static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
2352{
2353	int err;
2354
2355	err = mv88e6xxx_disable_ports(chip);
2356	if (err)
2357		return err;
2358
2359	mv88e6xxx_hardware_reset(chip);
2360
2361	return mv88e6xxx_software_reset(chip);
2362}
2363
2364static int mv88e6xxx_set_port_mode(struct mv88e6xxx_chip *chip, int port,
2365				   enum mv88e6xxx_frame_mode frame,
2366				   enum mv88e6xxx_egress_mode egress, u16 etype)
2367{
2368	int err;
2369
2370	if (!chip->info->ops->port_set_frame_mode)
2371		return -EOPNOTSUPP;
2372
2373	err = mv88e6xxx_port_set_egress_mode(chip, port, egress);
2374	if (err)
2375		return err;
2376
2377	err = chip->info->ops->port_set_frame_mode(chip, port, frame);
2378	if (err)
2379		return err;
2380
2381	if (chip->info->ops->port_set_ether_type)
2382		return chip->info->ops->port_set_ether_type(chip, port, etype);
2383
2384	return 0;
2385}
2386
2387static int mv88e6xxx_set_port_mode_normal(struct mv88e6xxx_chip *chip, int port)
2388{
2389	return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_NORMAL,
2390				       MV88E6XXX_EGRESS_MODE_UNMODIFIED,
2391				       MV88E6XXX_PORT_ETH_TYPE_DEFAULT);
2392}
2393
2394static int mv88e6xxx_set_port_mode_dsa(struct mv88e6xxx_chip *chip, int port)
2395{
2396	return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_DSA,
2397				       MV88E6XXX_EGRESS_MODE_UNMODIFIED,
2398				       MV88E6XXX_PORT_ETH_TYPE_DEFAULT);
2399}
2400
2401static int mv88e6xxx_set_port_mode_edsa(struct mv88e6xxx_chip *chip, int port)
2402{
2403	return mv88e6xxx_set_port_mode(chip, port,
2404				       MV88E6XXX_FRAME_MODE_ETHERTYPE,
2405				       MV88E6XXX_EGRESS_MODE_ETHERTYPE,
2406				       ETH_P_EDSA);
2407}
2408
2409static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)
2410{
2411	if (dsa_is_dsa_port(chip->ds, port))
2412		return mv88e6xxx_set_port_mode_dsa(chip, port);
2413
2414	if (dsa_is_user_port(chip->ds, port))
2415		return mv88e6xxx_set_port_mode_normal(chip, port);
2416
2417	/* Setup CPU port mode depending on its supported tag format */
2418	if (chip->info->tag_protocol == DSA_TAG_PROTO_DSA)
2419		return mv88e6xxx_set_port_mode_dsa(chip, port);
2420
2421	if (chip->info->tag_protocol == DSA_TAG_PROTO_EDSA)
2422		return mv88e6xxx_set_port_mode_edsa(chip, port);
2423
2424	return -EINVAL;
2425}
2426
2427static int mv88e6xxx_setup_message_port(struct mv88e6xxx_chip *chip, int port)
2428{
2429	bool message = dsa_is_dsa_port(chip->ds, port);
2430
2431	return mv88e6xxx_port_set_message_port(chip, port, message);
2432}
2433
2434static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
2435{
2436	struct dsa_switch *ds = chip->ds;
2437	bool flood;
2438
2439	/* Upstream ports flood frames with unknown unicast or multicast DA */
2440	flood = dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port);
2441	if (chip->info->ops->port_set_egress_floods)
2442		return chip->info->ops->port_set_egress_floods(chip, port,
2443							       flood, flood);
2444
2445	return 0;
2446}
2447
2448static irqreturn_t mv88e6xxx_serdes_irq_thread_fn(int irq, void *dev_id)
2449{
2450	struct mv88e6xxx_port *mvp = dev_id;
2451	struct mv88e6xxx_chip *chip = mvp->chip;
2452	irqreturn_t ret = IRQ_NONE;
2453	int port = mvp->port;
2454	u8 lane;
2455
2456	mv88e6xxx_reg_lock(chip);
2457	lane = mv88e6xxx_serdes_get_lane(chip, port);
2458	if (lane)
2459		ret = mv88e6xxx_serdes_irq_status(chip, port, lane);
2460	mv88e6xxx_reg_unlock(chip);
2461
2462	return ret;
2463}
2464
2465static int mv88e6xxx_serdes_irq_request(struct mv88e6xxx_chip *chip, int port,
2466					u8 lane)
2467{
2468	struct mv88e6xxx_port *dev_id = &chip->ports[port];
2469	unsigned int irq;
2470	int err;
2471
2472	/* Nothing to request if this SERDES port has no IRQ */
2473	irq = mv88e6xxx_serdes_irq_mapping(chip, port);
2474	if (!irq)
2475		return 0;
2476
2477	snprintf(dev_id->serdes_irq_name, sizeof(dev_id->serdes_irq_name),
2478		 "mv88e6xxx-%s-serdes-%d", dev_name(chip->dev), port);
2479
2480	/* Requesting the IRQ will trigger IRQ callbacks, so release the lock */
2481	mv88e6xxx_reg_unlock(chip);
2482	err = request_threaded_irq(irq, NULL, mv88e6xxx_serdes_irq_thread_fn,
2483				   IRQF_ONESHOT, dev_id->serdes_irq_name,
2484				   dev_id);
2485	mv88e6xxx_reg_lock(chip);
2486	if (err)
2487		return err;
2488
2489	dev_id->serdes_irq = irq;
2490
2491	return mv88e6xxx_serdes_irq_enable(chip, port, lane);
2492}
2493
2494static int mv88e6xxx_serdes_irq_free(struct mv88e6xxx_chip *chip, int port,
2495				     u8 lane)
2496{
2497	struct mv88e6xxx_port *dev_id = &chip->ports[port];
2498	unsigned int irq = dev_id->serdes_irq;
2499	int err;
2500
2501	/* Nothing to free if no IRQ has been requested */
2502	if (!irq)
2503		return 0;
2504
2505	err = mv88e6xxx_serdes_irq_disable(chip, port, lane);
2506
2507	/* Freeing the IRQ will trigger IRQ callbacks, so release the lock */
2508	mv88e6xxx_reg_unlock(chip);
2509	free_irq(irq, dev_id);
2510	mv88e6xxx_reg_lock(chip);
2511
2512	dev_id->serdes_irq = 0;
2513
2514	return err;
2515}
2516
2517static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
2518				  bool on)
2519{
2520	u8 lane;
2521	int err;
2522
2523	lane = mv88e6xxx_serdes_get_lane(chip, port);
2524	if (!lane)
2525		return 0;
2526
2527	if (on) {
2528		err = mv88e6xxx_serdes_power_up(chip, port, lane);
2529		if (err)
2530			return err;
2531
2532		err = mv88e6xxx_serdes_irq_request(chip, port, lane);
2533	} else {
2534		err = mv88e6xxx_serdes_irq_free(chip, port, lane);
2535		if (err)
2536			return err;
2537
2538		err = mv88e6xxx_serdes_power_down(chip, port, lane);
2539	}
2540
2541	return err;
2542}
2543
2544static int mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip *chip, int port)
2545{
2546	struct dsa_switch *ds = chip->ds;
2547	int upstream_port;
2548	int err;
2549
2550	upstream_port = dsa_upstream_port(ds, port);
2551	if (chip->info->ops->port_set_upstream_port) {
2552		err = chip->info->ops->port_set_upstream_port(chip, port,
2553							      upstream_port);
2554		if (err)
2555			return err;
2556	}
2557
2558	if (port == upstream_port) {
2559		if (chip->info->ops->set_cpu_port) {
2560			err = chip->info->ops->set_cpu_port(chip,
2561							    upstream_port);
2562			if (err)
2563				return err;
2564		}
2565
2566		if (chip->info->ops->set_egress_port) {
2567			err = chip->info->ops->set_egress_port(chip,
2568						MV88E6XXX_EGRESS_DIR_INGRESS,
2569						upstream_port);
2570			if (err)
2571				return err;
2572
2573			err = chip->info->ops->set_egress_port(chip,
2574						MV88E6XXX_EGRESS_DIR_EGRESS,
2575						upstream_port);
2576			if (err)
2577				return err;
2578		}
2579	}
2580
2581	return 0;
2582}
2583
2584static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
2585{
2586	struct dsa_switch *ds = chip->ds;
2587	int err;
2588	u16 reg;
2589
2590	chip->ports[port].chip = chip;
2591	chip->ports[port].port = port;
2592
2593	/* MAC Forcing register: don't force link, speed, duplex or flow control
2594	 * state to any particular values on physical ports, but force the CPU
2595	 * port and all DSA ports to their maximum bandwidth and full duplex.
2596	 */
2597	if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))
2598		err = mv88e6xxx_port_setup_mac(chip, port, LINK_FORCED_UP,
2599					       SPEED_MAX, DUPLEX_FULL,
2600					       PAUSE_OFF,
2601					       PHY_INTERFACE_MODE_NA);
2602	else
2603		err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED,
2604					       SPEED_UNFORCED, DUPLEX_UNFORCED,
2605					       PAUSE_ON,
2606					       PHY_INTERFACE_MODE_NA);
2607	if (err)
2608		return err;
2609
2610	/* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
2611	 * disable Header mode, enable IGMP/MLD snooping, disable VLAN
2612	 * tunneling, determine priority by looking at 802.1p and IP
2613	 * priority fields (IP prio has precedence), and set STP state
2614	 * to Forwarding.
2615	 *
2616	 * If this is the CPU link, use DSA or EDSA tagging depending
2617	 * on which tagging mode was configured.
2618	 *
2619	 * If this is a link to another switch, use DSA tagging mode.
2620	 *
2621	 * If this is the upstream port for this switch, enable
2622	 * forwarding of unknown unicasts and multicasts.
2623	 */
2624	reg = MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
2625		MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
2626	/* Forward any IPv4 IGMP or IPv6 MLD frames received
2627	 * by a USER port to the CPU port to allow snooping.
2628	 */
2629	if (dsa_is_user_port(ds, port))
2630		reg |= MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP;
2631
2632	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
2633	if (err)
2634		return err;
2635
2636	err = mv88e6xxx_setup_port_mode(chip, port);
2637	if (err)
2638		return err;
2639
2640	err = mv88e6xxx_setup_egress_floods(chip, port);
2641	if (err)
2642		return err;
2643
2644	/* Port Control 2: don't force a good FCS, set the MTU size to
2645	 * 10222 bytes, disable 802.1q tags checking, don't discard tagged or
2646	 * untagged frames on this port, do a destination address lookup on all
2647	 * received packets as usual, disable ARP mirroring and don't send a
2648	 * copy of all transmitted/received frames on this port to the CPU.
2649	 */
2650	err = mv88e6xxx_port_set_map_da(chip, port);
2651	if (err)
2652		return err;
2653
2654	err = mv88e6xxx_setup_upstream_port(chip, port);
2655	if (err)
2656		return err;
2657
2658	err = mv88e6xxx_port_set_8021q_mode(chip, port,
2659				MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED);
2660	if (err)
2661		return err;
2662
2663	if (chip->info->ops->port_set_jumbo_size) {
2664		err = chip->info->ops->port_set_jumbo_size(chip, port, 10218);
2665		if (err)
2666			return err;
2667	}
2668
2669	/* Port Association Vector: when learning source addresses
2670	 * of packets, add the address to the address database using
2671	 * a port bitmap that has only the bit for this port set and
2672	 * the other bits clear.
2673	 */
2674	reg = 1 << port;
2675	/* Disable learning for CPU port */
2676	if (dsa_is_cpu_port(ds, port))
2677		reg = 0;
2678
2679	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
2680				   reg);
2681	if (err)
2682		return err;
2683
2684	/* Egress rate control 2: disable egress rate control. */
2685	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL2,
2686				   0x0000);
2687	if (err)
2688		return err;
2689
2690	if (chip->info->ops->port_pause_limit) {
2691		err = chip->info->ops->port_pause_limit(chip, port, 0, 0);
2692		if (err)
2693			return err;
2694	}
2695
2696	if (chip->info->ops->port_disable_learn_limit) {
2697		err = chip->info->ops->port_disable_learn_limit(chip, port);
2698		if (err)
2699			return err;
2700	}
2701
2702	if (chip->info->ops->port_disable_pri_override) {
2703		err = chip->info->ops->port_disable_pri_override(chip, port);
2704		if (err)
2705			return err;
2706	}
2707
2708	if (chip->info->ops->port_tag_remap) {
2709		err = chip->info->ops->port_tag_remap(chip, port);
2710		if (err)
2711			return err;
2712	}
2713
2714	if (chip->info->ops->port_egress_rate_limiting) {
2715		err = chip->info->ops->port_egress_rate_limiting(chip, port);
2716		if (err)
2717			return err;
2718	}
2719
2720	if (chip->info->ops->port_setup_message_port) {
2721		err = chip->info->ops->port_setup_message_port(chip, port);
2722		if (err)
2723			return err;
2724	}
2725
2726	/* Port based VLAN map: give each port the same default address
2727	 * database, and allow bidirectional communication between the
2728	 * CPU and DSA port(s), and the other ports.
2729	 */
2730	err = mv88e6xxx_port_set_fid(chip, port, 0);
2731	if (err)
2732		return err;
2733
2734	err = mv88e6xxx_port_vlan_map(chip, port);
2735	if (err)
2736		return err;
2737
2738	/* Default VLAN ID and priority: don't set a default VLAN
2739	 * ID, and set the default packet priority to zero.
2740	 */
2741	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 0);
2742}
2743
2744static int mv88e6xxx_get_max_mtu(struct dsa_switch *ds, int port)
2745{
2746	struct mv88e6xxx_chip *chip = ds->priv;
2747
2748	if (chip->info->ops->port_set_jumbo_size)
2749		return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
2750	else if (chip->info->ops->set_max_frame_size)
2751		return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
2752	return ETH_DATA_LEN;
2753}
2754
2755static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
2756{
2757	struct mv88e6xxx_chip *chip = ds->priv;
2758	int ret = 0;
2759
2760	/* For families where we don't know how to alter the MTU,
2761	 * just accept any value up to ETH_DATA_LEN
2762	 */
2763	if (!chip->info->ops->port_set_jumbo_size &&
2764	    !chip->info->ops->set_max_frame_size) {
2765		if (new_mtu > ETH_DATA_LEN)
2766			return -EINVAL;
2767
2768		return 0;
2769	}
2770
2771	if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
2772		new_mtu += EDSA_HLEN;
2773
2774	mv88e6xxx_reg_lock(chip);
2775	if (chip->info->ops->port_set_jumbo_size)
2776		ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu);
2777	else if (chip->info->ops->set_max_frame_size)
2778		ret = chip->info->ops->set_max_frame_size(chip, new_mtu);
2779	mv88e6xxx_reg_unlock(chip);
2780
2781	return ret;
2782}
2783
2784static int mv88e6xxx_port_enable(struct dsa_switch *ds, int port,
2785				 struct phy_device *phydev)
2786{
2787	struct mv88e6xxx_chip *chip = ds->priv;
2788	int err;
2789
2790	mv88e6xxx_reg_lock(chip);
2791	err = mv88e6xxx_serdes_power(chip, port, true);
2792	mv88e6xxx_reg_unlock(chip);
2793
2794	return err;
2795}
2796
2797static void mv88e6xxx_port_disable(struct dsa_switch *ds, int port)
2798{
2799	struct mv88e6xxx_chip *chip = ds->priv;
2800
2801	mv88e6xxx_reg_lock(chip);
2802	if (mv88e6xxx_serdes_power(chip, port, false))
2803		dev_err(chip->dev, "failed to power off SERDES\n");
2804	mv88e6xxx_reg_unlock(chip);
2805}
2806
2807static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds,
2808				     unsigned int ageing_time)
2809{
2810	struct mv88e6xxx_chip *chip = ds->priv;
2811	int err;
2812
2813	mv88e6xxx_reg_lock(chip);
2814	err = mv88e6xxx_g1_atu_set_age_time(chip, ageing_time);
2815	mv88e6xxx_reg_unlock(chip);
2816
2817	return err;
2818}
2819
2820static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip)
2821{
2822	int err;
2823
2824	/* Initialize the statistics unit */
2825	if (chip->info->ops->stats_set_histogram) {
2826		err = chip->info->ops->stats_set_histogram(chip);
2827		if (err)
2828			return err;
2829	}
2830
2831	return mv88e6xxx_g1_stats_clear(chip);
2832}
2833
2834/* Check if the errata has already been applied. */
2835static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip)
2836{
2837	int port;
2838	int err;
2839	u16 val;
2840
2841	for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
2842		err = mv88e6xxx_port_hidden_read(chip, 0xf, port, 0, &val);
2843		if (err) {
2844			dev_err(chip->dev,
2845				"Error reading hidden register: %d\n", err);
2846			return false;
2847		}
2848		if (val != 0x01c0)
2849			return false;
2850	}
2851
2852	return true;
2853}
2854
2855/* The 6390 copper ports have an errata which require poking magic
2856 * values into undocumented hidden registers and then performing a
2857 * software reset.
2858 */
2859static int mv88e6390_setup_errata(struct mv88e6xxx_chip *chip)
2860{
2861	int port;
2862	int err;
2863
2864	if (mv88e6390_setup_errata_applied(chip))
2865		return 0;
2866
2867	/* Set the ports into blocking mode */
2868	for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
2869		err = mv88e6xxx_port_set_state(chip, port, BR_STATE_DISABLED);
2870		if (err)
2871			return err;
2872	}
2873
2874	for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
2875		err = mv88e6xxx_port_hidden_write(chip, 0xf, port, 0, 0x01c0);
2876		if (err)
2877			return err;
2878	}
2879
2880	return mv88e6xxx_software_reset(chip);
2881}
2882
2883static void mv88e6xxx_teardown(struct dsa_switch *ds)
2884{
2885	mv88e6xxx_teardown_devlink_params(ds);
2886	dsa_devlink_resources_unregister(ds);
2887	mv88e6xxx_teardown_devlink_regions(ds);
2888}
2889
2890static int mv88e6xxx_setup(struct dsa_switch *ds)
2891{
2892	struct mv88e6xxx_chip *chip = ds->priv;
2893	u8 cmode;
2894	int err;
2895	int i;
2896
2897	chip->ds = ds;
2898	ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip);
2899
2900	mv88e6xxx_reg_lock(chip);
2901
2902	if (chip->info->ops->setup_errata) {
2903		err = chip->info->ops->setup_errata(chip);
2904		if (err)
2905			goto unlock;
2906	}
2907
2908	/* Cache the cmode of each port. */
2909	for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
2910		if (chip->info->ops->port_get_cmode) {
2911			err = chip->info->ops->port_get_cmode(chip, i, &cmode);
2912			if (err)
2913				goto unlock;
2914
2915			chip->ports[i].cmode = cmode;
2916		}
2917	}
2918
2919	/* Setup Switch Port Registers */
2920	for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
2921		if (dsa_is_unused_port(ds, i))
2922			continue;
2923
2924		/* Prevent the use of an invalid port. */
2925		if (mv88e6xxx_is_invalid_port(chip, i)) {
2926			dev_err(chip->dev, "port %d is invalid\n", i);
2927			err = -EINVAL;
2928			goto unlock;
2929		}
2930
2931		err = mv88e6xxx_setup_port(chip, i);
2932		if (err)
2933			goto unlock;
2934	}
2935
2936	err = mv88e6xxx_irl_setup(chip);
2937	if (err)
2938		goto unlock;
2939
2940	err = mv88e6xxx_mac_setup(chip);
2941	if (err)
2942		goto unlock;
2943
2944	err = mv88e6xxx_phy_setup(chip);
2945	if (err)
2946		goto unlock;
2947
2948	err = mv88e6xxx_vtu_setup(chip);
2949	if (err)
2950		goto unlock;
2951
2952	err = mv88e6xxx_pvt_setup(chip);
2953	if (err)
2954		goto unlock;
2955
2956	err = mv88e6xxx_atu_setup(chip);
2957	if (err)
2958		goto unlock;
2959
2960	err = mv88e6xxx_broadcast_setup(chip, 0);
2961	if (err)
2962		goto unlock;
2963
2964	err = mv88e6xxx_pot_setup(chip);
2965	if (err)
2966		goto unlock;
2967
2968	err = mv88e6xxx_rmu_setup(chip);
2969	if (err)
2970		goto unlock;
2971
2972	err = mv88e6xxx_rsvd2cpu_setup(chip);
2973	if (err)
2974		goto unlock;
2975
2976	err = mv88e6xxx_trunk_setup(chip);
2977	if (err)
2978		goto unlock;
2979
2980	err = mv88e6xxx_devmap_setup(chip);
2981	if (err)
2982		goto unlock;
2983
2984	err = mv88e6xxx_pri_setup(chip);
2985	if (err)
2986		goto unlock;
2987
2988	/* Setup PTP Hardware Clock and timestamping */
2989	if (chip->info->ptp_support) {
2990		err = mv88e6xxx_ptp_setup(chip);
2991		if (err)
2992			goto unlock;
2993
2994		err = mv88e6xxx_hwtstamp_setup(chip);
2995		if (err)
2996			goto unlock;
2997	}
2998
2999	err = mv88e6xxx_stats_setup(chip);
3000	if (err)
3001		goto unlock;
3002
3003unlock:
3004	mv88e6xxx_reg_unlock(chip);
3005
3006	if (err)
3007		return err;
3008
3009	/* Have to be called without holding the register lock, since
3010	 * they take the devlink lock, and we later take the locks in
3011	 * the reverse order when getting/setting parameters or
3012	 * resource occupancy.
3013	 */
3014	err = mv88e6xxx_setup_devlink_resources(ds);
3015	if (err)
3016		return err;
3017
3018	err = mv88e6xxx_setup_devlink_params(ds);
3019	if (err)
3020		goto out_resources;
3021
3022	err = mv88e6xxx_setup_devlink_regions(ds);
3023	if (err)
3024		goto out_params;
3025
3026	return 0;
3027
3028out_params:
3029	mv88e6xxx_teardown_devlink_params(ds);
3030out_resources:
3031	dsa_devlink_resources_unregister(ds);
3032
3033	return err;
3034}
3035
3036/* prod_id for switch families which do not have a PHY model number */
3037static const u16 family_prod_id_table[] = {
3038	[MV88E6XXX_FAMILY_6341] = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
3039	[MV88E6XXX_FAMILY_6390] = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
3040};
3041
3042static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
3043{
3044	struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
3045	struct mv88e6xxx_chip *chip = mdio_bus->chip;
3046	u16 prod_id;
3047	u16 val;
3048	int err;
3049
3050	if (!chip->info->ops->phy_read)
3051		return -EOPNOTSUPP;
3052
3053	mv88e6xxx_reg_lock(chip);
3054	err = chip->info->ops->phy_read(chip, bus, phy, reg, &val);
3055	mv88e6xxx_reg_unlock(chip);
3056
3057	/* Some internal PHYs don't have a model number. */
3058	if (reg == MII_PHYSID2 && !(val & 0x3f0) &&
3059	    chip->info->family < ARRAY_SIZE(family_prod_id_table)) {
3060		prod_id = family_prod_id_table[chip->info->family];
3061		if (prod_id)
3062			val |= prod_id >> 4;
3063	}
3064
3065	return err ? err : val;
3066}
3067
3068static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
3069{
3070	struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
3071	struct mv88e6xxx_chip *chip = mdio_bus->chip;
3072	int err;
3073
3074	if (!chip->info->ops->phy_write)
3075		return -EOPNOTSUPP;
3076
3077	mv88e6xxx_reg_lock(chip);
3078	err = chip->info->ops->phy_write(chip, bus, phy, reg, val);
3079	mv88e6xxx_reg_unlock(chip);
3080
3081	return err;
3082}
3083
3084static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
3085				   struct device_node *np,
3086				   bool external)
3087{
3088	static int index;
3089	struct mv88e6xxx_mdio_bus *mdio_bus;
3090	struct mii_bus *bus;
3091	int err;
3092
3093	if (external) {
3094		mv88e6xxx_reg_lock(chip);
3095		err = mv88e6xxx_g2_scratch_gpio_set_smi(chip, true);
3096		mv88e6xxx_reg_unlock(chip);
3097
3098		if (err)
3099			return err;
3100	}
3101
3102	bus = mdiobus_alloc_size(sizeof(*mdio_bus));
3103	if (!bus)
3104		return -ENOMEM;
3105
3106	mdio_bus = bus->priv;
3107	mdio_bus->bus = bus;
3108	mdio_bus->chip = chip;
3109	INIT_LIST_HEAD(&mdio_bus->list);
3110	mdio_bus->external = external;
3111
3112	if (np) {
3113		bus->name = np->full_name;
3114		snprintf(bus->id, MII_BUS_ID_SIZE, "%pOF", np);
3115	} else {
3116		bus->name = "mv88e6xxx SMI";
3117		snprintf(bus->id, MII_BUS_ID_SIZE, "mv88e6xxx-%d", index++);
3118	}
3119
3120	bus->read = mv88e6xxx_mdio_read;
3121	bus->write = mv88e6xxx_mdio_write;
3122	bus->parent = chip->dev;
3123
3124	if (!external) {
3125		err = mv88e6xxx_g2_irq_mdio_setup(chip, bus);
3126		if (err)
3127			goto out;
3128	}
3129
3130	err = of_mdiobus_register(bus, np);
3131	if (err) {
3132		dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err);
3133		mv88e6xxx_g2_irq_mdio_free(chip, bus);
3134		goto out;
3135	}
3136
3137	if (external)
3138		list_add_tail(&mdio_bus->list, &chip->mdios);
3139	else
3140		list_add(&mdio_bus->list, &chip->mdios);
3141
3142	return 0;
3143
3144out:
3145	mdiobus_free(bus);
3146	return err;
3147}
3148
3149static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
3150
3151{
3152	struct mv88e6xxx_mdio_bus *mdio_bus;
3153	struct mii_bus *bus;
3154
3155	list_for_each_entry(mdio_bus, &chip->mdios, list) {
3156		bus = mdio_bus->bus;
3157
3158		if (!mdio_bus->external)
3159			mv88e6xxx_g2_irq_mdio_free(chip, bus);
3160
3161		mdiobus_unregister(bus);
3162		mdiobus_free(bus);
3163	}
3164}
3165
3166static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip,
3167				    struct device_node *np)
3168{
3169	struct device_node *child;
3170	int err;
3171
3172	/* Always register one mdio bus for the internal/default mdio
3173	 * bus. This maybe represented in the device tree, but is
3174	 * optional.
3175	 */
3176	child = of_get_child_by_name(np, "mdio");
3177	err = mv88e6xxx_mdio_register(chip, child, false);
3178	of_node_put(child);
3179	if (err)
3180		return err;
3181
3182	/* Walk the device tree, and see if there are any other nodes
3183	 * which say they are compatible with the external mdio
3184	 * bus.
3185	 */
3186	for_each_available_child_of_node(np, child) {
3187		if (of_device_is_compatible(
3188			    child, "marvell,mv88e6xxx-mdio-external")) {
3189			err = mv88e6xxx_mdio_register(chip, child, true);
3190			if (err) {
3191				mv88e6xxx_mdios_unregister(chip);
3192				of_node_put(child);
3193				return err;
3194			}
3195		}
3196	}
3197
3198	return 0;
3199}
3200
3201static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
3202{
3203	struct mv88e6xxx_chip *chip = ds->priv;
3204
3205	return chip->eeprom_len;
3206}
3207
3208static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
3209				struct ethtool_eeprom *eeprom, u8 *data)
3210{
3211	struct mv88e6xxx_chip *chip = ds->priv;
3212	int err;
3213
3214	if (!chip->info->ops->get_eeprom)
3215		return -EOPNOTSUPP;
3216
3217	mv88e6xxx_reg_lock(chip);
3218	err = chip->info->ops->get_eeprom(chip, eeprom, data);
3219	mv88e6xxx_reg_unlock(chip);
3220
3221	if (err)
3222		return err;
3223
3224	eeprom->magic = 0xc3ec4951;
3225
3226	return 0;
3227}
3228
3229static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
3230				struct ethtool_eeprom *eeprom, u8 *data)
3231{
3232	struct mv88e6xxx_chip *chip = ds->priv;
3233	int err;
3234
3235	if (!chip->info->ops->set_eeprom)
3236		return -EOPNOTSUPP;
3237
3238	if (eeprom->magic != 0xc3ec4951)
3239		return -EINVAL;
3240
3241	mv88e6xxx_reg_lock(chip);
3242	err = chip->info->ops->set_eeprom(chip, eeprom, data);
3243	mv88e6xxx_reg_unlock(chip);
3244
3245	return err;
3246}
3247
3248static const struct mv88e6xxx_ops mv88e6085_ops = {
3249	/* MV88E6XXX_FAMILY_6097 */
3250	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3251	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3252	.irl_init_all = mv88e6352_g2_irl_init_all,
3253	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
3254	.phy_read = mv88e6185_phy_ppu_read,
3255	.phy_write = mv88e6185_phy_ppu_write,
3256	.port_set_link = mv88e6xxx_port_set_link,
3257	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
3258	.port_tag_remap = mv88e6095_port_tag_remap,
3259	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
3260	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
3261	.port_set_ether_type = mv88e6351_port_set_ether_type,
3262	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3263	.port_pause_limit = mv88e6097_port_pause_limit,
3264	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3265	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3266	.port_get_cmode = mv88e6185_port_get_cmode,
3267	.port_setup_message_port = mv88e6xxx_setup_message_port,
3268	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
3269	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3270	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
3271	.stats_get_strings = mv88e6095_stats_get_strings,
3272	.stats_get_stats = mv88e6095_stats_get_stats,
3273	.set_cpu_port = mv88e6095_g1_set_cpu_port,
3274	.set_egress_port = mv88e6095_g1_set_egress_port,
3275	.watchdog_ops = &mv88e6097_watchdog_ops,
3276	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
3277	.pot_clear = mv88e6xxx_g2_pot_clear,
3278	.ppu_enable = mv88e6185_g1_ppu_enable,
3279	.ppu_disable = mv88e6185_g1_ppu_disable,
3280	.reset = mv88e6185_g1_reset,
3281	.rmu_disable = mv88e6085_g1_rmu_disable,
3282	.vtu_getnext = mv88e6352_g1_vtu_getnext,
3283	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3284	.phylink_validate = mv88e6185_phylink_validate,
3285	.set_max_frame_size = mv88e6185_g1_set_max_frame_size,
3286};
3287
3288static const struct mv88e6xxx_ops mv88e6095_ops = {
3289	/* MV88E6XXX_FAMILY_6095 */
3290	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3291	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3292	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
3293	.phy_read = mv88e6185_phy_ppu_read,
3294	.phy_write = mv88e6185_phy_ppu_write,
3295	.port_set_link = mv88e6xxx_port_set_link,
3296	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
3297	.port_set_frame_mode = mv88e6085_port_set_frame_mode,
3298	.port_set_egress_floods = mv88e6185_port_set_egress_floods,
3299	.port_set_upstream_port = mv88e6095_port_set_upstream_port,
3300	.port_get_cmode = mv88e6185_port_get_cmode,
3301	.port_setup_message_port = mv88e6xxx_setup_message_port,
3302	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
3303	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3304	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
3305	.stats_get_strings = mv88e6095_stats_get_strings,
3306	.stats_get_stats = mv88e6095_stats_get_stats,
3307	.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
3308	.ppu_enable = mv88e6185_g1_ppu_enable,
3309	.ppu_disable = mv88e6185_g1_ppu_disable,
3310	.reset = mv88e6185_g1_reset,
3311	.vtu_getnext = mv88e6185_g1_vtu_getnext,
3312	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
3313	.phylink_validate = mv88e6185_phylink_validate,
3314	.set_max_frame_size = mv88e6185_g1_set_max_frame_size,
3315};
3316
3317static const struct mv88e6xxx_ops mv88e6097_ops = {
3318	/* MV88E6XXX_FAMILY_6097 */
3319	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3320	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3321	.irl_init_all = mv88e6352_g2_irl_init_all,
3322	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3323	.phy_read = mv88e6xxx_g2_smi_phy_read,
3324	.phy_write = mv88e6xxx_g2_smi_phy_write,
3325	.port_set_link = mv88e6xxx_port_set_link,
3326	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
3327	.port_tag_remap = mv88e6095_port_tag_remap,
3328	.port_set_policy = mv88e6352_port_set_policy,
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_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
3333	.port_pause_limit = mv88e6097_port_pause_limit,
3334	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3335	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3336	.port_get_cmode = mv88e6185_port_get_cmode,
3337	.port_setup_message_port = mv88e6xxx_setup_message_port,
3338	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
3339	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3340	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
3341	.stats_get_strings = mv88e6095_stats_get_strings,
3342	.stats_get_stats = mv88e6095_stats_get_stats,
3343	.set_cpu_port = mv88e6095_g1_set_cpu_port,
3344	.set_egress_port = mv88e6095_g1_set_egress_port,
3345	.watchdog_ops = &mv88e6097_watchdog_ops,
3346	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
3347	.pot_clear = mv88e6xxx_g2_pot_clear,
3348	.reset = mv88e6352_g1_reset,
3349	.rmu_disable = mv88e6085_g1_rmu_disable,
3350	.vtu_getnext = mv88e6352_g1_vtu_getnext,
3351	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3352	.phylink_validate = mv88e6185_phylink_validate,
3353	.set_max_frame_size = mv88e6185_g1_set_max_frame_size,
3354};
3355
3356static const struct mv88e6xxx_ops mv88e6123_ops = {
3357	/* MV88E6XXX_FAMILY_6165 */
3358	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3359	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3360	.irl_init_all = mv88e6352_g2_irl_init_all,
3361	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3362	.phy_read = mv88e6xxx_g2_smi_phy_read,
3363	.phy_write = mv88e6xxx_g2_smi_phy_write,
3364	.port_set_link = mv88e6xxx_port_set_link,
3365	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
3366	.port_set_frame_mode = mv88e6085_port_set_frame_mode,
3367	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
3368	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3369	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3370	.port_get_cmode = mv88e6185_port_get_cmode,
3371	.port_setup_message_port = mv88e6xxx_setup_message_port,
3372	.stats_snapshot = mv88e6320_g1_stats_snapshot,
3373	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3374	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
3375	.stats_get_strings = mv88e6095_stats_get_strings,
3376	.stats_get_stats = mv88e6095_stats_get_stats,
3377	.set_cpu_port = mv88e6095_g1_set_cpu_port,
3378	.set_egress_port = mv88e6095_g1_set_egress_port,
3379	.watchdog_ops = &mv88e6097_watchdog_ops,
3380	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
3381	.pot_clear = mv88e6xxx_g2_pot_clear,
3382	.reset = mv88e6352_g1_reset,
3383	.atu_get_hash = mv88e6165_g1_atu_get_hash,
3384	.atu_set_hash = mv88e6165_g1_atu_set_hash,
3385	.vtu_getnext = mv88e6352_g1_vtu_getnext,
3386	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3387	.phylink_validate = mv88e6185_phylink_validate,
3388	.set_max_frame_size = mv88e6185_g1_set_max_frame_size,
3389};
3390
3391static const struct mv88e6xxx_ops mv88e6131_ops = {
3392	/* MV88E6XXX_FAMILY_6185 */
3393	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3394	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3395	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
3396	.phy_read = mv88e6185_phy_ppu_read,
3397	.phy_write = mv88e6185_phy_ppu_write,
3398	.port_set_link = mv88e6xxx_port_set_link,
3399	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
3400	.port_tag_remap = mv88e6095_port_tag_remap,
3401	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
3402	.port_set_egress_floods = mv88e6185_port_set_egress_floods,
3403	.port_set_ether_type = mv88e6351_port_set_ether_type,
3404	.port_set_upstream_port = mv88e6095_port_set_upstream_port,
3405	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3406	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3407	.port_pause_limit = mv88e6097_port_pause_limit,
3408	.port_set_pause = mv88e6185_port_set_pause,
3409	.port_get_cmode = mv88e6185_port_get_cmode,
3410	.port_setup_message_port = mv88e6xxx_setup_message_port,
3411	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
3412	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3413	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
3414	.stats_get_strings = mv88e6095_stats_get_strings,
3415	.stats_get_stats = mv88e6095_stats_get_stats,
3416	.set_cpu_port = mv88e6095_g1_set_cpu_port,
3417	.set_egress_port = mv88e6095_g1_set_egress_port,
3418	.watchdog_ops = &mv88e6097_watchdog_ops,
3419	.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
3420	.ppu_enable = mv88e6185_g1_ppu_enable,
3421	.set_cascade_port = mv88e6185_g1_set_cascade_port,
3422	.ppu_disable = mv88e6185_g1_ppu_disable,
3423	.reset = mv88e6185_g1_reset,
3424	.vtu_getnext = mv88e6185_g1_vtu_getnext,
3425	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
3426	.phylink_validate = mv88e6185_phylink_validate,
3427};
3428
3429static const struct mv88e6xxx_ops mv88e6141_ops = {
3430	/* MV88E6XXX_FAMILY_6341 */
3431	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3432	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3433	.irl_init_all = mv88e6352_g2_irl_init_all,
3434	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
3435	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
3436	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3437	.phy_read = mv88e6xxx_g2_smi_phy_read,
3438	.phy_write = mv88e6xxx_g2_smi_phy_write,
3439	.port_set_link = mv88e6xxx_port_set_link,
3440	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3441	.port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
3442	.port_max_speed_mode = mv88e6341_port_max_speed_mode,
3443	.port_tag_remap = mv88e6095_port_tag_remap,
3444	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
3445	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
3446	.port_set_ether_type = mv88e6351_port_set_ether_type,
3447	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3448	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3449	.port_pause_limit = mv88e6097_port_pause_limit,
3450	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3451	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3452	.port_get_cmode = mv88e6352_port_get_cmode,
3453	.port_set_cmode = mv88e6341_port_set_cmode,
3454	.port_setup_message_port = mv88e6xxx_setup_message_port,
3455	.stats_snapshot = mv88e6390_g1_stats_snapshot,
3456	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
3457	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
3458	.stats_get_strings = mv88e6320_stats_get_strings,
3459	.stats_get_stats = mv88e6390_stats_get_stats,
3460	.set_cpu_port = mv88e6390_g1_set_cpu_port,
3461	.set_egress_port = mv88e6390_g1_set_egress_port,
3462	.watchdog_ops = &mv88e6390_watchdog_ops,
3463	.mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
3464	.pot_clear = mv88e6xxx_g2_pot_clear,
3465	.reset = mv88e6352_g1_reset,
3466	.rmu_disable = mv88e6390_g1_rmu_disable,
3467	.atu_get_hash = mv88e6165_g1_atu_get_hash,
3468	.atu_set_hash = mv88e6165_g1_atu_set_hash,
3469	.vtu_getnext = mv88e6352_g1_vtu_getnext,
3470	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3471	.serdes_power = mv88e6390_serdes_power,
3472	.serdes_get_lane = mv88e6341_serdes_get_lane,
3473	/* Check status register pause & lpa register */
3474	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
3475	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
3476	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
3477	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
3478	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3479	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
3480	.serdes_irq_status = mv88e6390_serdes_irq_status,
3481	.gpio_ops = &mv88e6352_gpio_ops,
3482	.serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
3483	.serdes_get_strings = mv88e6390_serdes_get_strings,
3484	.serdes_get_stats = mv88e6390_serdes_get_stats,
3485	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
3486	.serdes_get_regs = mv88e6390_serdes_get_regs,
3487	.phylink_validate = mv88e6341_phylink_validate,
3488};
3489
3490static const struct mv88e6xxx_ops mv88e6161_ops = {
3491	/* MV88E6XXX_FAMILY_6165 */
3492	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3493	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3494	.irl_init_all = mv88e6352_g2_irl_init_all,
3495	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3496	.phy_read = mv88e6xxx_g2_smi_phy_read,
3497	.phy_write = mv88e6xxx_g2_smi_phy_write,
3498	.port_set_link = mv88e6xxx_port_set_link,
3499	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
3500	.port_tag_remap = mv88e6095_port_tag_remap,
3501	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
3502	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
3503	.port_set_ether_type = mv88e6351_port_set_ether_type,
3504	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3505	.port_pause_limit = mv88e6097_port_pause_limit,
3506	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3507	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3508	.port_get_cmode = mv88e6185_port_get_cmode,
3509	.port_setup_message_port = mv88e6xxx_setup_message_port,
3510	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
3511	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3512	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
3513	.stats_get_strings = mv88e6095_stats_get_strings,
3514	.stats_get_stats = mv88e6095_stats_get_stats,
3515	.set_cpu_port = mv88e6095_g1_set_cpu_port,
3516	.set_egress_port = mv88e6095_g1_set_egress_port,
3517	.watchdog_ops = &mv88e6097_watchdog_ops,
3518	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
3519	.pot_clear = mv88e6xxx_g2_pot_clear,
3520	.reset = mv88e6352_g1_reset,
3521	.atu_get_hash = mv88e6165_g1_atu_get_hash,
3522	.atu_set_hash = mv88e6165_g1_atu_set_hash,
3523	.vtu_getnext = mv88e6352_g1_vtu_getnext,
3524	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3525	.avb_ops = &mv88e6165_avb_ops,
3526	.ptp_ops = &mv88e6165_ptp_ops,
3527	.phylink_validate = mv88e6185_phylink_validate,
3528	.set_max_frame_size = mv88e6185_g1_set_max_frame_size,
3529};
3530
3531static const struct mv88e6xxx_ops mv88e6165_ops = {
3532	/* MV88E6XXX_FAMILY_6165 */
3533	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3534	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3535	.irl_init_all = mv88e6352_g2_irl_init_all,
3536	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3537	.phy_read = mv88e6165_phy_read,
3538	.phy_write = mv88e6165_phy_write,
3539	.port_set_link = mv88e6xxx_port_set_link,
3540	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
3541	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3542	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3543	.port_get_cmode = mv88e6185_port_get_cmode,
3544	.port_setup_message_port = mv88e6xxx_setup_message_port,
3545	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
3546	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3547	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
3548	.stats_get_strings = mv88e6095_stats_get_strings,
3549	.stats_get_stats = mv88e6095_stats_get_stats,
3550	.set_cpu_port = mv88e6095_g1_set_cpu_port,
3551	.set_egress_port = mv88e6095_g1_set_egress_port,
3552	.watchdog_ops = &mv88e6097_watchdog_ops,
3553	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
3554	.pot_clear = mv88e6xxx_g2_pot_clear,
3555	.reset = mv88e6352_g1_reset,
3556	.atu_get_hash = mv88e6165_g1_atu_get_hash,
3557	.atu_set_hash = mv88e6165_g1_atu_set_hash,
3558	.vtu_getnext = mv88e6352_g1_vtu_getnext,
3559	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3560	.avb_ops = &mv88e6165_avb_ops,
3561	.ptp_ops = &mv88e6165_ptp_ops,
3562	.phylink_validate = mv88e6185_phylink_validate,
3563};
3564
3565static const struct mv88e6xxx_ops mv88e6171_ops = {
3566	/* MV88E6XXX_FAMILY_6351 */
3567	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3568	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3569	.irl_init_all = mv88e6352_g2_irl_init_all,
3570	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3571	.phy_read = mv88e6xxx_g2_smi_phy_read,
3572	.phy_write = mv88e6xxx_g2_smi_phy_write,
3573	.port_set_link = mv88e6xxx_port_set_link,
3574	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3575	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
3576	.port_tag_remap = mv88e6095_port_tag_remap,
3577	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
3578	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
3579	.port_set_ether_type = mv88e6351_port_set_ether_type,
3580	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3581	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3582	.port_pause_limit = mv88e6097_port_pause_limit,
3583	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3584	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3585	.port_get_cmode = mv88e6352_port_get_cmode,
3586	.port_setup_message_port = mv88e6xxx_setup_message_port,
3587	.stats_snapshot = mv88e6320_g1_stats_snapshot,
3588	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3589	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
3590	.stats_get_strings = mv88e6095_stats_get_strings,
3591	.stats_get_stats = mv88e6095_stats_get_stats,
3592	.set_cpu_port = mv88e6095_g1_set_cpu_port,
3593	.set_egress_port = mv88e6095_g1_set_egress_port,
3594	.watchdog_ops = &mv88e6097_watchdog_ops,
3595	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
3596	.pot_clear = mv88e6xxx_g2_pot_clear,
3597	.reset = mv88e6352_g1_reset,
3598	.atu_get_hash = mv88e6165_g1_atu_get_hash,
3599	.atu_set_hash = mv88e6165_g1_atu_set_hash,
3600	.vtu_getnext = mv88e6352_g1_vtu_getnext,
3601	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3602	.phylink_validate = mv88e6185_phylink_validate,
3603};
3604
3605static const struct mv88e6xxx_ops mv88e6172_ops = {
3606	/* MV88E6XXX_FAMILY_6352 */
3607	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3608	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3609	.irl_init_all = mv88e6352_g2_irl_init_all,
3610	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
3611	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3612	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3613	.phy_read = mv88e6xxx_g2_smi_phy_read,
3614	.phy_write = mv88e6xxx_g2_smi_phy_write,
3615	.port_set_link = mv88e6xxx_port_set_link,
3616	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3617	.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
3618	.port_tag_remap = mv88e6095_port_tag_remap,
3619	.port_set_policy = mv88e6352_port_set_policy,
3620	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
3621	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
3622	.port_set_ether_type = mv88e6351_port_set_ether_type,
3623	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3624	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3625	.port_pause_limit = mv88e6097_port_pause_limit,
3626	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3627	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3628	.port_get_cmode = mv88e6352_port_get_cmode,
3629	.port_setup_message_port = mv88e6xxx_setup_message_port,
3630	.stats_snapshot = mv88e6320_g1_stats_snapshot,
3631	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3632	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
3633	.stats_get_strings = mv88e6095_stats_get_strings,
3634	.stats_get_stats = mv88e6095_stats_get_stats,
3635	.set_cpu_port = mv88e6095_g1_set_cpu_port,
3636	.set_egress_port = mv88e6095_g1_set_egress_port,
3637	.watchdog_ops = &mv88e6097_watchdog_ops,
3638	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
3639	.pot_clear = mv88e6xxx_g2_pot_clear,
3640	.reset = mv88e6352_g1_reset,
3641	.rmu_disable = mv88e6352_g1_rmu_disable,
3642	.atu_get_hash = mv88e6165_g1_atu_get_hash,
3643	.atu_set_hash = mv88e6165_g1_atu_set_hash,
3644	.vtu_getnext = mv88e6352_g1_vtu_getnext,
3645	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3646	.serdes_get_lane = mv88e6352_serdes_get_lane,
3647	.serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
3648	.serdes_pcs_config = mv88e6352_serdes_pcs_config,
3649	.serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
3650	.serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
3651	.serdes_power = mv88e6352_serdes_power,
3652	.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
3653	.serdes_get_regs = mv88e6352_serdes_get_regs,
3654	.gpio_ops = &mv88e6352_gpio_ops,
3655	.phylink_validate = mv88e6352_phylink_validate,
3656};
3657
3658static const struct mv88e6xxx_ops mv88e6175_ops = {
3659	/* MV88E6XXX_FAMILY_6351 */
3660	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3661	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3662	.irl_init_all = mv88e6352_g2_irl_init_all,
3663	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3664	.phy_read = mv88e6xxx_g2_smi_phy_read,
3665	.phy_write = mv88e6xxx_g2_smi_phy_write,
3666	.port_set_link = mv88e6xxx_port_set_link,
3667	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3668	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
3669	.port_tag_remap = mv88e6095_port_tag_remap,
3670	.port_set_policy = mv88e6352_port_set_policy,
3671	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
3672	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
3673	.port_set_ether_type = mv88e6351_port_set_ether_type,
3674	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3675	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3676	.port_pause_limit = mv88e6097_port_pause_limit,
3677	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3678	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3679	.port_get_cmode = mv88e6352_port_get_cmode,
3680	.port_setup_message_port = mv88e6xxx_setup_message_port,
3681	.stats_snapshot = mv88e6320_g1_stats_snapshot,
3682	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3683	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
3684	.stats_get_strings = mv88e6095_stats_get_strings,
3685	.stats_get_stats = mv88e6095_stats_get_stats,
3686	.set_cpu_port = mv88e6095_g1_set_cpu_port,
3687	.set_egress_port = mv88e6095_g1_set_egress_port,
3688	.watchdog_ops = &mv88e6097_watchdog_ops,
3689	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
3690	.pot_clear = mv88e6xxx_g2_pot_clear,
3691	.reset = mv88e6352_g1_reset,
3692	.atu_get_hash = mv88e6165_g1_atu_get_hash,
3693	.atu_set_hash = mv88e6165_g1_atu_set_hash,
3694	.vtu_getnext = mv88e6352_g1_vtu_getnext,
3695	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3696	.phylink_validate = mv88e6185_phylink_validate,
3697};
3698
3699static const struct mv88e6xxx_ops mv88e6176_ops = {
3700	/* MV88E6XXX_FAMILY_6352 */
3701	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3702	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3703	.irl_init_all = mv88e6352_g2_irl_init_all,
3704	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
3705	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3706	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3707	.phy_read = mv88e6xxx_g2_smi_phy_read,
3708	.phy_write = mv88e6xxx_g2_smi_phy_write,
3709	.port_set_link = mv88e6xxx_port_set_link,
3710	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3711	.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
3712	.port_tag_remap = mv88e6095_port_tag_remap,
3713	.port_set_policy = mv88e6352_port_set_policy,
3714	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
3715	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
3716	.port_set_ether_type = mv88e6351_port_set_ether_type,
3717	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3718	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3719	.port_pause_limit = mv88e6097_port_pause_limit,
3720	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3721	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3722	.port_get_cmode = mv88e6352_port_get_cmode,
3723	.port_setup_message_port = mv88e6xxx_setup_message_port,
3724	.stats_snapshot = mv88e6320_g1_stats_snapshot,
3725	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3726	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
3727	.stats_get_strings = mv88e6095_stats_get_strings,
3728	.stats_get_stats = mv88e6095_stats_get_stats,
3729	.set_cpu_port = mv88e6095_g1_set_cpu_port,
3730	.set_egress_port = mv88e6095_g1_set_egress_port,
3731	.watchdog_ops = &mv88e6097_watchdog_ops,
3732	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
3733	.pot_clear = mv88e6xxx_g2_pot_clear,
3734	.reset = mv88e6352_g1_reset,
3735	.rmu_disable = mv88e6352_g1_rmu_disable,
3736	.atu_get_hash = mv88e6165_g1_atu_get_hash,
3737	.atu_set_hash = mv88e6165_g1_atu_set_hash,
3738	.vtu_getnext = mv88e6352_g1_vtu_getnext,
3739	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3740	.serdes_get_lane = mv88e6352_serdes_get_lane,
3741	.serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
3742	.serdes_pcs_config = mv88e6352_serdes_pcs_config,
3743	.serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
3744	.serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
3745	.serdes_power = mv88e6352_serdes_power,
3746	.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
3747	.serdes_irq_enable = mv88e6352_serdes_irq_enable,
3748	.serdes_irq_status = mv88e6352_serdes_irq_status,
3749	.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
3750	.serdes_get_regs = mv88e6352_serdes_get_regs,
3751	.gpio_ops = &mv88e6352_gpio_ops,
3752	.phylink_validate = mv88e6352_phylink_validate,
3753};
3754
3755static const struct mv88e6xxx_ops mv88e6185_ops = {
3756	/* MV88E6XXX_FAMILY_6185 */
3757	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3758	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3759	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
3760	.phy_read = mv88e6185_phy_ppu_read,
3761	.phy_write = mv88e6185_phy_ppu_write,
3762	.port_set_link = mv88e6xxx_port_set_link,
3763	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
3764	.port_set_frame_mode = mv88e6085_port_set_frame_mode,
3765	.port_set_egress_floods = mv88e6185_port_set_egress_floods,
3766	.port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
3767	.port_set_upstream_port = mv88e6095_port_set_upstream_port,
3768	.port_set_pause = mv88e6185_port_set_pause,
3769	.port_get_cmode = mv88e6185_port_get_cmode,
3770	.port_setup_message_port = mv88e6xxx_setup_message_port,
3771	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
3772	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3773	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
3774	.stats_get_strings = mv88e6095_stats_get_strings,
3775	.stats_get_stats = mv88e6095_stats_get_stats,
3776	.set_cpu_port = mv88e6095_g1_set_cpu_port,
3777	.set_egress_port = mv88e6095_g1_set_egress_port,
3778	.watchdog_ops = &mv88e6097_watchdog_ops,
3779	.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
3780	.set_cascade_port = mv88e6185_g1_set_cascade_port,
3781	.ppu_enable = mv88e6185_g1_ppu_enable,
3782	.ppu_disable = mv88e6185_g1_ppu_disable,
3783	.reset = mv88e6185_g1_reset,
3784	.vtu_getnext = mv88e6185_g1_vtu_getnext,
3785	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
3786	.phylink_validate = mv88e6185_phylink_validate,
3787	.set_max_frame_size = mv88e6185_g1_set_max_frame_size,
3788};
3789
3790static const struct mv88e6xxx_ops mv88e6190_ops = {
3791	/* MV88E6XXX_FAMILY_6390 */
3792	.setup_errata = mv88e6390_setup_errata,
3793	.irl_init_all = mv88e6390_g2_irl_init_all,
3794	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
3795	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
3796	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3797	.phy_read = mv88e6xxx_g2_smi_phy_read,
3798	.phy_write = mv88e6xxx_g2_smi_phy_write,
3799	.port_set_link = mv88e6xxx_port_set_link,
3800	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3801	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
3802	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
3803	.port_tag_remap = mv88e6390_port_tag_remap,
3804	.port_set_policy = mv88e6352_port_set_policy,
3805	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
3806	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
3807	.port_set_ether_type = mv88e6351_port_set_ether_type,
3808	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3809	.port_pause_limit = mv88e6390_port_pause_limit,
3810	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3811	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3812	.port_get_cmode = mv88e6352_port_get_cmode,
3813	.port_set_cmode = mv88e6390_port_set_cmode,
3814	.port_setup_message_port = mv88e6xxx_setup_message_port,
3815	.stats_snapshot = mv88e6390_g1_stats_snapshot,
3816	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
3817	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
3818	.stats_get_strings = mv88e6320_stats_get_strings,
3819	.stats_get_stats = mv88e6390_stats_get_stats,
3820	.set_cpu_port = mv88e6390_g1_set_cpu_port,
3821	.set_egress_port = mv88e6390_g1_set_egress_port,
3822	.watchdog_ops = &mv88e6390_watchdog_ops,
3823	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
3824	.pot_clear = mv88e6xxx_g2_pot_clear,
3825	.reset = mv88e6352_g1_reset,
3826	.rmu_disable = mv88e6390_g1_rmu_disable,
3827	.atu_get_hash = mv88e6165_g1_atu_get_hash,
3828	.atu_set_hash = mv88e6165_g1_atu_set_hash,
3829	.vtu_getnext = mv88e6390_g1_vtu_getnext,
3830	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
3831	.serdes_power = mv88e6390_serdes_power,
3832	.serdes_get_lane = mv88e6390_serdes_get_lane,
3833	/* Check status register pause & lpa register */
3834	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
3835	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
3836	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
3837	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
3838	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3839	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
3840	.serdes_irq_status = mv88e6390_serdes_irq_status,
3841	.serdes_get_strings = mv88e6390_serdes_get_strings,
3842	.serdes_get_stats = mv88e6390_serdes_get_stats,
3843	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
3844	.serdes_get_regs = mv88e6390_serdes_get_regs,
3845	.gpio_ops = &mv88e6352_gpio_ops,
3846	.phylink_validate = mv88e6390_phylink_validate,
3847};
3848
3849static const struct mv88e6xxx_ops mv88e6190x_ops = {
3850	/* MV88E6XXX_FAMILY_6390 */
3851	.setup_errata = mv88e6390_setup_errata,
3852	.irl_init_all = mv88e6390_g2_irl_init_all,
3853	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
3854	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
3855	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3856	.phy_read = mv88e6xxx_g2_smi_phy_read,
3857	.phy_write = mv88e6xxx_g2_smi_phy_write,
3858	.port_set_link = mv88e6xxx_port_set_link,
3859	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3860	.port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
3861	.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
3862	.port_tag_remap = mv88e6390_port_tag_remap,
3863	.port_set_policy = mv88e6352_port_set_policy,
3864	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
3865	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
3866	.port_set_ether_type = mv88e6351_port_set_ether_type,
3867	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3868	.port_pause_limit = mv88e6390_port_pause_limit,
3869	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3870	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3871	.port_get_cmode = mv88e6352_port_get_cmode,
3872	.port_set_cmode = mv88e6390x_port_set_cmode,
3873	.port_setup_message_port = mv88e6xxx_setup_message_port,
3874	.stats_snapshot = mv88e6390_g1_stats_snapshot,
3875	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
3876	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
3877	.stats_get_strings = mv88e6320_stats_get_strings,
3878	.stats_get_stats = mv88e6390_stats_get_stats,
3879	.set_cpu_port = mv88e6390_g1_set_cpu_port,
3880	.set_egress_port = mv88e6390_g1_set_egress_port,
3881	.watchdog_ops = &mv88e6390_watchdog_ops,
3882	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
3883	.pot_clear = mv88e6xxx_g2_pot_clear,
3884	.reset = mv88e6352_g1_reset,
3885	.rmu_disable = mv88e6390_g1_rmu_disable,
3886	.atu_get_hash = mv88e6165_g1_atu_get_hash,
3887	.atu_set_hash = mv88e6165_g1_atu_set_hash,
3888	.vtu_getnext = mv88e6390_g1_vtu_getnext,
3889	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
3890	.serdes_power = mv88e6390_serdes_power,
3891	.serdes_get_lane = mv88e6390x_serdes_get_lane,
3892	/* Check status register pause & lpa register */
3893	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
3894	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
3895	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
3896	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
3897	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3898	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
3899	.serdes_irq_status = mv88e6390_serdes_irq_status,
3900	.serdes_get_strings = mv88e6390_serdes_get_strings,
3901	.serdes_get_stats = mv88e6390_serdes_get_stats,
3902	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
3903	.serdes_get_regs = mv88e6390_serdes_get_regs,
3904	.gpio_ops = &mv88e6352_gpio_ops,
3905	.phylink_validate = mv88e6390x_phylink_validate,
3906};
3907
3908static const struct mv88e6xxx_ops mv88e6191_ops = {
3909	/* MV88E6XXX_FAMILY_6390 */
3910	.setup_errata = mv88e6390_setup_errata,
3911	.irl_init_all = mv88e6390_g2_irl_init_all,
3912	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
3913	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
3914	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3915	.phy_read = mv88e6xxx_g2_smi_phy_read,
3916	.phy_write = mv88e6xxx_g2_smi_phy_write,
3917	.port_set_link = mv88e6xxx_port_set_link,
3918	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
3919	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
3920	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
3921	.port_tag_remap = mv88e6390_port_tag_remap,
3922	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
3923	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
3924	.port_set_ether_type = mv88e6351_port_set_ether_type,
3925	.port_pause_limit = mv88e6390_port_pause_limit,
3926	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3927	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3928	.port_get_cmode = mv88e6352_port_get_cmode,
3929	.port_set_cmode = mv88e6390_port_set_cmode,
3930	.port_setup_message_port = mv88e6xxx_setup_message_port,
3931	.stats_snapshot = mv88e6390_g1_stats_snapshot,
3932	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
3933	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
3934	.stats_get_strings = mv88e6320_stats_get_strings,
3935	.stats_get_stats = mv88e6390_stats_get_stats,
3936	.set_cpu_port = mv88e6390_g1_set_cpu_port,
3937	.set_egress_port = mv88e6390_g1_set_egress_port,
3938	.watchdog_ops = &mv88e6390_watchdog_ops,
3939	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
3940	.pot_clear = mv88e6xxx_g2_pot_clear,
3941	.reset = mv88e6352_g1_reset,
3942	.rmu_disable = mv88e6390_g1_rmu_disable,
3943	.atu_get_hash = mv88e6165_g1_atu_get_hash,
3944	.atu_set_hash = mv88e6165_g1_atu_set_hash,
3945	.vtu_getnext = mv88e6390_g1_vtu_getnext,
3946	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
3947	.serdes_power = mv88e6390_serdes_power,
3948	.serdes_get_lane = mv88e6390_serdes_get_lane,
3949	/* Check status register pause & lpa register */
3950	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
3951	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
3952	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
3953	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
3954	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3955	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
3956	.serdes_irq_status = mv88e6390_serdes_irq_status,
3957	.serdes_get_strings = mv88e6390_serdes_get_strings,
3958	.serdes_get_stats = mv88e6390_serdes_get_stats,
3959	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
3960	.serdes_get_regs = mv88e6390_serdes_get_regs,
3961	.avb_ops = &mv88e6390_avb_ops,
3962	.ptp_ops = &mv88e6352_ptp_ops,
3963	.phylink_validate = mv88e6390_phylink_validate,
3964};
3965
3966static const struct mv88e6xxx_ops mv88e6240_ops = {
3967	/* MV88E6XXX_FAMILY_6352 */
3968	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
3969	.ip_pri_map = mv88e6085_g1_ip_pri_map,
3970	.irl_init_all = mv88e6352_g2_irl_init_all,
3971	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
3972	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3973	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3974	.phy_read = mv88e6xxx_g2_smi_phy_read,
3975	.phy_write = mv88e6xxx_g2_smi_phy_write,
3976	.port_set_link = mv88e6xxx_port_set_link,
3977	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
3978	.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
3979	.port_tag_remap = mv88e6095_port_tag_remap,
3980	.port_set_policy = mv88e6352_port_set_policy,
3981	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
3982	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
3983	.port_set_ether_type = mv88e6351_port_set_ether_type,
3984	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
3985	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
3986	.port_pause_limit = mv88e6097_port_pause_limit,
3987	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
3988	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
3989	.port_get_cmode = mv88e6352_port_get_cmode,
3990	.port_setup_message_port = mv88e6xxx_setup_message_port,
3991	.stats_snapshot = mv88e6320_g1_stats_snapshot,
3992	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
3993	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
3994	.stats_get_strings = mv88e6095_stats_get_strings,
3995	.stats_get_stats = mv88e6095_stats_get_stats,
3996	.set_cpu_port = mv88e6095_g1_set_cpu_port,
3997	.set_egress_port = mv88e6095_g1_set_egress_port,
3998	.watchdog_ops = &mv88e6097_watchdog_ops,
3999	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4000	.pot_clear = mv88e6xxx_g2_pot_clear,
4001	.reset = mv88e6352_g1_reset,
4002	.rmu_disable = mv88e6352_g1_rmu_disable,
4003	.atu_get_hash = mv88e6165_g1_atu_get_hash,
4004	.atu_set_hash = mv88e6165_g1_atu_set_hash,
4005	.vtu_getnext = mv88e6352_g1_vtu_getnext,
4006	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4007	.serdes_get_lane = mv88e6352_serdes_get_lane,
4008	.serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
4009	.serdes_pcs_config = mv88e6352_serdes_pcs_config,
4010	.serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
4011	.serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
4012	.serdes_power = mv88e6352_serdes_power,
4013	.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
4014	.serdes_irq_enable = mv88e6352_serdes_irq_enable,
4015	.serdes_irq_status = mv88e6352_serdes_irq_status,
4016	.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
4017	.serdes_get_regs = mv88e6352_serdes_get_regs,
4018	.gpio_ops = &mv88e6352_gpio_ops,
4019	.avb_ops = &mv88e6352_avb_ops,
4020	.ptp_ops = &mv88e6352_ptp_ops,
4021	.phylink_validate = mv88e6352_phylink_validate,
4022};
4023
4024static const struct mv88e6xxx_ops mv88e6250_ops = {
4025	/* MV88E6XXX_FAMILY_6250 */
4026	.ieee_pri_map = mv88e6250_g1_ieee_pri_map,
4027	.ip_pri_map = mv88e6085_g1_ip_pri_map,
4028	.irl_init_all = mv88e6352_g2_irl_init_all,
4029	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
4030	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
4031	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4032	.phy_read = mv88e6xxx_g2_smi_phy_read,
4033	.phy_write = mv88e6xxx_g2_smi_phy_write,
4034	.port_set_link = mv88e6xxx_port_set_link,
4035	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4036	.port_set_speed_duplex = mv88e6250_port_set_speed_duplex,
4037	.port_tag_remap = mv88e6095_port_tag_remap,
4038	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
4039	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
4040	.port_set_ether_type = mv88e6351_port_set_ether_type,
4041	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4042	.port_pause_limit = mv88e6097_port_pause_limit,
4043	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4044	.stats_snapshot = mv88e6320_g1_stats_snapshot,
4045	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4046	.stats_get_sset_count = mv88e6250_stats_get_sset_count,
4047	.stats_get_strings = mv88e6250_stats_get_strings,
4048	.stats_get_stats = mv88e6250_stats_get_stats,
4049	.set_cpu_port = mv88e6095_g1_set_cpu_port,
4050	.set_egress_port = mv88e6095_g1_set_egress_port,
4051	.watchdog_ops = &mv88e6250_watchdog_ops,
4052	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4053	.pot_clear = mv88e6xxx_g2_pot_clear,
4054	.reset = mv88e6250_g1_reset,
4055	.vtu_getnext = mv88e6250_g1_vtu_getnext,
4056	.vtu_loadpurge = mv88e6250_g1_vtu_loadpurge,
4057	.avb_ops = &mv88e6352_avb_ops,
4058	.ptp_ops = &mv88e6250_ptp_ops,
4059	.phylink_validate = mv88e6065_phylink_validate,
4060};
4061
4062static const struct mv88e6xxx_ops mv88e6290_ops = {
4063	/* MV88E6XXX_FAMILY_6390 */
4064	.setup_errata = mv88e6390_setup_errata,
4065	.irl_init_all = mv88e6390_g2_irl_init_all,
4066	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
4067	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
4068	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4069	.phy_read = mv88e6xxx_g2_smi_phy_read,
4070	.phy_write = mv88e6xxx_g2_smi_phy_write,
4071	.port_set_link = mv88e6xxx_port_set_link,
4072	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
4073	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
4074	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
4075	.port_tag_remap = mv88e6390_port_tag_remap,
4076	.port_set_policy = mv88e6352_port_set_policy,
4077	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
4078	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
4079	.port_set_ether_type = mv88e6351_port_set_ether_type,
4080	.port_pause_limit = mv88e6390_port_pause_limit,
4081	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4082	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4083	.port_get_cmode = mv88e6352_port_get_cmode,
4084	.port_set_cmode = mv88e6390_port_set_cmode,
4085	.port_setup_message_port = mv88e6xxx_setup_message_port,
4086	.stats_snapshot = mv88e6390_g1_stats_snapshot,
4087	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
4088	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
4089	.stats_get_strings = mv88e6320_stats_get_strings,
4090	.stats_get_stats = mv88e6390_stats_get_stats,
4091	.set_cpu_port = mv88e6390_g1_set_cpu_port,
4092	.set_egress_port = mv88e6390_g1_set_egress_port,
4093	.watchdog_ops = &mv88e6390_watchdog_ops,
4094	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
4095	.pot_clear = mv88e6xxx_g2_pot_clear,
4096	.reset = mv88e6352_g1_reset,
4097	.rmu_disable = mv88e6390_g1_rmu_disable,
4098	.atu_get_hash = mv88e6165_g1_atu_get_hash,
4099	.atu_set_hash = mv88e6165_g1_atu_set_hash,
4100	.vtu_getnext = mv88e6390_g1_vtu_getnext,
4101	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
4102	.serdes_power = mv88e6390_serdes_power,
4103	.serdes_get_lane = mv88e6390_serdes_get_lane,
4104	/* Check status register pause & lpa register */
4105	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4106	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
4107	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4108	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4109	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4110	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
4111	.serdes_irq_status = mv88e6390_serdes_irq_status,
4112	.serdes_get_strings = mv88e6390_serdes_get_strings,
4113	.serdes_get_stats = mv88e6390_serdes_get_stats,
4114	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4115	.serdes_get_regs = mv88e6390_serdes_get_regs,
4116	.gpio_ops = &mv88e6352_gpio_ops,
4117	.avb_ops = &mv88e6390_avb_ops,
4118	.ptp_ops = &mv88e6352_ptp_ops,
4119	.phylink_validate = mv88e6390_phylink_validate,
4120};
4121
4122static const struct mv88e6xxx_ops mv88e6320_ops = {
4123	/* MV88E6XXX_FAMILY_6320 */
4124	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4125	.ip_pri_map = mv88e6085_g1_ip_pri_map,
4126	.irl_init_all = mv88e6352_g2_irl_init_all,
4127	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
4128	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
4129	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4130	.phy_read = mv88e6xxx_g2_smi_phy_read,
4131	.phy_write = mv88e6xxx_g2_smi_phy_write,
4132	.port_set_link = mv88e6xxx_port_set_link,
4133	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4134	.port_tag_remap = mv88e6095_port_tag_remap,
4135	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
4136	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
4137	.port_set_ether_type = mv88e6351_port_set_ether_type,
4138	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4139	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4140	.port_pause_limit = mv88e6097_port_pause_limit,
4141	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4142	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4143	.port_get_cmode = mv88e6352_port_get_cmode,
4144	.port_setup_message_port = mv88e6xxx_setup_message_port,
4145	.stats_snapshot = mv88e6320_g1_stats_snapshot,
4146	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4147	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
4148	.stats_get_strings = mv88e6320_stats_get_strings,
4149	.stats_get_stats = mv88e6320_stats_get_stats,
4150	.set_cpu_port = mv88e6095_g1_set_cpu_port,
4151	.set_egress_port = mv88e6095_g1_set_egress_port,
4152	.watchdog_ops = &mv88e6390_watchdog_ops,
4153	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4154	.pot_clear = mv88e6xxx_g2_pot_clear,
4155	.reset = mv88e6352_g1_reset,
4156	.vtu_getnext = mv88e6185_g1_vtu_getnext,
4157	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
4158	.gpio_ops = &mv88e6352_gpio_ops,
4159	.avb_ops = &mv88e6352_avb_ops,
4160	.ptp_ops = &mv88e6352_ptp_ops,
4161	.phylink_validate = mv88e6185_phylink_validate,
4162};
4163
4164static const struct mv88e6xxx_ops mv88e6321_ops = {
4165	/* MV88E6XXX_FAMILY_6320 */
4166	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4167	.ip_pri_map = mv88e6085_g1_ip_pri_map,
4168	.irl_init_all = mv88e6352_g2_irl_init_all,
4169	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
4170	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
4171	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4172	.phy_read = mv88e6xxx_g2_smi_phy_read,
4173	.phy_write = mv88e6xxx_g2_smi_phy_write,
4174	.port_set_link = mv88e6xxx_port_set_link,
4175	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4176	.port_tag_remap = mv88e6095_port_tag_remap,
4177	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
4178	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
4179	.port_set_ether_type = mv88e6351_port_set_ether_type,
4180	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4181	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4182	.port_pause_limit = mv88e6097_port_pause_limit,
4183	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4184	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4185	.port_get_cmode = mv88e6352_port_get_cmode,
4186	.port_setup_message_port = mv88e6xxx_setup_message_port,
4187	.stats_snapshot = mv88e6320_g1_stats_snapshot,
4188	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4189	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
4190	.stats_get_strings = mv88e6320_stats_get_strings,
4191	.stats_get_stats = mv88e6320_stats_get_stats,
4192	.set_cpu_port = mv88e6095_g1_set_cpu_port,
4193	.set_egress_port = mv88e6095_g1_set_egress_port,
4194	.watchdog_ops = &mv88e6390_watchdog_ops,
4195	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4196	.reset = mv88e6352_g1_reset,
4197	.vtu_getnext = mv88e6185_g1_vtu_getnext,
4198	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
4199	.gpio_ops = &mv88e6352_gpio_ops,
4200	.avb_ops = &mv88e6352_avb_ops,
4201	.ptp_ops = &mv88e6352_ptp_ops,
4202	.phylink_validate = mv88e6185_phylink_validate,
4203};
4204
4205static const struct mv88e6xxx_ops mv88e6341_ops = {
4206	/* MV88E6XXX_FAMILY_6341 */
4207	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4208	.ip_pri_map = mv88e6085_g1_ip_pri_map,
4209	.irl_init_all = mv88e6352_g2_irl_init_all,
4210	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
4211	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
4212	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4213	.phy_read = mv88e6xxx_g2_smi_phy_read,
4214	.phy_write = mv88e6xxx_g2_smi_phy_write,
4215	.port_set_link = mv88e6xxx_port_set_link,
4216	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
4217	.port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
4218	.port_max_speed_mode = mv88e6341_port_max_speed_mode,
4219	.port_tag_remap = mv88e6095_port_tag_remap,
4220	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
4221	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
4222	.port_set_ether_type = mv88e6351_port_set_ether_type,
4223	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4224	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4225	.port_pause_limit = mv88e6097_port_pause_limit,
4226	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4227	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4228	.port_get_cmode = mv88e6352_port_get_cmode,
4229	.port_set_cmode = mv88e6341_port_set_cmode,
4230	.port_setup_message_port = mv88e6xxx_setup_message_port,
4231	.stats_snapshot = mv88e6390_g1_stats_snapshot,
4232	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
4233	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
4234	.stats_get_strings = mv88e6320_stats_get_strings,
4235	.stats_get_stats = mv88e6390_stats_get_stats,
4236	.set_cpu_port = mv88e6390_g1_set_cpu_port,
4237	.set_egress_port = mv88e6390_g1_set_egress_port,
4238	.watchdog_ops = &mv88e6390_watchdog_ops,
4239	.mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
4240	.pot_clear = mv88e6xxx_g2_pot_clear,
4241	.reset = mv88e6352_g1_reset,
4242	.rmu_disable = mv88e6390_g1_rmu_disable,
4243	.atu_get_hash = mv88e6165_g1_atu_get_hash,
4244	.atu_set_hash = mv88e6165_g1_atu_set_hash,
4245	.vtu_getnext = mv88e6352_g1_vtu_getnext,
4246	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4247	.serdes_power = mv88e6390_serdes_power,
4248	.serdes_get_lane = mv88e6341_serdes_get_lane,
4249	/* Check status register pause & lpa register */
4250	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4251	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
4252	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4253	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4254	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4255	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
4256	.serdes_irq_status = mv88e6390_serdes_irq_status,
4257	.gpio_ops = &mv88e6352_gpio_ops,
4258	.avb_ops = &mv88e6390_avb_ops,
4259	.ptp_ops = &mv88e6352_ptp_ops,
4260	.serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
4261	.serdes_get_strings = mv88e6390_serdes_get_strings,
4262	.serdes_get_stats = mv88e6390_serdes_get_stats,
4263	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4264	.serdes_get_regs = mv88e6390_serdes_get_regs,
4265	.phylink_validate = mv88e6341_phylink_validate,
4266};
4267
4268static const struct mv88e6xxx_ops mv88e6350_ops = {
4269	/* MV88E6XXX_FAMILY_6351 */
4270	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4271	.ip_pri_map = mv88e6085_g1_ip_pri_map,
4272	.irl_init_all = mv88e6352_g2_irl_init_all,
4273	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4274	.phy_read = mv88e6xxx_g2_smi_phy_read,
4275	.phy_write = mv88e6xxx_g2_smi_phy_write,
4276	.port_set_link = mv88e6xxx_port_set_link,
4277	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4278	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4279	.port_tag_remap = mv88e6095_port_tag_remap,
4280	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
4281	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
4282	.port_set_ether_type = mv88e6351_port_set_ether_type,
4283	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4284	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4285	.port_pause_limit = mv88e6097_port_pause_limit,
4286	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4287	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4288	.port_get_cmode = mv88e6352_port_get_cmode,
4289	.port_setup_message_port = mv88e6xxx_setup_message_port,
4290	.stats_snapshot = mv88e6320_g1_stats_snapshot,
4291	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4292	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
4293	.stats_get_strings = mv88e6095_stats_get_strings,
4294	.stats_get_stats = mv88e6095_stats_get_stats,
4295	.set_cpu_port = mv88e6095_g1_set_cpu_port,
4296	.set_egress_port = mv88e6095_g1_set_egress_port,
4297	.watchdog_ops = &mv88e6097_watchdog_ops,
4298	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4299	.pot_clear = mv88e6xxx_g2_pot_clear,
4300	.reset = mv88e6352_g1_reset,
4301	.atu_get_hash = mv88e6165_g1_atu_get_hash,
4302	.atu_set_hash = mv88e6165_g1_atu_set_hash,
4303	.vtu_getnext = mv88e6352_g1_vtu_getnext,
4304	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4305	.phylink_validate = mv88e6185_phylink_validate,
4306};
4307
4308static const struct mv88e6xxx_ops mv88e6351_ops = {
4309	/* MV88E6XXX_FAMILY_6351 */
4310	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4311	.ip_pri_map = mv88e6085_g1_ip_pri_map,
4312	.irl_init_all = mv88e6352_g2_irl_init_all,
4313	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4314	.phy_read = mv88e6xxx_g2_smi_phy_read,
4315	.phy_write = mv88e6xxx_g2_smi_phy_write,
4316	.port_set_link = mv88e6xxx_port_set_link,
4317	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4318	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4319	.port_tag_remap = mv88e6095_port_tag_remap,
4320	.port_set_policy = mv88e6352_port_set_policy,
4321	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
4322	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
4323	.port_set_ether_type = mv88e6351_port_set_ether_type,
4324	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4325	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4326	.port_pause_limit = mv88e6097_port_pause_limit,
4327	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4328	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4329	.port_get_cmode = mv88e6352_port_get_cmode,
4330	.port_setup_message_port = mv88e6xxx_setup_message_port,
4331	.stats_snapshot = mv88e6320_g1_stats_snapshot,
4332	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4333	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
4334	.stats_get_strings = mv88e6095_stats_get_strings,
4335	.stats_get_stats = mv88e6095_stats_get_stats,
4336	.set_cpu_port = mv88e6095_g1_set_cpu_port,
4337	.set_egress_port = mv88e6095_g1_set_egress_port,
4338	.watchdog_ops = &mv88e6097_watchdog_ops,
4339	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4340	.pot_clear = mv88e6xxx_g2_pot_clear,
4341	.reset = mv88e6352_g1_reset,
4342	.atu_get_hash = mv88e6165_g1_atu_get_hash,
4343	.atu_set_hash = mv88e6165_g1_atu_set_hash,
4344	.vtu_getnext = mv88e6352_g1_vtu_getnext,
4345	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4346	.avb_ops = &mv88e6352_avb_ops,
4347	.ptp_ops = &mv88e6352_ptp_ops,
4348	.phylink_validate = mv88e6185_phylink_validate,
4349};
4350
4351static const struct mv88e6xxx_ops mv88e6352_ops = {
4352	/* MV88E6XXX_FAMILY_6352 */
4353	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4354	.ip_pri_map = mv88e6085_g1_ip_pri_map,
4355	.irl_init_all = mv88e6352_g2_irl_init_all,
4356	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
4357	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
4358	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4359	.phy_read = mv88e6xxx_g2_smi_phy_read,
4360	.phy_write = mv88e6xxx_g2_smi_phy_write,
4361	.port_set_link = mv88e6xxx_port_set_link,
4362	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4363	.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
4364	.port_tag_remap = mv88e6095_port_tag_remap,
4365	.port_set_policy = mv88e6352_port_set_policy,
4366	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
4367	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
4368	.port_set_ether_type = mv88e6351_port_set_ether_type,
4369	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4370	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4371	.port_pause_limit = mv88e6097_port_pause_limit,
4372	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4373	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4374	.port_get_cmode = mv88e6352_port_get_cmode,
4375	.port_setup_message_port = mv88e6xxx_setup_message_port,
4376	.stats_snapshot = mv88e6320_g1_stats_snapshot,
4377	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4378	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
4379	.stats_get_strings = mv88e6095_stats_get_strings,
4380	.stats_get_stats = mv88e6095_stats_get_stats,
4381	.set_cpu_port = mv88e6095_g1_set_cpu_port,
4382	.set_egress_port = mv88e6095_g1_set_egress_port,
4383	.watchdog_ops = &mv88e6097_watchdog_ops,
4384	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4385	.pot_clear = mv88e6xxx_g2_pot_clear,
4386	.reset = mv88e6352_g1_reset,
4387	.rmu_disable = mv88e6352_g1_rmu_disable,
4388	.atu_get_hash = mv88e6165_g1_atu_get_hash,
4389	.atu_set_hash = mv88e6165_g1_atu_set_hash,
4390	.vtu_getnext = mv88e6352_g1_vtu_getnext,
4391	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4392	.serdes_get_lane = mv88e6352_serdes_get_lane,
4393	.serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
4394	.serdes_pcs_config = mv88e6352_serdes_pcs_config,
4395	.serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
4396	.serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
4397	.serdes_power = mv88e6352_serdes_power,
4398	.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
4399	.serdes_irq_enable = mv88e6352_serdes_irq_enable,
4400	.serdes_irq_status = mv88e6352_serdes_irq_status,
4401	.gpio_ops = &mv88e6352_gpio_ops,
4402	.avb_ops = &mv88e6352_avb_ops,
4403	.ptp_ops = &mv88e6352_ptp_ops,
4404	.serdes_get_sset_count = mv88e6352_serdes_get_sset_count,
4405	.serdes_get_strings = mv88e6352_serdes_get_strings,
4406	.serdes_get_stats = mv88e6352_serdes_get_stats,
4407	.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
4408	.serdes_get_regs = mv88e6352_serdes_get_regs,
4409	.phylink_validate = mv88e6352_phylink_validate,
4410};
4411
4412static const struct mv88e6xxx_ops mv88e6390_ops = {
4413	/* MV88E6XXX_FAMILY_6390 */
4414	.setup_errata = mv88e6390_setup_errata,
4415	.irl_init_all = mv88e6390_g2_irl_init_all,
4416	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
4417	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
4418	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4419	.phy_read = mv88e6xxx_g2_smi_phy_read,
4420	.phy_write = mv88e6xxx_g2_smi_phy_write,
4421	.port_set_link = mv88e6xxx_port_set_link,
4422	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
4423	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
4424	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
4425	.port_tag_remap = mv88e6390_port_tag_remap,
4426	.port_set_policy = mv88e6352_port_set_policy,
4427	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
4428	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
4429	.port_set_ether_type = mv88e6351_port_set_ether_type,
4430	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4431	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4432	.port_pause_limit = mv88e6390_port_pause_limit,
4433	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4434	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4435	.port_get_cmode = mv88e6352_port_get_cmode,
4436	.port_set_cmode = mv88e6390_port_set_cmode,
4437	.port_setup_message_port = mv88e6xxx_setup_message_port,
4438	.stats_snapshot = mv88e6390_g1_stats_snapshot,
4439	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
4440	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
4441	.stats_get_strings = mv88e6320_stats_get_strings,
4442	.stats_get_stats = mv88e6390_stats_get_stats,
4443	.set_cpu_port = mv88e6390_g1_set_cpu_port,
4444	.set_egress_port = mv88e6390_g1_set_egress_port,
4445	.watchdog_ops = &mv88e6390_watchdog_ops,
4446	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
4447	.pot_clear = mv88e6xxx_g2_pot_clear,
4448	.reset = mv88e6352_g1_reset,
4449	.rmu_disable = mv88e6390_g1_rmu_disable,
4450	.atu_get_hash = mv88e6165_g1_atu_get_hash,
4451	.atu_set_hash = mv88e6165_g1_atu_set_hash,
4452	.vtu_getnext = mv88e6390_g1_vtu_getnext,
4453	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
4454	.serdes_power = mv88e6390_serdes_power,
4455	.serdes_get_lane = mv88e6390_serdes_get_lane,
4456	/* Check status register pause & lpa register */
4457	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4458	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
4459	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4460	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4461	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4462	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
4463	.serdes_irq_status = mv88e6390_serdes_irq_status,
4464	.gpio_ops = &mv88e6352_gpio_ops,
4465	.avb_ops = &mv88e6390_avb_ops,
4466	.ptp_ops = &mv88e6352_ptp_ops,
4467	.serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
4468	.serdes_get_strings = mv88e6390_serdes_get_strings,
4469	.serdes_get_stats = mv88e6390_serdes_get_stats,
4470	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4471	.serdes_get_regs = mv88e6390_serdes_get_regs,
4472	.phylink_validate = mv88e6390_phylink_validate,
4473};
4474
4475static const struct mv88e6xxx_ops mv88e6390x_ops = {
4476	/* MV88E6XXX_FAMILY_6390 */
4477	.setup_errata = mv88e6390_setup_errata,
4478	.irl_init_all = mv88e6390_g2_irl_init_all,
4479	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
4480	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
4481	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4482	.phy_read = mv88e6xxx_g2_smi_phy_read,
4483	.phy_write = mv88e6xxx_g2_smi_phy_write,
4484	.port_set_link = mv88e6xxx_port_set_link,
4485	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
4486	.port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
4487	.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
4488	.port_tag_remap = mv88e6390_port_tag_remap,
4489	.port_set_policy = mv88e6352_port_set_policy,
4490	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
4491	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
4492	.port_set_ether_type = mv88e6351_port_set_ether_type,
4493	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4494	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4495	.port_pause_limit = mv88e6390_port_pause_limit,
4496	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4497	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4498	.port_get_cmode = mv88e6352_port_get_cmode,
4499	.port_set_cmode = mv88e6390x_port_set_cmode,
4500	.port_setup_message_port = mv88e6xxx_setup_message_port,
4501	.stats_snapshot = mv88e6390_g1_stats_snapshot,
4502	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
4503	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
4504	.stats_get_strings = mv88e6320_stats_get_strings,
4505	.stats_get_stats = mv88e6390_stats_get_stats,
4506	.set_cpu_port = mv88e6390_g1_set_cpu_port,
4507	.set_egress_port = mv88e6390_g1_set_egress_port,
4508	.watchdog_ops = &mv88e6390_watchdog_ops,
4509	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
4510	.pot_clear = mv88e6xxx_g2_pot_clear,
4511	.reset = mv88e6352_g1_reset,
4512	.rmu_disable = mv88e6390_g1_rmu_disable,
4513	.atu_get_hash = mv88e6165_g1_atu_get_hash,
4514	.atu_set_hash = mv88e6165_g1_atu_set_hash,
4515	.vtu_getnext = mv88e6390_g1_vtu_getnext,
4516	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
4517	.serdes_power = mv88e6390_serdes_power,
4518	.serdes_get_lane = mv88e6390x_serdes_get_lane,
4519	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4520	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
4521	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4522	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4523	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4524	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
4525	.serdes_irq_status = mv88e6390_serdes_irq_status,
4526	.serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
4527	.serdes_get_strings = mv88e6390_serdes_get_strings,
4528	.serdes_get_stats = mv88e6390_serdes_get_stats,
4529	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4530	.serdes_get_regs = mv88e6390_serdes_get_regs,
4531	.gpio_ops = &mv88e6352_gpio_ops,
4532	.avb_ops = &mv88e6390_avb_ops,
4533	.ptp_ops = &mv88e6352_ptp_ops,
4534	.phylink_validate = mv88e6390x_phylink_validate,
4535};
4536
4537static const struct mv88e6xxx_info mv88e6xxx_table[] = {
4538	[MV88E6085] = {
4539		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6085,
4540		.family = MV88E6XXX_FAMILY_6097,
4541		.name = "Marvell 88E6085",
4542		.num_databases = 4096,
4543		.num_macs = 8192,
4544		.num_ports = 10,
4545		.num_internal_phys = 5,
4546		.max_vid = 4095,
4547		.port_base_addr = 0x10,
4548		.phy_base_addr = 0x0,
4549		.global1_addr = 0x1b,
4550		.global2_addr = 0x1c,
4551		.age_time_coeff = 15000,
4552		.g1_irqs = 8,
4553		.g2_irqs = 10,
4554		.atu_move_port_mask = 0xf,
4555		.pvt = true,
4556		.multi_chip = true,
4557		.tag_protocol = DSA_TAG_PROTO_DSA,
4558		.ops = &mv88e6085_ops,
4559	},
4560
4561	[MV88E6095] = {
4562		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6095,
4563		.family = MV88E6XXX_FAMILY_6095,
4564		.name = "Marvell 88E6095/88E6095F",
4565		.num_databases = 256,
4566		.num_macs = 8192,
4567		.num_ports = 11,
4568		.num_internal_phys = 0,
4569		.max_vid = 4095,
4570		.port_base_addr = 0x10,
4571		.phy_base_addr = 0x0,
4572		.global1_addr = 0x1b,
4573		.global2_addr = 0x1c,
4574		.age_time_coeff = 15000,
4575		.g1_irqs = 8,
4576		.atu_move_port_mask = 0xf,
4577		.multi_chip = true,
4578		.tag_protocol = DSA_TAG_PROTO_DSA,
4579		.ops = &mv88e6095_ops,
4580	},
4581
4582	[MV88E6097] = {
4583		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6097,
4584		.family = MV88E6XXX_FAMILY_6097,
4585		.name = "Marvell 88E6097/88E6097F",
4586		.num_databases = 4096,
4587		.num_macs = 8192,
4588		.num_ports = 11,
4589		.num_internal_phys = 8,
4590		.max_vid = 4095,
4591		.port_base_addr = 0x10,
4592		.phy_base_addr = 0x0,
4593		.global1_addr = 0x1b,
4594		.global2_addr = 0x1c,
4595		.age_time_coeff = 15000,
4596		.g1_irqs = 8,
4597		.g2_irqs = 10,
4598		.atu_move_port_mask = 0xf,
4599		.pvt = true,
4600		.multi_chip = true,
4601		.tag_protocol = DSA_TAG_PROTO_EDSA,
4602		.ops = &mv88e6097_ops,
4603	},
4604
4605	[MV88E6123] = {
4606		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6123,
4607		.family = MV88E6XXX_FAMILY_6165,
4608		.name = "Marvell 88E6123",
4609		.num_databases = 4096,
4610		.num_macs = 1024,
4611		.num_ports = 3,
4612		.num_internal_phys = 5,
4613		.max_vid = 4095,
4614		.port_base_addr = 0x10,
4615		.phy_base_addr = 0x0,
4616		.global1_addr = 0x1b,
4617		.global2_addr = 0x1c,
4618		.age_time_coeff = 15000,
4619		.g1_irqs = 9,
4620		.g2_irqs = 10,
4621		.atu_move_port_mask = 0xf,
4622		.pvt = true,
4623		.multi_chip = true,
4624		.tag_protocol = DSA_TAG_PROTO_EDSA,
4625		.ops = &mv88e6123_ops,
4626	},
4627
4628	[MV88E6131] = {
4629		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6131,
4630		.family = MV88E6XXX_FAMILY_6185,
4631		.name = "Marvell 88E6131",
4632		.num_databases = 256,
4633		.num_macs = 8192,
4634		.num_ports = 8,
4635		.num_internal_phys = 0,
4636		.max_vid = 4095,
4637		.port_base_addr = 0x10,
4638		.phy_base_addr = 0x0,
4639		.global1_addr = 0x1b,
4640		.global2_addr = 0x1c,
4641		.age_time_coeff = 15000,
4642		.g1_irqs = 9,
4643		.atu_move_port_mask = 0xf,
4644		.multi_chip = true,
4645		.tag_protocol = DSA_TAG_PROTO_DSA,
4646		.ops = &mv88e6131_ops,
4647	},
4648
4649	[MV88E6141] = {
4650		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
4651		.family = MV88E6XXX_FAMILY_6341,
4652		.name = "Marvell 88E6141",
4653		.num_databases = 4096,
4654		.num_macs = 2048,
4655		.num_ports = 6,
4656		.num_internal_phys = 5,
4657		.num_gpio = 11,
4658		.max_vid = 4095,
4659		.port_base_addr = 0x10,
4660		.phy_base_addr = 0x10,
4661		.global1_addr = 0x1b,
4662		.global2_addr = 0x1c,
4663		.age_time_coeff = 3750,
4664		.atu_move_port_mask = 0x1f,
4665		.g1_irqs = 9,
4666		.g2_irqs = 10,
4667		.pvt = true,
4668		.multi_chip = true,
4669		.tag_protocol = DSA_TAG_PROTO_EDSA,
4670		.ops = &mv88e6141_ops,
4671	},
4672
4673	[MV88E6161] = {
4674		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6161,
4675		.family = MV88E6XXX_FAMILY_6165,
4676		.name = "Marvell 88E6161",
4677		.num_databases = 4096,
4678		.num_macs = 1024,
4679		.num_ports = 6,
4680		.num_internal_phys = 5,
4681		.max_vid = 4095,
4682		.port_base_addr = 0x10,
4683		.phy_base_addr = 0x0,
4684		.global1_addr = 0x1b,
4685		.global2_addr = 0x1c,
4686		.age_time_coeff = 15000,
4687		.g1_irqs = 9,
4688		.g2_irqs = 10,
4689		.atu_move_port_mask = 0xf,
4690		.pvt = true,
4691		.multi_chip = true,
4692		.tag_protocol = DSA_TAG_PROTO_EDSA,
4693		.ptp_support = true,
4694		.ops = &mv88e6161_ops,
4695	},
4696
4697	[MV88E6165] = {
4698		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6165,
4699		.family = MV88E6XXX_FAMILY_6165,
4700		.name = "Marvell 88E6165",
4701		.num_databases = 4096,
4702		.num_macs = 8192,
4703		.num_ports = 6,
4704		.num_internal_phys = 0,
4705		.max_vid = 4095,
4706		.port_base_addr = 0x10,
4707		.phy_base_addr = 0x0,
4708		.global1_addr = 0x1b,
4709		.global2_addr = 0x1c,
4710		.age_time_coeff = 15000,
4711		.g1_irqs = 9,
4712		.g2_irqs = 10,
4713		.atu_move_port_mask = 0xf,
4714		.pvt = true,
4715		.multi_chip = true,
4716		.tag_protocol = DSA_TAG_PROTO_DSA,
4717		.ptp_support = true,
4718		.ops = &mv88e6165_ops,
4719	},
4720
4721	[MV88E6171] = {
4722		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6171,
4723		.family = MV88E6XXX_FAMILY_6351,
4724		.name = "Marvell 88E6171",
4725		.num_databases = 4096,
4726		.num_macs = 8192,
4727		.num_ports = 7,
4728		.num_internal_phys = 5,
4729		.max_vid = 4095,
4730		.port_base_addr = 0x10,
4731		.phy_base_addr = 0x0,
4732		.global1_addr = 0x1b,
4733		.global2_addr = 0x1c,
4734		.age_time_coeff = 15000,
4735		.g1_irqs = 9,
4736		.g2_irqs = 10,
4737		.atu_move_port_mask = 0xf,
4738		.pvt = true,
4739		.multi_chip = true,
4740		.tag_protocol = DSA_TAG_PROTO_EDSA,
4741		.ops = &mv88e6171_ops,
4742	},
4743
4744	[MV88E6172] = {
4745		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6172,
4746		.family = MV88E6XXX_FAMILY_6352,
4747		.name = "Marvell 88E6172",
4748		.num_databases = 4096,
4749		.num_macs = 8192,
4750		.num_ports = 7,
4751		.num_internal_phys = 5,
4752		.num_gpio = 15,
4753		.max_vid = 4095,
4754		.port_base_addr = 0x10,
4755		.phy_base_addr = 0x0,
4756		.global1_addr = 0x1b,
4757		.global2_addr = 0x1c,
4758		.age_time_coeff = 15000,
4759		.g1_irqs = 9,
4760		.g2_irqs = 10,
4761		.atu_move_port_mask = 0xf,
4762		.pvt = true,
4763		.multi_chip = true,
4764		.tag_protocol = DSA_TAG_PROTO_EDSA,
4765		.ops = &mv88e6172_ops,
4766	},
4767
4768	[MV88E6175] = {
4769		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6175,
4770		.family = MV88E6XXX_FAMILY_6351,
4771		.name = "Marvell 88E6175",
4772		.num_databases = 4096,
4773		.num_macs = 8192,
4774		.num_ports = 7,
4775		.num_internal_phys = 5,
4776		.max_vid = 4095,
4777		.port_base_addr = 0x10,
4778		.phy_base_addr = 0x0,
4779		.global1_addr = 0x1b,
4780		.global2_addr = 0x1c,
4781		.age_time_coeff = 15000,
4782		.g1_irqs = 9,
4783		.g2_irqs = 10,
4784		.atu_move_port_mask = 0xf,
4785		.pvt = true,
4786		.multi_chip = true,
4787		.tag_protocol = DSA_TAG_PROTO_EDSA,
4788		.ops = &mv88e6175_ops,
4789	},
4790
4791	[MV88E6176] = {
4792		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6176,
4793		.family = MV88E6XXX_FAMILY_6352,
4794		.name = "Marvell 88E6176",
4795		.num_databases = 4096,
4796		.num_macs = 8192,
4797		.num_ports = 7,
4798		.num_internal_phys = 5,
4799		.num_gpio = 15,
4800		.max_vid = 4095,
4801		.port_base_addr = 0x10,
4802		.phy_base_addr = 0x0,
4803		.global1_addr = 0x1b,
4804		.global2_addr = 0x1c,
4805		.age_time_coeff = 15000,
4806		.g1_irqs = 9,
4807		.g2_irqs = 10,
4808		.atu_move_port_mask = 0xf,
4809		.pvt = true,
4810		.multi_chip = true,
4811		.tag_protocol = DSA_TAG_PROTO_EDSA,
4812		.ops = &mv88e6176_ops,
4813	},
4814
4815	[MV88E6185] = {
4816		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6185,
4817		.family = MV88E6XXX_FAMILY_6185,
4818		.name = "Marvell 88E6185",
4819		.num_databases = 256,
4820		.num_macs = 8192,
4821		.num_ports = 10,
4822		.num_internal_phys = 0,
4823		.max_vid = 4095,
4824		.port_base_addr = 0x10,
4825		.phy_base_addr = 0x0,
4826		.global1_addr = 0x1b,
4827		.global2_addr = 0x1c,
4828		.age_time_coeff = 15000,
4829		.g1_irqs = 8,
4830		.atu_move_port_mask = 0xf,
4831		.multi_chip = true,
4832		.tag_protocol = DSA_TAG_PROTO_EDSA,
4833		.ops = &mv88e6185_ops,
4834	},
4835
4836	[MV88E6190] = {
4837		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190,
4838		.family = MV88E6XXX_FAMILY_6390,
4839		.name = "Marvell 88E6190",
4840		.num_databases = 4096,
4841		.num_macs = 16384,
4842		.num_ports = 11,	/* 10 + Z80 */
4843		.num_internal_phys = 9,
4844		.num_gpio = 16,
4845		.max_vid = 8191,
4846		.port_base_addr = 0x0,
4847		.phy_base_addr = 0x0,
4848		.global1_addr = 0x1b,
4849		.global2_addr = 0x1c,
4850		.tag_protocol = DSA_TAG_PROTO_DSA,
4851		.age_time_coeff = 3750,
4852		.g1_irqs = 9,
4853		.g2_irqs = 14,
4854		.pvt = true,
4855		.multi_chip = true,
4856		.atu_move_port_mask = 0x1f,
4857		.ops = &mv88e6190_ops,
4858	},
4859
4860	[MV88E6190X] = {
4861		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190X,
4862		.family = MV88E6XXX_FAMILY_6390,
4863		.name = "Marvell 88E6190X",
4864		.num_databases = 4096,
4865		.num_macs = 16384,
4866		.num_ports = 11,	/* 10 + Z80 */
4867		.num_internal_phys = 9,
4868		.num_gpio = 16,
4869		.max_vid = 8191,
4870		.port_base_addr = 0x0,
4871		.phy_base_addr = 0x0,
4872		.global1_addr = 0x1b,
4873		.global2_addr = 0x1c,
4874		.age_time_coeff = 3750,
4875		.g1_irqs = 9,
4876		.g2_irqs = 14,
4877		.atu_move_port_mask = 0x1f,
4878		.pvt = true,
4879		.multi_chip = true,
4880		.tag_protocol = DSA_TAG_PROTO_DSA,
4881		.ops = &mv88e6190x_ops,
4882	},
4883
4884	[MV88E6191] = {
4885		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6191,
4886		.family = MV88E6XXX_FAMILY_6390,
4887		.name = "Marvell 88E6191",
4888		.num_databases = 4096,
4889		.num_macs = 16384,
4890		.num_ports = 11,	/* 10 + Z80 */
4891		.num_internal_phys = 9,
4892		.max_vid = 8191,
4893		.port_base_addr = 0x0,
4894		.phy_base_addr = 0x0,
4895		.global1_addr = 0x1b,
4896		.global2_addr = 0x1c,
4897		.age_time_coeff = 3750,
4898		.g1_irqs = 9,
4899		.g2_irqs = 14,
4900		.atu_move_port_mask = 0x1f,
4901		.pvt = true,
4902		.multi_chip = true,
4903		.tag_protocol = DSA_TAG_PROTO_DSA,
4904		.ptp_support = true,
4905		.ops = &mv88e6191_ops,
4906	},
4907
4908	[MV88E6220] = {
4909		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6220,
4910		.family = MV88E6XXX_FAMILY_6250,
4911		.name = "Marvell 88E6220",
4912		.num_databases = 64,
4913
4914		/* Ports 2-4 are not routed to pins
4915		 * => usable ports 0, 1, 5, 6
4916		 */
4917		.num_ports = 7,
4918		.num_internal_phys = 2,
4919		.invalid_port_mask = BIT(2) | BIT(3) | BIT(4),
4920		.max_vid = 4095,
4921		.port_base_addr = 0x08,
4922		.phy_base_addr = 0x00,
4923		.global1_addr = 0x0f,
4924		.global2_addr = 0x07,
4925		.age_time_coeff = 15000,
4926		.g1_irqs = 9,
4927		.g2_irqs = 10,
4928		.atu_move_port_mask = 0xf,
4929		.dual_chip = true,
4930		.tag_protocol = DSA_TAG_PROTO_DSA,
4931		.ptp_support = true,
4932		.ops = &mv88e6250_ops,
4933	},
4934
4935	[MV88E6240] = {
4936		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6240,
4937		.family = MV88E6XXX_FAMILY_6352,
4938		.name = "Marvell 88E6240",
4939		.num_databases = 4096,
4940		.num_macs = 8192,
4941		.num_ports = 7,
4942		.num_internal_phys = 5,
4943		.num_gpio = 15,
4944		.max_vid = 4095,
4945		.port_base_addr = 0x10,
4946		.phy_base_addr = 0x0,
4947		.global1_addr = 0x1b,
4948		.global2_addr = 0x1c,
4949		.age_time_coeff = 15000,
4950		.g1_irqs = 9,
4951		.g2_irqs = 10,
4952		.atu_move_port_mask = 0xf,
4953		.pvt = true,
4954		.multi_chip = true,
4955		.tag_protocol = DSA_TAG_PROTO_EDSA,
4956		.ptp_support = true,
4957		.ops = &mv88e6240_ops,
4958	},
4959
4960	[MV88E6250] = {
4961		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6250,
4962		.family = MV88E6XXX_FAMILY_6250,
4963		.name = "Marvell 88E6250",
4964		.num_databases = 64,
4965		.num_ports = 7,
4966		.num_internal_phys = 5,
4967		.max_vid = 4095,
4968		.port_base_addr = 0x08,
4969		.phy_base_addr = 0x00,
4970		.global1_addr = 0x0f,
4971		.global2_addr = 0x07,
4972		.age_time_coeff = 15000,
4973		.g1_irqs = 9,
4974		.g2_irqs = 10,
4975		.atu_move_port_mask = 0xf,
4976		.dual_chip = true,
4977		.tag_protocol = DSA_TAG_PROTO_DSA,
4978		.ptp_support = true,
4979		.ops = &mv88e6250_ops,
4980	},
4981
4982	[MV88E6290] = {
4983		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6290,
4984		.family = MV88E6XXX_FAMILY_6390,
4985		.name = "Marvell 88E6290",
4986		.num_databases = 4096,
4987		.num_ports = 11,	/* 10 + Z80 */
4988		.num_internal_phys = 9,
4989		.num_gpio = 16,
4990		.max_vid = 8191,
4991		.port_base_addr = 0x0,
4992		.phy_base_addr = 0x0,
4993		.global1_addr = 0x1b,
4994		.global2_addr = 0x1c,
4995		.age_time_coeff = 3750,
4996		.g1_irqs = 9,
4997		.g2_irqs = 14,
4998		.atu_move_port_mask = 0x1f,
4999		.pvt = true,
5000		.multi_chip = true,
5001		.tag_protocol = DSA_TAG_PROTO_DSA,
5002		.ptp_support = true,
5003		.ops = &mv88e6290_ops,
5004	},
5005
5006	[MV88E6320] = {
5007		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6320,
5008		.family = MV88E6XXX_FAMILY_6320,
5009		.name = "Marvell 88E6320",
5010		.num_databases = 4096,
5011		.num_macs = 8192,
5012		.num_ports = 7,
5013		.num_internal_phys = 5,
5014		.num_gpio = 15,
5015		.max_vid = 4095,
5016		.port_base_addr = 0x10,
5017		.phy_base_addr = 0x0,
5018		.global1_addr = 0x1b,
5019		.global2_addr = 0x1c,
5020		.age_time_coeff = 15000,
5021		.g1_irqs = 8,
5022		.g2_irqs = 10,
5023		.atu_move_port_mask = 0xf,
5024		.pvt = true,
5025		.multi_chip = true,
5026		.tag_protocol = DSA_TAG_PROTO_EDSA,
5027		.ptp_support = true,
5028		.ops = &mv88e6320_ops,
5029	},
5030
5031	[MV88E6321] = {
5032		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6321,
5033		.family = MV88E6XXX_FAMILY_6320,
5034		.name = "Marvell 88E6321",
5035		.num_databases = 4096,
5036		.num_macs = 8192,
5037		.num_ports = 7,
5038		.num_internal_phys = 5,
5039		.num_gpio = 15,
5040		.max_vid = 4095,
5041		.port_base_addr = 0x10,
5042		.phy_base_addr = 0x0,
5043		.global1_addr = 0x1b,
5044		.global2_addr = 0x1c,
5045		.age_time_coeff = 15000,
5046		.g1_irqs = 8,
5047		.g2_irqs = 10,
5048		.atu_move_port_mask = 0xf,
5049		.multi_chip = true,
5050		.tag_protocol = DSA_TAG_PROTO_EDSA,
5051		.ptp_support = true,
5052		.ops = &mv88e6321_ops,
5053	},
5054
5055	[MV88E6341] = {
5056		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
5057		.family = MV88E6XXX_FAMILY_6341,
5058		.name = "Marvell 88E6341",
5059		.num_databases = 4096,
5060		.num_macs = 2048,
5061		.num_internal_phys = 5,
5062		.num_ports = 6,
5063		.num_gpio = 11,
5064		.max_vid = 4095,
5065		.port_base_addr = 0x10,
5066		.phy_base_addr = 0x10,
5067		.global1_addr = 0x1b,
5068		.global2_addr = 0x1c,
5069		.age_time_coeff = 3750,
5070		.atu_move_port_mask = 0x1f,
5071		.g1_irqs = 9,
5072		.g2_irqs = 10,
5073		.pvt = true,
5074		.multi_chip = true,
5075		.tag_protocol = DSA_TAG_PROTO_EDSA,
5076		.ptp_support = true,
5077		.ops = &mv88e6341_ops,
5078	},
5079
5080	[MV88E6350] = {
5081		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6350,
5082		.family = MV88E6XXX_FAMILY_6351,
5083		.name = "Marvell 88E6350",
5084		.num_databases = 4096,
5085		.num_macs = 8192,
5086		.num_ports = 7,
5087		.num_internal_phys = 5,
5088		.max_vid = 4095,
5089		.port_base_addr = 0x10,
5090		.phy_base_addr = 0x0,
5091		.global1_addr = 0x1b,
5092		.global2_addr = 0x1c,
5093		.age_time_coeff = 15000,
5094		.g1_irqs = 9,
5095		.g2_irqs = 10,
5096		.atu_move_port_mask = 0xf,
5097		.pvt = true,
5098		.multi_chip = true,
5099		.tag_protocol = DSA_TAG_PROTO_EDSA,
5100		.ops = &mv88e6350_ops,
5101	},
5102
5103	[MV88E6351] = {
5104		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6351,
5105		.family = MV88E6XXX_FAMILY_6351,
5106		.name = "Marvell 88E6351",
5107		.num_databases = 4096,
5108		.num_macs = 8192,
5109		.num_ports = 7,
5110		.num_internal_phys = 5,
5111		.max_vid = 4095,
5112		.port_base_addr = 0x10,
5113		.phy_base_addr = 0x0,
5114		.global1_addr = 0x1b,
5115		.global2_addr = 0x1c,
5116		.age_time_coeff = 15000,
5117		.g1_irqs = 9,
5118		.g2_irqs = 10,
5119		.atu_move_port_mask = 0xf,
5120		.pvt = true,
5121		.multi_chip = true,
5122		.tag_protocol = DSA_TAG_PROTO_EDSA,
5123		.ops = &mv88e6351_ops,
5124	},
5125
5126	[MV88E6352] = {
5127		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6352,
5128		.family = MV88E6XXX_FAMILY_6352,
5129		.name = "Marvell 88E6352",
5130		.num_databases = 4096,
5131		.num_macs = 8192,
5132		.num_ports = 7,
5133		.num_internal_phys = 5,
5134		.num_gpio = 15,
5135		.max_vid = 4095,
5136		.port_base_addr = 0x10,
5137		.phy_base_addr = 0x0,
5138		.global1_addr = 0x1b,
5139		.global2_addr = 0x1c,
5140		.age_time_coeff = 15000,
5141		.g1_irqs = 9,
5142		.g2_irqs = 10,
5143		.atu_move_port_mask = 0xf,
5144		.pvt = true,
5145		.multi_chip = true,
5146		.tag_protocol = DSA_TAG_PROTO_EDSA,
5147		.ptp_support = true,
5148		.ops = &mv88e6352_ops,
5149	},
5150	[MV88E6390] = {
5151		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
5152		.family = MV88E6XXX_FAMILY_6390,
5153		.name = "Marvell 88E6390",
5154		.num_databases = 4096,
5155		.num_macs = 16384,
5156		.num_ports = 11,	/* 10 + Z80 */
5157		.num_internal_phys = 9,
5158		.num_gpio = 16,
5159		.max_vid = 8191,
5160		.port_base_addr = 0x0,
5161		.phy_base_addr = 0x0,
5162		.global1_addr = 0x1b,
5163		.global2_addr = 0x1c,
5164		.age_time_coeff = 3750,
5165		.g1_irqs = 9,
5166		.g2_irqs = 14,
5167		.atu_move_port_mask = 0x1f,
5168		.pvt = true,
5169		.multi_chip = true,
5170		.tag_protocol = DSA_TAG_PROTO_DSA,
5171		.ptp_support = true,
5172		.ops = &mv88e6390_ops,
5173	},
5174	[MV88E6390X] = {
5175		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390X,
5176		.family = MV88E6XXX_FAMILY_6390,
5177		.name = "Marvell 88E6390X",
5178		.num_databases = 4096,
5179		.num_macs = 16384,
5180		.num_ports = 11,	/* 10 + Z80 */
5181		.num_internal_phys = 9,
5182		.num_gpio = 16,
5183		.max_vid = 8191,
5184		.port_base_addr = 0x0,
5185		.phy_base_addr = 0x0,
5186		.global1_addr = 0x1b,
5187		.global2_addr = 0x1c,
5188		.age_time_coeff = 3750,
5189		.g1_irqs = 9,
5190		.g2_irqs = 14,
5191		.atu_move_port_mask = 0x1f,
5192		.pvt = true,
5193		.multi_chip = true,
5194		.tag_protocol = DSA_TAG_PROTO_DSA,
5195		.ptp_support = true,
5196		.ops = &mv88e6390x_ops,
5197	},
5198};
5199
5200static const struct mv88e6xxx_info *mv88e6xxx_lookup_info(unsigned int prod_num)
5201{
5202	int i;
5203
5204	for (i = 0; i < ARRAY_SIZE(mv88e6xxx_table); ++i)
5205		if (mv88e6xxx_table[i].prod_num == prod_num)
5206			return &mv88e6xxx_table[i];
5207
5208	return NULL;
5209}
5210
5211static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip)
5212{
5213	const struct mv88e6xxx_info *info;
5214	unsigned int prod_num, rev;
5215	u16 id;
5216	int err;
5217
5218	mv88e6xxx_reg_lock(chip);
5219	err = mv88e6xxx_port_read(chip, 0, MV88E6XXX_PORT_SWITCH_ID, &id);
5220	mv88e6xxx_reg_unlock(chip);
5221	if (err)
5222		return err;
5223
5224	prod_num = id & MV88E6XXX_PORT_SWITCH_ID_PROD_MASK;
5225	rev = id & MV88E6XXX_PORT_SWITCH_ID_REV_MASK;
5226
5227	info = mv88e6xxx_lookup_info(prod_num);
5228	if (!info)
5229		return -ENODEV;
5230
5231	/* Update the compatible info with the probed one */
5232	chip->info = info;
5233
5234	err = mv88e6xxx_g2_require(chip);
5235	if (err)
5236		return err;
5237
5238	dev_info(chip->dev, "switch 0x%x detected: %s, revision %u\n",
5239		 chip->info->prod_num, chip->info->name, rev);
5240
5241	return 0;
5242}
5243
5244static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev)
5245{
5246	struct mv88e6xxx_chip *chip;
5247
5248	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
5249	if (!chip)
5250		return NULL;
5251
5252	chip->dev = dev;
5253
5254	mutex_init(&chip->reg_lock);
5255	INIT_LIST_HEAD(&chip->mdios);
5256	idr_init(&chip->policies);
5257
5258	return chip;
5259}
5260
5261static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds,
5262							int port,
5263							enum dsa_tag_protocol m)
5264{
5265	struct mv88e6xxx_chip *chip = ds->priv;
5266
5267	return chip->info->tag_protocol;
5268}
5269
5270static int mv88e6xxx_port_mdb_prepare(struct dsa_switch *ds, int port,
5271				      const struct switchdev_obj_port_mdb *mdb)
5272{
5273	/* We don't need any dynamic resource from the kernel (yet),
5274	 * so skip the prepare phase.
5275	 */
5276
5277	return 0;
5278}
5279
5280static void mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port,
5281				   const struct switchdev_obj_port_mdb *mdb)
5282{
5283	struct mv88e6xxx_chip *chip = ds->priv;
5284
5285	mv88e6xxx_reg_lock(chip);
5286	if (mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
5287					 MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC))
5288		dev_err(ds->dev, "p%d: failed to load multicast MAC address\n",
5289			port);
5290	mv88e6xxx_reg_unlock(chip);
5291}
5292
5293static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port,
5294				  const struct switchdev_obj_port_mdb *mdb)
5295{
5296	struct mv88e6xxx_chip *chip = ds->priv;
5297	int err;
5298
5299	mv88e6xxx_reg_lock(chip);
5300	err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid, 0);
5301	mv88e6xxx_reg_unlock(chip);
5302
5303	return err;
5304}
5305
5306static int mv88e6xxx_port_mirror_add(struct dsa_switch *ds, int port,
5307				     struct dsa_mall_mirror_tc_entry *mirror,
5308				     bool ingress)
5309{
5310	enum mv88e6xxx_egress_direction direction = ingress ?
5311						MV88E6XXX_EGRESS_DIR_INGRESS :
5312						MV88E6XXX_EGRESS_DIR_EGRESS;
5313	struct mv88e6xxx_chip *chip = ds->priv;
5314	bool other_mirrors = false;
5315	int i;
5316	int err;
5317
5318	if (!chip->info->ops->set_egress_port)
5319		return -EOPNOTSUPP;
5320
5321	mutex_lock(&chip->reg_lock);
5322	if ((ingress ? chip->ingress_dest_port : chip->egress_dest_port) !=
5323	    mirror->to_local_port) {
5324		for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
5325			other_mirrors |= ingress ?
5326					 chip->ports[i].mirror_ingress :
5327					 chip->ports[i].mirror_egress;
5328
5329		/* Can't change egress port when other mirror is active */
5330		if (other_mirrors) {
5331			err = -EBUSY;
5332			goto out;
5333		}
5334
5335		err = chip->info->ops->set_egress_port(chip,
5336						       direction,
5337						       mirror->to_local_port);
5338		if (err)
5339			goto out;
5340	}
5341
5342	err = mv88e6xxx_port_set_mirror(chip, port, direction, true);
5343out:
5344	mutex_unlock(&chip->reg_lock);
5345
5346	return err;
5347}
5348
5349static void mv88e6xxx_port_mirror_del(struct dsa_switch *ds, int port,
5350				      struct dsa_mall_mirror_tc_entry *mirror)
5351{
5352	enum mv88e6xxx_egress_direction direction = mirror->ingress ?
5353						MV88E6XXX_EGRESS_DIR_INGRESS :
5354						MV88E6XXX_EGRESS_DIR_EGRESS;
5355	struct mv88e6xxx_chip *chip = ds->priv;
5356	bool other_mirrors = false;
5357	int i;
5358
5359	mutex_lock(&chip->reg_lock);
5360	if (mv88e6xxx_port_set_mirror(chip, port, direction, false))
5361		dev_err(ds->dev, "p%d: failed to disable mirroring\n", port);
5362
5363	for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
5364		other_mirrors |= mirror->ingress ?
5365				 chip->ports[i].mirror_ingress :
5366				 chip->ports[i].mirror_egress;
5367
5368	/* Reset egress port when no other mirror is active */
5369	if (!other_mirrors) {
5370		if (chip->info->ops->set_egress_port(chip,
5371						     direction,
5372						     dsa_upstream_port(ds,
5373								       port)))
5374			dev_err(ds->dev, "failed to set egress port\n");
5375	}
5376
5377	mutex_unlock(&chip->reg_lock);
5378}
5379
5380static int mv88e6xxx_port_egress_floods(struct dsa_switch *ds, int port,
5381					 bool unicast, bool multicast)
5382{
5383	struct mv88e6xxx_chip *chip = ds->priv;
5384	int err = -EOPNOTSUPP;
5385
5386	mv88e6xxx_reg_lock(chip);
5387	if (chip->info->ops->port_set_egress_floods)
5388		err = chip->info->ops->port_set_egress_floods(chip, port,
5389							      unicast,
5390							      multicast);
5391	mv88e6xxx_reg_unlock(chip);
5392
5393	return err;
5394}
5395
5396static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
5397	.get_tag_protocol	= mv88e6xxx_get_tag_protocol,
5398	.setup			= mv88e6xxx_setup,
5399	.teardown		= mv88e6xxx_teardown,
5400	.phylink_validate	= mv88e6xxx_validate,
5401	.phylink_mac_link_state	= mv88e6xxx_serdes_pcs_get_state,
5402	.phylink_mac_config	= mv88e6xxx_mac_config,
5403	.phylink_mac_an_restart	= mv88e6xxx_serdes_pcs_an_restart,
5404	.phylink_mac_link_down	= mv88e6xxx_mac_link_down,
5405	.phylink_mac_link_up	= mv88e6xxx_mac_link_up,
5406	.get_strings		= mv88e6xxx_get_strings,
5407	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
5408	.get_sset_count		= mv88e6xxx_get_sset_count,
5409	.port_enable		= mv88e6xxx_port_enable,
5410	.port_disable		= mv88e6xxx_port_disable,
5411	.port_max_mtu		= mv88e6xxx_get_max_mtu,
5412	.port_change_mtu	= mv88e6xxx_change_mtu,
5413	.get_mac_eee		= mv88e6xxx_get_mac_eee,
5414	.set_mac_eee		= mv88e6xxx_set_mac_eee,
5415	.get_eeprom_len		= mv88e6xxx_get_eeprom_len,
5416	.get_eeprom		= mv88e6xxx_get_eeprom,
5417	.set_eeprom		= mv88e6xxx_set_eeprom,
5418	.get_regs_len		= mv88e6xxx_get_regs_len,
5419	.get_regs		= mv88e6xxx_get_regs,
5420	.get_rxnfc		= mv88e6xxx_get_rxnfc,
5421	.set_rxnfc		= mv88e6xxx_set_rxnfc,
5422	.set_ageing_time	= mv88e6xxx_set_ageing_time,
5423	.port_bridge_join	= mv88e6xxx_port_bridge_join,
5424	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
5425	.port_egress_floods	= mv88e6xxx_port_egress_floods,
5426	.port_stp_state_set	= mv88e6xxx_port_stp_state_set,
5427	.port_fast_age		= mv88e6xxx_port_fast_age,
5428	.port_vlan_filtering	= mv88e6xxx_port_vlan_filtering,
5429	.port_vlan_prepare	= mv88e6xxx_port_vlan_prepare,
5430	.port_vlan_add		= mv88e6xxx_port_vlan_add,
5431	.port_vlan_del		= mv88e6xxx_port_vlan_del,
5432	.port_fdb_add           = mv88e6xxx_port_fdb_add,
5433	.port_fdb_del           = mv88e6xxx_port_fdb_del,
5434	.port_fdb_dump          = mv88e6xxx_port_fdb_dump,
5435	.port_mdb_prepare       = mv88e6xxx_port_mdb_prepare,
5436	.port_mdb_add           = mv88e6xxx_port_mdb_add,
5437	.port_mdb_del           = mv88e6xxx_port_mdb_del,
5438	.port_mirror_add	= mv88e6xxx_port_mirror_add,
5439	.port_mirror_del	= mv88e6xxx_port_mirror_del,
5440	.crosschip_bridge_join	= mv88e6xxx_crosschip_bridge_join,
5441	.crosschip_bridge_leave	= mv88e6xxx_crosschip_bridge_leave,
5442	.port_hwtstamp_set	= mv88e6xxx_port_hwtstamp_set,
5443	.port_hwtstamp_get	= mv88e6xxx_port_hwtstamp_get,
5444	.port_txtstamp		= mv88e6xxx_port_txtstamp,
5445	.port_rxtstamp		= mv88e6xxx_port_rxtstamp,
5446	.get_ts_info		= mv88e6xxx_get_ts_info,
5447	.devlink_param_get	= mv88e6xxx_devlink_param_get,
5448	.devlink_param_set	= mv88e6xxx_devlink_param_set,
5449	.devlink_info_get	= mv88e6xxx_devlink_info_get,
5450};
5451
5452static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
5453{
5454	struct device *dev = chip->dev;
5455	struct dsa_switch *ds;
5456
5457	ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
5458	if (!ds)
5459		return -ENOMEM;
5460
5461	ds->dev = dev;
5462	ds->num_ports = mv88e6xxx_num_ports(chip);
5463	ds->priv = chip;
5464	ds->dev = dev;
5465	ds->ops = &mv88e6xxx_switch_ops;
5466	ds->ageing_time_min = chip->info->age_time_coeff;
5467	ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
5468
5469	dev_set_drvdata(dev, ds);
5470
5471	return dsa_register_switch(ds);
5472}
5473
5474static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip)
5475{
5476	dsa_unregister_switch(chip->ds);
5477}
5478
5479static const void *pdata_device_get_match_data(struct device *dev)
5480{
5481	const struct of_device_id *matches = dev->driver->of_match_table;
5482	const struct dsa_mv88e6xxx_pdata *pdata = dev->platform_data;
5483
5484	for (; matches->name[0] || matches->type[0] || matches->compatible[0];
5485	     matches++) {
5486		if (!strcmp(pdata->compatible, matches->compatible))
5487			return matches->data;
5488	}
5489	return NULL;
5490}
5491
5492/* There is no suspend to RAM support at DSA level yet, the switch configuration
5493 * would be lost after a power cycle so prevent it to be suspended.
5494 */
5495static int __maybe_unused mv88e6xxx_suspend(struct device *dev)
5496{
5497	return -EOPNOTSUPP;
5498}
5499
5500static int __maybe_unused mv88e6xxx_resume(struct device *dev)
5501{
5502	return 0;
5503}
5504
5505static SIMPLE_DEV_PM_OPS(mv88e6xxx_pm_ops, mv88e6xxx_suspend, mv88e6xxx_resume);
5506
5507static int mv88e6xxx_probe(struct mdio_device *mdiodev)
5508{
5509	struct dsa_mv88e6xxx_pdata *pdata = mdiodev->dev.platform_data;
5510	const struct mv88e6xxx_info *compat_info = NULL;
5511	struct device *dev = &mdiodev->dev;
5512	struct device_node *np = dev->of_node;
5513	struct mv88e6xxx_chip *chip;
5514	int port;
5515	int err;
5516
5517	if (!np && !pdata)
5518		return -EINVAL;
5519
5520	if (np)
5521		compat_info = of_device_get_match_data(dev);
5522
5523	if (pdata) {
5524		compat_info = pdata_device_get_match_data(dev);
5525
5526		if (!pdata->netdev)
5527			return -EINVAL;
5528
5529		for (port = 0; port < DSA_MAX_PORTS; port++) {
5530			if (!(pdata->enabled_ports & (1 << port)))
5531				continue;
5532			if (strcmp(pdata->cd.port_names[port], "cpu"))
5533				continue;
5534			pdata->cd.netdev[port] = &pdata->netdev->dev;
5535			break;
5536		}
5537	}
5538
5539	if (!compat_info)
5540		return -EINVAL;
5541
5542	chip = mv88e6xxx_alloc_chip(dev);
5543	if (!chip) {
5544		err = -ENOMEM;
5545		goto out;
5546	}
5547
5548	chip->info = compat_info;
5549
5550	err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
5551	if (err)
5552		goto out;
5553
5554	chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
5555	if (IS_ERR(chip->reset)) {
5556		err = PTR_ERR(chip->reset);
5557		goto out;
5558	}
5559	if (chip->reset)
5560		usleep_range(10000, 20000);
5561
5562	err = mv88e6xxx_detect(chip);
5563	if (err)
5564		goto out;
5565
5566	mv88e6xxx_phy_init(chip);
5567
5568	if (chip->info->ops->get_eeprom) {
5569		if (np)
5570			of_property_read_u32(np, "eeprom-length",
5571					     &chip->eeprom_len);
5572		else
5573			chip->eeprom_len = pdata->eeprom_len;
5574	}
5575
5576	mv88e6xxx_reg_lock(chip);
5577	err = mv88e6xxx_switch_reset(chip);
5578	mv88e6xxx_reg_unlock(chip);
5579	if (err)
5580		goto out;
5581
5582	if (np) {
5583		chip->irq = of_irq_get(np, 0);
5584		if (chip->irq == -EPROBE_DEFER) {
5585			err = chip->irq;
5586			goto out;
5587		}
5588	}
5589
5590	if (pdata)
5591		chip->irq = pdata->irq;
5592
5593	/* Has to be performed before the MDIO bus is created, because
5594	 * the PHYs will link their interrupts to these interrupt
5595	 * controllers
5596	 */
5597	mv88e6xxx_reg_lock(chip);
5598	if (chip->irq > 0)
5599		err = mv88e6xxx_g1_irq_setup(chip);
5600	else
5601		err = mv88e6xxx_irq_poll_setup(chip);
5602	mv88e6xxx_reg_unlock(chip);
5603
5604	if (err)
5605		goto out;
5606
5607	if (chip->info->g2_irqs > 0) {
5608		err = mv88e6xxx_g2_irq_setup(chip);
5609		if (err)
5610			goto out_g1_irq;
5611	}
5612
5613	err = mv88e6xxx_g1_atu_prob_irq_setup(chip);
5614	if (err)
5615		goto out_g2_irq;
5616
5617	err = mv88e6xxx_g1_vtu_prob_irq_setup(chip);
5618	if (err)
5619		goto out_g1_atu_prob_irq;
5620
5621	err = mv88e6xxx_mdios_register(chip, np);
5622	if (err)
5623		goto out_g1_vtu_prob_irq;
5624
5625	err = mv88e6xxx_register_switch(chip);
5626	if (err)
5627		goto out_mdio;
5628
5629	return 0;
5630
5631out_mdio:
5632	mv88e6xxx_mdios_unregister(chip);
5633out_g1_vtu_prob_irq:
5634	mv88e6xxx_g1_vtu_prob_irq_free(chip);
5635out_g1_atu_prob_irq:
5636	mv88e6xxx_g1_atu_prob_irq_free(chip);
5637out_g2_irq:
5638	if (chip->info->g2_irqs > 0)
5639		mv88e6xxx_g2_irq_free(chip);
5640out_g1_irq:
5641	if (chip->irq > 0)
5642		mv88e6xxx_g1_irq_free(chip);
5643	else
5644		mv88e6xxx_irq_poll_free(chip);
5645out:
5646	if (pdata)
5647		dev_put(pdata->netdev);
5648
5649	return err;
5650}
5651
5652static void mv88e6xxx_remove(struct mdio_device *mdiodev)
5653{
5654	struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
5655	struct mv88e6xxx_chip *chip = ds->priv;
5656
5657	if (chip->info->ptp_support) {
5658		mv88e6xxx_hwtstamp_free(chip);
5659		mv88e6xxx_ptp_free(chip);
5660	}
5661
5662	mv88e6xxx_phy_destroy(chip);
5663	mv88e6xxx_unregister_switch(chip);
5664	mv88e6xxx_mdios_unregister(chip);
5665
5666	mv88e6xxx_g1_vtu_prob_irq_free(chip);
5667	mv88e6xxx_g1_atu_prob_irq_free(chip);
5668
5669	if (chip->info->g2_irqs > 0)
5670		mv88e6xxx_g2_irq_free(chip);
5671
5672	if (chip->irq > 0)
5673		mv88e6xxx_g1_irq_free(chip);
5674	else
5675		mv88e6xxx_irq_poll_free(chip);
5676}
5677
5678static const struct of_device_id mv88e6xxx_of_match[] = {
5679	{
5680		.compatible = "marvell,mv88e6085",
5681		.data = &mv88e6xxx_table[MV88E6085],
5682	},
5683	{
5684		.compatible = "marvell,mv88e6190",
5685		.data = &mv88e6xxx_table[MV88E6190],
5686	},
5687	{
5688		.compatible = "marvell,mv88e6250",
5689		.data = &mv88e6xxx_table[MV88E6250],
5690	},
5691	{ /* sentinel */ },
5692};
5693
5694MODULE_DEVICE_TABLE(of, mv88e6xxx_of_match);
5695
5696static struct mdio_driver mv88e6xxx_driver = {
5697	.probe	= mv88e6xxx_probe,
5698	.remove = mv88e6xxx_remove,
5699	.mdiodrv.driver = {
5700		.name = "mv88e6085",
5701		.of_match_table = mv88e6xxx_of_match,
5702		.pm = &mv88e6xxx_pm_ops,
5703	},
5704};
5705
5706mdio_module_driver(mv88e6xxx_driver);
5707
5708MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
5709MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
5710MODULE_LICENSE("GPL");
5711