0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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
0095
0096
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, ®);
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, ®);
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, ®);
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
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
0277
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
0315 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®);
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
0347
0348
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
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
0479
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, ®);
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
0623
0624
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
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, ®);
0654 if (err)
0655 return err;
0656
0657
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
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
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
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
0717 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
0718
0719
0720 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
0721 MAC_1000FD;
0722
0723
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
0739 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
0740
0741
0742 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
0743 MAC_1000FD;
0744
0745
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
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778 if (port >= 2 && port <= 7)
0779 __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
0780
0781
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
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
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
0813
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
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
0848
0849
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
0866
0867
0868
0869 if (err > 0)
0870 err = 0;
0871 }
0872
0873
0874
0875
0876
0877
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
0905
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
0935
0936
0937
0938 if (!mv88e6xxx_port_ppu_updates(chip, port) ||
0939 mode == MLO_AN_FIXED) {
0940
0941
0942
0943
0944
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, ®);
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, ®);
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, ®);
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
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
1375 return 0;
1376 }
1377
1378
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
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
1392
1393
1394
1395 found = true;
1396 break;
1397 }
1398 }
1399
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
1416 if (!found)
1417 return 0;
1418
1419
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
1426
1427
1428 if (!dsa_port_bridge_dev_get(dp))
1429 return BIT(dsa_switch_upstream_port(ds));
1430
1431
1432
1433
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
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
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
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
1563
1564
1565
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
1586
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
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
1627
1628
1629
1630
1631
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
1650
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
1672
1673
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
1776
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
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
1818
1819
1820
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
1912
1913
1914
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
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;
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
2084
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
2103
2104
2105
2106
2107
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
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
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
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;
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
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
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
2390
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
2440 err = mv88e6xxx_port_broadcast_sync_vlan(chip, &vid0, &ctx);
2441 if (err)
2442 return err;
2443
2444
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
2527
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
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
2576
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
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
2619
2620
2621
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
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
2843
2844
2845 err = mv88e6xxx_port_vlan_map(chip, dp->index);
2846 if (err)
2847 return err;
2848 } else {
2849
2850
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
2864
2865
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
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
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
3013
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
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
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
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
3175 if (!irq)
3176 return 0;
3177
3178 err = mv88e6xxx_serdes_irq_disable(chip, port, lane);
3179
3180
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
3292
3293
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
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
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
3363
3364
3365
3366
3367
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
3378
3379
3380
3381
3382
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
3394
3395
3396
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
3406
3407
3408
3409
3410
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
3419
3420
3421
3422
3423
3424
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
3439
3440
3441
3442
3443
3444
3445
3446
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
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
3517
3518
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
3529
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
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
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
3638
3639
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
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
3683
3684
3685
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
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
3715
3716
3717 err = mv88e6xxx_stu_setup(chip);
3718 if (err)
3719 goto unlock;
3720
3721
3722 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
3723 if (dsa_is_unused_port(ds, i))
3724 continue;
3725
3726
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
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
3808
3809
3810
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
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
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
3982
3983
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
3992
3993
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
5490
5491
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
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,
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,
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,
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,
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,
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
5951
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,
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,
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,
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,
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
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
6310 if (chip->info->dual_chip)
6311 return -EINVAL;
6312
6313
6314
6315
6316
6317
6318
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
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
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
6602 members++;
6603
6604 if (members > 8)
6605 return false;
6606
6607
6608
6609
6610 if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
6611 return false;
6612
6613
6614
6615
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
6628 id = lag.id - 1;
6629
6630
6631
6632
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
6642
6643
6644
6645
6646
6647
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
6686 ivec = BIT(mv88e6xxx_num_ports(chip)) - 1;
6687
6688
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
6700
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
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
6941
6942
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
6970
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
7036
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
7082
7083
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 { },
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");