Linux Audio

Check our new training course

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