Linux Audio

Check our new training course

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