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