Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Marvell 88e6xxx Ethernet switch single-chip support
0004  *
0005  * Copyright (c) 2008 Marvell Semiconductor
0006  *
0007  * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch>
0008  *
0009  * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
0010  *  Vivien Didelot <vivien.didelot@savoirfairelinux.com>
0011  */
0012 
0013 #include <linux/bitfield.h>
0014 #include <linux/delay.h>
0015 #include <linux/dsa/mv88e6xxx.h>
0016 #include <linux/etherdevice.h>
0017 #include <linux/ethtool.h>
0018 #include <linux/if_bridge.h>
0019 #include <linux/interrupt.h>
0020 #include <linux/irq.h>
0021 #include <linux/irqdomain.h>
0022 #include <linux/jiffies.h>
0023 #include <linux/list.h>
0024 #include <linux/mdio.h>
0025 #include <linux/module.h>
0026 #include <linux/of_device.h>
0027 #include <linux/of_irq.h>
0028 #include <linux/of_mdio.h>
0029 #include <linux/platform_data/mv88e6xxx.h>
0030 #include <linux/netdevice.h>
0031 #include <linux/gpio/consumer.h>
0032 #include <linux/phylink.h>
0033 #include <net/dsa.h>
0034 
0035 #include "chip.h"
0036 #include "devlink.h"
0037 #include "global1.h"
0038 #include "global2.h"
0039 #include "hwtstamp.h"
0040 #include "phy.h"
0041 #include "port.h"
0042 #include "ptp.h"
0043 #include "serdes.h"
0044 #include "smi.h"
0045 
0046 static void assert_reg_lock(struct mv88e6xxx_chip *chip)
0047 {
0048     if (unlikely(!mutex_is_locked(&chip->reg_lock))) {
0049         dev_err(chip->dev, "Switch registers lock not held!\n");
0050         dump_stack();
0051     }
0052 }
0053 
0054 int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val)
0055 {
0056     int err;
0057 
0058     assert_reg_lock(chip);
0059 
0060     err = mv88e6xxx_smi_read(chip, addr, reg, val);
0061     if (err)
0062         return err;
0063 
0064     dev_dbg(chip->dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
0065         addr, reg, *val);
0066 
0067     return 0;
0068 }
0069 
0070 int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val)
0071 {
0072     int err;
0073 
0074     assert_reg_lock(chip);
0075 
0076     err = mv88e6xxx_smi_write(chip, addr, reg, val);
0077     if (err)
0078         return err;
0079 
0080     dev_dbg(chip->dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
0081         addr, reg, val);
0082 
0083     return 0;
0084 }
0085 
0086 int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
0087             u16 mask, u16 val)
0088 {
0089     const unsigned long timeout = jiffies + msecs_to_jiffies(50);
0090     u16 data;
0091     int err;
0092     int i;
0093 
0094     /* There's no bus specific operation to wait for a mask. Even
0095      * if the initial poll takes longer than 50ms, always do at
0096      * least one more attempt.
0097      */
0098     for (i = 0; time_before(jiffies, timeout) || (i < 2); i++) {
0099         err = mv88e6xxx_read(chip, addr, reg, &data);
0100         if (err)
0101             return err;
0102 
0103         if ((data & mask) == val)
0104             return 0;
0105 
0106         if (i < 2)
0107             cpu_relax();
0108         else
0109             usleep_range(1000, 2000);
0110     }
0111 
0112     dev_err(chip->dev, "Timeout while waiting for switch\n");
0113     return -ETIMEDOUT;
0114 }
0115 
0116 int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,
0117                int bit, int val)
0118 {
0119     return mv88e6xxx_wait_mask(chip, addr, reg, BIT(bit),
0120                    val ? BIT(bit) : 0x0000);
0121 }
0122 
0123 struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip)
0124 {
0125     struct mv88e6xxx_mdio_bus *mdio_bus;
0126 
0127     mdio_bus = list_first_entry(&chip->mdios, struct mv88e6xxx_mdio_bus,
0128                     list);
0129     if (!mdio_bus)
0130         return NULL;
0131 
0132     return mdio_bus->bus;
0133 }
0134 
0135 static void mv88e6xxx_g1_irq_mask(struct irq_data *d)
0136 {
0137     struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
0138     unsigned int n = d->hwirq;
0139 
0140     chip->g1_irq.masked |= (1 << n);
0141 }
0142 
0143 static void mv88e6xxx_g1_irq_unmask(struct irq_data *d)
0144 {
0145     struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
0146     unsigned int n = d->hwirq;
0147 
0148     chip->g1_irq.masked &= ~(1 << n);
0149 }
0150 
0151 static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct mv88e6xxx_chip *chip)
0152 {
0153     unsigned int nhandled = 0;
0154     unsigned int sub_irq;
0155     unsigned int n;
0156     u16 reg;
0157     u16 ctl1;
0158     int err;
0159 
0160     mv88e6xxx_reg_lock(chip);
0161     err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
0162     mv88e6xxx_reg_unlock(chip);
0163 
0164     if (err)
0165         goto out;
0166 
0167     do {
0168         for (n = 0; n < chip->g1_irq.nirqs; ++n) {
0169             if (reg & (1 << n)) {
0170                 sub_irq = irq_find_mapping(chip->g1_irq.domain,
0171                                n);
0172                 handle_nested_irq(sub_irq);
0173                 ++nhandled;
0174             }
0175         }
0176 
0177         mv88e6xxx_reg_lock(chip);
0178         err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &ctl1);
0179         if (err)
0180             goto unlock;
0181         err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
0182 unlock:
0183         mv88e6xxx_reg_unlock(chip);
0184         if (err)
0185             goto out;
0186         ctl1 &= GENMASK(chip->g1_irq.nirqs, 0);
0187     } while (reg & ctl1);
0188 
0189 out:
0190     return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
0191 }
0192 
0193 static irqreturn_t mv88e6xxx_g1_irq_thread_fn(int irq, void *dev_id)
0194 {
0195     struct mv88e6xxx_chip *chip = dev_id;
0196 
0197     return mv88e6xxx_g1_irq_thread_work(chip);
0198 }
0199 
0200 static void mv88e6xxx_g1_irq_bus_lock(struct irq_data *d)
0201 {
0202     struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
0203 
0204     mv88e6xxx_reg_lock(chip);
0205 }
0206 
0207 static void mv88e6xxx_g1_irq_bus_sync_unlock(struct irq_data *d)
0208 {
0209     struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
0210     u16 mask = GENMASK(chip->g1_irq.nirqs, 0);
0211     u16 reg;
0212     int err;
0213 
0214     err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &reg);
0215     if (err)
0216         goto out;
0217 
0218     reg &= ~mask;
0219     reg |= (~chip->g1_irq.masked & mask);
0220 
0221     err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, reg);
0222     if (err)
0223         goto out;
0224 
0225 out:
0226     mv88e6xxx_reg_unlock(chip);
0227 }
0228 
0229 static const struct irq_chip mv88e6xxx_g1_irq_chip = {
0230     .name           = "mv88e6xxx-g1",
0231     .irq_mask       = mv88e6xxx_g1_irq_mask,
0232     .irq_unmask     = mv88e6xxx_g1_irq_unmask,
0233     .irq_bus_lock       = mv88e6xxx_g1_irq_bus_lock,
0234     .irq_bus_sync_unlock    = mv88e6xxx_g1_irq_bus_sync_unlock,
0235 };
0236 
0237 static int mv88e6xxx_g1_irq_domain_map(struct irq_domain *d,
0238                        unsigned int irq,
0239                        irq_hw_number_t hwirq)
0240 {
0241     struct mv88e6xxx_chip *chip = d->host_data;
0242 
0243     irq_set_chip_data(irq, d->host_data);
0244     irq_set_chip_and_handler(irq, &chip->g1_irq.chip, handle_level_irq);
0245     irq_set_noprobe(irq);
0246 
0247     return 0;
0248 }
0249 
0250 static const struct irq_domain_ops mv88e6xxx_g1_irq_domain_ops = {
0251     .map    = mv88e6xxx_g1_irq_domain_map,
0252     .xlate  = irq_domain_xlate_twocell,
0253 };
0254 
0255 /* To be called with reg_lock held */
0256 static void mv88e6xxx_g1_irq_free_common(struct mv88e6xxx_chip *chip)
0257 {
0258     int irq, virq;
0259     u16 mask;
0260 
0261     mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
0262     mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
0263     mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
0264 
0265     for (irq = 0; irq < chip->g1_irq.nirqs; irq++) {
0266         virq = irq_find_mapping(chip->g1_irq.domain, irq);
0267         irq_dispose_mapping(virq);
0268     }
0269 
0270     irq_domain_remove(chip->g1_irq.domain);
0271 }
0272 
0273 static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip)
0274 {
0275     /*
0276      * free_irq must be called without reg_lock taken because the irq
0277      * handler takes this lock, too.
0278      */
0279     free_irq(chip->irq, chip);
0280 
0281     mv88e6xxx_reg_lock(chip);
0282     mv88e6xxx_g1_irq_free_common(chip);
0283     mv88e6xxx_reg_unlock(chip);
0284 }
0285 
0286 static int mv88e6xxx_g1_irq_setup_common(struct mv88e6xxx_chip *chip)
0287 {
0288     int err, irq, virq;
0289     u16 reg, mask;
0290 
0291     chip->g1_irq.nirqs = chip->info->g1_irqs;
0292     chip->g1_irq.domain = irq_domain_add_simple(
0293         NULL, chip->g1_irq.nirqs, 0,
0294         &mv88e6xxx_g1_irq_domain_ops, chip);
0295     if (!chip->g1_irq.domain)
0296         return -ENOMEM;
0297 
0298     for (irq = 0; irq < chip->g1_irq.nirqs; irq++)
0299         irq_create_mapping(chip->g1_irq.domain, irq);
0300 
0301     chip->g1_irq.chip = mv88e6xxx_g1_irq_chip;
0302     chip->g1_irq.masked = ~0;
0303 
0304     err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
0305     if (err)
0306         goto out_mapping;
0307 
0308     mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
0309 
0310     err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
0311     if (err)
0312         goto out_disable;
0313 
0314     /* Reading the interrupt status clears (most of) them */
0315     err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
0316     if (err)
0317         goto out_disable;
0318 
0319     return 0;
0320 
0321 out_disable:
0322     mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
0323     mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
0324 
0325 out_mapping:
0326     for (irq = 0; irq < 16; irq++) {
0327         virq = irq_find_mapping(chip->g1_irq.domain, irq);
0328         irq_dispose_mapping(virq);
0329     }
0330 
0331     irq_domain_remove(chip->g1_irq.domain);
0332 
0333     return err;
0334 }
0335 
0336 static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip)
0337 {
0338     static struct lock_class_key lock_key;
0339     static struct lock_class_key request_key;
0340     int err;
0341 
0342     err = mv88e6xxx_g1_irq_setup_common(chip);
0343     if (err)
0344         return err;
0345 
0346     /* These lock classes tells lockdep that global 1 irqs are in
0347      * a different category than their parent GPIO, so it won't
0348      * report false recursion.
0349      */
0350     irq_set_lockdep_class(chip->irq, &lock_key, &request_key);
0351 
0352     snprintf(chip->irq_name, sizeof(chip->irq_name),
0353          "mv88e6xxx-%s", dev_name(chip->dev));
0354 
0355     mv88e6xxx_reg_unlock(chip);
0356     err = request_threaded_irq(chip->irq, NULL,
0357                    mv88e6xxx_g1_irq_thread_fn,
0358                    IRQF_ONESHOT | IRQF_SHARED,
0359                    chip->irq_name, chip);
0360     mv88e6xxx_reg_lock(chip);
0361     if (err)
0362         mv88e6xxx_g1_irq_free_common(chip);
0363 
0364     return err;
0365 }
0366 
0367 static void mv88e6xxx_irq_poll(struct kthread_work *work)
0368 {
0369     struct mv88e6xxx_chip *chip = container_of(work,
0370                            struct mv88e6xxx_chip,
0371                            irq_poll_work.work);
0372     mv88e6xxx_g1_irq_thread_work(chip);
0373 
0374     kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work,
0375                    msecs_to_jiffies(100));
0376 }
0377 
0378 static int mv88e6xxx_irq_poll_setup(struct mv88e6xxx_chip *chip)
0379 {
0380     int err;
0381 
0382     err = mv88e6xxx_g1_irq_setup_common(chip);
0383     if (err)
0384         return err;
0385 
0386     kthread_init_delayed_work(&chip->irq_poll_work,
0387                   mv88e6xxx_irq_poll);
0388 
0389     chip->kworker = kthread_create_worker(0, "%s", dev_name(chip->dev));
0390     if (IS_ERR(chip->kworker))
0391         return PTR_ERR(chip->kworker);
0392 
0393     kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work,
0394                    msecs_to_jiffies(100));
0395 
0396     return 0;
0397 }
0398 
0399 static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip)
0400 {
0401     kthread_cancel_delayed_work_sync(&chip->irq_poll_work);
0402     kthread_destroy_worker(chip->kworker);
0403 
0404     mv88e6xxx_reg_lock(chip);
0405     mv88e6xxx_g1_irq_free_common(chip);
0406     mv88e6xxx_reg_unlock(chip);
0407 }
0408 
0409 static int mv88e6xxx_port_config_interface(struct mv88e6xxx_chip *chip,
0410                        int port, phy_interface_t interface)
0411 {
0412     int err;
0413 
0414     if (chip->info->ops->port_set_rgmii_delay) {
0415         err = chip->info->ops->port_set_rgmii_delay(chip, port,
0416                                 interface);
0417         if (err && err != -EOPNOTSUPP)
0418             return err;
0419     }
0420 
0421     if (chip->info->ops->port_set_cmode) {
0422         err = chip->info->ops->port_set_cmode(chip, port,
0423                               interface);
0424         if (err && err != -EOPNOTSUPP)
0425             return err;
0426     }
0427 
0428     return 0;
0429 }
0430 
0431 static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port,
0432                     int link, int speed, int duplex, int pause,
0433                     phy_interface_t mode)
0434 {
0435     int err;
0436 
0437     if (!chip->info->ops->port_set_link)
0438         return 0;
0439 
0440     /* Port's MAC control must not be changed unless the link is down */
0441     err = chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN);
0442     if (err)
0443         return err;
0444 
0445     if (chip->info->ops->port_set_speed_duplex) {
0446         err = chip->info->ops->port_set_speed_duplex(chip, port,
0447                                  speed, duplex);
0448         if (err && err != -EOPNOTSUPP)
0449             goto restore_link;
0450     }
0451 
0452     if (chip->info->ops->port_set_pause) {
0453         err = chip->info->ops->port_set_pause(chip, port, pause);
0454         if (err)
0455             goto restore_link;
0456     }
0457 
0458     err = mv88e6xxx_port_config_interface(chip, port, mode);
0459 restore_link:
0460     if (chip->info->ops->port_set_link(chip, port, link))
0461         dev_err(chip->dev, "p%d: failed to restore MAC's link\n", port);
0462 
0463     return err;
0464 }
0465 
0466 static int mv88e6xxx_phy_is_internal(struct dsa_switch *ds, int port)
0467 {
0468     struct mv88e6xxx_chip *chip = ds->priv;
0469 
0470     return port < chip->info->num_internal_phys;
0471 }
0472 
0473 static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port)
0474 {
0475     u16 reg;
0476     int err;
0477 
0478     /* The 88e6250 family does not have the PHY detect bit. Instead,
0479      * report whether the port is internal.
0480      */
0481     if (chip->info->family == MV88E6XXX_FAMILY_6250)
0482         return port < chip->info->num_internal_phys;
0483 
0484     err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
0485     if (err) {
0486         dev_err(chip->dev,
0487             "p%d: %s: failed to read port status\n",
0488             port, __func__);
0489         return err;
0490     }
0491 
0492     return !!(reg & MV88E6XXX_PORT_STS_PHY_DETECT);
0493 }
0494 
0495 static int mv88e6xxx_serdes_pcs_get_state(struct dsa_switch *ds, int port,
0496                       struct phylink_link_state *state)
0497 {
0498     struct mv88e6xxx_chip *chip = ds->priv;
0499     int lane;
0500     int err;
0501 
0502     mv88e6xxx_reg_lock(chip);
0503     lane = mv88e6xxx_serdes_get_lane(chip, port);
0504     if (lane >= 0 && chip->info->ops->serdes_pcs_get_state)
0505         err = chip->info->ops->serdes_pcs_get_state(chip, port, lane,
0506                                 state);
0507     else
0508         err = -EOPNOTSUPP;
0509     mv88e6xxx_reg_unlock(chip);
0510 
0511     return err;
0512 }
0513 
0514 static int mv88e6xxx_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
0515                        unsigned int mode,
0516                        phy_interface_t interface,
0517                        const unsigned long *advertise)
0518 {
0519     const struct mv88e6xxx_ops *ops = chip->info->ops;
0520     int lane;
0521 
0522     if (ops->serdes_pcs_config) {
0523         lane = mv88e6xxx_serdes_get_lane(chip, port);
0524         if (lane >= 0)
0525             return ops->serdes_pcs_config(chip, port, lane, mode,
0526                               interface, advertise);
0527     }
0528 
0529     return 0;
0530 }
0531 
0532 static void mv88e6xxx_serdes_pcs_an_restart(struct dsa_switch *ds, int port)
0533 {
0534     struct mv88e6xxx_chip *chip = ds->priv;
0535     const struct mv88e6xxx_ops *ops;
0536     int err = 0;
0537     int lane;
0538 
0539     ops = chip->info->ops;
0540 
0541     if (ops->serdes_pcs_an_restart) {
0542         mv88e6xxx_reg_lock(chip);
0543         lane = mv88e6xxx_serdes_get_lane(chip, port);
0544         if (lane >= 0)
0545             err = ops->serdes_pcs_an_restart(chip, port, lane);
0546         mv88e6xxx_reg_unlock(chip);
0547 
0548         if (err)
0549             dev_err(ds->dev, "p%d: failed to restart AN\n", port);
0550     }
0551 }
0552 
0553 static int mv88e6xxx_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
0554                     unsigned int mode,
0555                     int speed, int duplex)
0556 {
0557     const struct mv88e6xxx_ops *ops = chip->info->ops;
0558     int lane;
0559 
0560     if (!phylink_autoneg_inband(mode) && ops->serdes_pcs_link_up) {
0561         lane = mv88e6xxx_serdes_get_lane(chip, port);
0562         if (lane >= 0)
0563             return ops->serdes_pcs_link_up(chip, port, lane,
0564                                speed, duplex);
0565     }
0566 
0567     return 0;
0568 }
0569 
0570 static const u8 mv88e6185_phy_interface_modes[] = {
0571     [MV88E6185_PORT_STS_CMODE_GMII_FD]   = PHY_INTERFACE_MODE_GMII,
0572     [MV88E6185_PORT_STS_CMODE_MII_100_FD_PS] = PHY_INTERFACE_MODE_MII,
0573     [MV88E6185_PORT_STS_CMODE_MII_100]   = PHY_INTERFACE_MODE_MII,
0574     [MV88E6185_PORT_STS_CMODE_MII_10]    = PHY_INTERFACE_MODE_MII,
0575     [MV88E6185_PORT_STS_CMODE_SERDES]    = PHY_INTERFACE_MODE_1000BASEX,
0576     [MV88E6185_PORT_STS_CMODE_1000BASE_X]    = PHY_INTERFACE_MODE_1000BASEX,
0577     [MV88E6185_PORT_STS_CMODE_PHY]       = PHY_INTERFACE_MODE_SGMII,
0578 };
0579 
0580 static void mv88e6095_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
0581                        struct phylink_config *config)
0582 {
0583     u8 cmode = chip->ports[port].cmode;
0584 
0585     config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
0586 
0587     if (mv88e6xxx_phy_is_internal(chip->ds, port)) {
0588         __set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces);
0589     } else {
0590         if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) &&
0591             mv88e6185_phy_interface_modes[cmode])
0592             __set_bit(mv88e6185_phy_interface_modes[cmode],
0593                   config->supported_interfaces);
0594 
0595         config->mac_capabilities |= MAC_1000FD;
0596     }
0597 }
0598 
0599 static void mv88e6185_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
0600                        struct phylink_config *config)
0601 {
0602     u8 cmode = chip->ports[port].cmode;
0603 
0604     if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) &&
0605         mv88e6185_phy_interface_modes[cmode])
0606         __set_bit(mv88e6185_phy_interface_modes[cmode],
0607               config->supported_interfaces);
0608 
0609     config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
0610                    MAC_1000FD;
0611 }
0612 
0613 static const u8 mv88e6xxx_phy_interface_modes[] = {
0614     [MV88E6XXX_PORT_STS_CMODE_MII_PHY]  = PHY_INTERFACE_MODE_MII,
0615     [MV88E6XXX_PORT_STS_CMODE_MII]      = PHY_INTERFACE_MODE_MII,
0616     [MV88E6XXX_PORT_STS_CMODE_GMII]     = PHY_INTERFACE_MODE_GMII,
0617     [MV88E6XXX_PORT_STS_CMODE_RMII_PHY] = PHY_INTERFACE_MODE_RMII,
0618     [MV88E6XXX_PORT_STS_CMODE_RMII]     = PHY_INTERFACE_MODE_RMII,
0619     [MV88E6XXX_PORT_STS_CMODE_100BASEX] = PHY_INTERFACE_MODE_100BASEX,
0620     [MV88E6XXX_PORT_STS_CMODE_1000BASEX]    = PHY_INTERFACE_MODE_1000BASEX,
0621     [MV88E6XXX_PORT_STS_CMODE_SGMII]    = PHY_INTERFACE_MODE_SGMII,
0622     /* higher interface modes are not needed here, since ports supporting
0623      * them are writable, and so the supported interfaces are filled in the
0624      * corresponding .phylink_set_interfaces() implementation below
0625      */
0626 };
0627 
0628 static void mv88e6xxx_translate_cmode(u8 cmode, unsigned long *supported)
0629 {
0630     if (cmode < ARRAY_SIZE(mv88e6xxx_phy_interface_modes) &&
0631         mv88e6xxx_phy_interface_modes[cmode])
0632         __set_bit(mv88e6xxx_phy_interface_modes[cmode], supported);
0633     else if (cmode == MV88E6XXX_PORT_STS_CMODE_RGMII)
0634         phy_interface_set_rgmii(supported);
0635 }
0636 
0637 static void mv88e6250_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
0638                        struct phylink_config *config)
0639 {
0640     unsigned long *supported = config->supported_interfaces;
0641 
0642     /* Translate the default cmode */
0643     mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
0644 
0645     config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
0646 }
0647 
0648 static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip)
0649 {
0650     u16 reg, val;
0651     int err;
0652 
0653     err = mv88e6xxx_port_read(chip, 4, MV88E6XXX_PORT_STS, &reg);
0654     if (err)
0655         return err;
0656 
0657     /* If PHY_DETECT is zero, then we are not in auto-media mode */
0658     if (!(reg & MV88E6XXX_PORT_STS_PHY_DETECT))
0659         return 0xf;
0660 
0661     val = reg & ~MV88E6XXX_PORT_STS_PHY_DETECT;
0662     err = mv88e6xxx_port_write(chip, 4, MV88E6XXX_PORT_STS, val);
0663     if (err)
0664         return err;
0665 
0666     err = mv88e6xxx_port_read(chip, 4, MV88E6XXX_PORT_STS, &val);
0667     if (err)
0668         return err;
0669 
0670     /* Restore PHY_DETECT value */
0671     err = mv88e6xxx_port_write(chip, 4, MV88E6XXX_PORT_STS, reg);
0672     if (err)
0673         return err;
0674 
0675     return val & MV88E6XXX_PORT_STS_CMODE_MASK;
0676 }
0677 
0678 static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
0679                        struct phylink_config *config)
0680 {
0681     unsigned long *supported = config->supported_interfaces;
0682     int err, cmode;
0683 
0684     /* Translate the default cmode */
0685     mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
0686 
0687     config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
0688                    MAC_1000FD;
0689 
0690     /* Port 4 supports automedia if the serdes is associated with it. */
0691     if (port == 4) {
0692         mv88e6xxx_reg_lock(chip);
0693         err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
0694         if (err < 0)
0695             dev_err(chip->dev, "p%d: failed to read scratch\n",
0696                 port);
0697         if (err <= 0)
0698             goto unlock;
0699 
0700         cmode = mv88e6352_get_port4_serdes_cmode(chip);
0701         if (cmode < 0)
0702             dev_err(chip->dev, "p%d: failed to read serdes cmode\n",
0703                 port);
0704         else
0705             mv88e6xxx_translate_cmode(cmode, supported);
0706 unlock:
0707         mv88e6xxx_reg_unlock(chip);
0708     }
0709 }
0710 
0711 static void mv88e6341_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
0712                        struct phylink_config *config)
0713 {
0714     unsigned long *supported = config->supported_interfaces;
0715 
0716     /* Translate the default cmode */
0717     mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
0718 
0719     /* No ethtool bits for 200Mbps */
0720     config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
0721                    MAC_1000FD;
0722 
0723     /* The C_Mode field is programmable on port 5 */
0724     if (port == 5) {
0725         __set_bit(PHY_INTERFACE_MODE_SGMII, supported);
0726         __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
0727         __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
0728 
0729         config->mac_capabilities |= MAC_2500FD;
0730     }
0731 }
0732 
0733 static void mv88e6390_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
0734                        struct phylink_config *config)
0735 {
0736     unsigned long *supported = config->supported_interfaces;
0737 
0738     /* Translate the default cmode */
0739     mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
0740 
0741     /* No ethtool bits for 200Mbps */
0742     config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
0743                    MAC_1000FD;
0744 
0745     /* The C_Mode field is programmable on ports 9 and 10 */
0746     if (port == 9 || port == 10) {
0747         __set_bit(PHY_INTERFACE_MODE_SGMII, supported);
0748         __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
0749         __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
0750 
0751         config->mac_capabilities |= MAC_2500FD;
0752     }
0753 }
0754 
0755 static void mv88e6390x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
0756                     struct phylink_config *config)
0757 {
0758     unsigned long *supported = config->supported_interfaces;
0759 
0760     mv88e6390_phylink_get_caps(chip, port, config);
0761 
0762     /* For the 6x90X, ports 2-7 can be in automedia mode.
0763      * (Note that 6x90 doesn't support RXAUI nor XAUI).
0764      *
0765      * Port 2 can also support 1000BASE-X in automedia mode if port 9 is
0766      * configured for 1000BASE-X, SGMII or 2500BASE-X.
0767      * Port 3-4 can also support 1000BASE-X in automedia mode if port 9 is
0768      * configured for RXAUI, 1000BASE-X, SGMII or 2500BASE-X.
0769      *
0770      * Port 5 can also support 1000BASE-X in automedia mode if port 10 is
0771      * configured for 1000BASE-X, SGMII or 2500BASE-X.
0772      * Port 6-7 can also support 1000BASE-X in automedia mode if port 10 is
0773      * configured for RXAUI, 1000BASE-X, SGMII or 2500BASE-X.
0774      *
0775      * For now, be permissive (as the old code was) and allow 1000BASE-X
0776      * on ports 2..7.
0777      */
0778     if (port >= 2 && port <= 7)
0779         __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
0780 
0781     /* The C_Mode field can also be programmed for 10G speeds */
0782     if (port == 9 || port == 10) {
0783         __set_bit(PHY_INTERFACE_MODE_XAUI, supported);
0784         __set_bit(PHY_INTERFACE_MODE_RXAUI, supported);
0785 
0786         config->mac_capabilities |= MAC_10000FD;
0787     }
0788 }
0789 
0790 static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
0791                     struct phylink_config *config)
0792 {
0793     unsigned long *supported = config->supported_interfaces;
0794     bool is_6191x =
0795         chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X;
0796 
0797     mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
0798 
0799     config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
0800                    MAC_1000FD;
0801 
0802     /* The C_Mode field can be programmed for ports 0, 9 and 10 */
0803     if (port == 0 || port == 9 || port == 10) {
0804         __set_bit(PHY_INTERFACE_MODE_SGMII, supported);
0805         __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
0806 
0807         /* 6191X supports >1G modes only on port 10 */
0808         if (!is_6191x || port == 10) {
0809             __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
0810             __set_bit(PHY_INTERFACE_MODE_5GBASER, supported);
0811             __set_bit(PHY_INTERFACE_MODE_10GBASER, supported);
0812             /* FIXME: USXGMII is not supported yet */
0813             /* __set_bit(PHY_INTERFACE_MODE_USXGMII, supported); */
0814 
0815             config->mac_capabilities |= MAC_2500FD | MAC_5000FD |
0816                 MAC_10000FD;
0817         }
0818     }
0819 }
0820 
0821 static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
0822                    struct phylink_config *config)
0823 {
0824     struct mv88e6xxx_chip *chip = ds->priv;
0825 
0826     chip->info->ops->phylink_get_caps(chip, port, config);
0827 
0828     /* Internal ports need GMII for PHYLIB */
0829     if (mv88e6xxx_phy_is_internal(ds, port))
0830         __set_bit(PHY_INTERFACE_MODE_GMII,
0831               config->supported_interfaces);
0832 }
0833 
0834 static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
0835                  unsigned int mode,
0836                  const struct phylink_link_state *state)
0837 {
0838     struct mv88e6xxx_chip *chip = ds->priv;
0839     struct mv88e6xxx_port *p;
0840     int err = 0;
0841 
0842     p = &chip->ports[port];
0843 
0844     mv88e6xxx_reg_lock(chip);
0845 
0846     if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) {
0847         /* In inband mode, the link may come up at any time while the
0848          * link is not forced down. Force the link down while we
0849          * reconfigure the interface mode.
0850          */
0851         if (mode == MLO_AN_INBAND &&
0852             p->interface != state->interface &&
0853             chip->info->ops->port_set_link)
0854             chip->info->ops->port_set_link(chip, port,
0855                                LINK_FORCED_DOWN);
0856 
0857         err = mv88e6xxx_port_config_interface(chip, port,
0858                               state->interface);
0859         if (err && err != -EOPNOTSUPP)
0860             goto err_unlock;
0861 
0862         err = mv88e6xxx_serdes_pcs_config(chip, port, mode,
0863                           state->interface,
0864                           state->advertising);
0865         /* FIXME: we should restart negotiation if something changed -
0866          * which is something we get if we convert to using phylinks
0867          * PCS operations.
0868          */
0869         if (err > 0)
0870             err = 0;
0871     }
0872 
0873     /* Undo the forced down state above after completing configuration
0874      * irrespective of its state on entry, which allows the link to come
0875      * up in the in-band case where there is no separate SERDES. Also
0876      * ensure that the link can come up if the PPU is in use and we are
0877      * in PHY mode (we treat the PPU as an effective in-band mechanism.)
0878      */
0879     if (chip->info->ops->port_set_link &&
0880         ((mode == MLO_AN_INBAND && p->interface != state->interface) ||
0881          (mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port))))
0882         chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
0883 
0884     p->interface = state->interface;
0885 
0886 err_unlock:
0887     mv88e6xxx_reg_unlock(chip);
0888 
0889     if (err && err != -EOPNOTSUPP)
0890         dev_err(ds->dev, "p%d: failed to configure MAC/PCS\n", port);
0891 }
0892 
0893 static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
0894                     unsigned int mode,
0895                     phy_interface_t interface)
0896 {
0897     struct mv88e6xxx_chip *chip = ds->priv;
0898     const struct mv88e6xxx_ops *ops;
0899     int err = 0;
0900 
0901     ops = chip->info->ops;
0902 
0903     mv88e6xxx_reg_lock(chip);
0904     /* Force the link down if we know the port may not be automatically
0905      * updated by the switch or if we are using fixed-link mode.
0906      */
0907     if ((!mv88e6xxx_port_ppu_updates(chip, port) ||
0908          mode == MLO_AN_FIXED) && ops->port_sync_link)
0909         err = ops->port_sync_link(chip, port, mode, false);
0910 
0911     if (!err && ops->port_set_speed_duplex)
0912         err = ops->port_set_speed_duplex(chip, port, SPEED_UNFORCED,
0913                          DUPLEX_UNFORCED);
0914     mv88e6xxx_reg_unlock(chip);
0915 
0916     if (err)
0917         dev_err(chip->dev,
0918             "p%d: failed to force MAC link down\n", port);
0919 }
0920 
0921 static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
0922                   unsigned int mode, phy_interface_t interface,
0923                   struct phy_device *phydev,
0924                   int speed, int duplex,
0925                   bool tx_pause, bool rx_pause)
0926 {
0927     struct mv88e6xxx_chip *chip = ds->priv;
0928     const struct mv88e6xxx_ops *ops;
0929     int err = 0;
0930 
0931     ops = chip->info->ops;
0932 
0933     mv88e6xxx_reg_lock(chip);
0934     /* Configure and force the link up if we know that the port may not
0935      * automatically updated by the switch or if we are using fixed-link
0936      * mode.
0937      */
0938     if (!mv88e6xxx_port_ppu_updates(chip, port) ||
0939         mode == MLO_AN_FIXED) {
0940         /* FIXME: for an automedia port, should we force the link
0941          * down here - what if the link comes up due to "other" media
0942          * while we're bringing the port up, how is the exclusivity
0943          * handled in the Marvell hardware? E.g. port 2 on 88E6390
0944          * shared between internal PHY and Serdes.
0945          */
0946         err = mv88e6xxx_serdes_pcs_link_up(chip, port, mode, speed,
0947                            duplex);
0948         if (err)
0949             goto error;
0950 
0951         if (ops->port_set_speed_duplex) {
0952             err = ops->port_set_speed_duplex(chip, port,
0953                              speed, duplex);
0954             if (err && err != -EOPNOTSUPP)
0955                 goto error;
0956         }
0957 
0958         if (ops->port_sync_link)
0959             err = ops->port_sync_link(chip, port, mode, true);
0960     }
0961 error:
0962     mv88e6xxx_reg_unlock(chip);
0963 
0964     if (err && err != -EOPNOTSUPP)
0965         dev_err(ds->dev,
0966             "p%d: failed to configure MAC link up\n", port);
0967 }
0968 
0969 static int mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
0970 {
0971     if (!chip->info->ops->stats_snapshot)
0972         return -EOPNOTSUPP;
0973 
0974     return chip->info->ops->stats_snapshot(chip, port);
0975 }
0976 
0977 static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
0978     { "in_good_octets",     8, 0x00, STATS_TYPE_BANK0, },
0979     { "in_bad_octets",      4, 0x02, STATS_TYPE_BANK0, },
0980     { "in_unicast",         4, 0x04, STATS_TYPE_BANK0, },
0981     { "in_broadcasts",      4, 0x06, STATS_TYPE_BANK0, },
0982     { "in_multicasts",      4, 0x07, STATS_TYPE_BANK0, },
0983     { "in_pause",           4, 0x16, STATS_TYPE_BANK0, },
0984     { "in_undersize",       4, 0x18, STATS_TYPE_BANK0, },
0985     { "in_fragments",       4, 0x19, STATS_TYPE_BANK0, },
0986     { "in_oversize",        4, 0x1a, STATS_TYPE_BANK0, },
0987     { "in_jabber",          4, 0x1b, STATS_TYPE_BANK0, },
0988     { "in_rx_error",        4, 0x1c, STATS_TYPE_BANK0, },
0989     { "in_fcs_error",       4, 0x1d, STATS_TYPE_BANK0, },
0990     { "out_octets",         8, 0x0e, STATS_TYPE_BANK0, },
0991     { "out_unicast",        4, 0x10, STATS_TYPE_BANK0, },
0992     { "out_broadcasts",     4, 0x13, STATS_TYPE_BANK0, },
0993     { "out_multicasts",     4, 0x12, STATS_TYPE_BANK0, },
0994     { "out_pause",          4, 0x15, STATS_TYPE_BANK0, },
0995     { "excessive",          4, 0x11, STATS_TYPE_BANK0, },
0996     { "collisions",         4, 0x1e, STATS_TYPE_BANK0, },
0997     { "deferred",           4, 0x05, STATS_TYPE_BANK0, },
0998     { "single",         4, 0x14, STATS_TYPE_BANK0, },
0999     { "multiple",           4, 0x17, STATS_TYPE_BANK0, },
1000     { "out_fcs_error",      4, 0x03, STATS_TYPE_BANK0, },
1001     { "late",           4, 0x1f, STATS_TYPE_BANK0, },
1002     { "hist_64bytes",       4, 0x08, STATS_TYPE_BANK0, },
1003     { "hist_65_127bytes",       4, 0x09, STATS_TYPE_BANK0, },
1004     { "hist_128_255bytes",      4, 0x0a, STATS_TYPE_BANK0, },
1005     { "hist_256_511bytes",      4, 0x0b, STATS_TYPE_BANK0, },
1006     { "hist_512_1023bytes",     4, 0x0c, STATS_TYPE_BANK0, },
1007     { "hist_1024_max_bytes",    4, 0x0d, STATS_TYPE_BANK0, },
1008     { "sw_in_discards",     4, 0x10, STATS_TYPE_PORT, },
1009     { "sw_in_filtered",     2, 0x12, STATS_TYPE_PORT, },
1010     { "sw_out_filtered",        2, 0x13, STATS_TYPE_PORT, },
1011     { "in_discards",        4, 0x00, STATS_TYPE_BANK1, },
1012     { "in_filtered",        4, 0x01, STATS_TYPE_BANK1, },
1013     { "in_accepted",        4, 0x02, STATS_TYPE_BANK1, },
1014     { "in_bad_accepted",        4, 0x03, STATS_TYPE_BANK1, },
1015     { "in_good_avb_class_a",    4, 0x04, STATS_TYPE_BANK1, },
1016     { "in_good_avb_class_b",    4, 0x05, STATS_TYPE_BANK1, },
1017     { "in_bad_avb_class_a",     4, 0x06, STATS_TYPE_BANK1, },
1018     { "in_bad_avb_class_b",     4, 0x07, STATS_TYPE_BANK1, },
1019     { "tcam_counter_0",     4, 0x08, STATS_TYPE_BANK1, },
1020     { "tcam_counter_1",     4, 0x09, STATS_TYPE_BANK1, },
1021     { "tcam_counter_2",     4, 0x0a, STATS_TYPE_BANK1, },
1022     { "tcam_counter_3",     4, 0x0b, STATS_TYPE_BANK1, },
1023     { "in_da_unknown",      4, 0x0e, STATS_TYPE_BANK1, },
1024     { "in_management",      4, 0x0f, STATS_TYPE_BANK1, },
1025     { "out_queue_0",        4, 0x10, STATS_TYPE_BANK1, },
1026     { "out_queue_1",        4, 0x11, STATS_TYPE_BANK1, },
1027     { "out_queue_2",        4, 0x12, STATS_TYPE_BANK1, },
1028     { "out_queue_3",        4, 0x13, STATS_TYPE_BANK1, },
1029     { "out_queue_4",        4, 0x14, STATS_TYPE_BANK1, },
1030     { "out_queue_5",        4, 0x15, STATS_TYPE_BANK1, },
1031     { "out_queue_6",        4, 0x16, STATS_TYPE_BANK1, },
1032     { "out_queue_7",        4, 0x17, STATS_TYPE_BANK1, },
1033     { "out_cut_through",        4, 0x18, STATS_TYPE_BANK1, },
1034     { "out_octets_a",       4, 0x1a, STATS_TYPE_BANK1, },
1035     { "out_octets_b",       4, 0x1b, STATS_TYPE_BANK1, },
1036     { "out_management",     4, 0x1f, STATS_TYPE_BANK1, },
1037 };
1038 
1039 static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
1040                         struct mv88e6xxx_hw_stat *s,
1041                         int port, u16 bank1_select,
1042                         u16 histogram)
1043 {
1044     u32 low;
1045     u32 high = 0;
1046     u16 reg = 0;
1047     int err;
1048     u64 value;
1049 
1050     switch (s->type) {
1051     case STATS_TYPE_PORT:
1052         err = mv88e6xxx_port_read(chip, port, s->reg, &reg);
1053         if (err)
1054             return U64_MAX;
1055 
1056         low = reg;
1057         if (s->size == 4) {
1058             err = mv88e6xxx_port_read(chip, port, s->reg + 1, &reg);
1059             if (err)
1060                 return U64_MAX;
1061             low |= ((u32)reg) << 16;
1062         }
1063         break;
1064     case STATS_TYPE_BANK1:
1065         reg = bank1_select;
1066         fallthrough;
1067     case STATS_TYPE_BANK0:
1068         reg |= s->reg | histogram;
1069         mv88e6xxx_g1_stats_read(chip, reg, &low);
1070         if (s->size == 8)
1071             mv88e6xxx_g1_stats_read(chip, reg + 1, &high);
1072         break;
1073     default:
1074         return U64_MAX;
1075     }
1076     value = (((u64)high) << 32) | low;
1077     return value;
1078 }
1079 
1080 static int mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip,
1081                        uint8_t *data, int types)
1082 {
1083     struct mv88e6xxx_hw_stat *stat;
1084     int i, j;
1085 
1086     for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
1087         stat = &mv88e6xxx_hw_stats[i];
1088         if (stat->type & types) {
1089             memcpy(data + j * ETH_GSTRING_LEN, stat->string,
1090                    ETH_GSTRING_LEN);
1091             j++;
1092         }
1093     }
1094 
1095     return j;
1096 }
1097 
1098 static int mv88e6095_stats_get_strings(struct mv88e6xxx_chip *chip,
1099                        uint8_t *data)
1100 {
1101     return mv88e6xxx_stats_get_strings(chip, data,
1102                        STATS_TYPE_BANK0 | STATS_TYPE_PORT);
1103 }
1104 
1105 static int mv88e6250_stats_get_strings(struct mv88e6xxx_chip *chip,
1106                        uint8_t *data)
1107 {
1108     return mv88e6xxx_stats_get_strings(chip, data, STATS_TYPE_BANK0);
1109 }
1110 
1111 static int mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip,
1112                        uint8_t *data)
1113 {
1114     return mv88e6xxx_stats_get_strings(chip, data,
1115                        STATS_TYPE_BANK0 | STATS_TYPE_BANK1);
1116 }
1117 
1118 static const uint8_t *mv88e6xxx_atu_vtu_stats_strings[] = {
1119     "atu_member_violation",
1120     "atu_miss_violation",
1121     "atu_full_violation",
1122     "vtu_member_violation",
1123     "vtu_miss_violation",
1124 };
1125 
1126 static void mv88e6xxx_atu_vtu_get_strings(uint8_t *data)
1127 {
1128     unsigned int i;
1129 
1130     for (i = 0; i < ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings); i++)
1131         strlcpy(data + i * ETH_GSTRING_LEN,
1132             mv88e6xxx_atu_vtu_stats_strings[i],
1133             ETH_GSTRING_LEN);
1134 }
1135 
1136 static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
1137                   u32 stringset, uint8_t *data)
1138 {
1139     struct mv88e6xxx_chip *chip = ds->priv;
1140     int count = 0;
1141 
1142     if (stringset != ETH_SS_STATS)
1143         return;
1144 
1145     mv88e6xxx_reg_lock(chip);
1146 
1147     if (chip->info->ops->stats_get_strings)
1148         count = chip->info->ops->stats_get_strings(chip, data);
1149 
1150     if (chip->info->ops->serdes_get_strings) {
1151         data += count * ETH_GSTRING_LEN;
1152         count = chip->info->ops->serdes_get_strings(chip, port, data);
1153     }
1154 
1155     data += count * ETH_GSTRING_LEN;
1156     mv88e6xxx_atu_vtu_get_strings(data);
1157 
1158     mv88e6xxx_reg_unlock(chip);
1159 }
1160 
1161 static int mv88e6xxx_stats_get_sset_count(struct mv88e6xxx_chip *chip,
1162                       int types)
1163 {
1164     struct mv88e6xxx_hw_stat *stat;
1165     int i, j;
1166 
1167     for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
1168         stat = &mv88e6xxx_hw_stats[i];
1169         if (stat->type & types)
1170             j++;
1171     }
1172     return j;
1173 }
1174 
1175 static int mv88e6095_stats_get_sset_count(struct mv88e6xxx_chip *chip)
1176 {
1177     return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 |
1178                           STATS_TYPE_PORT);
1179 }
1180 
1181 static int mv88e6250_stats_get_sset_count(struct mv88e6xxx_chip *chip)
1182 {
1183     return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0);
1184 }
1185 
1186 static int mv88e6320_stats_get_sset_count(struct mv88e6xxx_chip *chip)
1187 {
1188     return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 |
1189                           STATS_TYPE_BANK1);
1190 }
1191 
1192 static int mv88e6xxx_get_sset_count(struct dsa_switch *ds, int port, int sset)
1193 {
1194     struct mv88e6xxx_chip *chip = ds->priv;
1195     int serdes_count = 0;
1196     int count = 0;
1197 
1198     if (sset != ETH_SS_STATS)
1199         return 0;
1200 
1201     mv88e6xxx_reg_lock(chip);
1202     if (chip->info->ops->stats_get_sset_count)
1203         count = chip->info->ops->stats_get_sset_count(chip);
1204     if (count < 0)
1205         goto out;
1206 
1207     if (chip->info->ops->serdes_get_sset_count)
1208         serdes_count = chip->info->ops->serdes_get_sset_count(chip,
1209                                       port);
1210     if (serdes_count < 0) {
1211         count = serdes_count;
1212         goto out;
1213     }
1214     count += serdes_count;
1215     count += ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings);
1216 
1217 out:
1218     mv88e6xxx_reg_unlock(chip);
1219 
1220     return count;
1221 }
1222 
1223 static int mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
1224                      uint64_t *data, int types,
1225                      u16 bank1_select, u16 histogram)
1226 {
1227     struct mv88e6xxx_hw_stat *stat;
1228     int i, j;
1229 
1230     for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
1231         stat = &mv88e6xxx_hw_stats[i];
1232         if (stat->type & types) {
1233             mv88e6xxx_reg_lock(chip);
1234             data[j] = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
1235                                   bank1_select,
1236                                   histogram);
1237             mv88e6xxx_reg_unlock(chip);
1238 
1239             j++;
1240         }
1241     }
1242     return j;
1243 }
1244 
1245 static int mv88e6095_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
1246                      uint64_t *data)
1247 {
1248     return mv88e6xxx_stats_get_stats(chip, port, data,
1249                      STATS_TYPE_BANK0 | STATS_TYPE_PORT,
1250                      0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
1251 }
1252 
1253 static int mv88e6250_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
1254                      uint64_t *data)
1255 {
1256     return mv88e6xxx_stats_get_stats(chip, port, data, STATS_TYPE_BANK0,
1257                      0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
1258 }
1259 
1260 static int mv88e6320_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
1261                      uint64_t *data)
1262 {
1263     return mv88e6xxx_stats_get_stats(chip, port, data,
1264                      STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
1265                      MV88E6XXX_G1_STATS_OP_BANK_1_BIT_9,
1266                      MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
1267 }
1268 
1269 static int mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
1270                      uint64_t *data)
1271 {
1272     return mv88e6xxx_stats_get_stats(chip, port, data,
1273                      STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
1274                      MV88E6XXX_G1_STATS_OP_BANK_1_BIT_10,
1275                      0);
1276 }
1277 
1278 static void mv88e6xxx_atu_vtu_get_stats(struct mv88e6xxx_chip *chip, int port,
1279                     uint64_t *data)
1280 {
1281     *data++ = chip->ports[port].atu_member_violation;
1282     *data++ = chip->ports[port].atu_miss_violation;
1283     *data++ = chip->ports[port].atu_full_violation;
1284     *data++ = chip->ports[port].vtu_member_violation;
1285     *data++ = chip->ports[port].vtu_miss_violation;
1286 }
1287 
1288 static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
1289                 uint64_t *data)
1290 {
1291     int count = 0;
1292 
1293     if (chip->info->ops->stats_get_stats)
1294         count = chip->info->ops->stats_get_stats(chip, port, data);
1295 
1296     mv88e6xxx_reg_lock(chip);
1297     if (chip->info->ops->serdes_get_stats) {
1298         data += count;
1299         count = chip->info->ops->serdes_get_stats(chip, port, data);
1300     }
1301     data += count;
1302     mv88e6xxx_atu_vtu_get_stats(chip, port, data);
1303     mv88e6xxx_reg_unlock(chip);
1304 }
1305 
1306 static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
1307                     uint64_t *data)
1308 {
1309     struct mv88e6xxx_chip *chip = ds->priv;
1310     int ret;
1311 
1312     mv88e6xxx_reg_lock(chip);
1313 
1314     ret = mv88e6xxx_stats_snapshot(chip, port);
1315     mv88e6xxx_reg_unlock(chip);
1316 
1317     if (ret < 0)
1318         return;
1319 
1320     mv88e6xxx_get_stats(chip, port, data);
1321 
1322 }
1323 
1324 static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
1325 {
1326     struct mv88e6xxx_chip *chip = ds->priv;
1327     int len;
1328 
1329     len = 32 * sizeof(u16);
1330     if (chip->info->ops->serdes_get_regs_len)
1331         len += chip->info->ops->serdes_get_regs_len(chip, port);
1332 
1333     return len;
1334 }
1335 
1336 static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
1337                    struct ethtool_regs *regs, void *_p)
1338 {
1339     struct mv88e6xxx_chip *chip = ds->priv;
1340     int err;
1341     u16 reg;
1342     u16 *p = _p;
1343     int i;
1344 
1345     regs->version = chip->info->prod_num;
1346 
1347     memset(p, 0xff, 32 * sizeof(u16));
1348 
1349     mv88e6xxx_reg_lock(chip);
1350 
1351     for (i = 0; i < 32; i++) {
1352 
1353         err = mv88e6xxx_port_read(chip, port, i, &reg);
1354         if (!err)
1355             p[i] = reg;
1356     }
1357 
1358     if (chip->info->ops->serdes_get_regs)
1359         chip->info->ops->serdes_get_regs(chip, port, &p[i]);
1360 
1361     mv88e6xxx_reg_unlock(chip);
1362 }
1363 
1364 static int mv88e6xxx_get_mac_eee(struct dsa_switch *ds, int port,
1365                  struct ethtool_eee *e)
1366 {
1367     /* Nothing to do on the port's MAC */
1368     return 0;
1369 }
1370 
1371 static int mv88e6xxx_set_mac_eee(struct dsa_switch *ds, int port,
1372                  struct ethtool_eee *e)
1373 {
1374     /* Nothing to do on the port's MAC */
1375     return 0;
1376 }
1377 
1378 /* Mask of the local ports allowed to receive frames from a given fabric port */
1379 static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port)
1380 {
1381     struct dsa_switch *ds = chip->ds;
1382     struct dsa_switch_tree *dst = ds->dst;
1383     struct dsa_port *dp, *other_dp;
1384     bool found = false;
1385     u16 pvlan;
1386 
1387     /* dev is a physical switch */
1388     if (dev <= dst->last_switch) {
1389         list_for_each_entry(dp, &dst->ports, list) {
1390             if (dp->ds->index == dev && dp->index == port) {
1391                 /* dp might be a DSA link or a user port, so it
1392                  * might or might not have a bridge.
1393                  * Use the "found" variable for both cases.
1394                  */
1395                 found = true;
1396                 break;
1397             }
1398         }
1399     /* dev is a virtual bridge */
1400     } else {
1401         list_for_each_entry(dp, &dst->ports, list) {
1402             unsigned int bridge_num = dsa_port_bridge_num_get(dp);
1403 
1404             if (!bridge_num)
1405                 continue;
1406 
1407             if (bridge_num + dst->last_switch != dev)
1408                 continue;
1409 
1410             found = true;
1411             break;
1412         }
1413     }
1414 
1415     /* Prevent frames from unknown switch or virtual bridge */
1416     if (!found)
1417         return 0;
1418 
1419     /* Frames from DSA links and CPU ports can egress any local port */
1420     if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA)
1421         return mv88e6xxx_port_mask(chip);
1422 
1423     pvlan = 0;
1424 
1425     /* Frames from standalone user ports can only egress on the
1426      * upstream port.
1427      */
1428     if (!dsa_port_bridge_dev_get(dp))
1429         return BIT(dsa_switch_upstream_port(ds));
1430 
1431     /* Frames from bridged user ports can egress any local DSA
1432      * links and CPU ports, as well as any local member of their
1433      * bridge group.
1434      */
1435     dsa_switch_for_each_port(other_dp, ds)
1436         if (other_dp->type == DSA_PORT_TYPE_CPU ||
1437             other_dp->type == DSA_PORT_TYPE_DSA ||
1438             dsa_port_bridge_same(dp, other_dp))
1439             pvlan |= BIT(other_dp->index);
1440 
1441     return pvlan;
1442 }
1443 
1444 static int mv88e6xxx_port_vlan_map(struct mv88e6xxx_chip *chip, int port)
1445 {
1446     u16 output_ports = mv88e6xxx_port_vlan(chip, chip->ds->index, port);
1447 
1448     /* prevent frames from going back out of the port they came in on */
1449     output_ports &= ~BIT(port);
1450 
1451     return mv88e6xxx_port_set_vlan_map(chip, port, output_ports);
1452 }
1453 
1454 static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
1455                      u8 state)
1456 {
1457     struct mv88e6xxx_chip *chip = ds->priv;
1458     int err;
1459 
1460     mv88e6xxx_reg_lock(chip);
1461     err = mv88e6xxx_port_set_state(chip, port, state);
1462     mv88e6xxx_reg_unlock(chip);
1463 
1464     if (err)
1465         dev_err(ds->dev, "p%d: failed to update state\n", port);
1466 }
1467 
1468 static int mv88e6xxx_pri_setup(struct mv88e6xxx_chip *chip)
1469 {
1470     int err;
1471 
1472     if (chip->info->ops->ieee_pri_map) {
1473         err = chip->info->ops->ieee_pri_map(chip);
1474         if (err)
1475             return err;
1476     }
1477 
1478     if (chip->info->ops->ip_pri_map) {
1479         err = chip->info->ops->ip_pri_map(chip);
1480         if (err)
1481             return err;
1482     }
1483 
1484     return 0;
1485 }
1486 
1487 static int mv88e6xxx_devmap_setup(struct mv88e6xxx_chip *chip)
1488 {
1489     struct dsa_switch *ds = chip->ds;
1490     int target, port;
1491     int err;
1492 
1493     if (!chip->info->global2_addr)
1494         return 0;
1495 
1496     /* Initialize the routing port to the 32 possible target devices */
1497     for (target = 0; target < 32; target++) {
1498         port = dsa_routing_port(ds, target);
1499         if (port == ds->num_ports)
1500             port = 0x1f;
1501 
1502         err = mv88e6xxx_g2_device_mapping_write(chip, target, port);
1503         if (err)
1504             return err;
1505     }
1506 
1507     if (chip->info->ops->set_cascade_port) {
1508         port = MV88E6XXX_CASCADE_PORT_MULTIPLE;
1509         err = chip->info->ops->set_cascade_port(chip, port);
1510         if (err)
1511             return err;
1512     }
1513 
1514     err = mv88e6xxx_g1_set_device_number(chip, chip->ds->index);
1515     if (err)
1516         return err;
1517 
1518     return 0;
1519 }
1520 
1521 static int mv88e6xxx_trunk_setup(struct mv88e6xxx_chip *chip)
1522 {
1523     /* Clear all trunk masks and mapping */
1524     if (chip->info->global2_addr)
1525         return mv88e6xxx_g2_trunk_clear(chip);
1526 
1527     return 0;
1528 }
1529 
1530 static int mv88e6xxx_rmu_setup(struct mv88e6xxx_chip *chip)
1531 {
1532     if (chip->info->ops->rmu_disable)
1533         return chip->info->ops->rmu_disable(chip);
1534 
1535     return 0;
1536 }
1537 
1538 static int mv88e6xxx_pot_setup(struct mv88e6xxx_chip *chip)
1539 {
1540     if (chip->info->ops->pot_clear)
1541         return chip->info->ops->pot_clear(chip);
1542 
1543     return 0;
1544 }
1545 
1546 static int mv88e6xxx_rsvd2cpu_setup(struct mv88e6xxx_chip *chip)
1547 {
1548     if (chip->info->ops->mgmt_rsvd2cpu)
1549         return chip->info->ops->mgmt_rsvd2cpu(chip);
1550 
1551     return 0;
1552 }
1553 
1554 static int mv88e6xxx_atu_setup(struct mv88e6xxx_chip *chip)
1555 {
1556     int err;
1557 
1558     err = mv88e6xxx_g1_atu_flush(chip, 0, true);
1559     if (err)
1560         return err;
1561 
1562     /* The chips that have a "learn2all" bit in Global1, ATU
1563      * Control are precisely those whose port registers have a
1564      * Message Port bit in Port Control 1 and hence implement
1565      * ->port_setup_message_port.
1566      */
1567     if (chip->info->ops->port_setup_message_port) {
1568         err = mv88e6xxx_g1_atu_set_learn2all(chip, true);
1569         if (err)
1570             return err;
1571     }
1572 
1573     return mv88e6xxx_g1_atu_set_age_time(chip, 300000);
1574 }
1575 
1576 static int mv88e6xxx_irl_setup(struct mv88e6xxx_chip *chip)
1577 {
1578     int port;
1579     int err;
1580 
1581     if (!chip->info->ops->irl_init_all)
1582         return 0;
1583 
1584     for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
1585         /* Disable ingress rate limiting by resetting all per port
1586          * ingress rate limit resources to their initial state.
1587          */
1588         err = chip->info->ops->irl_init_all(chip, port);
1589         if (err)
1590             return err;
1591     }
1592 
1593     return 0;
1594 }
1595 
1596 static int mv88e6xxx_mac_setup(struct mv88e6xxx_chip *chip)
1597 {
1598     if (chip->info->ops->set_switch_mac) {
1599         u8 addr[ETH_ALEN];
1600 
1601         eth_random_addr(addr);
1602 
1603         return chip->info->ops->set_switch_mac(chip, addr);
1604     }
1605 
1606     return 0;
1607 }
1608 
1609 static int mv88e6xxx_pvt_map(struct mv88e6xxx_chip *chip, int dev, int port)
1610 {
1611     struct dsa_switch_tree *dst = chip->ds->dst;
1612     struct dsa_switch *ds;
1613     struct dsa_port *dp;
1614     u16 pvlan = 0;
1615 
1616     if (!mv88e6xxx_has_pvt(chip))
1617         return 0;
1618 
1619     /* Skip the local source device, which uses in-chip port VLAN */
1620     if (dev != chip->ds->index) {
1621         pvlan = mv88e6xxx_port_vlan(chip, dev, port);
1622 
1623         ds = dsa_switch_find(dst->index, dev);
1624         dp = ds ? dsa_to_port(ds, port) : NULL;
1625         if (dp && dp->lag) {
1626             /* As the PVT is used to limit flooding of
1627              * FORWARD frames, which use the LAG ID as the
1628              * source port, we must translate dev/port to
1629              * the special "LAG device" in the PVT, using
1630              * the LAG ID (one-based) as the port number
1631              * (zero-based).
1632              */
1633             dev = MV88E6XXX_G2_PVT_ADDR_DEV_TRUNK;
1634             port = dsa_port_lag_id_get(dp) - 1;
1635         }
1636     }
1637 
1638     return mv88e6xxx_g2_pvt_write(chip, dev, port, pvlan);
1639 }
1640 
1641 static int mv88e6xxx_pvt_setup(struct mv88e6xxx_chip *chip)
1642 {
1643     int dev, port;
1644     int err;
1645 
1646     if (!mv88e6xxx_has_pvt(chip))
1647         return 0;
1648 
1649     /* Clear 5 Bit Port for usage with Marvell Link Street devices:
1650      * use 4 bits for the Src_Port/Src_Trunk and 5 bits for the Src_Dev.
1651      */
1652     err = mv88e6xxx_g2_misc_4_bit_port(chip);
1653     if (err)
1654         return err;
1655 
1656     for (dev = 0; dev < MV88E6XXX_MAX_PVT_SWITCHES; ++dev) {
1657         for (port = 0; port < MV88E6XXX_MAX_PVT_PORTS; ++port) {
1658             err = mv88e6xxx_pvt_map(chip, dev, port);
1659             if (err)
1660                 return err;
1661         }
1662     }
1663 
1664     return 0;
1665 }
1666 
1667 static int mv88e6xxx_port_fast_age_fid(struct mv88e6xxx_chip *chip, int port,
1668                        u16 fid)
1669 {
1670     if (dsa_to_port(chip->ds, port)->lag)
1671         /* Hardware is incapable of fast-aging a LAG through a
1672          * regular ATU move operation. Until we have something
1673          * more fancy in place this is a no-op.
1674          */
1675         return -EOPNOTSUPP;
1676 
1677     return mv88e6xxx_g1_atu_remove(chip, fid, port, false);
1678 }
1679 
1680 static void mv88e6xxx_port_fast_age(struct dsa_switch *ds, int port)
1681 {
1682     struct mv88e6xxx_chip *chip = ds->priv;
1683     int err;
1684 
1685     mv88e6xxx_reg_lock(chip);
1686     err = mv88e6xxx_port_fast_age_fid(chip, port, 0);
1687     mv88e6xxx_reg_unlock(chip);
1688 
1689     if (err)
1690         dev_err(chip->ds->dev, "p%d: failed to flush ATU: %d\n",
1691             port, err);
1692 }
1693 
1694 static int mv88e6xxx_vtu_setup(struct mv88e6xxx_chip *chip)
1695 {
1696     if (!mv88e6xxx_max_vid(chip))
1697         return 0;
1698 
1699     return mv88e6xxx_g1_vtu_flush(chip);
1700 }
1701 
1702 static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
1703                  struct mv88e6xxx_vtu_entry *entry)
1704 {
1705     int err;
1706 
1707     if (!chip->info->ops->vtu_getnext)
1708         return -EOPNOTSUPP;
1709 
1710     entry->vid = vid ? vid - 1 : mv88e6xxx_max_vid(chip);
1711     entry->valid = false;
1712 
1713     err = chip->info->ops->vtu_getnext(chip, entry);
1714 
1715     if (entry->vid != vid)
1716         entry->valid = false;
1717 
1718     return err;
1719 }
1720 
1721 static int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
1722                   int (*cb)(struct mv88e6xxx_chip *chip,
1723                     const struct mv88e6xxx_vtu_entry *entry,
1724                     void *priv),
1725                   void *priv)
1726 {
1727     struct mv88e6xxx_vtu_entry entry = {
1728         .vid = mv88e6xxx_max_vid(chip),
1729         .valid = false,
1730     };
1731     int err;
1732 
1733     if (!chip->info->ops->vtu_getnext)
1734         return -EOPNOTSUPP;
1735 
1736     do {
1737         err = chip->info->ops->vtu_getnext(chip, &entry);
1738         if (err)
1739             return err;
1740 
1741         if (!entry.valid)
1742             break;
1743 
1744         err = cb(chip, &entry, priv);
1745         if (err)
1746             return err;
1747     } while (entry.vid < mv88e6xxx_max_vid(chip));
1748 
1749     return 0;
1750 }
1751 
1752 static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
1753                    struct mv88e6xxx_vtu_entry *entry)
1754 {
1755     if (!chip->info->ops->vtu_loadpurge)
1756         return -EOPNOTSUPP;
1757 
1758     return chip->info->ops->vtu_loadpurge(chip, entry);
1759 }
1760 
1761 static int mv88e6xxx_fid_map_vlan(struct mv88e6xxx_chip *chip,
1762                   const struct mv88e6xxx_vtu_entry *entry,
1763                   void *_fid_bitmap)
1764 {
1765     unsigned long *fid_bitmap = _fid_bitmap;
1766 
1767     set_bit(entry->fid, fid_bitmap);
1768     return 0;
1769 }
1770 
1771 int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *fid_bitmap)
1772 {
1773     bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);
1774 
1775     /* Every FID has an associated VID, so walking the VTU
1776      * will discover the full set of FIDs in use.
1777      */
1778     return mv88e6xxx_vtu_walk(chip, mv88e6xxx_fid_map_vlan, fid_bitmap);
1779 }
1780 
1781 static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
1782 {
1783     DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID);
1784     int err;
1785 
1786     err = mv88e6xxx_fid_map(chip, fid_bitmap);
1787     if (err)
1788         return err;
1789 
1790     *fid = find_first_zero_bit(fid_bitmap, MV88E6XXX_N_FID);
1791     if (unlikely(*fid >= mv88e6xxx_num_databases(chip)))
1792         return -ENOSPC;
1793 
1794     /* Clear the database */
1795     return mv88e6xxx_g1_atu_flush(chip, *fid, true);
1796 }
1797 
1798 static int mv88e6xxx_stu_loadpurge(struct mv88e6xxx_chip *chip,
1799                    struct mv88e6xxx_stu_entry *entry)
1800 {
1801     if (!chip->info->ops->stu_loadpurge)
1802         return -EOPNOTSUPP;
1803 
1804     return chip->info->ops->stu_loadpurge(chip, entry);
1805 }
1806 
1807 static int mv88e6xxx_stu_setup(struct mv88e6xxx_chip *chip)
1808 {
1809     struct mv88e6xxx_stu_entry stu = {
1810         .valid = true,
1811         .sid = 0
1812     };
1813 
1814     if (!mv88e6xxx_has_stu(chip))
1815         return 0;
1816 
1817     /* Make sure that SID 0 is always valid. This is used by VTU
1818      * entries that do not make use of the STU, e.g. when creating
1819      * a VLAN upper on a port that is also part of a VLAN
1820      * filtering bridge.
1821      */
1822     return mv88e6xxx_stu_loadpurge(chip, &stu);
1823 }
1824 
1825 static int mv88e6xxx_sid_get(struct mv88e6xxx_chip *chip, u8 *sid)
1826 {
1827     DECLARE_BITMAP(busy, MV88E6XXX_N_SID) = { 0 };
1828     struct mv88e6xxx_mst *mst;
1829 
1830     __set_bit(0, busy);
1831 
1832     list_for_each_entry(mst, &chip->msts, node)
1833         __set_bit(mst->stu.sid, busy);
1834 
1835     *sid = find_first_zero_bit(busy, MV88E6XXX_N_SID);
1836 
1837     return (*sid >= mv88e6xxx_max_sid(chip)) ? -ENOSPC : 0;
1838 }
1839 
1840 static int mv88e6xxx_mst_put(struct mv88e6xxx_chip *chip, u8 sid)
1841 {
1842     struct mv88e6xxx_mst *mst, *tmp;
1843     int err;
1844 
1845     if (!sid)
1846         return 0;
1847 
1848     list_for_each_entry_safe(mst, tmp, &chip->msts, node) {
1849         if (mst->stu.sid != sid)
1850             continue;
1851 
1852         if (!refcount_dec_and_test(&mst->refcnt))
1853             return 0;
1854 
1855         mst->stu.valid = false;
1856         err = mv88e6xxx_stu_loadpurge(chip, &mst->stu);
1857         if (err) {
1858             refcount_set(&mst->refcnt, 1);
1859             return err;
1860         }
1861 
1862         list_del(&mst->node);
1863         kfree(mst);
1864         return 0;
1865     }
1866 
1867     return -ENOENT;
1868 }
1869 
1870 static int mv88e6xxx_mst_get(struct mv88e6xxx_chip *chip, struct net_device *br,
1871                  u16 msti, u8 *sid)
1872 {
1873     struct mv88e6xxx_mst *mst;
1874     int err, i;
1875 
1876     if (!mv88e6xxx_has_stu(chip)) {
1877         err = -EOPNOTSUPP;
1878         goto err;
1879     }
1880 
1881     if (!msti) {
1882         *sid = 0;
1883         return 0;
1884     }
1885 
1886     list_for_each_entry(mst, &chip->msts, node) {
1887         if (mst->br == br && mst->msti == msti) {
1888             refcount_inc(&mst->refcnt);
1889             *sid = mst->stu.sid;
1890             return 0;
1891         }
1892     }
1893 
1894     err = mv88e6xxx_sid_get(chip, sid);
1895     if (err)
1896         goto err;
1897 
1898     mst = kzalloc(sizeof(*mst), GFP_KERNEL);
1899     if (!mst) {
1900         err = -ENOMEM;
1901         goto err;
1902     }
1903 
1904     INIT_LIST_HEAD(&mst->node);
1905     refcount_set(&mst->refcnt, 1);
1906     mst->br = br;
1907     mst->msti = msti;
1908     mst->stu.valid = true;
1909     mst->stu.sid = *sid;
1910 
1911     /* The bridge starts out all ports in the disabled state. But
1912      * a STU state of disabled means to go by the port-global
1913      * state. So we set all user port's initial state to blocking,
1914      * to match the bridge's behavior.
1915      */
1916     for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
1917         mst->stu.state[i] = dsa_is_user_port(chip->ds, i) ?
1918             MV88E6XXX_PORT_CTL0_STATE_BLOCKING :
1919             MV88E6XXX_PORT_CTL0_STATE_DISABLED;
1920 
1921     err = mv88e6xxx_stu_loadpurge(chip, &mst->stu);
1922     if (err)
1923         goto err_free;
1924 
1925     list_add_tail(&mst->node, &chip->msts);
1926     return 0;
1927 
1928 err_free:
1929     kfree(mst);
1930 err:
1931     return err;
1932 }
1933 
1934 static int mv88e6xxx_port_mst_state_set(struct dsa_switch *ds, int port,
1935                     const struct switchdev_mst_state *st)
1936 {
1937     struct dsa_port *dp = dsa_to_port(ds, port);
1938     struct mv88e6xxx_chip *chip = ds->priv;
1939     struct mv88e6xxx_mst *mst;
1940     u8 state;
1941     int err;
1942 
1943     if (!mv88e6xxx_has_stu(chip))
1944         return -EOPNOTSUPP;
1945 
1946     switch (st->state) {
1947     case BR_STATE_DISABLED:
1948     case BR_STATE_BLOCKING:
1949     case BR_STATE_LISTENING:
1950         state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
1951         break;
1952     case BR_STATE_LEARNING:
1953         state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
1954         break;
1955     case BR_STATE_FORWARDING:
1956         state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
1957         break;
1958     default:
1959         return -EINVAL;
1960     }
1961 
1962     list_for_each_entry(mst, &chip->msts, node) {
1963         if (mst->br == dsa_port_bridge_dev_get(dp) &&
1964             mst->msti == st->msti) {
1965             if (mst->stu.state[port] == state)
1966                 return 0;
1967 
1968             mst->stu.state[port] = state;
1969             mv88e6xxx_reg_lock(chip);
1970             err = mv88e6xxx_stu_loadpurge(chip, &mst->stu);
1971             mv88e6xxx_reg_unlock(chip);
1972             return err;
1973         }
1974     }
1975 
1976     return -ENOENT;
1977 }
1978 
1979 static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
1980                     u16 vid)
1981 {
1982     struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
1983     struct mv88e6xxx_chip *chip = ds->priv;
1984     struct mv88e6xxx_vtu_entry vlan;
1985     int err;
1986 
1987     /* DSA and CPU ports have to be members of multiple vlans */
1988     if (dsa_port_is_dsa(dp) || dsa_port_is_cpu(dp))
1989         return 0;
1990 
1991     err = mv88e6xxx_vtu_get(chip, vid, &vlan);
1992     if (err)
1993         return err;
1994 
1995     if (!vlan.valid)
1996         return 0;
1997 
1998     dsa_switch_for_each_user_port(other_dp, ds) {
1999         struct net_device *other_br;
2000 
2001         if (vlan.member[other_dp->index] ==
2002             MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
2003             continue;
2004 
2005         if (dsa_port_bridge_same(dp, other_dp))
2006             break; /* same bridge, check next VLAN */
2007 
2008         other_br = dsa_port_bridge_dev_get(other_dp);
2009         if (!other_br)
2010             continue;
2011 
2012         dev_err(ds->dev, "p%d: hw VLAN %d already used by port %d in %s\n",
2013             port, vlan.vid, other_dp->index, netdev_name(other_br));
2014         return -EOPNOTSUPP;
2015     }
2016 
2017     return 0;
2018 }
2019 
2020 static int mv88e6xxx_port_commit_pvid(struct mv88e6xxx_chip *chip, int port)
2021 {
2022     struct dsa_port *dp = dsa_to_port(chip->ds, port);
2023     struct net_device *br = dsa_port_bridge_dev_get(dp);
2024     struct mv88e6xxx_port *p = &chip->ports[port];
2025     u16 pvid = MV88E6XXX_VID_STANDALONE;
2026     bool drop_untagged = false;
2027     int err;
2028 
2029     if (br) {
2030         if (br_vlan_enabled(br)) {
2031             pvid = p->bridge_pvid.vid;
2032             drop_untagged = !p->bridge_pvid.valid;
2033         } else {
2034             pvid = MV88E6XXX_VID_BRIDGED;
2035         }
2036     }
2037 
2038     err = mv88e6xxx_port_set_pvid(chip, port, pvid);
2039     if (err)
2040         return err;
2041 
2042     return mv88e6xxx_port_drop_untagged(chip, port, drop_untagged);
2043 }
2044 
2045 static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
2046                      bool vlan_filtering,
2047                      struct netlink_ext_ack *extack)
2048 {
2049     struct mv88e6xxx_chip *chip = ds->priv;
2050     u16 mode = vlan_filtering ? MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE :
2051         MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED;
2052     int err;
2053 
2054     if (!mv88e6xxx_max_vid(chip))
2055         return -EOPNOTSUPP;
2056 
2057     mv88e6xxx_reg_lock(chip);
2058 
2059     err = mv88e6xxx_port_set_8021q_mode(chip, port, mode);
2060     if (err)
2061         goto unlock;
2062 
2063     err = mv88e6xxx_port_commit_pvid(chip, port);
2064     if (err)
2065         goto unlock;
2066 
2067 unlock:
2068     mv88e6xxx_reg_unlock(chip);
2069 
2070     return err;
2071 }
2072 
2073 static int
2074 mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
2075                 const struct switchdev_obj_port_vlan *vlan)
2076 {
2077     struct mv88e6xxx_chip *chip = ds->priv;
2078     int err;
2079 
2080     if (!mv88e6xxx_max_vid(chip))
2081         return -EOPNOTSUPP;
2082 
2083     /* If the requested port doesn't belong to the same bridge as the VLAN
2084      * members, do not support it (yet) and fallback to software VLAN.
2085      */
2086     mv88e6xxx_reg_lock(chip);
2087     err = mv88e6xxx_port_check_hw_vlan(ds, port, vlan->vid);
2088     mv88e6xxx_reg_unlock(chip);
2089 
2090     return err;
2091 }
2092 
2093 static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
2094                     const unsigned char *addr, u16 vid,
2095                     u8 state)
2096 {
2097     struct mv88e6xxx_atu_entry entry;
2098     struct mv88e6xxx_vtu_entry vlan;
2099     u16 fid;
2100     int err;
2101 
2102     /* Ports have two private address databases: one for when the port is
2103      * standalone and one for when the port is under a bridge and the
2104      * 802.1Q mode is disabled. When the port is standalone, DSA wants its
2105      * address database to remain 100% empty, so we never load an ATU entry
2106      * into a standalone port's database. Therefore, translate the null
2107      * VLAN ID into the port's database used for VLAN-unaware bridging.
2108      */
2109     if (vid == 0) {
2110         fid = MV88E6XXX_FID_BRIDGED;
2111     } else {
2112         err = mv88e6xxx_vtu_get(chip, vid, &vlan);
2113         if (err)
2114             return err;
2115 
2116         /* switchdev expects -EOPNOTSUPP to honor software VLANs */
2117         if (!vlan.valid)
2118             return -EOPNOTSUPP;
2119 
2120         fid = vlan.fid;
2121     }
2122 
2123     entry.state = 0;
2124     ether_addr_copy(entry.mac, addr);
2125     eth_addr_dec(entry.mac);
2126 
2127     err = mv88e6xxx_g1_atu_getnext(chip, fid, &entry);
2128     if (err)
2129         return err;
2130 
2131     /* Initialize a fresh ATU entry if it isn't found */
2132     if (!entry.state || !ether_addr_equal(entry.mac, addr)) {
2133         memset(&entry, 0, sizeof(entry));
2134         ether_addr_copy(entry.mac, addr);
2135     }
2136 
2137     /* Purge the ATU entry only if no port is using it anymore */
2138     if (!state) {
2139         entry.portvec &= ~BIT(port);
2140         if (!entry.portvec)
2141             entry.state = 0;
2142     } else {
2143         if (state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC)
2144             entry.portvec = BIT(port);
2145         else
2146             entry.portvec |= BIT(port);
2147 
2148         entry.state = state;
2149     }
2150 
2151     return mv88e6xxx_g1_atu_loadpurge(chip, fid, &entry);
2152 }
2153 
2154 static int mv88e6xxx_policy_apply(struct mv88e6xxx_chip *chip, int port,
2155                   const struct mv88e6xxx_policy *policy)
2156 {
2157     enum mv88e6xxx_policy_mapping mapping = policy->mapping;
2158     enum mv88e6xxx_policy_action action = policy->action;
2159     const u8 *addr = policy->addr;
2160     u16 vid = policy->vid;
2161     u8 state;
2162     int err;
2163     int id;
2164 
2165     if (!chip->info->ops->port_set_policy)
2166         return -EOPNOTSUPP;
2167 
2168     switch (mapping) {
2169     case MV88E6XXX_POLICY_MAPPING_DA:
2170     case MV88E6XXX_POLICY_MAPPING_SA:
2171         if (action == MV88E6XXX_POLICY_ACTION_NORMAL)
2172             state = 0; /* Dissociate the port and address */
2173         else if (action == MV88E6XXX_POLICY_ACTION_DISCARD &&
2174              is_multicast_ether_addr(addr))
2175             state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_POLICY;
2176         else if (action == MV88E6XXX_POLICY_ACTION_DISCARD &&
2177              is_unicast_ether_addr(addr))
2178             state = MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_POLICY;
2179         else
2180             return -EOPNOTSUPP;
2181 
2182         err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
2183                            state);
2184         if (err)
2185             return err;
2186         break;
2187     default:
2188         return -EOPNOTSUPP;
2189     }
2190 
2191     /* Skip the port's policy clearing if the mapping is still in use */
2192     if (action == MV88E6XXX_POLICY_ACTION_NORMAL)
2193         idr_for_each_entry(&chip->policies, policy, id)
2194             if (policy->port == port &&
2195                 policy->mapping == mapping &&
2196                 policy->action != action)
2197                 return 0;
2198 
2199     return chip->info->ops->port_set_policy(chip, port, mapping, action);
2200 }
2201 
2202 static int mv88e6xxx_policy_insert(struct mv88e6xxx_chip *chip, int port,
2203                    struct ethtool_rx_flow_spec *fs)
2204 {
2205     struct ethhdr *mac_entry = &fs->h_u.ether_spec;
2206     struct ethhdr *mac_mask = &fs->m_u.ether_spec;
2207     enum mv88e6xxx_policy_mapping mapping;
2208     enum mv88e6xxx_policy_action action;
2209     struct mv88e6xxx_policy *policy;
2210     u16 vid = 0;
2211     u8 *addr;
2212     int err;
2213     int id;
2214 
2215     if (fs->location != RX_CLS_LOC_ANY)
2216         return -EINVAL;
2217 
2218     if (fs->ring_cookie == RX_CLS_FLOW_DISC)
2219         action = MV88E6XXX_POLICY_ACTION_DISCARD;
2220     else
2221         return -EOPNOTSUPP;
2222 
2223     switch (fs->flow_type & ~FLOW_EXT) {
2224     case ETHER_FLOW:
2225         if (!is_zero_ether_addr(mac_mask->h_dest) &&
2226             is_zero_ether_addr(mac_mask->h_source)) {
2227             mapping = MV88E6XXX_POLICY_MAPPING_DA;
2228             addr = mac_entry->h_dest;
2229         } else if (is_zero_ether_addr(mac_mask->h_dest) &&
2230             !is_zero_ether_addr(mac_mask->h_source)) {
2231             mapping = MV88E6XXX_POLICY_MAPPING_SA;
2232             addr = mac_entry->h_source;
2233         } else {
2234             /* Cannot support DA and SA mapping in the same rule */
2235             return -EOPNOTSUPP;
2236         }
2237         break;
2238     default:
2239         return -EOPNOTSUPP;
2240     }
2241 
2242     if ((fs->flow_type & FLOW_EXT) && fs->m_ext.vlan_tci) {
2243         if (fs->m_ext.vlan_tci != htons(0xffff))
2244             return -EOPNOTSUPP;
2245         vid = be16_to_cpu(fs->h_ext.vlan_tci) & VLAN_VID_MASK;
2246     }
2247 
2248     idr_for_each_entry(&chip->policies, policy, id) {
2249         if (policy->port == port && policy->mapping == mapping &&
2250             policy->action == action && policy->vid == vid &&
2251             ether_addr_equal(policy->addr, addr))
2252             return -EEXIST;
2253     }
2254 
2255     policy = devm_kzalloc(chip->dev, sizeof(*policy), GFP_KERNEL);
2256     if (!policy)
2257         return -ENOMEM;
2258 
2259     fs->location = 0;
2260     err = idr_alloc_u32(&chip->policies, policy, &fs->location, 0xffffffff,
2261                 GFP_KERNEL);
2262     if (err) {
2263         devm_kfree(chip->dev, policy);
2264         return err;
2265     }
2266 
2267     memcpy(&policy->fs, fs, sizeof(*fs));
2268     ether_addr_copy(policy->addr, addr);
2269     policy->mapping = mapping;
2270     policy->action = action;
2271     policy->port = port;
2272     policy->vid = vid;
2273 
2274     err = mv88e6xxx_policy_apply(chip, port, policy);
2275     if (err) {
2276         idr_remove(&chip->policies, fs->location);
2277         devm_kfree(chip->dev, policy);
2278         return err;
2279     }
2280 
2281     return 0;
2282 }
2283 
2284 static int mv88e6xxx_get_rxnfc(struct dsa_switch *ds, int port,
2285                    struct ethtool_rxnfc *rxnfc, u32 *rule_locs)
2286 {
2287     struct ethtool_rx_flow_spec *fs = &rxnfc->fs;
2288     struct mv88e6xxx_chip *chip = ds->priv;
2289     struct mv88e6xxx_policy *policy;
2290     int err;
2291     int id;
2292 
2293     mv88e6xxx_reg_lock(chip);
2294 
2295     switch (rxnfc->cmd) {
2296     case ETHTOOL_GRXCLSRLCNT:
2297         rxnfc->data = 0;
2298         rxnfc->data |= RX_CLS_LOC_SPECIAL;
2299         rxnfc->rule_cnt = 0;
2300         idr_for_each_entry(&chip->policies, policy, id)
2301             if (policy->port == port)
2302                 rxnfc->rule_cnt++;
2303         err = 0;
2304         break;
2305     case ETHTOOL_GRXCLSRULE:
2306         err = -ENOENT;
2307         policy = idr_find(&chip->policies, fs->location);
2308         if (policy) {
2309             memcpy(fs, &policy->fs, sizeof(*fs));
2310             err = 0;
2311         }
2312         break;
2313     case ETHTOOL_GRXCLSRLALL:
2314         rxnfc->data = 0;
2315         rxnfc->rule_cnt = 0;
2316         idr_for_each_entry(&chip->policies, policy, id)
2317             if (policy->port == port)
2318                 rule_locs[rxnfc->rule_cnt++] = id;
2319         err = 0;
2320         break;
2321     default:
2322         err = -EOPNOTSUPP;
2323         break;
2324     }
2325 
2326     mv88e6xxx_reg_unlock(chip);
2327 
2328     return err;
2329 }
2330 
2331 static int mv88e6xxx_set_rxnfc(struct dsa_switch *ds, int port,
2332                    struct ethtool_rxnfc *rxnfc)
2333 {
2334     struct ethtool_rx_flow_spec *fs = &rxnfc->fs;
2335     struct mv88e6xxx_chip *chip = ds->priv;
2336     struct mv88e6xxx_policy *policy;
2337     int err;
2338 
2339     mv88e6xxx_reg_lock(chip);
2340 
2341     switch (rxnfc->cmd) {
2342     case ETHTOOL_SRXCLSRLINS:
2343         err = mv88e6xxx_policy_insert(chip, port, fs);
2344         break;
2345     case ETHTOOL_SRXCLSRLDEL:
2346         err = -ENOENT;
2347         policy = idr_remove(&chip->policies, fs->location);
2348         if (policy) {
2349             policy->action = MV88E6XXX_POLICY_ACTION_NORMAL;
2350             err = mv88e6xxx_policy_apply(chip, port, policy);
2351             devm_kfree(chip->dev, policy);
2352         }
2353         break;
2354     default:
2355         err = -EOPNOTSUPP;
2356         break;
2357     }
2358 
2359     mv88e6xxx_reg_unlock(chip);
2360 
2361     return err;
2362 }
2363 
2364 static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port,
2365                     u16 vid)
2366 {
2367     u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC;
2368     u8 broadcast[ETH_ALEN];
2369 
2370     eth_broadcast_addr(broadcast);
2371 
2372     return mv88e6xxx_port_db_load_purge(chip, port, broadcast, vid, state);
2373 }
2374 
2375 static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid)
2376 {
2377     int port;
2378     int err;
2379 
2380     for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
2381         struct dsa_port *dp = dsa_to_port(chip->ds, port);
2382         struct net_device *brport;
2383 
2384         if (dsa_is_unused_port(chip->ds, port))
2385             continue;
2386 
2387         brport = dsa_port_to_bridge_port(dp);
2388         if (brport && !br_port_flag_is_set(brport, BR_BCAST_FLOOD))
2389             /* Skip bridged user ports where broadcast
2390              * flooding is disabled.
2391              */
2392             continue;
2393 
2394         err = mv88e6xxx_port_add_broadcast(chip, port, vid);
2395         if (err)
2396             return err;
2397     }
2398 
2399     return 0;
2400 }
2401 
2402 struct mv88e6xxx_port_broadcast_sync_ctx {
2403     int port;
2404     bool flood;
2405 };
2406 
2407 static int
2408 mv88e6xxx_port_broadcast_sync_vlan(struct mv88e6xxx_chip *chip,
2409                    const struct mv88e6xxx_vtu_entry *vlan,
2410                    void *_ctx)
2411 {
2412     struct mv88e6xxx_port_broadcast_sync_ctx *ctx = _ctx;
2413     u8 broadcast[ETH_ALEN];
2414     u8 state;
2415 
2416     if (ctx->flood)
2417         state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC;
2418     else
2419         state = MV88E6XXX_G1_ATU_DATA_STATE_MC_UNUSED;
2420 
2421     eth_broadcast_addr(broadcast);
2422 
2423     return mv88e6xxx_port_db_load_purge(chip, ctx->port, broadcast,
2424                         vlan->vid, state);
2425 }
2426 
2427 static int mv88e6xxx_port_broadcast_sync(struct mv88e6xxx_chip *chip, int port,
2428                      bool flood)
2429 {
2430     struct mv88e6xxx_port_broadcast_sync_ctx ctx = {
2431         .port = port,
2432         .flood = flood,
2433     };
2434     struct mv88e6xxx_vtu_entry vid0 = {
2435         .vid = 0,
2436     };
2437     int err;
2438 
2439     /* Update the port's private database... */
2440     err = mv88e6xxx_port_broadcast_sync_vlan(chip, &vid0, &ctx);
2441     if (err)
2442         return err;
2443 
2444     /* ...and the database for all VLANs. */
2445     return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_broadcast_sync_vlan,
2446                   &ctx);
2447 }
2448 
2449 static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port,
2450                     u16 vid, u8 member, bool warn)
2451 {
2452     const u8 non_member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
2453     struct mv88e6xxx_vtu_entry vlan;
2454     int i, err;
2455 
2456     err = mv88e6xxx_vtu_get(chip, vid, &vlan);
2457     if (err)
2458         return err;
2459 
2460     if (!vlan.valid) {
2461         memset(&vlan, 0, sizeof(vlan));
2462 
2463         if (vid == MV88E6XXX_VID_STANDALONE)
2464             vlan.policy = true;
2465 
2466         err = mv88e6xxx_atu_new(chip, &vlan.fid);
2467         if (err)
2468             return err;
2469 
2470         for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
2471             if (i == port)
2472                 vlan.member[i] = member;
2473             else
2474                 vlan.member[i] = non_member;
2475 
2476         vlan.vid = vid;
2477         vlan.valid = true;
2478 
2479         err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
2480         if (err)
2481             return err;
2482 
2483         err = mv88e6xxx_broadcast_setup(chip, vlan.vid);
2484         if (err)
2485             return err;
2486     } else if (vlan.member[port] != member) {
2487         vlan.member[port] = member;
2488 
2489         err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
2490         if (err)
2491             return err;
2492     } else if (warn) {
2493         dev_info(chip->dev, "p%d: already a member of VLAN %d\n",
2494              port, vid);
2495     }
2496 
2497     return 0;
2498 }
2499 
2500 static int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
2501                    const struct switchdev_obj_port_vlan *vlan,
2502                    struct netlink_ext_ack *extack)
2503 {
2504     struct mv88e6xxx_chip *chip = ds->priv;
2505     bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
2506     bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
2507     struct mv88e6xxx_port *p = &chip->ports[port];
2508     bool warn;
2509     u8 member;
2510     int err;
2511 
2512     if (!vlan->vid)
2513         return 0;
2514 
2515     err = mv88e6xxx_port_vlan_prepare(ds, port, vlan);
2516     if (err)
2517         return err;
2518 
2519     if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
2520         member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED;
2521     else if (untagged)
2522         member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNTAGGED;
2523     else
2524         member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_TAGGED;
2525 
2526     /* net/dsa/slave.c will call dsa_port_vlan_add() for the affected port
2527      * and then the CPU port. Do not warn for duplicates for the CPU port.
2528      */
2529     warn = !dsa_is_cpu_port(ds, port) && !dsa_is_dsa_port(ds, port);
2530 
2531     mv88e6xxx_reg_lock(chip);
2532 
2533     err = mv88e6xxx_port_vlan_join(chip, port, vlan->vid, member, warn);
2534     if (err) {
2535         dev_err(ds->dev, "p%d: failed to add VLAN %d%c\n", port,
2536             vlan->vid, untagged ? 'u' : 't');
2537         goto out;
2538     }
2539 
2540     if (pvid) {
2541         p->bridge_pvid.vid = vlan->vid;
2542         p->bridge_pvid.valid = true;
2543 
2544         err = mv88e6xxx_port_commit_pvid(chip, port);
2545         if (err)
2546             goto out;
2547     } else if (vlan->vid && p->bridge_pvid.vid == vlan->vid) {
2548         /* The old pvid was reinstalled as a non-pvid VLAN */
2549         p->bridge_pvid.valid = false;
2550 
2551         err = mv88e6xxx_port_commit_pvid(chip, port);
2552         if (err)
2553             goto out;
2554     }
2555 
2556 out:
2557     mv88e6xxx_reg_unlock(chip);
2558 
2559     return err;
2560 }
2561 
2562 static int mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip *chip,
2563                      int port, u16 vid)
2564 {
2565     struct mv88e6xxx_vtu_entry vlan;
2566     int i, err;
2567 
2568     if (!vid)
2569         return 0;
2570 
2571     err = mv88e6xxx_vtu_get(chip, vid, &vlan);
2572     if (err)
2573         return err;
2574 
2575     /* If the VLAN doesn't exist in hardware or the port isn't a member,
2576      * tell switchdev that this VLAN is likely handled in software.
2577      */
2578     if (!vlan.valid ||
2579         vlan.member[port] == MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
2580         return -EOPNOTSUPP;
2581 
2582     vlan.member[port] = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
2583 
2584     /* keep the VLAN unless all ports are excluded */
2585     vlan.valid = false;
2586     for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
2587         if (vlan.member[i] !=
2588             MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
2589             vlan.valid = true;
2590             break;
2591         }
2592     }
2593 
2594     err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
2595     if (err)
2596         return err;
2597 
2598     if (!vlan.valid) {
2599         err = mv88e6xxx_mst_put(chip, vlan.sid);
2600         if (err)
2601             return err;
2602     }
2603 
2604     return mv88e6xxx_g1_atu_remove(chip, vlan.fid, port, false);
2605 }
2606 
2607 static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
2608                    const struct switchdev_obj_port_vlan *vlan)
2609 {
2610     struct mv88e6xxx_chip *chip = ds->priv;
2611     struct mv88e6xxx_port *p = &chip->ports[port];
2612     int err = 0;
2613     u16 pvid;
2614 
2615     if (!mv88e6xxx_max_vid(chip))
2616         return -EOPNOTSUPP;
2617 
2618     /* The ATU removal procedure needs the FID to be mapped in the VTU,
2619      * but FDB deletion runs concurrently with VLAN deletion. Flush the DSA
2620      * switchdev workqueue to ensure that all FDB entries are deleted
2621      * before we remove the VLAN.
2622      */
2623     dsa_flush_workqueue();
2624 
2625     mv88e6xxx_reg_lock(chip);
2626 
2627     err = mv88e6xxx_port_get_pvid(chip, port, &pvid);
2628     if (err)
2629         goto unlock;
2630 
2631     err = mv88e6xxx_port_vlan_leave(chip, port, vlan->vid);
2632     if (err)
2633         goto unlock;
2634 
2635     if (vlan->vid == pvid) {
2636         p->bridge_pvid.valid = false;
2637 
2638         err = mv88e6xxx_port_commit_pvid(chip, port);
2639         if (err)
2640             goto unlock;
2641     }
2642 
2643 unlock:
2644     mv88e6xxx_reg_unlock(chip);
2645 
2646     return err;
2647 }
2648 
2649 static int mv88e6xxx_port_vlan_fast_age(struct dsa_switch *ds, int port, u16 vid)
2650 {
2651     struct mv88e6xxx_chip *chip = ds->priv;
2652     struct mv88e6xxx_vtu_entry vlan;
2653     int err;
2654 
2655     mv88e6xxx_reg_lock(chip);
2656 
2657     err = mv88e6xxx_vtu_get(chip, vid, &vlan);
2658     if (err)
2659         goto unlock;
2660 
2661     err = mv88e6xxx_port_fast_age_fid(chip, port, vlan.fid);
2662 
2663 unlock:
2664     mv88e6xxx_reg_unlock(chip);
2665 
2666     return err;
2667 }
2668 
2669 static int mv88e6xxx_vlan_msti_set(struct dsa_switch *ds,
2670                    struct dsa_bridge bridge,
2671                    const struct switchdev_vlan_msti *msti)
2672 {
2673     struct mv88e6xxx_chip *chip = ds->priv;
2674     struct mv88e6xxx_vtu_entry vlan;
2675     u8 old_sid, new_sid;
2676     int err;
2677 
2678     if (!mv88e6xxx_has_stu(chip))
2679         return -EOPNOTSUPP;
2680 
2681     mv88e6xxx_reg_lock(chip);
2682 
2683     err = mv88e6xxx_vtu_get(chip, msti->vid, &vlan);
2684     if (err)
2685         goto unlock;
2686 
2687     if (!vlan.valid) {
2688         err = -EINVAL;
2689         goto unlock;
2690     }
2691 
2692     old_sid = vlan.sid;
2693 
2694     err = mv88e6xxx_mst_get(chip, bridge.dev, msti->msti, &new_sid);
2695     if (err)
2696         goto unlock;
2697 
2698     if (new_sid != old_sid) {
2699         vlan.sid = new_sid;
2700 
2701         err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
2702         if (err) {
2703             mv88e6xxx_mst_put(chip, new_sid);
2704             goto unlock;
2705         }
2706     }
2707 
2708     err = mv88e6xxx_mst_put(chip, old_sid);
2709 
2710 unlock:
2711     mv88e6xxx_reg_unlock(chip);
2712     return err;
2713 }
2714 
2715 static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
2716                   const unsigned char *addr, u16 vid,
2717                   struct dsa_db db)
2718 {
2719     struct mv88e6xxx_chip *chip = ds->priv;
2720     int err;
2721 
2722     mv88e6xxx_reg_lock(chip);
2723     err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
2724                        MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
2725     mv88e6xxx_reg_unlock(chip);
2726 
2727     return err;
2728 }
2729 
2730 static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
2731                   const unsigned char *addr, u16 vid,
2732                   struct dsa_db db)
2733 {
2734     struct mv88e6xxx_chip *chip = ds->priv;
2735     int err;
2736 
2737     mv88e6xxx_reg_lock(chip);
2738     err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, 0);
2739     mv88e6xxx_reg_unlock(chip);
2740 
2741     return err;
2742 }
2743 
2744 static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
2745                       u16 fid, u16 vid, int port,
2746                       dsa_fdb_dump_cb_t *cb, void *data)
2747 {
2748     struct mv88e6xxx_atu_entry addr;
2749     bool is_static;
2750     int err;
2751 
2752     addr.state = 0;
2753     eth_broadcast_addr(addr.mac);
2754 
2755     do {
2756         err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr);
2757         if (err)
2758             return err;
2759 
2760         if (!addr.state)
2761             break;
2762 
2763         if (addr.trunk || (addr.portvec & BIT(port)) == 0)
2764             continue;
2765 
2766         if (!is_unicast_ether_addr(addr.mac))
2767             continue;
2768 
2769         is_static = (addr.state ==
2770                  MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
2771         err = cb(addr.mac, vid, is_static, data);
2772         if (err)
2773             return err;
2774     } while (!is_broadcast_ether_addr(addr.mac));
2775 
2776     return err;
2777 }
2778 
2779 struct mv88e6xxx_port_db_dump_vlan_ctx {
2780     int port;
2781     dsa_fdb_dump_cb_t *cb;
2782     void *data;
2783 };
2784 
2785 static int mv88e6xxx_port_db_dump_vlan(struct mv88e6xxx_chip *chip,
2786                        const struct mv88e6xxx_vtu_entry *entry,
2787                        void *_data)
2788 {
2789     struct mv88e6xxx_port_db_dump_vlan_ctx *ctx = _data;
2790 
2791     return mv88e6xxx_port_db_dump_fid(chip, entry->fid, entry->vid,
2792                       ctx->port, ctx->cb, ctx->data);
2793 }
2794 
2795 static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
2796                   dsa_fdb_dump_cb_t *cb, void *data)
2797 {
2798     struct mv88e6xxx_port_db_dump_vlan_ctx ctx = {
2799         .port = port,
2800         .cb = cb,
2801         .data = data,
2802     };
2803     u16 fid;
2804     int err;
2805 
2806     /* Dump port's default Filtering Information Database (VLAN ID 0) */
2807     err = mv88e6xxx_port_get_fid(chip, port, &fid);
2808     if (err)
2809         return err;
2810 
2811     err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, cb, data);
2812     if (err)
2813         return err;
2814 
2815     return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_db_dump_vlan, &ctx);
2816 }
2817 
2818 static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
2819                    dsa_fdb_dump_cb_t *cb, void *data)
2820 {
2821     struct mv88e6xxx_chip *chip = ds->priv;
2822     int err;
2823 
2824     mv88e6xxx_reg_lock(chip);
2825     err = mv88e6xxx_port_db_dump(chip, port, cb, data);
2826     mv88e6xxx_reg_unlock(chip);
2827 
2828     return err;
2829 }
2830 
2831 static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip,
2832                 struct dsa_bridge bridge)
2833 {
2834     struct dsa_switch *ds = chip->ds;
2835     struct dsa_switch_tree *dst = ds->dst;
2836     struct dsa_port *dp;
2837     int err;
2838 
2839     list_for_each_entry(dp, &dst->ports, list) {
2840         if (dsa_port_offloads_bridge(dp, &bridge)) {
2841             if (dp->ds == ds) {
2842                 /* This is a local bridge group member,
2843                  * remap its Port VLAN Map.
2844                  */
2845                 err = mv88e6xxx_port_vlan_map(chip, dp->index);
2846                 if (err)
2847                     return err;
2848             } else {
2849                 /* This is an external bridge group member,
2850                  * remap its cross-chip Port VLAN Table entry.
2851                  */
2852                 err = mv88e6xxx_pvt_map(chip, dp->ds->index,
2853                             dp->index);
2854                 if (err)
2855                     return err;
2856             }
2857         }
2858     }
2859 
2860     return 0;
2861 }
2862 
2863 /* Treat the software bridge as a virtual single-port switch behind the
2864  * CPU and map in the PVT. First dst->last_switch elements are taken by
2865  * physical switches, so start from beyond that range.
2866  */
2867 static int mv88e6xxx_map_virtual_bridge_to_pvt(struct dsa_switch *ds,
2868                            unsigned int bridge_num)
2869 {
2870     u8 dev = bridge_num + ds->dst->last_switch;
2871     struct mv88e6xxx_chip *chip = ds->priv;
2872 
2873     return mv88e6xxx_pvt_map(chip, dev, 0);
2874 }
2875 
2876 static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
2877                       struct dsa_bridge bridge,
2878                       bool *tx_fwd_offload,
2879                       struct netlink_ext_ack *extack)
2880 {
2881     struct mv88e6xxx_chip *chip = ds->priv;
2882     int err;
2883 
2884     mv88e6xxx_reg_lock(chip);
2885 
2886     err = mv88e6xxx_bridge_map(chip, bridge);
2887     if (err)
2888         goto unlock;
2889 
2890     err = mv88e6xxx_port_set_map_da(chip, port, true);
2891     if (err)
2892         goto unlock;
2893 
2894     err = mv88e6xxx_port_commit_pvid(chip, port);
2895     if (err)
2896         goto unlock;
2897 
2898     if (mv88e6xxx_has_pvt(chip)) {
2899         err = mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num);
2900         if (err)
2901             goto unlock;
2902 
2903         *tx_fwd_offload = true;
2904     }
2905 
2906 unlock:
2907     mv88e6xxx_reg_unlock(chip);
2908 
2909     return err;
2910 }
2911 
2912 static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port,
2913                     struct dsa_bridge bridge)
2914 {
2915     struct mv88e6xxx_chip *chip = ds->priv;
2916     int err;
2917 
2918     mv88e6xxx_reg_lock(chip);
2919 
2920     if (bridge.tx_fwd_offload &&
2921         mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num))
2922         dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n");
2923 
2924     if (mv88e6xxx_bridge_map(chip, bridge) ||
2925         mv88e6xxx_port_vlan_map(chip, port))
2926         dev_err(ds->dev, "failed to remap in-chip Port VLAN\n");
2927 
2928     err = mv88e6xxx_port_set_map_da(chip, port, false);
2929     if (err)
2930         dev_err(ds->dev,
2931             "port %d failed to restore map-DA: %pe\n",
2932             port, ERR_PTR(err));
2933 
2934     err = mv88e6xxx_port_commit_pvid(chip, port);
2935     if (err)
2936         dev_err(ds->dev,
2937             "port %d failed to restore standalone pvid: %pe\n",
2938             port, ERR_PTR(err));
2939 
2940     mv88e6xxx_reg_unlock(chip);
2941 }
2942 
2943 static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds,
2944                        int tree_index, int sw_index,
2945                        int port, struct dsa_bridge bridge,
2946                        struct netlink_ext_ack *extack)
2947 {
2948     struct mv88e6xxx_chip *chip = ds->priv;
2949     int err;
2950 
2951     if (tree_index != ds->dst->index)
2952         return 0;
2953 
2954     mv88e6xxx_reg_lock(chip);
2955     err = mv88e6xxx_pvt_map(chip, sw_index, port);
2956     err = err ? : mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num);
2957     mv88e6xxx_reg_unlock(chip);
2958 
2959     return err;
2960 }
2961 
2962 static void mv88e6xxx_crosschip_bridge_leave(struct dsa_switch *ds,
2963                          int tree_index, int sw_index,
2964                          int port, struct dsa_bridge bridge)
2965 {
2966     struct mv88e6xxx_chip *chip = ds->priv;
2967 
2968     if (tree_index != ds->dst->index)
2969         return;
2970 
2971     mv88e6xxx_reg_lock(chip);
2972     if (mv88e6xxx_pvt_map(chip, sw_index, port) ||
2973         mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num))
2974         dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n");
2975     mv88e6xxx_reg_unlock(chip);
2976 }
2977 
2978 static int mv88e6xxx_software_reset(struct mv88e6xxx_chip *chip)
2979 {
2980     if (chip->info->ops->reset)
2981         return chip->info->ops->reset(chip);
2982 
2983     return 0;
2984 }
2985 
2986 static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
2987 {
2988     struct gpio_desc *gpiod = chip->reset;
2989 
2990     /* If there is a GPIO connected to the reset pin, toggle it */
2991     if (gpiod) {
2992         gpiod_set_value_cansleep(gpiod, 1);
2993         usleep_range(10000, 20000);
2994         gpiod_set_value_cansleep(gpiod, 0);
2995         usleep_range(10000, 20000);
2996 
2997         mv88e6xxx_g1_wait_eeprom_done(chip);
2998     }
2999 }
3000 
3001 static int mv88e6xxx_disable_ports(struct mv88e6xxx_chip *chip)
3002 {
3003     int i, err;
3004 
3005     /* Set all ports to the Disabled state */
3006     for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
3007         err = mv88e6xxx_port_set_state(chip, i, BR_STATE_DISABLED);
3008         if (err)
3009             return err;
3010     }
3011 
3012     /* Wait for transmit queues to drain,
3013      * i.e. 2ms for a maximum frame to be transmitted at 10 Mbps.
3014      */
3015     usleep_range(2000, 4000);
3016 
3017     return 0;
3018 }
3019 
3020 static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
3021 {
3022     int err;
3023 
3024     err = mv88e6xxx_disable_ports(chip);
3025     if (err)
3026         return err;
3027 
3028     mv88e6xxx_hardware_reset(chip);
3029 
3030     return mv88e6xxx_software_reset(chip);
3031 }
3032 
3033 static int mv88e6xxx_set_port_mode(struct mv88e6xxx_chip *chip, int port,
3034                    enum mv88e6xxx_frame_mode frame,
3035                    enum mv88e6xxx_egress_mode egress, u16 etype)
3036 {
3037     int err;
3038 
3039     if (!chip->info->ops->port_set_frame_mode)
3040         return -EOPNOTSUPP;
3041 
3042     err = mv88e6xxx_port_set_egress_mode(chip, port, egress);
3043     if (err)
3044         return err;
3045 
3046     err = chip->info->ops->port_set_frame_mode(chip, port, frame);
3047     if (err)
3048         return err;
3049 
3050     if (chip->info->ops->port_set_ether_type)
3051         return chip->info->ops->port_set_ether_type(chip, port, etype);
3052 
3053     return 0;
3054 }
3055 
3056 static int mv88e6xxx_set_port_mode_normal(struct mv88e6xxx_chip *chip, int port)
3057 {
3058     return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_NORMAL,
3059                        MV88E6XXX_EGRESS_MODE_UNMODIFIED,
3060                        MV88E6XXX_PORT_ETH_TYPE_DEFAULT);
3061 }
3062 
3063 static int mv88e6xxx_set_port_mode_dsa(struct mv88e6xxx_chip *chip, int port)
3064 {
3065     return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_DSA,
3066                        MV88E6XXX_EGRESS_MODE_UNMODIFIED,
3067                        MV88E6XXX_PORT_ETH_TYPE_DEFAULT);
3068 }
3069 
3070 static int mv88e6xxx_set_port_mode_edsa(struct mv88e6xxx_chip *chip, int port)
3071 {
3072     return mv88e6xxx_set_port_mode(chip, port,
3073                        MV88E6XXX_FRAME_MODE_ETHERTYPE,
3074                        MV88E6XXX_EGRESS_MODE_ETHERTYPE,
3075                        ETH_P_EDSA);
3076 }
3077 
3078 static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)
3079 {
3080     if (dsa_is_dsa_port(chip->ds, port))
3081         return mv88e6xxx_set_port_mode_dsa(chip, port);
3082 
3083     if (dsa_is_user_port(chip->ds, port))
3084         return mv88e6xxx_set_port_mode_normal(chip, port);
3085 
3086     /* Setup CPU port mode depending on its supported tag format */
3087     if (chip->tag_protocol == DSA_TAG_PROTO_DSA)
3088         return mv88e6xxx_set_port_mode_dsa(chip, port);
3089 
3090     if (chip->tag_protocol == DSA_TAG_PROTO_EDSA)
3091         return mv88e6xxx_set_port_mode_edsa(chip, port);
3092 
3093     return -EINVAL;
3094 }
3095 
3096 static int mv88e6xxx_setup_message_port(struct mv88e6xxx_chip *chip, int port)
3097 {
3098     bool message = dsa_is_dsa_port(chip->ds, port);
3099 
3100     return mv88e6xxx_port_set_message_port(chip, port, message);
3101 }
3102 
3103 static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
3104 {
3105     int err;
3106 
3107     if (chip->info->ops->port_set_ucast_flood) {
3108         err = chip->info->ops->port_set_ucast_flood(chip, port, true);
3109         if (err)
3110             return err;
3111     }
3112     if (chip->info->ops->port_set_mcast_flood) {
3113         err = chip->info->ops->port_set_mcast_flood(chip, port, true);
3114         if (err)
3115             return err;
3116     }
3117 
3118     return 0;
3119 }
3120 
3121 static irqreturn_t mv88e6xxx_serdes_irq_thread_fn(int irq, void *dev_id)
3122 {
3123     struct mv88e6xxx_port *mvp = dev_id;
3124     struct mv88e6xxx_chip *chip = mvp->chip;
3125     irqreturn_t ret = IRQ_NONE;
3126     int port = mvp->port;
3127     int lane;
3128 
3129     mv88e6xxx_reg_lock(chip);
3130     lane = mv88e6xxx_serdes_get_lane(chip, port);
3131     if (lane >= 0)
3132         ret = mv88e6xxx_serdes_irq_status(chip, port, lane);
3133     mv88e6xxx_reg_unlock(chip);
3134 
3135     return ret;
3136 }
3137 
3138 static int mv88e6xxx_serdes_irq_request(struct mv88e6xxx_chip *chip, int port,
3139                     int lane)
3140 {
3141     struct mv88e6xxx_port *dev_id = &chip->ports[port];
3142     unsigned int irq;
3143     int err;
3144 
3145     /* Nothing to request if this SERDES port has no IRQ */
3146     irq = mv88e6xxx_serdes_irq_mapping(chip, port);
3147     if (!irq)
3148         return 0;
3149 
3150     snprintf(dev_id->serdes_irq_name, sizeof(dev_id->serdes_irq_name),
3151          "mv88e6xxx-%s-serdes-%d", dev_name(chip->dev), port);
3152 
3153     /* Requesting the IRQ will trigger IRQ callbacks, so release the lock */
3154     mv88e6xxx_reg_unlock(chip);
3155     err = request_threaded_irq(irq, NULL, mv88e6xxx_serdes_irq_thread_fn,
3156                    IRQF_ONESHOT, dev_id->serdes_irq_name,
3157                    dev_id);
3158     mv88e6xxx_reg_lock(chip);
3159     if (err)
3160         return err;
3161 
3162     dev_id->serdes_irq = irq;
3163 
3164     return mv88e6xxx_serdes_irq_enable(chip, port, lane);
3165 }
3166 
3167 static int mv88e6xxx_serdes_irq_free(struct mv88e6xxx_chip *chip, int port,
3168                      int lane)
3169 {
3170     struct mv88e6xxx_port *dev_id = &chip->ports[port];
3171     unsigned int irq = dev_id->serdes_irq;
3172     int err;
3173 
3174     /* Nothing to free if no IRQ has been requested */
3175     if (!irq)
3176         return 0;
3177 
3178     err = mv88e6xxx_serdes_irq_disable(chip, port, lane);
3179 
3180     /* Freeing the IRQ will trigger IRQ callbacks, so release the lock */
3181     mv88e6xxx_reg_unlock(chip);
3182     free_irq(irq, dev_id);
3183     mv88e6xxx_reg_lock(chip);
3184 
3185     dev_id->serdes_irq = 0;
3186 
3187     return err;
3188 }
3189 
3190 static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
3191                   bool on)
3192 {
3193     int lane;
3194     int err;
3195 
3196     lane = mv88e6xxx_serdes_get_lane(chip, port);
3197     if (lane < 0)
3198         return 0;
3199 
3200     if (on) {
3201         err = mv88e6xxx_serdes_power_up(chip, port, lane);
3202         if (err)
3203             return err;
3204 
3205         err = mv88e6xxx_serdes_irq_request(chip, port, lane);
3206     } else {
3207         err = mv88e6xxx_serdes_irq_free(chip, port, lane);
3208         if (err)
3209             return err;
3210 
3211         err = mv88e6xxx_serdes_power_down(chip, port, lane);
3212     }
3213 
3214     return err;
3215 }
3216 
3217 static int mv88e6xxx_set_egress_port(struct mv88e6xxx_chip *chip,
3218                      enum mv88e6xxx_egress_direction direction,
3219                      int port)
3220 {
3221     int err;
3222 
3223     if (!chip->info->ops->set_egress_port)
3224         return -EOPNOTSUPP;
3225 
3226     err = chip->info->ops->set_egress_port(chip, direction, port);
3227     if (err)
3228         return err;
3229 
3230     if (direction == MV88E6XXX_EGRESS_DIR_INGRESS)
3231         chip->ingress_dest_port = port;
3232     else
3233         chip->egress_dest_port = port;
3234 
3235     return 0;
3236 }
3237 
3238 static int mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip *chip, int port)
3239 {
3240     struct dsa_switch *ds = chip->ds;
3241     int upstream_port;
3242     int err;
3243 
3244     upstream_port = dsa_upstream_port(ds, port);
3245     if (chip->info->ops->port_set_upstream_port) {
3246         err = chip->info->ops->port_set_upstream_port(chip, port,
3247                                   upstream_port);
3248         if (err)
3249             return err;
3250     }
3251 
3252     if (port == upstream_port) {
3253         if (chip->info->ops->set_cpu_port) {
3254             err = chip->info->ops->set_cpu_port(chip,
3255                                 upstream_port);
3256             if (err)
3257                 return err;
3258         }
3259 
3260         err = mv88e6xxx_set_egress_port(chip,
3261                         MV88E6XXX_EGRESS_DIR_INGRESS,
3262                         upstream_port);
3263         if (err && err != -EOPNOTSUPP)
3264             return err;
3265 
3266         err = mv88e6xxx_set_egress_port(chip,
3267                         MV88E6XXX_EGRESS_DIR_EGRESS,
3268                         upstream_port);
3269         if (err && err != -EOPNOTSUPP)
3270             return err;
3271     }
3272 
3273     return 0;
3274 }
3275 
3276 static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
3277 {
3278     struct device_node *phy_handle = NULL;
3279     struct dsa_switch *ds = chip->ds;
3280     phy_interface_t mode;
3281     struct dsa_port *dp;
3282     int tx_amp, speed;
3283     int err;
3284     u16 reg;
3285 
3286     chip->ports[port].chip = chip;
3287     chip->ports[port].port = port;
3288 
3289     dp = dsa_to_port(ds, port);
3290 
3291     /* MAC Forcing register: don't force link, speed, duplex or flow control
3292      * state to any particular values on physical ports, but force the CPU
3293      * port and all DSA ports to their maximum bandwidth and full duplex.
3294      */
3295     if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
3296         struct phylink_config pl_config = {};
3297         unsigned long caps;
3298 
3299         mv88e6xxx_get_caps(ds, port, &pl_config);
3300 
3301         caps = pl_config.mac_capabilities;
3302 
3303         if (chip->info->ops->port_max_speed_mode)
3304             mode = chip->info->ops->port_max_speed_mode(port);
3305         else
3306             mode = PHY_INTERFACE_MODE_NA;
3307 
3308         if (caps & MAC_10000FD)
3309             speed = SPEED_10000;
3310         else if (caps & MAC_5000FD)
3311             speed = SPEED_5000;
3312         else if (caps & MAC_2500FD)
3313             speed = SPEED_2500;
3314         else if (caps & MAC_1000)
3315             speed = SPEED_1000;
3316         else if (caps & MAC_100)
3317             speed = SPEED_100;
3318         else
3319             speed = SPEED_10;
3320 
3321         err = mv88e6xxx_port_setup_mac(chip, port, LINK_FORCED_UP,
3322                            speed, DUPLEX_FULL,
3323                            PAUSE_OFF, mode);
3324     } else {
3325         err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED,
3326                            SPEED_UNFORCED, DUPLEX_UNFORCED,
3327                            PAUSE_ON,
3328                            PHY_INTERFACE_MODE_NA);
3329     }
3330     if (err)
3331         return err;
3332 
3333     /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
3334      * disable Header mode, enable IGMP/MLD snooping, disable VLAN
3335      * tunneling, determine priority by looking at 802.1p and IP
3336      * priority fields (IP prio has precedence), and set STP state
3337      * to Forwarding.
3338      *
3339      * If this is the CPU link, use DSA or EDSA tagging depending
3340      * on which tagging mode was configured.
3341      *
3342      * If this is a link to another switch, use DSA tagging mode.
3343      *
3344      * If this is the upstream port for this switch, enable
3345      * forwarding of unknown unicasts and multicasts.
3346      */
3347     reg = MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP |
3348         MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
3349         MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
3350     err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
3351     if (err)
3352         return err;
3353 
3354     err = mv88e6xxx_setup_port_mode(chip, port);
3355     if (err)
3356         return err;
3357 
3358     err = mv88e6xxx_setup_egress_floods(chip, port);
3359     if (err)
3360         return err;
3361 
3362     /* Port Control 2: don't force a good FCS, set the MTU size to
3363      * 10222 bytes, disable 802.1q tags checking, don't discard
3364      * tagged or untagged frames on this port, skip destination
3365      * address lookup on user ports, disable ARP mirroring and don't
3366      * send a copy of all transmitted/received frames on this port
3367      * to the CPU.
3368      */
3369     err = mv88e6xxx_port_set_map_da(chip, port, !dsa_is_user_port(ds, port));
3370     if (err)
3371         return err;
3372 
3373     err = mv88e6xxx_setup_upstream_port(chip, port);
3374     if (err)
3375         return err;
3376 
3377     /* On chips that support it, set all downstream DSA ports'
3378      * VLAN policy to TRAP. In combination with loading
3379      * MV88E6XXX_VID_STANDALONE as a policy entry in the VTU, this
3380      * provides a better isolation barrier between standalone
3381      * ports, as the ATU is bypassed on any intermediate switches
3382      * between the incoming port and the CPU.
3383      */
3384     if (dsa_is_downstream_port(ds, port) &&
3385         chip->info->ops->port_set_policy) {
3386         err = chip->info->ops->port_set_policy(chip, port,
3387                         MV88E6XXX_POLICY_MAPPING_VTU,
3388                         MV88E6XXX_POLICY_ACTION_TRAP);
3389         if (err)
3390             return err;
3391     }
3392 
3393     /* User ports start out in standalone mode and 802.1Q is
3394      * therefore disabled. On DSA ports, all valid VIDs are always
3395      * loaded in the VTU - therefore, enable 802.1Q in order to take
3396      * advantage of VLAN policy on chips that supports it.
3397      */
3398     err = mv88e6xxx_port_set_8021q_mode(chip, port,
3399                 dsa_is_user_port(ds, port) ?
3400                 MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED :
3401                 MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE);
3402     if (err)
3403         return err;
3404 
3405     /* Bind MV88E6XXX_VID_STANDALONE to MV88E6XXX_FID_STANDALONE by
3406      * virtue of the fact that mv88e6xxx_atu_new() will pick it as
3407      * the first free FID. This will be used as the private PVID for
3408      * unbridged ports. Shared (DSA and CPU) ports must also be
3409      * members of this VID, in order to trap all frames assigned to
3410      * it to the CPU.
3411      */
3412     err = mv88e6xxx_port_vlan_join(chip, port, MV88E6XXX_VID_STANDALONE,
3413                        MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED,
3414                        false);
3415     if (err)
3416         return err;
3417 
3418     /* Associate MV88E6XXX_VID_BRIDGED with MV88E6XXX_FID_BRIDGED in the
3419      * ATU by virtue of the fact that mv88e6xxx_atu_new() will pick it as
3420      * the first free FID after MV88E6XXX_FID_STANDALONE. This will be used
3421      * as the private PVID on ports under a VLAN-unaware bridge.
3422      * Shared (DSA and CPU) ports must also be members of it, to translate
3423      * the VID from the DSA tag into MV88E6XXX_FID_BRIDGED, instead of
3424      * relying on their port default FID.
3425      */
3426     err = mv88e6xxx_port_vlan_join(chip, port, MV88E6XXX_VID_BRIDGED,
3427                        MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED,
3428                        false);
3429     if (err)
3430         return err;
3431 
3432     if (chip->info->ops->port_set_jumbo_size) {
3433         err = chip->info->ops->port_set_jumbo_size(chip, port, 10218);
3434         if (err)
3435             return err;
3436     }
3437 
3438     /* Port Association Vector: disable automatic address learning
3439      * on all user ports since they start out in standalone
3440      * mode. When joining a bridge, learning will be configured to
3441      * match the bridge port settings. Enable learning on all
3442      * DSA/CPU ports. NOTE: FROM_CPU frames always bypass the
3443      * learning process.
3444      *
3445      * Disable HoldAt1, IntOnAgeOut, LockedPort, IgnoreWrongData,
3446      * and RefreshLocked. I.e. setup standard automatic learning.
3447      */
3448     if (dsa_is_user_port(ds, port))
3449         reg = 0;
3450     else
3451         reg = 1 << port;
3452 
3453     err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
3454                    reg);
3455     if (err)
3456         return err;
3457 
3458     /* Egress rate control 2: disable egress rate control. */
3459     err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL2,
3460                    0x0000);
3461     if (err)
3462         return err;
3463 
3464     if (chip->info->ops->port_pause_limit) {
3465         err = chip->info->ops->port_pause_limit(chip, port, 0, 0);
3466         if (err)
3467             return err;
3468     }
3469 
3470     if (chip->info->ops->port_disable_learn_limit) {
3471         err = chip->info->ops->port_disable_learn_limit(chip, port);
3472         if (err)
3473             return err;
3474     }
3475 
3476     if (chip->info->ops->port_disable_pri_override) {
3477         err = chip->info->ops->port_disable_pri_override(chip, port);
3478         if (err)
3479             return err;
3480     }
3481 
3482     if (chip->info->ops->port_tag_remap) {
3483         err = chip->info->ops->port_tag_remap(chip, port);
3484         if (err)
3485             return err;
3486     }
3487 
3488     if (chip->info->ops->port_egress_rate_limiting) {
3489         err = chip->info->ops->port_egress_rate_limiting(chip, port);
3490         if (err)
3491             return err;
3492     }
3493 
3494     if (chip->info->ops->port_setup_message_port) {
3495         err = chip->info->ops->port_setup_message_port(chip, port);
3496         if (err)
3497             return err;
3498     }
3499 
3500     if (chip->info->ops->serdes_set_tx_amplitude) {
3501         if (dp)
3502             phy_handle = of_parse_phandle(dp->dn, "phy-handle", 0);
3503 
3504         if (phy_handle && !of_property_read_u32(phy_handle,
3505                             "tx-p2p-microvolt",
3506                             &tx_amp))
3507             err = chip->info->ops->serdes_set_tx_amplitude(chip,
3508                                 port, tx_amp);
3509         if (phy_handle) {
3510             of_node_put(phy_handle);
3511             if (err)
3512                 return err;
3513         }
3514     }
3515 
3516     /* Port based VLAN map: give each port the same default address
3517      * database, and allow bidirectional communication between the
3518      * CPU and DSA port(s), and the other ports.
3519      */
3520     err = mv88e6xxx_port_set_fid(chip, port, MV88E6XXX_FID_STANDALONE);
3521     if (err)
3522         return err;
3523 
3524     err = mv88e6xxx_port_vlan_map(chip, port);
3525     if (err)
3526         return err;
3527 
3528     /* Default VLAN ID and priority: don't set a default VLAN
3529      * ID, and set the default packet priority to zero.
3530      */
3531     return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 0);
3532 }
3533 
3534 static int mv88e6xxx_get_max_mtu(struct dsa_switch *ds, int port)
3535 {
3536     struct mv88e6xxx_chip *chip = ds->priv;
3537 
3538     if (chip->info->ops->port_set_jumbo_size)
3539         return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
3540     else if (chip->info->ops->set_max_frame_size)
3541         return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
3542     return 1522 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
3543 }
3544 
3545 static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
3546 {
3547     struct mv88e6xxx_chip *chip = ds->priv;
3548     int ret = 0;
3549 
3550     if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
3551         new_mtu += EDSA_HLEN;
3552 
3553     mv88e6xxx_reg_lock(chip);
3554     if (chip->info->ops->port_set_jumbo_size)
3555         ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu);
3556     else if (chip->info->ops->set_max_frame_size)
3557         ret = chip->info->ops->set_max_frame_size(chip, new_mtu);
3558     else
3559         if (new_mtu > 1522)
3560             ret = -EINVAL;
3561     mv88e6xxx_reg_unlock(chip);
3562 
3563     return ret;
3564 }
3565 
3566 static int mv88e6xxx_port_enable(struct dsa_switch *ds, int port,
3567                  struct phy_device *phydev)
3568 {
3569     struct mv88e6xxx_chip *chip = ds->priv;
3570     int err;
3571 
3572     mv88e6xxx_reg_lock(chip);
3573     err = mv88e6xxx_serdes_power(chip, port, true);
3574     mv88e6xxx_reg_unlock(chip);
3575 
3576     return err;
3577 }
3578 
3579 static void mv88e6xxx_port_disable(struct dsa_switch *ds, int port)
3580 {
3581     struct mv88e6xxx_chip *chip = ds->priv;
3582 
3583     mv88e6xxx_reg_lock(chip);
3584     if (mv88e6xxx_serdes_power(chip, port, false))
3585         dev_err(chip->dev, "failed to power off SERDES\n");
3586     mv88e6xxx_reg_unlock(chip);
3587 }
3588 
3589 static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds,
3590                      unsigned int ageing_time)
3591 {
3592     struct mv88e6xxx_chip *chip = ds->priv;
3593     int err;
3594 
3595     mv88e6xxx_reg_lock(chip);
3596     err = mv88e6xxx_g1_atu_set_age_time(chip, ageing_time);
3597     mv88e6xxx_reg_unlock(chip);
3598 
3599     return err;
3600 }
3601 
3602 static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip)
3603 {
3604     int err;
3605 
3606     /* Initialize the statistics unit */
3607     if (chip->info->ops->stats_set_histogram) {
3608         err = chip->info->ops->stats_set_histogram(chip);
3609         if (err)
3610             return err;
3611     }
3612 
3613     return mv88e6xxx_g1_stats_clear(chip);
3614 }
3615 
3616 /* Check if the errata has already been applied. */
3617 static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip)
3618 {
3619     int port;
3620     int err;
3621     u16 val;
3622 
3623     for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
3624         err = mv88e6xxx_port_hidden_read(chip, 0xf, port, 0, &val);
3625         if (err) {
3626             dev_err(chip->dev,
3627                 "Error reading hidden register: %d\n", err);
3628             return false;
3629         }
3630         if (val != 0x01c0)
3631             return false;
3632     }
3633 
3634     return true;
3635 }
3636 
3637 /* The 6390 copper ports have an errata which require poking magic
3638  * values into undocumented hidden registers and then performing a
3639  * software reset.
3640  */
3641 static int mv88e6390_setup_errata(struct mv88e6xxx_chip *chip)
3642 {
3643     int port;
3644     int err;
3645 
3646     if (mv88e6390_setup_errata_applied(chip))
3647         return 0;
3648 
3649     /* Set the ports into blocking mode */
3650     for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
3651         err = mv88e6xxx_port_set_state(chip, port, BR_STATE_DISABLED);
3652         if (err)
3653             return err;
3654     }
3655 
3656     for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
3657         err = mv88e6xxx_port_hidden_write(chip, 0xf, port, 0, 0x01c0);
3658         if (err)
3659             return err;
3660     }
3661 
3662     return mv88e6xxx_software_reset(chip);
3663 }
3664 
3665 static void mv88e6xxx_teardown(struct dsa_switch *ds)
3666 {
3667     mv88e6xxx_teardown_devlink_params(ds);
3668     dsa_devlink_resources_unregister(ds);
3669     mv88e6xxx_teardown_devlink_regions_global(ds);
3670 }
3671 
3672 static int mv88e6xxx_setup(struct dsa_switch *ds)
3673 {
3674     struct mv88e6xxx_chip *chip = ds->priv;
3675     u8 cmode;
3676     int err;
3677     int i;
3678 
3679     chip->ds = ds;
3680     ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip);
3681 
3682     /* Since virtual bridges are mapped in the PVT, the number we support
3683      * depends on the physical switch topology. We need to let DSA figure
3684      * that out and therefore we cannot set this at dsa_register_switch()
3685      * time.
3686      */
3687     if (mv88e6xxx_has_pvt(chip))
3688         ds->max_num_bridges = MV88E6XXX_MAX_PVT_SWITCHES -
3689                       ds->dst->last_switch - 1;
3690 
3691     mv88e6xxx_reg_lock(chip);
3692 
3693     if (chip->info->ops->setup_errata) {
3694         err = chip->info->ops->setup_errata(chip);
3695         if (err)
3696             goto unlock;
3697     }
3698 
3699     /* Cache the cmode of each port. */
3700     for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
3701         if (chip->info->ops->port_get_cmode) {
3702             err = chip->info->ops->port_get_cmode(chip, i, &cmode);
3703             if (err)
3704                 goto unlock;
3705 
3706             chip->ports[i].cmode = cmode;
3707         }
3708     }
3709 
3710     err = mv88e6xxx_vtu_setup(chip);
3711     if (err)
3712         goto unlock;
3713 
3714     /* Must be called after mv88e6xxx_vtu_setup (which flushes the
3715      * VTU, thereby also flushing the STU).
3716      */
3717     err = mv88e6xxx_stu_setup(chip);
3718     if (err)
3719         goto unlock;
3720 
3721     /* Setup Switch Port Registers */
3722     for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
3723         if (dsa_is_unused_port(ds, i))
3724             continue;
3725 
3726         /* Prevent the use of an invalid port. */
3727         if (mv88e6xxx_is_invalid_port(chip, i)) {
3728             dev_err(chip->dev, "port %d is invalid\n", i);
3729             err = -EINVAL;
3730             goto unlock;
3731         }
3732 
3733         err = mv88e6xxx_setup_port(chip, i);
3734         if (err)
3735             goto unlock;
3736     }
3737 
3738     err = mv88e6xxx_irl_setup(chip);
3739     if (err)
3740         goto unlock;
3741 
3742     err = mv88e6xxx_mac_setup(chip);
3743     if (err)
3744         goto unlock;
3745 
3746     err = mv88e6xxx_phy_setup(chip);
3747     if (err)
3748         goto unlock;
3749 
3750     err = mv88e6xxx_pvt_setup(chip);
3751     if (err)
3752         goto unlock;
3753 
3754     err = mv88e6xxx_atu_setup(chip);
3755     if (err)
3756         goto unlock;
3757 
3758     err = mv88e6xxx_broadcast_setup(chip, 0);
3759     if (err)
3760         goto unlock;
3761 
3762     err = mv88e6xxx_pot_setup(chip);
3763     if (err)
3764         goto unlock;
3765 
3766     err = mv88e6xxx_rmu_setup(chip);
3767     if (err)
3768         goto unlock;
3769 
3770     err = mv88e6xxx_rsvd2cpu_setup(chip);
3771     if (err)
3772         goto unlock;
3773 
3774     err = mv88e6xxx_trunk_setup(chip);
3775     if (err)
3776         goto unlock;
3777 
3778     err = mv88e6xxx_devmap_setup(chip);
3779     if (err)
3780         goto unlock;
3781 
3782     err = mv88e6xxx_pri_setup(chip);
3783     if (err)
3784         goto unlock;
3785 
3786     /* Setup PTP Hardware Clock and timestamping */
3787     if (chip->info->ptp_support) {
3788         err = mv88e6xxx_ptp_setup(chip);
3789         if (err)
3790             goto unlock;
3791 
3792         err = mv88e6xxx_hwtstamp_setup(chip);
3793         if (err)
3794             goto unlock;
3795     }
3796 
3797     err = mv88e6xxx_stats_setup(chip);
3798     if (err)
3799         goto unlock;
3800 
3801 unlock:
3802     mv88e6xxx_reg_unlock(chip);
3803 
3804     if (err)
3805         return err;
3806 
3807     /* Have to be called without holding the register lock, since
3808      * they take the devlink lock, and we later take the locks in
3809      * the reverse order when getting/setting parameters or
3810      * resource occupancy.
3811      */
3812     err = mv88e6xxx_setup_devlink_resources(ds);
3813     if (err)
3814         return err;
3815 
3816     err = mv88e6xxx_setup_devlink_params(ds);
3817     if (err)
3818         goto out_resources;
3819 
3820     err = mv88e6xxx_setup_devlink_regions_global(ds);
3821     if (err)
3822         goto out_params;
3823 
3824     return 0;
3825 
3826 out_params:
3827     mv88e6xxx_teardown_devlink_params(ds);
3828 out_resources:
3829     dsa_devlink_resources_unregister(ds);
3830 
3831     return err;
3832 }
3833 
3834 static int mv88e6xxx_port_setup(struct dsa_switch *ds, int port)
3835 {
3836     return mv88e6xxx_setup_devlink_regions_port(ds, port);
3837 }
3838 
3839 static void mv88e6xxx_port_teardown(struct dsa_switch *ds, int port)
3840 {
3841     mv88e6xxx_teardown_devlink_regions_port(ds, port);
3842 }
3843 
3844 /* prod_id for switch families which do not have a PHY model number */
3845 static const u16 family_prod_id_table[] = {
3846     [MV88E6XXX_FAMILY_6341] = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
3847     [MV88E6XXX_FAMILY_6390] = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
3848     [MV88E6XXX_FAMILY_6393] = MV88E6XXX_PORT_SWITCH_ID_PROD_6393X,
3849 };
3850 
3851 static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
3852 {
3853     struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
3854     struct mv88e6xxx_chip *chip = mdio_bus->chip;
3855     u16 prod_id;
3856     u16 val;
3857     int err;
3858 
3859     if (!chip->info->ops->phy_read)
3860         return -EOPNOTSUPP;
3861 
3862     mv88e6xxx_reg_lock(chip);
3863     err = chip->info->ops->phy_read(chip, bus, phy, reg, &val);
3864     mv88e6xxx_reg_unlock(chip);
3865 
3866     /* Some internal PHYs don't have a model number. */
3867     if (reg == MII_PHYSID2 && !(val & 0x3f0) &&
3868         chip->info->family < ARRAY_SIZE(family_prod_id_table)) {
3869         prod_id = family_prod_id_table[chip->info->family];
3870         if (prod_id)
3871             val |= prod_id >> 4;
3872     }
3873 
3874     return err ? err : val;
3875 }
3876 
3877 static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
3878 {
3879     struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
3880     struct mv88e6xxx_chip *chip = mdio_bus->chip;
3881     int err;
3882 
3883     if (!chip->info->ops->phy_write)
3884         return -EOPNOTSUPP;
3885 
3886     mv88e6xxx_reg_lock(chip);
3887     err = chip->info->ops->phy_write(chip, bus, phy, reg, val);
3888     mv88e6xxx_reg_unlock(chip);
3889 
3890     return err;
3891 }
3892 
3893 static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
3894                    struct device_node *np,
3895                    bool external)
3896 {
3897     static int index;
3898     struct mv88e6xxx_mdio_bus *mdio_bus;
3899     struct mii_bus *bus;
3900     int err;
3901 
3902     if (external) {
3903         mv88e6xxx_reg_lock(chip);
3904         err = mv88e6xxx_g2_scratch_gpio_set_smi(chip, true);
3905         mv88e6xxx_reg_unlock(chip);
3906 
3907         if (err)
3908             return err;
3909     }
3910 
3911     bus = mdiobus_alloc_size(sizeof(*mdio_bus));
3912     if (!bus)
3913         return -ENOMEM;
3914 
3915     mdio_bus = bus->priv;
3916     mdio_bus->bus = bus;
3917     mdio_bus->chip = chip;
3918     INIT_LIST_HEAD(&mdio_bus->list);
3919     mdio_bus->external = external;
3920 
3921     if (np) {
3922         bus->name = np->full_name;
3923         snprintf(bus->id, MII_BUS_ID_SIZE, "%pOF", np);
3924     } else {
3925         bus->name = "mv88e6xxx SMI";
3926         snprintf(bus->id, MII_BUS_ID_SIZE, "mv88e6xxx-%d", index++);
3927     }
3928 
3929     bus->read = mv88e6xxx_mdio_read;
3930     bus->write = mv88e6xxx_mdio_write;
3931     bus->parent = chip->dev;
3932 
3933     if (!external) {
3934         err = mv88e6xxx_g2_irq_mdio_setup(chip, bus);
3935         if (err)
3936             goto out;
3937     }
3938 
3939     err = of_mdiobus_register(bus, np);
3940     if (err) {
3941         dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err);
3942         mv88e6xxx_g2_irq_mdio_free(chip, bus);
3943         goto out;
3944     }
3945 
3946     if (external)
3947         list_add_tail(&mdio_bus->list, &chip->mdios);
3948     else
3949         list_add(&mdio_bus->list, &chip->mdios);
3950 
3951     return 0;
3952 
3953 out:
3954     mdiobus_free(bus);
3955     return err;
3956 }
3957 
3958 static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
3959 
3960 {
3961     struct mv88e6xxx_mdio_bus *mdio_bus, *p;
3962     struct mii_bus *bus;
3963 
3964     list_for_each_entry_safe(mdio_bus, p, &chip->mdios, list) {
3965         bus = mdio_bus->bus;
3966 
3967         if (!mdio_bus->external)
3968             mv88e6xxx_g2_irq_mdio_free(chip, bus);
3969 
3970         mdiobus_unregister(bus);
3971         mdiobus_free(bus);
3972     }
3973 }
3974 
3975 static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip,
3976                     struct device_node *np)
3977 {
3978     struct device_node *child;
3979     int err;
3980 
3981     /* Always register one mdio bus for the internal/default mdio
3982      * bus. This maybe represented in the device tree, but is
3983      * optional.
3984      */
3985     child = of_get_child_by_name(np, "mdio");
3986     err = mv88e6xxx_mdio_register(chip, child, false);
3987     of_node_put(child);
3988     if (err)
3989         return err;
3990 
3991     /* Walk the device tree, and see if there are any other nodes
3992      * which say they are compatible with the external mdio
3993      * bus.
3994      */
3995     for_each_available_child_of_node(np, child) {
3996         if (of_device_is_compatible(
3997                 child, "marvell,mv88e6xxx-mdio-external")) {
3998             err = mv88e6xxx_mdio_register(chip, child, true);
3999             if (err) {
4000                 mv88e6xxx_mdios_unregister(chip);
4001                 of_node_put(child);
4002                 return err;
4003             }
4004         }
4005     }
4006 
4007     return 0;
4008 }
4009 
4010 static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
4011 {
4012     struct mv88e6xxx_chip *chip = ds->priv;
4013 
4014     return chip->eeprom_len;
4015 }
4016 
4017 static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
4018                 struct ethtool_eeprom *eeprom, u8 *data)
4019 {
4020     struct mv88e6xxx_chip *chip = ds->priv;
4021     int err;
4022 
4023     if (!chip->info->ops->get_eeprom)
4024         return -EOPNOTSUPP;
4025 
4026     mv88e6xxx_reg_lock(chip);
4027     err = chip->info->ops->get_eeprom(chip, eeprom, data);
4028     mv88e6xxx_reg_unlock(chip);
4029 
4030     if (err)
4031         return err;
4032 
4033     eeprom->magic = 0xc3ec4951;
4034 
4035     return 0;
4036 }
4037 
4038 static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
4039                 struct ethtool_eeprom *eeprom, u8 *data)
4040 {
4041     struct mv88e6xxx_chip *chip = ds->priv;
4042     int err;
4043 
4044     if (!chip->info->ops->set_eeprom)
4045         return -EOPNOTSUPP;
4046 
4047     if (eeprom->magic != 0xc3ec4951)
4048         return -EINVAL;
4049 
4050     mv88e6xxx_reg_lock(chip);
4051     err = chip->info->ops->set_eeprom(chip, eeprom, data);
4052     mv88e6xxx_reg_unlock(chip);
4053 
4054     return err;
4055 }
4056 
4057 static const struct mv88e6xxx_ops mv88e6085_ops = {
4058     /* MV88E6XXX_FAMILY_6097 */
4059     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4060     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4061     .irl_init_all = mv88e6352_g2_irl_init_all,
4062     .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
4063     .phy_read = mv88e6185_phy_ppu_read,
4064     .phy_write = mv88e6185_phy_ppu_write,
4065     .port_set_link = mv88e6xxx_port_set_link,
4066     .port_sync_link = mv88e6xxx_port_sync_link,
4067     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4068     .port_tag_remap = mv88e6095_port_tag_remap,
4069     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4070     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4071     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4072     .port_set_ether_type = mv88e6351_port_set_ether_type,
4073     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4074     .port_pause_limit = mv88e6097_port_pause_limit,
4075     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4076     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4077     .port_get_cmode = mv88e6185_port_get_cmode,
4078     .port_setup_message_port = mv88e6xxx_setup_message_port,
4079     .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4080     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4081     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4082     .stats_get_strings = mv88e6095_stats_get_strings,
4083     .stats_get_stats = mv88e6095_stats_get_stats,
4084     .set_cpu_port = mv88e6095_g1_set_cpu_port,
4085     .set_egress_port = mv88e6095_g1_set_egress_port,
4086     .watchdog_ops = &mv88e6097_watchdog_ops,
4087     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4088     .pot_clear = mv88e6xxx_g2_pot_clear,
4089     .ppu_enable = mv88e6185_g1_ppu_enable,
4090     .ppu_disable = mv88e6185_g1_ppu_disable,
4091     .reset = mv88e6185_g1_reset,
4092     .rmu_disable = mv88e6085_g1_rmu_disable,
4093     .vtu_getnext = mv88e6352_g1_vtu_getnext,
4094     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4095     .stu_getnext = mv88e6352_g1_stu_getnext,
4096     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4097     .phylink_get_caps = mv88e6185_phylink_get_caps,
4098     .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
4099 };
4100 
4101 static const struct mv88e6xxx_ops mv88e6095_ops = {
4102     /* MV88E6XXX_FAMILY_6095 */
4103     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4104     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4105     .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
4106     .phy_read = mv88e6185_phy_ppu_read,
4107     .phy_write = mv88e6185_phy_ppu_write,
4108     .port_set_link = mv88e6xxx_port_set_link,
4109     .port_sync_link = mv88e6185_port_sync_link,
4110     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4111     .port_set_frame_mode = mv88e6085_port_set_frame_mode,
4112     .port_set_ucast_flood = mv88e6185_port_set_forward_unknown,
4113     .port_set_mcast_flood = mv88e6185_port_set_default_forward,
4114     .port_set_upstream_port = mv88e6095_port_set_upstream_port,
4115     .port_get_cmode = mv88e6185_port_get_cmode,
4116     .port_setup_message_port = mv88e6xxx_setup_message_port,
4117     .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4118     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4119     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4120     .stats_get_strings = mv88e6095_stats_get_strings,
4121     .stats_get_stats = mv88e6095_stats_get_stats,
4122     .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
4123     .serdes_power = mv88e6185_serdes_power,
4124     .serdes_get_lane = mv88e6185_serdes_get_lane,
4125     .serdes_pcs_get_state = mv88e6185_serdes_pcs_get_state,
4126     .ppu_enable = mv88e6185_g1_ppu_enable,
4127     .ppu_disable = mv88e6185_g1_ppu_disable,
4128     .reset = mv88e6185_g1_reset,
4129     .vtu_getnext = mv88e6185_g1_vtu_getnext,
4130     .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
4131     .phylink_get_caps = mv88e6095_phylink_get_caps,
4132     .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
4133 };
4134 
4135 static const struct mv88e6xxx_ops mv88e6097_ops = {
4136     /* MV88E6XXX_FAMILY_6097 */
4137     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4138     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4139     .irl_init_all = mv88e6352_g2_irl_init_all,
4140     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4141     .phy_read = mv88e6xxx_g2_smi_phy_read,
4142     .phy_write = mv88e6xxx_g2_smi_phy_write,
4143     .port_set_link = mv88e6xxx_port_set_link,
4144     .port_sync_link = mv88e6185_port_sync_link,
4145     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4146     .port_tag_remap = mv88e6095_port_tag_remap,
4147     .port_set_policy = mv88e6352_port_set_policy,
4148     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4149     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4150     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4151     .port_set_ether_type = mv88e6351_port_set_ether_type,
4152     .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
4153     .port_pause_limit = mv88e6097_port_pause_limit,
4154     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4155     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4156     .port_get_cmode = mv88e6185_port_get_cmode,
4157     .port_setup_message_port = mv88e6xxx_setup_message_port,
4158     .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4159     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4160     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4161     .stats_get_strings = mv88e6095_stats_get_strings,
4162     .stats_get_stats = mv88e6095_stats_get_stats,
4163     .set_cpu_port = mv88e6095_g1_set_cpu_port,
4164     .set_egress_port = mv88e6095_g1_set_egress_port,
4165     .watchdog_ops = &mv88e6097_watchdog_ops,
4166     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4167     .serdes_power = mv88e6185_serdes_power,
4168     .serdes_get_lane = mv88e6185_serdes_get_lane,
4169     .serdes_pcs_get_state = mv88e6185_serdes_pcs_get_state,
4170     .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4171     .serdes_irq_enable = mv88e6097_serdes_irq_enable,
4172     .serdes_irq_status = mv88e6097_serdes_irq_status,
4173     .pot_clear = mv88e6xxx_g2_pot_clear,
4174     .reset = mv88e6352_g1_reset,
4175     .rmu_disable = mv88e6085_g1_rmu_disable,
4176     .vtu_getnext = mv88e6352_g1_vtu_getnext,
4177     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4178     .phylink_get_caps = mv88e6095_phylink_get_caps,
4179     .stu_getnext = mv88e6352_g1_stu_getnext,
4180     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4181     .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
4182 };
4183 
4184 static const struct mv88e6xxx_ops mv88e6123_ops = {
4185     /* MV88E6XXX_FAMILY_6165 */
4186     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4187     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4188     .irl_init_all = mv88e6352_g2_irl_init_all,
4189     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4190     .phy_read = mv88e6xxx_g2_smi_phy_read,
4191     .phy_write = mv88e6xxx_g2_smi_phy_write,
4192     .port_set_link = mv88e6xxx_port_set_link,
4193     .port_sync_link = mv88e6xxx_port_sync_link,
4194     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4195     .port_set_frame_mode = mv88e6085_port_set_frame_mode,
4196     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4197     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4198     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4199     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4200     .port_get_cmode = mv88e6185_port_get_cmode,
4201     .port_setup_message_port = mv88e6xxx_setup_message_port,
4202     .stats_snapshot = mv88e6320_g1_stats_snapshot,
4203     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4204     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4205     .stats_get_strings = mv88e6095_stats_get_strings,
4206     .stats_get_stats = mv88e6095_stats_get_stats,
4207     .set_cpu_port = mv88e6095_g1_set_cpu_port,
4208     .set_egress_port = mv88e6095_g1_set_egress_port,
4209     .watchdog_ops = &mv88e6097_watchdog_ops,
4210     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4211     .pot_clear = mv88e6xxx_g2_pot_clear,
4212     .reset = mv88e6352_g1_reset,
4213     .atu_get_hash = mv88e6165_g1_atu_get_hash,
4214     .atu_set_hash = mv88e6165_g1_atu_set_hash,
4215     .vtu_getnext = mv88e6352_g1_vtu_getnext,
4216     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4217     .stu_getnext = mv88e6352_g1_stu_getnext,
4218     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4219     .phylink_get_caps = mv88e6185_phylink_get_caps,
4220     .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
4221 };
4222 
4223 static const struct mv88e6xxx_ops mv88e6131_ops = {
4224     /* MV88E6XXX_FAMILY_6185 */
4225     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4226     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4227     .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
4228     .phy_read = mv88e6185_phy_ppu_read,
4229     .phy_write = mv88e6185_phy_ppu_write,
4230     .port_set_link = mv88e6xxx_port_set_link,
4231     .port_sync_link = mv88e6xxx_port_sync_link,
4232     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4233     .port_tag_remap = mv88e6095_port_tag_remap,
4234     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4235     .port_set_ucast_flood = mv88e6185_port_set_forward_unknown,
4236     .port_set_mcast_flood = mv88e6185_port_set_default_forward,
4237     .port_set_ether_type = mv88e6351_port_set_ether_type,
4238     .port_set_upstream_port = mv88e6095_port_set_upstream_port,
4239     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4240     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4241     .port_pause_limit = mv88e6097_port_pause_limit,
4242     .port_set_pause = mv88e6185_port_set_pause,
4243     .port_get_cmode = mv88e6185_port_get_cmode,
4244     .port_setup_message_port = mv88e6xxx_setup_message_port,
4245     .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4246     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4247     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4248     .stats_get_strings = mv88e6095_stats_get_strings,
4249     .stats_get_stats = mv88e6095_stats_get_stats,
4250     .set_cpu_port = mv88e6095_g1_set_cpu_port,
4251     .set_egress_port = mv88e6095_g1_set_egress_port,
4252     .watchdog_ops = &mv88e6097_watchdog_ops,
4253     .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
4254     .ppu_enable = mv88e6185_g1_ppu_enable,
4255     .set_cascade_port = mv88e6185_g1_set_cascade_port,
4256     .ppu_disable = mv88e6185_g1_ppu_disable,
4257     .reset = mv88e6185_g1_reset,
4258     .vtu_getnext = mv88e6185_g1_vtu_getnext,
4259     .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
4260     .phylink_get_caps = mv88e6185_phylink_get_caps,
4261 };
4262 
4263 static const struct mv88e6xxx_ops mv88e6141_ops = {
4264     /* MV88E6XXX_FAMILY_6341 */
4265     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4266     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4267     .irl_init_all = mv88e6352_g2_irl_init_all,
4268     .get_eeprom = mv88e6xxx_g2_get_eeprom8,
4269     .set_eeprom = mv88e6xxx_g2_set_eeprom8,
4270     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4271     .phy_read = mv88e6xxx_g2_smi_phy_read,
4272     .phy_write = mv88e6xxx_g2_smi_phy_write,
4273     .port_set_link = mv88e6xxx_port_set_link,
4274     .port_sync_link = mv88e6xxx_port_sync_link,
4275     .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
4276     .port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
4277     .port_max_speed_mode = mv88e6341_port_max_speed_mode,
4278     .port_tag_remap = mv88e6095_port_tag_remap,
4279     .port_set_policy = mv88e6352_port_set_policy,
4280     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4281     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4282     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4283     .port_set_ether_type = mv88e6351_port_set_ether_type,
4284     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4285     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4286     .port_pause_limit = mv88e6097_port_pause_limit,
4287     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4288     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4289     .port_get_cmode = mv88e6352_port_get_cmode,
4290     .port_set_cmode = mv88e6341_port_set_cmode,
4291     .port_setup_message_port = mv88e6xxx_setup_message_port,
4292     .stats_snapshot = mv88e6390_g1_stats_snapshot,
4293     .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
4294     .stats_get_sset_count = mv88e6320_stats_get_sset_count,
4295     .stats_get_strings = mv88e6320_stats_get_strings,
4296     .stats_get_stats = mv88e6390_stats_get_stats,
4297     .set_cpu_port = mv88e6390_g1_set_cpu_port,
4298     .set_egress_port = mv88e6390_g1_set_egress_port,
4299     .watchdog_ops = &mv88e6390_watchdog_ops,
4300     .mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
4301     .pot_clear = mv88e6xxx_g2_pot_clear,
4302     .reset = mv88e6352_g1_reset,
4303     .rmu_disable = mv88e6390_g1_rmu_disable,
4304     .atu_get_hash = mv88e6165_g1_atu_get_hash,
4305     .atu_set_hash = mv88e6165_g1_atu_set_hash,
4306     .vtu_getnext = mv88e6352_g1_vtu_getnext,
4307     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4308     .stu_getnext = mv88e6352_g1_stu_getnext,
4309     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4310     .serdes_power = mv88e6390_serdes_power,
4311     .serdes_get_lane = mv88e6341_serdes_get_lane,
4312     /* Check status register pause & lpa register */
4313     .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4314     .serdes_pcs_config = mv88e6390_serdes_pcs_config,
4315     .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4316     .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4317     .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4318     .serdes_irq_enable = mv88e6390_serdes_irq_enable,
4319     .serdes_irq_status = mv88e6390_serdes_irq_status,
4320     .gpio_ops = &mv88e6352_gpio_ops,
4321     .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
4322     .serdes_get_strings = mv88e6390_serdes_get_strings,
4323     .serdes_get_stats = mv88e6390_serdes_get_stats,
4324     .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4325     .serdes_get_regs = mv88e6390_serdes_get_regs,
4326     .phylink_get_caps = mv88e6341_phylink_get_caps,
4327 };
4328 
4329 static const struct mv88e6xxx_ops mv88e6161_ops = {
4330     /* MV88E6XXX_FAMILY_6165 */
4331     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4332     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4333     .irl_init_all = mv88e6352_g2_irl_init_all,
4334     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4335     .phy_read = mv88e6xxx_g2_smi_phy_read,
4336     .phy_write = mv88e6xxx_g2_smi_phy_write,
4337     .port_set_link = mv88e6xxx_port_set_link,
4338     .port_sync_link = mv88e6xxx_port_sync_link,
4339     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4340     .port_tag_remap = mv88e6095_port_tag_remap,
4341     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4342     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4343     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4344     .port_set_ether_type = mv88e6351_port_set_ether_type,
4345     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4346     .port_pause_limit = mv88e6097_port_pause_limit,
4347     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4348     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4349     .port_get_cmode = mv88e6185_port_get_cmode,
4350     .port_setup_message_port = mv88e6xxx_setup_message_port,
4351     .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4352     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4353     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4354     .stats_get_strings = mv88e6095_stats_get_strings,
4355     .stats_get_stats = mv88e6095_stats_get_stats,
4356     .set_cpu_port = mv88e6095_g1_set_cpu_port,
4357     .set_egress_port = mv88e6095_g1_set_egress_port,
4358     .watchdog_ops = &mv88e6097_watchdog_ops,
4359     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4360     .pot_clear = mv88e6xxx_g2_pot_clear,
4361     .reset = mv88e6352_g1_reset,
4362     .atu_get_hash = mv88e6165_g1_atu_get_hash,
4363     .atu_set_hash = mv88e6165_g1_atu_set_hash,
4364     .vtu_getnext = mv88e6352_g1_vtu_getnext,
4365     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4366     .stu_getnext = mv88e6352_g1_stu_getnext,
4367     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4368     .avb_ops = &mv88e6165_avb_ops,
4369     .ptp_ops = &mv88e6165_ptp_ops,
4370     .phylink_get_caps = mv88e6185_phylink_get_caps,
4371     .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
4372 };
4373 
4374 static const struct mv88e6xxx_ops mv88e6165_ops = {
4375     /* MV88E6XXX_FAMILY_6165 */
4376     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4377     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4378     .irl_init_all = mv88e6352_g2_irl_init_all,
4379     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4380     .phy_read = mv88e6165_phy_read,
4381     .phy_write = mv88e6165_phy_write,
4382     .port_set_link = mv88e6xxx_port_set_link,
4383     .port_sync_link = mv88e6xxx_port_sync_link,
4384     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4385     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4386     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4387     .port_get_cmode = mv88e6185_port_get_cmode,
4388     .port_setup_message_port = mv88e6xxx_setup_message_port,
4389     .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4390     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4391     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4392     .stats_get_strings = mv88e6095_stats_get_strings,
4393     .stats_get_stats = mv88e6095_stats_get_stats,
4394     .set_cpu_port = mv88e6095_g1_set_cpu_port,
4395     .set_egress_port = mv88e6095_g1_set_egress_port,
4396     .watchdog_ops = &mv88e6097_watchdog_ops,
4397     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4398     .pot_clear = mv88e6xxx_g2_pot_clear,
4399     .reset = mv88e6352_g1_reset,
4400     .atu_get_hash = mv88e6165_g1_atu_get_hash,
4401     .atu_set_hash = mv88e6165_g1_atu_set_hash,
4402     .vtu_getnext = mv88e6352_g1_vtu_getnext,
4403     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4404     .stu_getnext = mv88e6352_g1_stu_getnext,
4405     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4406     .avb_ops = &mv88e6165_avb_ops,
4407     .ptp_ops = &mv88e6165_ptp_ops,
4408     .phylink_get_caps = mv88e6185_phylink_get_caps,
4409 };
4410 
4411 static const struct mv88e6xxx_ops mv88e6171_ops = {
4412     /* MV88E6XXX_FAMILY_6351 */
4413     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4414     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4415     .irl_init_all = mv88e6352_g2_irl_init_all,
4416     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4417     .phy_read = mv88e6xxx_g2_smi_phy_read,
4418     .phy_write = mv88e6xxx_g2_smi_phy_write,
4419     .port_set_link = mv88e6xxx_port_set_link,
4420     .port_sync_link = mv88e6xxx_port_sync_link,
4421     .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4422     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4423     .port_tag_remap = mv88e6095_port_tag_remap,
4424     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4425     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4426     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4427     .port_set_ether_type = mv88e6351_port_set_ether_type,
4428     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4429     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4430     .port_pause_limit = mv88e6097_port_pause_limit,
4431     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4432     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4433     .port_get_cmode = mv88e6352_port_get_cmode,
4434     .port_setup_message_port = mv88e6xxx_setup_message_port,
4435     .stats_snapshot = mv88e6320_g1_stats_snapshot,
4436     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4437     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4438     .stats_get_strings = mv88e6095_stats_get_strings,
4439     .stats_get_stats = mv88e6095_stats_get_stats,
4440     .set_cpu_port = mv88e6095_g1_set_cpu_port,
4441     .set_egress_port = mv88e6095_g1_set_egress_port,
4442     .watchdog_ops = &mv88e6097_watchdog_ops,
4443     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4444     .pot_clear = mv88e6xxx_g2_pot_clear,
4445     .reset = mv88e6352_g1_reset,
4446     .atu_get_hash = mv88e6165_g1_atu_get_hash,
4447     .atu_set_hash = mv88e6165_g1_atu_set_hash,
4448     .vtu_getnext = mv88e6352_g1_vtu_getnext,
4449     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4450     .stu_getnext = mv88e6352_g1_stu_getnext,
4451     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4452     .phylink_get_caps = mv88e6185_phylink_get_caps,
4453 };
4454 
4455 static const struct mv88e6xxx_ops mv88e6172_ops = {
4456     /* MV88E6XXX_FAMILY_6352 */
4457     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4458     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4459     .irl_init_all = mv88e6352_g2_irl_init_all,
4460     .get_eeprom = mv88e6xxx_g2_get_eeprom16,
4461     .set_eeprom = mv88e6xxx_g2_set_eeprom16,
4462     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4463     .phy_read = mv88e6xxx_g2_smi_phy_read,
4464     .phy_write = mv88e6xxx_g2_smi_phy_write,
4465     .port_set_link = mv88e6xxx_port_set_link,
4466     .port_sync_link = mv88e6xxx_port_sync_link,
4467     .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4468     .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
4469     .port_tag_remap = mv88e6095_port_tag_remap,
4470     .port_set_policy = mv88e6352_port_set_policy,
4471     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4472     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4473     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4474     .port_set_ether_type = mv88e6351_port_set_ether_type,
4475     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4476     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4477     .port_pause_limit = mv88e6097_port_pause_limit,
4478     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4479     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4480     .port_get_cmode = mv88e6352_port_get_cmode,
4481     .port_setup_message_port = mv88e6xxx_setup_message_port,
4482     .stats_snapshot = mv88e6320_g1_stats_snapshot,
4483     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4484     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4485     .stats_get_strings = mv88e6095_stats_get_strings,
4486     .stats_get_stats = mv88e6095_stats_get_stats,
4487     .set_cpu_port = mv88e6095_g1_set_cpu_port,
4488     .set_egress_port = mv88e6095_g1_set_egress_port,
4489     .watchdog_ops = &mv88e6097_watchdog_ops,
4490     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4491     .pot_clear = mv88e6xxx_g2_pot_clear,
4492     .reset = mv88e6352_g1_reset,
4493     .rmu_disable = mv88e6352_g1_rmu_disable,
4494     .atu_get_hash = mv88e6165_g1_atu_get_hash,
4495     .atu_set_hash = mv88e6165_g1_atu_set_hash,
4496     .vtu_getnext = mv88e6352_g1_vtu_getnext,
4497     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4498     .stu_getnext = mv88e6352_g1_stu_getnext,
4499     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4500     .serdes_get_lane = mv88e6352_serdes_get_lane,
4501     .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
4502     .serdes_pcs_config = mv88e6352_serdes_pcs_config,
4503     .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
4504     .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
4505     .serdes_power = mv88e6352_serdes_power,
4506     .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
4507     .serdes_get_regs = mv88e6352_serdes_get_regs,
4508     .gpio_ops = &mv88e6352_gpio_ops,
4509     .phylink_get_caps = mv88e6352_phylink_get_caps,
4510 };
4511 
4512 static const struct mv88e6xxx_ops mv88e6175_ops = {
4513     /* MV88E6XXX_FAMILY_6351 */
4514     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4515     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4516     .irl_init_all = mv88e6352_g2_irl_init_all,
4517     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4518     .phy_read = mv88e6xxx_g2_smi_phy_read,
4519     .phy_write = mv88e6xxx_g2_smi_phy_write,
4520     .port_set_link = mv88e6xxx_port_set_link,
4521     .port_sync_link = mv88e6xxx_port_sync_link,
4522     .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4523     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4524     .port_tag_remap = mv88e6095_port_tag_remap,
4525     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4526     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4527     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4528     .port_set_ether_type = mv88e6351_port_set_ether_type,
4529     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4530     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4531     .port_pause_limit = mv88e6097_port_pause_limit,
4532     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4533     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4534     .port_get_cmode = mv88e6352_port_get_cmode,
4535     .port_setup_message_port = mv88e6xxx_setup_message_port,
4536     .stats_snapshot = mv88e6320_g1_stats_snapshot,
4537     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4538     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4539     .stats_get_strings = mv88e6095_stats_get_strings,
4540     .stats_get_stats = mv88e6095_stats_get_stats,
4541     .set_cpu_port = mv88e6095_g1_set_cpu_port,
4542     .set_egress_port = mv88e6095_g1_set_egress_port,
4543     .watchdog_ops = &mv88e6097_watchdog_ops,
4544     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4545     .pot_clear = mv88e6xxx_g2_pot_clear,
4546     .reset = mv88e6352_g1_reset,
4547     .atu_get_hash = mv88e6165_g1_atu_get_hash,
4548     .atu_set_hash = mv88e6165_g1_atu_set_hash,
4549     .vtu_getnext = mv88e6352_g1_vtu_getnext,
4550     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4551     .stu_getnext = mv88e6352_g1_stu_getnext,
4552     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4553     .phylink_get_caps = mv88e6185_phylink_get_caps,
4554 };
4555 
4556 static const struct mv88e6xxx_ops mv88e6176_ops = {
4557     /* MV88E6XXX_FAMILY_6352 */
4558     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4559     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4560     .irl_init_all = mv88e6352_g2_irl_init_all,
4561     .get_eeprom = mv88e6xxx_g2_get_eeprom16,
4562     .set_eeprom = mv88e6xxx_g2_set_eeprom16,
4563     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4564     .phy_read = mv88e6xxx_g2_smi_phy_read,
4565     .phy_write = mv88e6xxx_g2_smi_phy_write,
4566     .port_set_link = mv88e6xxx_port_set_link,
4567     .port_sync_link = mv88e6xxx_port_sync_link,
4568     .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4569     .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
4570     .port_tag_remap = mv88e6095_port_tag_remap,
4571     .port_set_policy = mv88e6352_port_set_policy,
4572     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4573     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4574     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4575     .port_set_ether_type = mv88e6351_port_set_ether_type,
4576     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4577     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4578     .port_pause_limit = mv88e6097_port_pause_limit,
4579     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4580     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4581     .port_get_cmode = mv88e6352_port_get_cmode,
4582     .port_setup_message_port = mv88e6xxx_setup_message_port,
4583     .stats_snapshot = mv88e6320_g1_stats_snapshot,
4584     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4585     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4586     .stats_get_strings = mv88e6095_stats_get_strings,
4587     .stats_get_stats = mv88e6095_stats_get_stats,
4588     .set_cpu_port = mv88e6095_g1_set_cpu_port,
4589     .set_egress_port = mv88e6095_g1_set_egress_port,
4590     .watchdog_ops = &mv88e6097_watchdog_ops,
4591     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4592     .pot_clear = mv88e6xxx_g2_pot_clear,
4593     .reset = mv88e6352_g1_reset,
4594     .rmu_disable = mv88e6352_g1_rmu_disable,
4595     .atu_get_hash = mv88e6165_g1_atu_get_hash,
4596     .atu_set_hash = mv88e6165_g1_atu_set_hash,
4597     .vtu_getnext = mv88e6352_g1_vtu_getnext,
4598     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4599     .stu_getnext = mv88e6352_g1_stu_getnext,
4600     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4601     .serdes_get_lane = mv88e6352_serdes_get_lane,
4602     .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
4603     .serdes_pcs_config = mv88e6352_serdes_pcs_config,
4604     .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
4605     .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
4606     .serdes_power = mv88e6352_serdes_power,
4607     .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
4608     .serdes_irq_enable = mv88e6352_serdes_irq_enable,
4609     .serdes_irq_status = mv88e6352_serdes_irq_status,
4610     .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
4611     .serdes_get_regs = mv88e6352_serdes_get_regs,
4612     .serdes_set_tx_amplitude = mv88e6352_serdes_set_tx_amplitude,
4613     .gpio_ops = &mv88e6352_gpio_ops,
4614     .phylink_get_caps = mv88e6352_phylink_get_caps,
4615 };
4616 
4617 static const struct mv88e6xxx_ops mv88e6185_ops = {
4618     /* MV88E6XXX_FAMILY_6185 */
4619     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4620     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4621     .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
4622     .phy_read = mv88e6185_phy_ppu_read,
4623     .phy_write = mv88e6185_phy_ppu_write,
4624     .port_set_link = mv88e6xxx_port_set_link,
4625     .port_sync_link = mv88e6185_port_sync_link,
4626     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4627     .port_set_frame_mode = mv88e6085_port_set_frame_mode,
4628     .port_set_ucast_flood = mv88e6185_port_set_forward_unknown,
4629     .port_set_mcast_flood = mv88e6185_port_set_default_forward,
4630     .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
4631     .port_set_upstream_port = mv88e6095_port_set_upstream_port,
4632     .port_set_pause = mv88e6185_port_set_pause,
4633     .port_get_cmode = mv88e6185_port_get_cmode,
4634     .port_setup_message_port = mv88e6xxx_setup_message_port,
4635     .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4636     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4637     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4638     .stats_get_strings = mv88e6095_stats_get_strings,
4639     .stats_get_stats = mv88e6095_stats_get_stats,
4640     .set_cpu_port = mv88e6095_g1_set_cpu_port,
4641     .set_egress_port = mv88e6095_g1_set_egress_port,
4642     .watchdog_ops = &mv88e6097_watchdog_ops,
4643     .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
4644     .serdes_power = mv88e6185_serdes_power,
4645     .serdes_get_lane = mv88e6185_serdes_get_lane,
4646     .serdes_pcs_get_state = mv88e6185_serdes_pcs_get_state,
4647     .set_cascade_port = mv88e6185_g1_set_cascade_port,
4648     .ppu_enable = mv88e6185_g1_ppu_enable,
4649     .ppu_disable = mv88e6185_g1_ppu_disable,
4650     .reset = mv88e6185_g1_reset,
4651     .vtu_getnext = mv88e6185_g1_vtu_getnext,
4652     .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
4653     .phylink_get_caps = mv88e6185_phylink_get_caps,
4654     .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
4655 };
4656 
4657 static const struct mv88e6xxx_ops mv88e6190_ops = {
4658     /* MV88E6XXX_FAMILY_6390 */
4659     .setup_errata = mv88e6390_setup_errata,
4660     .irl_init_all = mv88e6390_g2_irl_init_all,
4661     .get_eeprom = mv88e6xxx_g2_get_eeprom8,
4662     .set_eeprom = mv88e6xxx_g2_set_eeprom8,
4663     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4664     .phy_read = mv88e6xxx_g2_smi_phy_read,
4665     .phy_write = mv88e6xxx_g2_smi_phy_write,
4666     .port_set_link = mv88e6xxx_port_set_link,
4667     .port_sync_link = mv88e6xxx_port_sync_link,
4668     .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
4669     .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
4670     .port_max_speed_mode = mv88e6390_port_max_speed_mode,
4671     .port_tag_remap = mv88e6390_port_tag_remap,
4672     .port_set_policy = mv88e6352_port_set_policy,
4673     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4674     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4675     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4676     .port_set_ether_type = mv88e6351_port_set_ether_type,
4677     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4678     .port_pause_limit = mv88e6390_port_pause_limit,
4679     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4680     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4681     .port_get_cmode = mv88e6352_port_get_cmode,
4682     .port_set_cmode = mv88e6390_port_set_cmode,
4683     .port_setup_message_port = mv88e6xxx_setup_message_port,
4684     .stats_snapshot = mv88e6390_g1_stats_snapshot,
4685     .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
4686     .stats_get_sset_count = mv88e6320_stats_get_sset_count,
4687     .stats_get_strings = mv88e6320_stats_get_strings,
4688     .stats_get_stats = mv88e6390_stats_get_stats,
4689     .set_cpu_port = mv88e6390_g1_set_cpu_port,
4690     .set_egress_port = mv88e6390_g1_set_egress_port,
4691     .watchdog_ops = &mv88e6390_watchdog_ops,
4692     .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
4693     .pot_clear = mv88e6xxx_g2_pot_clear,
4694     .reset = mv88e6352_g1_reset,
4695     .rmu_disable = mv88e6390_g1_rmu_disable,
4696     .atu_get_hash = mv88e6165_g1_atu_get_hash,
4697     .atu_set_hash = mv88e6165_g1_atu_set_hash,
4698     .vtu_getnext = mv88e6390_g1_vtu_getnext,
4699     .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
4700     .stu_getnext = mv88e6390_g1_stu_getnext,
4701     .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
4702     .serdes_power = mv88e6390_serdes_power,
4703     .serdes_get_lane = mv88e6390_serdes_get_lane,
4704     /* Check status register pause & lpa register */
4705     .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4706     .serdes_pcs_config = mv88e6390_serdes_pcs_config,
4707     .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4708     .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4709     .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4710     .serdes_irq_enable = mv88e6390_serdes_irq_enable,
4711     .serdes_irq_status = mv88e6390_serdes_irq_status,
4712     .serdes_get_strings = mv88e6390_serdes_get_strings,
4713     .serdes_get_stats = mv88e6390_serdes_get_stats,
4714     .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4715     .serdes_get_regs = mv88e6390_serdes_get_regs,
4716     .gpio_ops = &mv88e6352_gpio_ops,
4717     .phylink_get_caps = mv88e6390_phylink_get_caps,
4718 };
4719 
4720 static const struct mv88e6xxx_ops mv88e6190x_ops = {
4721     /* MV88E6XXX_FAMILY_6390 */
4722     .setup_errata = mv88e6390_setup_errata,
4723     .irl_init_all = mv88e6390_g2_irl_init_all,
4724     .get_eeprom = mv88e6xxx_g2_get_eeprom8,
4725     .set_eeprom = mv88e6xxx_g2_set_eeprom8,
4726     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4727     .phy_read = mv88e6xxx_g2_smi_phy_read,
4728     .phy_write = mv88e6xxx_g2_smi_phy_write,
4729     .port_set_link = mv88e6xxx_port_set_link,
4730     .port_sync_link = mv88e6xxx_port_sync_link,
4731     .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
4732     .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
4733     .port_max_speed_mode = mv88e6390x_port_max_speed_mode,
4734     .port_tag_remap = mv88e6390_port_tag_remap,
4735     .port_set_policy = mv88e6352_port_set_policy,
4736     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4737     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4738     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4739     .port_set_ether_type = mv88e6351_port_set_ether_type,
4740     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4741     .port_pause_limit = mv88e6390_port_pause_limit,
4742     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4743     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4744     .port_get_cmode = mv88e6352_port_get_cmode,
4745     .port_set_cmode = mv88e6390x_port_set_cmode,
4746     .port_setup_message_port = mv88e6xxx_setup_message_port,
4747     .stats_snapshot = mv88e6390_g1_stats_snapshot,
4748     .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
4749     .stats_get_sset_count = mv88e6320_stats_get_sset_count,
4750     .stats_get_strings = mv88e6320_stats_get_strings,
4751     .stats_get_stats = mv88e6390_stats_get_stats,
4752     .set_cpu_port = mv88e6390_g1_set_cpu_port,
4753     .set_egress_port = mv88e6390_g1_set_egress_port,
4754     .watchdog_ops = &mv88e6390_watchdog_ops,
4755     .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
4756     .pot_clear = mv88e6xxx_g2_pot_clear,
4757     .reset = mv88e6352_g1_reset,
4758     .rmu_disable = mv88e6390_g1_rmu_disable,
4759     .atu_get_hash = mv88e6165_g1_atu_get_hash,
4760     .atu_set_hash = mv88e6165_g1_atu_set_hash,
4761     .vtu_getnext = mv88e6390_g1_vtu_getnext,
4762     .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
4763     .stu_getnext = mv88e6390_g1_stu_getnext,
4764     .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
4765     .serdes_power = mv88e6390_serdes_power,
4766     .serdes_get_lane = mv88e6390x_serdes_get_lane,
4767     /* Check status register pause & lpa register */
4768     .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4769     .serdes_pcs_config = mv88e6390_serdes_pcs_config,
4770     .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4771     .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4772     .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4773     .serdes_irq_enable = mv88e6390_serdes_irq_enable,
4774     .serdes_irq_status = mv88e6390_serdes_irq_status,
4775     .serdes_get_strings = mv88e6390_serdes_get_strings,
4776     .serdes_get_stats = mv88e6390_serdes_get_stats,
4777     .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4778     .serdes_get_regs = mv88e6390_serdes_get_regs,
4779     .gpio_ops = &mv88e6352_gpio_ops,
4780     .phylink_get_caps = mv88e6390x_phylink_get_caps,
4781 };
4782 
4783 static const struct mv88e6xxx_ops mv88e6191_ops = {
4784     /* MV88E6XXX_FAMILY_6390 */
4785     .setup_errata = mv88e6390_setup_errata,
4786     .irl_init_all = mv88e6390_g2_irl_init_all,
4787     .get_eeprom = mv88e6xxx_g2_get_eeprom8,
4788     .set_eeprom = mv88e6xxx_g2_set_eeprom8,
4789     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4790     .phy_read = mv88e6xxx_g2_smi_phy_read,
4791     .phy_write = mv88e6xxx_g2_smi_phy_write,
4792     .port_set_link = mv88e6xxx_port_set_link,
4793     .port_sync_link = mv88e6xxx_port_sync_link,
4794     .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
4795     .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
4796     .port_max_speed_mode = mv88e6390_port_max_speed_mode,
4797     .port_tag_remap = mv88e6390_port_tag_remap,
4798     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4799     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4800     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4801     .port_set_ether_type = mv88e6351_port_set_ether_type,
4802     .port_pause_limit = mv88e6390_port_pause_limit,
4803     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4804     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4805     .port_get_cmode = mv88e6352_port_get_cmode,
4806     .port_set_cmode = mv88e6390_port_set_cmode,
4807     .port_setup_message_port = mv88e6xxx_setup_message_port,
4808     .stats_snapshot = mv88e6390_g1_stats_snapshot,
4809     .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
4810     .stats_get_sset_count = mv88e6320_stats_get_sset_count,
4811     .stats_get_strings = mv88e6320_stats_get_strings,
4812     .stats_get_stats = mv88e6390_stats_get_stats,
4813     .set_cpu_port = mv88e6390_g1_set_cpu_port,
4814     .set_egress_port = mv88e6390_g1_set_egress_port,
4815     .watchdog_ops = &mv88e6390_watchdog_ops,
4816     .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
4817     .pot_clear = mv88e6xxx_g2_pot_clear,
4818     .reset = mv88e6352_g1_reset,
4819     .rmu_disable = mv88e6390_g1_rmu_disable,
4820     .atu_get_hash = mv88e6165_g1_atu_get_hash,
4821     .atu_set_hash = mv88e6165_g1_atu_set_hash,
4822     .vtu_getnext = mv88e6390_g1_vtu_getnext,
4823     .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
4824     .stu_getnext = mv88e6390_g1_stu_getnext,
4825     .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
4826     .serdes_power = mv88e6390_serdes_power,
4827     .serdes_get_lane = mv88e6390_serdes_get_lane,
4828     /* Check status register pause & lpa register */
4829     .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4830     .serdes_pcs_config = mv88e6390_serdes_pcs_config,
4831     .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4832     .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4833     .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4834     .serdes_irq_enable = mv88e6390_serdes_irq_enable,
4835     .serdes_irq_status = mv88e6390_serdes_irq_status,
4836     .serdes_get_strings = mv88e6390_serdes_get_strings,
4837     .serdes_get_stats = mv88e6390_serdes_get_stats,
4838     .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4839     .serdes_get_regs = mv88e6390_serdes_get_regs,
4840     .avb_ops = &mv88e6390_avb_ops,
4841     .ptp_ops = &mv88e6352_ptp_ops,
4842     .phylink_get_caps = mv88e6390_phylink_get_caps,
4843 };
4844 
4845 static const struct mv88e6xxx_ops mv88e6240_ops = {
4846     /* MV88E6XXX_FAMILY_6352 */
4847     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4848     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4849     .irl_init_all = mv88e6352_g2_irl_init_all,
4850     .get_eeprom = mv88e6xxx_g2_get_eeprom16,
4851     .set_eeprom = mv88e6xxx_g2_set_eeprom16,
4852     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4853     .phy_read = mv88e6xxx_g2_smi_phy_read,
4854     .phy_write = mv88e6xxx_g2_smi_phy_write,
4855     .port_set_link = mv88e6xxx_port_set_link,
4856     .port_sync_link = mv88e6xxx_port_sync_link,
4857     .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4858     .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
4859     .port_tag_remap = mv88e6095_port_tag_remap,
4860     .port_set_policy = mv88e6352_port_set_policy,
4861     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4862     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4863     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4864     .port_set_ether_type = mv88e6351_port_set_ether_type,
4865     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4866     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4867     .port_pause_limit = mv88e6097_port_pause_limit,
4868     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4869     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4870     .port_get_cmode = mv88e6352_port_get_cmode,
4871     .port_setup_message_port = mv88e6xxx_setup_message_port,
4872     .stats_snapshot = mv88e6320_g1_stats_snapshot,
4873     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4874     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4875     .stats_get_strings = mv88e6095_stats_get_strings,
4876     .stats_get_stats = mv88e6095_stats_get_stats,
4877     .set_cpu_port = mv88e6095_g1_set_cpu_port,
4878     .set_egress_port = mv88e6095_g1_set_egress_port,
4879     .watchdog_ops = &mv88e6097_watchdog_ops,
4880     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4881     .pot_clear = mv88e6xxx_g2_pot_clear,
4882     .reset = mv88e6352_g1_reset,
4883     .rmu_disable = mv88e6352_g1_rmu_disable,
4884     .atu_get_hash = mv88e6165_g1_atu_get_hash,
4885     .atu_set_hash = mv88e6165_g1_atu_set_hash,
4886     .vtu_getnext = mv88e6352_g1_vtu_getnext,
4887     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4888     .stu_getnext = mv88e6352_g1_stu_getnext,
4889     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4890     .serdes_get_lane = mv88e6352_serdes_get_lane,
4891     .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
4892     .serdes_pcs_config = mv88e6352_serdes_pcs_config,
4893     .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
4894     .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
4895     .serdes_power = mv88e6352_serdes_power,
4896     .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
4897     .serdes_irq_enable = mv88e6352_serdes_irq_enable,
4898     .serdes_irq_status = mv88e6352_serdes_irq_status,
4899     .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
4900     .serdes_get_regs = mv88e6352_serdes_get_regs,
4901     .serdes_set_tx_amplitude = mv88e6352_serdes_set_tx_amplitude,
4902     .gpio_ops = &mv88e6352_gpio_ops,
4903     .avb_ops = &mv88e6352_avb_ops,
4904     .ptp_ops = &mv88e6352_ptp_ops,
4905     .phylink_get_caps = mv88e6352_phylink_get_caps,
4906 };
4907 
4908 static const struct mv88e6xxx_ops mv88e6250_ops = {
4909     /* MV88E6XXX_FAMILY_6250 */
4910     .ieee_pri_map = mv88e6250_g1_ieee_pri_map,
4911     .ip_pri_map = mv88e6085_g1_ip_pri_map,
4912     .irl_init_all = mv88e6352_g2_irl_init_all,
4913     .get_eeprom = mv88e6xxx_g2_get_eeprom16,
4914     .set_eeprom = mv88e6xxx_g2_set_eeprom16,
4915     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4916     .phy_read = mv88e6xxx_g2_smi_phy_read,
4917     .phy_write = mv88e6xxx_g2_smi_phy_write,
4918     .port_set_link = mv88e6xxx_port_set_link,
4919     .port_sync_link = mv88e6xxx_port_sync_link,
4920     .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4921     .port_set_speed_duplex = mv88e6250_port_set_speed_duplex,
4922     .port_tag_remap = mv88e6095_port_tag_remap,
4923     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4924     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4925     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4926     .port_set_ether_type = mv88e6351_port_set_ether_type,
4927     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4928     .port_pause_limit = mv88e6097_port_pause_limit,
4929     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4930     .stats_snapshot = mv88e6320_g1_stats_snapshot,
4931     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4932     .stats_get_sset_count = mv88e6250_stats_get_sset_count,
4933     .stats_get_strings = mv88e6250_stats_get_strings,
4934     .stats_get_stats = mv88e6250_stats_get_stats,
4935     .set_cpu_port = mv88e6095_g1_set_cpu_port,
4936     .set_egress_port = mv88e6095_g1_set_egress_port,
4937     .watchdog_ops = &mv88e6250_watchdog_ops,
4938     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4939     .pot_clear = mv88e6xxx_g2_pot_clear,
4940     .reset = mv88e6250_g1_reset,
4941     .vtu_getnext = mv88e6185_g1_vtu_getnext,
4942     .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
4943     .avb_ops = &mv88e6352_avb_ops,
4944     .ptp_ops = &mv88e6250_ptp_ops,
4945     .phylink_get_caps = mv88e6250_phylink_get_caps,
4946 };
4947 
4948 static const struct mv88e6xxx_ops mv88e6290_ops = {
4949     /* MV88E6XXX_FAMILY_6390 */
4950     .setup_errata = mv88e6390_setup_errata,
4951     .irl_init_all = mv88e6390_g2_irl_init_all,
4952     .get_eeprom = mv88e6xxx_g2_get_eeprom8,
4953     .set_eeprom = mv88e6xxx_g2_set_eeprom8,
4954     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4955     .phy_read = mv88e6xxx_g2_smi_phy_read,
4956     .phy_write = mv88e6xxx_g2_smi_phy_write,
4957     .port_set_link = mv88e6xxx_port_set_link,
4958     .port_sync_link = mv88e6xxx_port_sync_link,
4959     .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
4960     .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
4961     .port_max_speed_mode = mv88e6390_port_max_speed_mode,
4962     .port_tag_remap = mv88e6390_port_tag_remap,
4963     .port_set_policy = mv88e6352_port_set_policy,
4964     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4965     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4966     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4967     .port_set_ether_type = mv88e6351_port_set_ether_type,
4968     .port_pause_limit = mv88e6390_port_pause_limit,
4969     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4970     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4971     .port_get_cmode = mv88e6352_port_get_cmode,
4972     .port_set_cmode = mv88e6390_port_set_cmode,
4973     .port_setup_message_port = mv88e6xxx_setup_message_port,
4974     .stats_snapshot = mv88e6390_g1_stats_snapshot,
4975     .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
4976     .stats_get_sset_count = mv88e6320_stats_get_sset_count,
4977     .stats_get_strings = mv88e6320_stats_get_strings,
4978     .stats_get_stats = mv88e6390_stats_get_stats,
4979     .set_cpu_port = mv88e6390_g1_set_cpu_port,
4980     .set_egress_port = mv88e6390_g1_set_egress_port,
4981     .watchdog_ops = &mv88e6390_watchdog_ops,
4982     .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
4983     .pot_clear = mv88e6xxx_g2_pot_clear,
4984     .reset = mv88e6352_g1_reset,
4985     .rmu_disable = mv88e6390_g1_rmu_disable,
4986     .atu_get_hash = mv88e6165_g1_atu_get_hash,
4987     .atu_set_hash = mv88e6165_g1_atu_set_hash,
4988     .vtu_getnext = mv88e6390_g1_vtu_getnext,
4989     .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
4990     .stu_getnext = mv88e6390_g1_stu_getnext,
4991     .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
4992     .serdes_power = mv88e6390_serdes_power,
4993     .serdes_get_lane = mv88e6390_serdes_get_lane,
4994     /* Check status register pause & lpa register */
4995     .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
4996     .serdes_pcs_config = mv88e6390_serdes_pcs_config,
4997     .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
4998     .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
4999     .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
5000     .serdes_irq_enable = mv88e6390_serdes_irq_enable,
5001     .serdes_irq_status = mv88e6390_serdes_irq_status,
5002     .serdes_get_strings = mv88e6390_serdes_get_strings,
5003     .serdes_get_stats = mv88e6390_serdes_get_stats,
5004     .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
5005     .serdes_get_regs = mv88e6390_serdes_get_regs,
5006     .gpio_ops = &mv88e6352_gpio_ops,
5007     .avb_ops = &mv88e6390_avb_ops,
5008     .ptp_ops = &mv88e6352_ptp_ops,
5009     .phylink_get_caps = mv88e6390_phylink_get_caps,
5010 };
5011 
5012 static const struct mv88e6xxx_ops mv88e6320_ops = {
5013     /* MV88E6XXX_FAMILY_6320 */
5014     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
5015     .ip_pri_map = mv88e6085_g1_ip_pri_map,
5016     .irl_init_all = mv88e6352_g2_irl_init_all,
5017     .get_eeprom = mv88e6xxx_g2_get_eeprom16,
5018     .set_eeprom = mv88e6xxx_g2_set_eeprom16,
5019     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5020     .phy_read = mv88e6xxx_g2_smi_phy_read,
5021     .phy_write = mv88e6xxx_g2_smi_phy_write,
5022     .port_set_link = mv88e6xxx_port_set_link,
5023     .port_sync_link = mv88e6xxx_port_sync_link,
5024     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
5025     .port_tag_remap = mv88e6095_port_tag_remap,
5026     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5027     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5028     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5029     .port_set_ether_type = mv88e6351_port_set_ether_type,
5030     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5031     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5032     .port_pause_limit = mv88e6097_port_pause_limit,
5033     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5034     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5035     .port_get_cmode = mv88e6352_port_get_cmode,
5036     .port_setup_message_port = mv88e6xxx_setup_message_port,
5037     .stats_snapshot = mv88e6320_g1_stats_snapshot,
5038     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
5039     .stats_get_sset_count = mv88e6320_stats_get_sset_count,
5040     .stats_get_strings = mv88e6320_stats_get_strings,
5041     .stats_get_stats = mv88e6320_stats_get_stats,
5042     .set_cpu_port = mv88e6095_g1_set_cpu_port,
5043     .set_egress_port = mv88e6095_g1_set_egress_port,
5044     .watchdog_ops = &mv88e6390_watchdog_ops,
5045     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
5046     .pot_clear = mv88e6xxx_g2_pot_clear,
5047     .reset = mv88e6352_g1_reset,
5048     .vtu_getnext = mv88e6185_g1_vtu_getnext,
5049     .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
5050     .gpio_ops = &mv88e6352_gpio_ops,
5051     .avb_ops = &mv88e6352_avb_ops,
5052     .ptp_ops = &mv88e6352_ptp_ops,
5053     .phylink_get_caps = mv88e6185_phylink_get_caps,
5054 };
5055 
5056 static const struct mv88e6xxx_ops mv88e6321_ops = {
5057     /* MV88E6XXX_FAMILY_6320 */
5058     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
5059     .ip_pri_map = mv88e6085_g1_ip_pri_map,
5060     .irl_init_all = mv88e6352_g2_irl_init_all,
5061     .get_eeprom = mv88e6xxx_g2_get_eeprom16,
5062     .set_eeprom = mv88e6xxx_g2_set_eeprom16,
5063     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5064     .phy_read = mv88e6xxx_g2_smi_phy_read,
5065     .phy_write = mv88e6xxx_g2_smi_phy_write,
5066     .port_set_link = mv88e6xxx_port_set_link,
5067     .port_sync_link = mv88e6xxx_port_sync_link,
5068     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
5069     .port_tag_remap = mv88e6095_port_tag_remap,
5070     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5071     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5072     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5073     .port_set_ether_type = mv88e6351_port_set_ether_type,
5074     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5075     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5076     .port_pause_limit = mv88e6097_port_pause_limit,
5077     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5078     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5079     .port_get_cmode = mv88e6352_port_get_cmode,
5080     .port_setup_message_port = mv88e6xxx_setup_message_port,
5081     .stats_snapshot = mv88e6320_g1_stats_snapshot,
5082     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
5083     .stats_get_sset_count = mv88e6320_stats_get_sset_count,
5084     .stats_get_strings = mv88e6320_stats_get_strings,
5085     .stats_get_stats = mv88e6320_stats_get_stats,
5086     .set_cpu_port = mv88e6095_g1_set_cpu_port,
5087     .set_egress_port = mv88e6095_g1_set_egress_port,
5088     .watchdog_ops = &mv88e6390_watchdog_ops,
5089     .reset = mv88e6352_g1_reset,
5090     .vtu_getnext = mv88e6185_g1_vtu_getnext,
5091     .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
5092     .gpio_ops = &mv88e6352_gpio_ops,
5093     .avb_ops = &mv88e6352_avb_ops,
5094     .ptp_ops = &mv88e6352_ptp_ops,
5095     .phylink_get_caps = mv88e6185_phylink_get_caps,
5096 };
5097 
5098 static const struct mv88e6xxx_ops mv88e6341_ops = {
5099     /* MV88E6XXX_FAMILY_6341 */
5100     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
5101     .ip_pri_map = mv88e6085_g1_ip_pri_map,
5102     .irl_init_all = mv88e6352_g2_irl_init_all,
5103     .get_eeprom = mv88e6xxx_g2_get_eeprom8,
5104     .set_eeprom = mv88e6xxx_g2_set_eeprom8,
5105     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5106     .phy_read = mv88e6xxx_g2_smi_phy_read,
5107     .phy_write = mv88e6xxx_g2_smi_phy_write,
5108     .port_set_link = mv88e6xxx_port_set_link,
5109     .port_sync_link = mv88e6xxx_port_sync_link,
5110     .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
5111     .port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
5112     .port_max_speed_mode = mv88e6341_port_max_speed_mode,
5113     .port_tag_remap = mv88e6095_port_tag_remap,
5114     .port_set_policy = mv88e6352_port_set_policy,
5115     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5116     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5117     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5118     .port_set_ether_type = mv88e6351_port_set_ether_type,
5119     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5120     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5121     .port_pause_limit = mv88e6097_port_pause_limit,
5122     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5123     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5124     .port_get_cmode = mv88e6352_port_get_cmode,
5125     .port_set_cmode = mv88e6341_port_set_cmode,
5126     .port_setup_message_port = mv88e6xxx_setup_message_port,
5127     .stats_snapshot = mv88e6390_g1_stats_snapshot,
5128     .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
5129     .stats_get_sset_count = mv88e6320_stats_get_sset_count,
5130     .stats_get_strings = mv88e6320_stats_get_strings,
5131     .stats_get_stats = mv88e6390_stats_get_stats,
5132     .set_cpu_port = mv88e6390_g1_set_cpu_port,
5133     .set_egress_port = mv88e6390_g1_set_egress_port,
5134     .watchdog_ops = &mv88e6390_watchdog_ops,
5135     .mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
5136     .pot_clear = mv88e6xxx_g2_pot_clear,
5137     .reset = mv88e6352_g1_reset,
5138     .rmu_disable = mv88e6390_g1_rmu_disable,
5139     .atu_get_hash = mv88e6165_g1_atu_get_hash,
5140     .atu_set_hash = mv88e6165_g1_atu_set_hash,
5141     .vtu_getnext = mv88e6352_g1_vtu_getnext,
5142     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
5143     .stu_getnext = mv88e6352_g1_stu_getnext,
5144     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
5145     .serdes_power = mv88e6390_serdes_power,
5146     .serdes_get_lane = mv88e6341_serdes_get_lane,
5147     /* Check status register pause & lpa register */
5148     .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
5149     .serdes_pcs_config = mv88e6390_serdes_pcs_config,
5150     .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
5151     .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
5152     .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
5153     .serdes_irq_enable = mv88e6390_serdes_irq_enable,
5154     .serdes_irq_status = mv88e6390_serdes_irq_status,
5155     .gpio_ops = &mv88e6352_gpio_ops,
5156     .avb_ops = &mv88e6390_avb_ops,
5157     .ptp_ops = &mv88e6352_ptp_ops,
5158     .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
5159     .serdes_get_strings = mv88e6390_serdes_get_strings,
5160     .serdes_get_stats = mv88e6390_serdes_get_stats,
5161     .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
5162     .serdes_get_regs = mv88e6390_serdes_get_regs,
5163     .phylink_get_caps = mv88e6341_phylink_get_caps,
5164 };
5165 
5166 static const struct mv88e6xxx_ops mv88e6350_ops = {
5167     /* MV88E6XXX_FAMILY_6351 */
5168     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
5169     .ip_pri_map = mv88e6085_g1_ip_pri_map,
5170     .irl_init_all = mv88e6352_g2_irl_init_all,
5171     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5172     .phy_read = mv88e6xxx_g2_smi_phy_read,
5173     .phy_write = mv88e6xxx_g2_smi_phy_write,
5174     .port_set_link = mv88e6xxx_port_set_link,
5175     .port_sync_link = mv88e6xxx_port_sync_link,
5176     .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
5177     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
5178     .port_tag_remap = mv88e6095_port_tag_remap,
5179     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5180     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5181     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5182     .port_set_ether_type = mv88e6351_port_set_ether_type,
5183     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5184     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5185     .port_pause_limit = mv88e6097_port_pause_limit,
5186     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5187     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5188     .port_get_cmode = mv88e6352_port_get_cmode,
5189     .port_setup_message_port = mv88e6xxx_setup_message_port,
5190     .stats_snapshot = mv88e6320_g1_stats_snapshot,
5191     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
5192     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
5193     .stats_get_strings = mv88e6095_stats_get_strings,
5194     .stats_get_stats = mv88e6095_stats_get_stats,
5195     .set_cpu_port = mv88e6095_g1_set_cpu_port,
5196     .set_egress_port = mv88e6095_g1_set_egress_port,
5197     .watchdog_ops = &mv88e6097_watchdog_ops,
5198     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
5199     .pot_clear = mv88e6xxx_g2_pot_clear,
5200     .reset = mv88e6352_g1_reset,
5201     .atu_get_hash = mv88e6165_g1_atu_get_hash,
5202     .atu_set_hash = mv88e6165_g1_atu_set_hash,
5203     .vtu_getnext = mv88e6352_g1_vtu_getnext,
5204     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
5205     .stu_getnext = mv88e6352_g1_stu_getnext,
5206     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
5207     .phylink_get_caps = mv88e6185_phylink_get_caps,
5208 };
5209 
5210 static const struct mv88e6xxx_ops mv88e6351_ops = {
5211     /* MV88E6XXX_FAMILY_6351 */
5212     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
5213     .ip_pri_map = mv88e6085_g1_ip_pri_map,
5214     .irl_init_all = mv88e6352_g2_irl_init_all,
5215     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5216     .phy_read = mv88e6xxx_g2_smi_phy_read,
5217     .phy_write = mv88e6xxx_g2_smi_phy_write,
5218     .port_set_link = mv88e6xxx_port_set_link,
5219     .port_sync_link = mv88e6xxx_port_sync_link,
5220     .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
5221     .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
5222     .port_tag_remap = mv88e6095_port_tag_remap,
5223     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5224     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5225     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5226     .port_set_ether_type = mv88e6351_port_set_ether_type,
5227     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5228     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5229     .port_pause_limit = mv88e6097_port_pause_limit,
5230     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5231     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5232     .port_get_cmode = mv88e6352_port_get_cmode,
5233     .port_setup_message_port = mv88e6xxx_setup_message_port,
5234     .stats_snapshot = mv88e6320_g1_stats_snapshot,
5235     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
5236     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
5237     .stats_get_strings = mv88e6095_stats_get_strings,
5238     .stats_get_stats = mv88e6095_stats_get_stats,
5239     .set_cpu_port = mv88e6095_g1_set_cpu_port,
5240     .set_egress_port = mv88e6095_g1_set_egress_port,
5241     .watchdog_ops = &mv88e6097_watchdog_ops,
5242     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
5243     .pot_clear = mv88e6xxx_g2_pot_clear,
5244     .reset = mv88e6352_g1_reset,
5245     .atu_get_hash = mv88e6165_g1_atu_get_hash,
5246     .atu_set_hash = mv88e6165_g1_atu_set_hash,
5247     .vtu_getnext = mv88e6352_g1_vtu_getnext,
5248     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
5249     .stu_getnext = mv88e6352_g1_stu_getnext,
5250     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
5251     .avb_ops = &mv88e6352_avb_ops,
5252     .ptp_ops = &mv88e6352_ptp_ops,
5253     .phylink_get_caps = mv88e6185_phylink_get_caps,
5254 };
5255 
5256 static const struct mv88e6xxx_ops mv88e6352_ops = {
5257     /* MV88E6XXX_FAMILY_6352 */
5258     .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
5259     .ip_pri_map = mv88e6085_g1_ip_pri_map,
5260     .irl_init_all = mv88e6352_g2_irl_init_all,
5261     .get_eeprom = mv88e6xxx_g2_get_eeprom16,
5262     .set_eeprom = mv88e6xxx_g2_set_eeprom16,
5263     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5264     .phy_read = mv88e6xxx_g2_smi_phy_read,
5265     .phy_write = mv88e6xxx_g2_smi_phy_write,
5266     .port_set_link = mv88e6xxx_port_set_link,
5267     .port_sync_link = mv88e6xxx_port_sync_link,
5268     .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
5269     .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
5270     .port_tag_remap = mv88e6095_port_tag_remap,
5271     .port_set_policy = mv88e6352_port_set_policy,
5272     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5273     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5274     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5275     .port_set_ether_type = mv88e6351_port_set_ether_type,
5276     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5277     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5278     .port_pause_limit = mv88e6097_port_pause_limit,
5279     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5280     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5281     .port_get_cmode = mv88e6352_port_get_cmode,
5282     .port_setup_message_port = mv88e6xxx_setup_message_port,
5283     .stats_snapshot = mv88e6320_g1_stats_snapshot,
5284     .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
5285     .stats_get_sset_count = mv88e6095_stats_get_sset_count,
5286     .stats_get_strings = mv88e6095_stats_get_strings,
5287     .stats_get_stats = mv88e6095_stats_get_stats,
5288     .set_cpu_port = mv88e6095_g1_set_cpu_port,
5289     .set_egress_port = mv88e6095_g1_set_egress_port,
5290     .watchdog_ops = &mv88e6097_watchdog_ops,
5291     .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
5292     .pot_clear = mv88e6xxx_g2_pot_clear,
5293     .reset = mv88e6352_g1_reset,
5294     .rmu_disable = mv88e6352_g1_rmu_disable,
5295     .atu_get_hash = mv88e6165_g1_atu_get_hash,
5296     .atu_set_hash = mv88e6165_g1_atu_set_hash,
5297     .vtu_getnext = mv88e6352_g1_vtu_getnext,
5298     .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
5299     .stu_getnext = mv88e6352_g1_stu_getnext,
5300     .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
5301     .serdes_get_lane = mv88e6352_serdes_get_lane,
5302     .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
5303     .serdes_pcs_config = mv88e6352_serdes_pcs_config,
5304     .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
5305     .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
5306     .serdes_power = mv88e6352_serdes_power,
5307     .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
5308     .serdes_irq_enable = mv88e6352_serdes_irq_enable,
5309     .serdes_irq_status = mv88e6352_serdes_irq_status,
5310     .gpio_ops = &mv88e6352_gpio_ops,
5311     .avb_ops = &mv88e6352_avb_ops,
5312     .ptp_ops = &mv88e6352_ptp_ops,
5313     .serdes_get_sset_count = mv88e6352_serdes_get_sset_count,
5314     .serdes_get_strings = mv88e6352_serdes_get_strings,
5315     .serdes_get_stats = mv88e6352_serdes_get_stats,
5316     .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
5317     .serdes_get_regs = mv88e6352_serdes_get_regs,
5318     .serdes_set_tx_amplitude = mv88e6352_serdes_set_tx_amplitude,
5319     .phylink_get_caps = mv88e6352_phylink_get_caps,
5320 };
5321 
5322 static const struct mv88e6xxx_ops mv88e6390_ops = {
5323     /* MV88E6XXX_FAMILY_6390 */
5324     .setup_errata = mv88e6390_setup_errata,
5325     .irl_init_all = mv88e6390_g2_irl_init_all,
5326     .get_eeprom = mv88e6xxx_g2_get_eeprom8,
5327     .set_eeprom = mv88e6xxx_g2_set_eeprom8,
5328     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5329     .phy_read = mv88e6xxx_g2_smi_phy_read,
5330     .phy_write = mv88e6xxx_g2_smi_phy_write,
5331     .port_set_link = mv88e6xxx_port_set_link,
5332     .port_sync_link = mv88e6xxx_port_sync_link,
5333     .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
5334     .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
5335     .port_max_speed_mode = mv88e6390_port_max_speed_mode,
5336     .port_tag_remap = mv88e6390_port_tag_remap,
5337     .port_set_policy = mv88e6352_port_set_policy,
5338     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5339     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5340     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5341     .port_set_ether_type = mv88e6351_port_set_ether_type,
5342     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5343     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5344     .port_pause_limit = mv88e6390_port_pause_limit,
5345     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5346     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5347     .port_get_cmode = mv88e6352_port_get_cmode,
5348     .port_set_cmode = mv88e6390_port_set_cmode,
5349     .port_setup_message_port = mv88e6xxx_setup_message_port,
5350     .stats_snapshot = mv88e6390_g1_stats_snapshot,
5351     .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
5352     .stats_get_sset_count = mv88e6320_stats_get_sset_count,
5353     .stats_get_strings = mv88e6320_stats_get_strings,
5354     .stats_get_stats = mv88e6390_stats_get_stats,
5355     .set_cpu_port = mv88e6390_g1_set_cpu_port,
5356     .set_egress_port = mv88e6390_g1_set_egress_port,
5357     .watchdog_ops = &mv88e6390_watchdog_ops,
5358     .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
5359     .pot_clear = mv88e6xxx_g2_pot_clear,
5360     .reset = mv88e6352_g1_reset,
5361     .rmu_disable = mv88e6390_g1_rmu_disable,
5362     .atu_get_hash = mv88e6165_g1_atu_get_hash,
5363     .atu_set_hash = mv88e6165_g1_atu_set_hash,
5364     .vtu_getnext = mv88e6390_g1_vtu_getnext,
5365     .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
5366     .stu_getnext = mv88e6390_g1_stu_getnext,
5367     .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
5368     .serdes_power = mv88e6390_serdes_power,
5369     .serdes_get_lane = mv88e6390_serdes_get_lane,
5370     /* Check status register pause & lpa register */
5371     .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
5372     .serdes_pcs_config = mv88e6390_serdes_pcs_config,
5373     .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
5374     .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
5375     .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
5376     .serdes_irq_enable = mv88e6390_serdes_irq_enable,
5377     .serdes_irq_status = mv88e6390_serdes_irq_status,
5378     .gpio_ops = &mv88e6352_gpio_ops,
5379     .avb_ops = &mv88e6390_avb_ops,
5380     .ptp_ops = &mv88e6352_ptp_ops,
5381     .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
5382     .serdes_get_strings = mv88e6390_serdes_get_strings,
5383     .serdes_get_stats = mv88e6390_serdes_get_stats,
5384     .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
5385     .serdes_get_regs = mv88e6390_serdes_get_regs,
5386     .phylink_get_caps = mv88e6390_phylink_get_caps,
5387 };
5388 
5389 static const struct mv88e6xxx_ops mv88e6390x_ops = {
5390     /* MV88E6XXX_FAMILY_6390 */
5391     .setup_errata = mv88e6390_setup_errata,
5392     .irl_init_all = mv88e6390_g2_irl_init_all,
5393     .get_eeprom = mv88e6xxx_g2_get_eeprom8,
5394     .set_eeprom = mv88e6xxx_g2_set_eeprom8,
5395     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5396     .phy_read = mv88e6xxx_g2_smi_phy_read,
5397     .phy_write = mv88e6xxx_g2_smi_phy_write,
5398     .port_set_link = mv88e6xxx_port_set_link,
5399     .port_sync_link = mv88e6xxx_port_sync_link,
5400     .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
5401     .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
5402     .port_max_speed_mode = mv88e6390x_port_max_speed_mode,
5403     .port_tag_remap = mv88e6390_port_tag_remap,
5404     .port_set_policy = mv88e6352_port_set_policy,
5405     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5406     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5407     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5408     .port_set_ether_type = mv88e6351_port_set_ether_type,
5409     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5410     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5411     .port_pause_limit = mv88e6390_port_pause_limit,
5412     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5413     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5414     .port_get_cmode = mv88e6352_port_get_cmode,
5415     .port_set_cmode = mv88e6390x_port_set_cmode,
5416     .port_setup_message_port = mv88e6xxx_setup_message_port,
5417     .stats_snapshot = mv88e6390_g1_stats_snapshot,
5418     .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
5419     .stats_get_sset_count = mv88e6320_stats_get_sset_count,
5420     .stats_get_strings = mv88e6320_stats_get_strings,
5421     .stats_get_stats = mv88e6390_stats_get_stats,
5422     .set_cpu_port = mv88e6390_g1_set_cpu_port,
5423     .set_egress_port = mv88e6390_g1_set_egress_port,
5424     .watchdog_ops = &mv88e6390_watchdog_ops,
5425     .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
5426     .pot_clear = mv88e6xxx_g2_pot_clear,
5427     .reset = mv88e6352_g1_reset,
5428     .rmu_disable = mv88e6390_g1_rmu_disable,
5429     .atu_get_hash = mv88e6165_g1_atu_get_hash,
5430     .atu_set_hash = mv88e6165_g1_atu_set_hash,
5431     .vtu_getnext = mv88e6390_g1_vtu_getnext,
5432     .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
5433     .stu_getnext = mv88e6390_g1_stu_getnext,
5434     .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
5435     .serdes_power = mv88e6390_serdes_power,
5436     .serdes_get_lane = mv88e6390x_serdes_get_lane,
5437     .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
5438     .serdes_pcs_config = mv88e6390_serdes_pcs_config,
5439     .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
5440     .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
5441     .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
5442     .serdes_irq_enable = mv88e6390_serdes_irq_enable,
5443     .serdes_irq_status = mv88e6390_serdes_irq_status,
5444     .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
5445     .serdes_get_strings = mv88e6390_serdes_get_strings,
5446     .serdes_get_stats = mv88e6390_serdes_get_stats,
5447     .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
5448     .serdes_get_regs = mv88e6390_serdes_get_regs,
5449     .gpio_ops = &mv88e6352_gpio_ops,
5450     .avb_ops = &mv88e6390_avb_ops,
5451     .ptp_ops = &mv88e6352_ptp_ops,
5452     .phylink_get_caps = mv88e6390x_phylink_get_caps,
5453 };
5454 
5455 static const struct mv88e6xxx_ops mv88e6393x_ops = {
5456     /* MV88E6XXX_FAMILY_6393 */
5457     .setup_errata = mv88e6393x_serdes_setup_errata,
5458     .irl_init_all = mv88e6390_g2_irl_init_all,
5459     .get_eeprom = mv88e6xxx_g2_get_eeprom8,
5460     .set_eeprom = mv88e6xxx_g2_set_eeprom8,
5461     .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5462     .phy_read = mv88e6xxx_g2_smi_phy_read,
5463     .phy_write = mv88e6xxx_g2_smi_phy_write,
5464     .port_set_link = mv88e6xxx_port_set_link,
5465     .port_sync_link = mv88e6xxx_port_sync_link,
5466     .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
5467     .port_set_speed_duplex = mv88e6393x_port_set_speed_duplex,
5468     .port_max_speed_mode = mv88e6393x_port_max_speed_mode,
5469     .port_tag_remap = mv88e6390_port_tag_remap,
5470     .port_set_policy = mv88e6393x_port_set_policy,
5471     .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5472     .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5473     .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5474     .port_set_ether_type = mv88e6393x_port_set_ether_type,
5475     .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5476     .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5477     .port_pause_limit = mv88e6390_port_pause_limit,
5478     .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5479     .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5480     .port_get_cmode = mv88e6352_port_get_cmode,
5481     .port_set_cmode = mv88e6393x_port_set_cmode,
5482     .port_setup_message_port = mv88e6xxx_setup_message_port,
5483     .port_set_upstream_port = mv88e6393x_port_set_upstream_port,
5484     .stats_snapshot = mv88e6390_g1_stats_snapshot,
5485     .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
5486     .stats_get_sset_count = mv88e6320_stats_get_sset_count,
5487     .stats_get_strings = mv88e6320_stats_get_strings,
5488     .stats_get_stats = mv88e6390_stats_get_stats,
5489     /* .set_cpu_port is missing because this family does not support a global
5490      * CPU port, only per port CPU port which is set via
5491      * .port_set_upstream_port method.
5492      */
5493     .set_egress_port = mv88e6393x_set_egress_port,
5494     .watchdog_ops = &mv88e6390_watchdog_ops,
5495     .mgmt_rsvd2cpu = mv88e6393x_port_mgmt_rsvd2cpu,
5496     .pot_clear = mv88e6xxx_g2_pot_clear,
5497     .reset = mv88e6352_g1_reset,
5498     .rmu_disable = mv88e6390_g1_rmu_disable,
5499     .atu_get_hash = mv88e6165_g1_atu_get_hash,
5500     .atu_set_hash = mv88e6165_g1_atu_set_hash,
5501     .vtu_getnext = mv88e6390_g1_vtu_getnext,
5502     .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
5503     .stu_getnext = mv88e6390_g1_stu_getnext,
5504     .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
5505     .serdes_power = mv88e6393x_serdes_power,
5506     .serdes_get_lane = mv88e6393x_serdes_get_lane,
5507     .serdes_pcs_get_state = mv88e6393x_serdes_pcs_get_state,
5508     .serdes_pcs_config = mv88e6390_serdes_pcs_config,
5509     .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
5510     .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
5511     .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
5512     .serdes_irq_enable = mv88e6393x_serdes_irq_enable,
5513     .serdes_irq_status = mv88e6393x_serdes_irq_status,
5514     /* TODO: serdes stats */
5515     .gpio_ops = &mv88e6352_gpio_ops,
5516     .avb_ops = &mv88e6390_avb_ops,
5517     .ptp_ops = &mv88e6352_ptp_ops,
5518     .phylink_get_caps = mv88e6393x_phylink_get_caps,
5519 };
5520 
5521 static const struct mv88e6xxx_info mv88e6xxx_table[] = {
5522     [MV88E6085] = {
5523         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6085,
5524         .family = MV88E6XXX_FAMILY_6097,
5525         .name = "Marvell 88E6085",
5526         .num_databases = 4096,
5527         .num_macs = 8192,
5528         .num_ports = 10,
5529         .num_internal_phys = 5,
5530         .max_vid = 4095,
5531         .max_sid = 63,
5532         .port_base_addr = 0x10,
5533         .phy_base_addr = 0x0,
5534         .global1_addr = 0x1b,
5535         .global2_addr = 0x1c,
5536         .age_time_coeff = 15000,
5537         .g1_irqs = 8,
5538         .g2_irqs = 10,
5539         .atu_move_port_mask = 0xf,
5540         .pvt = true,
5541         .multi_chip = true,
5542         .ops = &mv88e6085_ops,
5543     },
5544 
5545     [MV88E6095] = {
5546         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6095,
5547         .family = MV88E6XXX_FAMILY_6095,
5548         .name = "Marvell 88E6095/88E6095F",
5549         .num_databases = 256,
5550         .num_macs = 8192,
5551         .num_ports = 11,
5552         .num_internal_phys = 0,
5553         .max_vid = 4095,
5554         .port_base_addr = 0x10,
5555         .phy_base_addr = 0x0,
5556         .global1_addr = 0x1b,
5557         .global2_addr = 0x1c,
5558         .age_time_coeff = 15000,
5559         .g1_irqs = 8,
5560         .atu_move_port_mask = 0xf,
5561         .multi_chip = true,
5562         .ops = &mv88e6095_ops,
5563     },
5564 
5565     [MV88E6097] = {
5566         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6097,
5567         .family = MV88E6XXX_FAMILY_6097,
5568         .name = "Marvell 88E6097/88E6097F",
5569         .num_databases = 4096,
5570         .num_macs = 8192,
5571         .num_ports = 11,
5572         .num_internal_phys = 8,
5573         .max_vid = 4095,
5574         .max_sid = 63,
5575         .port_base_addr = 0x10,
5576         .phy_base_addr = 0x0,
5577         .global1_addr = 0x1b,
5578         .global2_addr = 0x1c,
5579         .age_time_coeff = 15000,
5580         .g1_irqs = 8,
5581         .g2_irqs = 10,
5582         .atu_move_port_mask = 0xf,
5583         .pvt = true,
5584         .multi_chip = true,
5585         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5586         .ops = &mv88e6097_ops,
5587     },
5588 
5589     [MV88E6123] = {
5590         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6123,
5591         .family = MV88E6XXX_FAMILY_6165,
5592         .name = "Marvell 88E6123",
5593         .num_databases = 4096,
5594         .num_macs = 1024,
5595         .num_ports = 3,
5596         .num_internal_phys = 5,
5597         .max_vid = 4095,
5598         .max_sid = 63,
5599         .port_base_addr = 0x10,
5600         .phy_base_addr = 0x0,
5601         .global1_addr = 0x1b,
5602         .global2_addr = 0x1c,
5603         .age_time_coeff = 15000,
5604         .g1_irqs = 9,
5605         .g2_irqs = 10,
5606         .atu_move_port_mask = 0xf,
5607         .pvt = true,
5608         .multi_chip = true,
5609         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5610         .ops = &mv88e6123_ops,
5611     },
5612 
5613     [MV88E6131] = {
5614         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6131,
5615         .family = MV88E6XXX_FAMILY_6185,
5616         .name = "Marvell 88E6131",
5617         .num_databases = 256,
5618         .num_macs = 8192,
5619         .num_ports = 8,
5620         .num_internal_phys = 0,
5621         .max_vid = 4095,
5622         .port_base_addr = 0x10,
5623         .phy_base_addr = 0x0,
5624         .global1_addr = 0x1b,
5625         .global2_addr = 0x1c,
5626         .age_time_coeff = 15000,
5627         .g1_irqs = 9,
5628         .atu_move_port_mask = 0xf,
5629         .multi_chip = true,
5630         .ops = &mv88e6131_ops,
5631     },
5632 
5633     [MV88E6141] = {
5634         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
5635         .family = MV88E6XXX_FAMILY_6341,
5636         .name = "Marvell 88E6141",
5637         .num_databases = 4096,
5638         .num_macs = 2048,
5639         .num_ports = 6,
5640         .num_internal_phys = 5,
5641         .num_gpio = 11,
5642         .max_vid = 4095,
5643         .max_sid = 63,
5644         .port_base_addr = 0x10,
5645         .phy_base_addr = 0x10,
5646         .global1_addr = 0x1b,
5647         .global2_addr = 0x1c,
5648         .age_time_coeff = 3750,
5649         .atu_move_port_mask = 0x1f,
5650         .g1_irqs = 9,
5651         .g2_irqs = 10,
5652         .pvt = true,
5653         .multi_chip = true,
5654         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5655         .ops = &mv88e6141_ops,
5656     },
5657 
5658     [MV88E6161] = {
5659         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6161,
5660         .family = MV88E6XXX_FAMILY_6165,
5661         .name = "Marvell 88E6161",
5662         .num_databases = 4096,
5663         .num_macs = 1024,
5664         .num_ports = 6,
5665         .num_internal_phys = 5,
5666         .max_vid = 4095,
5667         .max_sid = 63,
5668         .port_base_addr = 0x10,
5669         .phy_base_addr = 0x0,
5670         .global1_addr = 0x1b,
5671         .global2_addr = 0x1c,
5672         .age_time_coeff = 15000,
5673         .g1_irqs = 9,
5674         .g2_irqs = 10,
5675         .atu_move_port_mask = 0xf,
5676         .pvt = true,
5677         .multi_chip = true,
5678         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5679         .ptp_support = true,
5680         .ops = &mv88e6161_ops,
5681     },
5682 
5683     [MV88E6165] = {
5684         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6165,
5685         .family = MV88E6XXX_FAMILY_6165,
5686         .name = "Marvell 88E6165",
5687         .num_databases = 4096,
5688         .num_macs = 8192,
5689         .num_ports = 6,
5690         .num_internal_phys = 0,
5691         .max_vid = 4095,
5692         .max_sid = 63,
5693         .port_base_addr = 0x10,
5694         .phy_base_addr = 0x0,
5695         .global1_addr = 0x1b,
5696         .global2_addr = 0x1c,
5697         .age_time_coeff = 15000,
5698         .g1_irqs = 9,
5699         .g2_irqs = 10,
5700         .atu_move_port_mask = 0xf,
5701         .pvt = true,
5702         .multi_chip = true,
5703         .ptp_support = true,
5704         .ops = &mv88e6165_ops,
5705     },
5706 
5707     [MV88E6171] = {
5708         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6171,
5709         .family = MV88E6XXX_FAMILY_6351,
5710         .name = "Marvell 88E6171",
5711         .num_databases = 4096,
5712         .num_macs = 8192,
5713         .num_ports = 7,
5714         .num_internal_phys = 5,
5715         .max_vid = 4095,
5716         .max_sid = 63,
5717         .port_base_addr = 0x10,
5718         .phy_base_addr = 0x0,
5719         .global1_addr = 0x1b,
5720         .global2_addr = 0x1c,
5721         .age_time_coeff = 15000,
5722         .g1_irqs = 9,
5723         .g2_irqs = 10,
5724         .atu_move_port_mask = 0xf,
5725         .pvt = true,
5726         .multi_chip = true,
5727         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5728         .ops = &mv88e6171_ops,
5729     },
5730 
5731     [MV88E6172] = {
5732         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6172,
5733         .family = MV88E6XXX_FAMILY_6352,
5734         .name = "Marvell 88E6172",
5735         .num_databases = 4096,
5736         .num_macs = 8192,
5737         .num_ports = 7,
5738         .num_internal_phys = 5,
5739         .num_gpio = 15,
5740         .max_vid = 4095,
5741         .max_sid = 63,
5742         .port_base_addr = 0x10,
5743         .phy_base_addr = 0x0,
5744         .global1_addr = 0x1b,
5745         .global2_addr = 0x1c,
5746         .age_time_coeff = 15000,
5747         .g1_irqs = 9,
5748         .g2_irqs = 10,
5749         .atu_move_port_mask = 0xf,
5750         .pvt = true,
5751         .multi_chip = true,
5752         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5753         .ops = &mv88e6172_ops,
5754     },
5755 
5756     [MV88E6175] = {
5757         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6175,
5758         .family = MV88E6XXX_FAMILY_6351,
5759         .name = "Marvell 88E6175",
5760         .num_databases = 4096,
5761         .num_macs = 8192,
5762         .num_ports = 7,
5763         .num_internal_phys = 5,
5764         .max_vid = 4095,
5765         .max_sid = 63,
5766         .port_base_addr = 0x10,
5767         .phy_base_addr = 0x0,
5768         .global1_addr = 0x1b,
5769         .global2_addr = 0x1c,
5770         .age_time_coeff = 15000,
5771         .g1_irqs = 9,
5772         .g2_irqs = 10,
5773         .atu_move_port_mask = 0xf,
5774         .pvt = true,
5775         .multi_chip = true,
5776         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5777         .ops = &mv88e6175_ops,
5778     },
5779 
5780     [MV88E6176] = {
5781         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6176,
5782         .family = MV88E6XXX_FAMILY_6352,
5783         .name = "Marvell 88E6176",
5784         .num_databases = 4096,
5785         .num_macs = 8192,
5786         .num_ports = 7,
5787         .num_internal_phys = 5,
5788         .num_gpio = 15,
5789         .max_vid = 4095,
5790         .max_sid = 63,
5791         .port_base_addr = 0x10,
5792         .phy_base_addr = 0x0,
5793         .global1_addr = 0x1b,
5794         .global2_addr = 0x1c,
5795         .age_time_coeff = 15000,
5796         .g1_irqs = 9,
5797         .g2_irqs = 10,
5798         .atu_move_port_mask = 0xf,
5799         .pvt = true,
5800         .multi_chip = true,
5801         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5802         .ops = &mv88e6176_ops,
5803     },
5804 
5805     [MV88E6185] = {
5806         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6185,
5807         .family = MV88E6XXX_FAMILY_6185,
5808         .name = "Marvell 88E6185",
5809         .num_databases = 256,
5810         .num_macs = 8192,
5811         .num_ports = 10,
5812         .num_internal_phys = 0,
5813         .max_vid = 4095,
5814         .port_base_addr = 0x10,
5815         .phy_base_addr = 0x0,
5816         .global1_addr = 0x1b,
5817         .global2_addr = 0x1c,
5818         .age_time_coeff = 15000,
5819         .g1_irqs = 8,
5820         .atu_move_port_mask = 0xf,
5821         .multi_chip = true,
5822         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5823         .ops = &mv88e6185_ops,
5824     },
5825 
5826     [MV88E6190] = {
5827         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190,
5828         .family = MV88E6XXX_FAMILY_6390,
5829         .name = "Marvell 88E6190",
5830         .num_databases = 4096,
5831         .num_macs = 16384,
5832         .num_ports = 11,    /* 10 + Z80 */
5833         .num_internal_phys = 9,
5834         .num_gpio = 16,
5835         .max_vid = 8191,
5836         .max_sid = 63,
5837         .port_base_addr = 0x0,
5838         .phy_base_addr = 0x0,
5839         .global1_addr = 0x1b,
5840         .global2_addr = 0x1c,
5841         .age_time_coeff = 3750,
5842         .g1_irqs = 9,
5843         .g2_irqs = 14,
5844         .pvt = true,
5845         .multi_chip = true,
5846         .atu_move_port_mask = 0x1f,
5847         .ops = &mv88e6190_ops,
5848     },
5849 
5850     [MV88E6190X] = {
5851         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190X,
5852         .family = MV88E6XXX_FAMILY_6390,
5853         .name = "Marvell 88E6190X",
5854         .num_databases = 4096,
5855         .num_macs = 16384,
5856         .num_ports = 11,    /* 10 + Z80 */
5857         .num_internal_phys = 9,
5858         .num_gpio = 16,
5859         .max_vid = 8191,
5860         .max_sid = 63,
5861         .port_base_addr = 0x0,
5862         .phy_base_addr = 0x0,
5863         .global1_addr = 0x1b,
5864         .global2_addr = 0x1c,
5865         .age_time_coeff = 3750,
5866         .g1_irqs = 9,
5867         .g2_irqs = 14,
5868         .atu_move_port_mask = 0x1f,
5869         .pvt = true,
5870         .multi_chip = true,
5871         .ops = &mv88e6190x_ops,
5872     },
5873 
5874     [MV88E6191] = {
5875         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6191,
5876         .family = MV88E6XXX_FAMILY_6390,
5877         .name = "Marvell 88E6191",
5878         .num_databases = 4096,
5879         .num_macs = 16384,
5880         .num_ports = 11,    /* 10 + Z80 */
5881         .num_internal_phys = 9,
5882         .max_vid = 8191,
5883         .max_sid = 63,
5884         .port_base_addr = 0x0,
5885         .phy_base_addr = 0x0,
5886         .global1_addr = 0x1b,
5887         .global2_addr = 0x1c,
5888         .age_time_coeff = 3750,
5889         .g1_irqs = 9,
5890         .g2_irqs = 14,
5891         .atu_move_port_mask = 0x1f,
5892         .pvt = true,
5893         .multi_chip = true,
5894         .ptp_support = true,
5895         .ops = &mv88e6191_ops,
5896     },
5897 
5898     [MV88E6191X] = {
5899         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6191X,
5900         .family = MV88E6XXX_FAMILY_6393,
5901         .name = "Marvell 88E6191X",
5902         .num_databases = 4096,
5903         .num_ports = 11,    /* 10 + Z80 */
5904         .num_internal_phys = 9,
5905         .max_vid = 8191,
5906         .max_sid = 63,
5907         .port_base_addr = 0x0,
5908         .phy_base_addr = 0x0,
5909         .global1_addr = 0x1b,
5910         .global2_addr = 0x1c,
5911         .age_time_coeff = 3750,
5912         .g1_irqs = 10,
5913         .g2_irqs = 14,
5914         .atu_move_port_mask = 0x1f,
5915         .pvt = true,
5916         .multi_chip = true,
5917         .ptp_support = true,
5918         .ops = &mv88e6393x_ops,
5919     },
5920 
5921     [MV88E6193X] = {
5922         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6193X,
5923         .family = MV88E6XXX_FAMILY_6393,
5924         .name = "Marvell 88E6193X",
5925         .num_databases = 4096,
5926         .num_ports = 11,    /* 10 + Z80 */
5927         .num_internal_phys = 9,
5928         .max_vid = 8191,
5929         .max_sid = 63,
5930         .port_base_addr = 0x0,
5931         .phy_base_addr = 0x0,
5932         .global1_addr = 0x1b,
5933         .global2_addr = 0x1c,
5934         .age_time_coeff = 3750,
5935         .g1_irqs = 10,
5936         .g2_irqs = 14,
5937         .atu_move_port_mask = 0x1f,
5938         .pvt = true,
5939         .multi_chip = true,
5940         .ptp_support = true,
5941         .ops = &mv88e6393x_ops,
5942     },
5943 
5944     [MV88E6220] = {
5945         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6220,
5946         .family = MV88E6XXX_FAMILY_6250,
5947         .name = "Marvell 88E6220",
5948         .num_databases = 64,
5949 
5950         /* Ports 2-4 are not routed to pins
5951          * => usable ports 0, 1, 5, 6
5952          */
5953         .num_ports = 7,
5954         .num_internal_phys = 2,
5955         .invalid_port_mask = BIT(2) | BIT(3) | BIT(4),
5956         .max_vid = 4095,
5957         .port_base_addr = 0x08,
5958         .phy_base_addr = 0x00,
5959         .global1_addr = 0x0f,
5960         .global2_addr = 0x07,
5961         .age_time_coeff = 15000,
5962         .g1_irqs = 9,
5963         .g2_irqs = 10,
5964         .atu_move_port_mask = 0xf,
5965         .dual_chip = true,
5966         .ptp_support = true,
5967         .ops = &mv88e6250_ops,
5968     },
5969 
5970     [MV88E6240] = {
5971         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6240,
5972         .family = MV88E6XXX_FAMILY_6352,
5973         .name = "Marvell 88E6240",
5974         .num_databases = 4096,
5975         .num_macs = 8192,
5976         .num_ports = 7,
5977         .num_internal_phys = 5,
5978         .num_gpio = 15,
5979         .max_vid = 4095,
5980         .max_sid = 63,
5981         .port_base_addr = 0x10,
5982         .phy_base_addr = 0x0,
5983         .global1_addr = 0x1b,
5984         .global2_addr = 0x1c,
5985         .age_time_coeff = 15000,
5986         .g1_irqs = 9,
5987         .g2_irqs = 10,
5988         .atu_move_port_mask = 0xf,
5989         .pvt = true,
5990         .multi_chip = true,
5991         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5992         .ptp_support = true,
5993         .ops = &mv88e6240_ops,
5994     },
5995 
5996     [MV88E6250] = {
5997         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6250,
5998         .family = MV88E6XXX_FAMILY_6250,
5999         .name = "Marvell 88E6250",
6000         .num_databases = 64,
6001         .num_ports = 7,
6002         .num_internal_phys = 5,
6003         .max_vid = 4095,
6004         .port_base_addr = 0x08,
6005         .phy_base_addr = 0x00,
6006         .global1_addr = 0x0f,
6007         .global2_addr = 0x07,
6008         .age_time_coeff = 15000,
6009         .g1_irqs = 9,
6010         .g2_irqs = 10,
6011         .atu_move_port_mask = 0xf,
6012         .dual_chip = true,
6013         .ptp_support = true,
6014         .ops = &mv88e6250_ops,
6015     },
6016 
6017     [MV88E6290] = {
6018         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6290,
6019         .family = MV88E6XXX_FAMILY_6390,
6020         .name = "Marvell 88E6290",
6021         .num_databases = 4096,
6022         .num_ports = 11,    /* 10 + Z80 */
6023         .num_internal_phys = 9,
6024         .num_gpio = 16,
6025         .max_vid = 8191,
6026         .max_sid = 63,
6027         .port_base_addr = 0x0,
6028         .phy_base_addr = 0x0,
6029         .global1_addr = 0x1b,
6030         .global2_addr = 0x1c,
6031         .age_time_coeff = 3750,
6032         .g1_irqs = 9,
6033         .g2_irqs = 14,
6034         .atu_move_port_mask = 0x1f,
6035         .pvt = true,
6036         .multi_chip = true,
6037         .ptp_support = true,
6038         .ops = &mv88e6290_ops,
6039     },
6040 
6041     [MV88E6320] = {
6042         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6320,
6043         .family = MV88E6XXX_FAMILY_6320,
6044         .name = "Marvell 88E6320",
6045         .num_databases = 4096,
6046         .num_macs = 8192,
6047         .num_ports = 7,
6048         .num_internal_phys = 5,
6049         .num_gpio = 15,
6050         .max_vid = 4095,
6051         .port_base_addr = 0x10,
6052         .phy_base_addr = 0x0,
6053         .global1_addr = 0x1b,
6054         .global2_addr = 0x1c,
6055         .age_time_coeff = 15000,
6056         .g1_irqs = 8,
6057         .g2_irqs = 10,
6058         .atu_move_port_mask = 0xf,
6059         .pvt = true,
6060         .multi_chip = true,
6061         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6062         .ptp_support = true,
6063         .ops = &mv88e6320_ops,
6064     },
6065 
6066     [MV88E6321] = {
6067         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6321,
6068         .family = MV88E6XXX_FAMILY_6320,
6069         .name = "Marvell 88E6321",
6070         .num_databases = 4096,
6071         .num_macs = 8192,
6072         .num_ports = 7,
6073         .num_internal_phys = 5,
6074         .num_gpio = 15,
6075         .max_vid = 4095,
6076         .port_base_addr = 0x10,
6077         .phy_base_addr = 0x0,
6078         .global1_addr = 0x1b,
6079         .global2_addr = 0x1c,
6080         .age_time_coeff = 15000,
6081         .g1_irqs = 8,
6082         .g2_irqs = 10,
6083         .atu_move_port_mask = 0xf,
6084         .multi_chip = true,
6085         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6086         .ptp_support = true,
6087         .ops = &mv88e6321_ops,
6088     },
6089 
6090     [MV88E6341] = {
6091         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
6092         .family = MV88E6XXX_FAMILY_6341,
6093         .name = "Marvell 88E6341",
6094         .num_databases = 4096,
6095         .num_macs = 2048,
6096         .num_internal_phys = 5,
6097         .num_ports = 6,
6098         .num_gpio = 11,
6099         .max_vid = 4095,
6100         .max_sid = 63,
6101         .port_base_addr = 0x10,
6102         .phy_base_addr = 0x10,
6103         .global1_addr = 0x1b,
6104         .global2_addr = 0x1c,
6105         .age_time_coeff = 3750,
6106         .atu_move_port_mask = 0x1f,
6107         .g1_irqs = 9,
6108         .g2_irqs = 10,
6109         .pvt = true,
6110         .multi_chip = true,
6111         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6112         .ptp_support = true,
6113         .ops = &mv88e6341_ops,
6114     },
6115 
6116     [MV88E6350] = {
6117         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6350,
6118         .family = MV88E6XXX_FAMILY_6351,
6119         .name = "Marvell 88E6350",
6120         .num_databases = 4096,
6121         .num_macs = 8192,
6122         .num_ports = 7,
6123         .num_internal_phys = 5,
6124         .max_vid = 4095,
6125         .max_sid = 63,
6126         .port_base_addr = 0x10,
6127         .phy_base_addr = 0x0,
6128         .global1_addr = 0x1b,
6129         .global2_addr = 0x1c,
6130         .age_time_coeff = 15000,
6131         .g1_irqs = 9,
6132         .g2_irqs = 10,
6133         .atu_move_port_mask = 0xf,
6134         .pvt = true,
6135         .multi_chip = true,
6136         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6137         .ops = &mv88e6350_ops,
6138     },
6139 
6140     [MV88E6351] = {
6141         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6351,
6142         .family = MV88E6XXX_FAMILY_6351,
6143         .name = "Marvell 88E6351",
6144         .num_databases = 4096,
6145         .num_macs = 8192,
6146         .num_ports = 7,
6147         .num_internal_phys = 5,
6148         .max_vid = 4095,
6149         .max_sid = 63,
6150         .port_base_addr = 0x10,
6151         .phy_base_addr = 0x0,
6152         .global1_addr = 0x1b,
6153         .global2_addr = 0x1c,
6154         .age_time_coeff = 15000,
6155         .g1_irqs = 9,
6156         .g2_irqs = 10,
6157         .atu_move_port_mask = 0xf,
6158         .pvt = true,
6159         .multi_chip = true,
6160         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6161         .ops = &mv88e6351_ops,
6162     },
6163 
6164     [MV88E6352] = {
6165         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6352,
6166         .family = MV88E6XXX_FAMILY_6352,
6167         .name = "Marvell 88E6352",
6168         .num_databases = 4096,
6169         .num_macs = 8192,
6170         .num_ports = 7,
6171         .num_internal_phys = 5,
6172         .num_gpio = 15,
6173         .max_vid = 4095,
6174         .max_sid = 63,
6175         .port_base_addr = 0x10,
6176         .phy_base_addr = 0x0,
6177         .global1_addr = 0x1b,
6178         .global2_addr = 0x1c,
6179         .age_time_coeff = 15000,
6180         .g1_irqs = 9,
6181         .g2_irqs = 10,
6182         .atu_move_port_mask = 0xf,
6183         .pvt = true,
6184         .multi_chip = true,
6185         .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6186         .ptp_support = true,
6187         .ops = &mv88e6352_ops,
6188     },
6189     [MV88E6390] = {
6190         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
6191         .family = MV88E6XXX_FAMILY_6390,
6192         .name = "Marvell 88E6390",
6193         .num_databases = 4096,
6194         .num_macs = 16384,
6195         .num_ports = 11,    /* 10 + Z80 */
6196         .num_internal_phys = 9,
6197         .num_gpio = 16,
6198         .max_vid = 8191,
6199         .max_sid = 63,
6200         .port_base_addr = 0x0,
6201         .phy_base_addr = 0x0,
6202         .global1_addr = 0x1b,
6203         .global2_addr = 0x1c,
6204         .age_time_coeff = 3750,
6205         .g1_irqs = 9,
6206         .g2_irqs = 14,
6207         .atu_move_port_mask = 0x1f,
6208         .pvt = true,
6209         .multi_chip = true,
6210         .edsa_support = MV88E6XXX_EDSA_UNDOCUMENTED,
6211         .ptp_support = true,
6212         .ops = &mv88e6390_ops,
6213     },
6214     [MV88E6390X] = {
6215         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390X,
6216         .family = MV88E6XXX_FAMILY_6390,
6217         .name = "Marvell 88E6390X",
6218         .num_databases = 4096,
6219         .num_macs = 16384,
6220         .num_ports = 11,    /* 10 + Z80 */
6221         .num_internal_phys = 9,
6222         .num_gpio = 16,
6223         .max_vid = 8191,
6224         .max_sid = 63,
6225         .port_base_addr = 0x0,
6226         .phy_base_addr = 0x0,
6227         .global1_addr = 0x1b,
6228         .global2_addr = 0x1c,
6229         .age_time_coeff = 3750,
6230         .g1_irqs = 9,
6231         .g2_irqs = 14,
6232         .atu_move_port_mask = 0x1f,
6233         .pvt = true,
6234         .multi_chip = true,
6235         .edsa_support = MV88E6XXX_EDSA_UNDOCUMENTED,
6236         .ptp_support = true,
6237         .ops = &mv88e6390x_ops,
6238     },
6239 
6240     [MV88E6393X] = {
6241         .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6393X,
6242         .family = MV88E6XXX_FAMILY_6393,
6243         .name = "Marvell 88E6393X",
6244         .num_databases = 4096,
6245         .num_ports = 11,    /* 10 + Z80 */
6246         .num_internal_phys = 9,
6247         .max_vid = 8191,
6248         .max_sid = 63,
6249         .port_base_addr = 0x0,
6250         .phy_base_addr = 0x0,
6251         .global1_addr = 0x1b,
6252         .global2_addr = 0x1c,
6253         .age_time_coeff = 3750,
6254         .g1_irqs = 10,
6255         .g2_irqs = 14,
6256         .atu_move_port_mask = 0x1f,
6257         .pvt = true,
6258         .multi_chip = true,
6259         .ptp_support = true,
6260         .ops = &mv88e6393x_ops,
6261     },
6262 };
6263 
6264 static const struct mv88e6xxx_info *mv88e6xxx_lookup_info(unsigned int prod_num)
6265 {
6266     int i;
6267 
6268     for (i = 0; i < ARRAY_SIZE(mv88e6xxx_table); ++i)
6269         if (mv88e6xxx_table[i].prod_num == prod_num)
6270             return &mv88e6xxx_table[i];
6271 
6272     return NULL;
6273 }
6274 
6275 static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip)
6276 {
6277     const struct mv88e6xxx_info *info;
6278     unsigned int prod_num, rev;
6279     u16 id;
6280     int err;
6281 
6282     mv88e6xxx_reg_lock(chip);
6283     err = mv88e6xxx_port_read(chip, 0, MV88E6XXX_PORT_SWITCH_ID, &id);
6284     mv88e6xxx_reg_unlock(chip);
6285     if (err)
6286         return err;
6287 
6288     prod_num = id & MV88E6XXX_PORT_SWITCH_ID_PROD_MASK;
6289     rev = id & MV88E6XXX_PORT_SWITCH_ID_REV_MASK;
6290 
6291     info = mv88e6xxx_lookup_info(prod_num);
6292     if (!info)
6293         return -ENODEV;
6294 
6295     /* Update the compatible info with the probed one */
6296     chip->info = info;
6297 
6298     dev_info(chip->dev, "switch 0x%x detected: %s, revision %u\n",
6299          chip->info->prod_num, chip->info->name, rev);
6300 
6301     return 0;
6302 }
6303 
6304 static int mv88e6xxx_single_chip_detect(struct mv88e6xxx_chip *chip,
6305                     struct mdio_device *mdiodev)
6306 {
6307     int err;
6308 
6309     /* dual_chip takes precedence over single/multi-chip modes */
6310     if (chip->info->dual_chip)
6311         return -EINVAL;
6312 
6313     /* If the mdio addr is 16 indicating the first port address of a switch
6314      * (e.g. mv88e6*41) in single chip addressing mode the device may be
6315      * configured in single chip addressing mode. Setup the smi access as
6316      * single chip addressing mode and attempt to detect the model of the
6317      * switch, if this fails the device is not configured in single chip
6318      * addressing mode.
6319      */
6320     if (mdiodev->addr != 16)
6321         return -EINVAL;
6322 
6323     err = mv88e6xxx_smi_init(chip, mdiodev->bus, 0);
6324     if (err)
6325         return err;
6326 
6327     return mv88e6xxx_detect(chip);
6328 }
6329 
6330 static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev)
6331 {
6332     struct mv88e6xxx_chip *chip;
6333 
6334     chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
6335     if (!chip)
6336         return NULL;
6337 
6338     chip->dev = dev;
6339 
6340     mutex_init(&chip->reg_lock);
6341     INIT_LIST_HEAD(&chip->mdios);
6342     idr_init(&chip->policies);
6343     INIT_LIST_HEAD(&chip->msts);
6344 
6345     return chip;
6346 }
6347 
6348 static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds,
6349                             int port,
6350                             enum dsa_tag_protocol m)
6351 {
6352     struct mv88e6xxx_chip *chip = ds->priv;
6353 
6354     return chip->tag_protocol;
6355 }
6356 
6357 static int mv88e6xxx_change_tag_protocol(struct dsa_switch *ds,
6358                      enum dsa_tag_protocol proto)
6359 {
6360     struct mv88e6xxx_chip *chip = ds->priv;
6361     enum dsa_tag_protocol old_protocol;
6362     struct dsa_port *cpu_dp;
6363     int err;
6364 
6365     switch (proto) {
6366     case DSA_TAG_PROTO_EDSA:
6367         switch (chip->info->edsa_support) {
6368         case MV88E6XXX_EDSA_UNSUPPORTED:
6369             return -EPROTONOSUPPORT;
6370         case MV88E6XXX_EDSA_UNDOCUMENTED:
6371             dev_warn(chip->dev, "Relying on undocumented EDSA tagging behavior\n");
6372             fallthrough;
6373         case MV88E6XXX_EDSA_SUPPORTED:
6374             break;
6375         }
6376         break;
6377     case DSA_TAG_PROTO_DSA:
6378         break;
6379     default:
6380         return -EPROTONOSUPPORT;
6381     }
6382 
6383     old_protocol = chip->tag_protocol;
6384     chip->tag_protocol = proto;
6385 
6386     mv88e6xxx_reg_lock(chip);
6387     dsa_switch_for_each_cpu_port(cpu_dp, ds) {
6388         err = mv88e6xxx_setup_port_mode(chip, cpu_dp->index);
6389         if (err) {
6390             mv88e6xxx_reg_unlock(chip);
6391             goto unwind;
6392         }
6393     }
6394     mv88e6xxx_reg_unlock(chip);
6395 
6396     return 0;
6397 
6398 unwind:
6399     chip->tag_protocol = old_protocol;
6400 
6401     mv88e6xxx_reg_lock(chip);
6402     dsa_switch_for_each_cpu_port_continue_reverse(cpu_dp, ds)
6403         mv88e6xxx_setup_port_mode(chip, cpu_dp->index);
6404     mv88e6xxx_reg_unlock(chip);
6405 
6406     return err;
6407 }
6408 
6409 static int mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port,
6410                   const struct switchdev_obj_port_mdb *mdb,
6411                   struct dsa_db db)
6412 {
6413     struct mv88e6xxx_chip *chip = ds->priv;
6414     int err;
6415 
6416     mv88e6xxx_reg_lock(chip);
6417     err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
6418                        MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC);
6419     mv88e6xxx_reg_unlock(chip);
6420 
6421     return err;
6422 }
6423 
6424 static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port,
6425                   const struct switchdev_obj_port_mdb *mdb,
6426                   struct dsa_db db)
6427 {
6428     struct mv88e6xxx_chip *chip = ds->priv;
6429     int err;
6430 
6431     mv88e6xxx_reg_lock(chip);
6432     err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid, 0);
6433     mv88e6xxx_reg_unlock(chip);
6434 
6435     return err;
6436 }
6437 
6438 static int mv88e6xxx_port_mirror_add(struct dsa_switch *ds, int port,
6439                      struct dsa_mall_mirror_tc_entry *mirror,
6440                      bool ingress,
6441                      struct netlink_ext_ack *extack)
6442 {
6443     enum mv88e6xxx_egress_direction direction = ingress ?
6444                         MV88E6XXX_EGRESS_DIR_INGRESS :
6445                         MV88E6XXX_EGRESS_DIR_EGRESS;
6446     struct mv88e6xxx_chip *chip = ds->priv;
6447     bool other_mirrors = false;
6448     int i;
6449     int err;
6450 
6451     mutex_lock(&chip->reg_lock);
6452     if ((ingress ? chip->ingress_dest_port : chip->egress_dest_port) !=
6453         mirror->to_local_port) {
6454         for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
6455             other_mirrors |= ingress ?
6456                      chip->ports[i].mirror_ingress :
6457                      chip->ports[i].mirror_egress;
6458 
6459         /* Can't change egress port when other mirror is active */
6460         if (other_mirrors) {
6461             err = -EBUSY;
6462             goto out;
6463         }
6464 
6465         err = mv88e6xxx_set_egress_port(chip, direction,
6466                         mirror->to_local_port);
6467         if (err)
6468             goto out;
6469     }
6470 
6471     err = mv88e6xxx_port_set_mirror(chip, port, direction, true);
6472 out:
6473     mutex_unlock(&chip->reg_lock);
6474 
6475     return err;
6476 }
6477 
6478 static void mv88e6xxx_port_mirror_del(struct dsa_switch *ds, int port,
6479                       struct dsa_mall_mirror_tc_entry *mirror)
6480 {
6481     enum mv88e6xxx_egress_direction direction = mirror->ingress ?
6482                         MV88E6XXX_EGRESS_DIR_INGRESS :
6483                         MV88E6XXX_EGRESS_DIR_EGRESS;
6484     struct mv88e6xxx_chip *chip = ds->priv;
6485     bool other_mirrors = false;
6486     int i;
6487 
6488     mutex_lock(&chip->reg_lock);
6489     if (mv88e6xxx_port_set_mirror(chip, port, direction, false))
6490         dev_err(ds->dev, "p%d: failed to disable mirroring\n", port);
6491 
6492     for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
6493         other_mirrors |= mirror->ingress ?
6494                  chip->ports[i].mirror_ingress :
6495                  chip->ports[i].mirror_egress;
6496 
6497     /* Reset egress port when no other mirror is active */
6498     if (!other_mirrors) {
6499         if (mv88e6xxx_set_egress_port(chip, direction,
6500                           dsa_upstream_port(ds, port)))
6501             dev_err(ds->dev, "failed to set egress port\n");
6502     }
6503 
6504     mutex_unlock(&chip->reg_lock);
6505 }
6506 
6507 static int mv88e6xxx_port_pre_bridge_flags(struct dsa_switch *ds, int port,
6508                        struct switchdev_brport_flags flags,
6509                        struct netlink_ext_ack *extack)
6510 {
6511     struct mv88e6xxx_chip *chip = ds->priv;
6512     const struct mv88e6xxx_ops *ops;
6513 
6514     if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
6515                BR_BCAST_FLOOD | BR_PORT_LOCKED))
6516         return -EINVAL;
6517 
6518     ops = chip->info->ops;
6519 
6520     if ((flags.mask & BR_FLOOD) && !ops->port_set_ucast_flood)
6521         return -EINVAL;
6522 
6523     if ((flags.mask & BR_MCAST_FLOOD) && !ops->port_set_mcast_flood)
6524         return -EINVAL;
6525 
6526     return 0;
6527 }
6528 
6529 static int mv88e6xxx_port_bridge_flags(struct dsa_switch *ds, int port,
6530                        struct switchdev_brport_flags flags,
6531                        struct netlink_ext_ack *extack)
6532 {
6533     struct mv88e6xxx_chip *chip = ds->priv;
6534     int err = -EOPNOTSUPP;
6535 
6536     mv88e6xxx_reg_lock(chip);
6537 
6538     if (flags.mask & BR_LEARNING) {
6539         bool learning = !!(flags.val & BR_LEARNING);
6540         u16 pav = learning ? (1 << port) : 0;
6541 
6542         err = mv88e6xxx_port_set_assoc_vector(chip, port, pav);
6543         if (err)
6544             goto out;
6545     }
6546 
6547     if (flags.mask & BR_FLOOD) {
6548         bool unicast = !!(flags.val & BR_FLOOD);
6549 
6550         err = chip->info->ops->port_set_ucast_flood(chip, port,
6551                                 unicast);
6552         if (err)
6553             goto out;
6554     }
6555 
6556     if (flags.mask & BR_MCAST_FLOOD) {
6557         bool multicast = !!(flags.val & BR_MCAST_FLOOD);
6558 
6559         err = chip->info->ops->port_set_mcast_flood(chip, port,
6560                                 multicast);
6561         if (err)
6562             goto out;
6563     }
6564 
6565     if (flags.mask & BR_BCAST_FLOOD) {
6566         bool broadcast = !!(flags.val & BR_BCAST_FLOOD);
6567 
6568         err = mv88e6xxx_port_broadcast_sync(chip, port, broadcast);
6569         if (err)
6570             goto out;
6571     }
6572 
6573     if (flags.mask & BR_PORT_LOCKED) {
6574         bool locked = !!(flags.val & BR_PORT_LOCKED);
6575 
6576         err = mv88e6xxx_port_set_lock(chip, port, locked);
6577         if (err)
6578             goto out;
6579     }
6580 out:
6581     mv88e6xxx_reg_unlock(chip);
6582 
6583     return err;
6584 }
6585 
6586 static bool mv88e6xxx_lag_can_offload(struct dsa_switch *ds,
6587                       struct dsa_lag lag,
6588                       struct netdev_lag_upper_info *info)
6589 {
6590     struct mv88e6xxx_chip *chip = ds->priv;
6591     struct dsa_port *dp;
6592     int members = 0;
6593 
6594     if (!mv88e6xxx_has_lag(chip))
6595         return false;
6596 
6597     if (!lag.id)
6598         return false;
6599 
6600     dsa_lag_foreach_port(dp, ds->dst, &lag)
6601         /* Includes the port joining the LAG */
6602         members++;
6603 
6604     if (members > 8)
6605         return false;
6606 
6607     /* We could potentially relax this to include active
6608      * backup in the future.
6609      */
6610     if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
6611         return false;
6612 
6613     /* Ideally we would also validate that the hash type matches
6614      * the hardware. Alas, this is always set to unknown on team
6615      * interfaces.
6616      */
6617     return true;
6618 }
6619 
6620 static int mv88e6xxx_lag_sync_map(struct dsa_switch *ds, struct dsa_lag lag)
6621 {
6622     struct mv88e6xxx_chip *chip = ds->priv;
6623     struct dsa_port *dp;
6624     u16 map = 0;
6625     int id;
6626 
6627     /* DSA LAG IDs are one-based, hardware is zero-based */
6628     id = lag.id - 1;
6629 
6630     /* Build the map of all ports to distribute flows destined for
6631      * this LAG. This can be either a local user port, or a DSA
6632      * port if the LAG port is on a remote chip.
6633      */
6634     dsa_lag_foreach_port(dp, ds->dst, &lag)
6635         map |= BIT(dsa_towards_port(ds, dp->ds->index, dp->index));
6636 
6637     return mv88e6xxx_g2_trunk_mapping_write(chip, id, map);
6638 }
6639 
6640 static const u8 mv88e6xxx_lag_mask_table[8][8] = {
6641     /* Row number corresponds to the number of active members in a
6642      * LAG. Each column states which of the eight hash buckets are
6643      * mapped to the column:th port in the LAG.
6644      *
6645      * Example: In a LAG with three active ports, the second port
6646      * ([2][1]) would be selected for traffic mapped to buckets
6647      * 3,4,5 (0x38).
6648      */
6649     { 0xff,    0,    0,    0,    0,    0,    0,    0 },
6650     { 0x0f, 0xf0,    0,    0,    0,    0,    0,    0 },
6651     { 0x07, 0x38, 0xc0,    0,    0,    0,    0,    0 },
6652     { 0x03, 0x0c, 0x30, 0xc0,    0,    0,    0,    0 },
6653     { 0x03, 0x0c, 0x30, 0x40, 0x80,    0,    0,    0 },
6654     { 0x03, 0x0c, 0x10, 0x20, 0x40, 0x80,    0,    0 },
6655     { 0x03, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,    0 },
6656     { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 },
6657 };
6658 
6659 static void mv88e6xxx_lag_set_port_mask(u16 *mask, int port,
6660                     int num_tx, int nth)
6661 {
6662     u8 active = 0;
6663     int i;
6664 
6665     num_tx = num_tx <= 8 ? num_tx : 8;
6666     if (nth < num_tx)
6667         active = mv88e6xxx_lag_mask_table[num_tx - 1][nth];
6668 
6669     for (i = 0; i < 8; i++) {
6670         if (BIT(i) & active)
6671             mask[i] |= BIT(port);
6672     }
6673 }
6674 
6675 static int mv88e6xxx_lag_sync_masks(struct dsa_switch *ds)
6676 {
6677     struct mv88e6xxx_chip *chip = ds->priv;
6678     unsigned int id, num_tx;
6679     struct dsa_port *dp;
6680     struct dsa_lag *lag;
6681     int i, err, nth;
6682     u16 mask[8];
6683     u16 ivec;
6684 
6685     /* Assume no port is a member of any LAG. */
6686     ivec = BIT(mv88e6xxx_num_ports(chip)) - 1;
6687 
6688     /* Disable all masks for ports that _are_ members of a LAG. */
6689     dsa_switch_for_each_port(dp, ds) {
6690         if (!dp->lag)
6691             continue;
6692 
6693         ivec &= ~BIT(dp->index);
6694     }
6695 
6696     for (i = 0; i < 8; i++)
6697         mask[i] = ivec;
6698 
6699     /* Enable the correct subset of masks for all LAG ports that
6700      * are in the Tx set.
6701      */
6702     dsa_lags_foreach_id(id, ds->dst) {
6703         lag = dsa_lag_by_id(ds->dst, id);
6704         if (!lag)
6705             continue;
6706 
6707         num_tx = 0;
6708         dsa_lag_foreach_port(dp, ds->dst, lag) {
6709             if (dp->lag_tx_enabled)
6710                 num_tx++;
6711         }
6712 
6713         if (!num_tx)
6714             continue;
6715 
6716         nth = 0;
6717         dsa_lag_foreach_port(dp, ds->dst, lag) {
6718             if (!dp->lag_tx_enabled)
6719                 continue;
6720 
6721             if (dp->ds == ds)
6722                 mv88e6xxx_lag_set_port_mask(mask, dp->index,
6723                                 num_tx, nth);
6724 
6725             nth++;
6726         }
6727     }
6728 
6729     for (i = 0; i < 8; i++) {
6730         err = mv88e6xxx_g2_trunk_mask_write(chip, i, true, mask[i]);
6731         if (err)
6732             return err;
6733     }
6734 
6735     return 0;
6736 }
6737 
6738 static int mv88e6xxx_lag_sync_masks_map(struct dsa_switch *ds,
6739                     struct dsa_lag lag)
6740 {
6741     int err;
6742 
6743     err = mv88e6xxx_lag_sync_masks(ds);
6744 
6745     if (!err)
6746         err = mv88e6xxx_lag_sync_map(ds, lag);
6747 
6748     return err;
6749 }
6750 
6751 static int mv88e6xxx_port_lag_change(struct dsa_switch *ds, int port)
6752 {
6753     struct mv88e6xxx_chip *chip = ds->priv;
6754     int err;
6755 
6756     mv88e6xxx_reg_lock(chip);
6757     err = mv88e6xxx_lag_sync_masks(ds);
6758     mv88e6xxx_reg_unlock(chip);
6759     return err;
6760 }
6761 
6762 static int mv88e6xxx_port_lag_join(struct dsa_switch *ds, int port,
6763                    struct dsa_lag lag,
6764                    struct netdev_lag_upper_info *info)
6765 {
6766     struct mv88e6xxx_chip *chip = ds->priv;
6767     int err, id;
6768 
6769     if (!mv88e6xxx_lag_can_offload(ds, lag, info))
6770         return -EOPNOTSUPP;
6771 
6772     /* DSA LAG IDs are one-based */
6773     id = lag.id - 1;
6774 
6775     mv88e6xxx_reg_lock(chip);
6776 
6777     err = mv88e6xxx_port_set_trunk(chip, port, true, id);
6778     if (err)
6779         goto err_unlock;
6780 
6781     err = mv88e6xxx_lag_sync_masks_map(ds, lag);
6782     if (err)
6783         goto err_clear_trunk;
6784 
6785     mv88e6xxx_reg_unlock(chip);
6786     return 0;
6787 
6788 err_clear_trunk:
6789     mv88e6xxx_port_set_trunk(chip, port, false, 0);
6790 err_unlock:
6791     mv88e6xxx_reg_unlock(chip);
6792     return err;
6793 }
6794 
6795 static int mv88e6xxx_port_lag_leave(struct dsa_switch *ds, int port,
6796                     struct dsa_lag lag)
6797 {
6798     struct mv88e6xxx_chip *chip = ds->priv;
6799     int err_sync, err_trunk;
6800 
6801     mv88e6xxx_reg_lock(chip);
6802     err_sync = mv88e6xxx_lag_sync_masks_map(ds, lag);
6803     err_trunk = mv88e6xxx_port_set_trunk(chip, port, false, 0);
6804     mv88e6xxx_reg_unlock(chip);
6805     return err_sync ? : err_trunk;
6806 }
6807 
6808 static int mv88e6xxx_crosschip_lag_change(struct dsa_switch *ds, int sw_index,
6809                       int port)
6810 {
6811     struct mv88e6xxx_chip *chip = ds->priv;
6812     int err;
6813 
6814     mv88e6xxx_reg_lock(chip);
6815     err = mv88e6xxx_lag_sync_masks(ds);
6816     mv88e6xxx_reg_unlock(chip);
6817     return err;
6818 }
6819 
6820 static int mv88e6xxx_crosschip_lag_join(struct dsa_switch *ds, int sw_index,
6821                     int port, struct dsa_lag lag,
6822                     struct netdev_lag_upper_info *info)
6823 {
6824     struct mv88e6xxx_chip *chip = ds->priv;
6825     int err;
6826 
6827     if (!mv88e6xxx_lag_can_offload(ds, lag, info))
6828         return -EOPNOTSUPP;
6829 
6830     mv88e6xxx_reg_lock(chip);
6831 
6832     err = mv88e6xxx_lag_sync_masks_map(ds, lag);
6833     if (err)
6834         goto unlock;
6835 
6836     err = mv88e6xxx_pvt_map(chip, sw_index, port);
6837 
6838 unlock:
6839     mv88e6xxx_reg_unlock(chip);
6840     return err;
6841 }
6842 
6843 static int mv88e6xxx_crosschip_lag_leave(struct dsa_switch *ds, int sw_index,
6844                      int port, struct dsa_lag lag)
6845 {
6846     struct mv88e6xxx_chip *chip = ds->priv;
6847     int err_sync, err_pvt;
6848 
6849     mv88e6xxx_reg_lock(chip);
6850     err_sync = mv88e6xxx_lag_sync_masks_map(ds, lag);
6851     err_pvt = mv88e6xxx_pvt_map(chip, sw_index, port);
6852     mv88e6xxx_reg_unlock(chip);
6853     return err_sync ? : err_pvt;
6854 }
6855 
6856 static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
6857     .get_tag_protocol   = mv88e6xxx_get_tag_protocol,
6858     .change_tag_protocol    = mv88e6xxx_change_tag_protocol,
6859     .setup          = mv88e6xxx_setup,
6860     .teardown       = mv88e6xxx_teardown,
6861     .port_setup     = mv88e6xxx_port_setup,
6862     .port_teardown      = mv88e6xxx_port_teardown,
6863     .phylink_get_caps   = mv88e6xxx_get_caps,
6864     .phylink_mac_link_state = mv88e6xxx_serdes_pcs_get_state,
6865     .phylink_mac_config = mv88e6xxx_mac_config,
6866     .phylink_mac_an_restart = mv88e6xxx_serdes_pcs_an_restart,
6867     .phylink_mac_link_down  = mv88e6xxx_mac_link_down,
6868     .phylink_mac_link_up    = mv88e6xxx_mac_link_up,
6869     .get_strings        = mv88e6xxx_get_strings,
6870     .get_ethtool_stats  = mv88e6xxx_get_ethtool_stats,
6871     .get_sset_count     = mv88e6xxx_get_sset_count,
6872     .port_enable        = mv88e6xxx_port_enable,
6873     .port_disable       = mv88e6xxx_port_disable,
6874     .port_max_mtu       = mv88e6xxx_get_max_mtu,
6875     .port_change_mtu    = mv88e6xxx_change_mtu,
6876     .get_mac_eee        = mv88e6xxx_get_mac_eee,
6877     .set_mac_eee        = mv88e6xxx_set_mac_eee,
6878     .get_eeprom_len     = mv88e6xxx_get_eeprom_len,
6879     .get_eeprom     = mv88e6xxx_get_eeprom,
6880     .set_eeprom     = mv88e6xxx_set_eeprom,
6881     .get_regs_len       = mv88e6xxx_get_regs_len,
6882     .get_regs       = mv88e6xxx_get_regs,
6883     .get_rxnfc      = mv88e6xxx_get_rxnfc,
6884     .set_rxnfc      = mv88e6xxx_set_rxnfc,
6885     .set_ageing_time    = mv88e6xxx_set_ageing_time,
6886     .port_bridge_join   = mv88e6xxx_port_bridge_join,
6887     .port_bridge_leave  = mv88e6xxx_port_bridge_leave,
6888     .port_pre_bridge_flags  = mv88e6xxx_port_pre_bridge_flags,
6889     .port_bridge_flags  = mv88e6xxx_port_bridge_flags,
6890     .port_stp_state_set = mv88e6xxx_port_stp_state_set,
6891     .port_mst_state_set = mv88e6xxx_port_mst_state_set,
6892     .port_fast_age      = mv88e6xxx_port_fast_age,
6893     .port_vlan_fast_age = mv88e6xxx_port_vlan_fast_age,
6894     .port_vlan_filtering    = mv88e6xxx_port_vlan_filtering,
6895     .port_vlan_add      = mv88e6xxx_port_vlan_add,
6896     .port_vlan_del      = mv88e6xxx_port_vlan_del,
6897     .vlan_msti_set      = mv88e6xxx_vlan_msti_set,
6898     .port_fdb_add       = mv88e6xxx_port_fdb_add,
6899     .port_fdb_del       = mv88e6xxx_port_fdb_del,
6900     .port_fdb_dump      = mv88e6xxx_port_fdb_dump,
6901     .port_mdb_add       = mv88e6xxx_port_mdb_add,
6902     .port_mdb_del       = mv88e6xxx_port_mdb_del,
6903     .port_mirror_add    = mv88e6xxx_port_mirror_add,
6904     .port_mirror_del    = mv88e6xxx_port_mirror_del,
6905     .crosschip_bridge_join  = mv88e6xxx_crosschip_bridge_join,
6906     .crosschip_bridge_leave = mv88e6xxx_crosschip_bridge_leave,
6907     .port_hwtstamp_set  = mv88e6xxx_port_hwtstamp_set,
6908     .port_hwtstamp_get  = mv88e6xxx_port_hwtstamp_get,
6909     .port_txtstamp      = mv88e6xxx_port_txtstamp,
6910     .port_rxtstamp      = mv88e6xxx_port_rxtstamp,
6911     .get_ts_info        = mv88e6xxx_get_ts_info,
6912     .devlink_param_get  = mv88e6xxx_devlink_param_get,
6913     .devlink_param_set  = mv88e6xxx_devlink_param_set,
6914     .devlink_info_get   = mv88e6xxx_devlink_info_get,
6915     .port_lag_change    = mv88e6xxx_port_lag_change,
6916     .port_lag_join      = mv88e6xxx_port_lag_join,
6917     .port_lag_leave     = mv88e6xxx_port_lag_leave,
6918     .crosschip_lag_change   = mv88e6xxx_crosschip_lag_change,
6919     .crosschip_lag_join = mv88e6xxx_crosschip_lag_join,
6920     .crosschip_lag_leave    = mv88e6xxx_crosschip_lag_leave,
6921 };
6922 
6923 static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
6924 {
6925     struct device *dev = chip->dev;
6926     struct dsa_switch *ds;
6927 
6928     ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
6929     if (!ds)
6930         return -ENOMEM;
6931 
6932     ds->dev = dev;
6933     ds->num_ports = mv88e6xxx_num_ports(chip);
6934     ds->priv = chip;
6935     ds->dev = dev;
6936     ds->ops = &mv88e6xxx_switch_ops;
6937     ds->ageing_time_min = chip->info->age_time_coeff;
6938     ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
6939 
6940     /* Some chips support up to 32, but that requires enabling the
6941      * 5-bit port mode, which we do not support. 640k^W16 ought to
6942      * be enough for anyone.
6943      */
6944     ds->num_lag_ids = mv88e6xxx_has_lag(chip) ? 16 : 0;
6945 
6946     dev_set_drvdata(dev, ds);
6947 
6948     return dsa_register_switch(ds);
6949 }
6950 
6951 static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip)
6952 {
6953     dsa_unregister_switch(chip->ds);
6954 }
6955 
6956 static const void *pdata_device_get_match_data(struct device *dev)
6957 {
6958     const struct of_device_id *matches = dev->driver->of_match_table;
6959     const struct dsa_mv88e6xxx_pdata *pdata = dev->platform_data;
6960 
6961     for (; matches->name[0] || matches->type[0] || matches->compatible[0];
6962          matches++) {
6963         if (!strcmp(pdata->compatible, matches->compatible))
6964             return matches->data;
6965     }
6966     return NULL;
6967 }
6968 
6969 /* There is no suspend to RAM support at DSA level yet, the switch configuration
6970  * would be lost after a power cycle so prevent it to be suspended.
6971  */
6972 static int __maybe_unused mv88e6xxx_suspend(struct device *dev)
6973 {
6974     return -EOPNOTSUPP;
6975 }
6976 
6977 static int __maybe_unused mv88e6xxx_resume(struct device *dev)
6978 {
6979     return 0;
6980 }
6981 
6982 static SIMPLE_DEV_PM_OPS(mv88e6xxx_pm_ops, mv88e6xxx_suspend, mv88e6xxx_resume);
6983 
6984 static int mv88e6xxx_probe(struct mdio_device *mdiodev)
6985 {
6986     struct dsa_mv88e6xxx_pdata *pdata = mdiodev->dev.platform_data;
6987     const struct mv88e6xxx_info *compat_info = NULL;
6988     struct device *dev = &mdiodev->dev;
6989     struct device_node *np = dev->of_node;
6990     struct mv88e6xxx_chip *chip;
6991     int port;
6992     int err;
6993 
6994     if (!np && !pdata)
6995         return -EINVAL;
6996 
6997     if (np)
6998         compat_info = of_device_get_match_data(dev);
6999 
7000     if (pdata) {
7001         compat_info = pdata_device_get_match_data(dev);
7002 
7003         if (!pdata->netdev)
7004             return -EINVAL;
7005 
7006         for (port = 0; port < DSA_MAX_PORTS; port++) {
7007             if (!(pdata->enabled_ports & (1 << port)))
7008                 continue;
7009             if (strcmp(pdata->cd.port_names[port], "cpu"))
7010                 continue;
7011             pdata->cd.netdev[port] = &pdata->netdev->dev;
7012             break;
7013         }
7014     }
7015 
7016     if (!compat_info)
7017         return -EINVAL;
7018 
7019     chip = mv88e6xxx_alloc_chip(dev);
7020     if (!chip) {
7021         err = -ENOMEM;
7022         goto out;
7023     }
7024 
7025     chip->info = compat_info;
7026 
7027     chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
7028     if (IS_ERR(chip->reset)) {
7029         err = PTR_ERR(chip->reset);
7030         goto out;
7031     }
7032     if (chip->reset)
7033         usleep_range(1000, 2000);
7034 
7035     /* Detect if the device is configured in single chip addressing mode,
7036      * otherwise continue with address specific smi init/detection.
7037      */
7038     err = mv88e6xxx_single_chip_detect(chip, mdiodev);
7039     if (err) {
7040         err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
7041         if (err)
7042             goto out;
7043 
7044         err = mv88e6xxx_detect(chip);
7045         if (err)
7046             goto out;
7047     }
7048 
7049     if (chip->info->edsa_support == MV88E6XXX_EDSA_SUPPORTED)
7050         chip->tag_protocol = DSA_TAG_PROTO_EDSA;
7051     else
7052         chip->tag_protocol = DSA_TAG_PROTO_DSA;
7053 
7054     mv88e6xxx_phy_init(chip);
7055 
7056     if (chip->info->ops->get_eeprom) {
7057         if (np)
7058             of_property_read_u32(np, "eeprom-length",
7059                          &chip->eeprom_len);
7060         else
7061             chip->eeprom_len = pdata->eeprom_len;
7062     }
7063 
7064     mv88e6xxx_reg_lock(chip);
7065     err = mv88e6xxx_switch_reset(chip);
7066     mv88e6xxx_reg_unlock(chip);
7067     if (err)
7068         goto out;
7069 
7070     if (np) {
7071         chip->irq = of_irq_get(np, 0);
7072         if (chip->irq == -EPROBE_DEFER) {
7073             err = chip->irq;
7074             goto out;
7075         }
7076     }
7077 
7078     if (pdata)
7079         chip->irq = pdata->irq;
7080 
7081     /* Has to be performed before the MDIO bus is created, because
7082      * the PHYs will link their interrupts to these interrupt
7083      * controllers
7084      */
7085     mv88e6xxx_reg_lock(chip);
7086     if (chip->irq > 0)
7087         err = mv88e6xxx_g1_irq_setup(chip);
7088     else
7089         err = mv88e6xxx_irq_poll_setup(chip);
7090     mv88e6xxx_reg_unlock(chip);
7091 
7092     if (err)
7093         goto out;
7094 
7095     if (chip->info->g2_irqs > 0) {
7096         err = mv88e6xxx_g2_irq_setup(chip);
7097         if (err)
7098             goto out_g1_irq;
7099     }
7100 
7101     err = mv88e6xxx_g1_atu_prob_irq_setup(chip);
7102     if (err)
7103         goto out_g2_irq;
7104 
7105     err = mv88e6xxx_g1_vtu_prob_irq_setup(chip);
7106     if (err)
7107         goto out_g1_atu_prob_irq;
7108 
7109     err = mv88e6xxx_mdios_register(chip, np);
7110     if (err)
7111         goto out_g1_vtu_prob_irq;
7112 
7113     err = mv88e6xxx_register_switch(chip);
7114     if (err)
7115         goto out_mdio;
7116 
7117     return 0;
7118 
7119 out_mdio:
7120     mv88e6xxx_mdios_unregister(chip);
7121 out_g1_vtu_prob_irq:
7122     mv88e6xxx_g1_vtu_prob_irq_free(chip);
7123 out_g1_atu_prob_irq:
7124     mv88e6xxx_g1_atu_prob_irq_free(chip);
7125 out_g2_irq:
7126     if (chip->info->g2_irqs > 0)
7127         mv88e6xxx_g2_irq_free(chip);
7128 out_g1_irq:
7129     if (chip->irq > 0)
7130         mv88e6xxx_g1_irq_free(chip);
7131     else
7132         mv88e6xxx_irq_poll_free(chip);
7133 out:
7134     if (pdata)
7135         dev_put(pdata->netdev);
7136 
7137     return err;
7138 }
7139 
7140 static void mv88e6xxx_remove(struct mdio_device *mdiodev)
7141 {
7142     struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
7143     struct mv88e6xxx_chip *chip;
7144 
7145     if (!ds)
7146         return;
7147 
7148     chip = ds->priv;
7149 
7150     if (chip->info->ptp_support) {
7151         mv88e6xxx_hwtstamp_free(chip);
7152         mv88e6xxx_ptp_free(chip);
7153     }
7154 
7155     mv88e6xxx_phy_destroy(chip);
7156     mv88e6xxx_unregister_switch(chip);
7157     mv88e6xxx_mdios_unregister(chip);
7158 
7159     mv88e6xxx_g1_vtu_prob_irq_free(chip);
7160     mv88e6xxx_g1_atu_prob_irq_free(chip);
7161 
7162     if (chip->info->g2_irqs > 0)
7163         mv88e6xxx_g2_irq_free(chip);
7164 
7165     if (chip->irq > 0)
7166         mv88e6xxx_g1_irq_free(chip);
7167     else
7168         mv88e6xxx_irq_poll_free(chip);
7169 
7170     dev_set_drvdata(&mdiodev->dev, NULL);
7171 }
7172 
7173 static void mv88e6xxx_shutdown(struct mdio_device *mdiodev)
7174 {
7175     struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
7176 
7177     if (!ds)
7178         return;
7179 
7180     dsa_switch_shutdown(ds);
7181 
7182     dev_set_drvdata(&mdiodev->dev, NULL);
7183 }
7184 
7185 static const struct of_device_id mv88e6xxx_of_match[] = {
7186     {
7187         .compatible = "marvell,mv88e6085",
7188         .data = &mv88e6xxx_table[MV88E6085],
7189     },
7190     {
7191         .compatible = "marvell,mv88e6190",
7192         .data = &mv88e6xxx_table[MV88E6190],
7193     },
7194     {
7195         .compatible = "marvell,mv88e6250",
7196         .data = &mv88e6xxx_table[MV88E6250],
7197     },
7198     { /* sentinel */ },
7199 };
7200 
7201 MODULE_DEVICE_TABLE(of, mv88e6xxx_of_match);
7202 
7203 static struct mdio_driver mv88e6xxx_driver = {
7204     .probe  = mv88e6xxx_probe,
7205     .remove = mv88e6xxx_remove,
7206     .shutdown = mv88e6xxx_shutdown,
7207     .mdiodrv.driver = {
7208         .name = "mv88e6085",
7209         .of_match_table = mv88e6xxx_of_match,
7210         .pm = &mv88e6xxx_pm_ops,
7211     },
7212 };
7213 
7214 mdio_module_driver(mv88e6xxx_driver);
7215 
7216 MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
7217 MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
7218 MODULE_LICENSE("GPL");