cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

chip.c (209497B)


      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/dsa/mv88e6xxx.h>
     16#include <linux/etherdevice.h>
     17#include <linux/ethtool.h>
     18#include <linux/if_bridge.h>
     19#include <linux/interrupt.h>
     20#include <linux/irq.h>
     21#include <linux/irqdomain.h>
     22#include <linux/jiffies.h>
     23#include <linux/list.h>
     24#include <linux/mdio.h>
     25#include <linux/module.h>
     26#include <linux/of_device.h>
     27#include <linux/of_irq.h>
     28#include <linux/of_mdio.h>
     29#include <linux/platform_data/mv88e6xxx.h>
     30#include <linux/netdevice.h>
     31#include <linux/gpio/consumer.h>
     32#include <linux/phylink.h>
     33#include <net/dsa.h>
     34
     35#include "chip.h"
     36#include "devlink.h"
     37#include "global1.h"
     38#include "global2.h"
     39#include "hwtstamp.h"
     40#include "phy.h"
     41#include "port.h"
     42#include "ptp.h"
     43#include "serdes.h"
     44#include "smi.h"
     45
     46static void assert_reg_lock(struct mv88e6xxx_chip *chip)
     47{
     48	if (unlikely(!mutex_is_locked(&chip->reg_lock))) {
     49		dev_err(chip->dev, "Switch registers lock not held!\n");
     50		dump_stack();
     51	}
     52}
     53
     54int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val)
     55{
     56	int err;
     57
     58	assert_reg_lock(chip);
     59
     60	err = mv88e6xxx_smi_read(chip, addr, reg, val);
     61	if (err)
     62		return err;
     63
     64	dev_dbg(chip->dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
     65		addr, reg, *val);
     66
     67	return 0;
     68}
     69
     70int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val)
     71{
     72	int err;
     73
     74	assert_reg_lock(chip);
     75
     76	err = mv88e6xxx_smi_write(chip, addr, reg, val);
     77	if (err)
     78		return err;
     79
     80	dev_dbg(chip->dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
     81		addr, reg, val);
     82
     83	return 0;
     84}
     85
     86int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
     87			u16 mask, u16 val)
     88{
     89	const unsigned long timeout = jiffies + msecs_to_jiffies(50);
     90	u16 data;
     91	int err;
     92	int i;
     93
     94	/* There's no bus specific operation to wait for a mask. Even
     95	 * if the initial poll takes longer than 50ms, always do at
     96	 * least one more attempt.
     97	 */
     98	for (i = 0; time_before(jiffies, timeout) || (i < 2); i++) {
     99		err = mv88e6xxx_read(chip, addr, reg, &data);
    100		if (err)
    101			return err;
    102
    103		if ((data & mask) == val)
    104			return 0;
    105
    106		if (i < 2)
    107			cpu_relax();
    108		else
    109			usleep_range(1000, 2000);
    110	}
    111
    112	dev_err(chip->dev, "Timeout while waiting for switch\n");
    113	return -ETIMEDOUT;
    114}
    115
    116int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,
    117		       int bit, int val)
    118{
    119	return mv88e6xxx_wait_mask(chip, addr, reg, BIT(bit),
    120				   val ? BIT(bit) : 0x0000);
    121}
    122
    123struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip)
    124{
    125	struct mv88e6xxx_mdio_bus *mdio_bus;
    126
    127	mdio_bus = list_first_entry(&chip->mdios, struct mv88e6xxx_mdio_bus,
    128				    list);
    129	if (!mdio_bus)
    130		return NULL;
    131
    132	return mdio_bus->bus;
    133}
    134
    135static void mv88e6xxx_g1_irq_mask(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 void mv88e6xxx_g1_irq_unmask(struct irq_data *d)
    144{
    145	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
    146	unsigned int n = d->hwirq;
    147
    148	chip->g1_irq.masked &= ~(1 << n);
    149}
    150
    151static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct mv88e6xxx_chip *chip)
    152{
    153	unsigned int nhandled = 0;
    154	unsigned int sub_irq;
    155	unsigned int n;
    156	u16 reg;
    157	u16 ctl1;
    158	int err;
    159
    160	mv88e6xxx_reg_lock(chip);
    161	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
    162	mv88e6xxx_reg_unlock(chip);
    163
    164	if (err)
    165		goto out;
    166
    167	do {
    168		for (n = 0; n < chip->g1_irq.nirqs; ++n) {
    169			if (reg & (1 << n)) {
    170				sub_irq = irq_find_mapping(chip->g1_irq.domain,
    171							   n);
    172				handle_nested_irq(sub_irq);
    173				++nhandled;
    174			}
    175		}
    176
    177		mv88e6xxx_reg_lock(chip);
    178		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &ctl1);
    179		if (err)
    180			goto unlock;
    181		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
    182unlock:
    183		mv88e6xxx_reg_unlock(chip);
    184		if (err)
    185			goto out;
    186		ctl1 &= GENMASK(chip->g1_irq.nirqs, 0);
    187	} while (reg & ctl1);
    188
    189out:
    190	return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
    191}
    192
    193static irqreturn_t mv88e6xxx_g1_irq_thread_fn(int irq, void *dev_id)
    194{
    195	struct mv88e6xxx_chip *chip = dev_id;
    196
    197	return mv88e6xxx_g1_irq_thread_work(chip);
    198}
    199
    200static void mv88e6xxx_g1_irq_bus_lock(struct irq_data *d)
    201{
    202	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
    203
    204	mv88e6xxx_reg_lock(chip);
    205}
    206
    207static void mv88e6xxx_g1_irq_bus_sync_unlock(struct irq_data *d)
    208{
    209	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
    210	u16 mask = GENMASK(chip->g1_irq.nirqs, 0);
    211	u16 reg;
    212	int err;
    213
    214	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &reg);
    215	if (err)
    216		goto out;
    217
    218	reg &= ~mask;
    219	reg |= (~chip->g1_irq.masked & mask);
    220
    221	err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, reg);
    222	if (err)
    223		goto out;
    224
    225out:
    226	mv88e6xxx_reg_unlock(chip);
    227}
    228
    229static const struct irq_chip mv88e6xxx_g1_irq_chip = {
    230	.name			= "mv88e6xxx-g1",
    231	.irq_mask		= mv88e6xxx_g1_irq_mask,
    232	.irq_unmask		= mv88e6xxx_g1_irq_unmask,
    233	.irq_bus_lock		= mv88e6xxx_g1_irq_bus_lock,
    234	.irq_bus_sync_unlock	= mv88e6xxx_g1_irq_bus_sync_unlock,
    235};
    236
    237static int mv88e6xxx_g1_irq_domain_map(struct irq_domain *d,
    238				       unsigned int irq,
    239				       irq_hw_number_t hwirq)
    240{
    241	struct mv88e6xxx_chip *chip = d->host_data;
    242
    243	irq_set_chip_data(irq, d->host_data);
    244	irq_set_chip_and_handler(irq, &chip->g1_irq.chip, handle_level_irq);
    245	irq_set_noprobe(irq);
    246
    247	return 0;
    248}
    249
    250static const struct irq_domain_ops mv88e6xxx_g1_irq_domain_ops = {
    251	.map	= mv88e6xxx_g1_irq_domain_map,
    252	.xlate	= irq_domain_xlate_twocell,
    253};
    254
    255/* To be called with reg_lock held */
    256static void mv88e6xxx_g1_irq_free_common(struct mv88e6xxx_chip *chip)
    257{
    258	int irq, virq;
    259	u16 mask;
    260
    261	mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
    262	mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
    263	mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
    264
    265	for (irq = 0; irq < chip->g1_irq.nirqs; irq++) {
    266		virq = irq_find_mapping(chip->g1_irq.domain, irq);
    267		irq_dispose_mapping(virq);
    268	}
    269
    270	irq_domain_remove(chip->g1_irq.domain);
    271}
    272
    273static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip)
    274{
    275	/*
    276	 * free_irq must be called without reg_lock taken because the irq
    277	 * handler takes this lock, too.
    278	 */
    279	free_irq(chip->irq, chip);
    280
    281	mv88e6xxx_reg_lock(chip);
    282	mv88e6xxx_g1_irq_free_common(chip);
    283	mv88e6xxx_reg_unlock(chip);
    284}
    285
    286static int mv88e6xxx_g1_irq_setup_common(struct mv88e6xxx_chip *chip)
    287{
    288	int err, irq, virq;
    289	u16 reg, mask;
    290
    291	chip->g1_irq.nirqs = chip->info->g1_irqs;
    292	chip->g1_irq.domain = irq_domain_add_simple(
    293		NULL, chip->g1_irq.nirqs, 0,
    294		&mv88e6xxx_g1_irq_domain_ops, chip);
    295	if (!chip->g1_irq.domain)
    296		return -ENOMEM;
    297
    298	for (irq = 0; irq < chip->g1_irq.nirqs; irq++)
    299		irq_create_mapping(chip->g1_irq.domain, irq);
    300
    301	chip->g1_irq.chip = mv88e6xxx_g1_irq_chip;
    302	chip->g1_irq.masked = ~0;
    303
    304	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
    305	if (err)
    306		goto out_mapping;
    307
    308	mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
    309
    310	err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
    311	if (err)
    312		goto out_disable;
    313
    314	/* Reading the interrupt status clears (most of) them */
    315	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
    316	if (err)
    317		goto out_disable;
    318
    319	return 0;
    320
    321out_disable:
    322	mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
    323	mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
    324
    325out_mapping:
    326	for (irq = 0; irq < 16; irq++) {
    327		virq = irq_find_mapping(chip->g1_irq.domain, irq);
    328		irq_dispose_mapping(virq);
    329	}
    330
    331	irq_domain_remove(chip->g1_irq.domain);
    332
    333	return err;
    334}
    335
    336static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip)
    337{
    338	static struct lock_class_key lock_key;
    339	static struct lock_class_key request_key;
    340	int err;
    341
    342	err = mv88e6xxx_g1_irq_setup_common(chip);
    343	if (err)
    344		return err;
    345
    346	/* These lock classes tells lockdep that global 1 irqs are in
    347	 * a different category than their parent GPIO, so it won't
    348	 * report false recursion.
    349	 */
    350	irq_set_lockdep_class(chip->irq, &lock_key, &request_key);
    351
    352	snprintf(chip->irq_name, sizeof(chip->irq_name),
    353		 "mv88e6xxx-%s", dev_name(chip->dev));
    354
    355	mv88e6xxx_reg_unlock(chip);
    356	err = request_threaded_irq(chip->irq, NULL,
    357				   mv88e6xxx_g1_irq_thread_fn,
    358				   IRQF_ONESHOT | IRQF_SHARED,
    359				   chip->irq_name, chip);
    360	mv88e6xxx_reg_lock(chip);
    361	if (err)
    362		mv88e6xxx_g1_irq_free_common(chip);
    363
    364	return err;
    365}
    366
    367static void mv88e6xxx_irq_poll(struct kthread_work *work)
    368{
    369	struct mv88e6xxx_chip *chip = container_of(work,
    370						   struct mv88e6xxx_chip,
    371						   irq_poll_work.work);
    372	mv88e6xxx_g1_irq_thread_work(chip);
    373
    374	kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work,
    375				   msecs_to_jiffies(100));
    376}
    377
    378static int mv88e6xxx_irq_poll_setup(struct mv88e6xxx_chip *chip)
    379{
    380	int err;
    381
    382	err = mv88e6xxx_g1_irq_setup_common(chip);
    383	if (err)
    384		return err;
    385
    386	kthread_init_delayed_work(&chip->irq_poll_work,
    387				  mv88e6xxx_irq_poll);
    388
    389	chip->kworker = kthread_create_worker(0, "%s", dev_name(chip->dev));
    390	if (IS_ERR(chip->kworker))
    391		return PTR_ERR(chip->kworker);
    392
    393	kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work,
    394				   msecs_to_jiffies(100));
    395
    396	return 0;
    397}
    398
    399static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip)
    400{
    401	kthread_cancel_delayed_work_sync(&chip->irq_poll_work);
    402	kthread_destroy_worker(chip->kworker);
    403
    404	mv88e6xxx_reg_lock(chip);
    405	mv88e6xxx_g1_irq_free_common(chip);
    406	mv88e6xxx_reg_unlock(chip);
    407}
    408
    409static int mv88e6xxx_port_config_interface(struct mv88e6xxx_chip *chip,
    410					   int port, phy_interface_t interface)
    411{
    412	int err;
    413
    414	if (chip->info->ops->port_set_rgmii_delay) {
    415		err = chip->info->ops->port_set_rgmii_delay(chip, port,
    416							    interface);
    417		if (err && err != -EOPNOTSUPP)
    418			return err;
    419	}
    420
    421	if (chip->info->ops->port_set_cmode) {
    422		err = chip->info->ops->port_set_cmode(chip, port,
    423						      interface);
    424		if (err && err != -EOPNOTSUPP)
    425			return err;
    426	}
    427
    428	return 0;
    429}
    430
    431static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port,
    432				    int link, int speed, int duplex, int pause,
    433				    phy_interface_t mode)
    434{
    435	int err;
    436
    437	if (!chip->info->ops->port_set_link)
    438		return 0;
    439
    440	/* Port's MAC control must not be changed unless the link is down */
    441	err = chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN);
    442	if (err)
    443		return err;
    444
    445	if (chip->info->ops->port_set_speed_duplex) {
    446		err = chip->info->ops->port_set_speed_duplex(chip, port,
    447							     speed, duplex);
    448		if (err && err != -EOPNOTSUPP)
    449			goto restore_link;
    450	}
    451
    452	if (speed == SPEED_MAX && chip->info->ops->port_max_speed_mode)
    453		mode = chip->info->ops->port_max_speed_mode(port);
    454
    455	if (chip->info->ops->port_set_pause) {
    456		err = chip->info->ops->port_set_pause(chip, port, pause);
    457		if (err)
    458			goto restore_link;
    459	}
    460
    461	err = mv88e6xxx_port_config_interface(chip, port, mode);
    462restore_link:
    463	if (chip->info->ops->port_set_link(chip, port, link))
    464		dev_err(chip->dev, "p%d: failed to restore MAC's link\n", port);
    465
    466	return err;
    467}
    468
    469static int mv88e6xxx_phy_is_internal(struct dsa_switch *ds, int port)
    470{
    471	struct mv88e6xxx_chip *chip = ds->priv;
    472
    473	return port < chip->info->num_internal_phys;
    474}
    475
    476static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port)
    477{
    478	u16 reg;
    479	int err;
    480
    481	/* The 88e6250 family does not have the PHY detect bit. Instead,
    482	 * report whether the port is internal.
    483	 */
    484	if (chip->info->family == MV88E6XXX_FAMILY_6250)
    485		return port < chip->info->num_internal_phys;
    486
    487	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
    488	if (err) {
    489		dev_err(chip->dev,
    490			"p%d: %s: failed to read port status\n",
    491			port, __func__);
    492		return err;
    493	}
    494
    495	return !!(reg & MV88E6XXX_PORT_STS_PHY_DETECT);
    496}
    497
    498static int mv88e6xxx_serdes_pcs_get_state(struct dsa_switch *ds, int port,
    499					  struct phylink_link_state *state)
    500{
    501	struct mv88e6xxx_chip *chip = ds->priv;
    502	int lane;
    503	int err;
    504
    505	mv88e6xxx_reg_lock(chip);
    506	lane = mv88e6xxx_serdes_get_lane(chip, port);
    507	if (lane >= 0 && chip->info->ops->serdes_pcs_get_state)
    508		err = chip->info->ops->serdes_pcs_get_state(chip, port, lane,
    509							    state);
    510	else
    511		err = -EOPNOTSUPP;
    512	mv88e6xxx_reg_unlock(chip);
    513
    514	return err;
    515}
    516
    517static int mv88e6xxx_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
    518				       unsigned int mode,
    519				       phy_interface_t interface,
    520				       const unsigned long *advertise)
    521{
    522	const struct mv88e6xxx_ops *ops = chip->info->ops;
    523	int lane;
    524
    525	if (ops->serdes_pcs_config) {
    526		lane = mv88e6xxx_serdes_get_lane(chip, port);
    527		if (lane >= 0)
    528			return ops->serdes_pcs_config(chip, port, lane, mode,
    529						      interface, advertise);
    530	}
    531
    532	return 0;
    533}
    534
    535static void mv88e6xxx_serdes_pcs_an_restart(struct dsa_switch *ds, int port)
    536{
    537	struct mv88e6xxx_chip *chip = ds->priv;
    538	const struct mv88e6xxx_ops *ops;
    539	int err = 0;
    540	int lane;
    541
    542	ops = chip->info->ops;
    543
    544	if (ops->serdes_pcs_an_restart) {
    545		mv88e6xxx_reg_lock(chip);
    546		lane = mv88e6xxx_serdes_get_lane(chip, port);
    547		if (lane >= 0)
    548			err = ops->serdes_pcs_an_restart(chip, port, lane);
    549		mv88e6xxx_reg_unlock(chip);
    550
    551		if (err)
    552			dev_err(ds->dev, "p%d: failed to restart AN\n", port);
    553	}
    554}
    555
    556static int mv88e6xxx_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
    557					unsigned int mode,
    558					int speed, int duplex)
    559{
    560	const struct mv88e6xxx_ops *ops = chip->info->ops;
    561	int lane;
    562
    563	if (!phylink_autoneg_inband(mode) && ops->serdes_pcs_link_up) {
    564		lane = mv88e6xxx_serdes_get_lane(chip, port);
    565		if (lane >= 0)
    566			return ops->serdes_pcs_link_up(chip, port, lane,
    567						       speed, duplex);
    568	}
    569
    570	return 0;
    571}
    572
    573static const u8 mv88e6185_phy_interface_modes[] = {
    574	[MV88E6185_PORT_STS_CMODE_GMII_FD]	 = PHY_INTERFACE_MODE_GMII,
    575	[MV88E6185_PORT_STS_CMODE_MII_100_FD_PS] = PHY_INTERFACE_MODE_MII,
    576	[MV88E6185_PORT_STS_CMODE_MII_100]	 = PHY_INTERFACE_MODE_MII,
    577	[MV88E6185_PORT_STS_CMODE_MII_10]	 = PHY_INTERFACE_MODE_MII,
    578	[MV88E6185_PORT_STS_CMODE_SERDES]	 = PHY_INTERFACE_MODE_1000BASEX,
    579	[MV88E6185_PORT_STS_CMODE_1000BASE_X]	 = PHY_INTERFACE_MODE_1000BASEX,
    580	[MV88E6185_PORT_STS_CMODE_PHY]		 = PHY_INTERFACE_MODE_SGMII,
    581};
    582
    583static void mv88e6095_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
    584				       struct phylink_config *config)
    585{
    586	u8 cmode = chip->ports[port].cmode;
    587
    588	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
    589
    590	if (mv88e6xxx_phy_is_internal(chip->ds, port)) {
    591		__set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces);
    592	} else {
    593		if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) &&
    594		    mv88e6185_phy_interface_modes[cmode])
    595			__set_bit(mv88e6185_phy_interface_modes[cmode],
    596				  config->supported_interfaces);
    597
    598		config->mac_capabilities |= MAC_1000FD;
    599	}
    600}
    601
    602static void mv88e6185_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
    603				       struct phylink_config *config)
    604{
    605	u8 cmode = chip->ports[port].cmode;
    606
    607	if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) &&
    608	    mv88e6185_phy_interface_modes[cmode])
    609		__set_bit(mv88e6185_phy_interface_modes[cmode],
    610			  config->supported_interfaces);
    611
    612	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
    613				   MAC_1000FD;
    614}
    615
    616static const u8 mv88e6xxx_phy_interface_modes[] = {
    617	[MV88E6XXX_PORT_STS_CMODE_MII_PHY]	= PHY_INTERFACE_MODE_MII,
    618	[MV88E6XXX_PORT_STS_CMODE_MII]		= PHY_INTERFACE_MODE_MII,
    619	[MV88E6XXX_PORT_STS_CMODE_GMII]		= PHY_INTERFACE_MODE_GMII,
    620	[MV88E6XXX_PORT_STS_CMODE_RMII_PHY]	= PHY_INTERFACE_MODE_RMII,
    621	[MV88E6XXX_PORT_STS_CMODE_RMII]		= PHY_INTERFACE_MODE_RMII,
    622	[MV88E6XXX_PORT_STS_CMODE_100BASEX]	= PHY_INTERFACE_MODE_100BASEX,
    623	[MV88E6XXX_PORT_STS_CMODE_1000BASEX]	= PHY_INTERFACE_MODE_1000BASEX,
    624	[MV88E6XXX_PORT_STS_CMODE_SGMII]	= PHY_INTERFACE_MODE_SGMII,
    625	/* higher interface modes are not needed here, since ports supporting
    626	 * them are writable, and so the supported interfaces are filled in the
    627	 * corresponding .phylink_set_interfaces() implementation below
    628	 */
    629};
    630
    631static void mv88e6xxx_translate_cmode(u8 cmode, unsigned long *supported)
    632{
    633	if (cmode < ARRAY_SIZE(mv88e6xxx_phy_interface_modes) &&
    634	    mv88e6xxx_phy_interface_modes[cmode])
    635		__set_bit(mv88e6xxx_phy_interface_modes[cmode], supported);
    636	else if (cmode == MV88E6XXX_PORT_STS_CMODE_RGMII)
    637		phy_interface_set_rgmii(supported);
    638}
    639
    640static void mv88e6250_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
    641				       struct phylink_config *config)
    642{
    643	unsigned long *supported = config->supported_interfaces;
    644
    645	/* Translate the default cmode */
    646	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
    647
    648	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
    649}
    650
    651static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip)
    652{
    653	u16 reg, val;
    654	int err;
    655
    656	err = mv88e6xxx_port_read(chip, 4, MV88E6XXX_PORT_STS, &reg);
    657	if (err)
    658		return err;
    659
    660	/* If PHY_DETECT is zero, then we are not in auto-media mode */
    661	if (!(reg & MV88E6XXX_PORT_STS_PHY_DETECT))
    662		return 0xf;
    663
    664	val = reg & ~MV88E6XXX_PORT_STS_PHY_DETECT;
    665	err = mv88e6xxx_port_write(chip, 4, MV88E6XXX_PORT_STS, val);
    666	if (err)
    667		return err;
    668
    669	err = mv88e6xxx_port_read(chip, 4, MV88E6XXX_PORT_STS, &val);
    670	if (err)
    671		return err;
    672
    673	/* Restore PHY_DETECT value */
    674	err = mv88e6xxx_port_write(chip, 4, MV88E6XXX_PORT_STS, reg);
    675	if (err)
    676		return err;
    677
    678	return val & MV88E6XXX_PORT_STS_CMODE_MASK;
    679}
    680
    681static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
    682				       struct phylink_config *config)
    683{
    684	unsigned long *supported = config->supported_interfaces;
    685	int err, cmode;
    686
    687	/* Translate the default cmode */
    688	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
    689
    690	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
    691				   MAC_1000FD;
    692
    693	/* Port 4 supports automedia if the serdes is associated with it. */
    694	if (port == 4) {
    695		mv88e6xxx_reg_lock(chip);
    696		err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
    697		if (err < 0)
    698			dev_err(chip->dev, "p%d: failed to read scratch\n",
    699				port);
    700		if (err <= 0)
    701			goto unlock;
    702
    703		cmode = mv88e6352_get_port4_serdes_cmode(chip);
    704		if (cmode < 0)
    705			dev_err(chip->dev, "p%d: failed to read serdes cmode\n",
    706				port);
    707		else
    708			mv88e6xxx_translate_cmode(cmode, supported);
    709unlock:
    710		mv88e6xxx_reg_unlock(chip);
    711	}
    712}
    713
    714static void mv88e6341_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
    715				       struct phylink_config *config)
    716{
    717	unsigned long *supported = config->supported_interfaces;
    718
    719	/* Translate the default cmode */
    720	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
    721
    722	/* No ethtool bits for 200Mbps */
    723	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
    724				   MAC_1000FD;
    725
    726	/* The C_Mode field is programmable on port 5 */
    727	if (port == 5) {
    728		__set_bit(PHY_INTERFACE_MODE_SGMII, supported);
    729		__set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
    730		__set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
    731
    732		config->mac_capabilities |= MAC_2500FD;
    733	}
    734}
    735
    736static void mv88e6390_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
    737				       struct phylink_config *config)
    738{
    739	unsigned long *supported = config->supported_interfaces;
    740
    741	/* Translate the default cmode */
    742	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
    743
    744	/* No ethtool bits for 200Mbps */
    745	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
    746				   MAC_1000FD;
    747
    748	/* The C_Mode field is programmable on ports 9 and 10 */
    749	if (port == 9 || port == 10) {
    750		__set_bit(PHY_INTERFACE_MODE_SGMII, supported);
    751		__set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
    752		__set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
    753
    754		config->mac_capabilities |= MAC_2500FD;
    755	}
    756}
    757
    758static void mv88e6390x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
    759					struct phylink_config *config)
    760{
    761	unsigned long *supported = config->supported_interfaces;
    762
    763	mv88e6390_phylink_get_caps(chip, port, config);
    764
    765	/* For the 6x90X, ports 2-7 can be in automedia mode.
    766	 * (Note that 6x90 doesn't support RXAUI nor XAUI).
    767	 *
    768	 * Port 2 can also support 1000BASE-X in automedia mode if port 9 is
    769	 * configured for 1000BASE-X, SGMII or 2500BASE-X.
    770	 * Port 3-4 can also support 1000BASE-X in automedia mode if port 9 is
    771	 * configured for RXAUI, 1000BASE-X, SGMII or 2500BASE-X.
    772	 *
    773	 * Port 5 can also support 1000BASE-X in automedia mode if port 10 is
    774	 * configured for 1000BASE-X, SGMII or 2500BASE-X.
    775	 * Port 6-7 can also support 1000BASE-X in automedia mode if port 10 is
    776	 * configured for RXAUI, 1000BASE-X, SGMII or 2500BASE-X.
    777	 *
    778	 * For now, be permissive (as the old code was) and allow 1000BASE-X
    779	 * on ports 2..7.
    780	 */
    781	if (port >= 2 && port <= 7)
    782		__set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
    783
    784	/* The C_Mode field can also be programmed for 10G speeds */
    785	if (port == 9 || port == 10) {
    786		__set_bit(PHY_INTERFACE_MODE_XAUI, supported);
    787		__set_bit(PHY_INTERFACE_MODE_RXAUI, supported);
    788
    789		config->mac_capabilities |= MAC_10000FD;
    790	}
    791}
    792
    793static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
    794					struct phylink_config *config)
    795{
    796	unsigned long *supported = config->supported_interfaces;
    797	bool is_6191x =
    798		chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X;
    799
    800	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
    801
    802	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
    803				   MAC_1000FD;
    804
    805	/* The C_Mode field can be programmed for ports 0, 9 and 10 */
    806	if (port == 0 || port == 9 || port == 10) {
    807		__set_bit(PHY_INTERFACE_MODE_SGMII, supported);
    808		__set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
    809
    810		/* 6191X supports >1G modes only on port 10 */
    811		if (!is_6191x || port == 10) {
    812			__set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
    813			__set_bit(PHY_INTERFACE_MODE_5GBASER, supported);
    814			__set_bit(PHY_INTERFACE_MODE_10GBASER, supported);
    815			/* FIXME: USXGMII is not supported yet */
    816			/* __set_bit(PHY_INTERFACE_MODE_USXGMII, supported); */
    817
    818			config->mac_capabilities |= MAC_2500FD | MAC_5000FD |
    819				MAC_10000FD;
    820		}
    821	}
    822}
    823
    824static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
    825			       struct phylink_config *config)
    826{
    827	struct mv88e6xxx_chip *chip = ds->priv;
    828
    829	chip->info->ops->phylink_get_caps(chip, port, config);
    830
    831	/* Internal ports need GMII for PHYLIB */
    832	if (mv88e6xxx_phy_is_internal(ds, port))
    833		__set_bit(PHY_INTERFACE_MODE_GMII,
    834			  config->supported_interfaces);
    835}
    836
    837static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
    838				 unsigned int mode,
    839				 const struct phylink_link_state *state)
    840{
    841	struct mv88e6xxx_chip *chip = ds->priv;
    842	struct mv88e6xxx_port *p;
    843	int err = 0;
    844
    845	p = &chip->ports[port];
    846
    847	mv88e6xxx_reg_lock(chip);
    848
    849	if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) {
    850		/* In inband mode, the link may come up at any time while the
    851		 * link is not forced down. Force the link down while we
    852		 * reconfigure the interface mode.
    853		 */
    854		if (mode == MLO_AN_INBAND &&
    855		    p->interface != state->interface &&
    856		    chip->info->ops->port_set_link)
    857			chip->info->ops->port_set_link(chip, port,
    858						       LINK_FORCED_DOWN);
    859
    860		err = mv88e6xxx_port_config_interface(chip, port,
    861						      state->interface);
    862		if (err && err != -EOPNOTSUPP)
    863			goto err_unlock;
    864
    865		err = mv88e6xxx_serdes_pcs_config(chip, port, mode,
    866						  state->interface,
    867						  state->advertising);
    868		/* FIXME: we should restart negotiation if something changed -
    869		 * which is something we get if we convert to using phylinks
    870		 * PCS operations.
    871		 */
    872		if (err > 0)
    873			err = 0;
    874	}
    875
    876	/* Undo the forced down state above after completing configuration
    877	 * irrespective of its state on entry, which allows the link to come
    878	 * up in the in-band case where there is no separate SERDES. Also
    879	 * ensure that the link can come up if the PPU is in use and we are
    880	 * in PHY mode (we treat the PPU as an effective in-band mechanism.)
    881	 */
    882	if (chip->info->ops->port_set_link &&
    883	    ((mode == MLO_AN_INBAND && p->interface != state->interface) ||
    884	     (mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port))))
    885		chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
    886
    887	p->interface = state->interface;
    888
    889err_unlock:
    890	mv88e6xxx_reg_unlock(chip);
    891
    892	if (err && err != -EOPNOTSUPP)
    893		dev_err(ds->dev, "p%d: failed to configure MAC/PCS\n", port);
    894}
    895
    896static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
    897				    unsigned int mode,
    898				    phy_interface_t interface)
    899{
    900	struct mv88e6xxx_chip *chip = ds->priv;
    901	const struct mv88e6xxx_ops *ops;
    902	int err = 0;
    903
    904	ops = chip->info->ops;
    905
    906	mv88e6xxx_reg_lock(chip);
    907	/* Force the link down if we know the port may not be automatically
    908	 * updated by the switch or if we are using fixed-link mode.
    909	 */
    910	if ((!mv88e6xxx_port_ppu_updates(chip, port) ||
    911	     mode == MLO_AN_FIXED) && ops->port_sync_link)
    912		err = ops->port_sync_link(chip, port, mode, false);
    913
    914	if (!err && ops->port_set_speed_duplex)
    915		err = ops->port_set_speed_duplex(chip, port, SPEED_UNFORCED,
    916						 DUPLEX_UNFORCED);
    917	mv88e6xxx_reg_unlock(chip);
    918
    919	if (err)
    920		dev_err(chip->dev,
    921			"p%d: failed to force MAC link down\n", port);
    922}
    923
    924static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
    925				  unsigned int mode, phy_interface_t interface,
    926				  struct phy_device *phydev,
    927				  int speed, int duplex,
    928				  bool tx_pause, bool rx_pause)
    929{
    930	struct mv88e6xxx_chip *chip = ds->priv;
    931	const struct mv88e6xxx_ops *ops;
    932	int err = 0;
    933
    934	ops = chip->info->ops;
    935
    936	mv88e6xxx_reg_lock(chip);
    937	/* Configure and force the link up if we know that the port may not
    938	 * automatically updated by the switch or if we are using fixed-link
    939	 * mode.
    940	 */
    941	if (!mv88e6xxx_port_ppu_updates(chip, port) ||
    942	    mode == MLO_AN_FIXED) {
    943		/* FIXME: for an automedia port, should we force the link
    944		 * down here - what if the link comes up due to "other" media
    945		 * while we're bringing the port up, how is the exclusivity
    946		 * handled in the Marvell hardware? E.g. port 2 on 88E6390
    947		 * shared between internal PHY and Serdes.
    948		 */
    949		err = mv88e6xxx_serdes_pcs_link_up(chip, port, mode, speed,
    950						   duplex);
    951		if (err)
    952			goto error;
    953
    954		if (ops->port_set_speed_duplex) {
    955			err = ops->port_set_speed_duplex(chip, port,
    956							 speed, duplex);
    957			if (err && err != -EOPNOTSUPP)
    958				goto error;
    959		}
    960
    961		if (ops->port_sync_link)
    962			err = ops->port_sync_link(chip, port, mode, true);
    963	}
    964error:
    965	mv88e6xxx_reg_unlock(chip);
    966
    967	if (err && err != -EOPNOTSUPP)
    968		dev_err(ds->dev,
    969			"p%d: failed to configure MAC link up\n", port);
    970}
    971
    972static int mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
    973{
    974	if (!chip->info->ops->stats_snapshot)
    975		return -EOPNOTSUPP;
    976
    977	return chip->info->ops->stats_snapshot(chip, port);
    978}
    979
    980static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
    981	{ "in_good_octets",		8, 0x00, STATS_TYPE_BANK0, },
    982	{ "in_bad_octets",		4, 0x02, STATS_TYPE_BANK0, },
    983	{ "in_unicast",			4, 0x04, STATS_TYPE_BANK0, },
    984	{ "in_broadcasts",		4, 0x06, STATS_TYPE_BANK0, },
    985	{ "in_multicasts",		4, 0x07, STATS_TYPE_BANK0, },
    986	{ "in_pause",			4, 0x16, STATS_TYPE_BANK0, },
    987	{ "in_undersize",		4, 0x18, STATS_TYPE_BANK0, },
    988	{ "in_fragments",		4, 0x19, STATS_TYPE_BANK0, },
    989	{ "in_oversize",		4, 0x1a, STATS_TYPE_BANK0, },
    990	{ "in_jabber",			4, 0x1b, STATS_TYPE_BANK0, },
    991	{ "in_rx_error",		4, 0x1c, STATS_TYPE_BANK0, },
    992	{ "in_fcs_error",		4, 0x1d, STATS_TYPE_BANK0, },
    993	{ "out_octets",			8, 0x0e, STATS_TYPE_BANK0, },
    994	{ "out_unicast",		4, 0x10, STATS_TYPE_BANK0, },
    995	{ "out_broadcasts",		4, 0x13, STATS_TYPE_BANK0, },
    996	{ "out_multicasts",		4, 0x12, STATS_TYPE_BANK0, },
    997	{ "out_pause",			4, 0x15, STATS_TYPE_BANK0, },
    998	{ "excessive",			4, 0x11, STATS_TYPE_BANK0, },
    999	{ "collisions",			4, 0x1e, STATS_TYPE_BANK0, },
   1000	{ "deferred",			4, 0x05, STATS_TYPE_BANK0, },
   1001	{ "single",			4, 0x14, STATS_TYPE_BANK0, },
   1002	{ "multiple",			4, 0x17, STATS_TYPE_BANK0, },
   1003	{ "out_fcs_error",		4, 0x03, STATS_TYPE_BANK0, },
   1004	{ "late",			4, 0x1f, STATS_TYPE_BANK0, },
   1005	{ "hist_64bytes",		4, 0x08, STATS_TYPE_BANK0, },
   1006	{ "hist_65_127bytes",		4, 0x09, STATS_TYPE_BANK0, },
   1007	{ "hist_128_255bytes",		4, 0x0a, STATS_TYPE_BANK0, },
   1008	{ "hist_256_511bytes",		4, 0x0b, STATS_TYPE_BANK0, },
   1009	{ "hist_512_1023bytes",		4, 0x0c, STATS_TYPE_BANK0, },
   1010	{ "hist_1024_max_bytes",	4, 0x0d, STATS_TYPE_BANK0, },
   1011	{ "sw_in_discards",		4, 0x10, STATS_TYPE_PORT, },
   1012	{ "sw_in_filtered",		2, 0x12, STATS_TYPE_PORT, },
   1013	{ "sw_out_filtered",		2, 0x13, STATS_TYPE_PORT, },
   1014	{ "in_discards",		4, 0x00, STATS_TYPE_BANK1, },
   1015	{ "in_filtered",		4, 0x01, STATS_TYPE_BANK1, },
   1016	{ "in_accepted",		4, 0x02, STATS_TYPE_BANK1, },
   1017	{ "in_bad_accepted",		4, 0x03, STATS_TYPE_BANK1, },
   1018	{ "in_good_avb_class_a",	4, 0x04, STATS_TYPE_BANK1, },
   1019	{ "in_good_avb_class_b",	4, 0x05, STATS_TYPE_BANK1, },
   1020	{ "in_bad_avb_class_a",		4, 0x06, STATS_TYPE_BANK1, },
   1021	{ "in_bad_avb_class_b",		4, 0x07, STATS_TYPE_BANK1, },
   1022	{ "tcam_counter_0",		4, 0x08, STATS_TYPE_BANK1, },
   1023	{ "tcam_counter_1",		4, 0x09, STATS_TYPE_BANK1, },
   1024	{ "tcam_counter_2",		4, 0x0a, STATS_TYPE_BANK1, },
   1025	{ "tcam_counter_3",		4, 0x0b, STATS_TYPE_BANK1, },
   1026	{ "in_da_unknown",		4, 0x0e, STATS_TYPE_BANK1, },
   1027	{ "in_management",		4, 0x0f, STATS_TYPE_BANK1, },
   1028	{ "out_queue_0",		4, 0x10, STATS_TYPE_BANK1, },
   1029	{ "out_queue_1",		4, 0x11, STATS_TYPE_BANK1, },
   1030	{ "out_queue_2",		4, 0x12, STATS_TYPE_BANK1, },
   1031	{ "out_queue_3",		4, 0x13, STATS_TYPE_BANK1, },
   1032	{ "out_queue_4",		4, 0x14, STATS_TYPE_BANK1, },
   1033	{ "out_queue_5",		4, 0x15, STATS_TYPE_BANK1, },
   1034	{ "out_queue_6",		4, 0x16, STATS_TYPE_BANK1, },
   1035	{ "out_queue_7",		4, 0x17, STATS_TYPE_BANK1, },
   1036	{ "out_cut_through",		4, 0x18, STATS_TYPE_BANK1, },
   1037	{ "out_octets_a",		4, 0x1a, STATS_TYPE_BANK1, },
   1038	{ "out_octets_b",		4, 0x1b, STATS_TYPE_BANK1, },
   1039	{ "out_management",		4, 0x1f, STATS_TYPE_BANK1, },
   1040};
   1041
   1042static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
   1043					    struct mv88e6xxx_hw_stat *s,
   1044					    int port, u16 bank1_select,
   1045					    u16 histogram)
   1046{
   1047	u32 low;
   1048	u32 high = 0;
   1049	u16 reg = 0;
   1050	int err;
   1051	u64 value;
   1052
   1053	switch (s->type) {
   1054	case STATS_TYPE_PORT:
   1055		err = mv88e6xxx_port_read(chip, port, s->reg, &reg);
   1056		if (err)
   1057			return U64_MAX;
   1058
   1059		low = reg;
   1060		if (s->size == 4) {
   1061			err = mv88e6xxx_port_read(chip, port, s->reg + 1, &reg);
   1062			if (err)
   1063				return U64_MAX;
   1064			low |= ((u32)reg) << 16;
   1065		}
   1066		break;
   1067	case STATS_TYPE_BANK1:
   1068		reg = bank1_select;
   1069		fallthrough;
   1070	case STATS_TYPE_BANK0:
   1071		reg |= s->reg | histogram;
   1072		mv88e6xxx_g1_stats_read(chip, reg, &low);
   1073		if (s->size == 8)
   1074			mv88e6xxx_g1_stats_read(chip, reg + 1, &high);
   1075		break;
   1076	default:
   1077		return U64_MAX;
   1078	}
   1079	value = (((u64)high) << 32) | low;
   1080	return value;
   1081}
   1082
   1083static int mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip,
   1084				       uint8_t *data, int types)
   1085{
   1086	struct mv88e6xxx_hw_stat *stat;
   1087	int i, j;
   1088
   1089	for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
   1090		stat = &mv88e6xxx_hw_stats[i];
   1091		if (stat->type & types) {
   1092			memcpy(data + j * ETH_GSTRING_LEN, stat->string,
   1093			       ETH_GSTRING_LEN);
   1094			j++;
   1095		}
   1096	}
   1097
   1098	return j;
   1099}
   1100
   1101static int mv88e6095_stats_get_strings(struct mv88e6xxx_chip *chip,
   1102				       uint8_t *data)
   1103{
   1104	return mv88e6xxx_stats_get_strings(chip, data,
   1105					   STATS_TYPE_BANK0 | STATS_TYPE_PORT);
   1106}
   1107
   1108static int mv88e6250_stats_get_strings(struct mv88e6xxx_chip *chip,
   1109				       uint8_t *data)
   1110{
   1111	return mv88e6xxx_stats_get_strings(chip, data, STATS_TYPE_BANK0);
   1112}
   1113
   1114static int mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip,
   1115				       uint8_t *data)
   1116{
   1117	return mv88e6xxx_stats_get_strings(chip, data,
   1118					   STATS_TYPE_BANK0 | STATS_TYPE_BANK1);
   1119}
   1120
   1121static const uint8_t *mv88e6xxx_atu_vtu_stats_strings[] = {
   1122	"atu_member_violation",
   1123	"atu_miss_violation",
   1124	"atu_full_violation",
   1125	"vtu_member_violation",
   1126	"vtu_miss_violation",
   1127};
   1128
   1129static void mv88e6xxx_atu_vtu_get_strings(uint8_t *data)
   1130{
   1131	unsigned int i;
   1132
   1133	for (i = 0; i < ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings); i++)
   1134		strlcpy(data + i * ETH_GSTRING_LEN,
   1135			mv88e6xxx_atu_vtu_stats_strings[i],
   1136			ETH_GSTRING_LEN);
   1137}
   1138
   1139static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
   1140				  u32 stringset, uint8_t *data)
   1141{
   1142	struct mv88e6xxx_chip *chip = ds->priv;
   1143	int count = 0;
   1144
   1145	if (stringset != ETH_SS_STATS)
   1146		return;
   1147
   1148	mv88e6xxx_reg_lock(chip);
   1149
   1150	if (chip->info->ops->stats_get_strings)
   1151		count = chip->info->ops->stats_get_strings(chip, data);
   1152
   1153	if (chip->info->ops->serdes_get_strings) {
   1154		data += count * ETH_GSTRING_LEN;
   1155		count = chip->info->ops->serdes_get_strings(chip, port, data);
   1156	}
   1157
   1158	data += count * ETH_GSTRING_LEN;
   1159	mv88e6xxx_atu_vtu_get_strings(data);
   1160
   1161	mv88e6xxx_reg_unlock(chip);
   1162}
   1163
   1164static int mv88e6xxx_stats_get_sset_count(struct mv88e6xxx_chip *chip,
   1165					  int types)
   1166{
   1167	struct mv88e6xxx_hw_stat *stat;
   1168	int i, j;
   1169
   1170	for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
   1171		stat = &mv88e6xxx_hw_stats[i];
   1172		if (stat->type & types)
   1173			j++;
   1174	}
   1175	return j;
   1176}
   1177
   1178static int mv88e6095_stats_get_sset_count(struct mv88e6xxx_chip *chip)
   1179{
   1180	return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 |
   1181					      STATS_TYPE_PORT);
   1182}
   1183
   1184static int mv88e6250_stats_get_sset_count(struct mv88e6xxx_chip *chip)
   1185{
   1186	return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0);
   1187}
   1188
   1189static int mv88e6320_stats_get_sset_count(struct mv88e6xxx_chip *chip)
   1190{
   1191	return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 |
   1192					      STATS_TYPE_BANK1);
   1193}
   1194
   1195static int mv88e6xxx_get_sset_count(struct dsa_switch *ds, int port, int sset)
   1196{
   1197	struct mv88e6xxx_chip *chip = ds->priv;
   1198	int serdes_count = 0;
   1199	int count = 0;
   1200
   1201	if (sset != ETH_SS_STATS)
   1202		return 0;
   1203
   1204	mv88e6xxx_reg_lock(chip);
   1205	if (chip->info->ops->stats_get_sset_count)
   1206		count = chip->info->ops->stats_get_sset_count(chip);
   1207	if (count < 0)
   1208		goto out;
   1209
   1210	if (chip->info->ops->serdes_get_sset_count)
   1211		serdes_count = chip->info->ops->serdes_get_sset_count(chip,
   1212								      port);
   1213	if (serdes_count < 0) {
   1214		count = serdes_count;
   1215		goto out;
   1216	}
   1217	count += serdes_count;
   1218	count += ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings);
   1219
   1220out:
   1221	mv88e6xxx_reg_unlock(chip);
   1222
   1223	return count;
   1224}
   1225
   1226static int mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
   1227				     uint64_t *data, int types,
   1228				     u16 bank1_select, u16 histogram)
   1229{
   1230	struct mv88e6xxx_hw_stat *stat;
   1231	int i, j;
   1232
   1233	for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
   1234		stat = &mv88e6xxx_hw_stats[i];
   1235		if (stat->type & types) {
   1236			mv88e6xxx_reg_lock(chip);
   1237			data[j] = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
   1238							      bank1_select,
   1239							      histogram);
   1240			mv88e6xxx_reg_unlock(chip);
   1241
   1242			j++;
   1243		}
   1244	}
   1245	return j;
   1246}
   1247
   1248static int mv88e6095_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
   1249				     uint64_t *data)
   1250{
   1251	return mv88e6xxx_stats_get_stats(chip, port, data,
   1252					 STATS_TYPE_BANK0 | STATS_TYPE_PORT,
   1253					 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
   1254}
   1255
   1256static int mv88e6250_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
   1257				     uint64_t *data)
   1258{
   1259	return mv88e6xxx_stats_get_stats(chip, port, data, STATS_TYPE_BANK0,
   1260					 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
   1261}
   1262
   1263static int mv88e6320_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
   1264				     uint64_t *data)
   1265{
   1266	return mv88e6xxx_stats_get_stats(chip, port, data,
   1267					 STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
   1268					 MV88E6XXX_G1_STATS_OP_BANK_1_BIT_9,
   1269					 MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
   1270}
   1271
   1272static int mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
   1273				     uint64_t *data)
   1274{
   1275	return mv88e6xxx_stats_get_stats(chip, port, data,
   1276					 STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
   1277					 MV88E6XXX_G1_STATS_OP_BANK_1_BIT_10,
   1278					 0);
   1279}
   1280
   1281static void mv88e6xxx_atu_vtu_get_stats(struct mv88e6xxx_chip *chip, int port,
   1282					uint64_t *data)
   1283{
   1284	*data++ = chip->ports[port].atu_member_violation;
   1285	*data++ = chip->ports[port].atu_miss_violation;
   1286	*data++ = chip->ports[port].atu_full_violation;
   1287	*data++ = chip->ports[port].vtu_member_violation;
   1288	*data++ = chip->ports[port].vtu_miss_violation;
   1289}
   1290
   1291static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
   1292				uint64_t *data)
   1293{
   1294	int count = 0;
   1295
   1296	if (chip->info->ops->stats_get_stats)
   1297		count = chip->info->ops->stats_get_stats(chip, port, data);
   1298
   1299	mv88e6xxx_reg_lock(chip);
   1300	if (chip->info->ops->serdes_get_stats) {
   1301		data += count;
   1302		count = chip->info->ops->serdes_get_stats(chip, port, data);
   1303	}
   1304	data += count;
   1305	mv88e6xxx_atu_vtu_get_stats(chip, port, data);
   1306	mv88e6xxx_reg_unlock(chip);
   1307}
   1308
   1309static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
   1310					uint64_t *data)
   1311{
   1312	struct mv88e6xxx_chip *chip = ds->priv;
   1313	int ret;
   1314
   1315	mv88e6xxx_reg_lock(chip);
   1316
   1317	ret = mv88e6xxx_stats_snapshot(chip, port);
   1318	mv88e6xxx_reg_unlock(chip);
   1319
   1320	if (ret < 0)
   1321		return;
   1322
   1323	mv88e6xxx_get_stats(chip, port, data);
   1324
   1325}
   1326
   1327static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
   1328{
   1329	struct mv88e6xxx_chip *chip = ds->priv;
   1330	int len;
   1331
   1332	len = 32 * sizeof(u16);
   1333	if (chip->info->ops->serdes_get_regs_len)
   1334		len += chip->info->ops->serdes_get_regs_len(chip, port);
   1335
   1336	return len;
   1337}
   1338
   1339static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
   1340			       struct ethtool_regs *regs, void *_p)
   1341{
   1342	struct mv88e6xxx_chip *chip = ds->priv;
   1343	int err;
   1344	u16 reg;
   1345	u16 *p = _p;
   1346	int i;
   1347
   1348	regs->version = chip->info->prod_num;
   1349
   1350	memset(p, 0xff, 32 * sizeof(u16));
   1351
   1352	mv88e6xxx_reg_lock(chip);
   1353
   1354	for (i = 0; i < 32; i++) {
   1355
   1356		err = mv88e6xxx_port_read(chip, port, i, &reg);
   1357		if (!err)
   1358			p[i] = reg;
   1359	}
   1360
   1361	if (chip->info->ops->serdes_get_regs)
   1362		chip->info->ops->serdes_get_regs(chip, port, &p[i]);
   1363
   1364	mv88e6xxx_reg_unlock(chip);
   1365}
   1366
   1367static int mv88e6xxx_get_mac_eee(struct dsa_switch *ds, int port,
   1368				 struct ethtool_eee *e)
   1369{
   1370	/* Nothing to do on the port's MAC */
   1371	return 0;
   1372}
   1373
   1374static int mv88e6xxx_set_mac_eee(struct dsa_switch *ds, int port,
   1375				 struct ethtool_eee *e)
   1376{
   1377	/* Nothing to do on the port's MAC */
   1378	return 0;
   1379}
   1380
   1381/* Mask of the local ports allowed to receive frames from a given fabric port */
   1382static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port)
   1383{
   1384	struct dsa_switch *ds = chip->ds;
   1385	struct dsa_switch_tree *dst = ds->dst;
   1386	struct dsa_port *dp, *other_dp;
   1387	bool found = false;
   1388	u16 pvlan;
   1389
   1390	/* dev is a physical switch */
   1391	if (dev <= dst->last_switch) {
   1392		list_for_each_entry(dp, &dst->ports, list) {
   1393			if (dp->ds->index == dev && dp->index == port) {
   1394				/* dp might be a DSA link or a user port, so it
   1395				 * might or might not have a bridge.
   1396				 * Use the "found" variable for both cases.
   1397				 */
   1398				found = true;
   1399				break;
   1400			}
   1401		}
   1402	/* dev is a virtual bridge */
   1403	} else {
   1404		list_for_each_entry(dp, &dst->ports, list) {
   1405			unsigned int bridge_num = dsa_port_bridge_num_get(dp);
   1406
   1407			if (!bridge_num)
   1408				continue;
   1409
   1410			if (bridge_num + dst->last_switch != dev)
   1411				continue;
   1412
   1413			found = true;
   1414			break;
   1415		}
   1416	}
   1417
   1418	/* Prevent frames from unknown switch or virtual bridge */
   1419	if (!found)
   1420		return 0;
   1421
   1422	/* Frames from DSA links and CPU ports can egress any local port */
   1423	if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA)
   1424		return mv88e6xxx_port_mask(chip);
   1425
   1426	pvlan = 0;
   1427
   1428	/* Frames from standalone user ports can only egress on the
   1429	 * upstream port.
   1430	 */
   1431	if (!dsa_port_bridge_dev_get(dp))
   1432		return BIT(dsa_switch_upstream_port(ds));
   1433
   1434	/* Frames from bridged user ports can egress any local DSA
   1435	 * links and CPU ports, as well as any local member of their
   1436	 * bridge group.
   1437	 */
   1438	dsa_switch_for_each_port(other_dp, ds)
   1439		if (other_dp->type == DSA_PORT_TYPE_CPU ||
   1440		    other_dp->type == DSA_PORT_TYPE_DSA ||
   1441		    dsa_port_bridge_same(dp, other_dp))
   1442			pvlan |= BIT(other_dp->index);
   1443
   1444	return pvlan;
   1445}
   1446
   1447static int mv88e6xxx_port_vlan_map(struct mv88e6xxx_chip *chip, int port)
   1448{
   1449	u16 output_ports = mv88e6xxx_port_vlan(chip, chip->ds->index, port);
   1450
   1451	/* prevent frames from going back out of the port they came in on */
   1452	output_ports &= ~BIT(port);
   1453
   1454	return mv88e6xxx_port_set_vlan_map(chip, port, output_ports);
   1455}
   1456
   1457static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
   1458					 u8 state)
   1459{
   1460	struct mv88e6xxx_chip *chip = ds->priv;
   1461	int err;
   1462
   1463	mv88e6xxx_reg_lock(chip);
   1464	err = mv88e6xxx_port_set_state(chip, port, state);
   1465	mv88e6xxx_reg_unlock(chip);
   1466
   1467	if (err)
   1468		dev_err(ds->dev, "p%d: failed to update state\n", port);
   1469}
   1470
   1471static int mv88e6xxx_pri_setup(struct mv88e6xxx_chip *chip)
   1472{
   1473	int err;
   1474
   1475	if (chip->info->ops->ieee_pri_map) {
   1476		err = chip->info->ops->ieee_pri_map(chip);
   1477		if (err)
   1478			return err;
   1479	}
   1480
   1481	if (chip->info->ops->ip_pri_map) {
   1482		err = chip->info->ops->ip_pri_map(chip);
   1483		if (err)
   1484			return err;
   1485	}
   1486
   1487	return 0;
   1488}
   1489
   1490static int mv88e6xxx_devmap_setup(struct mv88e6xxx_chip *chip)
   1491{
   1492	struct dsa_switch *ds = chip->ds;
   1493	int target, port;
   1494	int err;
   1495
   1496	if (!chip->info->global2_addr)
   1497		return 0;
   1498
   1499	/* Initialize the routing port to the 32 possible target devices */
   1500	for (target = 0; target < 32; target++) {
   1501		port = dsa_routing_port(ds, target);
   1502		if (port == ds->num_ports)
   1503			port = 0x1f;
   1504
   1505		err = mv88e6xxx_g2_device_mapping_write(chip, target, port);
   1506		if (err)
   1507			return err;
   1508	}
   1509
   1510	if (chip->info->ops->set_cascade_port) {
   1511		port = MV88E6XXX_CASCADE_PORT_MULTIPLE;
   1512		err = chip->info->ops->set_cascade_port(chip, port);
   1513		if (err)
   1514			return err;
   1515	}
   1516
   1517	err = mv88e6xxx_g1_set_device_number(chip, chip->ds->index);
   1518	if (err)
   1519		return err;
   1520
   1521	return 0;
   1522}
   1523
   1524static int mv88e6xxx_trunk_setup(struct mv88e6xxx_chip *chip)
   1525{
   1526	/* Clear all trunk masks and mapping */
   1527	if (chip->info->global2_addr)
   1528		return mv88e6xxx_g2_trunk_clear(chip);
   1529
   1530	return 0;
   1531}
   1532
   1533static int mv88e6xxx_rmu_setup(struct mv88e6xxx_chip *chip)
   1534{
   1535	if (chip->info->ops->rmu_disable)
   1536		return chip->info->ops->rmu_disable(chip);
   1537
   1538	return 0;
   1539}
   1540
   1541static int mv88e6xxx_pot_setup(struct mv88e6xxx_chip *chip)
   1542{
   1543	if (chip->info->ops->pot_clear)
   1544		return chip->info->ops->pot_clear(chip);
   1545
   1546	return 0;
   1547}
   1548
   1549static int mv88e6xxx_rsvd2cpu_setup(struct mv88e6xxx_chip *chip)
   1550{
   1551	if (chip->info->ops->mgmt_rsvd2cpu)
   1552		return chip->info->ops->mgmt_rsvd2cpu(chip);
   1553
   1554	return 0;
   1555}
   1556
   1557static int mv88e6xxx_atu_setup(struct mv88e6xxx_chip *chip)
   1558{
   1559	int err;
   1560
   1561	err = mv88e6xxx_g1_atu_flush(chip, 0, true);
   1562	if (err)
   1563		return err;
   1564
   1565	/* The chips that have a "learn2all" bit in Global1, ATU
   1566	 * Control are precisely those whose port registers have a
   1567	 * Message Port bit in Port Control 1 and hence implement
   1568	 * ->port_setup_message_port.
   1569	 */
   1570	if (chip->info->ops->port_setup_message_port) {
   1571		err = mv88e6xxx_g1_atu_set_learn2all(chip, true);
   1572		if (err)
   1573			return err;
   1574	}
   1575
   1576	return mv88e6xxx_g1_atu_set_age_time(chip, 300000);
   1577}
   1578
   1579static int mv88e6xxx_irl_setup(struct mv88e6xxx_chip *chip)
   1580{
   1581	int port;
   1582	int err;
   1583
   1584	if (!chip->info->ops->irl_init_all)
   1585		return 0;
   1586
   1587	for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
   1588		/* Disable ingress rate limiting by resetting all per port
   1589		 * ingress rate limit resources to their initial state.
   1590		 */
   1591		err = chip->info->ops->irl_init_all(chip, port);
   1592		if (err)
   1593			return err;
   1594	}
   1595
   1596	return 0;
   1597}
   1598
   1599static int mv88e6xxx_mac_setup(struct mv88e6xxx_chip *chip)
   1600{
   1601	if (chip->info->ops->set_switch_mac) {
   1602		u8 addr[ETH_ALEN];
   1603
   1604		eth_random_addr(addr);
   1605
   1606		return chip->info->ops->set_switch_mac(chip, addr);
   1607	}
   1608
   1609	return 0;
   1610}
   1611
   1612static int mv88e6xxx_pvt_map(struct mv88e6xxx_chip *chip, int dev, int port)
   1613{
   1614	struct dsa_switch_tree *dst = chip->ds->dst;
   1615	struct dsa_switch *ds;
   1616	struct dsa_port *dp;
   1617	u16 pvlan = 0;
   1618
   1619	if (!mv88e6xxx_has_pvt(chip))
   1620		return 0;
   1621
   1622	/* Skip the local source device, which uses in-chip port VLAN */
   1623	if (dev != chip->ds->index) {
   1624		pvlan = mv88e6xxx_port_vlan(chip, dev, port);
   1625
   1626		ds = dsa_switch_find(dst->index, dev);
   1627		dp = ds ? dsa_to_port(ds, port) : NULL;
   1628		if (dp && dp->lag) {
   1629			/* As the PVT is used to limit flooding of
   1630			 * FORWARD frames, which use the LAG ID as the
   1631			 * source port, we must translate dev/port to
   1632			 * the special "LAG device" in the PVT, using
   1633			 * the LAG ID (one-based) as the port number
   1634			 * (zero-based).
   1635			 */
   1636			dev = MV88E6XXX_G2_PVT_ADDR_DEV_TRUNK;
   1637			port = dsa_port_lag_id_get(dp) - 1;
   1638		}
   1639	}
   1640
   1641	return mv88e6xxx_g2_pvt_write(chip, dev, port, pvlan);
   1642}
   1643
   1644static int mv88e6xxx_pvt_setup(struct mv88e6xxx_chip *chip)
   1645{
   1646	int dev, port;
   1647	int err;
   1648
   1649	if (!mv88e6xxx_has_pvt(chip))
   1650		return 0;
   1651
   1652	/* Clear 5 Bit Port for usage with Marvell Link Street devices:
   1653	 * use 4 bits for the Src_Port/Src_Trunk and 5 bits for the Src_Dev.
   1654	 */
   1655	err = mv88e6xxx_g2_misc_4_bit_port(chip);
   1656	if (err)
   1657		return err;
   1658
   1659	for (dev = 0; dev < MV88E6XXX_MAX_PVT_SWITCHES; ++dev) {
   1660		for (port = 0; port < MV88E6XXX_MAX_PVT_PORTS; ++port) {
   1661			err = mv88e6xxx_pvt_map(chip, dev, port);
   1662			if (err)
   1663				return err;
   1664		}
   1665	}
   1666
   1667	return 0;
   1668}
   1669
   1670static int mv88e6xxx_port_fast_age_fid(struct mv88e6xxx_chip *chip, int port,
   1671				       u16 fid)
   1672{
   1673	if (dsa_to_port(chip->ds, port)->lag)
   1674		/* Hardware is incapable of fast-aging a LAG through a
   1675		 * regular ATU move operation. Until we have something
   1676		 * more fancy in place this is a no-op.
   1677		 */
   1678		return -EOPNOTSUPP;
   1679
   1680	return mv88e6xxx_g1_atu_remove(chip, fid, port, false);
   1681}
   1682
   1683static void mv88e6xxx_port_fast_age(struct dsa_switch *ds, int port)
   1684{
   1685	struct mv88e6xxx_chip *chip = ds->priv;
   1686	int err;
   1687
   1688	mv88e6xxx_reg_lock(chip);
   1689	err = mv88e6xxx_port_fast_age_fid(chip, port, 0);
   1690	mv88e6xxx_reg_unlock(chip);
   1691
   1692	if (err)
   1693		dev_err(chip->ds->dev, "p%d: failed to flush ATU: %d\n",
   1694			port, err);
   1695}
   1696
   1697static int mv88e6xxx_vtu_setup(struct mv88e6xxx_chip *chip)
   1698{
   1699	if (!mv88e6xxx_max_vid(chip))
   1700		return 0;
   1701
   1702	return mv88e6xxx_g1_vtu_flush(chip);
   1703}
   1704
   1705static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
   1706			     struct mv88e6xxx_vtu_entry *entry)
   1707{
   1708	int err;
   1709
   1710	if (!chip->info->ops->vtu_getnext)
   1711		return -EOPNOTSUPP;
   1712
   1713	entry->vid = vid ? vid - 1 : mv88e6xxx_max_vid(chip);
   1714	entry->valid = false;
   1715
   1716	err = chip->info->ops->vtu_getnext(chip, entry);
   1717
   1718	if (entry->vid != vid)
   1719		entry->valid = false;
   1720
   1721	return err;
   1722}
   1723
   1724static int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
   1725			      int (*cb)(struct mv88e6xxx_chip *chip,
   1726					const struct mv88e6xxx_vtu_entry *entry,
   1727					void *priv),
   1728			      void *priv)
   1729{
   1730	struct mv88e6xxx_vtu_entry entry = {
   1731		.vid = mv88e6xxx_max_vid(chip),
   1732		.valid = false,
   1733	};
   1734	int err;
   1735
   1736	if (!chip->info->ops->vtu_getnext)
   1737		return -EOPNOTSUPP;
   1738
   1739	do {
   1740		err = chip->info->ops->vtu_getnext(chip, &entry);
   1741		if (err)
   1742			return err;
   1743
   1744		if (!entry.valid)
   1745			break;
   1746
   1747		err = cb(chip, &entry, priv);
   1748		if (err)
   1749			return err;
   1750	} while (entry.vid < mv88e6xxx_max_vid(chip));
   1751
   1752	return 0;
   1753}
   1754
   1755static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
   1756				   struct mv88e6xxx_vtu_entry *entry)
   1757{
   1758	if (!chip->info->ops->vtu_loadpurge)
   1759		return -EOPNOTSUPP;
   1760
   1761	return chip->info->ops->vtu_loadpurge(chip, entry);
   1762}
   1763
   1764static int mv88e6xxx_fid_map_vlan(struct mv88e6xxx_chip *chip,
   1765				  const struct mv88e6xxx_vtu_entry *entry,
   1766				  void *_fid_bitmap)
   1767{
   1768	unsigned long *fid_bitmap = _fid_bitmap;
   1769
   1770	set_bit(entry->fid, fid_bitmap);
   1771	return 0;
   1772}
   1773
   1774int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *fid_bitmap)
   1775{
   1776	bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);
   1777
   1778	/* Every FID has an associated VID, so walking the VTU
   1779	 * will discover the full set of FIDs in use.
   1780	 */
   1781	return mv88e6xxx_vtu_walk(chip, mv88e6xxx_fid_map_vlan, fid_bitmap);
   1782}
   1783
   1784static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
   1785{
   1786	DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID);
   1787	int err;
   1788
   1789	err = mv88e6xxx_fid_map(chip, fid_bitmap);
   1790	if (err)
   1791		return err;
   1792
   1793	*fid = find_first_zero_bit(fid_bitmap, MV88E6XXX_N_FID);
   1794	if (unlikely(*fid >= mv88e6xxx_num_databases(chip)))
   1795		return -ENOSPC;
   1796
   1797	/* Clear the database */
   1798	return mv88e6xxx_g1_atu_flush(chip, *fid, true);
   1799}
   1800
   1801static int mv88e6xxx_stu_loadpurge(struct mv88e6xxx_chip *chip,
   1802				   struct mv88e6xxx_stu_entry *entry)
   1803{
   1804	if (!chip->info->ops->stu_loadpurge)
   1805		return -EOPNOTSUPP;
   1806
   1807	return chip->info->ops->stu_loadpurge(chip, entry);
   1808}
   1809
   1810static int mv88e6xxx_stu_setup(struct mv88e6xxx_chip *chip)
   1811{
   1812	struct mv88e6xxx_stu_entry stu = {
   1813		.valid = true,
   1814		.sid = 0
   1815	};
   1816
   1817	if (!mv88e6xxx_has_stu(chip))
   1818		return 0;
   1819
   1820	/* Make sure that SID 0 is always valid. This is used by VTU
   1821	 * entries that do not make use of the STU, e.g. when creating
   1822	 * a VLAN upper on a port that is also part of a VLAN
   1823	 * filtering bridge.
   1824	 */
   1825	return mv88e6xxx_stu_loadpurge(chip, &stu);
   1826}
   1827
   1828static int mv88e6xxx_sid_get(struct mv88e6xxx_chip *chip, u8 *sid)
   1829{
   1830	DECLARE_BITMAP(busy, MV88E6XXX_N_SID) = { 0 };
   1831	struct mv88e6xxx_mst *mst;
   1832
   1833	__set_bit(0, busy);
   1834
   1835	list_for_each_entry(mst, &chip->msts, node)
   1836		__set_bit(mst->stu.sid, busy);
   1837
   1838	*sid = find_first_zero_bit(busy, MV88E6XXX_N_SID);
   1839
   1840	return (*sid >= mv88e6xxx_max_sid(chip)) ? -ENOSPC : 0;
   1841}
   1842
   1843static int mv88e6xxx_mst_put(struct mv88e6xxx_chip *chip, u8 sid)
   1844{
   1845	struct mv88e6xxx_mst *mst, *tmp;
   1846	int err;
   1847
   1848	if (!sid)
   1849		return 0;
   1850
   1851	list_for_each_entry_safe(mst, tmp, &chip->msts, node) {
   1852		if (mst->stu.sid != sid)
   1853			continue;
   1854
   1855		if (!refcount_dec_and_test(&mst->refcnt))
   1856			return 0;
   1857
   1858		mst->stu.valid = false;
   1859		err = mv88e6xxx_stu_loadpurge(chip, &mst->stu);
   1860		if (err) {
   1861			refcount_set(&mst->refcnt, 1);
   1862			return err;
   1863		}
   1864
   1865		list_del(&mst->node);
   1866		kfree(mst);
   1867		return 0;
   1868	}
   1869
   1870	return -ENOENT;
   1871}
   1872
   1873static int mv88e6xxx_mst_get(struct mv88e6xxx_chip *chip, struct net_device *br,
   1874			     u16 msti, u8 *sid)
   1875{
   1876	struct mv88e6xxx_mst *mst;
   1877	int err, i;
   1878
   1879	if (!mv88e6xxx_has_stu(chip)) {
   1880		err = -EOPNOTSUPP;
   1881		goto err;
   1882	}
   1883
   1884	if (!msti) {
   1885		*sid = 0;
   1886		return 0;
   1887	}
   1888
   1889	list_for_each_entry(mst, &chip->msts, node) {
   1890		if (mst->br == br && mst->msti == msti) {
   1891			refcount_inc(&mst->refcnt);
   1892			*sid = mst->stu.sid;
   1893			return 0;
   1894		}
   1895	}
   1896
   1897	err = mv88e6xxx_sid_get(chip, sid);
   1898	if (err)
   1899		goto err;
   1900
   1901	mst = kzalloc(sizeof(*mst), GFP_KERNEL);
   1902	if (!mst) {
   1903		err = -ENOMEM;
   1904		goto err;
   1905	}
   1906
   1907	INIT_LIST_HEAD(&mst->node);
   1908	refcount_set(&mst->refcnt, 1);
   1909	mst->br = br;
   1910	mst->msti = msti;
   1911	mst->stu.valid = true;
   1912	mst->stu.sid = *sid;
   1913
   1914	/* The bridge starts out all ports in the disabled state. But
   1915	 * a STU state of disabled means to go by the port-global
   1916	 * state. So we set all user port's initial state to blocking,
   1917	 * to match the bridge's behavior.
   1918	 */
   1919	for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
   1920		mst->stu.state[i] = dsa_is_user_port(chip->ds, i) ?
   1921			MV88E6XXX_PORT_CTL0_STATE_BLOCKING :
   1922			MV88E6XXX_PORT_CTL0_STATE_DISABLED;
   1923
   1924	err = mv88e6xxx_stu_loadpurge(chip, &mst->stu);
   1925	if (err)
   1926		goto err_free;
   1927
   1928	list_add_tail(&mst->node, &chip->msts);
   1929	return 0;
   1930
   1931err_free:
   1932	kfree(mst);
   1933err:
   1934	return err;
   1935}
   1936
   1937static int mv88e6xxx_port_mst_state_set(struct dsa_switch *ds, int port,
   1938					const struct switchdev_mst_state *st)
   1939{
   1940	struct dsa_port *dp = dsa_to_port(ds, port);
   1941	struct mv88e6xxx_chip *chip = ds->priv;
   1942	struct mv88e6xxx_mst *mst;
   1943	u8 state;
   1944	int err;
   1945
   1946	if (!mv88e6xxx_has_stu(chip))
   1947		return -EOPNOTSUPP;
   1948
   1949	switch (st->state) {
   1950	case BR_STATE_DISABLED:
   1951	case BR_STATE_BLOCKING:
   1952	case BR_STATE_LISTENING:
   1953		state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
   1954		break;
   1955	case BR_STATE_LEARNING:
   1956		state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
   1957		break;
   1958	case BR_STATE_FORWARDING:
   1959		state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
   1960		break;
   1961	default:
   1962		return -EINVAL;
   1963	}
   1964
   1965	list_for_each_entry(mst, &chip->msts, node) {
   1966		if (mst->br == dsa_port_bridge_dev_get(dp) &&
   1967		    mst->msti == st->msti) {
   1968			if (mst->stu.state[port] == state)
   1969				return 0;
   1970
   1971			mst->stu.state[port] = state;
   1972			mv88e6xxx_reg_lock(chip);
   1973			err = mv88e6xxx_stu_loadpurge(chip, &mst->stu);
   1974			mv88e6xxx_reg_unlock(chip);
   1975			return err;
   1976		}
   1977	}
   1978
   1979	return -ENOENT;
   1980}
   1981
   1982static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
   1983					u16 vid)
   1984{
   1985	struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
   1986	struct mv88e6xxx_chip *chip = ds->priv;
   1987	struct mv88e6xxx_vtu_entry vlan;
   1988	int err;
   1989
   1990	/* DSA and CPU ports have to be members of multiple vlans */
   1991	if (dsa_port_is_dsa(dp) || dsa_port_is_cpu(dp))
   1992		return 0;
   1993
   1994	err = mv88e6xxx_vtu_get(chip, vid, &vlan);
   1995	if (err)
   1996		return err;
   1997
   1998	if (!vlan.valid)
   1999		return 0;
   2000
   2001	dsa_switch_for_each_user_port(other_dp, ds) {
   2002		struct net_device *other_br;
   2003
   2004		if (vlan.member[other_dp->index] ==
   2005		    MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
   2006			continue;
   2007
   2008		if (dsa_port_bridge_same(dp, other_dp))
   2009			break; /* same bridge, check next VLAN */
   2010
   2011		other_br = dsa_port_bridge_dev_get(other_dp);
   2012		if (!other_br)
   2013			continue;
   2014
   2015		dev_err(ds->dev, "p%d: hw VLAN %d already used by port %d in %s\n",
   2016			port, vlan.vid, other_dp->index, netdev_name(other_br));
   2017		return -EOPNOTSUPP;
   2018	}
   2019
   2020	return 0;
   2021}
   2022
   2023static int mv88e6xxx_port_commit_pvid(struct mv88e6xxx_chip *chip, int port)
   2024{
   2025	struct dsa_port *dp = dsa_to_port(chip->ds, port);
   2026	struct net_device *br = dsa_port_bridge_dev_get(dp);
   2027	struct mv88e6xxx_port *p = &chip->ports[port];
   2028	u16 pvid = MV88E6XXX_VID_STANDALONE;
   2029	bool drop_untagged = false;
   2030	int err;
   2031
   2032	if (br) {
   2033		if (br_vlan_enabled(br)) {
   2034			pvid = p->bridge_pvid.vid;
   2035			drop_untagged = !p->bridge_pvid.valid;
   2036		} else {
   2037			pvid = MV88E6XXX_VID_BRIDGED;
   2038		}
   2039	}
   2040
   2041	err = mv88e6xxx_port_set_pvid(chip, port, pvid);
   2042	if (err)
   2043		return err;
   2044
   2045	return mv88e6xxx_port_drop_untagged(chip, port, drop_untagged);
   2046}
   2047
   2048static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
   2049					 bool vlan_filtering,
   2050					 struct netlink_ext_ack *extack)
   2051{
   2052	struct mv88e6xxx_chip *chip = ds->priv;
   2053	u16 mode = vlan_filtering ? MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE :
   2054		MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED;
   2055	int err;
   2056
   2057	if (!mv88e6xxx_max_vid(chip))
   2058		return -EOPNOTSUPP;
   2059
   2060	mv88e6xxx_reg_lock(chip);
   2061
   2062	err = mv88e6xxx_port_set_8021q_mode(chip, port, mode);
   2063	if (err)
   2064		goto unlock;
   2065
   2066	err = mv88e6xxx_port_commit_pvid(chip, port);
   2067	if (err)
   2068		goto unlock;
   2069
   2070unlock:
   2071	mv88e6xxx_reg_unlock(chip);
   2072
   2073	return err;
   2074}
   2075
   2076static int
   2077mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
   2078			    const struct switchdev_obj_port_vlan *vlan)
   2079{
   2080	struct mv88e6xxx_chip *chip = ds->priv;
   2081	int err;
   2082
   2083	if (!mv88e6xxx_max_vid(chip))
   2084		return -EOPNOTSUPP;
   2085
   2086	/* If the requested port doesn't belong to the same bridge as the VLAN
   2087	 * members, do not support it (yet) and fallback to software VLAN.
   2088	 */
   2089	mv88e6xxx_reg_lock(chip);
   2090	err = mv88e6xxx_port_check_hw_vlan(ds, port, vlan->vid);
   2091	mv88e6xxx_reg_unlock(chip);
   2092
   2093	return err;
   2094}
   2095
   2096static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
   2097					const unsigned char *addr, u16 vid,
   2098					u8 state)
   2099{
   2100	struct mv88e6xxx_atu_entry entry;
   2101	struct mv88e6xxx_vtu_entry vlan;
   2102	u16 fid;
   2103	int err;
   2104
   2105	/* Ports have two private address databases: one for when the port is
   2106	 * standalone and one for when the port is under a bridge and the
   2107	 * 802.1Q mode is disabled. When the port is standalone, DSA wants its
   2108	 * address database to remain 100% empty, so we never load an ATU entry
   2109	 * into a standalone port's database. Therefore, translate the null
   2110	 * VLAN ID into the port's database used for VLAN-unaware bridging.
   2111	 */
   2112	if (vid == 0) {
   2113		fid = MV88E6XXX_FID_BRIDGED;
   2114	} else {
   2115		err = mv88e6xxx_vtu_get(chip, vid, &vlan);
   2116		if (err)
   2117			return err;
   2118
   2119		/* switchdev expects -EOPNOTSUPP to honor software VLANs */
   2120		if (!vlan.valid)
   2121			return -EOPNOTSUPP;
   2122
   2123		fid = vlan.fid;
   2124	}
   2125
   2126	entry.state = 0;
   2127	ether_addr_copy(entry.mac, addr);
   2128	eth_addr_dec(entry.mac);
   2129
   2130	err = mv88e6xxx_g1_atu_getnext(chip, fid, &entry);
   2131	if (err)
   2132		return err;
   2133
   2134	/* Initialize a fresh ATU entry if it isn't found */
   2135	if (!entry.state || !ether_addr_equal(entry.mac, addr)) {
   2136		memset(&entry, 0, sizeof(entry));
   2137		ether_addr_copy(entry.mac, addr);
   2138	}
   2139
   2140	/* Purge the ATU entry only if no port is using it anymore */
   2141	if (!state) {
   2142		entry.portvec &= ~BIT(port);
   2143		if (!entry.portvec)
   2144			entry.state = 0;
   2145	} else {
   2146		if (state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC)
   2147			entry.portvec = BIT(port);
   2148		else
   2149			entry.portvec |= BIT(port);
   2150
   2151		entry.state = state;
   2152	}
   2153
   2154	return mv88e6xxx_g1_atu_loadpurge(chip, fid, &entry);
   2155}
   2156
   2157static int mv88e6xxx_policy_apply(struct mv88e6xxx_chip *chip, int port,
   2158				  const struct mv88e6xxx_policy *policy)
   2159{
   2160	enum mv88e6xxx_policy_mapping mapping = policy->mapping;
   2161	enum mv88e6xxx_policy_action action = policy->action;
   2162	const u8 *addr = policy->addr;
   2163	u16 vid = policy->vid;
   2164	u8 state;
   2165	int err;
   2166	int id;
   2167
   2168	if (!chip->info->ops->port_set_policy)
   2169		return -EOPNOTSUPP;
   2170
   2171	switch (mapping) {
   2172	case MV88E6XXX_POLICY_MAPPING_DA:
   2173	case MV88E6XXX_POLICY_MAPPING_SA:
   2174		if (action == MV88E6XXX_POLICY_ACTION_NORMAL)
   2175			state = 0; /* Dissociate the port and address */
   2176		else if (action == MV88E6XXX_POLICY_ACTION_DISCARD &&
   2177			 is_multicast_ether_addr(addr))
   2178			state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_POLICY;
   2179		else if (action == MV88E6XXX_POLICY_ACTION_DISCARD &&
   2180			 is_unicast_ether_addr(addr))
   2181			state = MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_POLICY;
   2182		else
   2183			return -EOPNOTSUPP;
   2184
   2185		err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
   2186						   state);
   2187		if (err)
   2188			return err;
   2189		break;
   2190	default:
   2191		return -EOPNOTSUPP;
   2192	}
   2193
   2194	/* Skip the port's policy clearing if the mapping is still in use */
   2195	if (action == MV88E6XXX_POLICY_ACTION_NORMAL)
   2196		idr_for_each_entry(&chip->policies, policy, id)
   2197			if (policy->port == port &&
   2198			    policy->mapping == mapping &&
   2199			    policy->action != action)
   2200				return 0;
   2201
   2202	return chip->info->ops->port_set_policy(chip, port, mapping, action);
   2203}
   2204
   2205static int mv88e6xxx_policy_insert(struct mv88e6xxx_chip *chip, int port,
   2206				   struct ethtool_rx_flow_spec *fs)
   2207{
   2208	struct ethhdr *mac_entry = &fs->h_u.ether_spec;
   2209	struct ethhdr *mac_mask = &fs->m_u.ether_spec;
   2210	enum mv88e6xxx_policy_mapping mapping;
   2211	enum mv88e6xxx_policy_action action;
   2212	struct mv88e6xxx_policy *policy;
   2213	u16 vid = 0;
   2214	u8 *addr;
   2215	int err;
   2216	int id;
   2217
   2218	if (fs->location != RX_CLS_LOC_ANY)
   2219		return -EINVAL;
   2220
   2221	if (fs->ring_cookie == RX_CLS_FLOW_DISC)
   2222		action = MV88E6XXX_POLICY_ACTION_DISCARD;
   2223	else
   2224		return -EOPNOTSUPP;
   2225
   2226	switch (fs->flow_type & ~FLOW_EXT) {
   2227	case ETHER_FLOW:
   2228		if (!is_zero_ether_addr(mac_mask->h_dest) &&
   2229		    is_zero_ether_addr(mac_mask->h_source)) {
   2230			mapping = MV88E6XXX_POLICY_MAPPING_DA;
   2231			addr = mac_entry->h_dest;
   2232		} else if (is_zero_ether_addr(mac_mask->h_dest) &&
   2233		    !is_zero_ether_addr(mac_mask->h_source)) {
   2234			mapping = MV88E6XXX_POLICY_MAPPING_SA;
   2235			addr = mac_entry->h_source;
   2236		} else {
   2237			/* Cannot support DA and SA mapping in the same rule */
   2238			return -EOPNOTSUPP;
   2239		}
   2240		break;
   2241	default:
   2242		return -EOPNOTSUPP;
   2243	}
   2244
   2245	if ((fs->flow_type & FLOW_EXT) && fs->m_ext.vlan_tci) {
   2246		if (fs->m_ext.vlan_tci != htons(0xffff))
   2247			return -EOPNOTSUPP;
   2248		vid = be16_to_cpu(fs->h_ext.vlan_tci) & VLAN_VID_MASK;
   2249	}
   2250
   2251	idr_for_each_entry(&chip->policies, policy, id) {
   2252		if (policy->port == port && policy->mapping == mapping &&
   2253		    policy->action == action && policy->vid == vid &&
   2254		    ether_addr_equal(policy->addr, addr))
   2255			return -EEXIST;
   2256	}
   2257
   2258	policy = devm_kzalloc(chip->dev, sizeof(*policy), GFP_KERNEL);
   2259	if (!policy)
   2260		return -ENOMEM;
   2261
   2262	fs->location = 0;
   2263	err = idr_alloc_u32(&chip->policies, policy, &fs->location, 0xffffffff,
   2264			    GFP_KERNEL);
   2265	if (err) {
   2266		devm_kfree(chip->dev, policy);
   2267		return err;
   2268	}
   2269
   2270	memcpy(&policy->fs, fs, sizeof(*fs));
   2271	ether_addr_copy(policy->addr, addr);
   2272	policy->mapping = mapping;
   2273	policy->action = action;
   2274	policy->port = port;
   2275	policy->vid = vid;
   2276
   2277	err = mv88e6xxx_policy_apply(chip, port, policy);
   2278	if (err) {
   2279		idr_remove(&chip->policies, fs->location);
   2280		devm_kfree(chip->dev, policy);
   2281		return err;
   2282	}
   2283
   2284	return 0;
   2285}
   2286
   2287static int mv88e6xxx_get_rxnfc(struct dsa_switch *ds, int port,
   2288			       struct ethtool_rxnfc *rxnfc, u32 *rule_locs)
   2289{
   2290	struct ethtool_rx_flow_spec *fs = &rxnfc->fs;
   2291	struct mv88e6xxx_chip *chip = ds->priv;
   2292	struct mv88e6xxx_policy *policy;
   2293	int err;
   2294	int id;
   2295
   2296	mv88e6xxx_reg_lock(chip);
   2297
   2298	switch (rxnfc->cmd) {
   2299	case ETHTOOL_GRXCLSRLCNT:
   2300		rxnfc->data = 0;
   2301		rxnfc->data |= RX_CLS_LOC_SPECIAL;
   2302		rxnfc->rule_cnt = 0;
   2303		idr_for_each_entry(&chip->policies, policy, id)
   2304			if (policy->port == port)
   2305				rxnfc->rule_cnt++;
   2306		err = 0;
   2307		break;
   2308	case ETHTOOL_GRXCLSRULE:
   2309		err = -ENOENT;
   2310		policy = idr_find(&chip->policies, fs->location);
   2311		if (policy) {
   2312			memcpy(fs, &policy->fs, sizeof(*fs));
   2313			err = 0;
   2314		}
   2315		break;
   2316	case ETHTOOL_GRXCLSRLALL:
   2317		rxnfc->data = 0;
   2318		rxnfc->rule_cnt = 0;
   2319		idr_for_each_entry(&chip->policies, policy, id)
   2320			if (policy->port == port)
   2321				rule_locs[rxnfc->rule_cnt++] = id;
   2322		err = 0;
   2323		break;
   2324	default:
   2325		err = -EOPNOTSUPP;
   2326		break;
   2327	}
   2328
   2329	mv88e6xxx_reg_unlock(chip);
   2330
   2331	return err;
   2332}
   2333
   2334static int mv88e6xxx_set_rxnfc(struct dsa_switch *ds, int port,
   2335			       struct ethtool_rxnfc *rxnfc)
   2336{
   2337	struct ethtool_rx_flow_spec *fs = &rxnfc->fs;
   2338	struct mv88e6xxx_chip *chip = ds->priv;
   2339	struct mv88e6xxx_policy *policy;
   2340	int err;
   2341
   2342	mv88e6xxx_reg_lock(chip);
   2343
   2344	switch (rxnfc->cmd) {
   2345	case ETHTOOL_SRXCLSRLINS:
   2346		err = mv88e6xxx_policy_insert(chip, port, fs);
   2347		break;
   2348	case ETHTOOL_SRXCLSRLDEL:
   2349		err = -ENOENT;
   2350		policy = idr_remove(&chip->policies, fs->location);
   2351		if (policy) {
   2352			policy->action = MV88E6XXX_POLICY_ACTION_NORMAL;
   2353			err = mv88e6xxx_policy_apply(chip, port, policy);
   2354			devm_kfree(chip->dev, policy);
   2355		}
   2356		break;
   2357	default:
   2358		err = -EOPNOTSUPP;
   2359		break;
   2360	}
   2361
   2362	mv88e6xxx_reg_unlock(chip);
   2363
   2364	return err;
   2365}
   2366
   2367static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port,
   2368					u16 vid)
   2369{
   2370	u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC;
   2371	u8 broadcast[ETH_ALEN];
   2372
   2373	eth_broadcast_addr(broadcast);
   2374
   2375	return mv88e6xxx_port_db_load_purge(chip, port, broadcast, vid, state);
   2376}
   2377
   2378static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid)
   2379{
   2380	int port;
   2381	int err;
   2382
   2383	for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
   2384		struct dsa_port *dp = dsa_to_port(chip->ds, port);
   2385		struct net_device *brport;
   2386
   2387		if (dsa_is_unused_port(chip->ds, port))
   2388			continue;
   2389
   2390		brport = dsa_port_to_bridge_port(dp);
   2391		if (brport && !br_port_flag_is_set(brport, BR_BCAST_FLOOD))
   2392			/* Skip bridged user ports where broadcast
   2393			 * flooding is disabled.
   2394			 */
   2395			continue;
   2396
   2397		err = mv88e6xxx_port_add_broadcast(chip, port, vid);
   2398		if (err)
   2399			return err;
   2400	}
   2401
   2402	return 0;
   2403}
   2404
   2405struct mv88e6xxx_port_broadcast_sync_ctx {
   2406	int port;
   2407	bool flood;
   2408};
   2409
   2410static int
   2411mv88e6xxx_port_broadcast_sync_vlan(struct mv88e6xxx_chip *chip,
   2412				   const struct mv88e6xxx_vtu_entry *vlan,
   2413				   void *_ctx)
   2414{
   2415	struct mv88e6xxx_port_broadcast_sync_ctx *ctx = _ctx;
   2416	u8 broadcast[ETH_ALEN];
   2417	u8 state;
   2418
   2419	if (ctx->flood)
   2420		state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC;
   2421	else
   2422		state = MV88E6XXX_G1_ATU_DATA_STATE_MC_UNUSED;
   2423
   2424	eth_broadcast_addr(broadcast);
   2425
   2426	return mv88e6xxx_port_db_load_purge(chip, ctx->port, broadcast,
   2427					    vlan->vid, state);
   2428}
   2429
   2430static int mv88e6xxx_port_broadcast_sync(struct mv88e6xxx_chip *chip, int port,
   2431					 bool flood)
   2432{
   2433	struct mv88e6xxx_port_broadcast_sync_ctx ctx = {
   2434		.port = port,
   2435		.flood = flood,
   2436	};
   2437	struct mv88e6xxx_vtu_entry vid0 = {
   2438		.vid = 0,
   2439	};
   2440	int err;
   2441
   2442	/* Update the port's private database... */
   2443	err = mv88e6xxx_port_broadcast_sync_vlan(chip, &vid0, &ctx);
   2444	if (err)
   2445		return err;
   2446
   2447	/* ...and the database for all VLANs. */
   2448	return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_broadcast_sync_vlan,
   2449				  &ctx);
   2450}
   2451
   2452static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port,
   2453				    u16 vid, u8 member, bool warn)
   2454{
   2455	const u8 non_member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
   2456	struct mv88e6xxx_vtu_entry vlan;
   2457	int i, err;
   2458
   2459	err = mv88e6xxx_vtu_get(chip, vid, &vlan);
   2460	if (err)
   2461		return err;
   2462
   2463	if (!vlan.valid) {
   2464		memset(&vlan, 0, sizeof(vlan));
   2465
   2466		if (vid == MV88E6XXX_VID_STANDALONE)
   2467			vlan.policy = true;
   2468
   2469		err = mv88e6xxx_atu_new(chip, &vlan.fid);
   2470		if (err)
   2471			return err;
   2472
   2473		for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
   2474			if (i == port)
   2475				vlan.member[i] = member;
   2476			else
   2477				vlan.member[i] = non_member;
   2478
   2479		vlan.vid = vid;
   2480		vlan.valid = true;
   2481
   2482		err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
   2483		if (err)
   2484			return err;
   2485
   2486		err = mv88e6xxx_broadcast_setup(chip, vlan.vid);
   2487		if (err)
   2488			return err;
   2489	} else if (vlan.member[port] != member) {
   2490		vlan.member[port] = member;
   2491
   2492		err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
   2493		if (err)
   2494			return err;
   2495	} else if (warn) {
   2496		dev_info(chip->dev, "p%d: already a member of VLAN %d\n",
   2497			 port, vid);
   2498	}
   2499
   2500	return 0;
   2501}
   2502
   2503static int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
   2504				   const struct switchdev_obj_port_vlan *vlan,
   2505				   struct netlink_ext_ack *extack)
   2506{
   2507	struct mv88e6xxx_chip *chip = ds->priv;
   2508	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
   2509	bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
   2510	struct mv88e6xxx_port *p = &chip->ports[port];
   2511	bool warn;
   2512	u8 member;
   2513	int err;
   2514
   2515	if (!vlan->vid)
   2516		return 0;
   2517
   2518	err = mv88e6xxx_port_vlan_prepare(ds, port, vlan);
   2519	if (err)
   2520		return err;
   2521
   2522	if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
   2523		member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED;
   2524	else if (untagged)
   2525		member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNTAGGED;
   2526	else
   2527		member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_TAGGED;
   2528
   2529	/* net/dsa/slave.c will call dsa_port_vlan_add() for the affected port
   2530	 * and then the CPU port. Do not warn for duplicates for the CPU port.
   2531	 */
   2532	warn = !dsa_is_cpu_port(ds, port) && !dsa_is_dsa_port(ds, port);
   2533
   2534	mv88e6xxx_reg_lock(chip);
   2535
   2536	err = mv88e6xxx_port_vlan_join(chip, port, vlan->vid, member, warn);
   2537	if (err) {
   2538		dev_err(ds->dev, "p%d: failed to add VLAN %d%c\n", port,
   2539			vlan->vid, untagged ? 'u' : 't');
   2540		goto out;
   2541	}
   2542
   2543	if (pvid) {
   2544		p->bridge_pvid.vid = vlan->vid;
   2545		p->bridge_pvid.valid = true;
   2546
   2547		err = mv88e6xxx_port_commit_pvid(chip, port);
   2548		if (err)
   2549			goto out;
   2550	} else if (vlan->vid && p->bridge_pvid.vid == vlan->vid) {
   2551		/* The old pvid was reinstalled as a non-pvid VLAN */
   2552		p->bridge_pvid.valid = false;
   2553
   2554		err = mv88e6xxx_port_commit_pvid(chip, port);
   2555		if (err)
   2556			goto out;
   2557	}
   2558
   2559out:
   2560	mv88e6xxx_reg_unlock(chip);
   2561
   2562	return err;
   2563}
   2564
   2565static int mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip *chip,
   2566				     int port, u16 vid)
   2567{
   2568	struct mv88e6xxx_vtu_entry vlan;
   2569	int i, err;
   2570
   2571	if (!vid)
   2572		return 0;
   2573
   2574	err = mv88e6xxx_vtu_get(chip, vid, &vlan);
   2575	if (err)
   2576		return err;
   2577
   2578	/* If the VLAN doesn't exist in hardware or the port isn't a member,
   2579	 * tell switchdev that this VLAN is likely handled in software.
   2580	 */
   2581	if (!vlan.valid ||
   2582	    vlan.member[port] == MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
   2583		return -EOPNOTSUPP;
   2584
   2585	vlan.member[port] = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
   2586
   2587	/* keep the VLAN unless all ports are excluded */
   2588	vlan.valid = false;
   2589	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
   2590		if (vlan.member[i] !=
   2591		    MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
   2592			vlan.valid = true;
   2593			break;
   2594		}
   2595	}
   2596
   2597	err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
   2598	if (err)
   2599		return err;
   2600
   2601	if (!vlan.valid) {
   2602		err = mv88e6xxx_mst_put(chip, vlan.sid);
   2603		if (err)
   2604			return err;
   2605	}
   2606
   2607	return mv88e6xxx_g1_atu_remove(chip, vlan.fid, port, false);
   2608}
   2609
   2610static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
   2611				   const struct switchdev_obj_port_vlan *vlan)
   2612{
   2613	struct mv88e6xxx_chip *chip = ds->priv;
   2614	struct mv88e6xxx_port *p = &chip->ports[port];
   2615	int err = 0;
   2616	u16 pvid;
   2617
   2618	if (!mv88e6xxx_max_vid(chip))
   2619		return -EOPNOTSUPP;
   2620
   2621	/* The ATU removal procedure needs the FID to be mapped in the VTU,
   2622	 * but FDB deletion runs concurrently with VLAN deletion. Flush the DSA
   2623	 * switchdev workqueue to ensure that all FDB entries are deleted
   2624	 * before we remove the VLAN.
   2625	 */
   2626	dsa_flush_workqueue();
   2627
   2628	mv88e6xxx_reg_lock(chip);
   2629
   2630	err = mv88e6xxx_port_get_pvid(chip, port, &pvid);
   2631	if (err)
   2632		goto unlock;
   2633
   2634	err = mv88e6xxx_port_vlan_leave(chip, port, vlan->vid);
   2635	if (err)
   2636		goto unlock;
   2637
   2638	if (vlan->vid == pvid) {
   2639		p->bridge_pvid.valid = false;
   2640
   2641		err = mv88e6xxx_port_commit_pvid(chip, port);
   2642		if (err)
   2643			goto unlock;
   2644	}
   2645
   2646unlock:
   2647	mv88e6xxx_reg_unlock(chip);
   2648
   2649	return err;
   2650}
   2651
   2652static int mv88e6xxx_port_vlan_fast_age(struct dsa_switch *ds, int port, u16 vid)
   2653{
   2654	struct mv88e6xxx_chip *chip = ds->priv;
   2655	struct mv88e6xxx_vtu_entry vlan;
   2656	int err;
   2657
   2658	mv88e6xxx_reg_lock(chip);
   2659
   2660	err = mv88e6xxx_vtu_get(chip, vid, &vlan);
   2661	if (err)
   2662		goto unlock;
   2663
   2664	err = mv88e6xxx_port_fast_age_fid(chip, port, vlan.fid);
   2665
   2666unlock:
   2667	mv88e6xxx_reg_unlock(chip);
   2668
   2669	return err;
   2670}
   2671
   2672static int mv88e6xxx_vlan_msti_set(struct dsa_switch *ds,
   2673				   struct dsa_bridge bridge,
   2674				   const struct switchdev_vlan_msti *msti)
   2675{
   2676	struct mv88e6xxx_chip *chip = ds->priv;
   2677	struct mv88e6xxx_vtu_entry vlan;
   2678	u8 old_sid, new_sid;
   2679	int err;
   2680
   2681	if (!mv88e6xxx_has_stu(chip))
   2682		return -EOPNOTSUPP;
   2683
   2684	mv88e6xxx_reg_lock(chip);
   2685
   2686	err = mv88e6xxx_vtu_get(chip, msti->vid, &vlan);
   2687	if (err)
   2688		goto unlock;
   2689
   2690	if (!vlan.valid) {
   2691		err = -EINVAL;
   2692		goto unlock;
   2693	}
   2694
   2695	old_sid = vlan.sid;
   2696
   2697	err = mv88e6xxx_mst_get(chip, bridge.dev, msti->msti, &new_sid);
   2698	if (err)
   2699		goto unlock;
   2700
   2701	if (new_sid != old_sid) {
   2702		vlan.sid = new_sid;
   2703
   2704		err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
   2705		if (err) {
   2706			mv88e6xxx_mst_put(chip, new_sid);
   2707			goto unlock;
   2708		}
   2709	}
   2710
   2711	err = mv88e6xxx_mst_put(chip, old_sid);
   2712
   2713unlock:
   2714	mv88e6xxx_reg_unlock(chip);
   2715	return err;
   2716}
   2717
   2718static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
   2719				  const unsigned char *addr, u16 vid,
   2720				  struct dsa_db db)
   2721{
   2722	struct mv88e6xxx_chip *chip = ds->priv;
   2723	int err;
   2724
   2725	mv88e6xxx_reg_lock(chip);
   2726	err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
   2727					   MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
   2728	mv88e6xxx_reg_unlock(chip);
   2729
   2730	return err;
   2731}
   2732
   2733static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
   2734				  const unsigned char *addr, u16 vid,
   2735				  struct dsa_db db)
   2736{
   2737	struct mv88e6xxx_chip *chip = ds->priv;
   2738	int err;
   2739
   2740	mv88e6xxx_reg_lock(chip);
   2741	err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, 0);
   2742	mv88e6xxx_reg_unlock(chip);
   2743
   2744	return err;
   2745}
   2746
   2747static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
   2748				      u16 fid, u16 vid, int port,
   2749				      dsa_fdb_dump_cb_t *cb, void *data)
   2750{
   2751	struct mv88e6xxx_atu_entry addr;
   2752	bool is_static;
   2753	int err;
   2754
   2755	addr.state = 0;
   2756	eth_broadcast_addr(addr.mac);
   2757
   2758	do {
   2759		err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr);
   2760		if (err)
   2761			return err;
   2762
   2763		if (!addr.state)
   2764			break;
   2765
   2766		if (addr.trunk || (addr.portvec & BIT(port)) == 0)
   2767			continue;
   2768
   2769		if (!is_unicast_ether_addr(addr.mac))
   2770			continue;
   2771
   2772		is_static = (addr.state ==
   2773			     MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
   2774		err = cb(addr.mac, vid, is_static, data);
   2775		if (err)
   2776			return err;
   2777	} while (!is_broadcast_ether_addr(addr.mac));
   2778
   2779	return err;
   2780}
   2781
   2782struct mv88e6xxx_port_db_dump_vlan_ctx {
   2783	int port;
   2784	dsa_fdb_dump_cb_t *cb;
   2785	void *data;
   2786};
   2787
   2788static int mv88e6xxx_port_db_dump_vlan(struct mv88e6xxx_chip *chip,
   2789				       const struct mv88e6xxx_vtu_entry *entry,
   2790				       void *_data)
   2791{
   2792	struct mv88e6xxx_port_db_dump_vlan_ctx *ctx = _data;
   2793
   2794	return mv88e6xxx_port_db_dump_fid(chip, entry->fid, entry->vid,
   2795					  ctx->port, ctx->cb, ctx->data);
   2796}
   2797
   2798static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
   2799				  dsa_fdb_dump_cb_t *cb, void *data)
   2800{
   2801	struct mv88e6xxx_port_db_dump_vlan_ctx ctx = {
   2802		.port = port,
   2803		.cb = cb,
   2804		.data = data,
   2805	};
   2806	u16 fid;
   2807	int err;
   2808
   2809	/* Dump port's default Filtering Information Database (VLAN ID 0) */
   2810	err = mv88e6xxx_port_get_fid(chip, port, &fid);
   2811	if (err)
   2812		return err;
   2813
   2814	err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, cb, data);
   2815	if (err)
   2816		return err;
   2817
   2818	return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_db_dump_vlan, &ctx);
   2819}
   2820
   2821static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
   2822				   dsa_fdb_dump_cb_t *cb, void *data)
   2823{
   2824	struct mv88e6xxx_chip *chip = ds->priv;
   2825	int err;
   2826
   2827	mv88e6xxx_reg_lock(chip);
   2828	err = mv88e6xxx_port_db_dump(chip, port, cb, data);
   2829	mv88e6xxx_reg_unlock(chip);
   2830
   2831	return err;
   2832}
   2833
   2834static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip,
   2835				struct dsa_bridge bridge)
   2836{
   2837	struct dsa_switch *ds = chip->ds;
   2838	struct dsa_switch_tree *dst = ds->dst;
   2839	struct dsa_port *dp;
   2840	int err;
   2841
   2842	list_for_each_entry(dp, &dst->ports, list) {
   2843		if (dsa_port_offloads_bridge(dp, &bridge)) {
   2844			if (dp->ds == ds) {
   2845				/* This is a local bridge group member,
   2846				 * remap its Port VLAN Map.
   2847				 */
   2848				err = mv88e6xxx_port_vlan_map(chip, dp->index);
   2849				if (err)
   2850					return err;
   2851			} else {
   2852				/* This is an external bridge group member,
   2853				 * remap its cross-chip Port VLAN Table entry.
   2854				 */
   2855				err = mv88e6xxx_pvt_map(chip, dp->ds->index,
   2856							dp->index);
   2857				if (err)
   2858					return err;
   2859			}
   2860		}
   2861	}
   2862
   2863	return 0;
   2864}
   2865
   2866/* Treat the software bridge as a virtual single-port switch behind the
   2867 * CPU and map in the PVT. First dst->last_switch elements are taken by
   2868 * physical switches, so start from beyond that range.
   2869 */
   2870static int mv88e6xxx_map_virtual_bridge_to_pvt(struct dsa_switch *ds,
   2871					       unsigned int bridge_num)
   2872{
   2873	u8 dev = bridge_num + ds->dst->last_switch;
   2874	struct mv88e6xxx_chip *chip = ds->priv;
   2875
   2876	return mv88e6xxx_pvt_map(chip, dev, 0);
   2877}
   2878
   2879static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
   2880				      struct dsa_bridge bridge,
   2881				      bool *tx_fwd_offload,
   2882				      struct netlink_ext_ack *extack)
   2883{
   2884	struct mv88e6xxx_chip *chip = ds->priv;
   2885	int err;
   2886
   2887	mv88e6xxx_reg_lock(chip);
   2888
   2889	err = mv88e6xxx_bridge_map(chip, bridge);
   2890	if (err)
   2891		goto unlock;
   2892
   2893	err = mv88e6xxx_port_set_map_da(chip, port, true);
   2894	if (err)
   2895		goto unlock;
   2896
   2897	err = mv88e6xxx_port_commit_pvid(chip, port);
   2898	if (err)
   2899		goto unlock;
   2900
   2901	if (mv88e6xxx_has_pvt(chip)) {
   2902		err = mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num);
   2903		if (err)
   2904			goto unlock;
   2905
   2906		*tx_fwd_offload = true;
   2907	}
   2908
   2909unlock:
   2910	mv88e6xxx_reg_unlock(chip);
   2911
   2912	return err;
   2913}
   2914
   2915static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port,
   2916					struct dsa_bridge bridge)
   2917{
   2918	struct mv88e6xxx_chip *chip = ds->priv;
   2919	int err;
   2920
   2921	mv88e6xxx_reg_lock(chip);
   2922
   2923	if (bridge.tx_fwd_offload &&
   2924	    mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num))
   2925		dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n");
   2926
   2927	if (mv88e6xxx_bridge_map(chip, bridge) ||
   2928	    mv88e6xxx_port_vlan_map(chip, port))
   2929		dev_err(ds->dev, "failed to remap in-chip Port VLAN\n");
   2930
   2931	err = mv88e6xxx_port_set_map_da(chip, port, false);
   2932	if (err)
   2933		dev_err(ds->dev,
   2934			"port %d failed to restore map-DA: %pe\n",
   2935			port, ERR_PTR(err));
   2936
   2937	err = mv88e6xxx_port_commit_pvid(chip, port);
   2938	if (err)
   2939		dev_err(ds->dev,
   2940			"port %d failed to restore standalone pvid: %pe\n",
   2941			port, ERR_PTR(err));
   2942
   2943	mv88e6xxx_reg_unlock(chip);
   2944}
   2945
   2946static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds,
   2947					   int tree_index, int sw_index,
   2948					   int port, struct dsa_bridge bridge,
   2949					   struct netlink_ext_ack *extack)
   2950{
   2951	struct mv88e6xxx_chip *chip = ds->priv;
   2952	int err;
   2953
   2954	if (tree_index != ds->dst->index)
   2955		return 0;
   2956
   2957	mv88e6xxx_reg_lock(chip);
   2958	err = mv88e6xxx_pvt_map(chip, sw_index, port);
   2959	err = err ? : mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num);
   2960	mv88e6xxx_reg_unlock(chip);
   2961
   2962	return err;
   2963}
   2964
   2965static void mv88e6xxx_crosschip_bridge_leave(struct dsa_switch *ds,
   2966					     int tree_index, int sw_index,
   2967					     int port, struct dsa_bridge bridge)
   2968{
   2969	struct mv88e6xxx_chip *chip = ds->priv;
   2970
   2971	if (tree_index != ds->dst->index)
   2972		return;
   2973
   2974	mv88e6xxx_reg_lock(chip);
   2975	if (mv88e6xxx_pvt_map(chip, sw_index, port) ||
   2976	    mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num))
   2977		dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n");
   2978	mv88e6xxx_reg_unlock(chip);
   2979}
   2980
   2981static int mv88e6xxx_software_reset(struct mv88e6xxx_chip *chip)
   2982{
   2983	if (chip->info->ops->reset)
   2984		return chip->info->ops->reset(chip);
   2985
   2986	return 0;
   2987}
   2988
   2989static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
   2990{
   2991	struct gpio_desc *gpiod = chip->reset;
   2992
   2993	/* If there is a GPIO connected to the reset pin, toggle it */
   2994	if (gpiod) {
   2995		gpiod_set_value_cansleep(gpiod, 1);
   2996		usleep_range(10000, 20000);
   2997		gpiod_set_value_cansleep(gpiod, 0);
   2998		usleep_range(10000, 20000);
   2999
   3000		mv88e6xxx_g1_wait_eeprom_done(chip);
   3001	}
   3002}
   3003
   3004static int mv88e6xxx_disable_ports(struct mv88e6xxx_chip *chip)
   3005{
   3006	int i, err;
   3007
   3008	/* Set all ports to the Disabled state */
   3009	for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
   3010		err = mv88e6xxx_port_set_state(chip, i, BR_STATE_DISABLED);
   3011		if (err)
   3012			return err;
   3013	}
   3014
   3015	/* Wait for transmit queues to drain,
   3016	 * i.e. 2ms for a maximum frame to be transmitted at 10 Mbps.
   3017	 */
   3018	usleep_range(2000, 4000);
   3019
   3020	return 0;
   3021}
   3022
   3023static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
   3024{
   3025	int err;
   3026
   3027	err = mv88e6xxx_disable_ports(chip);
   3028	if (err)
   3029		return err;
   3030
   3031	mv88e6xxx_hardware_reset(chip);
   3032
   3033	return mv88e6xxx_software_reset(chip);
   3034}
   3035
   3036static int mv88e6xxx_set_port_mode(struct mv88e6xxx_chip *chip, int port,
   3037				   enum mv88e6xxx_frame_mode frame,
   3038				   enum mv88e6xxx_egress_mode egress, u16 etype)
   3039{
   3040	int err;
   3041
   3042	if (!chip->info->ops->port_set_frame_mode)
   3043		return -EOPNOTSUPP;
   3044
   3045	err = mv88e6xxx_port_set_egress_mode(chip, port, egress);
   3046	if (err)
   3047		return err;
   3048
   3049	err = chip->info->ops->port_set_frame_mode(chip, port, frame);
   3050	if (err)
   3051		return err;
   3052
   3053	if (chip->info->ops->port_set_ether_type)
   3054		return chip->info->ops->port_set_ether_type(chip, port, etype);
   3055
   3056	return 0;
   3057}
   3058
   3059static int mv88e6xxx_set_port_mode_normal(struct mv88e6xxx_chip *chip, int port)
   3060{
   3061	return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_NORMAL,
   3062				       MV88E6XXX_EGRESS_MODE_UNMODIFIED,
   3063				       MV88E6XXX_PORT_ETH_TYPE_DEFAULT);
   3064}
   3065
   3066static int mv88e6xxx_set_port_mode_dsa(struct mv88e6xxx_chip *chip, int port)
   3067{
   3068	return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_DSA,
   3069				       MV88E6XXX_EGRESS_MODE_UNMODIFIED,
   3070				       MV88E6XXX_PORT_ETH_TYPE_DEFAULT);
   3071}
   3072
   3073static int mv88e6xxx_set_port_mode_edsa(struct mv88e6xxx_chip *chip, int port)
   3074{
   3075	return mv88e6xxx_set_port_mode(chip, port,
   3076				       MV88E6XXX_FRAME_MODE_ETHERTYPE,
   3077				       MV88E6XXX_EGRESS_MODE_ETHERTYPE,
   3078				       ETH_P_EDSA);
   3079}
   3080
   3081static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)
   3082{
   3083	if (dsa_is_dsa_port(chip->ds, port))
   3084		return mv88e6xxx_set_port_mode_dsa(chip, port);
   3085
   3086	if (dsa_is_user_port(chip->ds, port))
   3087		return mv88e6xxx_set_port_mode_normal(chip, port);
   3088
   3089	/* Setup CPU port mode depending on its supported tag format */
   3090	if (chip->tag_protocol == DSA_TAG_PROTO_DSA)
   3091		return mv88e6xxx_set_port_mode_dsa(chip, port);
   3092
   3093	if (chip->tag_protocol == DSA_TAG_PROTO_EDSA)
   3094		return mv88e6xxx_set_port_mode_edsa(chip, port);
   3095
   3096	return -EINVAL;
   3097}
   3098
   3099static int mv88e6xxx_setup_message_port(struct mv88e6xxx_chip *chip, int port)
   3100{
   3101	bool message = dsa_is_dsa_port(chip->ds, port);
   3102
   3103	return mv88e6xxx_port_set_message_port(chip, port, message);
   3104}
   3105
   3106static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
   3107{
   3108	int err;
   3109
   3110	if (chip->info->ops->port_set_ucast_flood) {
   3111		err = chip->info->ops->port_set_ucast_flood(chip, port, true);
   3112		if (err)
   3113			return err;
   3114	}
   3115	if (chip->info->ops->port_set_mcast_flood) {
   3116		err = chip->info->ops->port_set_mcast_flood(chip, port, true);
   3117		if (err)
   3118			return err;
   3119	}
   3120
   3121	return 0;
   3122}
   3123
   3124static irqreturn_t mv88e6xxx_serdes_irq_thread_fn(int irq, void *dev_id)
   3125{
   3126	struct mv88e6xxx_port *mvp = dev_id;
   3127	struct mv88e6xxx_chip *chip = mvp->chip;
   3128	irqreturn_t ret = IRQ_NONE;
   3129	int port = mvp->port;
   3130	int lane;
   3131
   3132	mv88e6xxx_reg_lock(chip);
   3133	lane = mv88e6xxx_serdes_get_lane(chip, port);
   3134	if (lane >= 0)
   3135		ret = mv88e6xxx_serdes_irq_status(chip, port, lane);
   3136	mv88e6xxx_reg_unlock(chip);
   3137
   3138	return ret;
   3139}
   3140
   3141static int mv88e6xxx_serdes_irq_request(struct mv88e6xxx_chip *chip, int port,
   3142					int lane)
   3143{
   3144	struct mv88e6xxx_port *dev_id = &chip->ports[port];
   3145	unsigned int irq;
   3146	int err;
   3147
   3148	/* Nothing to request if this SERDES port has no IRQ */
   3149	irq = mv88e6xxx_serdes_irq_mapping(chip, port);
   3150	if (!irq)
   3151		return 0;
   3152
   3153	snprintf(dev_id->serdes_irq_name, sizeof(dev_id->serdes_irq_name),
   3154		 "mv88e6xxx-%s-serdes-%d", dev_name(chip->dev), port);
   3155
   3156	/* Requesting the IRQ will trigger IRQ callbacks, so release the lock */
   3157	mv88e6xxx_reg_unlock(chip);
   3158	err = request_threaded_irq(irq, NULL, mv88e6xxx_serdes_irq_thread_fn,
   3159				   IRQF_ONESHOT, dev_id->serdes_irq_name,
   3160				   dev_id);
   3161	mv88e6xxx_reg_lock(chip);
   3162	if (err)
   3163		return err;
   3164
   3165	dev_id->serdes_irq = irq;
   3166
   3167	return mv88e6xxx_serdes_irq_enable(chip, port, lane);
   3168}
   3169
   3170static int mv88e6xxx_serdes_irq_free(struct mv88e6xxx_chip *chip, int port,
   3171				     int lane)
   3172{
   3173	struct mv88e6xxx_port *dev_id = &chip->ports[port];
   3174	unsigned int irq = dev_id->serdes_irq;
   3175	int err;
   3176
   3177	/* Nothing to free if no IRQ has been requested */
   3178	if (!irq)
   3179		return 0;
   3180
   3181	err = mv88e6xxx_serdes_irq_disable(chip, port, lane);
   3182
   3183	/* Freeing the IRQ will trigger IRQ callbacks, so release the lock */
   3184	mv88e6xxx_reg_unlock(chip);
   3185	free_irq(irq, dev_id);
   3186	mv88e6xxx_reg_lock(chip);
   3187
   3188	dev_id->serdes_irq = 0;
   3189
   3190	return err;
   3191}
   3192
   3193static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
   3194				  bool on)
   3195{
   3196	int lane;
   3197	int err;
   3198
   3199	lane = mv88e6xxx_serdes_get_lane(chip, port);
   3200	if (lane < 0)
   3201		return 0;
   3202
   3203	if (on) {
   3204		err = mv88e6xxx_serdes_power_up(chip, port, lane);
   3205		if (err)
   3206			return err;
   3207
   3208		err = mv88e6xxx_serdes_irq_request(chip, port, lane);
   3209	} else {
   3210		err = mv88e6xxx_serdes_irq_free(chip, port, lane);
   3211		if (err)
   3212			return err;
   3213
   3214		err = mv88e6xxx_serdes_power_down(chip, port, lane);
   3215	}
   3216
   3217	return err;
   3218}
   3219
   3220static int mv88e6xxx_set_egress_port(struct mv88e6xxx_chip *chip,
   3221				     enum mv88e6xxx_egress_direction direction,
   3222				     int port)
   3223{
   3224	int err;
   3225
   3226	if (!chip->info->ops->set_egress_port)
   3227		return -EOPNOTSUPP;
   3228
   3229	err = chip->info->ops->set_egress_port(chip, direction, port);
   3230	if (err)
   3231		return err;
   3232
   3233	if (direction == MV88E6XXX_EGRESS_DIR_INGRESS)
   3234		chip->ingress_dest_port = port;
   3235	else
   3236		chip->egress_dest_port = port;
   3237
   3238	return 0;
   3239}
   3240
   3241static int mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip *chip, int port)
   3242{
   3243	struct dsa_switch *ds = chip->ds;
   3244	int upstream_port;
   3245	int err;
   3246
   3247	upstream_port = dsa_upstream_port(ds, port);
   3248	if (chip->info->ops->port_set_upstream_port) {
   3249		err = chip->info->ops->port_set_upstream_port(chip, port,
   3250							      upstream_port);
   3251		if (err)
   3252			return err;
   3253	}
   3254
   3255	if (port == upstream_port) {
   3256		if (chip->info->ops->set_cpu_port) {
   3257			err = chip->info->ops->set_cpu_port(chip,
   3258							    upstream_port);
   3259			if (err)
   3260				return err;
   3261		}
   3262
   3263		err = mv88e6xxx_set_egress_port(chip,
   3264						MV88E6XXX_EGRESS_DIR_INGRESS,
   3265						upstream_port);
   3266		if (err && err != -EOPNOTSUPP)
   3267			return err;
   3268
   3269		err = mv88e6xxx_set_egress_port(chip,
   3270						MV88E6XXX_EGRESS_DIR_EGRESS,
   3271						upstream_port);
   3272		if (err && err != -EOPNOTSUPP)
   3273			return err;
   3274	}
   3275
   3276	return 0;
   3277}
   3278
   3279static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
   3280{
   3281	struct device_node *phy_handle = NULL;
   3282	struct dsa_switch *ds = chip->ds;
   3283	struct dsa_port *dp;
   3284	int tx_amp;
   3285	int err;
   3286	u16 reg;
   3287
   3288	chip->ports[port].chip = chip;
   3289	chip->ports[port].port = port;
   3290
   3291	/* MAC Forcing register: don't force link, speed, duplex or flow control
   3292	 * state to any particular values on physical ports, but force the CPU
   3293	 * port and all DSA ports to their maximum bandwidth and full duplex.
   3294	 */
   3295	if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))
   3296		err = mv88e6xxx_port_setup_mac(chip, port, LINK_FORCED_UP,
   3297					       SPEED_MAX, DUPLEX_FULL,
   3298					       PAUSE_OFF,
   3299					       PHY_INTERFACE_MODE_NA);
   3300	else
   3301		err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED,
   3302					       SPEED_UNFORCED, DUPLEX_UNFORCED,
   3303					       PAUSE_ON,
   3304					       PHY_INTERFACE_MODE_NA);
   3305	if (err)
   3306		return err;
   3307
   3308	/* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
   3309	 * disable Header mode, enable IGMP/MLD snooping, disable VLAN
   3310	 * tunneling, determine priority by looking at 802.1p and IP
   3311	 * priority fields (IP prio has precedence), and set STP state
   3312	 * to Forwarding.
   3313	 *
   3314	 * If this is the CPU link, use DSA or EDSA tagging depending
   3315	 * on which tagging mode was configured.
   3316	 *
   3317	 * If this is a link to another switch, use DSA tagging mode.
   3318	 *
   3319	 * If this is the upstream port for this switch, enable
   3320	 * forwarding of unknown unicasts and multicasts.
   3321	 */
   3322	reg = MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP |
   3323		MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
   3324		MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
   3325	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
   3326	if (err)
   3327		return err;
   3328
   3329	err = mv88e6xxx_setup_port_mode(chip, port);
   3330	if (err)
   3331		return err;
   3332
   3333	err = mv88e6xxx_setup_egress_floods(chip, port);
   3334	if (err)
   3335		return err;
   3336
   3337	/* Port Control 2: don't force a good FCS, set the MTU size to
   3338	 * 10222 bytes, disable 802.1q tags checking, don't discard
   3339	 * tagged or untagged frames on this port, skip destination
   3340	 * address lookup on user ports, disable ARP mirroring and don't
   3341	 * send a copy of all transmitted/received frames on this port
   3342	 * to the CPU.
   3343	 */
   3344	err = mv88e6xxx_port_set_map_da(chip, port, !dsa_is_user_port(ds, port));
   3345	if (err)
   3346		return err;
   3347
   3348	err = mv88e6xxx_setup_upstream_port(chip, port);
   3349	if (err)
   3350		return err;
   3351
   3352	/* On chips that support it, set all downstream DSA ports'
   3353	 * VLAN policy to TRAP. In combination with loading
   3354	 * MV88E6XXX_VID_STANDALONE as a policy entry in the VTU, this
   3355	 * provides a better isolation barrier between standalone
   3356	 * ports, as the ATU is bypassed on any intermediate switches
   3357	 * between the incoming port and the CPU.
   3358	 */
   3359	if (dsa_is_downstream_port(ds, port) &&
   3360	    chip->info->ops->port_set_policy) {
   3361		err = chip->info->ops->port_set_policy(chip, port,
   3362						MV88E6XXX_POLICY_MAPPING_VTU,
   3363						MV88E6XXX_POLICY_ACTION_TRAP);
   3364		if (err)
   3365			return err;
   3366	}
   3367
   3368	/* User ports start out in standalone mode and 802.1Q is
   3369	 * therefore disabled. On DSA ports, all valid VIDs are always
   3370	 * loaded in the VTU - therefore, enable 802.1Q in order to take
   3371	 * advantage of VLAN policy on chips that supports it.
   3372	 */
   3373	err = mv88e6xxx_port_set_8021q_mode(chip, port,
   3374				dsa_is_user_port(ds, port) ?
   3375				MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED :
   3376				MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE);
   3377	if (err)
   3378		return err;
   3379
   3380	/* Bind MV88E6XXX_VID_STANDALONE to MV88E6XXX_FID_STANDALONE by
   3381	 * virtue of the fact that mv88e6xxx_atu_new() will pick it as
   3382	 * the first free FID. This will be used as the private PVID for
   3383	 * unbridged ports. Shared (DSA and CPU) ports must also be
   3384	 * members of this VID, in order to trap all frames assigned to
   3385	 * it to the CPU.
   3386	 */
   3387	err = mv88e6xxx_port_vlan_join(chip, port, MV88E6XXX_VID_STANDALONE,
   3388				       MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED,
   3389				       false);
   3390	if (err)
   3391		return err;
   3392
   3393	/* Associate MV88E6XXX_VID_BRIDGED with MV88E6XXX_FID_BRIDGED in the
   3394	 * ATU by virtue of the fact that mv88e6xxx_atu_new() will pick it as
   3395	 * the first free FID after MV88E6XXX_FID_STANDALONE. This will be used
   3396	 * as the private PVID on ports under a VLAN-unaware bridge.
   3397	 * Shared (DSA and CPU) ports must also be members of it, to translate
   3398	 * the VID from the DSA tag into MV88E6XXX_FID_BRIDGED, instead of
   3399	 * relying on their port default FID.
   3400	 */
   3401	err = mv88e6xxx_port_vlan_join(chip, port, MV88E6XXX_VID_BRIDGED,
   3402				       MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED,
   3403				       false);
   3404	if (err)
   3405		return err;
   3406
   3407	if (chip->info->ops->port_set_jumbo_size) {
   3408		err = chip->info->ops->port_set_jumbo_size(chip, port, 10218);
   3409		if (err)
   3410			return err;
   3411	}
   3412
   3413	/* Port Association Vector: disable automatic address learning
   3414	 * on all user ports since they start out in standalone
   3415	 * mode. When joining a bridge, learning will be configured to
   3416	 * match the bridge port settings. Enable learning on all
   3417	 * DSA/CPU ports. NOTE: FROM_CPU frames always bypass the
   3418	 * learning process.
   3419	 *
   3420	 * Disable HoldAt1, IntOnAgeOut, LockedPort, IgnoreWrongData,
   3421	 * and RefreshLocked. I.e. setup standard automatic learning.
   3422	 */
   3423	if (dsa_is_user_port(ds, port))
   3424		reg = 0;
   3425	else
   3426		reg = 1 << port;
   3427
   3428	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
   3429				   reg);
   3430	if (err)
   3431		return err;
   3432
   3433	/* Egress rate control 2: disable egress rate control. */
   3434	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL2,
   3435				   0x0000);
   3436	if (err)
   3437		return err;
   3438
   3439	if (chip->info->ops->port_pause_limit) {
   3440		err = chip->info->ops->port_pause_limit(chip, port, 0, 0);
   3441		if (err)
   3442			return err;
   3443	}
   3444
   3445	if (chip->info->ops->port_disable_learn_limit) {
   3446		err = chip->info->ops->port_disable_learn_limit(chip, port);
   3447		if (err)
   3448			return err;
   3449	}
   3450
   3451	if (chip->info->ops->port_disable_pri_override) {
   3452		err = chip->info->ops->port_disable_pri_override(chip, port);
   3453		if (err)
   3454			return err;
   3455	}
   3456
   3457	if (chip->info->ops->port_tag_remap) {
   3458		err = chip->info->ops->port_tag_remap(chip, port);
   3459		if (err)
   3460			return err;
   3461	}
   3462
   3463	if (chip->info->ops->port_egress_rate_limiting) {
   3464		err = chip->info->ops->port_egress_rate_limiting(chip, port);
   3465		if (err)
   3466			return err;
   3467	}
   3468
   3469	if (chip->info->ops->port_setup_message_port) {
   3470		err = chip->info->ops->port_setup_message_port(chip, port);
   3471		if (err)
   3472			return err;
   3473	}
   3474
   3475	if (chip->info->ops->serdes_set_tx_amplitude) {
   3476		dp = dsa_to_port(ds, port);
   3477		if (dp)
   3478			phy_handle = of_parse_phandle(dp->dn, "phy-handle", 0);
   3479
   3480		if (phy_handle && !of_property_read_u32(phy_handle,
   3481							"tx-p2p-microvolt",
   3482							&tx_amp))
   3483			err = chip->info->ops->serdes_set_tx_amplitude(chip,
   3484								port, tx_amp);
   3485		if (phy_handle) {
   3486			of_node_put(phy_handle);
   3487			if (err)
   3488				return err;
   3489		}
   3490	}
   3491
   3492	/* Port based VLAN map: give each port the same default address
   3493	 * database, and allow bidirectional communication between the
   3494	 * CPU and DSA port(s), and the other ports.
   3495	 */
   3496	err = mv88e6xxx_port_set_fid(chip, port, MV88E6XXX_FID_STANDALONE);
   3497	if (err)
   3498		return err;
   3499
   3500	err = mv88e6xxx_port_vlan_map(chip, port);
   3501	if (err)
   3502		return err;
   3503
   3504	/* Default VLAN ID and priority: don't set a default VLAN
   3505	 * ID, and set the default packet priority to zero.
   3506	 */
   3507	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 0);
   3508}
   3509
   3510static int mv88e6xxx_get_max_mtu(struct dsa_switch *ds, int port)
   3511{
   3512	struct mv88e6xxx_chip *chip = ds->priv;
   3513
   3514	if (chip->info->ops->port_set_jumbo_size)
   3515		return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
   3516	else if (chip->info->ops->set_max_frame_size)
   3517		return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
   3518	return 1522 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
   3519}
   3520
   3521static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
   3522{
   3523	struct mv88e6xxx_chip *chip = ds->priv;
   3524	int ret = 0;
   3525
   3526	if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
   3527		new_mtu += EDSA_HLEN;
   3528
   3529	mv88e6xxx_reg_lock(chip);
   3530	if (chip->info->ops->port_set_jumbo_size)
   3531		ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu);
   3532	else if (chip->info->ops->set_max_frame_size)
   3533		ret = chip->info->ops->set_max_frame_size(chip, new_mtu);
   3534	else
   3535		if (new_mtu > 1522)
   3536			ret = -EINVAL;
   3537	mv88e6xxx_reg_unlock(chip);
   3538
   3539	return ret;
   3540}
   3541
   3542static int mv88e6xxx_port_enable(struct dsa_switch *ds, int port,
   3543				 struct phy_device *phydev)
   3544{
   3545	struct mv88e6xxx_chip *chip = ds->priv;
   3546	int err;
   3547
   3548	mv88e6xxx_reg_lock(chip);
   3549	err = mv88e6xxx_serdes_power(chip, port, true);
   3550	mv88e6xxx_reg_unlock(chip);
   3551
   3552	return err;
   3553}
   3554
   3555static void mv88e6xxx_port_disable(struct dsa_switch *ds, int port)
   3556{
   3557	struct mv88e6xxx_chip *chip = ds->priv;
   3558
   3559	mv88e6xxx_reg_lock(chip);
   3560	if (mv88e6xxx_serdes_power(chip, port, false))
   3561		dev_err(chip->dev, "failed to power off SERDES\n");
   3562	mv88e6xxx_reg_unlock(chip);
   3563}
   3564
   3565static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds,
   3566				     unsigned int ageing_time)
   3567{
   3568	struct mv88e6xxx_chip *chip = ds->priv;
   3569	int err;
   3570
   3571	mv88e6xxx_reg_lock(chip);
   3572	err = mv88e6xxx_g1_atu_set_age_time(chip, ageing_time);
   3573	mv88e6xxx_reg_unlock(chip);
   3574
   3575	return err;
   3576}
   3577
   3578static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip)
   3579{
   3580	int err;
   3581
   3582	/* Initialize the statistics unit */
   3583	if (chip->info->ops->stats_set_histogram) {
   3584		err = chip->info->ops->stats_set_histogram(chip);
   3585		if (err)
   3586			return err;
   3587	}
   3588
   3589	return mv88e6xxx_g1_stats_clear(chip);
   3590}
   3591
   3592/* Check if the errata has already been applied. */
   3593static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip)
   3594{
   3595	int port;
   3596	int err;
   3597	u16 val;
   3598
   3599	for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
   3600		err = mv88e6xxx_port_hidden_read(chip, 0xf, port, 0, &val);
   3601		if (err) {
   3602			dev_err(chip->dev,
   3603				"Error reading hidden register: %d\n", err);
   3604			return false;
   3605		}
   3606		if (val != 0x01c0)
   3607			return false;
   3608	}
   3609
   3610	return true;
   3611}
   3612
   3613/* The 6390 copper ports have an errata which require poking magic
   3614 * values into undocumented hidden registers and then performing a
   3615 * software reset.
   3616 */
   3617static int mv88e6390_setup_errata(struct mv88e6xxx_chip *chip)
   3618{
   3619	int port;
   3620	int err;
   3621
   3622	if (mv88e6390_setup_errata_applied(chip))
   3623		return 0;
   3624
   3625	/* Set the ports into blocking mode */
   3626	for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
   3627		err = mv88e6xxx_port_set_state(chip, port, BR_STATE_DISABLED);
   3628		if (err)
   3629			return err;
   3630	}
   3631
   3632	for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
   3633		err = mv88e6xxx_port_hidden_write(chip, 0xf, port, 0, 0x01c0);
   3634		if (err)
   3635			return err;
   3636	}
   3637
   3638	return mv88e6xxx_software_reset(chip);
   3639}
   3640
   3641static void mv88e6xxx_teardown(struct dsa_switch *ds)
   3642{
   3643	mv88e6xxx_teardown_devlink_params(ds);
   3644	dsa_devlink_resources_unregister(ds);
   3645	mv88e6xxx_teardown_devlink_regions_global(ds);
   3646}
   3647
   3648static int mv88e6xxx_setup(struct dsa_switch *ds)
   3649{
   3650	struct mv88e6xxx_chip *chip = ds->priv;
   3651	u8 cmode;
   3652	int err;
   3653	int i;
   3654
   3655	chip->ds = ds;
   3656	ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip);
   3657
   3658	/* Since virtual bridges are mapped in the PVT, the number we support
   3659	 * depends on the physical switch topology. We need to let DSA figure
   3660	 * that out and therefore we cannot set this at dsa_register_switch()
   3661	 * time.
   3662	 */
   3663	if (mv88e6xxx_has_pvt(chip))
   3664		ds->max_num_bridges = MV88E6XXX_MAX_PVT_SWITCHES -
   3665				      ds->dst->last_switch - 1;
   3666
   3667	mv88e6xxx_reg_lock(chip);
   3668
   3669	if (chip->info->ops->setup_errata) {
   3670		err = chip->info->ops->setup_errata(chip);
   3671		if (err)
   3672			goto unlock;
   3673	}
   3674
   3675	/* Cache the cmode of each port. */
   3676	for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
   3677		if (chip->info->ops->port_get_cmode) {
   3678			err = chip->info->ops->port_get_cmode(chip, i, &cmode);
   3679			if (err)
   3680				goto unlock;
   3681
   3682			chip->ports[i].cmode = cmode;
   3683		}
   3684	}
   3685
   3686	err = mv88e6xxx_vtu_setup(chip);
   3687	if (err)
   3688		goto unlock;
   3689
   3690	/* Must be called after mv88e6xxx_vtu_setup (which flushes the
   3691	 * VTU, thereby also flushing the STU).
   3692	 */
   3693	err = mv88e6xxx_stu_setup(chip);
   3694	if (err)
   3695		goto unlock;
   3696
   3697	/* Setup Switch Port Registers */
   3698	for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
   3699		if (dsa_is_unused_port(ds, i))
   3700			continue;
   3701
   3702		/* Prevent the use of an invalid port. */
   3703		if (mv88e6xxx_is_invalid_port(chip, i)) {
   3704			dev_err(chip->dev, "port %d is invalid\n", i);
   3705			err = -EINVAL;
   3706			goto unlock;
   3707		}
   3708
   3709		err = mv88e6xxx_setup_port(chip, i);
   3710		if (err)
   3711			goto unlock;
   3712	}
   3713
   3714	err = mv88e6xxx_irl_setup(chip);
   3715	if (err)
   3716		goto unlock;
   3717
   3718	err = mv88e6xxx_mac_setup(chip);
   3719	if (err)
   3720		goto unlock;
   3721
   3722	err = mv88e6xxx_phy_setup(chip);
   3723	if (err)
   3724		goto unlock;
   3725
   3726	err = mv88e6xxx_pvt_setup(chip);
   3727	if (err)
   3728		goto unlock;
   3729
   3730	err = mv88e6xxx_atu_setup(chip);
   3731	if (err)
   3732		goto unlock;
   3733
   3734	err = mv88e6xxx_broadcast_setup(chip, 0);
   3735	if (err)
   3736		goto unlock;
   3737
   3738	err = mv88e6xxx_pot_setup(chip);
   3739	if (err)
   3740		goto unlock;
   3741
   3742	err = mv88e6xxx_rmu_setup(chip);
   3743	if (err)
   3744		goto unlock;
   3745
   3746	err = mv88e6xxx_rsvd2cpu_setup(chip);
   3747	if (err)
   3748		goto unlock;
   3749
   3750	err = mv88e6xxx_trunk_setup(chip);
   3751	if (err)
   3752		goto unlock;
   3753
   3754	err = mv88e6xxx_devmap_setup(chip);
   3755	if (err)
   3756		goto unlock;
   3757
   3758	err = mv88e6xxx_pri_setup(chip);
   3759	if (err)
   3760		goto unlock;
   3761
   3762	/* Setup PTP Hardware Clock and timestamping */
   3763	if (chip->info->ptp_support) {
   3764		err = mv88e6xxx_ptp_setup(chip);
   3765		if (err)
   3766			goto unlock;
   3767
   3768		err = mv88e6xxx_hwtstamp_setup(chip);
   3769		if (err)
   3770			goto unlock;
   3771	}
   3772
   3773	err = mv88e6xxx_stats_setup(chip);
   3774	if (err)
   3775		goto unlock;
   3776
   3777unlock:
   3778	mv88e6xxx_reg_unlock(chip);
   3779
   3780	if (err)
   3781		return err;
   3782
   3783	/* Have to be called without holding the register lock, since
   3784	 * they take the devlink lock, and we later take the locks in
   3785	 * the reverse order when getting/setting parameters or
   3786	 * resource occupancy.
   3787	 */
   3788	err = mv88e6xxx_setup_devlink_resources(ds);
   3789	if (err)
   3790		return err;
   3791
   3792	err = mv88e6xxx_setup_devlink_params(ds);
   3793	if (err)
   3794		goto out_resources;
   3795
   3796	err = mv88e6xxx_setup_devlink_regions_global(ds);
   3797	if (err)
   3798		goto out_params;
   3799
   3800	return 0;
   3801
   3802out_params:
   3803	mv88e6xxx_teardown_devlink_params(ds);
   3804out_resources:
   3805	dsa_devlink_resources_unregister(ds);
   3806
   3807	return err;
   3808}
   3809
   3810static int mv88e6xxx_port_setup(struct dsa_switch *ds, int port)
   3811{
   3812	return mv88e6xxx_setup_devlink_regions_port(ds, port);
   3813}
   3814
   3815static void mv88e6xxx_port_teardown(struct dsa_switch *ds, int port)
   3816{
   3817	mv88e6xxx_teardown_devlink_regions_port(ds, port);
   3818}
   3819
   3820/* prod_id for switch families which do not have a PHY model number */
   3821static const u16 family_prod_id_table[] = {
   3822	[MV88E6XXX_FAMILY_6341] = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
   3823	[MV88E6XXX_FAMILY_6390] = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
   3824	[MV88E6XXX_FAMILY_6393] = MV88E6XXX_PORT_SWITCH_ID_PROD_6393X,
   3825};
   3826
   3827static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
   3828{
   3829	struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
   3830	struct mv88e6xxx_chip *chip = mdio_bus->chip;
   3831	u16 prod_id;
   3832	u16 val;
   3833	int err;
   3834
   3835	if (!chip->info->ops->phy_read)
   3836		return -EOPNOTSUPP;
   3837
   3838	mv88e6xxx_reg_lock(chip);
   3839	err = chip->info->ops->phy_read(chip, bus, phy, reg, &val);
   3840	mv88e6xxx_reg_unlock(chip);
   3841
   3842	/* Some internal PHYs don't have a model number. */
   3843	if (reg == MII_PHYSID2 && !(val & 0x3f0) &&
   3844	    chip->info->family < ARRAY_SIZE(family_prod_id_table)) {
   3845		prod_id = family_prod_id_table[chip->info->family];
   3846		if (prod_id)
   3847			val |= prod_id >> 4;
   3848	}
   3849
   3850	return err ? err : val;
   3851}
   3852
   3853static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
   3854{
   3855	struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
   3856	struct mv88e6xxx_chip *chip = mdio_bus->chip;
   3857	int err;
   3858
   3859	if (!chip->info->ops->phy_write)
   3860		return -EOPNOTSUPP;
   3861
   3862	mv88e6xxx_reg_lock(chip);
   3863	err = chip->info->ops->phy_write(chip, bus, phy, reg, val);
   3864	mv88e6xxx_reg_unlock(chip);
   3865
   3866	return err;
   3867}
   3868
   3869static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
   3870				   struct device_node *np,
   3871				   bool external)
   3872{
   3873	static int index;
   3874	struct mv88e6xxx_mdio_bus *mdio_bus;
   3875	struct mii_bus *bus;
   3876	int err;
   3877
   3878	if (external) {
   3879		mv88e6xxx_reg_lock(chip);
   3880		err = mv88e6xxx_g2_scratch_gpio_set_smi(chip, true);
   3881		mv88e6xxx_reg_unlock(chip);
   3882
   3883		if (err)
   3884			return err;
   3885	}
   3886
   3887	bus = mdiobus_alloc_size(sizeof(*mdio_bus));
   3888	if (!bus)
   3889		return -ENOMEM;
   3890
   3891	mdio_bus = bus->priv;
   3892	mdio_bus->bus = bus;
   3893	mdio_bus->chip = chip;
   3894	INIT_LIST_HEAD(&mdio_bus->list);
   3895	mdio_bus->external = external;
   3896
   3897	if (np) {
   3898		bus->name = np->full_name;
   3899		snprintf(bus->id, MII_BUS_ID_SIZE, "%pOF", np);
   3900	} else {
   3901		bus->name = "mv88e6xxx SMI";
   3902		snprintf(bus->id, MII_BUS_ID_SIZE, "mv88e6xxx-%d", index++);
   3903	}
   3904
   3905	bus->read = mv88e6xxx_mdio_read;
   3906	bus->write = mv88e6xxx_mdio_write;
   3907	bus->parent = chip->dev;
   3908
   3909	if (!external) {
   3910		err = mv88e6xxx_g2_irq_mdio_setup(chip, bus);
   3911		if (err)
   3912			goto out;
   3913	}
   3914
   3915	err = of_mdiobus_register(bus, np);
   3916	if (err) {
   3917		dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err);
   3918		mv88e6xxx_g2_irq_mdio_free(chip, bus);
   3919		goto out;
   3920	}
   3921
   3922	if (external)
   3923		list_add_tail(&mdio_bus->list, &chip->mdios);
   3924	else
   3925		list_add(&mdio_bus->list, &chip->mdios);
   3926
   3927	return 0;
   3928
   3929out:
   3930	mdiobus_free(bus);
   3931	return err;
   3932}
   3933
   3934static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
   3935
   3936{
   3937	struct mv88e6xxx_mdio_bus *mdio_bus, *p;
   3938	struct mii_bus *bus;
   3939
   3940	list_for_each_entry_safe(mdio_bus, p, &chip->mdios, list) {
   3941		bus = mdio_bus->bus;
   3942
   3943		if (!mdio_bus->external)
   3944			mv88e6xxx_g2_irq_mdio_free(chip, bus);
   3945
   3946		mdiobus_unregister(bus);
   3947		mdiobus_free(bus);
   3948	}
   3949}
   3950
   3951static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip,
   3952				    struct device_node *np)
   3953{
   3954	struct device_node *child;
   3955	int err;
   3956
   3957	/* Always register one mdio bus for the internal/default mdio
   3958	 * bus. This maybe represented in the device tree, but is
   3959	 * optional.
   3960	 */
   3961	child = of_get_child_by_name(np, "mdio");
   3962	err = mv88e6xxx_mdio_register(chip, child, false);
   3963	of_node_put(child);
   3964	if (err)
   3965		return err;
   3966
   3967	/* Walk the device tree, and see if there are any other nodes
   3968	 * which say they are compatible with the external mdio
   3969	 * bus.
   3970	 */
   3971	for_each_available_child_of_node(np, child) {
   3972		if (of_device_is_compatible(
   3973			    child, "marvell,mv88e6xxx-mdio-external")) {
   3974			err = mv88e6xxx_mdio_register(chip, child, true);
   3975			if (err) {
   3976				mv88e6xxx_mdios_unregister(chip);
   3977				of_node_put(child);
   3978				return err;
   3979			}
   3980		}
   3981	}
   3982
   3983	return 0;
   3984}
   3985
   3986static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
   3987{
   3988	struct mv88e6xxx_chip *chip = ds->priv;
   3989
   3990	return chip->eeprom_len;
   3991}
   3992
   3993static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
   3994				struct ethtool_eeprom *eeprom, u8 *data)
   3995{
   3996	struct mv88e6xxx_chip *chip = ds->priv;
   3997	int err;
   3998
   3999	if (!chip->info->ops->get_eeprom)
   4000		return -EOPNOTSUPP;
   4001
   4002	mv88e6xxx_reg_lock(chip);
   4003	err = chip->info->ops->get_eeprom(chip, eeprom, data);
   4004	mv88e6xxx_reg_unlock(chip);
   4005
   4006	if (err)
   4007		return err;
   4008
   4009	eeprom->magic = 0xc3ec4951;
   4010
   4011	return 0;
   4012}
   4013
   4014static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
   4015				struct ethtool_eeprom *eeprom, u8 *data)
   4016{
   4017	struct mv88e6xxx_chip *chip = ds->priv;
   4018	int err;
   4019
   4020	if (!chip->info->ops->set_eeprom)
   4021		return -EOPNOTSUPP;
   4022
   4023	if (eeprom->magic != 0xc3ec4951)
   4024		return -EINVAL;
   4025
   4026	mv88e6xxx_reg_lock(chip);
   4027	err = chip->info->ops->set_eeprom(chip, eeprom, data);
   4028	mv88e6xxx_reg_unlock(chip);
   4029
   4030	return err;
   4031}
   4032
   4033static const struct mv88e6xxx_ops mv88e6085_ops = {
   4034	/* MV88E6XXX_FAMILY_6097 */
   4035	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4036	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4037	.irl_init_all = mv88e6352_g2_irl_init_all,
   4038	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
   4039	.phy_read = mv88e6185_phy_ppu_read,
   4040	.phy_write = mv88e6185_phy_ppu_write,
   4041	.port_set_link = mv88e6xxx_port_set_link,
   4042	.port_sync_link = mv88e6xxx_port_sync_link,
   4043	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   4044	.port_tag_remap = mv88e6095_port_tag_remap,
   4045	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4046	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4047	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4048	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4049	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   4050	.port_pause_limit = mv88e6097_port_pause_limit,
   4051	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4052	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4053	.port_get_cmode = mv88e6185_port_get_cmode,
   4054	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4055	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
   4056	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4057	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   4058	.stats_get_strings = mv88e6095_stats_get_strings,
   4059	.stats_get_stats = mv88e6095_stats_get_stats,
   4060	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   4061	.set_egress_port = mv88e6095_g1_set_egress_port,
   4062	.watchdog_ops = &mv88e6097_watchdog_ops,
   4063	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   4064	.pot_clear = mv88e6xxx_g2_pot_clear,
   4065	.ppu_enable = mv88e6185_g1_ppu_enable,
   4066	.ppu_disable = mv88e6185_g1_ppu_disable,
   4067	.reset = mv88e6185_g1_reset,
   4068	.rmu_disable = mv88e6085_g1_rmu_disable,
   4069	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   4070	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   4071	.stu_getnext = mv88e6352_g1_stu_getnext,
   4072	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   4073	.phylink_get_caps = mv88e6185_phylink_get_caps,
   4074	.set_max_frame_size = mv88e6185_g1_set_max_frame_size,
   4075};
   4076
   4077static const struct mv88e6xxx_ops mv88e6095_ops = {
   4078	/* MV88E6XXX_FAMILY_6095 */
   4079	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4080	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4081	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
   4082	.phy_read = mv88e6185_phy_ppu_read,
   4083	.phy_write = mv88e6185_phy_ppu_write,
   4084	.port_set_link = mv88e6xxx_port_set_link,
   4085	.port_sync_link = mv88e6185_port_sync_link,
   4086	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   4087	.port_set_frame_mode = mv88e6085_port_set_frame_mode,
   4088	.port_set_ucast_flood = mv88e6185_port_set_forward_unknown,
   4089	.port_set_mcast_flood = mv88e6185_port_set_default_forward,
   4090	.port_set_upstream_port = mv88e6095_port_set_upstream_port,
   4091	.port_get_cmode = mv88e6185_port_get_cmode,
   4092	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4093	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
   4094	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4095	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   4096	.stats_get_strings = mv88e6095_stats_get_strings,
   4097	.stats_get_stats = mv88e6095_stats_get_stats,
   4098	.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
   4099	.serdes_power = mv88e6185_serdes_power,
   4100	.serdes_get_lane = mv88e6185_serdes_get_lane,
   4101	.serdes_pcs_get_state = mv88e6185_serdes_pcs_get_state,
   4102	.ppu_enable = mv88e6185_g1_ppu_enable,
   4103	.ppu_disable = mv88e6185_g1_ppu_disable,
   4104	.reset = mv88e6185_g1_reset,
   4105	.vtu_getnext = mv88e6185_g1_vtu_getnext,
   4106	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
   4107	.phylink_get_caps = mv88e6095_phylink_get_caps,
   4108	.set_max_frame_size = mv88e6185_g1_set_max_frame_size,
   4109};
   4110
   4111static const struct mv88e6xxx_ops mv88e6097_ops = {
   4112	/* MV88E6XXX_FAMILY_6097 */
   4113	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4114	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4115	.irl_init_all = mv88e6352_g2_irl_init_all,
   4116	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4117	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4118	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4119	.port_set_link = mv88e6xxx_port_set_link,
   4120	.port_sync_link = mv88e6185_port_sync_link,
   4121	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   4122	.port_tag_remap = mv88e6095_port_tag_remap,
   4123	.port_set_policy = mv88e6352_port_set_policy,
   4124	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4125	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4126	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4127	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4128	.port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
   4129	.port_pause_limit = mv88e6097_port_pause_limit,
   4130	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4131	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4132	.port_get_cmode = mv88e6185_port_get_cmode,
   4133	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4134	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
   4135	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4136	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   4137	.stats_get_strings = mv88e6095_stats_get_strings,
   4138	.stats_get_stats = mv88e6095_stats_get_stats,
   4139	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   4140	.set_egress_port = mv88e6095_g1_set_egress_port,
   4141	.watchdog_ops = &mv88e6097_watchdog_ops,
   4142	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   4143	.serdes_power = mv88e6185_serdes_power,
   4144	.serdes_get_lane = mv88e6185_serdes_get_lane,
   4145	.serdes_pcs_get_state = mv88e6185_serdes_pcs_get_state,
   4146	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
   4147	.serdes_irq_enable = mv88e6097_serdes_irq_enable,
   4148	.serdes_irq_status = mv88e6097_serdes_irq_status,
   4149	.pot_clear = mv88e6xxx_g2_pot_clear,
   4150	.reset = mv88e6352_g1_reset,
   4151	.rmu_disable = mv88e6085_g1_rmu_disable,
   4152	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   4153	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   4154	.phylink_get_caps = mv88e6095_phylink_get_caps,
   4155	.stu_getnext = mv88e6352_g1_stu_getnext,
   4156	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   4157	.set_max_frame_size = mv88e6185_g1_set_max_frame_size,
   4158};
   4159
   4160static const struct mv88e6xxx_ops mv88e6123_ops = {
   4161	/* MV88E6XXX_FAMILY_6165 */
   4162	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4163	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4164	.irl_init_all = mv88e6352_g2_irl_init_all,
   4165	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4166	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4167	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4168	.port_set_link = mv88e6xxx_port_set_link,
   4169	.port_sync_link = mv88e6xxx_port_sync_link,
   4170	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   4171	.port_set_frame_mode = mv88e6085_port_set_frame_mode,
   4172	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4173	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4174	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4175	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4176	.port_get_cmode = mv88e6185_port_get_cmode,
   4177	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4178	.stats_snapshot = mv88e6320_g1_stats_snapshot,
   4179	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4180	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   4181	.stats_get_strings = mv88e6095_stats_get_strings,
   4182	.stats_get_stats = mv88e6095_stats_get_stats,
   4183	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   4184	.set_egress_port = mv88e6095_g1_set_egress_port,
   4185	.watchdog_ops = &mv88e6097_watchdog_ops,
   4186	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   4187	.pot_clear = mv88e6xxx_g2_pot_clear,
   4188	.reset = mv88e6352_g1_reset,
   4189	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   4190	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   4191	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   4192	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   4193	.stu_getnext = mv88e6352_g1_stu_getnext,
   4194	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   4195	.phylink_get_caps = mv88e6185_phylink_get_caps,
   4196	.set_max_frame_size = mv88e6185_g1_set_max_frame_size,
   4197};
   4198
   4199static const struct mv88e6xxx_ops mv88e6131_ops = {
   4200	/* MV88E6XXX_FAMILY_6185 */
   4201	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4202	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4203	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
   4204	.phy_read = mv88e6185_phy_ppu_read,
   4205	.phy_write = mv88e6185_phy_ppu_write,
   4206	.port_set_link = mv88e6xxx_port_set_link,
   4207	.port_sync_link = mv88e6xxx_port_sync_link,
   4208	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   4209	.port_tag_remap = mv88e6095_port_tag_remap,
   4210	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4211	.port_set_ucast_flood = mv88e6185_port_set_forward_unknown,
   4212	.port_set_mcast_flood = mv88e6185_port_set_default_forward,
   4213	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4214	.port_set_upstream_port = mv88e6095_port_set_upstream_port,
   4215	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   4216	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   4217	.port_pause_limit = mv88e6097_port_pause_limit,
   4218	.port_set_pause = mv88e6185_port_set_pause,
   4219	.port_get_cmode = mv88e6185_port_get_cmode,
   4220	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4221	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
   4222	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4223	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   4224	.stats_get_strings = mv88e6095_stats_get_strings,
   4225	.stats_get_stats = mv88e6095_stats_get_stats,
   4226	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   4227	.set_egress_port = mv88e6095_g1_set_egress_port,
   4228	.watchdog_ops = &mv88e6097_watchdog_ops,
   4229	.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
   4230	.ppu_enable = mv88e6185_g1_ppu_enable,
   4231	.set_cascade_port = mv88e6185_g1_set_cascade_port,
   4232	.ppu_disable = mv88e6185_g1_ppu_disable,
   4233	.reset = mv88e6185_g1_reset,
   4234	.vtu_getnext = mv88e6185_g1_vtu_getnext,
   4235	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
   4236	.phylink_get_caps = mv88e6185_phylink_get_caps,
   4237};
   4238
   4239static const struct mv88e6xxx_ops mv88e6141_ops = {
   4240	/* MV88E6XXX_FAMILY_6341 */
   4241	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4242	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4243	.irl_init_all = mv88e6352_g2_irl_init_all,
   4244	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
   4245	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
   4246	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4247	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4248	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4249	.port_set_link = mv88e6xxx_port_set_link,
   4250	.port_sync_link = mv88e6xxx_port_sync_link,
   4251	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
   4252	.port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
   4253	.port_max_speed_mode = mv88e6341_port_max_speed_mode,
   4254	.port_tag_remap = mv88e6095_port_tag_remap,
   4255	.port_set_policy = mv88e6352_port_set_policy,
   4256	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4257	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4258	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4259	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4260	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   4261	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   4262	.port_pause_limit = mv88e6097_port_pause_limit,
   4263	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4264	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4265	.port_get_cmode = mv88e6352_port_get_cmode,
   4266	.port_set_cmode = mv88e6341_port_set_cmode,
   4267	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4268	.stats_snapshot = mv88e6390_g1_stats_snapshot,
   4269	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
   4270	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
   4271	.stats_get_strings = mv88e6320_stats_get_strings,
   4272	.stats_get_stats = mv88e6390_stats_get_stats,
   4273	.set_cpu_port = mv88e6390_g1_set_cpu_port,
   4274	.set_egress_port = mv88e6390_g1_set_egress_port,
   4275	.watchdog_ops = &mv88e6390_watchdog_ops,
   4276	.mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
   4277	.pot_clear = mv88e6xxx_g2_pot_clear,
   4278	.reset = mv88e6352_g1_reset,
   4279	.rmu_disable = mv88e6390_g1_rmu_disable,
   4280	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   4281	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   4282	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   4283	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   4284	.stu_getnext = mv88e6352_g1_stu_getnext,
   4285	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   4286	.serdes_power = mv88e6390_serdes_power,
   4287	.serdes_get_lane = mv88e6341_serdes_get_lane,
   4288	/* Check status register pause & lpa register */
   4289	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
   4290	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
   4291	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
   4292	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
   4293	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
   4294	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
   4295	.serdes_irq_status = mv88e6390_serdes_irq_status,
   4296	.gpio_ops = &mv88e6352_gpio_ops,
   4297	.serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
   4298	.serdes_get_strings = mv88e6390_serdes_get_strings,
   4299	.serdes_get_stats = mv88e6390_serdes_get_stats,
   4300	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
   4301	.serdes_get_regs = mv88e6390_serdes_get_regs,
   4302	.phylink_get_caps = mv88e6341_phylink_get_caps,
   4303};
   4304
   4305static const struct mv88e6xxx_ops mv88e6161_ops = {
   4306	/* MV88E6XXX_FAMILY_6165 */
   4307	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4308	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4309	.irl_init_all = mv88e6352_g2_irl_init_all,
   4310	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4311	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4312	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4313	.port_set_link = mv88e6xxx_port_set_link,
   4314	.port_sync_link = mv88e6xxx_port_sync_link,
   4315	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   4316	.port_tag_remap = mv88e6095_port_tag_remap,
   4317	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4318	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4319	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4320	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4321	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   4322	.port_pause_limit = mv88e6097_port_pause_limit,
   4323	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4324	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4325	.port_get_cmode = mv88e6185_port_get_cmode,
   4326	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4327	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
   4328	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4329	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   4330	.stats_get_strings = mv88e6095_stats_get_strings,
   4331	.stats_get_stats = mv88e6095_stats_get_stats,
   4332	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   4333	.set_egress_port = mv88e6095_g1_set_egress_port,
   4334	.watchdog_ops = &mv88e6097_watchdog_ops,
   4335	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   4336	.pot_clear = mv88e6xxx_g2_pot_clear,
   4337	.reset = mv88e6352_g1_reset,
   4338	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   4339	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   4340	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   4341	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   4342	.stu_getnext = mv88e6352_g1_stu_getnext,
   4343	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   4344	.avb_ops = &mv88e6165_avb_ops,
   4345	.ptp_ops = &mv88e6165_ptp_ops,
   4346	.phylink_get_caps = mv88e6185_phylink_get_caps,
   4347	.set_max_frame_size = mv88e6185_g1_set_max_frame_size,
   4348};
   4349
   4350static const struct mv88e6xxx_ops mv88e6165_ops = {
   4351	/* MV88E6XXX_FAMILY_6165 */
   4352	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4353	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4354	.irl_init_all = mv88e6352_g2_irl_init_all,
   4355	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4356	.phy_read = mv88e6165_phy_read,
   4357	.phy_write = mv88e6165_phy_write,
   4358	.port_set_link = mv88e6xxx_port_set_link,
   4359	.port_sync_link = mv88e6xxx_port_sync_link,
   4360	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   4361	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4362	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4363	.port_get_cmode = mv88e6185_port_get_cmode,
   4364	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4365	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
   4366	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4367	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   4368	.stats_get_strings = mv88e6095_stats_get_strings,
   4369	.stats_get_stats = mv88e6095_stats_get_stats,
   4370	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   4371	.set_egress_port = mv88e6095_g1_set_egress_port,
   4372	.watchdog_ops = &mv88e6097_watchdog_ops,
   4373	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   4374	.pot_clear = mv88e6xxx_g2_pot_clear,
   4375	.reset = mv88e6352_g1_reset,
   4376	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   4377	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   4378	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   4379	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   4380	.stu_getnext = mv88e6352_g1_stu_getnext,
   4381	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   4382	.avb_ops = &mv88e6165_avb_ops,
   4383	.ptp_ops = &mv88e6165_ptp_ops,
   4384	.phylink_get_caps = mv88e6185_phylink_get_caps,
   4385};
   4386
   4387static const struct mv88e6xxx_ops mv88e6171_ops = {
   4388	/* MV88E6XXX_FAMILY_6351 */
   4389	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4390	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4391	.irl_init_all = mv88e6352_g2_irl_init_all,
   4392	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4393	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4394	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4395	.port_set_link = mv88e6xxx_port_set_link,
   4396	.port_sync_link = mv88e6xxx_port_sync_link,
   4397	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
   4398	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   4399	.port_tag_remap = mv88e6095_port_tag_remap,
   4400	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4401	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4402	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4403	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4404	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   4405	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   4406	.port_pause_limit = mv88e6097_port_pause_limit,
   4407	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4408	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4409	.port_get_cmode = mv88e6352_port_get_cmode,
   4410	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4411	.stats_snapshot = mv88e6320_g1_stats_snapshot,
   4412	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4413	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   4414	.stats_get_strings = mv88e6095_stats_get_strings,
   4415	.stats_get_stats = mv88e6095_stats_get_stats,
   4416	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   4417	.set_egress_port = mv88e6095_g1_set_egress_port,
   4418	.watchdog_ops = &mv88e6097_watchdog_ops,
   4419	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   4420	.pot_clear = mv88e6xxx_g2_pot_clear,
   4421	.reset = mv88e6352_g1_reset,
   4422	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   4423	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   4424	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   4425	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   4426	.stu_getnext = mv88e6352_g1_stu_getnext,
   4427	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   4428	.phylink_get_caps = mv88e6185_phylink_get_caps,
   4429};
   4430
   4431static const struct mv88e6xxx_ops mv88e6172_ops = {
   4432	/* MV88E6XXX_FAMILY_6352 */
   4433	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4434	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4435	.irl_init_all = mv88e6352_g2_irl_init_all,
   4436	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
   4437	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
   4438	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4439	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4440	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4441	.port_set_link = mv88e6xxx_port_set_link,
   4442	.port_sync_link = mv88e6xxx_port_sync_link,
   4443	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
   4444	.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
   4445	.port_tag_remap = mv88e6095_port_tag_remap,
   4446	.port_set_policy = mv88e6352_port_set_policy,
   4447	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4448	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4449	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4450	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4451	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   4452	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   4453	.port_pause_limit = mv88e6097_port_pause_limit,
   4454	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4455	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4456	.port_get_cmode = mv88e6352_port_get_cmode,
   4457	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4458	.stats_snapshot = mv88e6320_g1_stats_snapshot,
   4459	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4460	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   4461	.stats_get_strings = mv88e6095_stats_get_strings,
   4462	.stats_get_stats = mv88e6095_stats_get_stats,
   4463	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   4464	.set_egress_port = mv88e6095_g1_set_egress_port,
   4465	.watchdog_ops = &mv88e6097_watchdog_ops,
   4466	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   4467	.pot_clear = mv88e6xxx_g2_pot_clear,
   4468	.reset = mv88e6352_g1_reset,
   4469	.rmu_disable = mv88e6352_g1_rmu_disable,
   4470	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   4471	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   4472	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   4473	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   4474	.stu_getnext = mv88e6352_g1_stu_getnext,
   4475	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   4476	.serdes_get_lane = mv88e6352_serdes_get_lane,
   4477	.serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
   4478	.serdes_pcs_config = mv88e6352_serdes_pcs_config,
   4479	.serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
   4480	.serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
   4481	.serdes_power = mv88e6352_serdes_power,
   4482	.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
   4483	.serdes_get_regs = mv88e6352_serdes_get_regs,
   4484	.gpio_ops = &mv88e6352_gpio_ops,
   4485	.phylink_get_caps = mv88e6352_phylink_get_caps,
   4486};
   4487
   4488static const struct mv88e6xxx_ops mv88e6175_ops = {
   4489	/* MV88E6XXX_FAMILY_6351 */
   4490	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4491	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4492	.irl_init_all = mv88e6352_g2_irl_init_all,
   4493	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4494	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4495	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4496	.port_set_link = mv88e6xxx_port_set_link,
   4497	.port_sync_link = mv88e6xxx_port_sync_link,
   4498	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
   4499	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   4500	.port_tag_remap = mv88e6095_port_tag_remap,
   4501	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4502	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4503	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4504	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4505	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   4506	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   4507	.port_pause_limit = mv88e6097_port_pause_limit,
   4508	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4509	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4510	.port_get_cmode = mv88e6352_port_get_cmode,
   4511	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4512	.stats_snapshot = mv88e6320_g1_stats_snapshot,
   4513	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4514	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   4515	.stats_get_strings = mv88e6095_stats_get_strings,
   4516	.stats_get_stats = mv88e6095_stats_get_stats,
   4517	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   4518	.set_egress_port = mv88e6095_g1_set_egress_port,
   4519	.watchdog_ops = &mv88e6097_watchdog_ops,
   4520	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   4521	.pot_clear = mv88e6xxx_g2_pot_clear,
   4522	.reset = mv88e6352_g1_reset,
   4523	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   4524	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   4525	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   4526	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   4527	.stu_getnext = mv88e6352_g1_stu_getnext,
   4528	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   4529	.phylink_get_caps = mv88e6185_phylink_get_caps,
   4530};
   4531
   4532static const struct mv88e6xxx_ops mv88e6176_ops = {
   4533	/* MV88E6XXX_FAMILY_6352 */
   4534	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4535	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4536	.irl_init_all = mv88e6352_g2_irl_init_all,
   4537	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
   4538	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
   4539	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4540	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4541	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4542	.port_set_link = mv88e6xxx_port_set_link,
   4543	.port_sync_link = mv88e6xxx_port_sync_link,
   4544	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
   4545	.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
   4546	.port_tag_remap = mv88e6095_port_tag_remap,
   4547	.port_set_policy = mv88e6352_port_set_policy,
   4548	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4549	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4550	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4551	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4552	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   4553	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   4554	.port_pause_limit = mv88e6097_port_pause_limit,
   4555	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4556	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4557	.port_get_cmode = mv88e6352_port_get_cmode,
   4558	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4559	.stats_snapshot = mv88e6320_g1_stats_snapshot,
   4560	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4561	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   4562	.stats_get_strings = mv88e6095_stats_get_strings,
   4563	.stats_get_stats = mv88e6095_stats_get_stats,
   4564	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   4565	.set_egress_port = mv88e6095_g1_set_egress_port,
   4566	.watchdog_ops = &mv88e6097_watchdog_ops,
   4567	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   4568	.pot_clear = mv88e6xxx_g2_pot_clear,
   4569	.reset = mv88e6352_g1_reset,
   4570	.rmu_disable = mv88e6352_g1_rmu_disable,
   4571	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   4572	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   4573	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   4574	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   4575	.stu_getnext = mv88e6352_g1_stu_getnext,
   4576	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   4577	.serdes_get_lane = mv88e6352_serdes_get_lane,
   4578	.serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
   4579	.serdes_pcs_config = mv88e6352_serdes_pcs_config,
   4580	.serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
   4581	.serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
   4582	.serdes_power = mv88e6352_serdes_power,
   4583	.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
   4584	.serdes_irq_enable = mv88e6352_serdes_irq_enable,
   4585	.serdes_irq_status = mv88e6352_serdes_irq_status,
   4586	.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
   4587	.serdes_get_regs = mv88e6352_serdes_get_regs,
   4588	.serdes_set_tx_amplitude = mv88e6352_serdes_set_tx_amplitude,
   4589	.gpio_ops = &mv88e6352_gpio_ops,
   4590	.phylink_get_caps = mv88e6352_phylink_get_caps,
   4591};
   4592
   4593static const struct mv88e6xxx_ops mv88e6185_ops = {
   4594	/* MV88E6XXX_FAMILY_6185 */
   4595	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4596	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4597	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
   4598	.phy_read = mv88e6185_phy_ppu_read,
   4599	.phy_write = mv88e6185_phy_ppu_write,
   4600	.port_set_link = mv88e6xxx_port_set_link,
   4601	.port_sync_link = mv88e6185_port_sync_link,
   4602	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   4603	.port_set_frame_mode = mv88e6085_port_set_frame_mode,
   4604	.port_set_ucast_flood = mv88e6185_port_set_forward_unknown,
   4605	.port_set_mcast_flood = mv88e6185_port_set_default_forward,
   4606	.port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
   4607	.port_set_upstream_port = mv88e6095_port_set_upstream_port,
   4608	.port_set_pause = mv88e6185_port_set_pause,
   4609	.port_get_cmode = mv88e6185_port_get_cmode,
   4610	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4611	.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
   4612	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4613	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   4614	.stats_get_strings = mv88e6095_stats_get_strings,
   4615	.stats_get_stats = mv88e6095_stats_get_stats,
   4616	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   4617	.set_egress_port = mv88e6095_g1_set_egress_port,
   4618	.watchdog_ops = &mv88e6097_watchdog_ops,
   4619	.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
   4620	.serdes_power = mv88e6185_serdes_power,
   4621	.serdes_get_lane = mv88e6185_serdes_get_lane,
   4622	.serdes_pcs_get_state = mv88e6185_serdes_pcs_get_state,
   4623	.set_cascade_port = mv88e6185_g1_set_cascade_port,
   4624	.ppu_enable = mv88e6185_g1_ppu_enable,
   4625	.ppu_disable = mv88e6185_g1_ppu_disable,
   4626	.reset = mv88e6185_g1_reset,
   4627	.vtu_getnext = mv88e6185_g1_vtu_getnext,
   4628	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
   4629	.phylink_get_caps = mv88e6185_phylink_get_caps,
   4630	.set_max_frame_size = mv88e6185_g1_set_max_frame_size,
   4631};
   4632
   4633static const struct mv88e6xxx_ops mv88e6190_ops = {
   4634	/* MV88E6XXX_FAMILY_6390 */
   4635	.setup_errata = mv88e6390_setup_errata,
   4636	.irl_init_all = mv88e6390_g2_irl_init_all,
   4637	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
   4638	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
   4639	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4640	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4641	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4642	.port_set_link = mv88e6xxx_port_set_link,
   4643	.port_sync_link = mv88e6xxx_port_sync_link,
   4644	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
   4645	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
   4646	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
   4647	.port_tag_remap = mv88e6390_port_tag_remap,
   4648	.port_set_policy = mv88e6352_port_set_policy,
   4649	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4650	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4651	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4652	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4653	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   4654	.port_pause_limit = mv88e6390_port_pause_limit,
   4655	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4656	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4657	.port_get_cmode = mv88e6352_port_get_cmode,
   4658	.port_set_cmode = mv88e6390_port_set_cmode,
   4659	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4660	.stats_snapshot = mv88e6390_g1_stats_snapshot,
   4661	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
   4662	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
   4663	.stats_get_strings = mv88e6320_stats_get_strings,
   4664	.stats_get_stats = mv88e6390_stats_get_stats,
   4665	.set_cpu_port = mv88e6390_g1_set_cpu_port,
   4666	.set_egress_port = mv88e6390_g1_set_egress_port,
   4667	.watchdog_ops = &mv88e6390_watchdog_ops,
   4668	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
   4669	.pot_clear = mv88e6xxx_g2_pot_clear,
   4670	.reset = mv88e6352_g1_reset,
   4671	.rmu_disable = mv88e6390_g1_rmu_disable,
   4672	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   4673	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   4674	.vtu_getnext = mv88e6390_g1_vtu_getnext,
   4675	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
   4676	.stu_getnext = mv88e6390_g1_stu_getnext,
   4677	.stu_loadpurge = mv88e6390_g1_stu_loadpurge,
   4678	.serdes_power = mv88e6390_serdes_power,
   4679	.serdes_get_lane = mv88e6390_serdes_get_lane,
   4680	/* Check status register pause & lpa register */
   4681	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
   4682	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
   4683	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
   4684	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
   4685	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
   4686	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
   4687	.serdes_irq_status = mv88e6390_serdes_irq_status,
   4688	.serdes_get_strings = mv88e6390_serdes_get_strings,
   4689	.serdes_get_stats = mv88e6390_serdes_get_stats,
   4690	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
   4691	.serdes_get_regs = mv88e6390_serdes_get_regs,
   4692	.gpio_ops = &mv88e6352_gpio_ops,
   4693	.phylink_get_caps = mv88e6390_phylink_get_caps,
   4694};
   4695
   4696static const struct mv88e6xxx_ops mv88e6190x_ops = {
   4697	/* MV88E6XXX_FAMILY_6390 */
   4698	.setup_errata = mv88e6390_setup_errata,
   4699	.irl_init_all = mv88e6390_g2_irl_init_all,
   4700	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
   4701	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
   4702	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4703	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4704	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4705	.port_set_link = mv88e6xxx_port_set_link,
   4706	.port_sync_link = mv88e6xxx_port_sync_link,
   4707	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
   4708	.port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
   4709	.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
   4710	.port_tag_remap = mv88e6390_port_tag_remap,
   4711	.port_set_policy = mv88e6352_port_set_policy,
   4712	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4713	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4714	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4715	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4716	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   4717	.port_pause_limit = mv88e6390_port_pause_limit,
   4718	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4719	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4720	.port_get_cmode = mv88e6352_port_get_cmode,
   4721	.port_set_cmode = mv88e6390x_port_set_cmode,
   4722	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4723	.stats_snapshot = mv88e6390_g1_stats_snapshot,
   4724	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
   4725	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
   4726	.stats_get_strings = mv88e6320_stats_get_strings,
   4727	.stats_get_stats = mv88e6390_stats_get_stats,
   4728	.set_cpu_port = mv88e6390_g1_set_cpu_port,
   4729	.set_egress_port = mv88e6390_g1_set_egress_port,
   4730	.watchdog_ops = &mv88e6390_watchdog_ops,
   4731	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
   4732	.pot_clear = mv88e6xxx_g2_pot_clear,
   4733	.reset = mv88e6352_g1_reset,
   4734	.rmu_disable = mv88e6390_g1_rmu_disable,
   4735	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   4736	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   4737	.vtu_getnext = mv88e6390_g1_vtu_getnext,
   4738	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
   4739	.stu_getnext = mv88e6390_g1_stu_getnext,
   4740	.stu_loadpurge = mv88e6390_g1_stu_loadpurge,
   4741	.serdes_power = mv88e6390_serdes_power,
   4742	.serdes_get_lane = mv88e6390x_serdes_get_lane,
   4743	/* Check status register pause & lpa register */
   4744	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
   4745	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
   4746	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
   4747	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
   4748	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
   4749	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
   4750	.serdes_irq_status = mv88e6390_serdes_irq_status,
   4751	.serdes_get_strings = mv88e6390_serdes_get_strings,
   4752	.serdes_get_stats = mv88e6390_serdes_get_stats,
   4753	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
   4754	.serdes_get_regs = mv88e6390_serdes_get_regs,
   4755	.gpio_ops = &mv88e6352_gpio_ops,
   4756	.phylink_get_caps = mv88e6390x_phylink_get_caps,
   4757};
   4758
   4759static const struct mv88e6xxx_ops mv88e6191_ops = {
   4760	/* MV88E6XXX_FAMILY_6390 */
   4761	.setup_errata = mv88e6390_setup_errata,
   4762	.irl_init_all = mv88e6390_g2_irl_init_all,
   4763	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
   4764	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
   4765	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4766	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4767	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4768	.port_set_link = mv88e6xxx_port_set_link,
   4769	.port_sync_link = mv88e6xxx_port_sync_link,
   4770	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
   4771	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
   4772	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
   4773	.port_tag_remap = mv88e6390_port_tag_remap,
   4774	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4775	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4776	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4777	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4778	.port_pause_limit = mv88e6390_port_pause_limit,
   4779	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4780	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4781	.port_get_cmode = mv88e6352_port_get_cmode,
   4782	.port_set_cmode = mv88e6390_port_set_cmode,
   4783	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4784	.stats_snapshot = mv88e6390_g1_stats_snapshot,
   4785	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
   4786	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
   4787	.stats_get_strings = mv88e6320_stats_get_strings,
   4788	.stats_get_stats = mv88e6390_stats_get_stats,
   4789	.set_cpu_port = mv88e6390_g1_set_cpu_port,
   4790	.set_egress_port = mv88e6390_g1_set_egress_port,
   4791	.watchdog_ops = &mv88e6390_watchdog_ops,
   4792	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
   4793	.pot_clear = mv88e6xxx_g2_pot_clear,
   4794	.reset = mv88e6352_g1_reset,
   4795	.rmu_disable = mv88e6390_g1_rmu_disable,
   4796	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   4797	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   4798	.vtu_getnext = mv88e6390_g1_vtu_getnext,
   4799	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
   4800	.stu_getnext = mv88e6390_g1_stu_getnext,
   4801	.stu_loadpurge = mv88e6390_g1_stu_loadpurge,
   4802	.serdes_power = mv88e6390_serdes_power,
   4803	.serdes_get_lane = mv88e6390_serdes_get_lane,
   4804	/* Check status register pause & lpa register */
   4805	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
   4806	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
   4807	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
   4808	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
   4809	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
   4810	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
   4811	.serdes_irq_status = mv88e6390_serdes_irq_status,
   4812	.serdes_get_strings = mv88e6390_serdes_get_strings,
   4813	.serdes_get_stats = mv88e6390_serdes_get_stats,
   4814	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
   4815	.serdes_get_regs = mv88e6390_serdes_get_regs,
   4816	.avb_ops = &mv88e6390_avb_ops,
   4817	.ptp_ops = &mv88e6352_ptp_ops,
   4818	.phylink_get_caps = mv88e6390_phylink_get_caps,
   4819};
   4820
   4821static const struct mv88e6xxx_ops mv88e6240_ops = {
   4822	/* MV88E6XXX_FAMILY_6352 */
   4823	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4824	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4825	.irl_init_all = mv88e6352_g2_irl_init_all,
   4826	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
   4827	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
   4828	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4829	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4830	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4831	.port_set_link = mv88e6xxx_port_set_link,
   4832	.port_sync_link = mv88e6xxx_port_sync_link,
   4833	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
   4834	.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
   4835	.port_tag_remap = mv88e6095_port_tag_remap,
   4836	.port_set_policy = mv88e6352_port_set_policy,
   4837	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4838	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4839	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4840	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4841	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   4842	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   4843	.port_pause_limit = mv88e6097_port_pause_limit,
   4844	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4845	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4846	.port_get_cmode = mv88e6352_port_get_cmode,
   4847	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4848	.stats_snapshot = mv88e6320_g1_stats_snapshot,
   4849	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4850	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   4851	.stats_get_strings = mv88e6095_stats_get_strings,
   4852	.stats_get_stats = mv88e6095_stats_get_stats,
   4853	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   4854	.set_egress_port = mv88e6095_g1_set_egress_port,
   4855	.watchdog_ops = &mv88e6097_watchdog_ops,
   4856	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   4857	.pot_clear = mv88e6xxx_g2_pot_clear,
   4858	.reset = mv88e6352_g1_reset,
   4859	.rmu_disable = mv88e6352_g1_rmu_disable,
   4860	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   4861	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   4862	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   4863	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   4864	.stu_getnext = mv88e6352_g1_stu_getnext,
   4865	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   4866	.serdes_get_lane = mv88e6352_serdes_get_lane,
   4867	.serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
   4868	.serdes_pcs_config = mv88e6352_serdes_pcs_config,
   4869	.serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
   4870	.serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
   4871	.serdes_power = mv88e6352_serdes_power,
   4872	.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
   4873	.serdes_irq_enable = mv88e6352_serdes_irq_enable,
   4874	.serdes_irq_status = mv88e6352_serdes_irq_status,
   4875	.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
   4876	.serdes_get_regs = mv88e6352_serdes_get_regs,
   4877	.serdes_set_tx_amplitude = mv88e6352_serdes_set_tx_amplitude,
   4878	.gpio_ops = &mv88e6352_gpio_ops,
   4879	.avb_ops = &mv88e6352_avb_ops,
   4880	.ptp_ops = &mv88e6352_ptp_ops,
   4881	.phylink_get_caps = mv88e6352_phylink_get_caps,
   4882};
   4883
   4884static const struct mv88e6xxx_ops mv88e6250_ops = {
   4885	/* MV88E6XXX_FAMILY_6250 */
   4886	.ieee_pri_map = mv88e6250_g1_ieee_pri_map,
   4887	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4888	.irl_init_all = mv88e6352_g2_irl_init_all,
   4889	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
   4890	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
   4891	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4892	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4893	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4894	.port_set_link = mv88e6xxx_port_set_link,
   4895	.port_sync_link = mv88e6xxx_port_sync_link,
   4896	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
   4897	.port_set_speed_duplex = mv88e6250_port_set_speed_duplex,
   4898	.port_tag_remap = mv88e6095_port_tag_remap,
   4899	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4900	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4901	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4902	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4903	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   4904	.port_pause_limit = mv88e6097_port_pause_limit,
   4905	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4906	.stats_snapshot = mv88e6320_g1_stats_snapshot,
   4907	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   4908	.stats_get_sset_count = mv88e6250_stats_get_sset_count,
   4909	.stats_get_strings = mv88e6250_stats_get_strings,
   4910	.stats_get_stats = mv88e6250_stats_get_stats,
   4911	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   4912	.set_egress_port = mv88e6095_g1_set_egress_port,
   4913	.watchdog_ops = &mv88e6250_watchdog_ops,
   4914	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   4915	.pot_clear = mv88e6xxx_g2_pot_clear,
   4916	.reset = mv88e6250_g1_reset,
   4917	.vtu_getnext = mv88e6185_g1_vtu_getnext,
   4918	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
   4919	.avb_ops = &mv88e6352_avb_ops,
   4920	.ptp_ops = &mv88e6250_ptp_ops,
   4921	.phylink_get_caps = mv88e6250_phylink_get_caps,
   4922};
   4923
   4924static const struct mv88e6xxx_ops mv88e6290_ops = {
   4925	/* MV88E6XXX_FAMILY_6390 */
   4926	.setup_errata = mv88e6390_setup_errata,
   4927	.irl_init_all = mv88e6390_g2_irl_init_all,
   4928	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
   4929	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
   4930	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4931	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4932	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4933	.port_set_link = mv88e6xxx_port_set_link,
   4934	.port_sync_link = mv88e6xxx_port_sync_link,
   4935	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
   4936	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
   4937	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
   4938	.port_tag_remap = mv88e6390_port_tag_remap,
   4939	.port_set_policy = mv88e6352_port_set_policy,
   4940	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   4941	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   4942	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   4943	.port_set_ether_type = mv88e6351_port_set_ether_type,
   4944	.port_pause_limit = mv88e6390_port_pause_limit,
   4945	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   4946	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   4947	.port_get_cmode = mv88e6352_port_get_cmode,
   4948	.port_set_cmode = mv88e6390_port_set_cmode,
   4949	.port_setup_message_port = mv88e6xxx_setup_message_port,
   4950	.stats_snapshot = mv88e6390_g1_stats_snapshot,
   4951	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
   4952	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
   4953	.stats_get_strings = mv88e6320_stats_get_strings,
   4954	.stats_get_stats = mv88e6390_stats_get_stats,
   4955	.set_cpu_port = mv88e6390_g1_set_cpu_port,
   4956	.set_egress_port = mv88e6390_g1_set_egress_port,
   4957	.watchdog_ops = &mv88e6390_watchdog_ops,
   4958	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
   4959	.pot_clear = mv88e6xxx_g2_pot_clear,
   4960	.reset = mv88e6352_g1_reset,
   4961	.rmu_disable = mv88e6390_g1_rmu_disable,
   4962	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   4963	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   4964	.vtu_getnext = mv88e6390_g1_vtu_getnext,
   4965	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
   4966	.stu_getnext = mv88e6390_g1_stu_getnext,
   4967	.stu_loadpurge = mv88e6390_g1_stu_loadpurge,
   4968	.serdes_power = mv88e6390_serdes_power,
   4969	.serdes_get_lane = mv88e6390_serdes_get_lane,
   4970	/* Check status register pause & lpa register */
   4971	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
   4972	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
   4973	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
   4974	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
   4975	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
   4976	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
   4977	.serdes_irq_status = mv88e6390_serdes_irq_status,
   4978	.serdes_get_strings = mv88e6390_serdes_get_strings,
   4979	.serdes_get_stats = mv88e6390_serdes_get_stats,
   4980	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
   4981	.serdes_get_regs = mv88e6390_serdes_get_regs,
   4982	.gpio_ops = &mv88e6352_gpio_ops,
   4983	.avb_ops = &mv88e6390_avb_ops,
   4984	.ptp_ops = &mv88e6352_ptp_ops,
   4985	.phylink_get_caps = mv88e6390_phylink_get_caps,
   4986};
   4987
   4988static const struct mv88e6xxx_ops mv88e6320_ops = {
   4989	/* MV88E6XXX_FAMILY_6320 */
   4990	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   4991	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   4992	.irl_init_all = mv88e6352_g2_irl_init_all,
   4993	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
   4994	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
   4995	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   4996	.phy_read = mv88e6xxx_g2_smi_phy_read,
   4997	.phy_write = mv88e6xxx_g2_smi_phy_write,
   4998	.port_set_link = mv88e6xxx_port_set_link,
   4999	.port_sync_link = mv88e6xxx_port_sync_link,
   5000	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   5001	.port_tag_remap = mv88e6095_port_tag_remap,
   5002	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   5003	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   5004	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   5005	.port_set_ether_type = mv88e6351_port_set_ether_type,
   5006	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   5007	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   5008	.port_pause_limit = mv88e6097_port_pause_limit,
   5009	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   5010	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   5011	.port_get_cmode = mv88e6352_port_get_cmode,
   5012	.port_setup_message_port = mv88e6xxx_setup_message_port,
   5013	.stats_snapshot = mv88e6320_g1_stats_snapshot,
   5014	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   5015	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
   5016	.stats_get_strings = mv88e6320_stats_get_strings,
   5017	.stats_get_stats = mv88e6320_stats_get_stats,
   5018	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   5019	.set_egress_port = mv88e6095_g1_set_egress_port,
   5020	.watchdog_ops = &mv88e6390_watchdog_ops,
   5021	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   5022	.pot_clear = mv88e6xxx_g2_pot_clear,
   5023	.reset = mv88e6352_g1_reset,
   5024	.vtu_getnext = mv88e6185_g1_vtu_getnext,
   5025	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
   5026	.gpio_ops = &mv88e6352_gpio_ops,
   5027	.avb_ops = &mv88e6352_avb_ops,
   5028	.ptp_ops = &mv88e6352_ptp_ops,
   5029	.phylink_get_caps = mv88e6185_phylink_get_caps,
   5030};
   5031
   5032static const struct mv88e6xxx_ops mv88e6321_ops = {
   5033	/* MV88E6XXX_FAMILY_6320 */
   5034	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   5035	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   5036	.irl_init_all = mv88e6352_g2_irl_init_all,
   5037	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
   5038	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
   5039	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   5040	.phy_read = mv88e6xxx_g2_smi_phy_read,
   5041	.phy_write = mv88e6xxx_g2_smi_phy_write,
   5042	.port_set_link = mv88e6xxx_port_set_link,
   5043	.port_sync_link = mv88e6xxx_port_sync_link,
   5044	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   5045	.port_tag_remap = mv88e6095_port_tag_remap,
   5046	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   5047	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   5048	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   5049	.port_set_ether_type = mv88e6351_port_set_ether_type,
   5050	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   5051	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   5052	.port_pause_limit = mv88e6097_port_pause_limit,
   5053	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   5054	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   5055	.port_get_cmode = mv88e6352_port_get_cmode,
   5056	.port_setup_message_port = mv88e6xxx_setup_message_port,
   5057	.stats_snapshot = mv88e6320_g1_stats_snapshot,
   5058	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   5059	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
   5060	.stats_get_strings = mv88e6320_stats_get_strings,
   5061	.stats_get_stats = mv88e6320_stats_get_stats,
   5062	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   5063	.set_egress_port = mv88e6095_g1_set_egress_port,
   5064	.watchdog_ops = &mv88e6390_watchdog_ops,
   5065	.reset = mv88e6352_g1_reset,
   5066	.vtu_getnext = mv88e6185_g1_vtu_getnext,
   5067	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
   5068	.gpio_ops = &mv88e6352_gpio_ops,
   5069	.avb_ops = &mv88e6352_avb_ops,
   5070	.ptp_ops = &mv88e6352_ptp_ops,
   5071	.phylink_get_caps = mv88e6185_phylink_get_caps,
   5072};
   5073
   5074static const struct mv88e6xxx_ops mv88e6341_ops = {
   5075	/* MV88E6XXX_FAMILY_6341 */
   5076	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   5077	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   5078	.irl_init_all = mv88e6352_g2_irl_init_all,
   5079	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
   5080	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
   5081	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   5082	.phy_read = mv88e6xxx_g2_smi_phy_read,
   5083	.phy_write = mv88e6xxx_g2_smi_phy_write,
   5084	.port_set_link = mv88e6xxx_port_set_link,
   5085	.port_sync_link = mv88e6xxx_port_sync_link,
   5086	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
   5087	.port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
   5088	.port_max_speed_mode = mv88e6341_port_max_speed_mode,
   5089	.port_tag_remap = mv88e6095_port_tag_remap,
   5090	.port_set_policy = mv88e6352_port_set_policy,
   5091	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   5092	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   5093	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   5094	.port_set_ether_type = mv88e6351_port_set_ether_type,
   5095	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   5096	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   5097	.port_pause_limit = mv88e6097_port_pause_limit,
   5098	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   5099	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   5100	.port_get_cmode = mv88e6352_port_get_cmode,
   5101	.port_set_cmode = mv88e6341_port_set_cmode,
   5102	.port_setup_message_port = mv88e6xxx_setup_message_port,
   5103	.stats_snapshot = mv88e6390_g1_stats_snapshot,
   5104	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
   5105	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
   5106	.stats_get_strings = mv88e6320_stats_get_strings,
   5107	.stats_get_stats = mv88e6390_stats_get_stats,
   5108	.set_cpu_port = mv88e6390_g1_set_cpu_port,
   5109	.set_egress_port = mv88e6390_g1_set_egress_port,
   5110	.watchdog_ops = &mv88e6390_watchdog_ops,
   5111	.mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
   5112	.pot_clear = mv88e6xxx_g2_pot_clear,
   5113	.reset = mv88e6352_g1_reset,
   5114	.rmu_disable = mv88e6390_g1_rmu_disable,
   5115	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   5116	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   5117	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   5118	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   5119	.stu_getnext = mv88e6352_g1_stu_getnext,
   5120	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   5121	.serdes_power = mv88e6390_serdes_power,
   5122	.serdes_get_lane = mv88e6341_serdes_get_lane,
   5123	/* Check status register pause & lpa register */
   5124	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
   5125	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
   5126	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
   5127	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
   5128	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
   5129	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
   5130	.serdes_irq_status = mv88e6390_serdes_irq_status,
   5131	.gpio_ops = &mv88e6352_gpio_ops,
   5132	.avb_ops = &mv88e6390_avb_ops,
   5133	.ptp_ops = &mv88e6352_ptp_ops,
   5134	.serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
   5135	.serdes_get_strings = mv88e6390_serdes_get_strings,
   5136	.serdes_get_stats = mv88e6390_serdes_get_stats,
   5137	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
   5138	.serdes_get_regs = mv88e6390_serdes_get_regs,
   5139	.phylink_get_caps = mv88e6341_phylink_get_caps,
   5140};
   5141
   5142static const struct mv88e6xxx_ops mv88e6350_ops = {
   5143	/* MV88E6XXX_FAMILY_6351 */
   5144	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   5145	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   5146	.irl_init_all = mv88e6352_g2_irl_init_all,
   5147	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   5148	.phy_read = mv88e6xxx_g2_smi_phy_read,
   5149	.phy_write = mv88e6xxx_g2_smi_phy_write,
   5150	.port_set_link = mv88e6xxx_port_set_link,
   5151	.port_sync_link = mv88e6xxx_port_sync_link,
   5152	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
   5153	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   5154	.port_tag_remap = mv88e6095_port_tag_remap,
   5155	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   5156	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   5157	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   5158	.port_set_ether_type = mv88e6351_port_set_ether_type,
   5159	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   5160	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   5161	.port_pause_limit = mv88e6097_port_pause_limit,
   5162	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   5163	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   5164	.port_get_cmode = mv88e6352_port_get_cmode,
   5165	.port_setup_message_port = mv88e6xxx_setup_message_port,
   5166	.stats_snapshot = mv88e6320_g1_stats_snapshot,
   5167	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   5168	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   5169	.stats_get_strings = mv88e6095_stats_get_strings,
   5170	.stats_get_stats = mv88e6095_stats_get_stats,
   5171	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   5172	.set_egress_port = mv88e6095_g1_set_egress_port,
   5173	.watchdog_ops = &mv88e6097_watchdog_ops,
   5174	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   5175	.pot_clear = mv88e6xxx_g2_pot_clear,
   5176	.reset = mv88e6352_g1_reset,
   5177	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   5178	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   5179	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   5180	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   5181	.stu_getnext = mv88e6352_g1_stu_getnext,
   5182	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   5183	.phylink_get_caps = mv88e6185_phylink_get_caps,
   5184};
   5185
   5186static const struct mv88e6xxx_ops mv88e6351_ops = {
   5187	/* MV88E6XXX_FAMILY_6351 */
   5188	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   5189	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   5190	.irl_init_all = mv88e6352_g2_irl_init_all,
   5191	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   5192	.phy_read = mv88e6xxx_g2_smi_phy_read,
   5193	.phy_write = mv88e6xxx_g2_smi_phy_write,
   5194	.port_set_link = mv88e6xxx_port_set_link,
   5195	.port_sync_link = mv88e6xxx_port_sync_link,
   5196	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
   5197	.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
   5198	.port_tag_remap = mv88e6095_port_tag_remap,
   5199	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   5200	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   5201	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   5202	.port_set_ether_type = mv88e6351_port_set_ether_type,
   5203	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   5204	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   5205	.port_pause_limit = mv88e6097_port_pause_limit,
   5206	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   5207	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   5208	.port_get_cmode = mv88e6352_port_get_cmode,
   5209	.port_setup_message_port = mv88e6xxx_setup_message_port,
   5210	.stats_snapshot = mv88e6320_g1_stats_snapshot,
   5211	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   5212	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   5213	.stats_get_strings = mv88e6095_stats_get_strings,
   5214	.stats_get_stats = mv88e6095_stats_get_stats,
   5215	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   5216	.set_egress_port = mv88e6095_g1_set_egress_port,
   5217	.watchdog_ops = &mv88e6097_watchdog_ops,
   5218	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   5219	.pot_clear = mv88e6xxx_g2_pot_clear,
   5220	.reset = mv88e6352_g1_reset,
   5221	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   5222	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   5223	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   5224	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   5225	.stu_getnext = mv88e6352_g1_stu_getnext,
   5226	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   5227	.avb_ops = &mv88e6352_avb_ops,
   5228	.ptp_ops = &mv88e6352_ptp_ops,
   5229	.phylink_get_caps = mv88e6185_phylink_get_caps,
   5230};
   5231
   5232static const struct mv88e6xxx_ops mv88e6352_ops = {
   5233	/* MV88E6XXX_FAMILY_6352 */
   5234	.ieee_pri_map = mv88e6085_g1_ieee_pri_map,
   5235	.ip_pri_map = mv88e6085_g1_ip_pri_map,
   5236	.irl_init_all = mv88e6352_g2_irl_init_all,
   5237	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
   5238	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
   5239	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   5240	.phy_read = mv88e6xxx_g2_smi_phy_read,
   5241	.phy_write = mv88e6xxx_g2_smi_phy_write,
   5242	.port_set_link = mv88e6xxx_port_set_link,
   5243	.port_sync_link = mv88e6xxx_port_sync_link,
   5244	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
   5245	.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
   5246	.port_tag_remap = mv88e6095_port_tag_remap,
   5247	.port_set_policy = mv88e6352_port_set_policy,
   5248	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   5249	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   5250	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   5251	.port_set_ether_type = mv88e6351_port_set_ether_type,
   5252	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   5253	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   5254	.port_pause_limit = mv88e6097_port_pause_limit,
   5255	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   5256	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   5257	.port_get_cmode = mv88e6352_port_get_cmode,
   5258	.port_setup_message_port = mv88e6xxx_setup_message_port,
   5259	.stats_snapshot = mv88e6320_g1_stats_snapshot,
   5260	.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
   5261	.stats_get_sset_count = mv88e6095_stats_get_sset_count,
   5262	.stats_get_strings = mv88e6095_stats_get_strings,
   5263	.stats_get_stats = mv88e6095_stats_get_stats,
   5264	.set_cpu_port = mv88e6095_g1_set_cpu_port,
   5265	.set_egress_port = mv88e6095_g1_set_egress_port,
   5266	.watchdog_ops = &mv88e6097_watchdog_ops,
   5267	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
   5268	.pot_clear = mv88e6xxx_g2_pot_clear,
   5269	.reset = mv88e6352_g1_reset,
   5270	.rmu_disable = mv88e6352_g1_rmu_disable,
   5271	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   5272	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   5273	.vtu_getnext = mv88e6352_g1_vtu_getnext,
   5274	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
   5275	.stu_getnext = mv88e6352_g1_stu_getnext,
   5276	.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
   5277	.serdes_get_lane = mv88e6352_serdes_get_lane,
   5278	.serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
   5279	.serdes_pcs_config = mv88e6352_serdes_pcs_config,
   5280	.serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
   5281	.serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
   5282	.serdes_power = mv88e6352_serdes_power,
   5283	.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
   5284	.serdes_irq_enable = mv88e6352_serdes_irq_enable,
   5285	.serdes_irq_status = mv88e6352_serdes_irq_status,
   5286	.gpio_ops = &mv88e6352_gpio_ops,
   5287	.avb_ops = &mv88e6352_avb_ops,
   5288	.ptp_ops = &mv88e6352_ptp_ops,
   5289	.serdes_get_sset_count = mv88e6352_serdes_get_sset_count,
   5290	.serdes_get_strings = mv88e6352_serdes_get_strings,
   5291	.serdes_get_stats = mv88e6352_serdes_get_stats,
   5292	.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
   5293	.serdes_get_regs = mv88e6352_serdes_get_regs,
   5294	.serdes_set_tx_amplitude = mv88e6352_serdes_set_tx_amplitude,
   5295	.phylink_get_caps = mv88e6352_phylink_get_caps,
   5296};
   5297
   5298static const struct mv88e6xxx_ops mv88e6390_ops = {
   5299	/* MV88E6XXX_FAMILY_6390 */
   5300	.setup_errata = mv88e6390_setup_errata,
   5301	.irl_init_all = mv88e6390_g2_irl_init_all,
   5302	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
   5303	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
   5304	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   5305	.phy_read = mv88e6xxx_g2_smi_phy_read,
   5306	.phy_write = mv88e6xxx_g2_smi_phy_write,
   5307	.port_set_link = mv88e6xxx_port_set_link,
   5308	.port_sync_link = mv88e6xxx_port_sync_link,
   5309	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
   5310	.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
   5311	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
   5312	.port_tag_remap = mv88e6390_port_tag_remap,
   5313	.port_set_policy = mv88e6352_port_set_policy,
   5314	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   5315	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   5316	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   5317	.port_set_ether_type = mv88e6351_port_set_ether_type,
   5318	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   5319	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   5320	.port_pause_limit = mv88e6390_port_pause_limit,
   5321	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   5322	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   5323	.port_get_cmode = mv88e6352_port_get_cmode,
   5324	.port_set_cmode = mv88e6390_port_set_cmode,
   5325	.port_setup_message_port = mv88e6xxx_setup_message_port,
   5326	.stats_snapshot = mv88e6390_g1_stats_snapshot,
   5327	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
   5328	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
   5329	.stats_get_strings = mv88e6320_stats_get_strings,
   5330	.stats_get_stats = mv88e6390_stats_get_stats,
   5331	.set_cpu_port = mv88e6390_g1_set_cpu_port,
   5332	.set_egress_port = mv88e6390_g1_set_egress_port,
   5333	.watchdog_ops = &mv88e6390_watchdog_ops,
   5334	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
   5335	.pot_clear = mv88e6xxx_g2_pot_clear,
   5336	.reset = mv88e6352_g1_reset,
   5337	.rmu_disable = mv88e6390_g1_rmu_disable,
   5338	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   5339	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   5340	.vtu_getnext = mv88e6390_g1_vtu_getnext,
   5341	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
   5342	.stu_getnext = mv88e6390_g1_stu_getnext,
   5343	.stu_loadpurge = mv88e6390_g1_stu_loadpurge,
   5344	.serdes_power = mv88e6390_serdes_power,
   5345	.serdes_get_lane = mv88e6390_serdes_get_lane,
   5346	/* Check status register pause & lpa register */
   5347	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
   5348	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
   5349	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
   5350	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
   5351	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
   5352	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
   5353	.serdes_irq_status = mv88e6390_serdes_irq_status,
   5354	.gpio_ops = &mv88e6352_gpio_ops,
   5355	.avb_ops = &mv88e6390_avb_ops,
   5356	.ptp_ops = &mv88e6352_ptp_ops,
   5357	.serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
   5358	.serdes_get_strings = mv88e6390_serdes_get_strings,
   5359	.serdes_get_stats = mv88e6390_serdes_get_stats,
   5360	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
   5361	.serdes_get_regs = mv88e6390_serdes_get_regs,
   5362	.phylink_get_caps = mv88e6390_phylink_get_caps,
   5363};
   5364
   5365static const struct mv88e6xxx_ops mv88e6390x_ops = {
   5366	/* MV88E6XXX_FAMILY_6390 */
   5367	.setup_errata = mv88e6390_setup_errata,
   5368	.irl_init_all = mv88e6390_g2_irl_init_all,
   5369	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
   5370	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
   5371	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   5372	.phy_read = mv88e6xxx_g2_smi_phy_read,
   5373	.phy_write = mv88e6xxx_g2_smi_phy_write,
   5374	.port_set_link = mv88e6xxx_port_set_link,
   5375	.port_sync_link = mv88e6xxx_port_sync_link,
   5376	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
   5377	.port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
   5378	.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
   5379	.port_tag_remap = mv88e6390_port_tag_remap,
   5380	.port_set_policy = mv88e6352_port_set_policy,
   5381	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   5382	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   5383	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   5384	.port_set_ether_type = mv88e6351_port_set_ether_type,
   5385	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   5386	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   5387	.port_pause_limit = mv88e6390_port_pause_limit,
   5388	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   5389	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   5390	.port_get_cmode = mv88e6352_port_get_cmode,
   5391	.port_set_cmode = mv88e6390x_port_set_cmode,
   5392	.port_setup_message_port = mv88e6xxx_setup_message_port,
   5393	.stats_snapshot = mv88e6390_g1_stats_snapshot,
   5394	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
   5395	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
   5396	.stats_get_strings = mv88e6320_stats_get_strings,
   5397	.stats_get_stats = mv88e6390_stats_get_stats,
   5398	.set_cpu_port = mv88e6390_g1_set_cpu_port,
   5399	.set_egress_port = mv88e6390_g1_set_egress_port,
   5400	.watchdog_ops = &mv88e6390_watchdog_ops,
   5401	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
   5402	.pot_clear = mv88e6xxx_g2_pot_clear,
   5403	.reset = mv88e6352_g1_reset,
   5404	.rmu_disable = mv88e6390_g1_rmu_disable,
   5405	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   5406	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   5407	.vtu_getnext = mv88e6390_g1_vtu_getnext,
   5408	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
   5409	.stu_getnext = mv88e6390_g1_stu_getnext,
   5410	.stu_loadpurge = mv88e6390_g1_stu_loadpurge,
   5411	.serdes_power = mv88e6390_serdes_power,
   5412	.serdes_get_lane = mv88e6390x_serdes_get_lane,
   5413	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
   5414	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
   5415	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
   5416	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
   5417	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
   5418	.serdes_irq_enable = mv88e6390_serdes_irq_enable,
   5419	.serdes_irq_status = mv88e6390_serdes_irq_status,
   5420	.serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
   5421	.serdes_get_strings = mv88e6390_serdes_get_strings,
   5422	.serdes_get_stats = mv88e6390_serdes_get_stats,
   5423	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
   5424	.serdes_get_regs = mv88e6390_serdes_get_regs,
   5425	.gpio_ops = &mv88e6352_gpio_ops,
   5426	.avb_ops = &mv88e6390_avb_ops,
   5427	.ptp_ops = &mv88e6352_ptp_ops,
   5428	.phylink_get_caps = mv88e6390x_phylink_get_caps,
   5429};
   5430
   5431static const struct mv88e6xxx_ops mv88e6393x_ops = {
   5432	/* MV88E6XXX_FAMILY_6393 */
   5433	.setup_errata = mv88e6393x_serdes_setup_errata,
   5434	.irl_init_all = mv88e6390_g2_irl_init_all,
   5435	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
   5436	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
   5437	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
   5438	.phy_read = mv88e6xxx_g2_smi_phy_read,
   5439	.phy_write = mv88e6xxx_g2_smi_phy_write,
   5440	.port_set_link = mv88e6xxx_port_set_link,
   5441	.port_sync_link = mv88e6xxx_port_sync_link,
   5442	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
   5443	.port_set_speed_duplex = mv88e6393x_port_set_speed_duplex,
   5444	.port_max_speed_mode = mv88e6393x_port_max_speed_mode,
   5445	.port_tag_remap = mv88e6390_port_tag_remap,
   5446	.port_set_policy = mv88e6393x_port_set_policy,
   5447	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
   5448	.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
   5449	.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
   5450	.port_set_ether_type = mv88e6393x_port_set_ether_type,
   5451	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
   5452	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
   5453	.port_pause_limit = mv88e6390_port_pause_limit,
   5454	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
   5455	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
   5456	.port_get_cmode = mv88e6352_port_get_cmode,
   5457	.port_set_cmode = mv88e6393x_port_set_cmode,
   5458	.port_setup_message_port = mv88e6xxx_setup_message_port,
   5459	.port_set_upstream_port = mv88e6393x_port_set_upstream_port,
   5460	.stats_snapshot = mv88e6390_g1_stats_snapshot,
   5461	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
   5462	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
   5463	.stats_get_strings = mv88e6320_stats_get_strings,
   5464	.stats_get_stats = mv88e6390_stats_get_stats,
   5465	/* .set_cpu_port is missing because this family does not support a global
   5466	 * CPU port, only per port CPU port which is set via
   5467	 * .port_set_upstream_port method.
   5468	 */
   5469	.set_egress_port = mv88e6393x_set_egress_port,
   5470	.watchdog_ops = &mv88e6390_watchdog_ops,
   5471	.mgmt_rsvd2cpu = mv88e6393x_port_mgmt_rsvd2cpu,
   5472	.pot_clear = mv88e6xxx_g2_pot_clear,
   5473	.reset = mv88e6352_g1_reset,
   5474	.rmu_disable = mv88e6390_g1_rmu_disable,
   5475	.atu_get_hash = mv88e6165_g1_atu_get_hash,
   5476	.atu_set_hash = mv88e6165_g1_atu_set_hash,
   5477	.vtu_getnext = mv88e6390_g1_vtu_getnext,
   5478	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
   5479	.stu_getnext = mv88e6390_g1_stu_getnext,
   5480	.stu_loadpurge = mv88e6390_g1_stu_loadpurge,
   5481	.serdes_power = mv88e6393x_serdes_power,
   5482	.serdes_get_lane = mv88e6393x_serdes_get_lane,
   5483	.serdes_pcs_get_state = mv88e6393x_serdes_pcs_get_state,
   5484	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
   5485	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
   5486	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
   5487	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
   5488	.serdes_irq_enable = mv88e6393x_serdes_irq_enable,
   5489	.serdes_irq_status = mv88e6393x_serdes_irq_status,
   5490	/* TODO: serdes stats */
   5491	.gpio_ops = &mv88e6352_gpio_ops,
   5492	.avb_ops = &mv88e6390_avb_ops,
   5493	.ptp_ops = &mv88e6352_ptp_ops,
   5494	.phylink_get_caps = mv88e6393x_phylink_get_caps,
   5495};
   5496
   5497static const struct mv88e6xxx_info mv88e6xxx_table[] = {
   5498	[MV88E6085] = {
   5499		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6085,
   5500		.family = MV88E6XXX_FAMILY_6097,
   5501		.name = "Marvell 88E6085",
   5502		.num_databases = 4096,
   5503		.num_macs = 8192,
   5504		.num_ports = 10,
   5505		.num_internal_phys = 5,
   5506		.max_vid = 4095,
   5507		.max_sid = 63,
   5508		.port_base_addr = 0x10,
   5509		.phy_base_addr = 0x0,
   5510		.global1_addr = 0x1b,
   5511		.global2_addr = 0x1c,
   5512		.age_time_coeff = 15000,
   5513		.g1_irqs = 8,
   5514		.g2_irqs = 10,
   5515		.atu_move_port_mask = 0xf,
   5516		.pvt = true,
   5517		.multi_chip = true,
   5518		.ops = &mv88e6085_ops,
   5519	},
   5520
   5521	[MV88E6095] = {
   5522		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6095,
   5523		.family = MV88E6XXX_FAMILY_6095,
   5524		.name = "Marvell 88E6095/88E6095F",
   5525		.num_databases = 256,
   5526		.num_macs = 8192,
   5527		.num_ports = 11,
   5528		.num_internal_phys = 0,
   5529		.max_vid = 4095,
   5530		.port_base_addr = 0x10,
   5531		.phy_base_addr = 0x0,
   5532		.global1_addr = 0x1b,
   5533		.global2_addr = 0x1c,
   5534		.age_time_coeff = 15000,
   5535		.g1_irqs = 8,
   5536		.atu_move_port_mask = 0xf,
   5537		.multi_chip = true,
   5538		.ops = &mv88e6095_ops,
   5539	},
   5540
   5541	[MV88E6097] = {
   5542		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6097,
   5543		.family = MV88E6XXX_FAMILY_6097,
   5544		.name = "Marvell 88E6097/88E6097F",
   5545		.num_databases = 4096,
   5546		.num_macs = 8192,
   5547		.num_ports = 11,
   5548		.num_internal_phys = 8,
   5549		.max_vid = 4095,
   5550		.max_sid = 63,
   5551		.port_base_addr = 0x10,
   5552		.phy_base_addr = 0x0,
   5553		.global1_addr = 0x1b,
   5554		.global2_addr = 0x1c,
   5555		.age_time_coeff = 15000,
   5556		.g1_irqs = 8,
   5557		.g2_irqs = 10,
   5558		.atu_move_port_mask = 0xf,
   5559		.pvt = true,
   5560		.multi_chip = true,
   5561		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   5562		.ops = &mv88e6097_ops,
   5563	},
   5564
   5565	[MV88E6123] = {
   5566		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6123,
   5567		.family = MV88E6XXX_FAMILY_6165,
   5568		.name = "Marvell 88E6123",
   5569		.num_databases = 4096,
   5570		.num_macs = 1024,
   5571		.num_ports = 3,
   5572		.num_internal_phys = 5,
   5573		.max_vid = 4095,
   5574		.max_sid = 63,
   5575		.port_base_addr = 0x10,
   5576		.phy_base_addr = 0x0,
   5577		.global1_addr = 0x1b,
   5578		.global2_addr = 0x1c,
   5579		.age_time_coeff = 15000,
   5580		.g1_irqs = 9,
   5581		.g2_irqs = 10,
   5582		.atu_move_port_mask = 0xf,
   5583		.pvt = true,
   5584		.multi_chip = true,
   5585		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   5586		.ops = &mv88e6123_ops,
   5587	},
   5588
   5589	[MV88E6131] = {
   5590		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6131,
   5591		.family = MV88E6XXX_FAMILY_6185,
   5592		.name = "Marvell 88E6131",
   5593		.num_databases = 256,
   5594		.num_macs = 8192,
   5595		.num_ports = 8,
   5596		.num_internal_phys = 0,
   5597		.max_vid = 4095,
   5598		.port_base_addr = 0x10,
   5599		.phy_base_addr = 0x0,
   5600		.global1_addr = 0x1b,
   5601		.global2_addr = 0x1c,
   5602		.age_time_coeff = 15000,
   5603		.g1_irqs = 9,
   5604		.atu_move_port_mask = 0xf,
   5605		.multi_chip = true,
   5606		.ops = &mv88e6131_ops,
   5607	},
   5608
   5609	[MV88E6141] = {
   5610		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
   5611		.family = MV88E6XXX_FAMILY_6341,
   5612		.name = "Marvell 88E6141",
   5613		.num_databases = 4096,
   5614		.num_macs = 2048,
   5615		.num_ports = 6,
   5616		.num_internal_phys = 5,
   5617		.num_gpio = 11,
   5618		.max_vid = 4095,
   5619		.max_sid = 63,
   5620		.port_base_addr = 0x10,
   5621		.phy_base_addr = 0x10,
   5622		.global1_addr = 0x1b,
   5623		.global2_addr = 0x1c,
   5624		.age_time_coeff = 3750,
   5625		.atu_move_port_mask = 0x1f,
   5626		.g1_irqs = 9,
   5627		.g2_irqs = 10,
   5628		.pvt = true,
   5629		.multi_chip = true,
   5630		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   5631		.ops = &mv88e6141_ops,
   5632	},
   5633
   5634	[MV88E6161] = {
   5635		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6161,
   5636		.family = MV88E6XXX_FAMILY_6165,
   5637		.name = "Marvell 88E6161",
   5638		.num_databases = 4096,
   5639		.num_macs = 1024,
   5640		.num_ports = 6,
   5641		.num_internal_phys = 5,
   5642		.max_vid = 4095,
   5643		.max_sid = 63,
   5644		.port_base_addr = 0x10,
   5645		.phy_base_addr = 0x0,
   5646		.global1_addr = 0x1b,
   5647		.global2_addr = 0x1c,
   5648		.age_time_coeff = 15000,
   5649		.g1_irqs = 9,
   5650		.g2_irqs = 10,
   5651		.atu_move_port_mask = 0xf,
   5652		.pvt = true,
   5653		.multi_chip = true,
   5654		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   5655		.ptp_support = true,
   5656		.ops = &mv88e6161_ops,
   5657	},
   5658
   5659	[MV88E6165] = {
   5660		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6165,
   5661		.family = MV88E6XXX_FAMILY_6165,
   5662		.name = "Marvell 88E6165",
   5663		.num_databases = 4096,
   5664		.num_macs = 8192,
   5665		.num_ports = 6,
   5666		.num_internal_phys = 0,
   5667		.max_vid = 4095,
   5668		.max_sid = 63,
   5669		.port_base_addr = 0x10,
   5670		.phy_base_addr = 0x0,
   5671		.global1_addr = 0x1b,
   5672		.global2_addr = 0x1c,
   5673		.age_time_coeff = 15000,
   5674		.g1_irqs = 9,
   5675		.g2_irqs = 10,
   5676		.atu_move_port_mask = 0xf,
   5677		.pvt = true,
   5678		.multi_chip = true,
   5679		.ptp_support = true,
   5680		.ops = &mv88e6165_ops,
   5681	},
   5682
   5683	[MV88E6171] = {
   5684		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6171,
   5685		.family = MV88E6XXX_FAMILY_6351,
   5686		.name = "Marvell 88E6171",
   5687		.num_databases = 4096,
   5688		.num_macs = 8192,
   5689		.num_ports = 7,
   5690		.num_internal_phys = 5,
   5691		.max_vid = 4095,
   5692		.max_sid = 63,
   5693		.port_base_addr = 0x10,
   5694		.phy_base_addr = 0x0,
   5695		.global1_addr = 0x1b,
   5696		.global2_addr = 0x1c,
   5697		.age_time_coeff = 15000,
   5698		.g1_irqs = 9,
   5699		.g2_irqs = 10,
   5700		.atu_move_port_mask = 0xf,
   5701		.pvt = true,
   5702		.multi_chip = true,
   5703		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   5704		.ops = &mv88e6171_ops,
   5705	},
   5706
   5707	[MV88E6172] = {
   5708		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6172,
   5709		.family = MV88E6XXX_FAMILY_6352,
   5710		.name = "Marvell 88E6172",
   5711		.num_databases = 4096,
   5712		.num_macs = 8192,
   5713		.num_ports = 7,
   5714		.num_internal_phys = 5,
   5715		.num_gpio = 15,
   5716		.max_vid = 4095,
   5717		.max_sid = 63,
   5718		.port_base_addr = 0x10,
   5719		.phy_base_addr = 0x0,
   5720		.global1_addr = 0x1b,
   5721		.global2_addr = 0x1c,
   5722		.age_time_coeff = 15000,
   5723		.g1_irqs = 9,
   5724		.g2_irqs = 10,
   5725		.atu_move_port_mask = 0xf,
   5726		.pvt = true,
   5727		.multi_chip = true,
   5728		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   5729		.ops = &mv88e6172_ops,
   5730	},
   5731
   5732	[MV88E6175] = {
   5733		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6175,
   5734		.family = MV88E6XXX_FAMILY_6351,
   5735		.name = "Marvell 88E6175",
   5736		.num_databases = 4096,
   5737		.num_macs = 8192,
   5738		.num_ports = 7,
   5739		.num_internal_phys = 5,
   5740		.max_vid = 4095,
   5741		.max_sid = 63,
   5742		.port_base_addr = 0x10,
   5743		.phy_base_addr = 0x0,
   5744		.global1_addr = 0x1b,
   5745		.global2_addr = 0x1c,
   5746		.age_time_coeff = 15000,
   5747		.g1_irqs = 9,
   5748		.g2_irqs = 10,
   5749		.atu_move_port_mask = 0xf,
   5750		.pvt = true,
   5751		.multi_chip = true,
   5752		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   5753		.ops = &mv88e6175_ops,
   5754	},
   5755
   5756	[MV88E6176] = {
   5757		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6176,
   5758		.family = MV88E6XXX_FAMILY_6352,
   5759		.name = "Marvell 88E6176",
   5760		.num_databases = 4096,
   5761		.num_macs = 8192,
   5762		.num_ports = 7,
   5763		.num_internal_phys = 5,
   5764		.num_gpio = 15,
   5765		.max_vid = 4095,
   5766		.max_sid = 63,
   5767		.port_base_addr = 0x10,
   5768		.phy_base_addr = 0x0,
   5769		.global1_addr = 0x1b,
   5770		.global2_addr = 0x1c,
   5771		.age_time_coeff = 15000,
   5772		.g1_irqs = 9,
   5773		.g2_irqs = 10,
   5774		.atu_move_port_mask = 0xf,
   5775		.pvt = true,
   5776		.multi_chip = true,
   5777		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   5778		.ops = &mv88e6176_ops,
   5779	},
   5780
   5781	[MV88E6185] = {
   5782		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6185,
   5783		.family = MV88E6XXX_FAMILY_6185,
   5784		.name = "Marvell 88E6185",
   5785		.num_databases = 256,
   5786		.num_macs = 8192,
   5787		.num_ports = 10,
   5788		.num_internal_phys = 0,
   5789		.max_vid = 4095,
   5790		.port_base_addr = 0x10,
   5791		.phy_base_addr = 0x0,
   5792		.global1_addr = 0x1b,
   5793		.global2_addr = 0x1c,
   5794		.age_time_coeff = 15000,
   5795		.g1_irqs = 8,
   5796		.atu_move_port_mask = 0xf,
   5797		.multi_chip = true,
   5798		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   5799		.ops = &mv88e6185_ops,
   5800	},
   5801
   5802	[MV88E6190] = {
   5803		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190,
   5804		.family = MV88E6XXX_FAMILY_6390,
   5805		.name = "Marvell 88E6190",
   5806		.num_databases = 4096,
   5807		.num_macs = 16384,
   5808		.num_ports = 11,	/* 10 + Z80 */
   5809		.num_internal_phys = 9,
   5810		.num_gpio = 16,
   5811		.max_vid = 8191,
   5812		.max_sid = 63,
   5813		.port_base_addr = 0x0,
   5814		.phy_base_addr = 0x0,
   5815		.global1_addr = 0x1b,
   5816		.global2_addr = 0x1c,
   5817		.age_time_coeff = 3750,
   5818		.g1_irqs = 9,
   5819		.g2_irqs = 14,
   5820		.pvt = true,
   5821		.multi_chip = true,
   5822		.atu_move_port_mask = 0x1f,
   5823		.ops = &mv88e6190_ops,
   5824	},
   5825
   5826	[MV88E6190X] = {
   5827		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190X,
   5828		.family = MV88E6XXX_FAMILY_6390,
   5829		.name = "Marvell 88E6190X",
   5830		.num_databases = 4096,
   5831		.num_macs = 16384,
   5832		.num_ports = 11,	/* 10 + Z80 */
   5833		.num_internal_phys = 9,
   5834		.num_gpio = 16,
   5835		.max_vid = 8191,
   5836		.max_sid = 63,
   5837		.port_base_addr = 0x0,
   5838		.phy_base_addr = 0x0,
   5839		.global1_addr = 0x1b,
   5840		.global2_addr = 0x1c,
   5841		.age_time_coeff = 3750,
   5842		.g1_irqs = 9,
   5843		.g2_irqs = 14,
   5844		.atu_move_port_mask = 0x1f,
   5845		.pvt = true,
   5846		.multi_chip = true,
   5847		.ops = &mv88e6190x_ops,
   5848	},
   5849
   5850	[MV88E6191] = {
   5851		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6191,
   5852		.family = MV88E6XXX_FAMILY_6390,
   5853		.name = "Marvell 88E6191",
   5854		.num_databases = 4096,
   5855		.num_macs = 16384,
   5856		.num_ports = 11,	/* 10 + Z80 */
   5857		.num_internal_phys = 9,
   5858		.max_vid = 8191,
   5859		.max_sid = 63,
   5860		.port_base_addr = 0x0,
   5861		.phy_base_addr = 0x0,
   5862		.global1_addr = 0x1b,
   5863		.global2_addr = 0x1c,
   5864		.age_time_coeff = 3750,
   5865		.g1_irqs = 9,
   5866		.g2_irqs = 14,
   5867		.atu_move_port_mask = 0x1f,
   5868		.pvt = true,
   5869		.multi_chip = true,
   5870		.ptp_support = true,
   5871		.ops = &mv88e6191_ops,
   5872	},
   5873
   5874	[MV88E6191X] = {
   5875		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6191X,
   5876		.family = MV88E6XXX_FAMILY_6393,
   5877		.name = "Marvell 88E6191X",
   5878		.num_databases = 4096,
   5879		.num_ports = 11,	/* 10 + Z80 */
   5880		.num_internal_phys = 9,
   5881		.max_vid = 8191,
   5882		.max_sid = 63,
   5883		.port_base_addr = 0x0,
   5884		.phy_base_addr = 0x0,
   5885		.global1_addr = 0x1b,
   5886		.global2_addr = 0x1c,
   5887		.age_time_coeff = 3750,
   5888		.g1_irqs = 10,
   5889		.g2_irqs = 14,
   5890		.atu_move_port_mask = 0x1f,
   5891		.pvt = true,
   5892		.multi_chip = true,
   5893		.ptp_support = true,
   5894		.ops = &mv88e6393x_ops,
   5895	},
   5896
   5897	[MV88E6193X] = {
   5898		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6193X,
   5899		.family = MV88E6XXX_FAMILY_6393,
   5900		.name = "Marvell 88E6193X",
   5901		.num_databases = 4096,
   5902		.num_ports = 11,	/* 10 + Z80 */
   5903		.num_internal_phys = 9,
   5904		.max_vid = 8191,
   5905		.max_sid = 63,
   5906		.port_base_addr = 0x0,
   5907		.phy_base_addr = 0x0,
   5908		.global1_addr = 0x1b,
   5909		.global2_addr = 0x1c,
   5910		.age_time_coeff = 3750,
   5911		.g1_irqs = 10,
   5912		.g2_irqs = 14,
   5913		.atu_move_port_mask = 0x1f,
   5914		.pvt = true,
   5915		.multi_chip = true,
   5916		.ptp_support = true,
   5917		.ops = &mv88e6393x_ops,
   5918	},
   5919
   5920	[MV88E6220] = {
   5921		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6220,
   5922		.family = MV88E6XXX_FAMILY_6250,
   5923		.name = "Marvell 88E6220",
   5924		.num_databases = 64,
   5925
   5926		/* Ports 2-4 are not routed to pins
   5927		 * => usable ports 0, 1, 5, 6
   5928		 */
   5929		.num_ports = 7,
   5930		.num_internal_phys = 2,
   5931		.invalid_port_mask = BIT(2) | BIT(3) | BIT(4),
   5932		.max_vid = 4095,
   5933		.port_base_addr = 0x08,
   5934		.phy_base_addr = 0x00,
   5935		.global1_addr = 0x0f,
   5936		.global2_addr = 0x07,
   5937		.age_time_coeff = 15000,
   5938		.g1_irqs = 9,
   5939		.g2_irqs = 10,
   5940		.atu_move_port_mask = 0xf,
   5941		.dual_chip = true,
   5942		.ptp_support = true,
   5943		.ops = &mv88e6250_ops,
   5944	},
   5945
   5946	[MV88E6240] = {
   5947		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6240,
   5948		.family = MV88E6XXX_FAMILY_6352,
   5949		.name = "Marvell 88E6240",
   5950		.num_databases = 4096,
   5951		.num_macs = 8192,
   5952		.num_ports = 7,
   5953		.num_internal_phys = 5,
   5954		.num_gpio = 15,
   5955		.max_vid = 4095,
   5956		.max_sid = 63,
   5957		.port_base_addr = 0x10,
   5958		.phy_base_addr = 0x0,
   5959		.global1_addr = 0x1b,
   5960		.global2_addr = 0x1c,
   5961		.age_time_coeff = 15000,
   5962		.g1_irqs = 9,
   5963		.g2_irqs = 10,
   5964		.atu_move_port_mask = 0xf,
   5965		.pvt = true,
   5966		.multi_chip = true,
   5967		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   5968		.ptp_support = true,
   5969		.ops = &mv88e6240_ops,
   5970	},
   5971
   5972	[MV88E6250] = {
   5973		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6250,
   5974		.family = MV88E6XXX_FAMILY_6250,
   5975		.name = "Marvell 88E6250",
   5976		.num_databases = 64,
   5977		.num_ports = 7,
   5978		.num_internal_phys = 5,
   5979		.max_vid = 4095,
   5980		.port_base_addr = 0x08,
   5981		.phy_base_addr = 0x00,
   5982		.global1_addr = 0x0f,
   5983		.global2_addr = 0x07,
   5984		.age_time_coeff = 15000,
   5985		.g1_irqs = 9,
   5986		.g2_irqs = 10,
   5987		.atu_move_port_mask = 0xf,
   5988		.dual_chip = true,
   5989		.ptp_support = true,
   5990		.ops = &mv88e6250_ops,
   5991	},
   5992
   5993	[MV88E6290] = {
   5994		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6290,
   5995		.family = MV88E6XXX_FAMILY_6390,
   5996		.name = "Marvell 88E6290",
   5997		.num_databases = 4096,
   5998		.num_ports = 11,	/* 10 + Z80 */
   5999		.num_internal_phys = 9,
   6000		.num_gpio = 16,
   6001		.max_vid = 8191,
   6002		.max_sid = 63,
   6003		.port_base_addr = 0x0,
   6004		.phy_base_addr = 0x0,
   6005		.global1_addr = 0x1b,
   6006		.global2_addr = 0x1c,
   6007		.age_time_coeff = 3750,
   6008		.g1_irqs = 9,
   6009		.g2_irqs = 14,
   6010		.atu_move_port_mask = 0x1f,
   6011		.pvt = true,
   6012		.multi_chip = true,
   6013		.ptp_support = true,
   6014		.ops = &mv88e6290_ops,
   6015	},
   6016
   6017	[MV88E6320] = {
   6018		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6320,
   6019		.family = MV88E6XXX_FAMILY_6320,
   6020		.name = "Marvell 88E6320",
   6021		.num_databases = 4096,
   6022		.num_macs = 8192,
   6023		.num_ports = 7,
   6024		.num_internal_phys = 5,
   6025		.num_gpio = 15,
   6026		.max_vid = 4095,
   6027		.port_base_addr = 0x10,
   6028		.phy_base_addr = 0x0,
   6029		.global1_addr = 0x1b,
   6030		.global2_addr = 0x1c,
   6031		.age_time_coeff = 15000,
   6032		.g1_irqs = 8,
   6033		.g2_irqs = 10,
   6034		.atu_move_port_mask = 0xf,
   6035		.pvt = true,
   6036		.multi_chip = true,
   6037		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   6038		.ptp_support = true,
   6039		.ops = &mv88e6320_ops,
   6040	},
   6041
   6042	[MV88E6321] = {
   6043		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6321,
   6044		.family = MV88E6XXX_FAMILY_6320,
   6045		.name = "Marvell 88E6321",
   6046		.num_databases = 4096,
   6047		.num_macs = 8192,
   6048		.num_ports = 7,
   6049		.num_internal_phys = 5,
   6050		.num_gpio = 15,
   6051		.max_vid = 4095,
   6052		.port_base_addr = 0x10,
   6053		.phy_base_addr = 0x0,
   6054		.global1_addr = 0x1b,
   6055		.global2_addr = 0x1c,
   6056		.age_time_coeff = 15000,
   6057		.g1_irqs = 8,
   6058		.g2_irqs = 10,
   6059		.atu_move_port_mask = 0xf,
   6060		.multi_chip = true,
   6061		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   6062		.ptp_support = true,
   6063		.ops = &mv88e6321_ops,
   6064	},
   6065
   6066	[MV88E6341] = {
   6067		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
   6068		.family = MV88E6XXX_FAMILY_6341,
   6069		.name = "Marvell 88E6341",
   6070		.num_databases = 4096,
   6071		.num_macs = 2048,
   6072		.num_internal_phys = 5,
   6073		.num_ports = 6,
   6074		.num_gpio = 11,
   6075		.max_vid = 4095,
   6076		.max_sid = 63,
   6077		.port_base_addr = 0x10,
   6078		.phy_base_addr = 0x10,
   6079		.global1_addr = 0x1b,
   6080		.global2_addr = 0x1c,
   6081		.age_time_coeff = 3750,
   6082		.atu_move_port_mask = 0x1f,
   6083		.g1_irqs = 9,
   6084		.g2_irqs = 10,
   6085		.pvt = true,
   6086		.multi_chip = true,
   6087		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   6088		.ptp_support = true,
   6089		.ops = &mv88e6341_ops,
   6090	},
   6091
   6092	[MV88E6350] = {
   6093		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6350,
   6094		.family = MV88E6XXX_FAMILY_6351,
   6095		.name = "Marvell 88E6350",
   6096		.num_databases = 4096,
   6097		.num_macs = 8192,
   6098		.num_ports = 7,
   6099		.num_internal_phys = 5,
   6100		.max_vid = 4095,
   6101		.max_sid = 63,
   6102		.port_base_addr = 0x10,
   6103		.phy_base_addr = 0x0,
   6104		.global1_addr = 0x1b,
   6105		.global2_addr = 0x1c,
   6106		.age_time_coeff = 15000,
   6107		.g1_irqs = 9,
   6108		.g2_irqs = 10,
   6109		.atu_move_port_mask = 0xf,
   6110		.pvt = true,
   6111		.multi_chip = true,
   6112		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   6113		.ops = &mv88e6350_ops,
   6114	},
   6115
   6116	[MV88E6351] = {
   6117		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6351,
   6118		.family = MV88E6XXX_FAMILY_6351,
   6119		.name = "Marvell 88E6351",
   6120		.num_databases = 4096,
   6121		.num_macs = 8192,
   6122		.num_ports = 7,
   6123		.num_internal_phys = 5,
   6124		.max_vid = 4095,
   6125		.max_sid = 63,
   6126		.port_base_addr = 0x10,
   6127		.phy_base_addr = 0x0,
   6128		.global1_addr = 0x1b,
   6129		.global2_addr = 0x1c,
   6130		.age_time_coeff = 15000,
   6131		.g1_irqs = 9,
   6132		.g2_irqs = 10,
   6133		.atu_move_port_mask = 0xf,
   6134		.pvt = true,
   6135		.multi_chip = true,
   6136		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   6137		.ops = &mv88e6351_ops,
   6138	},
   6139
   6140	[MV88E6352] = {
   6141		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6352,
   6142		.family = MV88E6XXX_FAMILY_6352,
   6143		.name = "Marvell 88E6352",
   6144		.num_databases = 4096,
   6145		.num_macs = 8192,
   6146		.num_ports = 7,
   6147		.num_internal_phys = 5,
   6148		.num_gpio = 15,
   6149		.max_vid = 4095,
   6150		.max_sid = 63,
   6151		.port_base_addr = 0x10,
   6152		.phy_base_addr = 0x0,
   6153		.global1_addr = 0x1b,
   6154		.global2_addr = 0x1c,
   6155		.age_time_coeff = 15000,
   6156		.g1_irqs = 9,
   6157		.g2_irqs = 10,
   6158		.atu_move_port_mask = 0xf,
   6159		.pvt = true,
   6160		.multi_chip = true,
   6161		.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
   6162		.ptp_support = true,
   6163		.ops = &mv88e6352_ops,
   6164	},
   6165	[MV88E6390] = {
   6166		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
   6167		.family = MV88E6XXX_FAMILY_6390,
   6168		.name = "Marvell 88E6390",
   6169		.num_databases = 4096,
   6170		.num_macs = 16384,
   6171		.num_ports = 11,	/* 10 + Z80 */
   6172		.num_internal_phys = 9,
   6173		.num_gpio = 16,
   6174		.max_vid = 8191,
   6175		.max_sid = 63,
   6176		.port_base_addr = 0x0,
   6177		.phy_base_addr = 0x0,
   6178		.global1_addr = 0x1b,
   6179		.global2_addr = 0x1c,
   6180		.age_time_coeff = 3750,
   6181		.g1_irqs = 9,
   6182		.g2_irqs = 14,
   6183		.atu_move_port_mask = 0x1f,
   6184		.pvt = true,
   6185		.multi_chip = true,
   6186		.edsa_support = MV88E6XXX_EDSA_UNDOCUMENTED,
   6187		.ptp_support = true,
   6188		.ops = &mv88e6390_ops,
   6189	},
   6190	[MV88E6390X] = {
   6191		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390X,
   6192		.family = MV88E6XXX_FAMILY_6390,
   6193		.name = "Marvell 88E6390X",
   6194		.num_databases = 4096,
   6195		.num_macs = 16384,
   6196		.num_ports = 11,	/* 10 + Z80 */
   6197		.num_internal_phys = 9,
   6198		.num_gpio = 16,
   6199		.max_vid = 8191,
   6200		.max_sid = 63,
   6201		.port_base_addr = 0x0,
   6202		.phy_base_addr = 0x0,
   6203		.global1_addr = 0x1b,
   6204		.global2_addr = 0x1c,
   6205		.age_time_coeff = 3750,
   6206		.g1_irqs = 9,
   6207		.g2_irqs = 14,
   6208		.atu_move_port_mask = 0x1f,
   6209		.pvt = true,
   6210		.multi_chip = true,
   6211		.edsa_support = MV88E6XXX_EDSA_UNDOCUMENTED,
   6212		.ptp_support = true,
   6213		.ops = &mv88e6390x_ops,
   6214	},
   6215
   6216	[MV88E6393X] = {
   6217		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6393X,
   6218		.family = MV88E6XXX_FAMILY_6393,
   6219		.name = "Marvell 88E6393X",
   6220		.num_databases = 4096,
   6221		.num_ports = 11,	/* 10 + Z80 */
   6222		.num_internal_phys = 9,
   6223		.max_vid = 8191,
   6224		.max_sid = 63,
   6225		.port_base_addr = 0x0,
   6226		.phy_base_addr = 0x0,
   6227		.global1_addr = 0x1b,
   6228		.global2_addr = 0x1c,
   6229		.age_time_coeff = 3750,
   6230		.g1_irqs = 10,
   6231		.g2_irqs = 14,
   6232		.atu_move_port_mask = 0x1f,
   6233		.pvt = true,
   6234		.multi_chip = true,
   6235		.ptp_support = true,
   6236		.ops = &mv88e6393x_ops,
   6237	},
   6238};
   6239
   6240static const struct mv88e6xxx_info *mv88e6xxx_lookup_info(unsigned int prod_num)
   6241{
   6242	int i;
   6243
   6244	for (i = 0; i < ARRAY_SIZE(mv88e6xxx_table); ++i)
   6245		if (mv88e6xxx_table[i].prod_num == prod_num)
   6246			return &mv88e6xxx_table[i];
   6247
   6248	return NULL;
   6249}
   6250
   6251static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip)
   6252{
   6253	const struct mv88e6xxx_info *info;
   6254	unsigned int prod_num, rev;
   6255	u16 id;
   6256	int err;
   6257
   6258	mv88e6xxx_reg_lock(chip);
   6259	err = mv88e6xxx_port_read(chip, 0, MV88E6XXX_PORT_SWITCH_ID, &id);
   6260	mv88e6xxx_reg_unlock(chip);
   6261	if (err)
   6262		return err;
   6263
   6264	prod_num = id & MV88E6XXX_PORT_SWITCH_ID_PROD_MASK;
   6265	rev = id & MV88E6XXX_PORT_SWITCH_ID_REV_MASK;
   6266
   6267	info = mv88e6xxx_lookup_info(prod_num);
   6268	if (!info)
   6269		return -ENODEV;
   6270
   6271	/* Update the compatible info with the probed one */
   6272	chip->info = info;
   6273
   6274	dev_info(chip->dev, "switch 0x%x detected: %s, revision %u\n",
   6275		 chip->info->prod_num, chip->info->name, rev);
   6276
   6277	return 0;
   6278}
   6279
   6280static int mv88e6xxx_single_chip_detect(struct mv88e6xxx_chip *chip,
   6281					struct mdio_device *mdiodev)
   6282{
   6283	int err;
   6284
   6285	/* dual_chip takes precedence over single/multi-chip modes */
   6286	if (chip->info->dual_chip)
   6287		return -EINVAL;
   6288
   6289	/* If the mdio addr is 16 indicating the first port address of a switch
   6290	 * (e.g. mv88e6*41) in single chip addressing mode the device may be
   6291	 * configured in single chip addressing mode. Setup the smi access as
   6292	 * single chip addressing mode and attempt to detect the model of the
   6293	 * switch, if this fails the device is not configured in single chip
   6294	 * addressing mode.
   6295	 */
   6296	if (mdiodev->addr != 16)
   6297		return -EINVAL;
   6298
   6299	err = mv88e6xxx_smi_init(chip, mdiodev->bus, 0);
   6300	if (err)
   6301		return err;
   6302
   6303	return mv88e6xxx_detect(chip);
   6304}
   6305
   6306static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev)
   6307{
   6308	struct mv88e6xxx_chip *chip;
   6309
   6310	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
   6311	if (!chip)
   6312		return NULL;
   6313
   6314	chip->dev = dev;
   6315
   6316	mutex_init(&chip->reg_lock);
   6317	INIT_LIST_HEAD(&chip->mdios);
   6318	idr_init(&chip->policies);
   6319	INIT_LIST_HEAD(&chip->msts);
   6320
   6321	return chip;
   6322}
   6323
   6324static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds,
   6325							int port,
   6326							enum dsa_tag_protocol m)
   6327{
   6328	struct mv88e6xxx_chip *chip = ds->priv;
   6329
   6330	return chip->tag_protocol;
   6331}
   6332
   6333static int mv88e6xxx_change_tag_protocol(struct dsa_switch *ds,
   6334					 enum dsa_tag_protocol proto)
   6335{
   6336	struct mv88e6xxx_chip *chip = ds->priv;
   6337	enum dsa_tag_protocol old_protocol;
   6338	struct dsa_port *cpu_dp;
   6339	int err;
   6340
   6341	switch (proto) {
   6342	case DSA_TAG_PROTO_EDSA:
   6343		switch (chip->info->edsa_support) {
   6344		case MV88E6XXX_EDSA_UNSUPPORTED:
   6345			return -EPROTONOSUPPORT;
   6346		case MV88E6XXX_EDSA_UNDOCUMENTED:
   6347			dev_warn(chip->dev, "Relying on undocumented EDSA tagging behavior\n");
   6348			fallthrough;
   6349		case MV88E6XXX_EDSA_SUPPORTED:
   6350			break;
   6351		}
   6352		break;
   6353	case DSA_TAG_PROTO_DSA:
   6354		break;
   6355	default:
   6356		return -EPROTONOSUPPORT;
   6357	}
   6358
   6359	old_protocol = chip->tag_protocol;
   6360	chip->tag_protocol = proto;
   6361
   6362	mv88e6xxx_reg_lock(chip);
   6363	dsa_switch_for_each_cpu_port(cpu_dp, ds) {
   6364		err = mv88e6xxx_setup_port_mode(chip, cpu_dp->index);
   6365		if (err) {
   6366			mv88e6xxx_reg_unlock(chip);
   6367			goto unwind;
   6368		}
   6369	}
   6370	mv88e6xxx_reg_unlock(chip);
   6371
   6372	return 0;
   6373
   6374unwind:
   6375	chip->tag_protocol = old_protocol;
   6376
   6377	mv88e6xxx_reg_lock(chip);
   6378	dsa_switch_for_each_cpu_port_continue_reverse(cpu_dp, ds)
   6379		mv88e6xxx_setup_port_mode(chip, cpu_dp->index);
   6380	mv88e6xxx_reg_unlock(chip);
   6381
   6382	return err;
   6383}
   6384
   6385static int mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port,
   6386				  const struct switchdev_obj_port_mdb *mdb,
   6387				  struct dsa_db db)
   6388{
   6389	struct mv88e6xxx_chip *chip = ds->priv;
   6390	int err;
   6391
   6392	mv88e6xxx_reg_lock(chip);
   6393	err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
   6394					   MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC);
   6395	mv88e6xxx_reg_unlock(chip);
   6396
   6397	return err;
   6398}
   6399
   6400static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port,
   6401				  const struct switchdev_obj_port_mdb *mdb,
   6402				  struct dsa_db db)
   6403{
   6404	struct mv88e6xxx_chip *chip = ds->priv;
   6405	int err;
   6406
   6407	mv88e6xxx_reg_lock(chip);
   6408	err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid, 0);
   6409	mv88e6xxx_reg_unlock(chip);
   6410
   6411	return err;
   6412}
   6413
   6414static int mv88e6xxx_port_mirror_add(struct dsa_switch *ds, int port,
   6415				     struct dsa_mall_mirror_tc_entry *mirror,
   6416				     bool ingress,
   6417				     struct netlink_ext_ack *extack)
   6418{
   6419	enum mv88e6xxx_egress_direction direction = ingress ?
   6420						MV88E6XXX_EGRESS_DIR_INGRESS :
   6421						MV88E6XXX_EGRESS_DIR_EGRESS;
   6422	struct mv88e6xxx_chip *chip = ds->priv;
   6423	bool other_mirrors = false;
   6424	int i;
   6425	int err;
   6426
   6427	mutex_lock(&chip->reg_lock);
   6428	if ((ingress ? chip->ingress_dest_port : chip->egress_dest_port) !=
   6429	    mirror->to_local_port) {
   6430		for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
   6431			other_mirrors |= ingress ?
   6432					 chip->ports[i].mirror_ingress :
   6433					 chip->ports[i].mirror_egress;
   6434
   6435		/* Can't change egress port when other mirror is active */
   6436		if (other_mirrors) {
   6437			err = -EBUSY;
   6438			goto out;
   6439		}
   6440
   6441		err = mv88e6xxx_set_egress_port(chip, direction,
   6442						mirror->to_local_port);
   6443		if (err)
   6444			goto out;
   6445	}
   6446
   6447	err = mv88e6xxx_port_set_mirror(chip, port, direction, true);
   6448out:
   6449	mutex_unlock(&chip->reg_lock);
   6450
   6451	return err;
   6452}
   6453
   6454static void mv88e6xxx_port_mirror_del(struct dsa_switch *ds, int port,
   6455				      struct dsa_mall_mirror_tc_entry *mirror)
   6456{
   6457	enum mv88e6xxx_egress_direction direction = mirror->ingress ?
   6458						MV88E6XXX_EGRESS_DIR_INGRESS :
   6459						MV88E6XXX_EGRESS_DIR_EGRESS;
   6460	struct mv88e6xxx_chip *chip = ds->priv;
   6461	bool other_mirrors = false;
   6462	int i;
   6463
   6464	mutex_lock(&chip->reg_lock);
   6465	if (mv88e6xxx_port_set_mirror(chip, port, direction, false))
   6466		dev_err(ds->dev, "p%d: failed to disable mirroring\n", port);
   6467
   6468	for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
   6469		other_mirrors |= mirror->ingress ?
   6470				 chip->ports[i].mirror_ingress :
   6471				 chip->ports[i].mirror_egress;
   6472
   6473	/* Reset egress port when no other mirror is active */
   6474	if (!other_mirrors) {
   6475		if (mv88e6xxx_set_egress_port(chip, direction,
   6476					      dsa_upstream_port(ds, port)))
   6477			dev_err(ds->dev, "failed to set egress port\n");
   6478	}
   6479
   6480	mutex_unlock(&chip->reg_lock);
   6481}
   6482
   6483static int mv88e6xxx_port_pre_bridge_flags(struct dsa_switch *ds, int port,
   6484					   struct switchdev_brport_flags flags,
   6485					   struct netlink_ext_ack *extack)
   6486{
   6487	struct mv88e6xxx_chip *chip = ds->priv;
   6488	const struct mv88e6xxx_ops *ops;
   6489
   6490	if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
   6491			   BR_BCAST_FLOOD | BR_PORT_LOCKED))
   6492		return -EINVAL;
   6493
   6494	ops = chip->info->ops;
   6495
   6496	if ((flags.mask & BR_FLOOD) && !ops->port_set_ucast_flood)
   6497		return -EINVAL;
   6498
   6499	if ((flags.mask & BR_MCAST_FLOOD) && !ops->port_set_mcast_flood)
   6500		return -EINVAL;
   6501
   6502	return 0;
   6503}
   6504
   6505static int mv88e6xxx_port_bridge_flags(struct dsa_switch *ds, int port,
   6506				       struct switchdev_brport_flags flags,
   6507				       struct netlink_ext_ack *extack)
   6508{
   6509	struct mv88e6xxx_chip *chip = ds->priv;
   6510	int err = -EOPNOTSUPP;
   6511
   6512	mv88e6xxx_reg_lock(chip);
   6513
   6514	if (flags.mask & BR_LEARNING) {
   6515		bool learning = !!(flags.val & BR_LEARNING);
   6516		u16 pav = learning ? (1 << port) : 0;
   6517
   6518		err = mv88e6xxx_port_set_assoc_vector(chip, port, pav);
   6519		if (err)
   6520			goto out;
   6521	}
   6522
   6523	if (flags.mask & BR_FLOOD) {
   6524		bool unicast = !!(flags.val & BR_FLOOD);
   6525
   6526		err = chip->info->ops->port_set_ucast_flood(chip, port,
   6527							    unicast);
   6528		if (err)
   6529			goto out;
   6530	}
   6531
   6532	if (flags.mask & BR_MCAST_FLOOD) {
   6533		bool multicast = !!(flags.val & BR_MCAST_FLOOD);
   6534
   6535		err = chip->info->ops->port_set_mcast_flood(chip, port,
   6536							    multicast);
   6537		if (err)
   6538			goto out;
   6539	}
   6540
   6541	if (flags.mask & BR_BCAST_FLOOD) {
   6542		bool broadcast = !!(flags.val & BR_BCAST_FLOOD);
   6543
   6544		err = mv88e6xxx_port_broadcast_sync(chip, port, broadcast);
   6545		if (err)
   6546			goto out;
   6547	}
   6548
   6549	if (flags.mask & BR_PORT_LOCKED) {
   6550		bool locked = !!(flags.val & BR_PORT_LOCKED);
   6551
   6552		err = mv88e6xxx_port_set_lock(chip, port, locked);
   6553		if (err)
   6554			goto out;
   6555	}
   6556out:
   6557	mv88e6xxx_reg_unlock(chip);
   6558
   6559	return err;
   6560}
   6561
   6562static bool mv88e6xxx_lag_can_offload(struct dsa_switch *ds,
   6563				      struct dsa_lag lag,
   6564				      struct netdev_lag_upper_info *info)
   6565{
   6566	struct mv88e6xxx_chip *chip = ds->priv;
   6567	struct dsa_port *dp;
   6568	int members = 0;
   6569
   6570	if (!mv88e6xxx_has_lag(chip))
   6571		return false;
   6572
   6573	if (!lag.id)
   6574		return false;
   6575
   6576	dsa_lag_foreach_port(dp, ds->dst, &lag)
   6577		/* Includes the port joining the LAG */
   6578		members++;
   6579
   6580	if (members > 8)
   6581		return false;
   6582
   6583	/* We could potentially relax this to include active
   6584	 * backup in the future.
   6585	 */
   6586	if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
   6587		return false;
   6588
   6589	/* Ideally we would also validate that the hash type matches
   6590	 * the hardware. Alas, this is always set to unknown on team
   6591	 * interfaces.
   6592	 */
   6593	return true;
   6594}
   6595
   6596static int mv88e6xxx_lag_sync_map(struct dsa_switch *ds, struct dsa_lag lag)
   6597{
   6598	struct mv88e6xxx_chip *chip = ds->priv;
   6599	struct dsa_port *dp;
   6600	u16 map = 0;
   6601	int id;
   6602
   6603	/* DSA LAG IDs are one-based, hardware is zero-based */
   6604	id = lag.id - 1;
   6605
   6606	/* Build the map of all ports to distribute flows destined for
   6607	 * this LAG. This can be either a local user port, or a DSA
   6608	 * port if the LAG port is on a remote chip.
   6609	 */
   6610	dsa_lag_foreach_port(dp, ds->dst, &lag)
   6611		map |= BIT(dsa_towards_port(ds, dp->ds->index, dp->index));
   6612
   6613	return mv88e6xxx_g2_trunk_mapping_write(chip, id, map);
   6614}
   6615
   6616static const u8 mv88e6xxx_lag_mask_table[8][8] = {
   6617	/* Row number corresponds to the number of active members in a
   6618	 * LAG. Each column states which of the eight hash buckets are
   6619	 * mapped to the column:th port in the LAG.
   6620	 *
   6621	 * Example: In a LAG with three active ports, the second port
   6622	 * ([2][1]) would be selected for traffic mapped to buckets
   6623	 * 3,4,5 (0x38).
   6624	 */
   6625	{ 0xff,    0,    0,    0,    0,    0,    0,    0 },
   6626	{ 0x0f, 0xf0,    0,    0,    0,    0,    0,    0 },
   6627	{ 0x07, 0x38, 0xc0,    0,    0,    0,    0,    0 },
   6628	{ 0x03, 0x0c, 0x30, 0xc0,    0,    0,    0,    0 },
   6629	{ 0x03, 0x0c, 0x30, 0x40, 0x80,    0,    0,    0 },
   6630	{ 0x03, 0x0c, 0x10, 0x20, 0x40, 0x80,    0,    0 },
   6631	{ 0x03, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,    0 },
   6632	{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 },
   6633};
   6634
   6635static void mv88e6xxx_lag_set_port_mask(u16 *mask, int port,
   6636					int num_tx, int nth)
   6637{
   6638	u8 active = 0;
   6639	int i;
   6640
   6641	num_tx = num_tx <= 8 ? num_tx : 8;
   6642	if (nth < num_tx)
   6643		active = mv88e6xxx_lag_mask_table[num_tx - 1][nth];
   6644
   6645	for (i = 0; i < 8; i++) {
   6646		if (BIT(i) & active)
   6647			mask[i] |= BIT(port);
   6648	}
   6649}
   6650
   6651static int mv88e6xxx_lag_sync_masks(struct dsa_switch *ds)
   6652{
   6653	struct mv88e6xxx_chip *chip = ds->priv;
   6654	unsigned int id, num_tx;
   6655	struct dsa_port *dp;
   6656	struct dsa_lag *lag;
   6657	int i, err, nth;
   6658	u16 mask[8];
   6659	u16 ivec;
   6660
   6661	/* Assume no port is a member of any LAG. */
   6662	ivec = BIT(mv88e6xxx_num_ports(chip)) - 1;
   6663
   6664	/* Disable all masks for ports that _are_ members of a LAG. */
   6665	dsa_switch_for_each_port(dp, ds) {
   6666		if (!dp->lag)
   6667			continue;
   6668
   6669		ivec &= ~BIT(dp->index);
   6670	}
   6671
   6672	for (i = 0; i < 8; i++)
   6673		mask[i] = ivec;
   6674
   6675	/* Enable the correct subset of masks for all LAG ports that
   6676	 * are in the Tx set.
   6677	 */
   6678	dsa_lags_foreach_id(id, ds->dst) {
   6679		lag = dsa_lag_by_id(ds->dst, id);
   6680		if (!lag)
   6681			continue;
   6682
   6683		num_tx = 0;
   6684		dsa_lag_foreach_port(dp, ds->dst, lag) {
   6685			if (dp->lag_tx_enabled)
   6686				num_tx++;
   6687		}
   6688
   6689		if (!num_tx)
   6690			continue;
   6691
   6692		nth = 0;
   6693		dsa_lag_foreach_port(dp, ds->dst, lag) {
   6694			if (!dp->lag_tx_enabled)
   6695				continue;
   6696
   6697			if (dp->ds == ds)
   6698				mv88e6xxx_lag_set_port_mask(mask, dp->index,
   6699							    num_tx, nth);
   6700
   6701			nth++;
   6702		}
   6703	}
   6704
   6705	for (i = 0; i < 8; i++) {
   6706		err = mv88e6xxx_g2_trunk_mask_write(chip, i, true, mask[i]);
   6707		if (err)
   6708			return err;
   6709	}
   6710
   6711	return 0;
   6712}
   6713
   6714static int mv88e6xxx_lag_sync_masks_map(struct dsa_switch *ds,
   6715					struct dsa_lag lag)
   6716{
   6717	int err;
   6718
   6719	err = mv88e6xxx_lag_sync_masks(ds);
   6720
   6721	if (!err)
   6722		err = mv88e6xxx_lag_sync_map(ds, lag);
   6723
   6724	return err;
   6725}
   6726
   6727static int mv88e6xxx_port_lag_change(struct dsa_switch *ds, int port)
   6728{
   6729	struct mv88e6xxx_chip *chip = ds->priv;
   6730	int err;
   6731
   6732	mv88e6xxx_reg_lock(chip);
   6733	err = mv88e6xxx_lag_sync_masks(ds);
   6734	mv88e6xxx_reg_unlock(chip);
   6735	return err;
   6736}
   6737
   6738static int mv88e6xxx_port_lag_join(struct dsa_switch *ds, int port,
   6739				   struct dsa_lag lag,
   6740				   struct netdev_lag_upper_info *info)
   6741{
   6742	struct mv88e6xxx_chip *chip = ds->priv;
   6743	int err, id;
   6744
   6745	if (!mv88e6xxx_lag_can_offload(ds, lag, info))
   6746		return -EOPNOTSUPP;
   6747
   6748	/* DSA LAG IDs are one-based */
   6749	id = lag.id - 1;
   6750
   6751	mv88e6xxx_reg_lock(chip);
   6752
   6753	err = mv88e6xxx_port_set_trunk(chip, port, true, id);
   6754	if (err)
   6755		goto err_unlock;
   6756
   6757	err = mv88e6xxx_lag_sync_masks_map(ds, lag);
   6758	if (err)
   6759		goto err_clear_trunk;
   6760
   6761	mv88e6xxx_reg_unlock(chip);
   6762	return 0;
   6763
   6764err_clear_trunk:
   6765	mv88e6xxx_port_set_trunk(chip, port, false, 0);
   6766err_unlock:
   6767	mv88e6xxx_reg_unlock(chip);
   6768	return err;
   6769}
   6770
   6771static int mv88e6xxx_port_lag_leave(struct dsa_switch *ds, int port,
   6772				    struct dsa_lag lag)
   6773{
   6774	struct mv88e6xxx_chip *chip = ds->priv;
   6775	int err_sync, err_trunk;
   6776
   6777	mv88e6xxx_reg_lock(chip);
   6778	err_sync = mv88e6xxx_lag_sync_masks_map(ds, lag);
   6779	err_trunk = mv88e6xxx_port_set_trunk(chip, port, false, 0);
   6780	mv88e6xxx_reg_unlock(chip);
   6781	return err_sync ? : err_trunk;
   6782}
   6783
   6784static int mv88e6xxx_crosschip_lag_change(struct dsa_switch *ds, int sw_index,
   6785					  int port)
   6786{
   6787	struct mv88e6xxx_chip *chip = ds->priv;
   6788	int err;
   6789
   6790	mv88e6xxx_reg_lock(chip);
   6791	err = mv88e6xxx_lag_sync_masks(ds);
   6792	mv88e6xxx_reg_unlock(chip);
   6793	return err;
   6794}
   6795
   6796static int mv88e6xxx_crosschip_lag_join(struct dsa_switch *ds, int sw_index,
   6797					int port, struct dsa_lag lag,
   6798					struct netdev_lag_upper_info *info)
   6799{
   6800	struct mv88e6xxx_chip *chip = ds->priv;
   6801	int err;
   6802
   6803	if (!mv88e6xxx_lag_can_offload(ds, lag, info))
   6804		return -EOPNOTSUPP;
   6805
   6806	mv88e6xxx_reg_lock(chip);
   6807
   6808	err = mv88e6xxx_lag_sync_masks_map(ds, lag);
   6809	if (err)
   6810		goto unlock;
   6811
   6812	err = mv88e6xxx_pvt_map(chip, sw_index, port);
   6813
   6814unlock:
   6815	mv88e6xxx_reg_unlock(chip);
   6816	return err;
   6817}
   6818
   6819static int mv88e6xxx_crosschip_lag_leave(struct dsa_switch *ds, int sw_index,
   6820					 int port, struct dsa_lag lag)
   6821{
   6822	struct mv88e6xxx_chip *chip = ds->priv;
   6823	int err_sync, err_pvt;
   6824
   6825	mv88e6xxx_reg_lock(chip);
   6826	err_sync = mv88e6xxx_lag_sync_masks_map(ds, lag);
   6827	err_pvt = mv88e6xxx_pvt_map(chip, sw_index, port);
   6828	mv88e6xxx_reg_unlock(chip);
   6829	return err_sync ? : err_pvt;
   6830}
   6831
   6832static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
   6833	.get_tag_protocol	= mv88e6xxx_get_tag_protocol,
   6834	.change_tag_protocol	= mv88e6xxx_change_tag_protocol,
   6835	.setup			= mv88e6xxx_setup,
   6836	.teardown		= mv88e6xxx_teardown,
   6837	.port_setup		= mv88e6xxx_port_setup,
   6838	.port_teardown		= mv88e6xxx_port_teardown,
   6839	.phylink_get_caps	= mv88e6xxx_get_caps,
   6840	.phylink_mac_link_state	= mv88e6xxx_serdes_pcs_get_state,
   6841	.phylink_mac_config	= mv88e6xxx_mac_config,
   6842	.phylink_mac_an_restart	= mv88e6xxx_serdes_pcs_an_restart,
   6843	.phylink_mac_link_down	= mv88e6xxx_mac_link_down,
   6844	.phylink_mac_link_up	= mv88e6xxx_mac_link_up,
   6845	.get_strings		= mv88e6xxx_get_strings,
   6846	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
   6847	.get_sset_count		= mv88e6xxx_get_sset_count,
   6848	.port_enable		= mv88e6xxx_port_enable,
   6849	.port_disable		= mv88e6xxx_port_disable,
   6850	.port_max_mtu		= mv88e6xxx_get_max_mtu,
   6851	.port_change_mtu	= mv88e6xxx_change_mtu,
   6852	.get_mac_eee		= mv88e6xxx_get_mac_eee,
   6853	.set_mac_eee		= mv88e6xxx_set_mac_eee,
   6854	.get_eeprom_len		= mv88e6xxx_get_eeprom_len,
   6855	.get_eeprom		= mv88e6xxx_get_eeprom,
   6856	.set_eeprom		= mv88e6xxx_set_eeprom,
   6857	.get_regs_len		= mv88e6xxx_get_regs_len,
   6858	.get_regs		= mv88e6xxx_get_regs,
   6859	.get_rxnfc		= mv88e6xxx_get_rxnfc,
   6860	.set_rxnfc		= mv88e6xxx_set_rxnfc,
   6861	.set_ageing_time	= mv88e6xxx_set_ageing_time,
   6862	.port_bridge_join	= mv88e6xxx_port_bridge_join,
   6863	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
   6864	.port_pre_bridge_flags	= mv88e6xxx_port_pre_bridge_flags,
   6865	.port_bridge_flags	= mv88e6xxx_port_bridge_flags,
   6866	.port_stp_state_set	= mv88e6xxx_port_stp_state_set,
   6867	.port_mst_state_set	= mv88e6xxx_port_mst_state_set,
   6868	.port_fast_age		= mv88e6xxx_port_fast_age,
   6869	.port_vlan_fast_age	= mv88e6xxx_port_vlan_fast_age,
   6870	.port_vlan_filtering	= mv88e6xxx_port_vlan_filtering,
   6871	.port_vlan_add		= mv88e6xxx_port_vlan_add,
   6872	.port_vlan_del		= mv88e6xxx_port_vlan_del,
   6873	.vlan_msti_set		= mv88e6xxx_vlan_msti_set,
   6874	.port_fdb_add		= mv88e6xxx_port_fdb_add,
   6875	.port_fdb_del		= mv88e6xxx_port_fdb_del,
   6876	.port_fdb_dump		= mv88e6xxx_port_fdb_dump,
   6877	.port_mdb_add		= mv88e6xxx_port_mdb_add,
   6878	.port_mdb_del		= mv88e6xxx_port_mdb_del,
   6879	.port_mirror_add	= mv88e6xxx_port_mirror_add,
   6880	.port_mirror_del	= mv88e6xxx_port_mirror_del,
   6881	.crosschip_bridge_join	= mv88e6xxx_crosschip_bridge_join,
   6882	.crosschip_bridge_leave	= mv88e6xxx_crosschip_bridge_leave,
   6883	.port_hwtstamp_set	= mv88e6xxx_port_hwtstamp_set,
   6884	.port_hwtstamp_get	= mv88e6xxx_port_hwtstamp_get,
   6885	.port_txtstamp		= mv88e6xxx_port_txtstamp,
   6886	.port_rxtstamp		= mv88e6xxx_port_rxtstamp,
   6887	.get_ts_info		= mv88e6xxx_get_ts_info,
   6888	.devlink_param_get	= mv88e6xxx_devlink_param_get,
   6889	.devlink_param_set	= mv88e6xxx_devlink_param_set,
   6890	.devlink_info_get	= mv88e6xxx_devlink_info_get,
   6891	.port_lag_change	= mv88e6xxx_port_lag_change,
   6892	.port_lag_join		= mv88e6xxx_port_lag_join,
   6893	.port_lag_leave		= mv88e6xxx_port_lag_leave,
   6894	.crosschip_lag_change	= mv88e6xxx_crosschip_lag_change,
   6895	.crosschip_lag_join	= mv88e6xxx_crosschip_lag_join,
   6896	.crosschip_lag_leave	= mv88e6xxx_crosschip_lag_leave,
   6897};
   6898
   6899static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
   6900{
   6901	struct device *dev = chip->dev;
   6902	struct dsa_switch *ds;
   6903
   6904	ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
   6905	if (!ds)
   6906		return -ENOMEM;
   6907
   6908	ds->dev = dev;
   6909	ds->num_ports = mv88e6xxx_num_ports(chip);
   6910	ds->priv = chip;
   6911	ds->dev = dev;
   6912	ds->ops = &mv88e6xxx_switch_ops;
   6913	ds->ageing_time_min = chip->info->age_time_coeff;
   6914	ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
   6915
   6916	/* Some chips support up to 32, but that requires enabling the
   6917	 * 5-bit port mode, which we do not support. 640k^W16 ought to
   6918	 * be enough for anyone.
   6919	 */
   6920	ds->num_lag_ids = mv88e6xxx_has_lag(chip) ? 16 : 0;
   6921
   6922	dev_set_drvdata(dev, ds);
   6923
   6924	return dsa_register_switch(ds);
   6925}
   6926
   6927static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip)
   6928{
   6929	dsa_unregister_switch(chip->ds);
   6930}
   6931
   6932static const void *pdata_device_get_match_data(struct device *dev)
   6933{
   6934	const struct of_device_id *matches = dev->driver->of_match_table;
   6935	const struct dsa_mv88e6xxx_pdata *pdata = dev->platform_data;
   6936
   6937	for (; matches->name[0] || matches->type[0] || matches->compatible[0];
   6938	     matches++) {
   6939		if (!strcmp(pdata->compatible, matches->compatible))
   6940			return matches->data;
   6941	}
   6942	return NULL;
   6943}
   6944
   6945/* There is no suspend to RAM support at DSA level yet, the switch configuration
   6946 * would be lost after a power cycle so prevent it to be suspended.
   6947 */
   6948static int __maybe_unused mv88e6xxx_suspend(struct device *dev)
   6949{
   6950	return -EOPNOTSUPP;
   6951}
   6952
   6953static int __maybe_unused mv88e6xxx_resume(struct device *dev)
   6954{
   6955	return 0;
   6956}
   6957
   6958static SIMPLE_DEV_PM_OPS(mv88e6xxx_pm_ops, mv88e6xxx_suspend, mv88e6xxx_resume);
   6959
   6960static int mv88e6xxx_probe(struct mdio_device *mdiodev)
   6961{
   6962	struct dsa_mv88e6xxx_pdata *pdata = mdiodev->dev.platform_data;
   6963	const struct mv88e6xxx_info *compat_info = NULL;
   6964	struct device *dev = &mdiodev->dev;
   6965	struct device_node *np = dev->of_node;
   6966	struct mv88e6xxx_chip *chip;
   6967	int port;
   6968	int err;
   6969
   6970	if (!np && !pdata)
   6971		return -EINVAL;
   6972
   6973	if (np)
   6974		compat_info = of_device_get_match_data(dev);
   6975
   6976	if (pdata) {
   6977		compat_info = pdata_device_get_match_data(dev);
   6978
   6979		if (!pdata->netdev)
   6980			return -EINVAL;
   6981
   6982		for (port = 0; port < DSA_MAX_PORTS; port++) {
   6983			if (!(pdata->enabled_ports & (1 << port)))
   6984				continue;
   6985			if (strcmp(pdata->cd.port_names[port], "cpu"))
   6986				continue;
   6987			pdata->cd.netdev[port] = &pdata->netdev->dev;
   6988			break;
   6989		}
   6990	}
   6991
   6992	if (!compat_info)
   6993		return -EINVAL;
   6994
   6995	chip = mv88e6xxx_alloc_chip(dev);
   6996	if (!chip) {
   6997		err = -ENOMEM;
   6998		goto out;
   6999	}
   7000
   7001	chip->info = compat_info;
   7002
   7003	chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
   7004	if (IS_ERR(chip->reset)) {
   7005		err = PTR_ERR(chip->reset);
   7006		goto out;
   7007	}
   7008	if (chip->reset)
   7009		usleep_range(1000, 2000);
   7010
   7011	/* Detect if the device is configured in single chip addressing mode,
   7012	 * otherwise continue with address specific smi init/detection.
   7013	 */
   7014	err = mv88e6xxx_single_chip_detect(chip, mdiodev);
   7015	if (err) {
   7016		err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
   7017		if (err)
   7018			goto out;
   7019
   7020		err = mv88e6xxx_detect(chip);
   7021		if (err)
   7022			goto out;
   7023	}
   7024
   7025	if (chip->info->edsa_support == MV88E6XXX_EDSA_SUPPORTED)
   7026		chip->tag_protocol = DSA_TAG_PROTO_EDSA;
   7027	else
   7028		chip->tag_protocol = DSA_TAG_PROTO_DSA;
   7029
   7030	mv88e6xxx_phy_init(chip);
   7031
   7032	if (chip->info->ops->get_eeprom) {
   7033		if (np)
   7034			of_property_read_u32(np, "eeprom-length",
   7035					     &chip->eeprom_len);
   7036		else
   7037			chip->eeprom_len = pdata->eeprom_len;
   7038	}
   7039
   7040	mv88e6xxx_reg_lock(chip);
   7041	err = mv88e6xxx_switch_reset(chip);
   7042	mv88e6xxx_reg_unlock(chip);
   7043	if (err)
   7044		goto out;
   7045
   7046	if (np) {
   7047		chip->irq = of_irq_get(np, 0);
   7048		if (chip->irq == -EPROBE_DEFER) {
   7049			err = chip->irq;
   7050			goto out;
   7051		}
   7052	}
   7053
   7054	if (pdata)
   7055		chip->irq = pdata->irq;
   7056
   7057	/* Has to be performed before the MDIO bus is created, because
   7058	 * the PHYs will link their interrupts to these interrupt
   7059	 * controllers
   7060	 */
   7061	mv88e6xxx_reg_lock(chip);
   7062	if (chip->irq > 0)
   7063		err = mv88e6xxx_g1_irq_setup(chip);
   7064	else
   7065		err = mv88e6xxx_irq_poll_setup(chip);
   7066	mv88e6xxx_reg_unlock(chip);
   7067
   7068	if (err)
   7069		goto out;
   7070
   7071	if (chip->info->g2_irqs > 0) {
   7072		err = mv88e6xxx_g2_irq_setup(chip);
   7073		if (err)
   7074			goto out_g1_irq;
   7075	}
   7076
   7077	err = mv88e6xxx_g1_atu_prob_irq_setup(chip);
   7078	if (err)
   7079		goto out_g2_irq;
   7080
   7081	err = mv88e6xxx_g1_vtu_prob_irq_setup(chip);
   7082	if (err)
   7083		goto out_g1_atu_prob_irq;
   7084
   7085	err = mv88e6xxx_mdios_register(chip, np);
   7086	if (err)
   7087		goto out_g1_vtu_prob_irq;
   7088
   7089	err = mv88e6xxx_register_switch(chip);
   7090	if (err)
   7091		goto out_mdio;
   7092
   7093	return 0;
   7094
   7095out_mdio:
   7096	mv88e6xxx_mdios_unregister(chip);
   7097out_g1_vtu_prob_irq:
   7098	mv88e6xxx_g1_vtu_prob_irq_free(chip);
   7099out_g1_atu_prob_irq:
   7100	mv88e6xxx_g1_atu_prob_irq_free(chip);
   7101out_g2_irq:
   7102	if (chip->info->g2_irqs > 0)
   7103		mv88e6xxx_g2_irq_free(chip);
   7104out_g1_irq:
   7105	if (chip->irq > 0)
   7106		mv88e6xxx_g1_irq_free(chip);
   7107	else
   7108		mv88e6xxx_irq_poll_free(chip);
   7109out:
   7110	if (pdata)
   7111		dev_put(pdata->netdev);
   7112
   7113	return err;
   7114}
   7115
   7116static void mv88e6xxx_remove(struct mdio_device *mdiodev)
   7117{
   7118	struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
   7119	struct mv88e6xxx_chip *chip;
   7120
   7121	if (!ds)
   7122		return;
   7123
   7124	chip = ds->priv;
   7125
   7126	if (chip->info->ptp_support) {
   7127		mv88e6xxx_hwtstamp_free(chip);
   7128		mv88e6xxx_ptp_free(chip);
   7129	}
   7130
   7131	mv88e6xxx_phy_destroy(chip);
   7132	mv88e6xxx_unregister_switch(chip);
   7133	mv88e6xxx_mdios_unregister(chip);
   7134
   7135	mv88e6xxx_g1_vtu_prob_irq_free(chip);
   7136	mv88e6xxx_g1_atu_prob_irq_free(chip);
   7137
   7138	if (chip->info->g2_irqs > 0)
   7139		mv88e6xxx_g2_irq_free(chip);
   7140
   7141	if (chip->irq > 0)
   7142		mv88e6xxx_g1_irq_free(chip);
   7143	else
   7144		mv88e6xxx_irq_poll_free(chip);
   7145
   7146	dev_set_drvdata(&mdiodev->dev, NULL);
   7147}
   7148
   7149static void mv88e6xxx_shutdown(struct mdio_device *mdiodev)
   7150{
   7151	struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
   7152
   7153	if (!ds)
   7154		return;
   7155
   7156	dsa_switch_shutdown(ds);
   7157
   7158	dev_set_drvdata(&mdiodev->dev, NULL);
   7159}
   7160
   7161static const struct of_device_id mv88e6xxx_of_match[] = {
   7162	{
   7163		.compatible = "marvell,mv88e6085",
   7164		.data = &mv88e6xxx_table[MV88E6085],
   7165	},
   7166	{
   7167		.compatible = "marvell,mv88e6190",
   7168		.data = &mv88e6xxx_table[MV88E6190],
   7169	},
   7170	{
   7171		.compatible = "marvell,mv88e6250",
   7172		.data = &mv88e6xxx_table[MV88E6250],
   7173	},
   7174	{ /* sentinel */ },
   7175};
   7176
   7177MODULE_DEVICE_TABLE(of, mv88e6xxx_of_match);
   7178
   7179static struct mdio_driver mv88e6xxx_driver = {
   7180	.probe	= mv88e6xxx_probe,
   7181	.remove = mv88e6xxx_remove,
   7182	.shutdown = mv88e6xxx_shutdown,
   7183	.mdiodrv.driver = {
   7184		.name = "mv88e6085",
   7185		.of_match_table = mv88e6xxx_of_match,
   7186		.pm = &mv88e6xxx_pm_ops,
   7187	},
   7188};
   7189
   7190mdio_module_driver(mv88e6xxx_driver);
   7191
   7192MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
   7193MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
   7194MODULE_LICENSE("GPL");