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