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