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