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