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