linux/drivers/net/dsa/mv88e6xxx/chip.c
<<
>>
Prefs
   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");
4367