FILE
chip.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/dsa/mv88e6xxx/chip.c
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Marvell 88e6xxx Ethernet switch single-chip support 4 * 5 * Copyright (c) 2008 Marvell Semiconductor 6 * 7 * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch> 8 * 9 * Copyright (c) 2016-2017 Savoir-faire Linux Inc. 10 * Vivien Didelot <vivien.didelot@savoirfairelinux.com> 11 */ 12 13#include <linux/bitfield.h> 14#include <linux/delay.h> 15#include <linux/dsa/mv88e6xxx.h> 16#include <linux/etherdevice.h> 17#include <linux/ethtool.h> 18#include <linux/if_bridge.h> 19#include <linux/interrupt.h> 20#include <linux/irq.h> 21#include <linux/irqdomain.h> 22#include <linux/jiffies.h> 23#include <linux/list.h> 24#include <linux/mdio.h> 25#include <linux/module.h> 26#include <linux/of.h> 27#include <linux/of_irq.h> 28#include <linux/of_mdio.h> 29#include <linux/platform_data/mv88e6xxx.h> 30#include <linux/property.h> 31#include <linux/netdevice.h> 32#include <linux/gpio/consumer.h> 33#include <linux/phylink.h> 34#include <net/dsa.h> 35 36#include "chip.h" 37#include "devlink.h" 38#include "global1.h" 39#include "global2.h" 40#include "hwtstamp.h" 41#include "phy.h" 42#include "port.h" 43#include "ptp.h" 44#include "serdes.h" 45#include "smi.h" 46 47static void assert_reg_lock(struct mv88e6xxx_chip *chip) 48{ 49 if (unlikely(!mutex_is_locked(&chip->reg_lock))) { 50 dev_err(chip->dev, "Switch registers lock not held!\n"); 51 dump_stack(); 52 } 53} 54 55int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val) 56{ 57 int err; 58 59 assert_reg_lock(chip); 60 61 err = mv88e6xxx_smi_read(chip, addr, reg, val); 62 if (err) 63 return err; 64 65 dev_dbg(chip->dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n", 66 addr, reg, *val); 67 68 return 0; 69} 70 71int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val) 72{ 73 int err; 74 75 assert_reg_lock(chip); 76 77 err = mv88e6xxx_smi_write(chip, addr, reg, val); 78 if (err) 79 return err; 80 81 dev_dbg(chip->dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n", 82 addr, reg, val); 83 84 return 0; 85} 86 87int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg, 88 u16 mask, u16 val) 89{ 90 const unsigned long timeout = jiffies + msecs_to_jiffies(50); 91 u16 data; 92 int err; 93 int i; 94 95 /* There's no bus specific operation to wait for a mask. Even 96 * if the initial poll takes longer than 50ms, always do at 97 * least one more attempt. 98 */ 99 for (i = 0; time_before(jiffies, timeout) || (i < 2); i++) { 100 err = mv88e6xxx_read(chip, addr, reg, &data); 101 if (err) 102 return err; 103 104 if ((data & mask) == val) 105 return 0; 106 107 if (i < 2) 108 cpu_relax(); 109 else 110 usleep_range(1000, 2000); 111 } 112 113 err = mv88e6xxx_read(chip, addr, reg, &data); 114 if (err) 115 return err; 116 117 if ((data & mask) == val) 118 return 0; 119 120 dev_err(chip->dev, "Timeout while waiting for switch\n"); 121 return -ETIMEDOUT; 122} 123 124int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg, 125 int bit, int val) 126{ 127 return mv88e6xxx_wait_mask(chip, addr, reg, BIT(bit), 128 val ? BIT(bit) : 0x0000); 129} 130 131struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip) 132{ 133 struct mv88e6xxx_mdio_bus *mdio_bus; 134 135 mdio_bus = list_first_entry_or_null(&chip->mdios, 136 struct mv88e6xxx_mdio_bus, list); 137 if (!mdio_bus) 138 return NULL; 139 140 return mdio_bus->bus; 141} 142 143static void mv88e6xxx_g1_irq_mask(struct irq_data *d) 144{ 145 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d); 146 unsigned int n = d->hwirq; 147 148 chip->g1_irq.masked |= (1 << n); 149} 150 151static void mv88e6xxx_g1_irq_unmask(struct irq_data *d) 152{ 153 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d); 154 unsigned int n = d->hwirq; 155 156 chip->g1_irq.masked &= ~(1 << n); 157} 158 159static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct mv88e6xxx_chip *chip) 160{ 161 unsigned int nhandled = 0; 162 unsigned int sub_irq; 163 unsigned int n; 164 u16 reg; 165 u16 ctl1; 166 int err; 167 168 mv88e6xxx_reg_lock(chip); 169 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®); 170 mv88e6xxx_reg_unlock(chip); 171 172 if (err) 173 goto out; 174 175 do { 176 for (n = 0; n < chip->g1_irq.nirqs; ++n) { 177 if (reg & (1 << n)) { 178 sub_irq = irq_find_mapping(chip->g1_irq.domain, 179 n); 180 handle_nested_irq(sub_irq); 181 ++nhandled; 182 } 183 } 184 185 mv88e6xxx_reg_lock(chip); 186 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &ctl1); 187 if (err) 188 goto unlock; 189 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®); 190unlock: 191 mv88e6xxx_reg_unlock(chip); 192 if (err) 193 goto out; 194 ctl1 &= GENMASK(chip->g1_irq.nirqs, 0); 195 } while (reg & ctl1); 196 197out: 198 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE); 199} 200 201static irqreturn_t mv88e6xxx_g1_irq_thread_fn(int irq, void *dev_id) 202{ 203 struct mv88e6xxx_chip *chip = dev_id; 204 205 return mv88e6xxx_g1_irq_thread_work(chip); 206} 207 208static void mv88e6xxx_g1_irq_bus_lock(struct irq_data *d) 209{ 210 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d); 211 212 mv88e6xxx_reg_lock(chip); 213} 214 215static void mv88e6xxx_g1_irq_bus_sync_unlock(struct irq_data *d) 216{ 217 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d); 218 u16 mask = GENMASK(chip->g1_irq.nirqs, 0); 219 u16 reg; 220 int err; 221 222 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, ®); 223 if (err) 224 goto out; 225 226 reg &= ~mask; 227 reg |= (~chip->g1_irq.masked & mask); 228 229 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, reg); 230 if (err) 231 goto out; 232 233out: 234 mv88e6xxx_reg_unlock(chip); 235} 236 237static const struct irq_chip mv88e6xxx_g1_irq_chip = { 238 .name = "mv88e6xxx-g1", 239 .irq_mask = mv88e6xxx_g1_irq_mask, 240 .irq_unmask = mv88e6xxx_g1_irq_unmask, 241 .irq_bus_lock = mv88e6xxx_g1_irq_bus_lock, 242 .irq_bus_sync_unlock = mv88e6xxx_g1_irq_bus_sync_unlock, 243}; 244 245static int mv88e6xxx_g1_irq_domain_map(struct irq_domain *d, 246 unsigned int irq, 247 irq_hw_number_t hwirq) 248{ 249 struct mv88e6xxx_chip *chip = d->host_data; 250 251 irq_set_chip_data(irq, d->host_data); 252 irq_set_chip_and_handler(irq, &chip->g1_irq.chip, handle_level_irq); 253 irq_set_noprobe(irq); 254 255 return 0; 256} 257 258static const struct irq_domain_ops mv88e6xxx_g1_irq_domain_ops = { 259 .map = mv88e6xxx_g1_irq_domain_map, 260 .xlate = irq_domain_xlate_twocell, 261}; 262 263/* To be called with reg_lock held */ 264static void mv88e6xxx_g1_irq_free_common(struct mv88e6xxx_chip *chip) 265{ 266 int irq, virq; 267 u16 mask; 268 269 mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask); 270 mask &= ~GENMASK(chip->g1_irq.nirqs, 0); 271 mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask); 272 273 for (irq = 0; irq < chip->g1_irq.nirqs; irq++) { 274 virq = irq_find_mapping(chip->g1_irq.domain, irq); 275 irq_dispose_mapping(virq); 276 } 277 278 irq_domain_remove(chip->g1_irq.domain); 279} 280 281static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip) 282{ 283 /* 284 * free_irq must be called without reg_lock taken because the irq 285 * handler takes this lock, too. 286 */ 287 free_irq(chip->irq, chip); 288 289 mv88e6xxx_reg_lock(chip); 290 mv88e6xxx_g1_irq_free_common(chip); 291 mv88e6xxx_reg_unlock(chip); 292} 293 294static int mv88e6xxx_g1_irq_setup_common(struct mv88e6xxx_chip *chip) 295{ 296 int err, irq, virq; 297 u16 reg, mask; 298 299 chip->g1_irq.nirqs = chip->info->g1_irqs; 300 chip->g1_irq.domain = irq_domain_create_simple( 301 NULL, chip->g1_irq.nirqs, 0, 302 &mv88e6xxx_g1_irq_domain_ops, chip); 303 if (!chip->g1_irq.domain) 304 return -ENOMEM; 305 306 for (irq = 0; irq < chip->g1_irq.nirqs; irq++) 307 irq_create_mapping(chip->g1_irq.domain, irq); 308 309 chip->g1_irq.chip = mv88e6xxx_g1_irq_chip; 310 chip->g1_irq.masked = ~0; 311 312 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask); 313 if (err) 314 goto out_mapping; 315 316 mask &= ~GENMASK(chip->g1_irq.nirqs, 0); 317 318 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask); 319 if (err) 320 goto out_disable; 321 322 /* Reading the interrupt status clears (most of) them */ 323 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®); 324 if (err) 325 goto out_disable; 326 327 return 0; 328 329out_disable: 330 mask &= ~GENMASK(chip->g1_irq.nirqs, 0); 331 mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask); 332 333out_mapping: 334 for (irq = 0; irq < 16; irq++) { 335 virq = irq_find_mapping(chip->g1_irq.domain, irq); 336 irq_dispose_mapping(virq); 337 } 338 339 irq_domain_remove(chip->g1_irq.domain); 340 341 return err; 342} 343 344static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip) 345{ 346 static struct lock_class_key lock_key; 347 static struct lock_class_key request_key; 348 int err; 349 350 err = mv88e6xxx_g1_irq_setup_common(chip); 351 if (err) 352 return err; 353 354 /* These lock classes tells lockdep that global 1 irqs are in 355 * a different category than their parent GPIO, so it won't 356 * report false recursion. 357 */ 358 irq_set_lockdep_class(chip->irq, &lock_key, &request_key); 359 360 snprintf(chip->irq_name, sizeof(chip->irq_name), 361 "mv88e6xxx-%s", dev_name(chip->dev)); 362 363 mv88e6xxx_reg_unlock(chip); 364 err = request_threaded_irq(chip->irq, NULL, 365 mv88e6xxx_g1_irq_thread_fn, 366 IRQF_ONESHOT | IRQF_SHARED, 367 chip->irq_name, chip); 368 mv88e6xxx_reg_lock(chip); 369 if (err) 370 mv88e6xxx_g1_irq_free_common(chip); 371 372 return err; 373} 374 375static void mv88e6xxx_irq_poll(struct kthread_work *work) 376{ 377 struct mv88e6xxx_chip *chip = container_of(work, 378 struct mv88e6xxx_chip, 379 irq_poll_work.work); 380 mv88e6xxx_g1_irq_thread_work(chip); 381 382 kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work, 383 msecs_to_jiffies(100)); 384} 385 386static int mv88e6xxx_irq_poll_setup(struct mv88e6xxx_chip *chip) 387{ 388 int err; 389 390 err = mv88e6xxx_g1_irq_setup_common(chip); 391 if (err) 392 return err; 393 394 kthread_init_delayed_work(&chip->irq_poll_work, 395 mv88e6xxx_irq_poll); 396 397 chip->kworker = kthread_run_worker(0, "%s", dev_name(chip->dev)); 398 if (IS_ERR(chip->kworker)) 399 return PTR_ERR(chip->kworker); 400 401 kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work, 402 msecs_to_jiffies(100)); 403 404 return 0; 405} 406 407static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip) 408{ 409 kthread_cancel_delayed_work_sync(&chip->irq_poll_work); 410 kthread_destroy_worker(chip->kworker); 411 412 mv88e6xxx_reg_lock(chip); 413 mv88e6xxx_g1_irq_free_common(chip); 414 mv88e6xxx_reg_unlock(chip); 415} 416 417static int mv88e6xxx_port_config_interface(struct mv88e6xxx_chip *chip, 418 int port, phy_interface_t interface) 419{ 420 int err; 421 422 if (chip->info->ops->port_set_rgmii_delay) { 423 err = chip->info->ops->port_set_rgmii_delay(chip, port, 424 interface); 425 if (err && err != -EOPNOTSUPP) 426 return err; 427 } 428 429 if (chip->info->ops->port_set_cmode) { 430 err = chip->info->ops->port_set_cmode(chip, port, 431 interface); 432 if (err && err != -EOPNOTSUPP) 433 return err; 434 } 435 436 return 0; 437} 438 439static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, 440 int link, int speed, int duplex, int pause, 441 phy_interface_t mode) 442{ 443 int err; 444 445 if (!chip->info->ops->port_set_link) 446 return 0; 447 448 /* Port's MAC control must not be changed unless the link is down */ 449 err = chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN); 450 if (err) 451 return err; 452 453 if (chip->info->ops->port_set_speed_duplex) { 454 err = chip->info->ops->port_set_speed_duplex(chip, port, 455 speed, duplex); 456 if (err && err != -EOPNOTSUPP) 457 goto restore_link; 458 } 459 460 if (chip->info->ops->port_set_pause) { 461 err = chip->info->ops->port_set_pause(chip, port, pause); 462 if (err) 463 goto restore_link; 464 } 465 466 err = mv88e6xxx_port_config_interface(chip, port, mode); 467restore_link: 468 if (chip->info->ops->port_set_link(chip, port, link)) 469 dev_err(chip->dev, "p%d: failed to restore MAC's link\n", port); 470 471 return err; 472} 473 474static int mv88e6xxx_phy_is_internal(struct mv88e6xxx_chip *chip, int port) 475{ 476 return port >= chip->info->internal_phys_offset && 477 port < chip->info->num_internal_phys + 478 chip->info->internal_phys_offset; 479} 480 481static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port) 482{ 483 u16 reg; 484 int err; 485 486 /* The 88e6250 family does not have the PHY detect bit. Instead, 487 * report whether the port is internal. 488 */ 489 if (chip->info->family == MV88E6XXX_FAMILY_6250) 490 return mv88e6xxx_phy_is_internal(chip, port); 491 492 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 493 if (err) { 494 dev_err(chip->dev, 495 "p%d: %s: failed to read port status\n", 496 port, __func__); 497 return err; 498 } 499 500 return !!(reg & MV88E6XXX_PORT_STS_PHY_DETECT); 501} 502 503static const u8 mv88e6185_phy_interface_modes[] = { 504 [MV88E6185_PORT_STS_CMODE_GMII_FD] = PHY_INTERFACE_MODE_GMII, 505 [MV88E6185_PORT_STS_CMODE_MII_100_FD_PS] = PHY_INTERFACE_MODE_MII, 506 [MV88E6185_PORT_STS_CMODE_MII_100] = PHY_INTERFACE_MODE_MII, 507 [MV88E6185_PORT_STS_CMODE_MII_10] = PHY_INTERFACE_MODE_MII, 508 [MV88E6185_PORT_STS_CMODE_SERDES] = PHY_INTERFACE_MODE_1000BASEX, 509 [MV88E6185_PORT_STS_CMODE_1000BASE_X] = PHY_INTERFACE_MODE_1000BASEX, 510 [MV88E6185_PORT_STS_CMODE_PHY] = PHY_INTERFACE_MODE_SGMII, 511}; 512 513static void mv88e6095_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, 514 struct phylink_config *config) 515{ 516 u8 cmode = chip->ports[port].cmode; 517 518 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100; 519 520 if (mv88e6xxx_phy_is_internal(chip, port)) { 521 __set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces); 522 } else { 523 if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) && 524 mv88e6185_phy_interface_modes[cmode]) 525 __set_bit(mv88e6185_phy_interface_modes[cmode], 526 config->supported_interfaces); 527 528 config->mac_capabilities |= MAC_1000FD; 529 } 530} 531 532static void mv88e6185_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, 533 struct phylink_config *config) 534{ 535 u8 cmode = chip->ports[port].cmode; 536 537 if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) && 538 mv88e6185_phy_interface_modes[cmode]) 539 __set_bit(mv88e6185_phy_interface_modes[cmode], 540 config->supported_interfaces); 541 542 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | 543 MAC_1000FD; 544} 545 546static const u8 mv88e6xxx_phy_interface_modes[] = { 547 [MV88E6XXX_PORT_STS_CMODE_MII_PHY] = PHY_INTERFACE_MODE_REVMII, 548 [MV88E6XXX_PORT_STS_CMODE_MII] = PHY_INTERFACE_MODE_MII, 549 [MV88E6XXX_PORT_STS_CMODE_GMII] = PHY_INTERFACE_MODE_GMII, 550 [MV88E6XXX_PORT_STS_CMODE_RMII_PHY] = PHY_INTERFACE_MODE_REVRMII, 551 [MV88E6XXX_PORT_STS_CMODE_RMII] = PHY_INTERFACE_MODE_RMII, 552 [MV88E6XXX_PORT_STS_CMODE_100BASEX] = PHY_INTERFACE_MODE_100BASEX, 553 [MV88E6XXX_PORT_STS_CMODE_1000BASEX] = PHY_INTERFACE_MODE_1000BASEX, 554 [MV88E6XXX_PORT_STS_CMODE_SGMII] = PHY_INTERFACE_MODE_SGMII, 555 /* higher interface modes are not needed here, since ports supporting 556 * them are writable, and so the supported interfaces are filled in the 557 * corresponding .phylink_set_interfaces() implementation below 558 */ 559}; 560 561static void mv88e6xxx_translate_cmode(u8 cmode, unsigned long *supported) 562{ 563 if (cmode < ARRAY_SIZE(mv88e6xxx_phy_interface_modes) && 564 mv88e6xxx_phy_interface_modes[cmode]) 565 __set_bit(mv88e6xxx_phy_interface_modes[cmode], supported); 566 else if (cmode == MV88E6XXX_PORT_STS_CMODE_RGMII) 567 phy_interface_set_rgmii(supported); 568} 569 570static void 571mv88e6250_setup_supported_interfaces(struct mv88e6xxx_chip *chip, int port, 572 struct phylink_config *config) 573{ 574 unsigned long *supported = config->supported_interfaces; 575 int err; 576 u16 reg; 577 578 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 579 if (err) { 580 dev_err(chip->dev, "p%d: failed to read port status\n", port); 581 return; 582 } 583 584 switch (reg & MV88E6250_PORT_STS_PORTMODE_MASK) { 585 case MV88E6250_PORT_STS_PORTMODE_MII_10_HALF_PHY: 586 case MV88E6250_PORT_STS_PORTMODE_MII_100_HALF_PHY: 587 case MV88E6250_PORT_STS_PORTMODE_MII_10_FULL_PHY: 588 case MV88E6250_PORT_STS_PORTMODE_MII_100_FULL_PHY: 589 __set_bit(PHY_INTERFACE_MODE_REVMII, supported); 590 break; 591 592 case MV88E6250_PORT_STS_PORTMODE_MII_HALF: 593 case MV88E6250_PORT_STS_PORTMODE_MII_FULL: 594 __set_bit(PHY_INTERFACE_MODE_MII, supported); 595 break; 596 597 case MV88E6250_PORT_STS_PORTMODE_MII_DUAL_100_RMII_FULL_PHY: 598 case MV88E6250_PORT_STS_PORTMODE_MII_200_RMII_FULL_PHY: 599 case MV88E6250_PORT_STS_PORTMODE_MII_10_100_RMII_HALF_PHY: 600 case MV88E6250_PORT_STS_PORTMODE_MII_10_100_RMII_FULL_PHY: 601 __set_bit(PHY_INTERFACE_MODE_REVRMII, supported); 602 break; 603 604 case MV88E6250_PORT_STS_PORTMODE_MII_DUAL_100_RMII_FULL: 605 case MV88E6250_PORT_STS_PORTMODE_MII_10_100_RMII_FULL: 606 __set_bit(PHY_INTERFACE_MODE_RMII, supported); 607 break; 608 609 case MV88E6250_PORT_STS_PORTMODE_MII_100_RGMII: 610 __set_bit(PHY_INTERFACE_MODE_RGMII, supported); 611 break; 612 613 default: 614 dev_err(chip->dev, 615 "p%d: invalid port mode in status register: %04x\n", 616 port, reg); 617 } 618} 619 620static void mv88e6250_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, 621 struct phylink_config *config) 622{ 623 if (!mv88e6xxx_phy_is_internal(chip, port)) 624 mv88e6250_setup_supported_interfaces(chip, port, config); 625 626 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100; 627} 628 629static void mv88e6351_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, 630 struct phylink_config *config) 631{ 632 unsigned long *supported = config->supported_interfaces; 633 634 /* Translate the default cmode */ 635 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); 636 637 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | 638 MAC_1000FD; 639} 640 641static int mv88e63xx_get_port_serdes_cmode(struct mv88e6xxx_chip *chip, int port) 642{ 643 u16 reg, val; 644 int err; 645 646 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 647 if (err) 648 return err; 649 650 /* If PHY_DETECT is zero, then we are not in auto-media mode */ 651 if (!(reg & MV88E6XXX_PORT_STS_PHY_DETECT)) 652 return 0xf; 653 654 val = reg & ~MV88E6XXX_PORT_STS_PHY_DETECT; 655 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, val); 656 if (err) 657 return err; 658 659 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &val); 660 if (err) 661 return err; 662 663 /* Restore PHY_DETECT value */ 664 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg); 665 if (err) 666 return err; 667 668 return val & MV88E6XXX_PORT_STS_CMODE_MASK; 669} 670 671static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, 672 struct phylink_config *config) 673{ 674 unsigned long *supported = config->supported_interfaces; 675 int err, cmode; 676 677 /* Translate the default cmode */ 678 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); 679 680 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | 681 MAC_1000FD; 682 683 /* Port 4 supports automedia if the serdes is associated with it. */ 684 if (port == 4) { 685 err = mv88e6352_g2_scratch_port_has_serdes(chip, port); 686 if (err < 0) 687 dev_err(chip->dev, "p%d: failed to read scratch\n", 688 port); 689 if (err <= 0) 690 return; 691 692 cmode = mv88e63xx_get_port_serdes_cmode(chip, port); 693 if (cmode < 0) 694 dev_err(chip->dev, "p%d: failed to read serdes cmode\n", 695 port); 696 else 697 mv88e6xxx_translate_cmode(cmode, supported); 698 } 699} 700 701static void mv88e632x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, 702 struct phylink_config *config) 703{ 704 unsigned long *supported = config->supported_interfaces; 705 int cmode; 706 707 /* Translate the default cmode */ 708 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); 709 710 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | 711 MAC_1000FD; 712 713 /* Port 0/1 are serdes only ports */ 714 if (port == 0 || port == 1) { 715 cmode = mv88e63xx_get_port_serdes_cmode(chip, port); 716 if (cmode < 0) 717 dev_err(chip->dev, "p%d: failed to read serdes cmode\n", 718 port); 719 else 720 mv88e6xxx_translate_cmode(cmode, supported); 721 } 722} 723 724static void mv88e6341_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, 725 struct phylink_config *config) 726{ 727 unsigned long *supported = config->supported_interfaces; 728 729 /* Translate the default cmode */ 730 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); 731 732 /* No ethtool bits for 200Mbps */ 733 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | 734 MAC_1000FD; 735 736 /* The C_Mode field is programmable on port 5 */ 737 if (port == 5) { 738 __set_bit(PHY_INTERFACE_MODE_SGMII, supported); 739 __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported); 740 __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported); 741 742 config->mac_capabilities |= MAC_2500FD; 743 } 744} 745 746static void mv88e6390_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, 747 struct phylink_config *config) 748{ 749 unsigned long *supported = config->supported_interfaces; 750 751 /* Translate the default cmode */ 752 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); 753 754 /* No ethtool bits for 200Mbps */ 755 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | 756 MAC_1000FD; 757 758 /* The C_Mode field is programmable on ports 9 and 10 */ 759 if (port == 9 || port == 10) { 760 __set_bit(PHY_INTERFACE_MODE_SGMII, supported); 761 __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported); 762 __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported); 763 764 config->mac_capabilities |= MAC_2500FD; 765 } 766} 767 768static void mv88e6390x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, 769 struct phylink_config *config) 770{ 771 unsigned long *supported = config->supported_interfaces; 772 773 mv88e6390_phylink_get_caps(chip, port, config); 774 775 /* For the 6x90X, ports 2-7 can be in automedia mode. 776 * (Note that 6x90 doesn't support RXAUI nor XAUI). 777 * 778 * Port 2 can also support 1000BASE-X in automedia mode if port 9 is 779 * configured for 1000BASE-X, SGMII or 2500BASE-X. 780 * Port 3-4 can also support 1000BASE-X in automedia mode if port 9 is 781 * configured for RXAUI, 1000BASE-X, SGMII or 2500BASE-X. 782 * 783 * Port 5 can also support 1000BASE-X in automedia mode if port 10 is 784 * configured for 1000BASE-X, SGMII or 2500BASE-X. 785 * Port 6-7 can also support 1000BASE-X in automedia mode if port 10 is 786 * configured for RXAUI, 1000BASE-X, SGMII or 2500BASE-X. 787 * 788 * For now, be permissive (as the old code was) and allow 1000BASE-X 789 * on ports 2..7. 790 */ 791 if (port >= 2 && port <= 7) 792 __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported); 793 794 /* The C_Mode field can also be programmed for 10G speeds */ 795 if (port == 9 || port == 10) { 796 __set_bit(PHY_INTERFACE_MODE_XAUI, supported); 797 __set_bit(PHY_INTERFACE_MODE_RXAUI, supported); 798 799 config->mac_capabilities |= MAC_10000FD; 800 } 801} 802 803static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, 804 struct phylink_config *config) 805{ 806 unsigned long *supported = config->supported_interfaces; 807 bool is_6191x = 808 chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X; 809 bool is_6361 = 810 chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361; 811 812 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); 813 814 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | 815 MAC_1000FD; 816 817 /* The C_Mode field can be programmed for ports 0, 9 and 10 */ 818 if (port == 0 || port == 9 || port == 10) { 819 __set_bit(PHY_INTERFACE_MODE_SGMII, supported); 820 __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported); 821 822 /* 6191X supports >1G modes only on port 10 */ 823 if (!is_6191x || port == 10) { 824 __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported); 825 config->mac_capabilities |= MAC_2500FD; 826 827 /* 6361 only supports up to 2500BaseX */ 828 if (!is_6361) { 829 __set_bit(PHY_INTERFACE_MODE_5GBASER, supported); 830 __set_bit(PHY_INTERFACE_MODE_10GBASER, supported); 831 __set_bit(PHY_INTERFACE_MODE_USXGMII, supported); 832 config->mac_capabilities |= MAC_5000FD | 833 MAC_10000FD; 834 } 835 } 836 } 837 838 if (port == 0) { 839 __set_bit(PHY_INTERFACE_MODE_RMII, supported); 840 __set_bit(PHY_INTERFACE_MODE_RGMII, supported); 841 __set_bit(PHY_INTERFACE_MODE_RGMII_ID, supported); 842 __set_bit(PHY_INTERFACE_MODE_RGMII_RXID, supported); 843 __set_bit(PHY_INTERFACE_MODE_RGMII_TXID, supported); 844 } 845} 846 847static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port, 848 struct phylink_config *config) 849{ 850 struct mv88e6xxx_chip *chip = ds->priv; 851 852 mv88e6xxx_reg_lock(chip); 853 chip->info->ops->phylink_get_caps(chip, port, config); 854 mv88e6xxx_reg_unlock(chip); 855 856 if (mv88e6xxx_phy_is_internal(chip, port)) { 857 __set_bit(PHY_INTERFACE_MODE_INTERNAL, 858 config->supported_interfaces); 859 /* Internal ports with no phy-mode need GMII for PHYLIB */ 860 __set_bit(PHY_INTERFACE_MODE_GMII, 861 config->supported_interfaces); 862 } 863} 864 865static struct phylink_pcs * 866mv88e6xxx_mac_select_pcs(struct phylink_config *config, 867 phy_interface_t interface) 868{ 869 struct dsa_port *dp = dsa_phylink_to_port(config); 870 struct mv88e6xxx_chip *chip = dp->ds->priv; 871 struct phylink_pcs *pcs = NULL; 872 873 if (chip->info->ops->pcs_ops) 874 pcs = chip->info->ops->pcs_ops->pcs_select(chip, dp->index, 875 interface); 876 877 return pcs; 878} 879 880static int mv88e6xxx_mac_prepare(struct phylink_config *config, 881 unsigned int mode, phy_interface_t interface) 882{ 883 struct dsa_port *dp = dsa_phylink_to_port(config); 884 struct mv88e6xxx_chip *chip = dp->ds->priv; 885 int port = dp->index; 886 int err = 0; 887 888 /* In inband mode, the link may come up at any time while the link 889 * is not forced down. Force the link down while we reconfigure the 890 * interface mode. 891 */ 892 if (mode == MLO_AN_INBAND && 893 chip->ports[port].interface != interface && 894 chip->info->ops->port_set_link) { 895 mv88e6xxx_reg_lock(chip); 896 err = chip->info->ops->port_set_link(chip, port, 897 LINK_FORCED_DOWN); 898 mv88e6xxx_reg_unlock(chip); 899 } 900 901 return err; 902} 903 904static void mv88e6xxx_mac_config(struct phylink_config *config, 905 unsigned int mode, 906 const struct phylink_link_state *state) 907{ 908 struct dsa_port *dp = dsa_phylink_to_port(config); 909 struct mv88e6xxx_chip *chip = dp->ds->priv; 910 int port = dp->index; 911 int err = 0; 912 913 mv88e6xxx_reg_lock(chip); 914 915 if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(chip, port)) { 916 err = mv88e6xxx_port_config_interface(chip, port, 917 state->interface); 918 if (err && err != -EOPNOTSUPP) 919 goto err_unlock; 920 } 921 922err_unlock: 923 mv88e6xxx_reg_unlock(chip); 924 925 if (err && err != -EOPNOTSUPP) 926 dev_err(chip->dev, "p%d: failed to configure MAC/PCS\n", port); 927} 928 929static int mv88e6xxx_mac_finish(struct phylink_config *config, 930 unsigned int mode, phy_interface_t interface) 931{ 932 struct dsa_port *dp = dsa_phylink_to_port(config); 933 struct mv88e6xxx_chip *chip = dp->ds->priv; 934 int port = dp->index; 935 int err = 0; 936 937 /* Undo the forced down state above after completing configuration 938 * irrespective of its state on entry, which allows the link to come 939 * up in the in-band case where there is no separate SERDES. Also 940 * ensure that the link can come up if the PPU is in use and we are 941 * in PHY mode (we treat the PPU as an effective in-band mechanism.) 942 */ 943 mv88e6xxx_reg_lock(chip); 944 945 if (chip->info->ops->port_set_link && 946 ((mode == MLO_AN_INBAND && 947 chip->ports[port].interface != interface) || 948 (mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port)))) 949 err = chip->info->ops->port_set_link(chip, port, LINK_UNFORCED); 950 951 mv88e6xxx_reg_unlock(chip); 952 953 chip->ports[port].interface = interface; 954 955 return err; 956} 957 958static void mv88e6xxx_mac_link_down(struct phylink_config *config, 959 unsigned int mode, 960 phy_interface_t interface) 961{ 962 struct dsa_port *dp = dsa_phylink_to_port(config); 963 struct mv88e6xxx_chip *chip = dp->ds->priv; 964 const struct mv88e6xxx_ops *ops; 965 int port = dp->index; 966 int err = 0; 967 968 ops = chip->info->ops; 969 970 mv88e6xxx_reg_lock(chip); 971 /* Force the link down if we know the port may not be automatically 972 * updated by the switch or if we are using fixed-link mode. 973 */ 974 if ((!mv88e6xxx_port_ppu_updates(chip, port) || 975 mode == MLO_AN_FIXED) && ops->port_sync_link) 976 err = ops->port_sync_link(chip, port, mode, false); 977 978 if (!err && ops->port_set_speed_duplex) 979 err = ops->port_set_speed_duplex(chip, port, SPEED_UNFORCED, 980 DUPLEX_UNFORCED); 981 mv88e6xxx_reg_unlock(chip); 982 983 if (err) 984 dev_err(chip->dev, 985 "p%d: failed to force MAC link down\n", port); 986} 987 988static void mv88e6xxx_mac_link_up(struct phylink_config *config, 989 struct phy_device *phydev, 990 unsigned int mode, phy_interface_t interface, 991 int speed, int duplex, 992 bool tx_pause, bool rx_pause) 993{ 994 struct dsa_port *dp = dsa_phylink_to_port(config); 995 struct mv88e6xxx_chip *chip = dp->ds->priv; 996 const struct mv88e6xxx_ops *ops; 997 int port = dp->index; 998 int err = 0; 999 1000 ops = chip->info->ops; 1001 1002 mv88e6xxx_reg_lock(chip); 1003 /* Configure and force the link up if we know that the port may not 1004 * automatically updated by the switch or if we are using fixed-link 1005 * mode. 1006 */ 1007 if (!mv88e6xxx_port_ppu_updates(chip, port) || 1008 mode == MLO_AN_FIXED) { 1009 if (ops->port_set_speed_duplex) { 1010 err = ops->port_set_speed_duplex(chip, port, 1011 speed, duplex); 1012 if (err && err != -EOPNOTSUPP) 1013 goto error; 1014 } 1015 1016 if (ops->port_sync_link) 1017 err = ops->port_sync_link(chip, port, mode, true); 1018 } 1019error: 1020 mv88e6xxx_reg_unlock(chip); 1021 1022 if (err && err != -EOPNOTSUPP) 1023 dev_err(chip->dev, 1024 "p%d: failed to configure MAC link up\n", port); 1025} 1026 1027static int mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port) 1028{ 1029 int err; 1030 1031 if (!chip->info->ops->stats_snapshot) 1032 return -EOPNOTSUPP; 1033 1034 mv88e6xxx_reg_lock(chip); 1035 err = chip->info->ops->stats_snapshot(chip, port); 1036 mv88e6xxx_reg_unlock(chip); 1037 1038 return err; 1039} 1040 1041#define MV88E6XXX_HW_STAT_MAPPER(_fn) \ 1042 _fn(in_good_octets, 8, 0x00, STATS_TYPE_BANK0), \ 1043 _fn(in_bad_octets, 4, 0x02, STATS_TYPE_BANK0), \ 1044 _fn(in_unicast, 4, 0x04, STATS_TYPE_BANK0), \ 1045 _fn(in_broadcasts, 4, 0x06, STATS_TYPE_BANK0), \ 1046 _fn(in_multicasts, 4, 0x07, STATS_TYPE_BANK0), \ 1047 _fn(in_pause, 4, 0x16, STATS_TYPE_BANK0), \ 1048 _fn(in_undersize, 4, 0x18, STATS_TYPE_BANK0), \ 1049 _fn(in_fragments, 4, 0x19, STATS_TYPE_BANK0), \ 1050 _fn(in_oversize, 4, 0x1a, STATS_TYPE_BANK0), \ 1051 _fn(in_jabber, 4, 0x1b, STATS_TYPE_BANK0), \ 1052 _fn(in_rx_error, 4, 0x1c, STATS_TYPE_BANK0), \ 1053 _fn(in_fcs_error, 4, 0x1d, STATS_TYPE_BANK0), \ 1054 _fn(out_octets, 8, 0x0e, STATS_TYPE_BANK0), \ 1055 _fn(out_unicast, 4, 0x10, STATS_TYPE_BANK0), \ 1056 _fn(out_broadcasts, 4, 0x13, STATS_TYPE_BANK0), \ 1057 _fn(out_multicasts, 4, 0x12, STATS_TYPE_BANK0), \ 1058 _fn(out_pause, 4, 0x15, STATS_TYPE_BANK0), \ 1059 _fn(excessive, 4, 0x11, STATS_TYPE_BANK0), \ 1060 _fn(collisions, 4, 0x1e, STATS_TYPE_BANK0), \ 1061 _fn(deferred, 4, 0x05, STATS_TYPE_BANK0), \ 1062 _fn(single, 4, 0x14, STATS_TYPE_BANK0), \ 1063 _fn(multiple, 4, 0x17, STATS_TYPE_BANK0), \ 1064 _fn(out_fcs_error, 4, 0x03, STATS_TYPE_BANK0), \ 1065 _fn(late, 4, 0x1f, STATS_TYPE_BANK0), \ 1066 _fn(hist_64bytes, 4, 0x08, STATS_TYPE_BANK0), \ 1067 _fn(hist_65_127bytes, 4, 0x09, STATS_TYPE_BANK0), \ 1068 _fn(hist_128_255bytes, 4, 0x0a, STATS_TYPE_BANK0), \ 1069 _fn(hist_256_511bytes, 4, 0x0b, STATS_TYPE_BANK0), \ 1070 _fn(hist_512_1023bytes, 4, 0x0c, STATS_TYPE_BANK0), \ 1071 _fn(hist_1024_max_bytes, 4, 0x0d, STATS_TYPE_BANK0), \ 1072 _fn(sw_in_discards, 4, 0x10, STATS_TYPE_PORT), \ 1073 _fn(sw_in_filtered, 2, 0x12, STATS_TYPE_PORT), \ 1074 _fn(sw_out_filtered, 2, 0x13, STATS_TYPE_PORT), \ 1075 _fn(in_discards, 4, 0x00, STATS_TYPE_BANK1), \ 1076 _fn(in_filtered, 4, 0x01, STATS_TYPE_BANK1), \ 1077 _fn(in_accepted, 4, 0x02, STATS_TYPE_BANK1), \ 1078 _fn(in_bad_accepted, 4, 0x03, STATS_TYPE_BANK1), \ 1079 _fn(in_good_avb_class_a, 4, 0x04, STATS_TYPE_BANK1), \ 1080 _fn(in_good_avb_class_b, 4, 0x05, STATS_TYPE_BANK1), \ 1081 _fn(in_bad_avb_class_a, 4, 0x06, STATS_TYPE_BANK1), \ 1082 _fn(in_bad_avb_class_b, 4, 0x07, STATS_TYPE_BANK1), \ 1083 _fn(tcam_counter_0, 4, 0x08, STATS_TYPE_BANK1), \ 1084 _fn(tcam_counter_1, 4, 0x09, STATS_TYPE_BANK1), \ 1085 _fn(tcam_counter_2, 4, 0x0a, STATS_TYPE_BANK1), \ 1086 _fn(tcam_counter_3, 4, 0x0b, STATS_TYPE_BANK1), \ 1087 _fn(in_da_unknown, 4, 0x0e, STATS_TYPE_BANK1), \ 1088 _fn(in_management, 4, 0x0f, STATS_TYPE_BANK1), \ 1089 _fn(out_queue_0, 4, 0x10, STATS_TYPE_BANK1), \ 1090 _fn(out_queue_1, 4, 0x11, STATS_TYPE_BANK1), \ 1091 _fn(out_queue_2, 4, 0x12, STATS_TYPE_BANK1), \ 1092 _fn(out_queue_3, 4, 0x13, STATS_TYPE_BANK1), \ 1093 _fn(out_queue_4, 4, 0x14, STATS_TYPE_BANK1), \ 1094 _fn(out_queue_5, 4, 0x15, STATS_TYPE_BANK1), \ 1095 _fn(out_queue_6, 4, 0x16, STATS_TYPE_BANK1), \ 1096 _fn(out_queue_7, 4, 0x17, STATS_TYPE_BANK1), \ 1097 _fn(out_cut_through, 4, 0x18, STATS_TYPE_BANK1), \ 1098 _fn(out_octets_a, 4, 0x1a, STATS_TYPE_BANK1), \ 1099 _fn(out_octets_b, 4, 0x1b, STATS_TYPE_BANK1), \ 1100 _fn(out_management, 4, 0x1f, STATS_TYPE_BANK1), \ 1101 /* */ 1102 1103#define MV88E6XXX_HW_STAT_ENTRY(_string, _size, _reg, _type) \ 1104 { #_string, _size, _reg, _type } 1105static const struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = { 1106 MV88E6XXX_HW_STAT_MAPPER(MV88E6XXX_HW_STAT_ENTRY) 1107}; 1108 1109#define MV88E6XXX_HW_STAT_ENUM(_string, _size, _reg, _type) \ 1110 MV88E6XXX_HW_STAT_ID_ ## _string 1111enum mv88e6xxx_hw_stat_id { 1112 MV88E6XXX_HW_STAT_MAPPER(MV88E6XXX_HW_STAT_ENUM) 1113}; 1114 1115static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip, 1116 const struct mv88e6xxx_hw_stat *s, 1117 int port, u16 bank1_select, 1118 u16 histogram) 1119{ 1120 u32 low; 1121 u32 high = 0; 1122 u16 reg = 0; 1123 int err; 1124 u64 value; 1125 1126 switch (s->type) { 1127 case STATS_TYPE_PORT: 1128 err = mv88e6xxx_port_read(chip, port, s->reg, ®); 1129 if (err) 1130 return U64_MAX; 1131 1132 low = reg; 1133 if (s->size == 4) { 1134 err = mv88e6xxx_port_read(chip, port, s->reg + 1, ®); 1135 if (err) 1136 return U64_MAX; 1137 low |= ((u32)reg) << 16; 1138 } 1139 break; 1140 case STATS_TYPE_BANK1: 1141 reg = bank1_select; 1142 fallthrough; 1143 case STATS_TYPE_BANK0: 1144 reg |= s->reg | histogram; 1145 mv88e6xxx_g1_stats_read(chip, reg, &low); 1146 if (s->size == 8) 1147 mv88e6xxx_g1_stats_read(chip, reg + 1, &high); 1148 break; 1149 default: 1150 return U64_MAX; 1151 } 1152 value = (((u64)high) << 32) | low; 1153 return value; 1154} 1155 1156static void mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip, 1157 uint8_t **data, int types) 1158{ 1159 const struct mv88e6xxx_hw_stat *stat; 1160 int i; 1161 1162 for (i = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) { 1163 stat = &mv88e6xxx_hw_stats[i]; 1164 if (stat->type & types) 1165 ethtool_puts(data, stat->string); 1166 } 1167} 1168 1169static void mv88e6095_stats_get_strings(struct mv88e6xxx_chip *chip, 1170 uint8_t **data) 1171{ 1172 mv88e6xxx_stats_get_strings(chip, data, 1173 STATS_TYPE_BANK0 | STATS_TYPE_PORT); 1174} 1175 1176static void mv88e6250_stats_get_strings(struct mv88e6xxx_chip *chip, 1177 uint8_t **data) 1178{ 1179 mv88e6xxx_stats_get_strings(chip, data, STATS_TYPE_BANK0); 1180} 1181 1182static void mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip, 1183 uint8_t **data) 1184{ 1185 mv88e6xxx_stats_get_strings(chip, data, 1186 STATS_TYPE_BANK0 | STATS_TYPE_BANK1); 1187} 1188 1189static const uint8_t *mv88e6xxx_atu_vtu_stats_strings[] = { 1190 "atu_member_violation", 1191 "atu_miss_violation", 1192 "atu_full_violation", 1193 "vtu_member_violation", 1194 "vtu_miss_violation", 1195}; 1196 1197static void mv88e6xxx_atu_vtu_get_strings(uint8_t **data) 1198{ 1199 unsigned int i; 1200 1201 for (i = 0; i < ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings); i++) 1202 ethtool_puts(data, mv88e6xxx_atu_vtu_stats_strings[i]); 1203} 1204 1205static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, 1206 u32 stringset, uint8_t *data) 1207{ 1208 struct mv88e6xxx_chip *chip = ds->priv; 1209 1210 if (stringset != ETH_SS_STATS) 1211 return; 1212 1213 mv88e6xxx_reg_lock(chip); 1214 1215 if (chip->info->ops->stats_get_strings) 1216 chip->info->ops->stats_get_strings(chip, &data); 1217 1218 if (chip->info->ops->serdes_get_strings) 1219 chip->info->ops->serdes_get_strings(chip, port, &data); 1220 1221 mv88e6xxx_atu_vtu_get_strings(&data); 1222 1223 mv88e6xxx_reg_unlock(chip); 1224} 1225 1226static int mv88e6xxx_stats_get_sset_count(struct mv88e6xxx_chip *chip, 1227 int types) 1228{ 1229 const struct mv88e6xxx_hw_stat *stat; 1230 int i, j; 1231 1232 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) { 1233 stat = &mv88e6xxx_hw_stats[i]; 1234 if (stat->type & types) 1235 j++; 1236 } 1237 return j; 1238} 1239 1240static int mv88e6095_stats_get_sset_count(struct mv88e6xxx_chip *chip) 1241{ 1242 return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 | 1243 STATS_TYPE_PORT); 1244} 1245 1246static int mv88e6250_stats_get_sset_count(struct mv88e6xxx_chip *chip) 1247{ 1248 return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0); 1249} 1250 1251static int mv88e6320_stats_get_sset_count(struct mv88e6xxx_chip *chip) 1252{ 1253 return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 | 1254 STATS_TYPE_BANK1); 1255} 1256 1257static int mv88e6xxx_get_sset_count(struct dsa_switch *ds, int port, int sset) 1258{ 1259 struct mv88e6xxx_chip *chip = ds->priv; 1260 int serdes_count = 0; 1261 int count = 0; 1262 1263 if (sset != ETH_SS_STATS) 1264 return 0; 1265 1266 mv88e6xxx_reg_lock(chip); 1267 if (chip->info->ops->stats_get_sset_count) 1268 count = chip->info->ops->stats_get_sset_count(chip); 1269 if (count < 0) 1270 goto out; 1271 1272 if (chip->info->ops->serdes_get_sset_count) 1273 serdes_count = chip->info->ops->serdes_get_sset_count(chip, 1274 port); 1275 if (serdes_count < 0) { 1276 count = serdes_count; 1277 goto out; 1278 } 1279 count += serdes_count; 1280 count += ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings); 1281 1282out: 1283 mv88e6xxx_reg_unlock(chip); 1284 1285 return count; 1286} 1287 1288static size_t mv88e6095_stats_get_stat(struct mv88e6xxx_chip *chip, int port, 1289 const struct mv88e6xxx_hw_stat *stat, 1290 uint64_t *data) 1291{ 1292 *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, 0, 1293 MV88E6XXX_G1_STATS_OP_HIST_RX); 1294 return 1; 1295} 1296 1297static size_t mv88e6250_stats_get_stat(struct mv88e6xxx_chip *chip, int port, 1298 const struct mv88e6xxx_hw_stat *stat, 1299 uint64_t *data) 1300{ 1301 *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, 0, 1302 MV88E6XXX_G1_STATS_OP_HIST_RX); 1303 return 1; 1304} 1305 1306static size_t mv88e6320_stats_get_stat(struct mv88e6xxx_chip *chip, int port, 1307 const struct mv88e6xxx_hw_stat *stat, 1308 uint64_t *data) 1309{ 1310 *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, 1311 MV88E6XXX_G1_STATS_OP_BANK_1_BIT_9, 1312 MV88E6XXX_G1_STATS_OP_HIST_RX); 1313 return 1; 1314} 1315 1316static size_t mv88e6390_stats_get_stat(struct mv88e6xxx_chip *chip, int port, 1317 const struct mv88e6xxx_hw_stat *stat, 1318 uint64_t *data) 1319{ 1320 *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, 1321 MV88E6XXX_G1_STATS_OP_BANK_1_BIT_10, 1322 0); 1323 return 1; 1324} 1325 1326static size_t mv88e6xxx_stats_get_stat(struct mv88e6xxx_chip *chip, int port, 1327 const struct mv88e6xxx_hw_stat *stat, 1328 uint64_t *data) 1329{ 1330 int ret = 0; 1331 1332 if (!(stat->type & chip->info->stats_type)) 1333 return 0; 1334 1335 if (chip->info->ops->stats_get_stat) { 1336 mv88e6xxx_reg_lock(chip); 1337 ret = chip->info->ops->stats_get_stat(chip, port, stat, data); 1338 mv88e6xxx_reg_unlock(chip); 1339 } 1340 1341 return ret; 1342} 1343 1344static size_t mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port, 1345 uint64_t *data) 1346{ 1347 const struct mv88e6xxx_hw_stat *stat; 1348 size_t i, j; 1349 1350 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) { 1351 stat = &mv88e6xxx_hw_stats[i]; 1352 j += mv88e6xxx_stats_get_stat(chip, port, stat, &data[j]); 1353 } 1354 return j; 1355} 1356 1357static void mv88e6xxx_atu_vtu_get_stats(struct mv88e6xxx_chip *chip, int port, 1358 uint64_t *data) 1359{ 1360 *data++ = chip->ports[port].atu_member_violation; 1361 *data++ = chip->ports[port].atu_miss_violation; 1362 *data++ = chip->ports[port].atu_full_violation; 1363 *data++ = chip->ports[port].vtu_member_violation; 1364 *data++ = chip->ports[port].vtu_miss_violation; 1365} 1366 1367static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port, 1368 uint64_t *data) 1369{ 1370 size_t count; 1371 1372 count = mv88e6xxx_stats_get_stats(chip, port, data); 1373 1374 mv88e6xxx_reg_lock(chip); 1375 if (chip->info->ops->serdes_get_stats) { 1376 data += count; 1377 count = chip->info->ops->serdes_get_stats(chip, port, data); 1378 } 1379 data += count; 1380 mv88e6xxx_atu_vtu_get_stats(chip, port, data); 1381 mv88e6xxx_reg_unlock(chip); 1382} 1383 1384static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port, 1385 uint64_t *data) 1386{ 1387 struct mv88e6xxx_chip *chip = ds->priv; 1388 int ret; 1389 1390 ret = mv88e6xxx_stats_snapshot(chip, port); 1391 if (ret < 0) 1392 return; 1393 1394 mv88e6xxx_get_stats(chip, port, data); 1395} 1396 1397static void mv88e6xxx_get_eth_mac_stats(struct dsa_switch *ds, int port, 1398 struct ethtool_eth_mac_stats *mac_stats) 1399{ 1400 struct mv88e6xxx_chip *chip = ds->priv; 1401 int ret; 1402 1403 ret = mv88e6xxx_stats_snapshot(chip, port); 1404 if (ret < 0) 1405 return; 1406 1407#define MV88E6XXX_ETH_MAC_STAT_MAP(_id, _member) \ 1408 mv88e6xxx_stats_get_stat(chip, port, \ 1409 &mv88e6xxx_hw_stats[MV88E6XXX_HW_STAT_ID_ ## _id], \ 1410 &mac_stats->stats._member) 1411 1412 MV88E6XXX_ETH_MAC_STAT_MAP(out_unicast, FramesTransmittedOK); 1413 MV88E6XXX_ETH_MAC_STAT_MAP(single, SingleCollisionFrames); 1414 MV88E6XXX_ETH_MAC_STAT_MAP(multiple, MultipleCollisionFrames); 1415 MV88E6XXX_ETH_MAC_STAT_MAP(in_unicast, FramesReceivedOK); 1416 MV88E6XXX_ETH_MAC_STAT_MAP(in_fcs_error, FrameCheckSequenceErrors); 1417 MV88E6XXX_ETH_MAC_STAT_MAP(out_octets, OctetsTransmittedOK); 1418 MV88E6XXX_ETH_MAC_STAT_MAP(deferred, FramesWithDeferredXmissions); 1419 MV88E6XXX_ETH_MAC_STAT_MAP(late, LateCollisions); 1420 MV88E6XXX_ETH_MAC_STAT_MAP(in_good_octets, OctetsReceivedOK); 1421 MV88E6XXX_ETH_MAC_STAT_MAP(out_multicasts, MulticastFramesXmittedOK); 1422 MV88E6XXX_ETH_MAC_STAT_MAP(out_broadcasts, BroadcastFramesXmittedOK); 1423 MV88E6XXX_ETH_MAC_STAT_MAP(excessive, FramesWithExcessiveDeferral); 1424 MV88E6XXX_ETH_MAC_STAT_MAP(in_multicasts, MulticastFramesReceivedOK); 1425 MV88E6XXX_ETH_MAC_STAT_MAP(in_broadcasts, BroadcastFramesReceivedOK); 1426 1427#undef MV88E6XXX_ETH_MAC_STAT_MAP 1428 1429 mac_stats->stats.FramesTransmittedOK += mac_stats->stats.MulticastFramesXmittedOK; 1430 mac_stats->stats.FramesTransmittedOK += mac_stats->stats.BroadcastFramesXmittedOK; 1431 mac_stats->stats.FramesReceivedOK += mac_stats->stats.MulticastFramesReceivedOK; 1432 mac_stats->stats.FramesReceivedOK += mac_stats->stats.BroadcastFramesReceivedOK; 1433} 1434 1435static void mv88e6xxx_get_rmon_stats(struct dsa_switch *ds, int port, 1436 struct ethtool_rmon_stats *rmon_stats, 1437 const struct ethtool_rmon_hist_range **ranges) 1438{ 1439 static const struct ethtool_rmon_hist_range rmon_ranges[] = { 1440 { 64, 64 }, 1441 { 65, 127 }, 1442 { 128, 255 }, 1443 { 256, 511 }, 1444 { 512, 1023 }, 1445 { 1024, 65535 }, 1446 {} 1447 }; 1448 struct mv88e6xxx_chip *chip = ds->priv; 1449 int ret; 1450 1451 ret = mv88e6xxx_stats_snapshot(chip, port); 1452 if (ret < 0) 1453 return; 1454 1455#define MV88E6XXX_RMON_STAT_MAP(_id, _member) \ 1456 mv88e6xxx_stats_get_stat(chip, port, \ 1457 &mv88e6xxx_hw_stats[MV88E6XXX_HW_STAT_ID_ ## _id], \ 1458 &rmon_stats->stats._member) 1459 1460 MV88E6XXX_RMON_STAT_MAP(in_undersize, undersize_pkts); 1461 MV88E6XXX_RMON_STAT_MAP(in_oversize, oversize_pkts); 1462 MV88E6XXX_RMON_STAT_MAP(in_fragments, fragments); 1463 MV88E6XXX_RMON_STAT_MAP(in_jabber, jabbers); 1464 MV88E6XXX_RMON_STAT_MAP(hist_64bytes, hist[0]); 1465 MV88E6XXX_RMON_STAT_MAP(hist_65_127bytes, hist[1]); 1466 MV88E6XXX_RMON_STAT_MAP(hist_128_255bytes, hist[2]); 1467 MV88E6XXX_RMON_STAT_MAP(hist_256_511bytes, hist[3]); 1468 MV88E6XXX_RMON_STAT_MAP(hist_512_1023bytes, hist[4]); 1469 MV88E6XXX_RMON_STAT_MAP(hist_1024_max_bytes, hist[5]); 1470 1471#undef MV88E6XXX_RMON_STAT_MAP 1472 1473 *ranges = rmon_ranges; 1474} 1475 1476static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port) 1477{ 1478 struct mv88e6xxx_chip *chip = ds->priv; 1479 int len; 1480 1481 len = 32 * sizeof(u16); 1482 if (chip->info->ops->serdes_get_regs_len) 1483 len += chip->info->ops->serdes_get_regs_len(chip, port); 1484 1485 return len; 1486} 1487 1488static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, 1489 struct ethtool_regs *regs, void *_p) 1490{ 1491 struct mv88e6xxx_chip *chip = ds->priv; 1492 int err; 1493 u16 reg; 1494 u16 *p = _p; 1495 int i; 1496 1497 regs->version = chip->info->prod_num; 1498 1499 memset(p, 0xff, 32 * sizeof(u16)); 1500 1501 mv88e6xxx_reg_lock(chip); 1502 1503 for (i = 0; i < 32; i++) { 1504 1505 err = mv88e6xxx_port_read(chip, port, i, ®); 1506 if (!err) 1507 p[i] = reg; 1508 } 1509 1510 if (chip->info->ops->serdes_get_regs) 1511 chip->info->ops->serdes_get_regs(chip, port, &p[i]); 1512 1513 mv88e6xxx_reg_unlock(chip); 1514} 1515 1516static int mv88e6xxx_set_mac_eee(struct dsa_switch *ds, int port, 1517 struct ethtool_keee *e) 1518{ 1519 /* Nothing to do on the port's MAC */ 1520 return 0; 1521} 1522 1523/* Mask of the local ports allowed to receive frames from a given fabric port */ 1524static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port) 1525{ 1526 struct dsa_switch *ds = chip->ds; 1527 struct dsa_switch_tree *dst = ds->dst; 1528 struct dsa_port *dp, *other_dp; 1529 bool found = false; 1530 u16 pvlan; 1531 1532 /* dev is a physical switch */ 1533 if (dev <= dst->last_switch) { 1534 list_for_each_entry(dp, &dst->ports, list) { 1535 if (dp->ds->index == dev && dp->index == port) { 1536 /* dp might be a DSA link or a user port, so it 1537 * might or might not have a bridge. 1538 * Use the "found" variable for both cases. 1539 */ 1540 found = true; 1541 break; 1542 } 1543 } 1544 /* dev is a virtual bridge */ 1545 } else { 1546 list_for_each_entry(dp, &dst->ports, list) { 1547 unsigned int bridge_num = dsa_port_bridge_num_get(dp); 1548 1549 if (!bridge_num) 1550 continue; 1551 1552 if (bridge_num + dst->last_switch != dev) 1553 continue; 1554 1555 found = true; 1556 break; 1557 } 1558 } 1559 1560 /* Prevent frames from unknown switch or virtual bridge */ 1561 if (!found) 1562 return 0; 1563 1564 /* Frames from DSA links and CPU ports can egress any local port */ 1565 if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA) 1566 return mv88e6xxx_port_mask(chip); 1567 1568 pvlan = 0; 1569 1570 /* Frames from standalone user ports can only egress on the 1571 * upstream port. 1572 */ 1573 if (!dsa_port_bridge_dev_get(dp)) 1574 return BIT(dsa_switch_upstream_port(ds)); 1575 1576 /* Frames from bridged user ports can egress any local DSA 1577 * links and CPU ports, as well as any local member of their 1578 * bridge group. 1579 */ 1580 dsa_switch_for_each_port(other_dp, ds) 1581 if (other_dp->type == DSA_PORT_TYPE_CPU || 1582 other_dp->type == DSA_PORT_TYPE_DSA || 1583 dsa_port_bridge_same(dp, other_dp)) 1584 pvlan |= BIT(other_dp->index); 1585 1586 return pvlan; 1587} 1588 1589static int mv88e6xxx_port_vlan_map(struct mv88e6xxx_chip *chip, int port) 1590{ 1591 u16 output_ports = mv88e6xxx_port_vlan(chip, chip->ds->index, port); 1592 1593 /* prevent frames from going back out of the port they came in on */ 1594 output_ports &= ~BIT(port); 1595 1596 return mv88e6xxx_port_set_vlan_map(chip, port, output_ports); 1597} 1598 1599static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, 1600 u8 state) 1601{ 1602 struct mv88e6xxx_chip *chip = ds->priv; 1603 int err; 1604 1605 mv88e6xxx_reg_lock(chip); 1606 err = mv88e6xxx_port_set_state(chip, port, state); 1607 mv88e6xxx_reg_unlock(chip); 1608 1609 if (err) 1610 dev_err(ds->dev, "p%d: failed to update state\n", port); 1611} 1612 1613static int mv88e6xxx_pri_setup(struct mv88e6xxx_chip *chip) 1614{ 1615 int err; 1616 1617 if (chip->info->ops->ieee_pri_map) { 1618 err = chip->info->ops->ieee_pri_map(chip); 1619 if (err) 1620 return err; 1621 } 1622 1623 if (chip->info->ops->ip_pri_map) { 1624 err = chip->info->ops->ip_pri_map(chip); 1625 if (err) 1626 return err; 1627 } 1628 1629 return 0; 1630} 1631 1632static int mv88e6xxx_devmap_setup(struct mv88e6xxx_chip *chip) 1633{ 1634 struct dsa_switch *ds = chip->ds; 1635 int target, port; 1636 int err; 1637 1638 if (!chip->info->global2_addr) 1639 return 0; 1640 1641 /* Initialize the routing port to the 32 possible target devices */ 1642 for (target = 0; target < 32; target++) { 1643 port = dsa_routing_port(ds, target); 1644 if (port == ds->num_ports) 1645 port = 0x1f; 1646 1647 err = mv88e6xxx_g2_device_mapping_write(chip, target, port); 1648 if (err) 1649 return err; 1650 } 1651 1652 if (chip->info->ops->set_cascade_port) { 1653 port = MV88E6XXX_CASCADE_PORT_MULTIPLE; 1654 err = chip->info->ops->set_cascade_port(chip, port); 1655 if (err) 1656 return err; 1657 } 1658 1659 err = mv88e6xxx_g1_set_device_number(chip, chip->ds->index); 1660 if (err) 1661 return err; 1662 1663 return 0; 1664} 1665 1666static int mv88e6xxx_trunk_setup(struct mv88e6xxx_chip *chip) 1667{ 1668 /* Clear all trunk masks and mapping */ 1669 if (chip->info->global2_addr) 1670 return mv88e6xxx_g2_trunk_clear(chip); 1671 1672 return 0; 1673} 1674 1675static int mv88e6xxx_rmu_setup(struct mv88e6xxx_chip *chip) 1676{ 1677 if (chip->info->ops->rmu_disable) 1678 return chip->info->ops->rmu_disable(chip); 1679 1680 return 0; 1681} 1682 1683static int mv88e6xxx_pot_setup(struct mv88e6xxx_chip *chip) 1684{ 1685 if (chip->info->ops->pot_clear) 1686 return chip->info->ops->pot_clear(chip); 1687 1688 return 0; 1689} 1690 1691static int mv88e6xxx_rsvd2cpu_setup(struct mv88e6xxx_chip *chip) 1692{ 1693 if (chip->info->ops->mgmt_rsvd2cpu) 1694 return chip->info->ops->mgmt_rsvd2cpu(chip); 1695 1696 return 0; 1697} 1698 1699static int mv88e6xxx_atu_setup(struct mv88e6xxx_chip *chip) 1700{ 1701 int err; 1702 1703 err = mv88e6xxx_g1_atu_flush(chip, 0, true); 1704 if (err) 1705 return err; 1706 1707 /* The chips that have a "learn2all" bit in Global1, ATU 1708 * Control are precisely those whose port registers have a 1709 * Message Port bit in Port Control 1 and hence implement 1710 * ->port_setup_message_port. 1711 */ 1712 if (chip->info->ops->port_setup_message_port) { 1713 err = mv88e6xxx_g1_atu_set_learn2all(chip, true); 1714 if (err) 1715 return err; 1716 } 1717 1718 return mv88e6xxx_g1_atu_set_age_time(chip, 300000); 1719} 1720 1721static int mv88e6xxx_irl_setup(struct mv88e6xxx_chip *chip) 1722{ 1723 int port; 1724 int err; 1725 1726 if (!chip->info->ops->irl_init_all) 1727 return 0; 1728 1729 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { 1730 /* Disable ingress rate limiting by resetting all per port 1731 * ingress rate limit resources to their initial state. 1732 */ 1733 err = chip->info->ops->irl_init_all(chip, port); 1734 if (err) 1735 return err; 1736 } 1737 1738 return 0; 1739} 1740 1741static int mv88e6xxx_mac_setup(struct mv88e6xxx_chip *chip) 1742{ 1743 if (chip->info->ops->set_switch_mac) { 1744 u8 addr[ETH_ALEN]; 1745 1746 eth_random_addr(addr); 1747 1748 return chip->info->ops->set_switch_mac(chip, addr); 1749 } 1750 1751 return 0; 1752} 1753 1754static int mv88e6xxx_pvt_map(struct mv88e6xxx_chip *chip, int dev, int port) 1755{ 1756 struct dsa_switch_tree *dst = chip->ds->dst; 1757 struct dsa_switch *ds; 1758 struct dsa_port *dp; 1759 u16 pvlan = 0; 1760 1761 if (!mv88e6xxx_has_pvt(chip)) 1762 return 0; 1763 1764 /* Skip the local source device, which uses in-chip port VLAN */ 1765 if (dev != chip->ds->index) { 1766 pvlan = mv88e6xxx_port_vlan(chip, dev, port); 1767 1768 ds = dsa_switch_find(dst->index, dev); 1769 dp = ds ? dsa_to_port(ds, port) : NULL; 1770 if (dp && dp->lag) { 1771 /* As the PVT is used to limit flooding of 1772 * FORWARD frames, which use the LAG ID as the 1773 * source port, we must translate dev/port to 1774 * the special "LAG device" in the PVT, using 1775 * the LAG ID (one-based) as the port number 1776 * (zero-based). 1777 */ 1778 dev = MV88E6XXX_G2_PVT_ADDR_DEV_TRUNK; 1779 port = dsa_port_lag_id_get(dp) - 1; 1780 } 1781 } 1782 1783 return mv88e6xxx_g2_pvt_write(chip, dev, port, pvlan); 1784} 1785 1786static int mv88e6xxx_pvt_setup(struct mv88e6xxx_chip *chip) 1787{ 1788 int dev, port; 1789 int err; 1790 1791 if (!mv88e6xxx_has_pvt(chip)) 1792 return 0; 1793 1794 /* Clear 5 Bit Port for usage with Marvell Link Street devices: 1795 * use 4 bits for the Src_Port/Src_Trunk and 5 bits for the Src_Dev. 1796 */ 1797 err = mv88e6xxx_g2_misc_4_bit_port(chip); 1798 if (err) 1799 return err; 1800 1801 for (dev = 0; dev < MV88E6XXX_MAX_PVT_SWITCHES; ++dev) { 1802 for (port = 0; port < MV88E6XXX_MAX_PVT_PORTS; ++port) { 1803 err = mv88e6xxx_pvt_map(chip, dev, port); 1804 if (err) 1805 return err; 1806 } 1807 } 1808 1809 return 0; 1810} 1811 1812static int mv88e6xxx_port_fast_age_fid(struct mv88e6xxx_chip *chip, int port, 1813 u16 fid) 1814{ 1815 if (dsa_to_port(chip->ds, port)->lag) 1816 /* Hardware is incapable of fast-aging a LAG through a 1817 * regular ATU move operation. Until we have something 1818 * more fancy in place this is a no-op. 1819 */ 1820 return -EOPNOTSUPP; 1821 1822 return mv88e6xxx_g1_atu_remove(chip, fid, port, false); 1823} 1824 1825static void mv88e6xxx_port_fast_age(struct dsa_switch *ds, int port) 1826{ 1827 struct mv88e6xxx_chip *chip = ds->priv; 1828 int err; 1829 1830 mv88e6xxx_reg_lock(chip); 1831 err = mv88e6xxx_port_fast_age_fid(chip, port, 0); 1832 mv88e6xxx_reg_unlock(chip); 1833 1834 if (err) 1835 dev_err(chip->ds->dev, "p%d: failed to flush ATU: %d\n", 1836 port, err); 1837} 1838 1839static int mv88e6xxx_vtu_setup(struct mv88e6xxx_chip *chip) 1840{ 1841 if (!mv88e6xxx_max_vid(chip)) 1842 return 0; 1843 1844 return mv88e6xxx_g1_vtu_flush(chip); 1845} 1846 1847static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid, 1848 struct mv88e6xxx_vtu_entry *entry) 1849{ 1850 int err; 1851 1852 if (!chip->info->ops->vtu_getnext) 1853 return -EOPNOTSUPP; 1854 1855 memset(entry, 0, sizeof(*entry)); 1856 1857 entry->vid = vid ? vid - 1 : mv88e6xxx_max_vid(chip); 1858 entry->valid = false; 1859 1860 err = chip->info->ops->vtu_getnext(chip, entry); 1861 1862 if (entry->vid != vid) 1863 entry->valid = false; 1864 1865 return err; 1866} 1867 1868int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip, 1869 int (*cb)(struct mv88e6xxx_chip *chip, 1870 const struct mv88e6xxx_vtu_entry *entry, 1871 void *priv), 1872 void *priv) 1873{ 1874 struct mv88e6xxx_vtu_entry entry = { 1875 .vid = mv88e6xxx_max_vid(chip), 1876 .valid = false, 1877 }; 1878 int err; 1879 1880 if (!chip->info->ops->vtu_getnext) 1881 return -EOPNOTSUPP; 1882 1883 do { 1884 err = chip->info->ops->vtu_getnext(chip, &entry); 1885 if (err) 1886 return err; 1887 1888 if (!entry.valid) 1889 break; 1890 1891 err = cb(chip, &entry, priv); 1892 if (err) 1893 return err; 1894 } while (entry.vid < mv88e6xxx_max_vid(chip)); 1895 1896 return 0; 1897} 1898 1899static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip, 1900 struct mv88e6xxx_vtu_entry *entry) 1901{ 1902 if (!chip->info->ops->vtu_loadpurge) 1903 return -EOPNOTSUPP; 1904 1905 return chip->info->ops->vtu_loadpurge(chip, entry); 1906} 1907 1908static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid) 1909{ 1910 *fid = find_first_zero_bit(chip->fid_bitmap, MV88E6XXX_N_FID); 1911 if (unlikely(*fid >= mv88e6xxx_num_databases(chip))) 1912 return -ENOSPC; 1913 1914 /* Clear the database */ 1915 return mv88e6xxx_g1_atu_flush(chip, *fid, true); 1916} 1917 1918static int mv88e6xxx_stu_loadpurge(struct mv88e6xxx_chip *chip, 1919 struct mv88e6xxx_stu_entry *entry) 1920{ 1921 if (!chip->info->ops->stu_loadpurge) 1922 return -EOPNOTSUPP; 1923 1924 return chip->info->ops->stu_loadpurge(chip, entry); 1925} 1926 1927static int mv88e6xxx_stu_setup(struct mv88e6xxx_chip *chip) 1928{ 1929 struct mv88e6xxx_stu_entry stu = { 1930 .valid = true, 1931 .sid = 0 1932 }; 1933 1934 if (!mv88e6xxx_has_stu(chip)) 1935 return 0; 1936 1937 /* Make sure that SID 0 is always valid. This is used by VTU 1938 * entries that do not make use of the STU, e.g. when creating 1939 * a VLAN upper on a port that is also part of a VLAN 1940 * filtering bridge. 1941 */ 1942 return mv88e6xxx_stu_loadpurge(chip, &stu); 1943} 1944 1945static int mv88e6xxx_sid_get(struct mv88e6xxx_chip *chip, u8 *sid) 1946{ 1947 DECLARE_BITMAP(busy, MV88E6XXX_N_SID) = { 0 }; 1948 struct mv88e6xxx_mst *mst; 1949 1950 __set_bit(0, busy); 1951 1952 list_for_each_entry(mst, &chip->msts, node) 1953 __set_bit(mst->stu.sid, busy); 1954 1955 *sid = find_first_zero_bit(busy, MV88E6XXX_N_SID); 1956 1957 return (*sid >= mv88e6xxx_max_sid(chip)) ? -ENOSPC : 0; 1958} 1959 1960static int mv88e6xxx_mst_put(struct mv88e6xxx_chip *chip, u8 sid) 1961{ 1962 struct mv88e6xxx_mst *mst, *tmp; 1963 int err; 1964 1965 /* If the SID is zero, it is for a VLAN mapped to the default MSTI, 1966 * and mv88e6xxx_stu_setup() made sure it is always present, and thus, 1967 * should not be removed here. 1968 * 1969 * If the chip lacks STU support, numerically the "sid" variable will 1970 * happen to also be zero, but we don't want to rely on that fact, so 1971 * we explicitly test that first. In that case, there is also nothing 1972 * to do here. 1973 */ 1974 if (!mv88e6xxx_has_stu(chip) || !sid) 1975 return 0; 1976 1977 list_for_each_entry_safe(mst, tmp, &chip->msts, node) { 1978 if (mst->stu.sid != sid) 1979 continue; 1980 1981 if (!refcount_dec_and_test(&mst->refcnt)) 1982 return 0; 1983 1984 mst->stu.valid = false; 1985 err = mv88e6xxx_stu_loadpurge(chip, &mst->stu); 1986 if (err) { 1987 refcount_set(&mst->refcnt, 1); 1988 return err; 1989 } 1990 1991 list_del(&mst->node); 1992 kfree(mst); 1993 return 0; 1994 } 1995 1996 return -ENOENT; 1997} 1998 1999static int mv88e6xxx_mst_get(struct mv88e6xxx_chip *chip, struct net_device *br, 2000 u16 msti, u8 *sid) 2001{ 2002 struct mv88e6xxx_mst *mst; 2003 int err, i; 2004 2005 if (!mv88e6xxx_has_stu(chip)) { 2006 err = -EOPNOTSUPP; 2007 goto err; 2008 } 2009 2010 if (!msti) { 2011 *sid = 0; 2012 return 0; 2013 } 2014 2015 list_for_each_entry(mst, &chip->msts, node) { 2016 if (mst->br == br && mst->msti == msti) { 2017 refcount_inc(&mst->refcnt); 2018 *sid = mst->stu.sid; 2019 return 0; 2020 } 2021 } 2022 2023 err = mv88e6xxx_sid_get(chip, sid); 2024 if (err) 2025 goto err; 2026 2027 mst = kzalloc(sizeof(*mst), GFP_KERNEL); 2028 if (!mst) { 2029 err = -ENOMEM; 2030 goto err; 2031 } 2032 2033 INIT_LIST_HEAD(&mst->node); 2034 refcount_set(&mst->refcnt, 1); 2035 mst->br = br; 2036 mst->msti = msti; 2037 mst->stu.valid = true; 2038 mst->stu.sid = *sid; 2039 2040 /* The bridge starts out all ports in the disabled state. But 2041 * a STU state of disabled means to go by the port-global 2042 * state. So we set all user port's initial state to blocking, 2043 * to match the bridge's behavior. 2044 */ 2045 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) 2046 mst->stu.state[i] = dsa_is_user_port(chip->ds, i) ? 2047 MV88E6XXX_PORT_CTL0_STATE_BLOCKING : 2048 MV88E6XXX_PORT_CTL0_STATE_DISABLED; 2049 2050 err = mv88e6xxx_stu_loadpurge(chip, &mst->stu); 2051 if (err) 2052 goto err_free; 2053 2054 list_add_tail(&mst->node, &chip->msts); 2055 return 0; 2056 2057err_free: 2058 kfree(mst); 2059err: 2060 return err; 2061} 2062 2063static int mv88e6xxx_port_mst_state_set(struct dsa_switch *ds, int port, 2064 const struct switchdev_mst_state *st) 2065{ 2066 struct dsa_port *dp = dsa_to_port(ds, port); 2067 struct mv88e6xxx_chip *chip = ds->priv; 2068 struct mv88e6xxx_mst *mst; 2069 u8 state; 2070 int err; 2071 2072 if (!mv88e6xxx_has_stu(chip)) 2073 return -EOPNOTSUPP; 2074 2075 switch (st->state) { 2076 case BR_STATE_DISABLED: 2077 case BR_STATE_BLOCKING: 2078 case BR_STATE_LISTENING: 2079 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING; 2080 break; 2081 case BR_STATE_LEARNING: 2082 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING; 2083 break; 2084 case BR_STATE_FORWARDING: 2085 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING; 2086 break; 2087 default: 2088 return -EINVAL; 2089 } 2090 2091 list_for_each_entry(mst, &chip->msts, node) { 2092 if (mst->br == dsa_port_bridge_dev_get(dp) && 2093 mst->msti == st->msti) { 2094 if (mst->stu.state[port] == state) 2095 return 0; 2096 2097 mst->stu.state[port] = state; 2098 mv88e6xxx_reg_lock(chip); 2099 err = mv88e6xxx_stu_loadpurge(chip, &mst->stu); 2100 mv88e6xxx_reg_unlock(chip); 2101 return err; 2102 } 2103 } 2104 2105 return -ENOENT; 2106} 2107 2108static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port, 2109 u16 vid) 2110{ 2111 struct dsa_port *dp = dsa_to_port(ds, port), *other_dp; 2112 struct mv88e6xxx_chip *chip = ds->priv; 2113 struct mv88e6xxx_vtu_entry vlan; 2114 int err; 2115 2116 /* DSA and CPU ports have to be members of multiple vlans */ 2117 if (dsa_port_is_dsa(dp) || dsa_port_is_cpu(dp)) 2118 return 0; 2119 2120 err = mv88e6xxx_vtu_get(chip, vid, &vlan); 2121 if (err) 2122 return err; 2123 2124 if (!vlan.valid) 2125 return 0; 2126 2127 dsa_switch_for_each_user_port(other_dp, ds) { 2128 struct net_device *other_br; 2129 2130 if (vlan.member[other_dp->index] == 2131 MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER) 2132 continue; 2133 2134 if (dsa_port_bridge_same(dp, other_dp)) 2135 break; /* same bridge, check next VLAN */ 2136 2137 other_br = dsa_port_bridge_dev_get(other_dp); 2138 if (!other_br) 2139 continue; 2140 2141 dev_err(ds->dev, "p%d: hw VLAN %d already used by port %d in %s\n", 2142 port, vlan.vid, other_dp->index, netdev_name(other_br)); 2143 return -EOPNOTSUPP; 2144 } 2145 2146 return 0; 2147} 2148 2149static int mv88e6xxx_port_commit_pvid(struct mv88e6xxx_chip *chip, int port) 2150{ 2151 struct dsa_port *dp = dsa_to_port(chip->ds, port); 2152 struct net_device *br = dsa_port_bridge_dev_get(dp); 2153 struct mv88e6xxx_port *p = &chip->ports[port]; 2154 u16 pvid = MV88E6XXX_VID_STANDALONE; 2155 bool drop_untagged = false; 2156 int err; 2157 2158 if (br) { 2159 if (br_vlan_enabled(br)) { 2160 pvid = p->bridge_pvid.vid; 2161 drop_untagged = !p->bridge_pvid.valid; 2162 } else { 2163 pvid = MV88E6XXX_VID_BRIDGED; 2164 } 2165 } 2166 2167 err = mv88e6xxx_port_set_pvid(chip, port, pvid); 2168 if (err) 2169 return err; 2170 2171 return mv88e6xxx_port_drop_untagged(chip, port, drop_untagged); 2172} 2173 2174static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port, 2175 bool vlan_filtering, 2176 struct netlink_ext_ack *extack) 2177{ 2178 struct mv88e6xxx_chip *chip = ds->priv; 2179 u16 mode = vlan_filtering ? MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE : 2180 MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED; 2181 int err; 2182 2183 if (!mv88e6xxx_max_vid(chip)) 2184 return -EOPNOTSUPP; 2185 2186 mv88e6xxx_reg_lock(chip); 2187 2188 err = mv88e6xxx_port_set_8021q_mode(chip, port, mode); 2189 if (err) 2190 goto unlock; 2191 2192 err = mv88e6xxx_port_commit_pvid(chip, port); 2193 if (err) 2194 goto unlock; 2195 2196unlock: 2197 mv88e6xxx_reg_unlock(chip); 2198 2199 return err; 2200} 2201 2202static int 2203mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, 2204 const struct switchdev_obj_port_vlan *vlan) 2205{ 2206 struct mv88e6xxx_chip *chip = ds->priv; 2207 int err; 2208 2209 if (!mv88e6xxx_max_vid(chip)) 2210 return -EOPNOTSUPP; 2211 2212 /* If the requested port doesn't belong to the same bridge as the VLAN 2213 * members, do not support it (yet) and fallback to software VLAN. 2214 */ 2215 mv88e6xxx_reg_lock(chip); 2216 err = mv88e6xxx_port_check_hw_vlan(ds, port, vlan->vid); 2217 mv88e6xxx_reg_unlock(chip); 2218 2219 return err; 2220} 2221 2222static int mv88e6xxx_port_db_get(struct mv88e6xxx_chip *chip, 2223 const unsigned char *addr, u16 vid, 2224 u16 *fid, struct mv88e6xxx_atu_entry *entry) 2225{ 2226 struct mv88e6xxx_vtu_entry vlan; 2227 int err; 2228 2229 /* Ports have two private address databases: one for when the port is 2230 * standalone and one for when the port is under a bridge and the 2231 * 802.1Q mode is disabled. When the port is standalone, DSA wants its 2232 * address database to remain 100% empty, so we never load an ATU entry 2233 * into a standalone port's database. Therefore, translate the null 2234 * VLAN ID into the port's database used for VLAN-unaware bridging. 2235 */ 2236 if (vid == 0) { 2237 *fid = MV88E6XXX_FID_BRIDGED; 2238 } else { 2239 err = mv88e6xxx_vtu_get(chip, vid, &vlan); 2240 if (err) 2241 return err; 2242 2243 /* switchdev expects -EOPNOTSUPP to honor software VLANs */ 2244 if (!vlan.valid) 2245 return -EOPNOTSUPP; 2246 2247 *fid = vlan.fid; 2248 } 2249 2250 entry->state = 0; 2251 ether_addr_copy(entry->mac, addr); 2252 eth_addr_dec(entry->mac); 2253 2254 return mv88e6xxx_g1_atu_getnext(chip, *fid, entry); 2255} 2256 2257static bool mv88e6xxx_port_db_find(struct mv88e6xxx_chip *chip, 2258 const unsigned char *addr, u16 vid) 2259{ 2260 struct mv88e6xxx_atu_entry entry; 2261 u16 fid; 2262 int err; 2263 2264 err = mv88e6xxx_port_db_get(chip, addr, vid, &fid, &entry); 2265 if (err) 2266 return false; 2267 2268 return entry.state && ether_addr_equal(entry.mac, addr); 2269} 2270 2271static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port, 2272 const unsigned char *addr, u16 vid, 2273 u8 state) 2274{ 2275 struct mv88e6xxx_atu_entry entry; 2276 u16 fid; 2277 int err; 2278 2279 err = mv88e6xxx_port_db_get(chip, addr, vid, &fid, &entry); 2280 if (err) 2281 return err; 2282 2283 /* Initialize a fresh ATU entry if it isn't found */ 2284 if (!entry.state || !ether_addr_equal(entry.mac, addr)) { 2285 memset(&entry, 0, sizeof(entry)); 2286 ether_addr_copy(entry.mac, addr); 2287 } 2288 2289 /* Purge the ATU entry only if no port is using it anymore */ 2290 if (!state) { 2291 entry.portvec &= ~BIT(port); 2292 if (!entry.portvec) 2293 entry.state = 0; 2294 } else { 2295 if (state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC) 2296 entry.portvec = BIT(port); 2297 else 2298 entry.portvec |= BIT(port); 2299 2300 entry.state = state; 2301 } 2302 2303 return mv88e6xxx_g1_atu_loadpurge(chip, fid, &entry); 2304} 2305 2306static int mv88e6xxx_policy_apply(struct mv88e6xxx_chip *chip, int port, 2307 const struct mv88e6xxx_policy *policy) 2308{ 2309 enum mv88e6xxx_policy_mapping mapping = policy->mapping; 2310 enum mv88e6xxx_policy_action action = policy->action; 2311 const u8 *addr = policy->addr; 2312 u16 vid = policy->vid; 2313 u8 state; 2314 int err; 2315 int id; 2316 2317 if (!chip->info->ops->port_set_policy) 2318 return -EOPNOTSUPP; 2319 2320 switch (mapping) { 2321 case MV88E6XXX_POLICY_MAPPING_DA: 2322 case MV88E6XXX_POLICY_MAPPING_SA: 2323 if (action == MV88E6XXX_POLICY_ACTION_NORMAL) 2324 state = 0; /* Dissociate the port and address */ 2325 else if (action == MV88E6XXX_POLICY_ACTION_DISCARD && 2326 is_multicast_ether_addr(addr)) 2327 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_POLICY; 2328 else if (action == MV88E6XXX_POLICY_ACTION_DISCARD && 2329 is_unicast_ether_addr(addr)) 2330 state = MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_POLICY; 2331 else 2332 return -EOPNOTSUPP; 2333 2334 err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, 2335 state); 2336 if (err) 2337 return err; 2338 break; 2339 default: 2340 return -EOPNOTSUPP; 2341 } 2342 2343 /* Skip the port's policy clearing if the mapping is still in use */ 2344 if (action == MV88E6XXX_POLICY_ACTION_NORMAL) 2345 idr_for_each_entry(&chip->policies, policy, id) 2346 if (policy->port == port && 2347 policy->mapping == mapping && 2348 policy->action != action) 2349 return 0; 2350 2351 return chip->info->ops->port_set_policy(chip, port, mapping, action); 2352} 2353 2354static int mv88e6xxx_policy_insert(struct mv88e6xxx_chip *chip, int port, 2355 struct ethtool_rx_flow_spec *fs) 2356{ 2357 struct ethhdr *mac_entry = &fs->h_u.ether_spec; 2358 struct ethhdr *mac_mask = &fs->m_u.ether_spec; 2359 enum mv88e6xxx_policy_mapping mapping; 2360 enum mv88e6xxx_policy_action action; 2361 struct mv88e6xxx_policy *policy; 2362 u16 vid = 0; 2363 u8 *addr; 2364 int err; 2365 int id; 2366 2367 if (fs->location != RX_CLS_LOC_ANY) 2368 return -EINVAL; 2369 2370 if (fs->ring_cookie == RX_CLS_FLOW_DISC) 2371 action = MV88E6XXX_POLICY_ACTION_DISCARD; 2372 else 2373 return -EOPNOTSUPP; 2374 2375 switch (fs->flow_type & ~FLOW_EXT) { 2376 case ETHER_FLOW: 2377 if (!is_zero_ether_addr(mac_mask->h_dest) && 2378 is_zero_ether_addr(mac_mask->h_source)) { 2379 mapping = MV88E6XXX_POLICY_MAPPING_DA; 2380 addr = mac_entry->h_dest; 2381 } else if (is_zero_ether_addr(mac_mask->h_dest) && 2382 !is_zero_ether_addr(mac_mask->h_source)) { 2383 mapping = MV88E6XXX_POLICY_MAPPING_SA; 2384 addr = mac_entry->h_source; 2385 } else { 2386 /* Cannot support DA and SA mapping in the same rule */ 2387 return -EOPNOTSUPP; 2388 } 2389 break; 2390 default: 2391 return -EOPNOTSUPP; 2392 } 2393 2394 if ((fs->flow_type & FLOW_EXT) && fs->m_ext.vlan_tci) { 2395 if (fs->m_ext.vlan_tci != htons(0xffff)) 2396 return -EOPNOTSUPP; 2397 vid = be16_to_cpu(fs->h_ext.vlan_tci) & VLAN_VID_MASK; 2398 } 2399 2400 idr_for_each_entry(&chip->policies, policy, id) { 2401 if (policy->port == port && policy->mapping == mapping && 2402 policy->action == action && policy->vid == vid && 2403 ether_addr_equal(policy->addr, addr)) 2404 return -EEXIST; 2405 } 2406 2407 policy = devm_kzalloc(chip->dev, sizeof(*policy), GFP_KERNEL); 2408 if (!policy) 2409 return -ENOMEM; 2410 2411 fs->location = 0; 2412 err = idr_alloc_u32(&chip->policies, policy, &fs->location, 0xffffffff, 2413 GFP_KERNEL); 2414 if (err) { 2415 devm_kfree(chip->dev, policy); 2416 return err; 2417 } 2418 2419 memcpy(&policy->fs, fs, sizeof(*fs)); 2420 ether_addr_copy(policy->addr, addr); 2421 policy->mapping = mapping; 2422 policy->action = action; 2423 policy->port = port; 2424 policy->vid = vid; 2425 2426 err = mv88e6xxx_policy_apply(chip, port, policy); 2427 if (err) { 2428 idr_remove(&chip->policies, fs->location); 2429 devm_kfree(chip->dev, policy); 2430 return err; 2431 } 2432 2433 return 0; 2434} 2435 2436static int mv88e6xxx_get_rxnfc(struct dsa_switch *ds, int port, 2437 struct ethtool_rxnfc *rxnfc, u32 *rule_locs) 2438{ 2439 struct ethtool_rx_flow_spec *fs = &rxnfc->fs; 2440 struct mv88e6xxx_chip *chip = ds->priv; 2441 struct mv88e6xxx_policy *policy; 2442 int err; 2443 int id; 2444 2445 mv88e6xxx_reg_lock(chip); 2446 2447 switch (rxnfc->cmd) { 2448 case ETHTOOL_GRXCLSRLCNT: 2449 rxnfc->data = 0; 2450 rxnfc->data |= RX_CLS_LOC_SPECIAL; 2451 rxnfc->rule_cnt = 0; 2452 idr_for_each_entry(&chip->policies, policy, id) 2453 if (policy->port == port) 2454 rxnfc->rule_cnt++; 2455 err = 0; 2456 break; 2457 case ETHTOOL_GRXCLSRULE: 2458 err = -ENOENT; 2459 policy = idr_find(&chip->policies, fs->location); 2460 if (policy) { 2461 memcpy(fs, &policy->fs, sizeof(*fs)); 2462 err = 0; 2463 } 2464 break; 2465 case ETHTOOL_GRXCLSRLALL: 2466 rxnfc->data = 0; 2467 rxnfc->rule_cnt = 0; 2468 idr_for_each_entry(&chip->policies, policy, id) 2469 if (policy->port == port) 2470 rule_locs[rxnfc->rule_cnt++] = id; 2471 err = 0; 2472 break; 2473 default: 2474 err = -EOPNOTSUPP; 2475 break; 2476 } 2477 2478 mv88e6xxx_reg_unlock(chip); 2479 2480 return err; 2481} 2482 2483static int mv88e6xxx_set_rxnfc(struct dsa_switch *ds, int port, 2484 struct ethtool_rxnfc *rxnfc) 2485{ 2486 struct ethtool_rx_flow_spec *fs = &rxnfc->fs; 2487 struct mv88e6xxx_chip *chip = ds->priv; 2488 struct mv88e6xxx_policy *policy; 2489 int err; 2490 2491 mv88e6xxx_reg_lock(chip); 2492 2493 switch (rxnfc->cmd) { 2494 case ETHTOOL_SRXCLSRLINS: 2495 err = mv88e6xxx_policy_insert(chip, port, fs); 2496 break; 2497 case ETHTOOL_SRXCLSRLDEL: 2498 err = -ENOENT; 2499 policy = idr_remove(&chip->policies, fs->location); 2500 if (policy) { 2501 policy->action = MV88E6XXX_POLICY_ACTION_NORMAL; 2502 err = mv88e6xxx_policy_apply(chip, port, policy); 2503 devm_kfree(chip->dev, policy); 2504 } 2505 break; 2506 default: 2507 err = -EOPNOTSUPP; 2508 break; 2509 } 2510 2511 mv88e6xxx_reg_unlock(chip); 2512 2513 return err; 2514} 2515 2516static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port, 2517 u16 vid) 2518{ 2519 u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC; 2520 u8 broadcast[ETH_ALEN]; 2521 2522 eth_broadcast_addr(broadcast); 2523 2524 return mv88e6xxx_port_db_load_purge(chip, port, broadcast, vid, state); 2525} 2526 2527static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid) 2528{ 2529 int port; 2530 int err; 2531 2532 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { 2533 struct dsa_port *dp = dsa_to_port(chip->ds, port); 2534 struct net_device *brport; 2535 2536 if (dsa_is_unused_port(chip->ds, port)) 2537 continue; 2538 2539 brport = dsa_port_to_bridge_port(dp); 2540 if (brport && !br_port_flag_is_set(brport, BR_BCAST_FLOOD)) 2541 /* Skip bridged user ports where broadcast 2542 * flooding is disabled. 2543 */ 2544 continue; 2545 2546 err = mv88e6xxx_port_add_broadcast(chip, port, vid); 2547 if (err) 2548 return err; 2549 } 2550 2551 return 0; 2552} 2553 2554struct mv88e6xxx_port_broadcast_sync_ctx { 2555 int port; 2556 bool flood; 2557}; 2558 2559static int 2560mv88e6xxx_port_broadcast_sync_vlan(struct mv88e6xxx_chip *chip, 2561 const struct mv88e6xxx_vtu_entry *vlan, 2562 void *_ctx) 2563{ 2564 struct mv88e6xxx_port_broadcast_sync_ctx *ctx = _ctx; 2565 u8 broadcast[ETH_ALEN]; 2566 u8 state; 2567 2568 if (ctx->flood) 2569 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC; 2570 else 2571 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_UNUSED; 2572 2573 eth_broadcast_addr(broadcast); 2574 2575 return mv88e6xxx_port_db_load_purge(chip, ctx->port, broadcast, 2576 vlan->vid, state); 2577} 2578 2579static int mv88e6xxx_port_broadcast_sync(struct mv88e6xxx_chip *chip, int port, 2580 bool flood) 2581{ 2582 struct mv88e6xxx_port_broadcast_sync_ctx ctx = { 2583 .port = port, 2584 .flood = flood, 2585 }; 2586 struct mv88e6xxx_vtu_entry vid0 = { 2587 .vid = 0, 2588 }; 2589 int err; 2590 2591 /* Update the port's private database... */ 2592 err = mv88e6xxx_port_broadcast_sync_vlan(chip, &vid0, &ctx); 2593 if (err) 2594 return err; 2595 2596 /* ...and the database for all VLANs. */ 2597 return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_broadcast_sync_vlan, 2598 &ctx); 2599} 2600 2601static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port, 2602 u16 vid, u8 member, bool warn) 2603{ 2604 const u8 non_member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER; 2605 struct mv88e6xxx_vtu_entry vlan; 2606 int i, err; 2607 2608 err = mv88e6xxx_vtu_get(chip, vid, &vlan); 2609 if (err) 2610 return err; 2611 2612 if (!vlan.valid) { 2613 memset(&vlan, 0, sizeof(vlan)); 2614 2615 if (vid == MV88E6XXX_VID_STANDALONE) 2616 vlan.policy = true; 2617 2618 err = mv88e6xxx_atu_new(chip, &vlan.fid); 2619 if (err) 2620 return err; 2621 2622 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) 2623 if (i == port) 2624 vlan.member[i] = member; 2625 else 2626 vlan.member[i] = non_member; 2627 2628 vlan.vid = vid; 2629 vlan.valid = true; 2630 2631 err = mv88e6xxx_vtu_loadpurge(chip, &vlan); 2632 if (err) 2633 return err; 2634 2635 err = mv88e6xxx_broadcast_setup(chip, vlan.vid); 2636 if (err) 2637 return err; 2638 } else if (vlan.member[port] != member) { 2639 vlan.member[port] = member; 2640 2641 err = mv88e6xxx_vtu_loadpurge(chip, &vlan); 2642 if (err) 2643 return err; 2644 } else if (warn) { 2645 dev_info(chip->dev, "p%d: already a member of VLAN %d\n", 2646 port, vid); 2647 } 2648 2649 /* Record FID used in SW FID map */ 2650 bitmap_set(chip->fid_bitmap, vlan.fid, 1); 2651 2652 return 0; 2653} 2654 2655static int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, 2656 const struct switchdev_obj_port_vlan *vlan, 2657 struct netlink_ext_ack *extack) 2658{ 2659 struct mv88e6xxx_chip *chip = ds->priv; 2660 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; 2661 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; 2662 struct mv88e6xxx_port *p = &chip->ports[port]; 2663 bool warn; 2664 u8 member; 2665 int err; 2666 2667 if (!vlan->vid) 2668 return 0; 2669 2670 err = mv88e6xxx_port_vlan_prepare(ds, port, vlan); 2671 if (err) 2672 return err; 2673 2674 if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port)) 2675 member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED; 2676 else if (untagged) 2677 member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNTAGGED; 2678 else 2679 member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_TAGGED; 2680 2681 /* net/dsa/user.c will call dsa_port_vlan_add() for the affected port 2682 * and then the CPU port. Do not warn for duplicates for the CPU port. 2683 */ 2684 warn = !dsa_is_cpu_port(ds, port) && !dsa_is_dsa_port(ds, port); 2685 2686 mv88e6xxx_reg_lock(chip); 2687 2688 err = mv88e6xxx_port_vlan_join(chip, port, vlan->vid, member, warn); 2689 if (err) { 2690 dev_err(ds->dev, "p%d: failed to add VLAN %d%c\n", port, 2691 vlan->vid, untagged ? 'u' : 't'); 2692 goto out; 2693 } 2694 2695 if (pvid) { 2696 p->bridge_pvid.vid = vlan->vid; 2697 p->bridge_pvid.valid = true; 2698 2699 err = mv88e6xxx_port_commit_pvid(chip, port); 2700 if (err) 2701 goto out; 2702 } else if (vlan->vid && p->bridge_pvid.vid == vlan->vid) { 2703 /* The old pvid was reinstalled as a non-pvid VLAN */ 2704 p->bridge_pvid.valid = false; 2705 2706 err = mv88e6xxx_port_commit_pvid(chip, port); 2707 if (err) 2708 goto out; 2709 } 2710 2711out: 2712 mv88e6xxx_reg_unlock(chip); 2713 2714 return err; 2715} 2716 2717static int mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip *chip, 2718 int port, u16 vid) 2719{ 2720 struct mv88e6xxx_vtu_entry vlan; 2721 int i, err; 2722 2723 if (!vid) 2724 return 0; 2725 2726 err = mv88e6xxx_vtu_get(chip, vid, &vlan); 2727 if (err) 2728 return err; 2729 2730 /* If the VLAN doesn't exist in hardware or the port isn't a member, 2731 * tell switchdev that this VLAN is likely handled in software. 2732 */ 2733 if (!vlan.valid || 2734 vlan.member[port] == MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER) 2735 return -EOPNOTSUPP; 2736 2737 vlan.member[port] = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER; 2738 2739 /* keep the VLAN unless all ports are excluded */ 2740 vlan.valid = false; 2741 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { 2742 if (vlan.member[i] != 2743 MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER) { 2744 vlan.valid = true; 2745 break; 2746 } 2747 } 2748 2749 err = mv88e6xxx_vtu_loadpurge(chip, &vlan); 2750 if (err) 2751 return err; 2752 2753 if (!vlan.valid) { 2754 err = mv88e6xxx_mst_put(chip, vlan.sid); 2755 if (err) 2756 return err; 2757 2758 /* Record FID freed in SW FID map */ 2759 bitmap_clear(chip->fid_bitmap, vlan.fid, 1); 2760 } 2761 2762 return mv88e6xxx_g1_atu_remove(chip, vlan.fid, port, false); 2763} 2764 2765static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, 2766 const struct switchdev_obj_port_vlan *vlan) 2767{ 2768 struct mv88e6xxx_chip *chip = ds->priv; 2769 struct mv88e6xxx_port *p = &chip->ports[port]; 2770 int err = 0; 2771 u16 pvid; 2772 2773 if (!mv88e6xxx_max_vid(chip)) 2774 return -EOPNOTSUPP; 2775 2776 /* The ATU removal procedure needs the FID to be mapped in the VTU, 2777 * but FDB deletion runs concurrently with VLAN deletion. Flush the DSA 2778 * switchdev workqueue to ensure that all FDB entries are deleted 2779 * before we remove the VLAN. 2780 */ 2781 dsa_flush_workqueue(); 2782 2783 mv88e6xxx_reg_lock(chip); 2784 2785 err = mv88e6xxx_port_get_pvid(chip, port, &pvid); 2786 if (err) 2787 goto unlock; 2788 2789 err = mv88e6xxx_port_vlan_leave(chip, port, vlan->vid); 2790 if (err) 2791 goto unlock; 2792 2793 if (vlan->vid == pvid) { 2794 p->bridge_pvid.valid = false; 2795 2796 err = mv88e6xxx_port_commit_pvid(chip, port); 2797 if (err) 2798 goto unlock; 2799 } 2800 2801unlock: 2802 mv88e6xxx_reg_unlock(chip); 2803 2804 return err; 2805} 2806 2807static int mv88e6xxx_port_vlan_fast_age(struct dsa_switch *ds, int port, u16 vid) 2808{ 2809 struct mv88e6xxx_chip *chip = ds->priv; 2810 struct mv88e6xxx_vtu_entry vlan; 2811 int err; 2812 2813 mv88e6xxx_reg_lock(chip); 2814 2815 err = mv88e6xxx_vtu_get(chip, vid, &vlan); 2816 if (err) 2817 goto unlock; 2818 2819 err = mv88e6xxx_port_fast_age_fid(chip, port, vlan.fid); 2820 2821unlock: 2822 mv88e6xxx_reg_unlock(chip); 2823 2824 return err; 2825} 2826 2827static int mv88e6xxx_vlan_msti_set(struct dsa_switch *ds, 2828 struct dsa_bridge bridge, 2829 const struct switchdev_vlan_msti *msti) 2830{ 2831 struct mv88e6xxx_chip *chip = ds->priv; 2832 struct mv88e6xxx_vtu_entry vlan; 2833 u8 old_sid, new_sid; 2834 int err; 2835 2836 if (!mv88e6xxx_has_stu(chip)) 2837 return -EOPNOTSUPP; 2838 2839 mv88e6xxx_reg_lock(chip); 2840 2841 err = mv88e6xxx_vtu_get(chip, msti->vid, &vlan); 2842 if (err) 2843 goto unlock; 2844 2845 if (!vlan.valid) { 2846 err = -EINVAL; 2847 goto unlock; 2848 } 2849 2850 old_sid = vlan.sid; 2851 2852 err = mv88e6xxx_mst_get(chip, bridge.dev, msti->msti, &new_sid); 2853 if (err) 2854 goto unlock; 2855 2856 if (new_sid != old_sid) { 2857 vlan.sid = new_sid; 2858 2859 err = mv88e6xxx_vtu_loadpurge(chip, &vlan); 2860 if (err) { 2861 mv88e6xxx_mst_put(chip, new_sid); 2862 goto unlock; 2863 } 2864 } 2865 2866 err = mv88e6xxx_mst_put(chip, old_sid); 2867 2868unlock: 2869 mv88e6xxx_reg_unlock(chip); 2870 return err; 2871} 2872 2873static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port, 2874 const unsigned char *addr, u16 vid, 2875 struct dsa_db db) 2876{ 2877 struct mv88e6xxx_chip *chip = ds->priv; 2878 int err; 2879 2880 mv88e6xxx_reg_lock(chip); 2881 err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, 2882 MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC); 2883 if (err) 2884 goto out; 2885 2886 if (!mv88e6xxx_port_db_find(chip, addr, vid)) 2887 err = -ENOSPC; 2888 2889out: 2890 mv88e6xxx_reg_unlock(chip); 2891 2892 return err; 2893} 2894 2895static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, 2896 const unsigned char *addr, u16 vid, 2897 struct dsa_db db) 2898{ 2899 struct mv88e6xxx_chip *chip = ds->priv; 2900 int err; 2901 2902 mv88e6xxx_reg_lock(chip); 2903 err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, 0); 2904 mv88e6xxx_reg_unlock(chip); 2905 2906 return err; 2907} 2908 2909static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip, 2910 u16 fid, u16 vid, int port, 2911 dsa_fdb_dump_cb_t *cb, void *data) 2912{ 2913 struct mv88e6xxx_atu_entry addr; 2914 bool is_static; 2915 int err; 2916 2917 addr.state = 0; 2918 eth_broadcast_addr(addr.mac); 2919 2920 do { 2921 err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr); 2922 if (err) 2923 return err; 2924 2925 if (!addr.state) 2926 break; 2927 2928 if (addr.trunk || (addr.portvec & BIT(port)) == 0) 2929 continue; 2930 2931 if (!is_unicast_ether_addr(addr.mac)) 2932 continue; 2933 2934 is_static = (addr.state == 2935 MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC); 2936 err = cb(addr.mac, vid, is_static, data); 2937 if (err) 2938 return err; 2939 } while (!is_broadcast_ether_addr(addr.mac)); 2940 2941 return err; 2942} 2943 2944struct mv88e6xxx_port_db_dump_vlan_ctx { 2945 int port; 2946 dsa_fdb_dump_cb_t *cb; 2947 void *data; 2948}; 2949 2950static int mv88e6xxx_port_db_dump_vlan(struct mv88e6xxx_chip *chip, 2951 const struct mv88e6xxx_vtu_entry *entry, 2952 void *_data) 2953{ 2954 struct mv88e6xxx_port_db_dump_vlan_ctx *ctx = _data; 2955 2956 return mv88e6xxx_port_db_dump_fid(chip, entry->fid, entry->vid, 2957 ctx->port, ctx->cb, ctx->data); 2958} 2959 2960static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port, 2961 dsa_fdb_dump_cb_t *cb, void *data) 2962{ 2963 struct mv88e6xxx_port_db_dump_vlan_ctx ctx = { 2964 .port = port, 2965 .cb = cb, 2966 .data = data, 2967 }; 2968 u16 fid; 2969 int err; 2970 2971 /* Dump port's default Filtering Information Database (VLAN ID 0) */ 2972 err = mv88e6xxx_port_get_fid(chip, port, &fid); 2973 if (err) 2974 return err; 2975 2976 err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, cb, data); 2977 if (err) 2978 return err; 2979 2980 return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_db_dump_vlan, &ctx); 2981} 2982 2983static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port, 2984 dsa_fdb_dump_cb_t *cb, void *data) 2985{ 2986 struct mv88e6xxx_chip *chip = ds->priv; 2987 int err; 2988 2989 mv88e6xxx_reg_lock(chip); 2990 err = mv88e6xxx_port_db_dump(chip, port, cb, data); 2991 mv88e6xxx_reg_unlock(chip); 2992 2993 return err; 2994} 2995 2996static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip, 2997 struct dsa_bridge bridge) 2998{ 2999 struct dsa_switch *ds = chip->ds; 3000 struct dsa_switch_tree *dst = ds->dst; 3001 struct dsa_port *dp; 3002 int err; 3003 3004 list_for_each_entry(dp, &dst->ports, list) { 3005 if (dsa_port_offloads_bridge(dp, &bridge)) { 3006 if (dp->ds == ds) { 3007 /* This is a local bridge group member, 3008 * remap its Port VLAN Map. 3009 */ 3010 err = mv88e6xxx_port_vlan_map(chip, dp->index); 3011 if (err) 3012 return err; 3013 } else { 3014 /* This is an external bridge group member, 3015 * remap its cross-chip Port VLAN Table entry. 3016 */ 3017 err = mv88e6xxx_pvt_map(chip, dp->ds->index, 3018 dp->index); 3019 if (err) 3020 return err; 3021 } 3022 } 3023 } 3024 3025 return 0; 3026} 3027 3028/* Treat the software bridge as a virtual single-port switch behind the 3029 * CPU and map in the PVT. First dst->last_switch elements are taken by 3030 * physical switches, so start from beyond that range. 3031 */ 3032static int mv88e6xxx_map_virtual_bridge_to_pvt(struct dsa_switch *ds, 3033 unsigned int bridge_num) 3034{ 3035 u8 dev = bridge_num + ds->dst->last_switch; 3036 struct mv88e6xxx_chip *chip = ds->priv; 3037 3038 return mv88e6xxx_pvt_map(chip, dev, 0); 3039} 3040 3041static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, 3042 struct dsa_bridge bridge, 3043 bool *tx_fwd_offload, 3044 struct netlink_ext_ack *extack) 3045{ 3046 struct mv88e6xxx_chip *chip = ds->priv; 3047 int err; 3048 3049 mv88e6xxx_reg_lock(chip); 3050 3051 err = mv88e6xxx_bridge_map(chip, bridge); 3052 if (err) 3053 goto unlock; 3054 3055 err = mv88e6xxx_port_set_map_da(chip, port, true); 3056 if (err) 3057 goto unlock; 3058 3059 err = mv88e6xxx_port_commit_pvid(chip, port); 3060 if (err) 3061 goto unlock; 3062 3063 if (mv88e6xxx_has_pvt(chip)) { 3064 err = mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num); 3065 if (err) 3066 goto unlock; 3067 3068 *tx_fwd_offload = true; 3069 } 3070 3071unlock: 3072 mv88e6xxx_reg_unlock(chip); 3073 3074 return err; 3075} 3076 3077static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, 3078 struct dsa_bridge bridge) 3079{ 3080 struct mv88e6xxx_chip *chip = ds->priv; 3081 int err; 3082 3083 mv88e6xxx_reg_lock(chip); 3084 3085 if (bridge.tx_fwd_offload && 3086 mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num)) 3087 dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n"); 3088 3089 if (mv88e6xxx_bridge_map(chip, bridge) || 3090 mv88e6xxx_port_vlan_map(chip, port)) 3091 dev_err(ds->dev, "failed to remap in-chip Port VLAN\n"); 3092 3093 err = mv88e6xxx_port_set_map_da(chip, port, false); 3094 if (err) 3095 dev_err(ds->dev, 3096 "port %d failed to restore map-DA: %pe\n", 3097 port, ERR_PTR(err)); 3098 3099 err = mv88e6xxx_port_commit_pvid(chip, port); 3100 if (err) 3101 dev_err(ds->dev, 3102 "port %d failed to restore standalone pvid: %pe\n", 3103 port, ERR_PTR(err)); 3104 3105 mv88e6xxx_reg_unlock(chip); 3106} 3107 3108static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds, 3109 int tree_index, int sw_index, 3110 int port, struct dsa_bridge bridge, 3111 struct netlink_ext_ack *extack) 3112{ 3113 struct mv88e6xxx_chip *chip = ds->priv; 3114 int err; 3115 3116 if (tree_index != ds->dst->index) 3117 return 0; 3118 3119 mv88e6xxx_reg_lock(chip); 3120 err = mv88e6xxx_pvt_map(chip, sw_index, port); 3121 err = err ? : mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num); 3122 mv88e6xxx_reg_unlock(chip); 3123 3124 return err; 3125} 3126 3127static void mv88e6xxx_crosschip_bridge_leave(struct dsa_switch *ds, 3128 int tree_index, int sw_index, 3129 int port, struct dsa_bridge bridge) 3130{ 3131 struct mv88e6xxx_chip *chip = ds->priv; 3132 3133 if (tree_index != ds->dst->index) 3134 return; 3135 3136 mv88e6xxx_reg_lock(chip); 3137 if (mv88e6xxx_pvt_map(chip, sw_index, port) || 3138 mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num)) 3139 dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n"); 3140 mv88e6xxx_reg_unlock(chip); 3141} 3142 3143static int mv88e6xxx_software_reset(struct mv88e6xxx_chip *chip) 3144{ 3145 if (chip->info->ops->reset) 3146 return chip->info->ops->reset(chip); 3147 3148 return 0; 3149} 3150 3151static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip) 3152{ 3153 struct gpio_desc *gpiod = chip->reset; 3154 int err; 3155 3156 /* If there is a GPIO connected to the reset pin, toggle it */ 3157 if (gpiod) { 3158 /* If the switch has just been reset and not yet completed 3159 * loading EEPROM, the reset may interrupt the I2C transaction 3160 * mid-byte, causing the first EEPROM read after the reset 3161 * from the wrong location resulting in the switch booting 3162 * to wrong mode and inoperable. 3163 * For this reason, switch families with EEPROM support 3164 * generally wait for EEPROM loads to complete as their pre- 3165 * and post-reset handlers. 3166 */ 3167 if (chip->info->ops->hardware_reset_pre) { 3168 err = chip->info->ops->hardware_reset_pre(chip); 3169 if (err) 3170 dev_err(chip->dev, "pre-reset error: %d\n", err); 3171 } 3172 3173 gpiod_set_value_cansleep(gpiod, 1); 3174 usleep_range(10000, 20000); 3175 gpiod_set_value_cansleep(gpiod, 0); 3176 usleep_range(10000, 20000); 3177 3178 if (chip->info->ops->hardware_reset_post) { 3179 err = chip->info->ops->hardware_reset_post(chip); 3180 if (err) 3181 dev_err(chip->dev, "post-reset error: %d\n", err); 3182 } 3183 } 3184} 3185 3186static int mv88e6xxx_disable_ports(struct mv88e6xxx_chip *chip) 3187{ 3188 int i, err; 3189 3190 /* Set all ports to the Disabled state */ 3191 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) { 3192 err = mv88e6xxx_port_set_state(chip, i, BR_STATE_DISABLED); 3193 if (err) 3194 return err; 3195 } 3196 3197 /* Wait for transmit queues to drain, 3198 * i.e. 2ms for a maximum frame to be transmitted at 10 Mbps. 3199 */ 3200 usleep_range(2000, 4000); 3201 3202 return 0; 3203} 3204 3205static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip) 3206{ 3207 int err; 3208 3209 err = mv88e6xxx_disable_ports(chip); 3210 if (err) 3211 return err; 3212 3213 mv88e6xxx_hardware_reset(chip); 3214 3215 return mv88e6xxx_software_reset(chip); 3216} 3217 3218static int mv88e6xxx_set_port_mode(struct mv88e6xxx_chip *chip, int port, 3219 enum mv88e6xxx_frame_mode frame, 3220 enum mv88e6xxx_egress_mode egress, u16 etype) 3221{ 3222 int err; 3223 3224 if (!chip->info->ops->port_set_frame_mode) 3225 return -EOPNOTSUPP; 3226 3227 err = mv88e6xxx_port_set_egress_mode(chip, port, egress); 3228 if (err) 3229 return err; 3230 3231 err = chip->info->ops->port_set_frame_mode(chip, port, frame); 3232 if (err) 3233 return err; 3234 3235 if (chip->info->ops->port_set_ether_type) 3236 return chip->info->ops->port_set_ether_type(chip, port, etype); 3237 3238 return 0; 3239} 3240 3241static int mv88e6xxx_set_port_mode_normal(struct mv88e6xxx_chip *chip, int port) 3242{ 3243 return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_NORMAL, 3244 MV88E6XXX_EGRESS_MODE_UNMODIFIED, 3245 MV88E6XXX_PORT_ETH_TYPE_DEFAULT); 3246} 3247 3248static int mv88e6xxx_set_port_mode_dsa(struct mv88e6xxx_chip *chip, int port) 3249{ 3250 return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_DSA, 3251 MV88E6XXX_EGRESS_MODE_UNMODIFIED, 3252 MV88E6XXX_PORT_ETH_TYPE_DEFAULT); 3253} 3254 3255static int mv88e6xxx_set_port_mode_edsa(struct mv88e6xxx_chip *chip, int port) 3256{ 3257 return mv88e6xxx_set_port_mode(chip, port, 3258 MV88E6XXX_FRAME_MODE_ETHERTYPE, 3259 MV88E6XXX_EGRESS_MODE_ETHERTYPE, 3260 ETH_P_EDSA); 3261} 3262 3263static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port) 3264{ 3265 if (dsa_is_dsa_port(chip->ds, port)) 3266 return mv88e6xxx_set_port_mode_dsa(chip, port); 3267 3268 if (dsa_is_user_port(chip->ds, port)) 3269 return mv88e6xxx_set_port_mode_normal(chip, port); 3270 3271 /* Setup CPU port mode depending on its supported tag format */ 3272 if (chip->tag_protocol == DSA_TAG_PROTO_DSA) 3273 return mv88e6xxx_set_port_mode_dsa(chip, port); 3274 3275 if (chip->tag_protocol == DSA_TAG_PROTO_EDSA) 3276 return mv88e6xxx_set_port_mode_edsa(chip, port); 3277 3278 return -EINVAL; 3279} 3280 3281static int mv88e6xxx_setup_message_port(struct mv88e6xxx_chip *chip, int port) 3282{ 3283 bool message = dsa_is_dsa_port(chip->ds, port); 3284 3285 return mv88e6xxx_port_set_message_port(chip, port, message); 3286} 3287 3288static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port) 3289{ 3290 int err; 3291 3292 if (chip->info->ops->port_set_ucast_flood) { 3293 err = chip->info->ops->port_set_ucast_flood(chip, port, true); 3294 if (err) 3295 return err; 3296 } 3297 if (chip->info->ops->port_set_mcast_flood) { 3298 err = chip->info->ops->port_set_mcast_flood(chip, port, true); 3299 if (err) 3300 return err; 3301 } 3302 3303 return 0; 3304} 3305 3306static int mv88e6xxx_set_egress_port(struct mv88e6xxx_chip *chip, 3307 enum mv88e6xxx_egress_direction direction, 3308 int port) 3309{ 3310 int err; 3311 3312 if (!chip->info->ops->set_egress_port) 3313 return -EOPNOTSUPP; 3314 3315 err = chip->info->ops->set_egress_port(chip, direction, port); 3316 if (err) 3317 return err; 3318 3319 if (direction == MV88E6XXX_EGRESS_DIR_INGRESS) 3320 chip->ingress_dest_port = port; 3321 else 3322 chip->egress_dest_port = port; 3323 3324 return 0; 3325} 3326 3327static int mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip *chip, int port) 3328{ 3329 struct dsa_switch *ds = chip->ds; 3330 int upstream_port; 3331 int err; 3332 3333 upstream_port = dsa_upstream_port(ds, port); 3334 if (chip->info->ops->port_set_upstream_port) { 3335 err = chip->info->ops->port_set_upstream_port(chip, port, 3336 upstream_port); 3337 if (err) 3338 return err; 3339 } 3340 3341 if (port == upstream_port) { 3342 if (chip->info->ops->set_cpu_port) { 3343 err = chip->info->ops->set_cpu_port(chip, 3344 upstream_port); 3345 if (err) 3346 return err; 3347 } 3348 3349 err = mv88e6xxx_set_egress_port(chip, 3350 MV88E6XXX_EGRESS_DIR_INGRESS, 3351 upstream_port); 3352 if (err && err != -EOPNOTSUPP) 3353 return err; 3354 3355 err = mv88e6xxx_set_egress_port(chip, 3356 MV88E6XXX_EGRESS_DIR_EGRESS, 3357 upstream_port); 3358 if (err && err != -EOPNOTSUPP) 3359 return err; 3360 } 3361 3362 return 0; 3363} 3364 3365static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port) 3366{ 3367 struct fwnode_handle *ports_fwnode; 3368 struct fwnode_handle *port_fwnode; 3369 struct dsa_switch *ds = chip->ds; 3370 struct mv88e6xxx_port *p; 3371 int err; 3372 u16 reg; 3373 u32 val; 3374 3375 p = &chip->ports[port]; 3376 p->chip = chip; 3377 p->port = port; 3378 3379 /* Look up corresponding fwnode if any */ 3380 ports_fwnode = device_get_named_child_node(chip->dev, "ethernet-ports"); 3381 if (!ports_fwnode) 3382 ports_fwnode = device_get_named_child_node(chip->dev, "ports"); 3383 if (ports_fwnode) { 3384 fwnode_for_each_child_node(ports_fwnode, port_fwnode) { 3385 if (fwnode_property_read_u32(port_fwnode, "reg", &val)) 3386 continue; 3387 if (val == port) { 3388 p->fwnode = port_fwnode; 3389 p->fiber = fwnode_property_present(port_fwnode, "sfp"); 3390 break; 3391 } 3392 } 3393 fwnode_handle_put(ports_fwnode); 3394 } else { 3395 dev_dbg(chip->dev, "no ethernet ports node defined for the device\n"); 3396 } 3397 3398 if (chip->info->ops->port_setup_leds) { 3399 err = chip->info->ops->port_setup_leds(chip, port); 3400 if (err && err != -EOPNOTSUPP) 3401 return err; 3402 } 3403 3404 err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED, 3405 SPEED_UNFORCED, DUPLEX_UNFORCED, 3406 PAUSE_ON, PHY_INTERFACE_MODE_NA); 3407 if (err) 3408 return err; 3409 3410 /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock, 3411 * disable Header mode, enable IGMP/MLD snooping, disable VLAN 3412 * tunneling, determine priority by looking at 802.1p and IP 3413 * priority fields (IP prio has precedence), and set STP state 3414 * to Forwarding. 3415 * 3416 * If this is the CPU link, use DSA or EDSA tagging depending 3417 * on which tagging mode was configured. 3418 * 3419 * If this is a link to another switch, use DSA tagging mode. 3420 * 3421 * If this is the upstream port for this switch, enable 3422 * forwarding of unknown unicasts and multicasts. 3423 */ 3424 reg = MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP | 3425 MV88E6XXX_PORT_CTL0_STATE_FORWARDING; 3426 /* Forward any IPv4 IGMP or IPv6 MLD frames received 3427 * by a USER port to the CPU port to allow snooping. 3428 */ 3429 if (dsa_is_user_port(ds, port)) 3430 reg |= MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP; 3431 3432 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 3433 if (err) 3434 return err; 3435 3436 err = mv88e6xxx_setup_port_mode(chip, port); 3437 if (err) 3438 return err; 3439 3440 err = mv88e6xxx_setup_egress_floods(chip, port); 3441 if (err) 3442 return err; 3443 3444 /* Port Control 2: don't force a good FCS, set the MTU size to 3445 * 10222 bytes, disable 802.1q tags checking, don't discard 3446 * tagged or untagged frames on this port, skip destination 3447 * address lookup on user ports, disable ARP mirroring and don't 3448 * send a copy of all transmitted/received frames on this port 3449 * to the CPU. 3450 */ 3451 err = mv88e6xxx_port_set_map_da(chip, port, !dsa_is_user_port(ds, port)); 3452 if (err) 3453 return err; 3454 3455 err = mv88e6xxx_setup_upstream_port(chip, port); 3456 if (err) 3457 return err; 3458 3459 /* On chips that support it, set all downstream DSA ports' 3460 * VLAN policy to TRAP. In combination with loading 3461 * MV88E6XXX_VID_STANDALONE as a policy entry in the VTU, this 3462 * provides a better isolation barrier between standalone 3463 * ports, as the ATU is bypassed on any intermediate switches 3464 * between the incoming port and the CPU. 3465 */ 3466 if (dsa_is_downstream_port(ds, port) && 3467 chip->info->ops->port_set_policy) { 3468 err = chip->info->ops->port_set_policy(chip, port, 3469 MV88E6XXX_POLICY_MAPPING_VTU, 3470 MV88E6XXX_POLICY_ACTION_TRAP); 3471 if (err) 3472 return err; 3473 } 3474 3475 /* User ports start out in standalone mode and 802.1Q is 3476 * therefore disabled. On DSA ports, all valid VIDs are always 3477 * loaded in the VTU - therefore, enable 802.1Q in order to take 3478 * advantage of VLAN policy on chips that supports it. 3479 */ 3480 err = mv88e6xxx_port_set_8021q_mode(chip, port, 3481 dsa_is_user_port(ds, port) ? 3482 MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED : 3483 MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE); 3484 if (err) 3485 return err; 3486 3487 /* Bind MV88E6XXX_VID_STANDALONE to MV88E6XXX_FID_STANDALONE by 3488 * virtue of the fact that mv88e6xxx_atu_new() will pick it as 3489 * the first free FID. This will be used as the private PVID for 3490 * unbridged ports. Shared (DSA and CPU) ports must also be 3491 * members of this VID, in order to trap all frames assigned to 3492 * it to the CPU. 3493 */ 3494 err = mv88e6xxx_port_vlan_join(chip, port, MV88E6XXX_VID_STANDALONE, 3495 MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED, 3496 false); 3497 if (err) 3498 return err; 3499 3500 /* Associate MV88E6XXX_VID_BRIDGED with MV88E6XXX_FID_BRIDGED in the 3501 * ATU by virtue of the fact that mv88e6xxx_atu_new() will pick it as 3502 * the first free FID after MV88E6XXX_FID_STANDALONE. This will be used 3503 * as the private PVID on ports under a VLAN-unaware bridge. 3504 * Shared (DSA and CPU) ports must also be members of it, to translate 3505 * the VID from the DSA tag into MV88E6XXX_FID_BRIDGED, instead of 3506 * relying on their port default FID. 3507 */ 3508 err = mv88e6xxx_port_vlan_join(chip, port, MV88E6XXX_VID_BRIDGED, 3509 MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED, 3510 false); 3511 if (err) 3512 return err; 3513 3514 if (chip->info->ops->port_set_jumbo_size) { 3515 err = chip->info->ops->port_set_jumbo_size(chip, port, 10218); 3516 if (err) 3517 return err; 3518 } 3519 3520 /* Port Association Vector: disable automatic address learning 3521 * on all user ports since they start out in standalone 3522 * mode. When joining a bridge, learning will be configured to 3523 * match the bridge port settings. Enable learning on all 3524 * DSA/CPU ports. NOTE: FROM_CPU frames always bypass the 3525 * learning process. 3526 * 3527 * Disable HoldAt1, IntOnAgeOut, LockedPort, IgnoreWrongData, 3528 * and RefreshLocked. I.e. setup standard automatic learning. 3529 */ 3530 if (dsa_is_user_port(ds, port)) 3531 reg = 0; 3532 else 3533 reg = 1 << port; 3534 3535 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR, 3536 reg); 3537 if (err) 3538 return err; 3539 3540 /* Egress rate control 2: disable egress rate control. */ 3541 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL2, 3542 0x0000); 3543 if (err) 3544 return err; 3545 3546 if (chip->info->ops->port_pause_limit) { 3547 err = chip->info->ops->port_pause_limit(chip, port, 0, 0); 3548 if (err) 3549 return err; 3550 } 3551 3552 if (chip->info->ops->port_disable_learn_limit) { 3553 err = chip->info->ops->port_disable_learn_limit(chip, port); 3554 if (err) 3555 return err; 3556 } 3557 3558 if (chip->info->ops->port_disable_pri_override) { 3559 err = chip->info->ops->port_disable_pri_override(chip, port); 3560 if (err) 3561 return err; 3562 } 3563 3564 if (chip->info->ops->port_tag_remap) { 3565 err = chip->info->ops->port_tag_remap(chip, port); 3566 if (err) 3567 return err; 3568 } 3569 3570 if (chip->info->ops->port_egress_rate_limiting) { 3571 err = chip->info->ops->port_egress_rate_limiting(chip, port); 3572 if (err) 3573 return err; 3574 } 3575 3576 if (chip->info->ops->port_setup_message_port) { 3577 err = chip->info->ops->port_setup_message_port(chip, port); 3578 if (err) 3579 return err; 3580 } 3581 3582 /* Port based VLAN map: give each port the same default address 3583 * database, and allow bidirectional communication between the 3584 * CPU and DSA port(s), and the other ports. 3585 */ 3586 err = mv88e6xxx_port_set_fid(chip, port, MV88E6XXX_FID_STANDALONE); 3587 if (err) 3588 return err; 3589 3590 err = mv88e6xxx_port_vlan_map(chip, port); 3591 if (err) 3592 return err; 3593 3594 /* Default VLAN ID and priority: don't set a default VLAN 3595 * ID, and set the default packet priority to zero. 3596 */ 3597 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 0); 3598} 3599 3600static int mv88e6xxx_get_max_mtu(struct dsa_switch *ds, int port) 3601{ 3602 struct mv88e6xxx_chip *chip = ds->priv; 3603 3604 if (chip->info->ops->port_set_jumbo_size) 3605 return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN; 3606 else if (chip->info->ops->set_max_frame_size) 3607 return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN; 3608 return ETH_DATA_LEN; 3609} 3610 3611static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu) 3612{ 3613 struct mv88e6xxx_chip *chip = ds->priv; 3614 int ret = 0; 3615 3616 /* For families where we don't know how to alter the MTU, 3617 * just accept any value up to ETH_DATA_LEN 3618 */ 3619 if (!chip->info->ops->port_set_jumbo_size && 3620 !chip->info->ops->set_max_frame_size) { 3621 if (new_mtu > ETH_DATA_LEN) 3622 return -EINVAL; 3623 3624 return 0; 3625 } 3626 3627 if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port)) 3628 new_mtu += EDSA_HLEN; 3629 3630 mv88e6xxx_reg_lock(chip); 3631 if (chip->info->ops->port_set_jumbo_size) 3632 ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu); 3633 else if (chip->info->ops->set_max_frame_size && 3634 dsa_is_cpu_port(ds, port)) 3635 ret = chip->info->ops->set_max_frame_size(chip, new_mtu); 3636 mv88e6xxx_reg_unlock(chip); 3637 3638 return ret; 3639} 3640 3641static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds, 3642 unsigned int ageing_time) 3643{ 3644 struct mv88e6xxx_chip *chip = ds->priv; 3645 int err; 3646 3647 mv88e6xxx_reg_lock(chip); 3648 err = mv88e6xxx_g1_atu_set_age_time(chip, ageing_time); 3649 mv88e6xxx_reg_unlock(chip); 3650 3651 return err; 3652} 3653 3654static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip) 3655{ 3656 int err; 3657 3658 /* Initialize the statistics unit */ 3659 if (chip->info->ops->stats_set_histogram) { 3660 err = chip->info->ops->stats_set_histogram(chip); 3661 if (err) 3662 return err; 3663 } 3664 3665 return mv88e6xxx_g1_stats_clear(chip); 3666} 3667 3668static int mv88e6320_setup_errata(struct mv88e6xxx_chip *chip) 3669{ 3670 u16 dummy; 3671 int err; 3672 3673 /* Workaround for erratum 3674 * 3.3 RGMII timing may be out of spec when transmit delay is enabled 3675 */ 3676 err = mv88e6xxx_port_hidden_write(chip, 0, 0xf, 0x7, 0xe000); 3677 if (err) 3678 return err; 3679 3680 return mv88e6xxx_port_hidden_read(chip, 0, 0xf, 0x7, &dummy); 3681} 3682 3683/* Check if the errata has already been applied. */ 3684static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip) 3685{ 3686 int port; 3687 int err; 3688 u16 val; 3689 3690 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { 3691 err = mv88e6xxx_port_hidden_read(chip, 0xf, port, 0, &val); 3692 if (err) { 3693 dev_err(chip->dev, 3694 "Error reading hidden register: %d\n", err); 3695 return false; 3696 } 3697 if (val != 0x01c0) 3698 return false; 3699 } 3700 3701 return true; 3702} 3703 3704/* The 6390 copper ports have an errata which require poking magic 3705 * values into undocumented hidden registers and then performing a 3706 * software reset. 3707 */ 3708static int mv88e6390_setup_errata(struct mv88e6xxx_chip *chip) 3709{ 3710 int port; 3711 int err; 3712 3713 if (mv88e6390_setup_errata_applied(chip)) 3714 return 0; 3715 3716 /* Set the ports into blocking mode */ 3717 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { 3718 err = mv88e6xxx_port_set_state(chip, port, BR_STATE_DISABLED); 3719 if (err) 3720 return err; 3721 } 3722 3723 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { 3724 err = mv88e6xxx_port_hidden_write(chip, 0xf, port, 0, 0x01c0); 3725 if (err) 3726 return err; 3727 } 3728 3729 return mv88e6xxx_software_reset(chip); 3730} 3731 3732/* prod_id for switch families which do not have a PHY model number */ 3733static const u16 family_prod_id_table[] = { 3734 [MV88E6XXX_FAMILY_6341] = MV88E6XXX_PORT_SWITCH_ID_PROD_6341, 3735 [MV88E6XXX_FAMILY_6390] = MV88E6XXX_PORT_SWITCH_ID_PROD_6390, 3736 [MV88E6XXX_FAMILY_6393] = MV88E6XXX_PORT_SWITCH_ID_PROD_6393X, 3737}; 3738 3739static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg) 3740{ 3741 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv; 3742 struct mv88e6xxx_chip *chip = mdio_bus->chip; 3743 u16 prod_id; 3744 u16 val; 3745 int err; 3746 3747 if (!chip->info->ops->phy_read) 3748 return -EOPNOTSUPP; 3749 3750 mv88e6xxx_reg_lock(chip); 3751 err = chip->info->ops->phy_read(chip, bus, phy, reg, &val); 3752 mv88e6xxx_reg_unlock(chip); 3753 3754 /* Some internal PHYs don't have a model number. */ 3755 if (reg == MII_PHYSID2 && !(val & 0x3f0) && 3756 chip->info->family < ARRAY_SIZE(family_prod_id_table)) { 3757 prod_id = family_prod_id_table[chip->info->family]; 3758 if (prod_id) 3759 val |= prod_id >> 4; 3760 } 3761 3762 return err ? err : val; 3763} 3764 3765static int mv88e6xxx_mdio_read_c45(struct mii_bus *bus, int phy, int devad, 3766 int reg) 3767{ 3768 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv; 3769 struct mv88e6xxx_chip *chip = mdio_bus->chip; 3770 u16 val; 3771 int err; 3772 3773 if (!chip->info->ops->phy_read_c45) 3774 return -ENODEV; 3775 3776 mv88e6xxx_reg_lock(chip); 3777 err = chip->info->ops->phy_read_c45(chip, bus, phy, devad, reg, &val); 3778 mv88e6xxx_reg_unlock(chip); 3779 3780 return err ? err : val; 3781} 3782 3783static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val) 3784{ 3785 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv; 3786 struct mv88e6xxx_chip *chip = mdio_bus->chip; 3787 int err; 3788 3789 if (!chip->info->ops->phy_write) 3790 return -EOPNOTSUPP; 3791 3792 mv88e6xxx_reg_lock(chip); 3793 err = chip->info->ops->phy_write(chip, bus, phy, reg, val); 3794 mv88e6xxx_reg_unlock(chip); 3795 3796 return err; 3797} 3798 3799static int mv88e6xxx_mdio_write_c45(struct mii_bus *bus, int phy, int devad, 3800 int reg, u16 val) 3801{ 3802 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv; 3803 struct mv88e6xxx_chip *chip = mdio_bus->chip; 3804 int err; 3805 3806 if (!chip->info->ops->phy_write_c45) 3807 return -EOPNOTSUPP; 3808 3809 mv88e6xxx_reg_lock(chip); 3810 err = chip->info->ops->phy_write_c45(chip, bus, phy, devad, reg, val); 3811 mv88e6xxx_reg_unlock(chip); 3812 3813 return err; 3814} 3815 3816static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip, 3817 struct device_node *np, 3818 bool external) 3819{ 3820 static int index; 3821 struct mv88e6xxx_mdio_bus *mdio_bus; 3822 struct mii_bus *bus; 3823 int err; 3824 3825 if (external) { 3826 mv88e6xxx_reg_lock(chip); 3827 if (chip->info->family == MV88E6XXX_FAMILY_6393) 3828 err = mv88e6393x_g2_scratch_gpio_set_smi(chip, true); 3829 else 3830 err = mv88e6390_g2_scratch_gpio_set_smi(chip, true); 3831 mv88e6xxx_reg_unlock(chip); 3832 3833 if (err) 3834 return err; 3835 } 3836 3837 bus = mdiobus_alloc_size(sizeof(*mdio_bus)); 3838 if (!bus) 3839 return -ENOMEM; 3840 3841 mdio_bus = bus->priv; 3842 mdio_bus->bus = bus; 3843 mdio_bus->chip = chip; 3844 INIT_LIST_HEAD(&mdio_bus->list); 3845 mdio_bus->external = external; 3846 3847 if (np) { 3848 bus->name = np->full_name; 3849 snprintf(bus->id, MII_BUS_ID_SIZE, "%pOF", np); 3850 } else { 3851 bus->name = "mv88e6xxx SMI"; 3852 snprintf(bus->id, MII_BUS_ID_SIZE, "mv88e6xxx-%d", index++); 3853 } 3854 3855 bus->read = mv88e6xxx_mdio_read; 3856 bus->write = mv88e6xxx_mdio_write; 3857 bus->read_c45 = mv88e6xxx_mdio_read_c45; 3858 bus->write_c45 = mv88e6xxx_mdio_write_c45; 3859 bus->parent = chip->dev; 3860 bus->phy_mask = ~GENMASK(chip->info->phy_base_addr + 3861 mv88e6xxx_num_ports(chip) - 1, 3862 chip->info->phy_base_addr); 3863 3864 if (!external) { 3865 err = mv88e6xxx_g2_irq_mdio_setup(chip, bus); 3866 if (err) 3867 goto out; 3868 } 3869 3870 err = of_mdiobus_register(bus, np); 3871 if (err) { 3872 dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err); 3873 mv88e6xxx_g2_irq_mdio_free(chip, bus); 3874 goto out; 3875 } 3876 3877 if (external) 3878 list_add_tail(&mdio_bus->list, &chip->mdios); 3879 else 3880 list_add(&mdio_bus->list, &chip->mdios); 3881 3882 return 0; 3883 3884out: 3885 mdiobus_free(bus); 3886 return err; 3887} 3888 3889static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip) 3890 3891{ 3892 struct mv88e6xxx_mdio_bus *mdio_bus, *p; 3893 struct mii_bus *bus; 3894 3895 list_for_each_entry_safe(mdio_bus, p, &chip->mdios, list) { 3896 bus = mdio_bus->bus; 3897 3898 if (!mdio_bus->external) 3899 mv88e6xxx_g2_irq_mdio_free(chip, bus); 3900 3901 mdiobus_unregister(bus); 3902 mdiobus_free(bus); 3903 } 3904} 3905 3906static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip) 3907{ 3908 struct device_node *np = chip->dev->of_node; 3909 struct device_node *child; 3910 int err; 3911 3912 /* Always register one mdio bus for the internal/default mdio 3913 * bus. This maybe represented in the device tree, but is 3914 * optional. 3915 */ 3916 child = of_get_child_by_name(np, "mdio"); 3917 err = mv88e6xxx_mdio_register(chip, child, false); 3918 of_node_put(child); 3919 if (err) 3920 return err; 3921 3922 /* Walk the device tree, and see if there are any other nodes 3923 * which say they are compatible with the external mdio 3924 * bus. 3925 */ 3926 for_each_available_child_of_node(np, child) { 3927 if (of_device_is_compatible( 3928 child, "marvell,mv88e6xxx-mdio-external")) { 3929 err = mv88e6xxx_mdio_register(chip, child, true); 3930 if (err) { 3931 mv88e6xxx_mdios_unregister(chip); 3932 of_node_put(child); 3933 return err; 3934 } 3935 } 3936 } 3937 3938 return 0; 3939} 3940 3941static void mv88e6xxx_teardown(struct dsa_switch *ds) 3942{ 3943 struct mv88e6xxx_chip *chip = ds->priv; 3944 3945 mv88e6xxx_teardown_devlink_params(ds); 3946 dsa_devlink_resources_unregister(ds); 3947 mv88e6xxx_teardown_devlink_regions_global(ds); 3948 mv88e6xxx_hwtstamp_free(chip); 3949 mv88e6xxx_ptp_free(chip); 3950 mv88e6xxx_mdios_unregister(chip); 3951} 3952 3953static int mv88e6xxx_setup(struct dsa_switch *ds) 3954{ 3955 struct mv88e6xxx_chip *chip = ds->priv; 3956 u8 cmode; 3957 int err; 3958 int i; 3959 3960 err = mv88e6xxx_mdios_register(chip); 3961 if (err) 3962 return err; 3963 3964 chip->ds = ds; 3965 ds->user_mii_bus = mv88e6xxx_default_mdio_bus(chip); 3966 3967 /* Since virtual bridges are mapped in the PVT, the number we support 3968 * depends on the physical switch topology. We need to let DSA figure 3969 * that out and therefore we cannot set this at dsa_register_switch() 3970 * time. 3971 */ 3972 if (mv88e6xxx_has_pvt(chip)) 3973 ds->max_num_bridges = MV88E6XXX_MAX_PVT_SWITCHES - 3974 ds->dst->last_switch - 1; 3975 3976 mv88e6xxx_reg_lock(chip); 3977 3978 if (chip->info->ops->setup_errata) { 3979 err = chip->info->ops->setup_errata(chip); 3980 if (err) 3981 goto unlock; 3982 } 3983 3984 /* Cache the cmode of each port. */ 3985 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) { 3986 if (chip->info->ops->port_get_cmode) { 3987 err = chip->info->ops->port_get_cmode(chip, i, &cmode); 3988 if (err) 3989 goto unlock; 3990 3991 chip->ports[i].cmode = cmode; 3992 } 3993 } 3994 3995 err = mv88e6xxx_vtu_setup(chip); 3996 if (err) 3997 goto unlock; 3998 3999 /* Must be called after mv88e6xxx_vtu_setup (which flushes the 4000 * VTU, thereby also flushing the STU). 4001 */ 4002 err = mv88e6xxx_stu_setup(chip); 4003 if (err) 4004 goto unlock; 4005 4006 /* Setup Switch Port Registers */ 4007 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) { 4008 if (dsa_is_unused_port(ds, i)) 4009 continue; 4010 4011 /* Prevent the use of an invalid port. */ 4012 if (mv88e6xxx_is_invalid_port(chip, i)) { 4013 dev_err(chip->dev, "port %d is invalid\n", i); 4014 err = -EINVAL; 4015 goto unlock; 4016 } 4017 4018 err = mv88e6xxx_setup_port(chip, i); 4019 if (err) 4020 goto unlock; 4021 } 4022 4023 err = mv88e6xxx_irl_setup(chip); 4024 if (err) 4025 goto unlock; 4026 4027 err = mv88e6xxx_mac_setup(chip); 4028 if (err) 4029 goto unlock; 4030 4031 err = mv88e6xxx_phy_setup(chip); 4032 if (err) 4033 goto unlock; 4034 4035 err = mv88e6xxx_pvt_setup(chip); 4036 if (err) 4037 goto unlock; 4038 4039 err = mv88e6xxx_atu_setup(chip); 4040 if (err) 4041 goto unlock; 4042 4043 err = mv88e6xxx_broadcast_setup(chip, 0); 4044 if (err) 4045 goto unlock; 4046 4047 err = mv88e6xxx_pot_setup(chip); 4048 if (err) 4049 goto unlock; 4050 4051 err = mv88e6xxx_rmu_setup(chip); 4052 if (err) 4053 goto unlock; 4054 4055 err = mv88e6xxx_rsvd2cpu_setup(chip); 4056 if (err) 4057 goto unlock; 4058 4059 err = mv88e6xxx_trunk_setup(chip); 4060 if (err) 4061 goto unlock; 4062 4063 err = mv88e6xxx_devmap_setup(chip); 4064 if (err) 4065 goto unlock; 4066 4067 err = mv88e6xxx_pri_setup(chip); 4068 if (err) 4069 goto unlock; 4070 4071 /* Setup PTP Hardware Clock and timestamping */ 4072 if (chip->info->ptp_support) { 4073 err = mv88e6xxx_ptp_setup(chip); 4074 if (err) 4075 goto unlock; 4076 4077 err = mv88e6xxx_hwtstamp_setup(chip); 4078 if (err) 4079 goto unlock; 4080 } 4081 4082 err = mv88e6xxx_stats_setup(chip); 4083 if (err) 4084 goto unlock; 4085 4086unlock: 4087 mv88e6xxx_reg_unlock(chip); 4088 4089 if (err) 4090 goto out_hwtstamp; 4091 4092 /* Have to be called without holding the register lock, since 4093 * they take the devlink lock, and we later take the locks in 4094 * the reverse order when getting/setting parameters or 4095 * resource occupancy. 4096 */ 4097 err = mv88e6xxx_setup_devlink_resources(ds); 4098 if (err) 4099 goto out_hwtstamp; 4100 4101 err = mv88e6xxx_setup_devlink_params(ds); 4102 if (err) 4103 goto out_resources; 4104 4105 err = mv88e6xxx_setup_devlink_regions_global(ds); 4106 if (err) 4107 goto out_params; 4108 4109 return 0; 4110 4111out_params: 4112 mv88e6xxx_teardown_devlink_params(ds); 4113out_resources: 4114 dsa_devlink_resources_unregister(ds); 4115out_hwtstamp: 4116 mv88e6xxx_hwtstamp_free(chip); 4117 mv88e6xxx_ptp_free(chip); 4118 mv88e6xxx_mdios_unregister(chip); 4119 4120 return err; 4121} 4122 4123static int mv88e6xxx_port_setup(struct dsa_switch *ds, int port) 4124{ 4125 struct mv88e6xxx_chip *chip = ds->priv; 4126 int err; 4127 4128 if (chip->info->ops->pcs_ops && 4129 chip->info->ops->pcs_ops->pcs_init) { 4130 err = chip->info->ops->pcs_ops->pcs_init(chip, port); 4131 if (err) 4132 return err; 4133 } 4134 4135 return mv88e6xxx_setup_devlink_regions_port(ds, port); 4136} 4137 4138static void mv88e6xxx_port_teardown(struct dsa_switch *ds, int port) 4139{ 4140 struct mv88e6xxx_chip *chip = ds->priv; 4141 4142 mv88e6xxx_teardown_devlink_regions_port(ds, port); 4143 4144 if (chip->info->ops->pcs_ops && 4145 chip->info->ops->pcs_ops->pcs_teardown) 4146 chip->info->ops->pcs_ops->pcs_teardown(chip, port); 4147} 4148 4149static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds) 4150{ 4151 struct mv88e6xxx_chip *chip = ds->priv; 4152 4153 return chip->eeprom_len; 4154} 4155 4156static int mv88e6xxx_get_eeprom(struct dsa_switch *ds, 4157 struct ethtool_eeprom *eeprom, u8 *data) 4158{ 4159 struct mv88e6xxx_chip *chip = ds->priv; 4160 int err; 4161 4162 if (!chip->info->ops->get_eeprom) 4163 return -EOPNOTSUPP; 4164 4165 mv88e6xxx_reg_lock(chip); 4166 err = chip->info->ops->get_eeprom(chip, eeprom, data); 4167 mv88e6xxx_reg_unlock(chip); 4168 4169 if (err) 4170 return err; 4171 4172 eeprom->magic = 0xc3ec4951; 4173 4174 return 0; 4175} 4176 4177static int mv88e6xxx_set_eeprom(struct dsa_switch *ds, 4178 struct ethtool_eeprom *eeprom, u8 *data) 4179{ 4180 struct mv88e6xxx_chip *chip = ds->priv; 4181 int err; 4182 4183 if (!chip->info->ops->set_eeprom) 4184 return -EOPNOTSUPP; 4185 4186 if (eeprom->magic != 0xc3ec4951) 4187 return -EINVAL; 4188 4189 mv88e6xxx_reg_lock(chip); 4190 err = chip->info->ops->set_eeprom(chip, eeprom, data); 4191 mv88e6xxx_reg_unlock(chip); 4192 4193 return err; 4194} 4195 4196static const struct mv88e6xxx_ops mv88e6085_ops = { 4197 /* MV88E6XXX_FAMILY_6097 */ 4198 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4199 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4200 .irl_init_all = mv88e6352_g2_irl_init_all, 4201 .set_switch_mac = mv88e6xxx_g1_set_switch_mac, 4202 .phy_read = mv88e6185_phy_ppu_read, 4203 .phy_write = mv88e6185_phy_ppu_write, 4204 .port_set_link = mv88e6xxx_port_set_link, 4205 .port_sync_link = mv88e6xxx_port_sync_link, 4206 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 4207 .port_tag_remap = mv88e6095_port_tag_remap, 4208 .port_set_policy = mv88e6352_port_set_policy, 4209 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 4210 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 4211 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 4212 .port_set_ether_type = mv88e6351_port_set_ether_type, 4213 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 4214 .port_pause_limit = mv88e6097_port_pause_limit, 4215 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4216 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 4217 .port_get_cmode = mv88e6185_port_get_cmode, 4218 .port_setup_message_port = mv88e6xxx_setup_message_port, 4219 .stats_snapshot = mv88e6xxx_g1_stats_snapshot, 4220 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 4221 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 4222 .stats_get_strings = mv88e6095_stats_get_strings, 4223 .stats_get_stat = mv88e6095_stats_get_stat, 4224 .set_cpu_port = mv88e6095_g1_set_cpu_port, 4225 .set_egress_port = mv88e6095_g1_set_egress_port, 4226 .watchdog_ops = &mv88e6097_watchdog_ops, 4227 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 4228 .pot_clear = mv88e6xxx_g2_pot_clear, 4229 .ppu_enable = mv88e6185_g1_ppu_enable, 4230 .ppu_disable = mv88e6185_g1_ppu_disable, 4231 .reset = mv88e6185_g1_reset, 4232 .rmu_disable = mv88e6085_g1_rmu_disable, 4233 .vtu_getnext = mv88e6352_g1_vtu_getnext, 4234 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 4235 .stu_getnext = mv88e6352_g1_stu_getnext, 4236 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 4237 .phylink_get_caps = mv88e6185_phylink_get_caps, 4238 .set_max_frame_size = mv88e6185_g1_set_max_frame_size, 4239}; 4240 4241static const struct mv88e6xxx_ops mv88e6095_ops = { 4242 /* MV88E6XXX_FAMILY_6095 */ 4243 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4244 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4245 .set_switch_mac = mv88e6xxx_g1_set_switch_mac, 4246 .phy_read = mv88e6185_phy_ppu_read, 4247 .phy_write = mv88e6185_phy_ppu_write, 4248 .port_set_link = mv88e6xxx_port_set_link, 4249 .port_sync_link = mv88e6185_port_sync_link, 4250 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 4251 .port_set_frame_mode = mv88e6085_port_set_frame_mode, 4252 .port_set_ucast_flood = mv88e6185_port_set_forward_unknown, 4253 .port_set_mcast_flood = mv88e6185_port_set_default_forward, 4254 .port_set_upstream_port = mv88e6095_port_set_upstream_port, 4255 .port_get_cmode = mv88e6185_port_get_cmode, 4256 .port_setup_message_port = mv88e6xxx_setup_message_port, 4257 .stats_snapshot = mv88e6xxx_g1_stats_snapshot, 4258 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 4259 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 4260 .stats_get_strings = mv88e6095_stats_get_strings, 4261 .stats_get_stat = mv88e6095_stats_get_stat, 4262 .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu, 4263 .ppu_enable = mv88e6185_g1_ppu_enable, 4264 .ppu_disable = mv88e6185_g1_ppu_disable, 4265 .reset = mv88e6185_g1_reset, 4266 .vtu_getnext = mv88e6185_g1_vtu_getnext, 4267 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, 4268 .phylink_get_caps = mv88e6095_phylink_get_caps, 4269 .pcs_ops = &mv88e6185_pcs_ops, 4270 .set_max_frame_size = mv88e6185_g1_set_max_frame_size, 4271}; 4272 4273static const struct mv88e6xxx_ops mv88e6097_ops = { 4274 /* MV88E6XXX_FAMILY_6097 */ 4275 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4276 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4277 .irl_init_all = mv88e6352_g2_irl_init_all, 4278 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 4279 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 4280 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 4281 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 4282 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 4283 .port_set_link = mv88e6xxx_port_set_link, 4284 .port_sync_link = mv88e6185_port_sync_link, 4285 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 4286 .port_tag_remap = mv88e6095_port_tag_remap, 4287 .port_set_policy = mv88e6352_port_set_policy, 4288 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 4289 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 4290 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 4291 .port_set_ether_type = mv88e6351_port_set_ether_type, 4292 .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting, 4293 .port_pause_limit = mv88e6097_port_pause_limit, 4294 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4295 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 4296 .port_get_cmode = mv88e6185_port_get_cmode, 4297 .port_setup_message_port = mv88e6xxx_setup_message_port, 4298 .stats_snapshot = mv88e6xxx_g1_stats_snapshot, 4299 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 4300 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 4301 .stats_get_strings = mv88e6095_stats_get_strings, 4302 .stats_get_stat = mv88e6095_stats_get_stat, 4303 .set_cpu_port = mv88e6095_g1_set_cpu_port, 4304 .set_egress_port = mv88e6095_g1_set_egress_port, 4305 .watchdog_ops = &mv88e6097_watchdog_ops, 4306 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 4307 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 4308 .pot_clear = mv88e6xxx_g2_pot_clear, 4309 .reset = mv88e6352_g1_reset, 4310 .rmu_disable = mv88e6085_g1_rmu_disable, 4311 .vtu_getnext = mv88e6352_g1_vtu_getnext, 4312 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 4313 .phylink_get_caps = mv88e6095_phylink_get_caps, 4314 .pcs_ops = &mv88e6185_pcs_ops, 4315 .stu_getnext = mv88e6352_g1_stu_getnext, 4316 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 4317 .set_max_frame_size = mv88e6185_g1_set_max_frame_size, 4318}; 4319 4320static const struct mv88e6xxx_ops mv88e6123_ops = { 4321 /* MV88E6XXX_FAMILY_6165 */ 4322 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4323 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4324 .irl_init_all = mv88e6352_g2_irl_init_all, 4325 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 4326 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 4327 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 4328 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 4329 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 4330 .port_set_link = mv88e6xxx_port_set_link, 4331 .port_sync_link = mv88e6xxx_port_sync_link, 4332 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 4333 .port_set_frame_mode = mv88e6085_port_set_frame_mode, 4334 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 4335 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 4336 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4337 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 4338 .port_get_cmode = mv88e6185_port_get_cmode, 4339 .port_setup_message_port = mv88e6xxx_setup_message_port, 4340 .stats_snapshot = mv88e6320_g1_stats_snapshot, 4341 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 4342 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 4343 .stats_get_strings = mv88e6095_stats_get_strings, 4344 .stats_get_stat = mv88e6095_stats_get_stat, 4345 .set_cpu_port = mv88e6095_g1_set_cpu_port, 4346 .set_egress_port = mv88e6095_g1_set_egress_port, 4347 .watchdog_ops = &mv88e6097_watchdog_ops, 4348 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 4349 .pot_clear = mv88e6xxx_g2_pot_clear, 4350 .reset = mv88e6352_g1_reset, 4351 .atu_get_hash = mv88e6165_g1_atu_get_hash, 4352 .atu_set_hash = mv88e6165_g1_atu_set_hash, 4353 .vtu_getnext = mv88e6352_g1_vtu_getnext, 4354 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 4355 .stu_getnext = mv88e6352_g1_stu_getnext, 4356 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 4357 .phylink_get_caps = mv88e6185_phylink_get_caps, 4358 .set_max_frame_size = mv88e6185_g1_set_max_frame_size, 4359}; 4360 4361static const struct mv88e6xxx_ops mv88e6131_ops = { 4362 /* MV88E6XXX_FAMILY_6185 */ 4363 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4364 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4365 .set_switch_mac = mv88e6xxx_g1_set_switch_mac, 4366 .phy_read = mv88e6185_phy_ppu_read, 4367 .phy_write = mv88e6185_phy_ppu_write, 4368 .port_set_link = mv88e6xxx_port_set_link, 4369 .port_sync_link = mv88e6xxx_port_sync_link, 4370 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 4371 .port_tag_remap = mv88e6095_port_tag_remap, 4372 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 4373 .port_set_ucast_flood = mv88e6185_port_set_forward_unknown, 4374 .port_set_mcast_flood = mv88e6185_port_set_default_forward, 4375 .port_set_ether_type = mv88e6351_port_set_ether_type, 4376 .port_set_upstream_port = mv88e6095_port_set_upstream_port, 4377 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 4378 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 4379 .port_pause_limit = mv88e6097_port_pause_limit, 4380 .port_set_pause = mv88e6185_port_set_pause, 4381 .port_get_cmode = mv88e6185_port_get_cmode, 4382 .port_setup_message_port = mv88e6xxx_setup_message_port, 4383 .stats_snapshot = mv88e6xxx_g1_stats_snapshot, 4384 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 4385 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 4386 .stats_get_strings = mv88e6095_stats_get_strings, 4387 .stats_get_stat = mv88e6095_stats_get_stat, 4388 .set_cpu_port = mv88e6095_g1_set_cpu_port, 4389 .set_egress_port = mv88e6095_g1_set_egress_port, 4390 .watchdog_ops = &mv88e6097_watchdog_ops, 4391 .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu, 4392 .ppu_enable = mv88e6185_g1_ppu_enable, 4393 .set_cascade_port = mv88e6185_g1_set_cascade_port, 4394 .ppu_disable = mv88e6185_g1_ppu_disable, 4395 .reset = mv88e6185_g1_reset, 4396 .vtu_getnext = mv88e6185_g1_vtu_getnext, 4397 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, 4398 .phylink_get_caps = mv88e6185_phylink_get_caps, 4399}; 4400 4401static const struct mv88e6xxx_ops mv88e6141_ops = { 4402 /* MV88E6XXX_FAMILY_6341 */ 4403 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4404 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4405 .irl_init_all = mv88e6352_g2_irl_init_all, 4406 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 4407 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 4408 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 4409 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 4410 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 4411 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 4412 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 4413 .port_set_link = mv88e6xxx_port_set_link, 4414 .port_sync_link = mv88e6xxx_port_sync_link, 4415 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, 4416 .port_set_speed_duplex = mv88e6341_port_set_speed_duplex, 4417 .port_max_speed_mode = mv88e6341_port_max_speed_mode, 4418 .port_tag_remap = mv88e6095_port_tag_remap, 4419 .port_set_policy = mv88e6352_port_set_policy, 4420 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 4421 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 4422 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 4423 .port_set_ether_type = mv88e6351_port_set_ether_type, 4424 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 4425 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 4426 .port_pause_limit = mv88e6097_port_pause_limit, 4427 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4428 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 4429 .port_get_cmode = mv88e6352_port_get_cmode, 4430 .port_set_cmode = mv88e6341_port_set_cmode, 4431 .port_setup_message_port = mv88e6xxx_setup_message_port, 4432 .stats_snapshot = mv88e6390_g1_stats_snapshot, 4433 .stats_set_histogram = mv88e6390_g1_stats_set_histogram, 4434 .stats_get_sset_count = mv88e6320_stats_get_sset_count, 4435 .stats_get_strings = mv88e6320_stats_get_strings, 4436 .stats_get_stat = mv88e6390_stats_get_stat, 4437 .set_cpu_port = mv88e6390_g1_set_cpu_port, 4438 .set_egress_port = mv88e6390_g1_set_egress_port, 4439 .watchdog_ops = &mv88e6390_watchdog_ops, 4440 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, 4441 .pot_clear = mv88e6xxx_g2_pot_clear, 4442 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 4443 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 4444 .reset = mv88e6352_g1_reset, 4445 .rmu_disable = mv88e6390_g1_rmu_disable, 4446 .atu_get_hash = mv88e6165_g1_atu_get_hash, 4447 .atu_set_hash = mv88e6165_g1_atu_set_hash, 4448 .vtu_getnext = mv88e6352_g1_vtu_getnext, 4449 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 4450 .stu_getnext = mv88e6352_g1_stu_getnext, 4451 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 4452 .serdes_get_lane = mv88e6341_serdes_get_lane, 4453 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 4454 .gpio_ops = &mv88e6352_gpio_ops, 4455 .serdes_get_sset_count = mv88e6390_serdes_get_sset_count, 4456 .serdes_get_strings = mv88e6390_serdes_get_strings, 4457 .serdes_get_stats = mv88e6390_serdes_get_stats, 4458 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, 4459 .serdes_get_regs = mv88e6390_serdes_get_regs, 4460 .phylink_get_caps = mv88e6341_phylink_get_caps, 4461 .pcs_ops = &mv88e6390_pcs_ops, 4462}; 4463 4464static const struct mv88e6xxx_ops mv88e6161_ops = { 4465 /* MV88E6XXX_FAMILY_6165 */ 4466 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4467 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4468 .irl_init_all = mv88e6352_g2_irl_init_all, 4469 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 4470 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 4471 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 4472 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 4473 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 4474 .port_set_link = mv88e6xxx_port_set_link, 4475 .port_sync_link = mv88e6xxx_port_sync_link, 4476 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 4477 .port_tag_remap = mv88e6095_port_tag_remap, 4478 .port_set_policy = mv88e6352_port_set_policy, 4479 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 4480 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 4481 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 4482 .port_set_ether_type = mv88e6351_port_set_ether_type, 4483 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 4484 .port_pause_limit = mv88e6097_port_pause_limit, 4485 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4486 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 4487 .port_get_cmode = mv88e6185_port_get_cmode, 4488 .port_setup_message_port = mv88e6xxx_setup_message_port, 4489 .stats_snapshot = mv88e6xxx_g1_stats_snapshot, 4490 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 4491 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 4492 .stats_get_strings = mv88e6095_stats_get_strings, 4493 .stats_get_stat = mv88e6095_stats_get_stat, 4494 .set_cpu_port = mv88e6095_g1_set_cpu_port, 4495 .set_egress_port = mv88e6095_g1_set_egress_port, 4496 .watchdog_ops = &mv88e6097_watchdog_ops, 4497 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 4498 .pot_clear = mv88e6xxx_g2_pot_clear, 4499 .reset = mv88e6352_g1_reset, 4500 .atu_get_hash = mv88e6165_g1_atu_get_hash, 4501 .atu_set_hash = mv88e6165_g1_atu_set_hash, 4502 .vtu_getnext = mv88e6352_g1_vtu_getnext, 4503 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 4504 .stu_getnext = mv88e6352_g1_stu_getnext, 4505 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 4506 .avb_ops = &mv88e6165_avb_ops, 4507 .ptp_ops = &mv88e6165_ptp_ops, 4508 .phylink_get_caps = mv88e6185_phylink_get_caps, 4509 .set_max_frame_size = mv88e6185_g1_set_max_frame_size, 4510}; 4511 4512static const struct mv88e6xxx_ops mv88e6165_ops = { 4513 /* MV88E6XXX_FAMILY_6165 */ 4514 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4515 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4516 .irl_init_all = mv88e6352_g2_irl_init_all, 4517 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 4518 .phy_read = mv88e6165_phy_read, 4519 .phy_write = mv88e6165_phy_write, 4520 .port_set_link = mv88e6xxx_port_set_link, 4521 .port_sync_link = mv88e6xxx_port_sync_link, 4522 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 4523 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4524 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 4525 .port_get_cmode = mv88e6185_port_get_cmode, 4526 .port_setup_message_port = mv88e6xxx_setup_message_port, 4527 .stats_snapshot = mv88e6xxx_g1_stats_snapshot, 4528 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 4529 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 4530 .stats_get_strings = mv88e6095_stats_get_strings, 4531 .stats_get_stat = mv88e6095_stats_get_stat, 4532 .set_cpu_port = mv88e6095_g1_set_cpu_port, 4533 .set_egress_port = mv88e6095_g1_set_egress_port, 4534 .watchdog_ops = &mv88e6097_watchdog_ops, 4535 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 4536 .pot_clear = mv88e6xxx_g2_pot_clear, 4537 .reset = mv88e6352_g1_reset, 4538 .atu_get_hash = mv88e6165_g1_atu_get_hash, 4539 .atu_set_hash = mv88e6165_g1_atu_set_hash, 4540 .vtu_getnext = mv88e6352_g1_vtu_getnext, 4541 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 4542 .stu_getnext = mv88e6352_g1_stu_getnext, 4543 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 4544 .avb_ops = &mv88e6165_avb_ops, 4545 .ptp_ops = &mv88e6165_ptp_ops, 4546 .phylink_get_caps = mv88e6185_phylink_get_caps, 4547}; 4548 4549static const struct mv88e6xxx_ops mv88e6171_ops = { 4550 /* MV88E6XXX_FAMILY_6351 */ 4551 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4552 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4553 .irl_init_all = mv88e6352_g2_irl_init_all, 4554 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 4555 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 4556 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 4557 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 4558 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 4559 .port_set_link = mv88e6xxx_port_set_link, 4560 .port_sync_link = mv88e6xxx_port_sync_link, 4561 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, 4562 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 4563 .port_tag_remap = mv88e6095_port_tag_remap, 4564 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 4565 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 4566 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 4567 .port_set_ether_type = mv88e6351_port_set_ether_type, 4568 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 4569 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 4570 .port_pause_limit = mv88e6097_port_pause_limit, 4571 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4572 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 4573 .port_get_cmode = mv88e6352_port_get_cmode, 4574 .port_setup_message_port = mv88e6xxx_setup_message_port, 4575 .stats_snapshot = mv88e6320_g1_stats_snapshot, 4576 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 4577 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 4578 .stats_get_strings = mv88e6095_stats_get_strings, 4579 .stats_get_stat = mv88e6095_stats_get_stat, 4580 .set_cpu_port = mv88e6095_g1_set_cpu_port, 4581 .set_egress_port = mv88e6095_g1_set_egress_port, 4582 .watchdog_ops = &mv88e6097_watchdog_ops, 4583 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 4584 .pot_clear = mv88e6xxx_g2_pot_clear, 4585 .reset = mv88e6352_g1_reset, 4586 .atu_get_hash = mv88e6165_g1_atu_get_hash, 4587 .atu_set_hash = mv88e6165_g1_atu_set_hash, 4588 .vtu_getnext = mv88e6352_g1_vtu_getnext, 4589 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 4590 .stu_getnext = mv88e6352_g1_stu_getnext, 4591 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 4592 .phylink_get_caps = mv88e6351_phylink_get_caps, 4593}; 4594 4595static const struct mv88e6xxx_ops mv88e6172_ops = { 4596 /* MV88E6XXX_FAMILY_6352 */ 4597 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4598 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4599 .irl_init_all = mv88e6352_g2_irl_init_all, 4600 .get_eeprom = mv88e6xxx_g2_get_eeprom16, 4601 .set_eeprom = mv88e6xxx_g2_set_eeprom16, 4602 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 4603 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 4604 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 4605 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 4606 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 4607 .port_set_link = mv88e6xxx_port_set_link, 4608 .port_sync_link = mv88e6xxx_port_sync_link, 4609 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, 4610 .port_set_speed_duplex = mv88e6352_port_set_speed_duplex, 4611 .port_tag_remap = mv88e6095_port_tag_remap, 4612 .port_set_policy = mv88e6352_port_set_policy, 4613 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 4614 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 4615 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 4616 .port_set_ether_type = mv88e6351_port_set_ether_type, 4617 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 4618 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 4619 .port_pause_limit = mv88e6097_port_pause_limit, 4620 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4621 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 4622 .port_get_cmode = mv88e6352_port_get_cmode, 4623 .port_setup_leds = mv88e6xxx_port_setup_leds, 4624 .port_setup_message_port = mv88e6xxx_setup_message_port, 4625 .stats_snapshot = mv88e6320_g1_stats_snapshot, 4626 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 4627 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 4628 .stats_get_strings = mv88e6095_stats_get_strings, 4629 .stats_get_stat = mv88e6095_stats_get_stat, 4630 .set_cpu_port = mv88e6095_g1_set_cpu_port, 4631 .set_egress_port = mv88e6095_g1_set_egress_port, 4632 .watchdog_ops = &mv88e6097_watchdog_ops, 4633 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 4634 .pot_clear = mv88e6xxx_g2_pot_clear, 4635 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 4636 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 4637 .reset = mv88e6352_g1_reset, 4638 .rmu_disable = mv88e6352_g1_rmu_disable, 4639 .atu_get_hash = mv88e6165_g1_atu_get_hash, 4640 .atu_set_hash = mv88e6165_g1_atu_set_hash, 4641 .vtu_getnext = mv88e6352_g1_vtu_getnext, 4642 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 4643 .stu_getnext = mv88e6352_g1_stu_getnext, 4644 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 4645 .serdes_get_regs_len = mv88e6352_serdes_get_regs_len, 4646 .serdes_get_regs = mv88e6352_serdes_get_regs, 4647 .gpio_ops = &mv88e6352_gpio_ops, 4648 .phylink_get_caps = mv88e6352_phylink_get_caps, 4649 .pcs_ops = &mv88e6352_pcs_ops, 4650}; 4651 4652static const struct mv88e6xxx_ops mv88e6175_ops = { 4653 /* MV88E6XXX_FAMILY_6351 */ 4654 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4655 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4656 .irl_init_all = mv88e6352_g2_irl_init_all, 4657 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 4658 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 4659 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 4660 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 4661 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 4662 .port_set_link = mv88e6xxx_port_set_link, 4663 .port_sync_link = mv88e6xxx_port_sync_link, 4664 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, 4665 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 4666 .port_tag_remap = mv88e6095_port_tag_remap, 4667 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 4668 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 4669 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 4670 .port_set_ether_type = mv88e6351_port_set_ether_type, 4671 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 4672 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 4673 .port_pause_limit = mv88e6097_port_pause_limit, 4674 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4675 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 4676 .port_get_cmode = mv88e6352_port_get_cmode, 4677 .port_setup_message_port = mv88e6xxx_setup_message_port, 4678 .stats_snapshot = mv88e6320_g1_stats_snapshot, 4679 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 4680 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 4681 .stats_get_strings = mv88e6095_stats_get_strings, 4682 .stats_get_stat = mv88e6095_stats_get_stat, 4683 .set_cpu_port = mv88e6095_g1_set_cpu_port, 4684 .set_egress_port = mv88e6095_g1_set_egress_port, 4685 .watchdog_ops = &mv88e6097_watchdog_ops, 4686 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 4687 .pot_clear = mv88e6xxx_g2_pot_clear, 4688 .reset = mv88e6352_g1_reset, 4689 .atu_get_hash = mv88e6165_g1_atu_get_hash, 4690 .atu_set_hash = mv88e6165_g1_atu_set_hash, 4691 .vtu_getnext = mv88e6352_g1_vtu_getnext, 4692 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 4693 .stu_getnext = mv88e6352_g1_stu_getnext, 4694 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 4695 .phylink_get_caps = mv88e6351_phylink_get_caps, 4696}; 4697 4698static const struct mv88e6xxx_ops mv88e6176_ops = { 4699 /* MV88E6XXX_FAMILY_6352 */ 4700 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4701 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4702 .irl_init_all = mv88e6352_g2_irl_init_all, 4703 .get_eeprom = mv88e6xxx_g2_get_eeprom16, 4704 .set_eeprom = mv88e6xxx_g2_set_eeprom16, 4705 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 4706 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 4707 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 4708 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 4709 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 4710 .port_set_link = mv88e6xxx_port_set_link, 4711 .port_sync_link = mv88e6xxx_port_sync_link, 4712 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, 4713 .port_set_speed_duplex = mv88e6352_port_set_speed_duplex, 4714 .port_tag_remap = mv88e6095_port_tag_remap, 4715 .port_set_policy = mv88e6352_port_set_policy, 4716 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 4717 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 4718 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 4719 .port_set_ether_type = mv88e6351_port_set_ether_type, 4720 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 4721 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 4722 .port_pause_limit = mv88e6097_port_pause_limit, 4723 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4724 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 4725 .port_get_cmode = mv88e6352_port_get_cmode, 4726 .port_setup_leds = mv88e6xxx_port_setup_leds, 4727 .port_setup_message_port = mv88e6xxx_setup_message_port, 4728 .stats_snapshot = mv88e6320_g1_stats_snapshot, 4729 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 4730 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 4731 .stats_get_strings = mv88e6095_stats_get_strings, 4732 .stats_get_stat = mv88e6095_stats_get_stat, 4733 .set_cpu_port = mv88e6095_g1_set_cpu_port, 4734 .set_egress_port = mv88e6095_g1_set_egress_port, 4735 .watchdog_ops = &mv88e6097_watchdog_ops, 4736 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 4737 .pot_clear = mv88e6xxx_g2_pot_clear, 4738 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 4739 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 4740 .reset = mv88e6352_g1_reset, 4741 .rmu_disable = mv88e6352_g1_rmu_disable, 4742 .atu_get_hash = mv88e6165_g1_atu_get_hash, 4743 .atu_set_hash = mv88e6165_g1_atu_set_hash, 4744 .vtu_getnext = mv88e6352_g1_vtu_getnext, 4745 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 4746 .stu_getnext = mv88e6352_g1_stu_getnext, 4747 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 4748 .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, 4749 .serdes_get_regs_len = mv88e6352_serdes_get_regs_len, 4750 .serdes_get_regs = mv88e6352_serdes_get_regs, 4751 .gpio_ops = &mv88e6352_gpio_ops, 4752 .phylink_get_caps = mv88e6352_phylink_get_caps, 4753 .pcs_ops = &mv88e6352_pcs_ops, 4754}; 4755 4756static const struct mv88e6xxx_ops mv88e6185_ops = { 4757 /* MV88E6XXX_FAMILY_6185 */ 4758 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4759 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4760 .set_switch_mac = mv88e6xxx_g1_set_switch_mac, 4761 .phy_read = mv88e6185_phy_ppu_read, 4762 .phy_write = mv88e6185_phy_ppu_write, 4763 .port_set_link = mv88e6xxx_port_set_link, 4764 .port_sync_link = mv88e6185_port_sync_link, 4765 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 4766 .port_set_frame_mode = mv88e6085_port_set_frame_mode, 4767 .port_set_ucast_flood = mv88e6185_port_set_forward_unknown, 4768 .port_set_mcast_flood = mv88e6185_port_set_default_forward, 4769 .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting, 4770 .port_set_upstream_port = mv88e6095_port_set_upstream_port, 4771 .port_set_pause = mv88e6185_port_set_pause, 4772 .port_get_cmode = mv88e6185_port_get_cmode, 4773 .port_setup_message_port = mv88e6xxx_setup_message_port, 4774 .stats_snapshot = mv88e6xxx_g1_stats_snapshot, 4775 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 4776 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 4777 .stats_get_strings = mv88e6095_stats_get_strings, 4778 .stats_get_stat = mv88e6095_stats_get_stat, 4779 .set_cpu_port = mv88e6095_g1_set_cpu_port, 4780 .set_egress_port = mv88e6095_g1_set_egress_port, 4781 .watchdog_ops = &mv88e6097_watchdog_ops, 4782 .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu, 4783 .set_cascade_port = mv88e6185_g1_set_cascade_port, 4784 .ppu_enable = mv88e6185_g1_ppu_enable, 4785 .ppu_disable = mv88e6185_g1_ppu_disable, 4786 .reset = mv88e6185_g1_reset, 4787 .vtu_getnext = mv88e6185_g1_vtu_getnext, 4788 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, 4789 .phylink_get_caps = mv88e6185_phylink_get_caps, 4790 .pcs_ops = &mv88e6185_pcs_ops, 4791 .set_max_frame_size = mv88e6185_g1_set_max_frame_size, 4792}; 4793 4794static const struct mv88e6xxx_ops mv88e6190_ops = { 4795 /* MV88E6XXX_FAMILY_6390 */ 4796 .setup_errata = mv88e6390_setup_errata, 4797 .irl_init_all = mv88e6390_g2_irl_init_all, 4798 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 4799 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 4800 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 4801 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 4802 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 4803 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 4804 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 4805 .port_set_link = mv88e6xxx_port_set_link, 4806 .port_sync_link = mv88e6xxx_port_sync_link, 4807 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, 4808 .port_set_speed_duplex = mv88e6390_port_set_speed_duplex, 4809 .port_max_speed_mode = mv88e6390_port_max_speed_mode, 4810 .port_tag_remap = mv88e6390_port_tag_remap, 4811 .port_set_policy = mv88e6352_port_set_policy, 4812 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 4813 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 4814 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 4815 .port_set_ether_type = mv88e6351_port_set_ether_type, 4816 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 4817 .port_pause_limit = mv88e6390_port_pause_limit, 4818 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4819 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 4820 .port_get_cmode = mv88e6352_port_get_cmode, 4821 .port_set_cmode = mv88e6390_port_set_cmode, 4822 .port_setup_message_port = mv88e6xxx_setup_message_port, 4823 .stats_snapshot = mv88e6390_g1_stats_snapshot, 4824 .stats_set_histogram = mv88e6390_g1_stats_set_histogram, 4825 .stats_get_sset_count = mv88e6320_stats_get_sset_count, 4826 .stats_get_strings = mv88e6320_stats_get_strings, 4827 .stats_get_stat = mv88e6390_stats_get_stat, 4828 .set_cpu_port = mv88e6390_g1_set_cpu_port, 4829 .set_egress_port = mv88e6390_g1_set_egress_port, 4830 .watchdog_ops = &mv88e6390_watchdog_ops, 4831 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, 4832 .pot_clear = mv88e6xxx_g2_pot_clear, 4833 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 4834 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 4835 .reset = mv88e6352_g1_reset, 4836 .rmu_disable = mv88e6390_g1_rmu_disable, 4837 .atu_get_hash = mv88e6165_g1_atu_get_hash, 4838 .atu_set_hash = mv88e6165_g1_atu_set_hash, 4839 .vtu_getnext = mv88e6390_g1_vtu_getnext, 4840 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, 4841 .stu_getnext = mv88e6390_g1_stu_getnext, 4842 .stu_loadpurge = mv88e6390_g1_stu_loadpurge, 4843 .serdes_get_lane = mv88e6390_serdes_get_lane, 4844 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 4845 .serdes_get_strings = mv88e6390_serdes_get_strings, 4846 .serdes_get_stats = mv88e6390_serdes_get_stats, 4847 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, 4848 .serdes_get_regs = mv88e6390_serdes_get_regs, 4849 .gpio_ops = &mv88e6352_gpio_ops, 4850 .phylink_get_caps = mv88e6390_phylink_get_caps, 4851 .pcs_ops = &mv88e6390_pcs_ops, 4852}; 4853 4854static const struct mv88e6xxx_ops mv88e6190x_ops = { 4855 /* MV88E6XXX_FAMILY_6390 */ 4856 .setup_errata = mv88e6390_setup_errata, 4857 .irl_init_all = mv88e6390_g2_irl_init_all, 4858 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 4859 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 4860 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 4861 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 4862 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 4863 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 4864 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 4865 .port_set_link = mv88e6xxx_port_set_link, 4866 .port_sync_link = mv88e6xxx_port_sync_link, 4867 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, 4868 .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex, 4869 .port_max_speed_mode = mv88e6390x_port_max_speed_mode, 4870 .port_tag_remap = mv88e6390_port_tag_remap, 4871 .port_set_policy = mv88e6352_port_set_policy, 4872 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 4873 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 4874 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 4875 .port_set_ether_type = mv88e6351_port_set_ether_type, 4876 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 4877 .port_pause_limit = mv88e6390_port_pause_limit, 4878 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4879 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 4880 .port_get_cmode = mv88e6352_port_get_cmode, 4881 .port_set_cmode = mv88e6390x_port_set_cmode, 4882 .port_setup_message_port = mv88e6xxx_setup_message_port, 4883 .stats_snapshot = mv88e6390_g1_stats_snapshot, 4884 .stats_set_histogram = mv88e6390_g1_stats_set_histogram, 4885 .stats_get_sset_count = mv88e6320_stats_get_sset_count, 4886 .stats_get_strings = mv88e6320_stats_get_strings, 4887 .stats_get_stat = mv88e6390_stats_get_stat, 4888 .set_cpu_port = mv88e6390_g1_set_cpu_port, 4889 .set_egress_port = mv88e6390_g1_set_egress_port, 4890 .watchdog_ops = &mv88e6390_watchdog_ops, 4891 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, 4892 .pot_clear = mv88e6xxx_g2_pot_clear, 4893 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 4894 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 4895 .reset = mv88e6352_g1_reset, 4896 .rmu_disable = mv88e6390_g1_rmu_disable, 4897 .atu_get_hash = mv88e6165_g1_atu_get_hash, 4898 .atu_set_hash = mv88e6165_g1_atu_set_hash, 4899 .vtu_getnext = mv88e6390_g1_vtu_getnext, 4900 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, 4901 .stu_getnext = mv88e6390_g1_stu_getnext, 4902 .stu_loadpurge = mv88e6390_g1_stu_loadpurge, 4903 .serdes_get_lane = mv88e6390x_serdes_get_lane, 4904 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 4905 .serdes_get_strings = mv88e6390_serdes_get_strings, 4906 .serdes_get_stats = mv88e6390_serdes_get_stats, 4907 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, 4908 .serdes_get_regs = mv88e6390_serdes_get_regs, 4909 .gpio_ops = &mv88e6352_gpio_ops, 4910 .phylink_get_caps = mv88e6390x_phylink_get_caps, 4911 .pcs_ops = &mv88e6390_pcs_ops, 4912}; 4913 4914static const struct mv88e6xxx_ops mv88e6191_ops = { 4915 /* MV88E6XXX_FAMILY_6390 */ 4916 .setup_errata = mv88e6390_setup_errata, 4917 .irl_init_all = mv88e6390_g2_irl_init_all, 4918 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 4919 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 4920 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 4921 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 4922 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 4923 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 4924 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 4925 .port_set_link = mv88e6xxx_port_set_link, 4926 .port_sync_link = mv88e6xxx_port_sync_link, 4927 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, 4928 .port_set_speed_duplex = mv88e6390_port_set_speed_duplex, 4929 .port_max_speed_mode = mv88e6390_port_max_speed_mode, 4930 .port_tag_remap = mv88e6390_port_tag_remap, 4931 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 4932 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 4933 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 4934 .port_set_ether_type = mv88e6351_port_set_ether_type, 4935 .port_pause_limit = mv88e6390_port_pause_limit, 4936 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4937 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 4938 .port_get_cmode = mv88e6352_port_get_cmode, 4939 .port_set_cmode = mv88e6390_port_set_cmode, 4940 .port_setup_message_port = mv88e6xxx_setup_message_port, 4941 .stats_snapshot = mv88e6390_g1_stats_snapshot, 4942 .stats_set_histogram = mv88e6390_g1_stats_set_histogram, 4943 .stats_get_sset_count = mv88e6320_stats_get_sset_count, 4944 .stats_get_strings = mv88e6320_stats_get_strings, 4945 .stats_get_stat = mv88e6390_stats_get_stat, 4946 .set_cpu_port = mv88e6390_g1_set_cpu_port, 4947 .set_egress_port = mv88e6390_g1_set_egress_port, 4948 .watchdog_ops = &mv88e6390_watchdog_ops, 4949 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, 4950 .pot_clear = mv88e6xxx_g2_pot_clear, 4951 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 4952 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 4953 .reset = mv88e6352_g1_reset, 4954 .rmu_disable = mv88e6390_g1_rmu_disable, 4955 .atu_get_hash = mv88e6165_g1_atu_get_hash, 4956 .atu_set_hash = mv88e6165_g1_atu_set_hash, 4957 .vtu_getnext = mv88e6390_g1_vtu_getnext, 4958 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, 4959 .stu_getnext = mv88e6390_g1_stu_getnext, 4960 .stu_loadpurge = mv88e6390_g1_stu_loadpurge, 4961 .serdes_get_lane = mv88e6390_serdes_get_lane, 4962 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 4963 .serdes_get_strings = mv88e6390_serdes_get_strings, 4964 .serdes_get_stats = mv88e6390_serdes_get_stats, 4965 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, 4966 .serdes_get_regs = mv88e6390_serdes_get_regs, 4967 .avb_ops = &mv88e6390_avb_ops, 4968 .ptp_ops = &mv88e6352_ptp_ops, 4969 .phylink_get_caps = mv88e6390_phylink_get_caps, 4970 .pcs_ops = &mv88e6390_pcs_ops, 4971}; 4972 4973static const struct mv88e6xxx_ops mv88e6240_ops = { 4974 /* MV88E6XXX_FAMILY_6352 */ 4975 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 4976 .ip_pri_map = mv88e6085_g1_ip_pri_map, 4977 .irl_init_all = mv88e6352_g2_irl_init_all, 4978 .get_eeprom = mv88e6xxx_g2_get_eeprom16, 4979 .set_eeprom = mv88e6xxx_g2_set_eeprom16, 4980 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 4981 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 4982 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 4983 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 4984 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 4985 .port_set_link = mv88e6xxx_port_set_link, 4986 .port_sync_link = mv88e6xxx_port_sync_link, 4987 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, 4988 .port_set_speed_duplex = mv88e6352_port_set_speed_duplex, 4989 .port_tag_remap = mv88e6095_port_tag_remap, 4990 .port_set_policy = mv88e6352_port_set_policy, 4991 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 4992 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 4993 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 4994 .port_set_ether_type = mv88e6351_port_set_ether_type, 4995 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 4996 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 4997 .port_pause_limit = mv88e6097_port_pause_limit, 4998 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 4999 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 5000 .port_get_cmode = mv88e6352_port_get_cmode, 5001 .port_setup_leds = mv88e6xxx_port_setup_leds, 5002 .port_setup_message_port = mv88e6xxx_setup_message_port, 5003 .stats_snapshot = mv88e6320_g1_stats_snapshot, 5004 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 5005 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 5006 .stats_get_strings = mv88e6095_stats_get_strings, 5007 .stats_get_stat = mv88e6095_stats_get_stat, 5008 .set_cpu_port = mv88e6095_g1_set_cpu_port, 5009 .set_egress_port = mv88e6095_g1_set_egress_port, 5010 .watchdog_ops = &mv88e6097_watchdog_ops, 5011 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 5012 .pot_clear = mv88e6xxx_g2_pot_clear, 5013 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 5014 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 5015 .reset = mv88e6352_g1_reset, 5016 .rmu_disable = mv88e6352_g1_rmu_disable, 5017 .atu_get_hash = mv88e6165_g1_atu_get_hash, 5018 .atu_set_hash = mv88e6165_g1_atu_set_hash, 5019 .vtu_getnext = mv88e6352_g1_vtu_getnext, 5020 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 5021 .stu_getnext = mv88e6352_g1_stu_getnext, 5022 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 5023 .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, 5024 .serdes_get_regs_len = mv88e6352_serdes_get_regs_len, 5025 .serdes_get_regs = mv88e6352_serdes_get_regs, 5026 .gpio_ops = &mv88e6352_gpio_ops, 5027 .avb_ops = &mv88e6352_avb_ops, 5028 .ptp_ops = &mv88e6352_ptp_ops, 5029 .phylink_get_caps = mv88e6352_phylink_get_caps, 5030 .pcs_ops = &mv88e6352_pcs_ops, 5031}; 5032 5033static const struct mv88e6xxx_ops mv88e6250_ops = { 5034 /* MV88E6XXX_FAMILY_6250 */ 5035 .ieee_pri_map = mv88e6250_g1_ieee_pri_map, 5036 .ip_pri_map = mv88e6085_g1_ip_pri_map, 5037 .irl_init_all = mv88e6352_g2_irl_init_all, 5038 .get_eeprom = mv88e6xxx_g2_get_eeprom16, 5039 .set_eeprom = mv88e6xxx_g2_set_eeprom16, 5040 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 5041 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 5042 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 5043 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 5044 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 5045 .port_set_link = mv88e6xxx_port_set_link, 5046 .port_sync_link = mv88e6xxx_port_sync_link, 5047 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, 5048 .port_set_speed_duplex = mv88e6250_port_set_speed_duplex, 5049 .port_tag_remap = mv88e6095_port_tag_remap, 5050 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 5051 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 5052 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 5053 .port_set_ether_type = mv88e6351_port_set_ether_type, 5054 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 5055 .port_pause_limit = mv88e6097_port_pause_limit, 5056 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 5057 .stats_snapshot = mv88e6320_g1_stats_snapshot, 5058 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 5059 .stats_get_sset_count = mv88e6250_stats_get_sset_count, 5060 .stats_get_strings = mv88e6250_stats_get_strings, 5061 .stats_get_stat = mv88e6250_stats_get_stat, 5062 .set_cpu_port = mv88e6095_g1_set_cpu_port, 5063 .set_egress_port = mv88e6095_g1_set_egress_port, 5064 .watchdog_ops = &mv88e6250_watchdog_ops, 5065 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 5066 .pot_clear = mv88e6xxx_g2_pot_clear, 5067 .hardware_reset_pre = mv88e6250_g1_wait_eeprom_done_prereset, 5068 .hardware_reset_post = mv88e6xxx_g1_wait_eeprom_done, 5069 .reset = mv88e6250_g1_reset, 5070 .vtu_getnext = mv88e6185_g1_vtu_getnext, 5071 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, 5072 .avb_ops = &mv88e6352_avb_ops, 5073 .ptp_ops = &mv88e6352_ptp_ops, 5074 .phylink_get_caps = mv88e6250_phylink_get_caps, 5075 .set_max_frame_size = mv88e6185_g1_set_max_frame_size, 5076}; 5077 5078static const struct mv88e6xxx_ops mv88e6290_ops = { 5079 /* MV88E6XXX_FAMILY_6390 */ 5080 .setup_errata = mv88e6390_setup_errata, 5081 .irl_init_all = mv88e6390_g2_irl_init_all, 5082 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 5083 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 5084 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 5085 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 5086 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 5087 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 5088 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 5089 .port_set_link = mv88e6xxx_port_set_link, 5090 .port_sync_link = mv88e6xxx_port_sync_link, 5091 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, 5092 .port_set_speed_duplex = mv88e6390_port_set_speed_duplex, 5093 .port_max_speed_mode = mv88e6390_port_max_speed_mode, 5094 .port_tag_remap = mv88e6390_port_tag_remap, 5095 .port_set_policy = mv88e6352_port_set_policy, 5096 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 5097 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 5098 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 5099 .port_set_ether_type = mv88e6351_port_set_ether_type, 5100 .port_pause_limit = mv88e6390_port_pause_limit, 5101 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 5102 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 5103 .port_get_cmode = mv88e6352_port_get_cmode, 5104 .port_set_cmode = mv88e6390_port_set_cmode, 5105 .port_setup_message_port = mv88e6xxx_setup_message_port, 5106 .stats_snapshot = mv88e6390_g1_stats_snapshot, 5107 .stats_set_histogram = mv88e6390_g1_stats_set_histogram, 5108 .stats_get_sset_count = mv88e6320_stats_get_sset_count, 5109 .stats_get_strings = mv88e6320_stats_get_strings, 5110 .stats_get_stat = mv88e6390_stats_get_stat, 5111 .set_cpu_port = mv88e6390_g1_set_cpu_port, 5112 .set_egress_port = mv88e6390_g1_set_egress_port, 5113 .watchdog_ops = &mv88e6390_watchdog_ops, 5114 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, 5115 .pot_clear = mv88e6xxx_g2_pot_clear, 5116 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 5117 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 5118 .reset = mv88e6352_g1_reset, 5119 .rmu_disable = mv88e6390_g1_rmu_disable, 5120 .atu_get_hash = mv88e6165_g1_atu_get_hash, 5121 .atu_set_hash = mv88e6165_g1_atu_set_hash, 5122 .vtu_getnext = mv88e6390_g1_vtu_getnext, 5123 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, 5124 .stu_getnext = mv88e6390_g1_stu_getnext, 5125 .stu_loadpurge = mv88e6390_g1_stu_loadpurge, 5126 .serdes_get_lane = mv88e6390_serdes_get_lane, 5127 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 5128 .serdes_get_strings = mv88e6390_serdes_get_strings, 5129 .serdes_get_stats = mv88e6390_serdes_get_stats, 5130 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, 5131 .serdes_get_regs = mv88e6390_serdes_get_regs, 5132 .gpio_ops = &mv88e6352_gpio_ops, 5133 .avb_ops = &mv88e6390_avb_ops, 5134 .ptp_ops = &mv88e6390_ptp_ops, 5135 .phylink_get_caps = mv88e6390_phylink_get_caps, 5136 .pcs_ops = &mv88e6390_pcs_ops, 5137}; 5138 5139static const struct mv88e6xxx_ops mv88e6320_ops = { 5140 /* MV88E6XXX_FAMILY_6320 */ 5141 .setup_errata = mv88e6320_setup_errata, 5142 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 5143 .ip_pri_map = mv88e6085_g1_ip_pri_map, 5144 .irl_init_all = mv88e6352_g2_irl_init_all, 5145 .get_eeprom = mv88e6xxx_g2_get_eeprom16, 5146 .set_eeprom = mv88e6xxx_g2_set_eeprom16, 5147 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 5148 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 5149 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 5150 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 5151 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 5152 .port_set_link = mv88e6xxx_port_set_link, 5153 .port_sync_link = mv88e6xxx_port_sync_link, 5154 .port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay, 5155 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 5156 .port_tag_remap = mv88e6095_port_tag_remap, 5157 .port_set_policy = mv88e6352_port_set_policy, 5158 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 5159 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 5160 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 5161 .port_set_ether_type = mv88e6351_port_set_ether_type, 5162 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 5163 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 5164 .port_pause_limit = mv88e6097_port_pause_limit, 5165 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 5166 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 5167 .port_get_cmode = mv88e6352_port_get_cmode, 5168 .port_setup_message_port = mv88e6xxx_setup_message_port, 5169 .stats_snapshot = mv88e6320_g1_stats_snapshot, 5170 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 5171 .stats_get_sset_count = mv88e6320_stats_get_sset_count, 5172 .stats_get_strings = mv88e6320_stats_get_strings, 5173 .stats_get_stat = mv88e6320_stats_get_stat, 5174 .set_cpu_port = mv88e6095_g1_set_cpu_port, 5175 .set_egress_port = mv88e6095_g1_set_egress_port, 5176 .watchdog_ops = &mv88e6390_watchdog_ops, 5177 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 5178 .pot_clear = mv88e6xxx_g2_pot_clear, 5179 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 5180 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 5181 .reset = mv88e6352_g1_reset, 5182 .vtu_getnext = mv88e6352_g1_vtu_getnext, 5183 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 5184 .stu_getnext = mv88e6352_g1_stu_getnext, 5185 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 5186 .gpio_ops = &mv88e6352_gpio_ops, 5187 .avb_ops = &mv88e6352_avb_ops, 5188 .ptp_ops = &mv88e6352_ptp_ops, 5189 .phylink_get_caps = mv88e632x_phylink_get_caps, 5190}; 5191 5192static const struct mv88e6xxx_ops mv88e6321_ops = { 5193 /* MV88E6XXX_FAMILY_6320 */ 5194 .setup_errata = mv88e6320_setup_errata, 5195 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 5196 .ip_pri_map = mv88e6085_g1_ip_pri_map, 5197 .irl_init_all = mv88e6352_g2_irl_init_all, 5198 .get_eeprom = mv88e6xxx_g2_get_eeprom16, 5199 .set_eeprom = mv88e6xxx_g2_set_eeprom16, 5200 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 5201 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 5202 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 5203 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 5204 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 5205 .port_set_link = mv88e6xxx_port_set_link, 5206 .port_sync_link = mv88e6xxx_port_sync_link, 5207 .port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay, 5208 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 5209 .port_tag_remap = mv88e6095_port_tag_remap, 5210 .port_set_policy = mv88e6352_port_set_policy, 5211 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 5212 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 5213 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 5214 .port_set_ether_type = mv88e6351_port_set_ether_type, 5215 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 5216 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 5217 .port_pause_limit = mv88e6097_port_pause_limit, 5218 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 5219 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 5220 .port_get_cmode = mv88e6352_port_get_cmode, 5221 .port_setup_message_port = mv88e6xxx_setup_message_port, 5222 .stats_snapshot = mv88e6320_g1_stats_snapshot, 5223 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 5224 .stats_get_sset_count = mv88e6320_stats_get_sset_count, 5225 .stats_get_strings = mv88e6320_stats_get_strings, 5226 .stats_get_stat = mv88e6320_stats_get_stat, 5227 .set_cpu_port = mv88e6095_g1_set_cpu_port, 5228 .set_egress_port = mv88e6095_g1_set_egress_port, 5229 .watchdog_ops = &mv88e6390_watchdog_ops, 5230 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 5231 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 5232 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 5233 .reset = mv88e6352_g1_reset, 5234 .vtu_getnext = mv88e6352_g1_vtu_getnext, 5235 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 5236 .stu_getnext = mv88e6352_g1_stu_getnext, 5237 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 5238 .gpio_ops = &mv88e6352_gpio_ops, 5239 .avb_ops = &mv88e6352_avb_ops, 5240 .ptp_ops = &mv88e6352_ptp_ops, 5241 .phylink_get_caps = mv88e632x_phylink_get_caps, 5242}; 5243 5244static const struct mv88e6xxx_ops mv88e6341_ops = { 5245 /* MV88E6XXX_FAMILY_6341 */ 5246 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 5247 .ip_pri_map = mv88e6085_g1_ip_pri_map, 5248 .irl_init_all = mv88e6352_g2_irl_init_all, 5249 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 5250 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 5251 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 5252 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 5253 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 5254 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 5255 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 5256 .port_set_link = mv88e6xxx_port_set_link, 5257 .port_sync_link = mv88e6xxx_port_sync_link, 5258 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, 5259 .port_set_speed_duplex = mv88e6341_port_set_speed_duplex, 5260 .port_max_speed_mode = mv88e6341_port_max_speed_mode, 5261 .port_tag_remap = mv88e6095_port_tag_remap, 5262 .port_set_policy = mv88e6352_port_set_policy, 5263 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 5264 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 5265 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 5266 .port_set_ether_type = mv88e6351_port_set_ether_type, 5267 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 5268 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 5269 .port_pause_limit = mv88e6097_port_pause_limit, 5270 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 5271 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 5272 .port_get_cmode = mv88e6352_port_get_cmode, 5273 .port_set_cmode = mv88e6341_port_set_cmode, 5274 .port_setup_message_port = mv88e6xxx_setup_message_port, 5275 .stats_snapshot = mv88e6390_g1_stats_snapshot, 5276 .stats_set_histogram = mv88e6390_g1_stats_set_histogram, 5277 .stats_get_sset_count = mv88e6320_stats_get_sset_count, 5278 .stats_get_strings = mv88e6320_stats_get_strings, 5279 .stats_get_stat = mv88e6390_stats_get_stat, 5280 .set_cpu_port = mv88e6390_g1_set_cpu_port, 5281 .set_egress_port = mv88e6390_g1_set_egress_port, 5282 .watchdog_ops = &mv88e6390_watchdog_ops, 5283 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, 5284 .pot_clear = mv88e6xxx_g2_pot_clear, 5285 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 5286 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 5287 .reset = mv88e6352_g1_reset, 5288 .rmu_disable = mv88e6390_g1_rmu_disable, 5289 .atu_get_hash = mv88e6165_g1_atu_get_hash, 5290 .atu_set_hash = mv88e6165_g1_atu_set_hash, 5291 .vtu_getnext = mv88e6352_g1_vtu_getnext, 5292 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 5293 .stu_getnext = mv88e6352_g1_stu_getnext, 5294 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 5295 .serdes_get_lane = mv88e6341_serdes_get_lane, 5296 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 5297 .gpio_ops = &mv88e6352_gpio_ops, 5298 .avb_ops = &mv88e6390_avb_ops, 5299 .ptp_ops = &mv88e6352_ptp_ops, 5300 .serdes_get_sset_count = mv88e6390_serdes_get_sset_count, 5301 .serdes_get_strings = mv88e6390_serdes_get_strings, 5302 .serdes_get_stats = mv88e6390_serdes_get_stats, 5303 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, 5304 .serdes_get_regs = mv88e6390_serdes_get_regs, 5305 .phylink_get_caps = mv88e6341_phylink_get_caps, 5306 .pcs_ops = &mv88e6390_pcs_ops, 5307}; 5308 5309static const struct mv88e6xxx_ops mv88e6350_ops = { 5310 /* MV88E6XXX_FAMILY_6351 */ 5311 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 5312 .ip_pri_map = mv88e6085_g1_ip_pri_map, 5313 .irl_init_all = mv88e6352_g2_irl_init_all, 5314 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 5315 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 5316 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 5317 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 5318 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 5319 .port_set_link = mv88e6xxx_port_set_link, 5320 .port_sync_link = mv88e6xxx_port_sync_link, 5321 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, 5322 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 5323 .port_tag_remap = mv88e6095_port_tag_remap, 5324 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 5325 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 5326 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 5327 .port_set_ether_type = mv88e6351_port_set_ether_type, 5328 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 5329 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 5330 .port_pause_limit = mv88e6097_port_pause_limit, 5331 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 5332 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 5333 .port_get_cmode = mv88e6352_port_get_cmode, 5334 .port_setup_message_port = mv88e6xxx_setup_message_port, 5335 .stats_snapshot = mv88e6320_g1_stats_snapshot, 5336 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 5337 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 5338 .stats_get_strings = mv88e6095_stats_get_strings, 5339 .stats_get_stat = mv88e6095_stats_get_stat, 5340 .set_cpu_port = mv88e6095_g1_set_cpu_port, 5341 .set_egress_port = mv88e6095_g1_set_egress_port, 5342 .watchdog_ops = &mv88e6097_watchdog_ops, 5343 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 5344 .pot_clear = mv88e6xxx_g2_pot_clear, 5345 .reset = mv88e6352_g1_reset, 5346 .atu_get_hash = mv88e6165_g1_atu_get_hash, 5347 .atu_set_hash = mv88e6165_g1_atu_set_hash, 5348 .vtu_getnext = mv88e6352_g1_vtu_getnext, 5349 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 5350 .stu_getnext = mv88e6352_g1_stu_getnext, 5351 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 5352 .phylink_get_caps = mv88e6351_phylink_get_caps, 5353}; 5354 5355static const struct mv88e6xxx_ops mv88e6351_ops = { 5356 /* MV88E6XXX_FAMILY_6351 */ 5357 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 5358 .ip_pri_map = mv88e6085_g1_ip_pri_map, 5359 .irl_init_all = mv88e6352_g2_irl_init_all, 5360 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 5361 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 5362 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 5363 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 5364 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 5365 .port_set_link = mv88e6xxx_port_set_link, 5366 .port_sync_link = mv88e6xxx_port_sync_link, 5367 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, 5368 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, 5369 .port_tag_remap = mv88e6095_port_tag_remap, 5370 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 5371 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 5372 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 5373 .port_set_ether_type = mv88e6351_port_set_ether_type, 5374 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 5375 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 5376 .port_pause_limit = mv88e6097_port_pause_limit, 5377 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 5378 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 5379 .port_get_cmode = mv88e6352_port_get_cmode, 5380 .port_setup_message_port = mv88e6xxx_setup_message_port, 5381 .stats_snapshot = mv88e6320_g1_stats_snapshot, 5382 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 5383 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 5384 .stats_get_strings = mv88e6095_stats_get_strings, 5385 .stats_get_stat = mv88e6095_stats_get_stat, 5386 .set_cpu_port = mv88e6095_g1_set_cpu_port, 5387 .set_egress_port = mv88e6095_g1_set_egress_port, 5388 .watchdog_ops = &mv88e6097_watchdog_ops, 5389 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 5390 .pot_clear = mv88e6xxx_g2_pot_clear, 5391 .reset = mv88e6352_g1_reset, 5392 .atu_get_hash = mv88e6165_g1_atu_get_hash, 5393 .atu_set_hash = mv88e6165_g1_atu_set_hash, 5394 .vtu_getnext = mv88e6352_g1_vtu_getnext, 5395 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 5396 .stu_getnext = mv88e6352_g1_stu_getnext, 5397 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 5398 .avb_ops = &mv88e6352_avb_ops, 5399 .ptp_ops = &mv88e6352_ptp_ops, 5400 .phylink_get_caps = mv88e6351_phylink_get_caps, 5401}; 5402 5403static const struct mv88e6xxx_ops mv88e6352_ops = { 5404 /* MV88E6XXX_FAMILY_6352 */ 5405 .ieee_pri_map = mv88e6085_g1_ieee_pri_map, 5406 .ip_pri_map = mv88e6085_g1_ip_pri_map, 5407 .irl_init_all = mv88e6352_g2_irl_init_all, 5408 .get_eeprom = mv88e6xxx_g2_get_eeprom16, 5409 .set_eeprom = mv88e6xxx_g2_set_eeprom16, 5410 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 5411 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 5412 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 5413 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 5414 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 5415 .port_set_link = mv88e6xxx_port_set_link, 5416 .port_sync_link = mv88e6xxx_port_sync_link, 5417 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, 5418 .port_set_speed_duplex = mv88e6352_port_set_speed_duplex, 5419 .port_tag_remap = mv88e6095_port_tag_remap, 5420 .port_set_policy = mv88e6352_port_set_policy, 5421 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 5422 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 5423 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 5424 .port_set_ether_type = mv88e6351_port_set_ether_type, 5425 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 5426 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 5427 .port_pause_limit = mv88e6097_port_pause_limit, 5428 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 5429 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 5430 .port_get_cmode = mv88e6352_port_get_cmode, 5431 .port_setup_leds = mv88e6xxx_port_setup_leds, 5432 .port_setup_message_port = mv88e6xxx_setup_message_port, 5433 .stats_snapshot = mv88e6320_g1_stats_snapshot, 5434 .stats_set_histogram = mv88e6095_g1_stats_set_histogram, 5435 .stats_get_sset_count = mv88e6095_stats_get_sset_count, 5436 .stats_get_strings = mv88e6095_stats_get_strings, 5437 .stats_get_stat = mv88e6095_stats_get_stat, 5438 .set_cpu_port = mv88e6095_g1_set_cpu_port, 5439 .set_egress_port = mv88e6095_g1_set_egress_port, 5440 .watchdog_ops = &mv88e6097_watchdog_ops, 5441 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, 5442 .pot_clear = mv88e6xxx_g2_pot_clear, 5443 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 5444 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 5445 .reset = mv88e6352_g1_reset, 5446 .rmu_disable = mv88e6352_g1_rmu_disable, 5447 .atu_get_hash = mv88e6165_g1_atu_get_hash, 5448 .atu_set_hash = mv88e6165_g1_atu_set_hash, 5449 .vtu_getnext = mv88e6352_g1_vtu_getnext, 5450 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 5451 .stu_getnext = mv88e6352_g1_stu_getnext, 5452 .stu_loadpurge = mv88e6352_g1_stu_loadpurge, 5453 .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, 5454 .gpio_ops = &mv88e6352_gpio_ops, 5455 .avb_ops = &mv88e6352_avb_ops, 5456 .ptp_ops = &mv88e6352_ptp_ops, 5457 .serdes_get_sset_count = mv88e6352_serdes_get_sset_count, 5458 .serdes_get_strings = mv88e6352_serdes_get_strings, 5459 .serdes_get_stats = mv88e6352_serdes_get_stats, 5460 .serdes_get_regs_len = mv88e6352_serdes_get_regs_len, 5461 .serdes_get_regs = mv88e6352_serdes_get_regs, 5462 .phylink_get_caps = mv88e6352_phylink_get_caps, 5463 .pcs_ops = &mv88e6352_pcs_ops, 5464}; 5465 5466static const struct mv88e6xxx_ops mv88e6390_ops = { 5467 /* MV88E6XXX_FAMILY_6390 */ 5468 .setup_errata = mv88e6390_setup_errata, 5469 .irl_init_all = mv88e6390_g2_irl_init_all, 5470 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 5471 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 5472 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 5473 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 5474 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 5475 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 5476 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 5477 .port_set_link = mv88e6xxx_port_set_link, 5478 .port_sync_link = mv88e6xxx_port_sync_link, 5479 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, 5480 .port_set_speed_duplex = mv88e6390_port_set_speed_duplex, 5481 .port_max_speed_mode = mv88e6390_port_max_speed_mode, 5482 .port_tag_remap = mv88e6390_port_tag_remap, 5483 .port_set_policy = mv88e6352_port_set_policy, 5484 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 5485 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 5486 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 5487 .port_set_ether_type = mv88e6351_port_set_ether_type, 5488 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 5489 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 5490 .port_pause_limit = mv88e6390_port_pause_limit, 5491 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 5492 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 5493 .port_get_cmode = mv88e6352_port_get_cmode, 5494 .port_set_cmode = mv88e6390_port_set_cmode, 5495 .port_setup_message_port = mv88e6xxx_setup_message_port, 5496 .stats_snapshot = mv88e6390_g1_stats_snapshot, 5497 .stats_set_histogram = mv88e6390_g1_stats_set_histogram, 5498 .stats_get_sset_count = mv88e6320_stats_get_sset_count, 5499 .stats_get_strings = mv88e6320_stats_get_strings, 5500 .stats_get_stat = mv88e6390_stats_get_stat, 5501 .set_cpu_port = mv88e6390_g1_set_cpu_port, 5502 .set_egress_port = mv88e6390_g1_set_egress_port, 5503 .watchdog_ops = &mv88e6390_watchdog_ops, 5504 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, 5505 .pot_clear = mv88e6xxx_g2_pot_clear, 5506 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 5507 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 5508 .reset = mv88e6352_g1_reset, 5509 .rmu_disable = mv88e6390_g1_rmu_disable, 5510 .atu_get_hash = mv88e6165_g1_atu_get_hash, 5511 .atu_set_hash = mv88e6165_g1_atu_set_hash, 5512 .vtu_getnext = mv88e6390_g1_vtu_getnext, 5513 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, 5514 .stu_getnext = mv88e6390_g1_stu_getnext, 5515 .stu_loadpurge = mv88e6390_g1_stu_loadpurge, 5516 .serdes_get_lane = mv88e6390_serdes_get_lane, 5517 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 5518 .gpio_ops = &mv88e6352_gpio_ops, 5519 .avb_ops = &mv88e6390_avb_ops, 5520 .ptp_ops = &mv88e6390_ptp_ops, 5521 .serdes_get_sset_count = mv88e6390_serdes_get_sset_count, 5522 .serdes_get_strings = mv88e6390_serdes_get_strings, 5523 .serdes_get_stats = mv88e6390_serdes_get_stats, 5524 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, 5525 .serdes_get_regs = mv88e6390_serdes_get_regs, 5526 .phylink_get_caps = mv88e6390_phylink_get_caps, 5527 .pcs_ops = &mv88e6390_pcs_ops, 5528}; 5529 5530static const struct mv88e6xxx_ops mv88e6390x_ops = { 5531 /* MV88E6XXX_FAMILY_6390 */ 5532 .setup_errata = mv88e6390_setup_errata, 5533 .irl_init_all = mv88e6390_g2_irl_init_all, 5534 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 5535 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 5536 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 5537 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 5538 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 5539 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 5540 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 5541 .port_set_link = mv88e6xxx_port_set_link, 5542 .port_sync_link = mv88e6xxx_port_sync_link, 5543 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, 5544 .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex, 5545 .port_max_speed_mode = mv88e6390x_port_max_speed_mode, 5546 .port_tag_remap = mv88e6390_port_tag_remap, 5547 .port_set_policy = mv88e6352_port_set_policy, 5548 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 5549 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 5550 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 5551 .port_set_ether_type = mv88e6351_port_set_ether_type, 5552 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 5553 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 5554 .port_pause_limit = mv88e6390_port_pause_limit, 5555 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 5556 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 5557 .port_get_cmode = mv88e6352_port_get_cmode, 5558 .port_set_cmode = mv88e6390x_port_set_cmode, 5559 .port_setup_message_port = mv88e6xxx_setup_message_port, 5560 .stats_snapshot = mv88e6390_g1_stats_snapshot, 5561 .stats_set_histogram = mv88e6390_g1_stats_set_histogram, 5562 .stats_get_sset_count = mv88e6320_stats_get_sset_count, 5563 .stats_get_strings = mv88e6320_stats_get_strings, 5564 .stats_get_stat = mv88e6390_stats_get_stat, 5565 .set_cpu_port = mv88e6390_g1_set_cpu_port, 5566 .set_egress_port = mv88e6390_g1_set_egress_port, 5567 .watchdog_ops = &mv88e6390_watchdog_ops, 5568 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, 5569 .pot_clear = mv88e6xxx_g2_pot_clear, 5570 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 5571 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 5572 .reset = mv88e6352_g1_reset, 5573 .rmu_disable = mv88e6390_g1_rmu_disable, 5574 .atu_get_hash = mv88e6165_g1_atu_get_hash, 5575 .atu_set_hash = mv88e6165_g1_atu_set_hash, 5576 .vtu_getnext = mv88e6390_g1_vtu_getnext, 5577 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, 5578 .stu_getnext = mv88e6390_g1_stu_getnext, 5579 .stu_loadpurge = mv88e6390_g1_stu_loadpurge, 5580 .serdes_get_lane = mv88e6390x_serdes_get_lane, 5581 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 5582 .serdes_get_sset_count = mv88e6390_serdes_get_sset_count, 5583 .serdes_get_strings = mv88e6390_serdes_get_strings, 5584 .serdes_get_stats = mv88e6390_serdes_get_stats, 5585 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, 5586 .serdes_get_regs = mv88e6390_serdes_get_regs, 5587 .gpio_ops = &mv88e6352_gpio_ops, 5588 .avb_ops = &mv88e6390_avb_ops, 5589 .ptp_ops = &mv88e6390_ptp_ops, 5590 .phylink_get_caps = mv88e6390x_phylink_get_caps, 5591 .pcs_ops = &mv88e6390_pcs_ops, 5592}; 5593 5594static const struct mv88e6xxx_ops mv88e6393x_ops = { 5595 /* MV88E6XXX_FAMILY_6393 */ 5596 .irl_init_all = mv88e6390_g2_irl_init_all, 5597 .get_eeprom = mv88e6xxx_g2_get_eeprom8, 5598 .set_eeprom = mv88e6xxx_g2_set_eeprom8, 5599 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 5600 .phy_read = mv88e6xxx_g2_smi_phy_read_c22, 5601 .phy_write = mv88e6xxx_g2_smi_phy_write_c22, 5602 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45, 5603 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45, 5604 .port_set_link = mv88e6xxx_port_set_link, 5605 .port_sync_link = mv88e6xxx_port_sync_link, 5606 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, 5607 .port_set_speed_duplex = mv88e6393x_port_set_speed_duplex, 5608 .port_max_speed_mode = mv88e6393x_port_max_speed_mode, 5609 .port_tag_remap = mv88e6390_port_tag_remap, 5610 .port_set_policy = mv88e6393x_port_set_policy, 5611 .port_set_frame_mode = mv88e6351_port_set_frame_mode, 5612 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, 5613 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, 5614 .port_set_ether_type = mv88e6393x_port_set_ether_type, 5615 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, 5616 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, 5617 .port_pause_limit = mv88e6390_port_pause_limit, 5618 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, 5619 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, 5620 .port_get_cmode = mv88e6352_port_get_cmode, 5621 .port_set_cmode = mv88e6393x_port_set_cmode, 5622 .port_setup_message_port = mv88e6xxx_setup_message_port, 5623 .port_set_upstream_port = mv88e6393x_port_set_upstream_port, 5624 .stats_snapshot = mv88e6390_g1_stats_snapshot, 5625 .stats_set_histogram = mv88e6390_g1_stats_set_histogram, 5626 .stats_get_sset_count = mv88e6320_stats_get_sset_count, 5627 .stats_get_strings = mv88e6320_stats_get_strings, 5628 .stats_get_stat = mv88e6390_stats_get_stat, 5629 /* .set_cpu_port is missing because this family does not support a global 5630 * CPU port, only per port CPU port which is set via 5631 * .port_set_upstream_port method. 5632 */ 5633 .set_egress_port = mv88e6393x_set_egress_port, 5634 .watchdog_ops = &mv88e6393x_watchdog_ops, 5635 .mgmt_rsvd2cpu = mv88e6393x_port_mgmt_rsvd2cpu, 5636 .pot_clear = mv88e6xxx_g2_pot_clear, 5637 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, 5638 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, 5639 .reset = mv88e6352_g1_reset, 5640 .rmu_disable = mv88e6390_g1_rmu_disable, 5641 .atu_get_hash = mv88e6165_g1_atu_get_hash, 5642 .atu_set_hash = mv88e6165_g1_atu_set_hash, 5643 .vtu_getnext = mv88e6390_g1_vtu_getnext, 5644 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, 5645 .stu_getnext = mv88e6390_g1_stu_getnext, 5646 .stu_loadpurge = mv88e6390_g1_stu_loadpurge, 5647 .serdes_get_lane = mv88e6393x_serdes_get_lane, 5648 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 5649 /* TODO: serdes stats */ 5650 .gpio_ops = &mv88e6352_gpio_ops, 5651 .avb_ops = &mv88e6390_avb_ops, 5652 .ptp_ops = &mv88e6352_ptp_ops, 5653 .phylink_get_caps = mv88e6393x_phylink_get_caps, 5654 .pcs_ops = &mv88e6393x_pcs_ops, 5655}; 5656 5657static const struct mv88e6xxx_info mv88e6xxx_table[] = { 5658 [MV88E6020] = { 5659 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6020, 5660 .family = MV88E6XXX_FAMILY_6250, 5661 .name = "Marvell 88E6020", 5662 .num_databases = 64, 5663 /* Ports 2-4 are not routed to pins 5664 * => usable ports 0, 1, 5, 6 5665 */ 5666 .num_ports = 7, 5667 .num_internal_phys = 2, 5668 .invalid_port_mask = BIT(2) | BIT(3) | BIT(4), 5669 .max_vid = 4095, 5670 .port_base_addr = 0x8, 5671 .phy_base_addr = 0x0, 5672 .global1_addr = 0xf, 5673 .global2_addr = 0x7, 5674 .age_time_coeff = 15000, 5675 .g1_irqs = 9, 5676 .g2_irqs = 5, 5677 .stats_type = STATS_TYPE_BANK0, 5678 .atu_move_port_mask = 0xf, 5679 .dual_chip = true, 5680 .ops = &mv88e6250_ops, 5681 }, 5682 5683 [MV88E6071] = { 5684 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6071, 5685 .family = MV88E6XXX_FAMILY_6250, 5686 .name = "Marvell 88E6071", 5687 .num_databases = 64, 5688 .num_ports = 7, 5689 .num_internal_phys = 5, 5690 .max_vid = 4095, 5691 .port_base_addr = 0x08, 5692 .phy_base_addr = 0x00, 5693 .global1_addr = 0x0f, 5694 .global2_addr = 0x07, 5695 .age_time_coeff = 15000, 5696 .g1_irqs = 9, 5697 .g2_irqs = 5, 5698 .stats_type = STATS_TYPE_BANK0, 5699 .atu_move_port_mask = 0xf, 5700 .dual_chip = true, 5701 .ops = &mv88e6250_ops, 5702 }, 5703 5704 [MV88E6085] = { 5705 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6085, 5706 .family = MV88E6XXX_FAMILY_6097, 5707 .name = "Marvell 88E6085", 5708 .num_databases = 4096, 5709 .num_macs = 8192, 5710 .num_ports = 10, 5711 .num_internal_phys = 5, 5712 .max_vid = 4095, 5713 .max_sid = 63, 5714 .port_base_addr = 0x10, 5715 .phy_base_addr = 0x0, 5716 .global1_addr = 0x1b, 5717 .global2_addr = 0x1c, 5718 .age_time_coeff = 15000, 5719 .g1_irqs = 8, 5720 .g2_irqs = 10, 5721 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 5722 .atu_move_port_mask = 0xf, 5723 .pvt = true, 5724 .multi_chip = true, 5725 .ops = &mv88e6085_ops, 5726 }, 5727 5728 [MV88E6095] = { 5729 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6095, 5730 .family = MV88E6XXX_FAMILY_6095, 5731 .name = "Marvell 88E6095/88E6095F", 5732 .num_databases = 256, 5733 .num_macs = 8192, 5734 .num_ports = 11, 5735 .num_internal_phys = 0, 5736 .max_vid = 4095, 5737 .port_base_addr = 0x10, 5738 .phy_base_addr = 0x0, 5739 .global1_addr = 0x1b, 5740 .global2_addr = 0x1c, 5741 .age_time_coeff = 15000, 5742 .g1_irqs = 8, 5743 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 5744 .atu_move_port_mask = 0xf, 5745 .multi_chip = true, 5746 .ops = &mv88e6095_ops, 5747 }, 5748 5749 [MV88E6097] = { 5750 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6097, 5751 .family = MV88E6XXX_FAMILY_6097, 5752 .name = "Marvell 88E6097/88E6097F", 5753 .num_databases = 4096, 5754 .num_macs = 8192, 5755 .num_ports = 11, 5756 .num_internal_phys = 8, 5757 .max_vid = 4095, 5758 .max_sid = 63, 5759 .port_base_addr = 0x10, 5760 .phy_base_addr = 0x0, 5761 .global1_addr = 0x1b, 5762 .global2_addr = 0x1c, 5763 .age_time_coeff = 15000, 5764 .g1_irqs = 8, 5765 .g2_irqs = 10, 5766 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 5767 .atu_move_port_mask = 0xf, 5768 .pvt = true, 5769 .multi_chip = true, 5770 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 5771 .ops = &mv88e6097_ops, 5772 }, 5773 5774 [MV88E6123] = { 5775 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6123, 5776 .family = MV88E6XXX_FAMILY_6165, 5777 .name = "Marvell 88E6123", 5778 .num_databases = 4096, 5779 .num_macs = 1024, 5780 .num_ports = 3, 5781 .num_internal_phys = 5, 5782 .max_vid = 4095, 5783 .max_sid = 63, 5784 .port_base_addr = 0x10, 5785 .phy_base_addr = 0x0, 5786 .global1_addr = 0x1b, 5787 .global2_addr = 0x1c, 5788 .age_time_coeff = 15000, 5789 .g1_irqs = 9, 5790 .g2_irqs = 10, 5791 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 5792 .atu_move_port_mask = 0xf, 5793 .pvt = true, 5794 .multi_chip = true, 5795 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 5796 .ops = &mv88e6123_ops, 5797 }, 5798 5799 [MV88E6131] = { 5800 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6131, 5801 .family = MV88E6XXX_FAMILY_6185, 5802 .name = "Marvell 88E6131", 5803 .num_databases = 256, 5804 .num_macs = 8192, 5805 .num_ports = 8, 5806 .num_internal_phys = 0, 5807 .max_vid = 4095, 5808 .port_base_addr = 0x10, 5809 .phy_base_addr = 0x0, 5810 .global1_addr = 0x1b, 5811 .global2_addr = 0x1c, 5812 .age_time_coeff = 15000, 5813 .g1_irqs = 9, 5814 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 5815 .atu_move_port_mask = 0xf, 5816 .multi_chip = true, 5817 .ops = &mv88e6131_ops, 5818 }, 5819 5820 [MV88E6141] = { 5821 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141, 5822 .family = MV88E6XXX_FAMILY_6341, 5823 .name = "Marvell 88E6141", 5824 .num_databases = 256, 5825 .num_macs = 2048, 5826 .num_ports = 6, 5827 .num_internal_phys = 5, 5828 .num_gpio = 11, 5829 .max_vid = 4095, 5830 .max_sid = 63, 5831 .port_base_addr = 0x10, 5832 .phy_base_addr = 0x10, 5833 .global1_addr = 0x1b, 5834 .global2_addr = 0x1c, 5835 .age_time_coeff = 3750, 5836 .atu_move_port_mask = 0xf, 5837 .g1_irqs = 9, 5838 .g2_irqs = 10, 5839 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 5840 .pvt = true, 5841 .multi_chip = true, 5842 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 5843 .ops = &mv88e6141_ops, 5844 }, 5845 5846 [MV88E6161] = { 5847 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6161, 5848 .family = MV88E6XXX_FAMILY_6165, 5849 .name = "Marvell 88E6161", 5850 .num_databases = 4096, 5851 .num_macs = 1024, 5852 .num_ports = 6, 5853 .num_internal_phys = 5, 5854 .max_vid = 4095, 5855 .max_sid = 63, 5856 .port_base_addr = 0x10, 5857 .phy_base_addr = 0x0, 5858 .global1_addr = 0x1b, 5859 .global2_addr = 0x1c, 5860 .age_time_coeff = 15000, 5861 .g1_irqs = 9, 5862 .g2_irqs = 10, 5863 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 5864 .atu_move_port_mask = 0xf, 5865 .pvt = true, 5866 .multi_chip = true, 5867 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 5868 .ptp_support = true, 5869 .ops = &mv88e6161_ops, 5870 }, 5871 5872 [MV88E6165] = { 5873 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6165, 5874 .family = MV88E6XXX_FAMILY_6165, 5875 .name = "Marvell 88E6165", 5876 .num_databases = 4096, 5877 .num_macs = 8192, 5878 .num_ports = 6, 5879 .num_internal_phys = 0, 5880 .max_vid = 4095, 5881 .max_sid = 63, 5882 .port_base_addr = 0x10, 5883 .phy_base_addr = 0x0, 5884 .global1_addr = 0x1b, 5885 .global2_addr = 0x1c, 5886 .age_time_coeff = 15000, 5887 .g1_irqs = 9, 5888 .g2_irqs = 10, 5889 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 5890 .atu_move_port_mask = 0xf, 5891 .pvt = true, 5892 .multi_chip = true, 5893 .ptp_support = true, 5894 .ops = &mv88e6165_ops, 5895 }, 5896 5897 [MV88E6171] = { 5898 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6171, 5899 .family = MV88E6XXX_FAMILY_6351, 5900 .name = "Marvell 88E6171", 5901 .num_databases = 4096, 5902 .num_macs = 8192, 5903 .num_ports = 7, 5904 .num_internal_phys = 5, 5905 .max_vid = 4095, 5906 .max_sid = 63, 5907 .port_base_addr = 0x10, 5908 .phy_base_addr = 0x0, 5909 .global1_addr = 0x1b, 5910 .global2_addr = 0x1c, 5911 .age_time_coeff = 15000, 5912 .g1_irqs = 9, 5913 .g2_irqs = 10, 5914 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 5915 .atu_move_port_mask = 0xf, 5916 .pvt = true, 5917 .multi_chip = true, 5918 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 5919 .ops = &mv88e6171_ops, 5920 }, 5921 5922 [MV88E6172] = { 5923 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6172, 5924 .family = MV88E6XXX_FAMILY_6352, 5925 .name = "Marvell 88E6172", 5926 .num_databases = 4096, 5927 .num_macs = 8192, 5928 .num_ports = 7, 5929 .num_internal_phys = 5, 5930 .num_gpio = 15, 5931 .max_vid = 4095, 5932 .max_sid = 63, 5933 .port_base_addr = 0x10, 5934 .phy_base_addr = 0x0, 5935 .global1_addr = 0x1b, 5936 .global2_addr = 0x1c, 5937 .age_time_coeff = 15000, 5938 .g1_irqs = 9, 5939 .g2_irqs = 10, 5940 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 5941 .atu_move_port_mask = 0xf, 5942 .pvt = true, 5943 .multi_chip = true, 5944 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 5945 .ops = &mv88e6172_ops, 5946 }, 5947 5948 [MV88E6175] = { 5949 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6175, 5950 .family = MV88E6XXX_FAMILY_6351, 5951 .name = "Marvell 88E6175", 5952 .num_databases = 4096, 5953 .num_macs = 8192, 5954 .num_ports = 7, 5955 .num_internal_phys = 5, 5956 .max_vid = 4095, 5957 .max_sid = 63, 5958 .port_base_addr = 0x10, 5959 .phy_base_addr = 0x0, 5960 .global1_addr = 0x1b, 5961 .global2_addr = 0x1c, 5962 .age_time_coeff = 15000, 5963 .g1_irqs = 9, 5964 .g2_irqs = 10, 5965 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 5966 .atu_move_port_mask = 0xf, 5967 .pvt = true, 5968 .multi_chip = true, 5969 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 5970 .ops = &mv88e6175_ops, 5971 }, 5972 5973 [MV88E6176] = { 5974 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6176, 5975 .family = MV88E6XXX_FAMILY_6352, 5976 .name = "Marvell 88E6176", 5977 .num_databases = 4096, 5978 .num_macs = 8192, 5979 .num_ports = 7, 5980 .num_internal_phys = 5, 5981 .num_gpio = 15, 5982 .max_vid = 4095, 5983 .max_sid = 63, 5984 .port_base_addr = 0x10, 5985 .phy_base_addr = 0x0, 5986 .global1_addr = 0x1b, 5987 .global2_addr = 0x1c, 5988 .age_time_coeff = 15000, 5989 .g1_irqs = 9, 5990 .g2_irqs = 10, 5991 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 5992 .atu_move_port_mask = 0xf, 5993 .pvt = true, 5994 .multi_chip = true, 5995 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 5996 .ops = &mv88e6176_ops, 5997 }, 5998 5999 [MV88E6185] = { 6000 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6185, 6001 .family = MV88E6XXX_FAMILY_6185, 6002 .name = "Marvell 88E6185", 6003 .num_databases = 256, 6004 .num_macs = 8192, 6005 .num_ports = 10, 6006 .num_internal_phys = 0, 6007 .max_vid = 4095, 6008 .port_base_addr = 0x10, 6009 .phy_base_addr = 0x0, 6010 .global1_addr = 0x1b, 6011 .global2_addr = 0x1c, 6012 .age_time_coeff = 15000, 6013 .g1_irqs = 8, 6014 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 6015 .atu_move_port_mask = 0xf, 6016 .multi_chip = true, 6017 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 6018 .ops = &mv88e6185_ops, 6019 }, 6020 6021 [MV88E6190] = { 6022 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190, 6023 .family = MV88E6XXX_FAMILY_6390, 6024 .name = "Marvell 88E6190", 6025 .num_databases = 4096, 6026 .num_macs = 16384, 6027 .num_ports = 11, /* 10 + Z80 */ 6028 .num_internal_phys = 9, 6029 .num_gpio = 16, 6030 .max_vid = 8191, 6031 .max_sid = 63, 6032 .port_base_addr = 0x0, 6033 .phy_base_addr = 0x0, 6034 .global1_addr = 0x1b, 6035 .global2_addr = 0x1c, 6036 .age_time_coeff = 3750, 6037 .g1_irqs = 9, 6038 .g2_irqs = 14, 6039 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 6040 .pvt = true, 6041 .multi_chip = true, 6042 .atu_move_port_mask = 0x1f, 6043 .ops = &mv88e6190_ops, 6044 }, 6045 6046 [MV88E6190X] = { 6047 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190X, 6048 .family = MV88E6XXX_FAMILY_6390, 6049 .name = "Marvell 88E6190X", 6050 .num_databases = 4096, 6051 .num_macs = 16384, 6052 .num_ports = 11, /* 10 + Z80 */ 6053 .num_internal_phys = 9, 6054 .num_gpio = 16, 6055 .max_vid = 8191, 6056 .max_sid = 63, 6057 .port_base_addr = 0x0, 6058 .phy_base_addr = 0x0, 6059 .global1_addr = 0x1b, 6060 .global2_addr = 0x1c, 6061 .age_time_coeff = 3750, 6062 .g1_irqs = 9, 6063 .g2_irqs = 14, 6064 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 6065 .atu_move_port_mask = 0x1f, 6066 .pvt = true, 6067 .multi_chip = true, 6068 .ops = &mv88e6190x_ops, 6069 }, 6070 6071 [MV88E6191] = { 6072 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6191, 6073 .family = MV88E6XXX_FAMILY_6390, 6074 .name = "Marvell 88E6191", 6075 .num_databases = 4096, 6076 .num_macs = 16384, 6077 .num_ports = 11, /* 10 + Z80 */ 6078 .num_internal_phys = 9, 6079 .max_vid = 8191, 6080 .max_sid = 63, 6081 .port_base_addr = 0x0, 6082 .phy_base_addr = 0x0, 6083 .global1_addr = 0x1b, 6084 .global2_addr = 0x1c, 6085 .age_time_coeff = 3750, 6086 .g1_irqs = 9, 6087 .g2_irqs = 14, 6088 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 6089 .atu_move_port_mask = 0x1f, 6090 .pvt = true, 6091 .multi_chip = true, 6092 .ptp_support = true, 6093 .ops = &mv88e6191_ops, 6094 }, 6095 6096 [MV88E6191X] = { 6097 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6191X, 6098 .family = MV88E6XXX_FAMILY_6393, 6099 .name = "Marvell 88E6191X", 6100 .num_databases = 4096, 6101 .num_ports = 11, /* 10 + Z80 */ 6102 .num_internal_phys = 8, 6103 .internal_phys_offset = 1, 6104 .max_vid = 8191, 6105 .max_sid = 63, 6106 .port_base_addr = 0x0, 6107 .phy_base_addr = 0x0, 6108 .global1_addr = 0x1b, 6109 .global2_addr = 0x1c, 6110 .age_time_coeff = 3750, 6111 .g1_irqs = 10, 6112 .g2_irqs = 14, 6113 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 6114 .atu_move_port_mask = 0x1f, 6115 .pvt = true, 6116 .multi_chip = true, 6117 .ptp_support = true, 6118 .ops = &mv88e6393x_ops, 6119 }, 6120 6121 [MV88E6193X] = { 6122 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6193X, 6123 .family = MV88E6XXX_FAMILY_6393, 6124 .name = "Marvell 88E6193X", 6125 .num_databases = 4096, 6126 .num_ports = 11, /* 10 + Z80 */ 6127 .num_internal_phys = 8, 6128 .internal_phys_offset = 1, 6129 .max_vid = 8191, 6130 .max_sid = 63, 6131 .port_base_addr = 0x0, 6132 .phy_base_addr = 0x0, 6133 .global1_addr = 0x1b, 6134 .global2_addr = 0x1c, 6135 .age_time_coeff = 3750, 6136 .g1_irqs = 10, 6137 .g2_irqs = 14, 6138 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 6139 .atu_move_port_mask = 0x1f, 6140 .pvt = true, 6141 .multi_chip = true, 6142 .ptp_support = true, 6143 .ops = &mv88e6393x_ops, 6144 }, 6145 6146 [MV88E6220] = { 6147 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6220, 6148 .family = MV88E6XXX_FAMILY_6250, 6149 .name = "Marvell 88E6220", 6150 .num_databases = 64, 6151 6152 /* Ports 2-4 are not routed to pins 6153 * => usable ports 0, 1, 5, 6 6154 */ 6155 .num_ports = 7, 6156 .num_internal_phys = 2, 6157 .invalid_port_mask = BIT(2) | BIT(3) | BIT(4), 6158 .max_vid = 4095, 6159 .port_base_addr = 0x08, 6160 .phy_base_addr = 0x00, 6161 .global1_addr = 0x0f, 6162 .global2_addr = 0x07, 6163 .age_time_coeff = 15000, 6164 .g1_irqs = 9, 6165 .g2_irqs = 10, 6166 .stats_type = STATS_TYPE_BANK0, 6167 .atu_move_port_mask = 0xf, 6168 .dual_chip = true, 6169 .ptp_support = true, 6170 .ops = &mv88e6250_ops, 6171 }, 6172 6173 [MV88E6240] = { 6174 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6240, 6175 .family = MV88E6XXX_FAMILY_6352, 6176 .name = "Marvell 88E6240", 6177 .num_databases = 4096, 6178 .num_macs = 8192, 6179 .num_ports = 7, 6180 .num_internal_phys = 5, 6181 .num_gpio = 15, 6182 .max_vid = 4095, 6183 .max_sid = 63, 6184 .port_base_addr = 0x10, 6185 .phy_base_addr = 0x0, 6186 .global1_addr = 0x1b, 6187 .global2_addr = 0x1c, 6188 .age_time_coeff = 15000, 6189 .g1_irqs = 9, 6190 .g2_irqs = 10, 6191 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 6192 .atu_move_port_mask = 0xf, 6193 .pvt = true, 6194 .multi_chip = true, 6195 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 6196 .ptp_support = true, 6197 .ops = &mv88e6240_ops, 6198 }, 6199 6200 [MV88E6250] = { 6201 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6250, 6202 .family = MV88E6XXX_FAMILY_6250, 6203 .name = "Marvell 88E6250", 6204 .num_databases = 64, 6205 .num_ports = 7, 6206 .num_internal_phys = 5, 6207 .max_vid = 4095, 6208 .port_base_addr = 0x08, 6209 .phy_base_addr = 0x00, 6210 .global1_addr = 0x0f, 6211 .global2_addr = 0x07, 6212 .age_time_coeff = 15000, 6213 .g1_irqs = 9, 6214 .g2_irqs = 10, 6215 .stats_type = STATS_TYPE_BANK0, 6216 .atu_move_port_mask = 0xf, 6217 .dual_chip = true, 6218 .ptp_support = true, 6219 .ops = &mv88e6250_ops, 6220 }, 6221 6222 [MV88E6290] = { 6223 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6290, 6224 .family = MV88E6XXX_FAMILY_6390, 6225 .name = "Marvell 88E6290", 6226 .num_databases = 4096, 6227 .num_ports = 11, /* 10 + Z80 */ 6228 .num_internal_phys = 9, 6229 .num_gpio = 16, 6230 .max_vid = 8191, 6231 .max_sid = 63, 6232 .port_base_addr = 0x0, 6233 .phy_base_addr = 0x0, 6234 .global1_addr = 0x1b, 6235 .global2_addr = 0x1c, 6236 .age_time_coeff = 3750, 6237 .g1_irqs = 9, 6238 .g2_irqs = 14, 6239 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 6240 .atu_move_port_mask = 0x1f, 6241 .pvt = true, 6242 .multi_chip = true, 6243 .ptp_support = true, 6244 .ops = &mv88e6290_ops, 6245 }, 6246 6247 [MV88E6320] = { 6248 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6320, 6249 .family = MV88E6XXX_FAMILY_6320, 6250 .name = "Marvell 88E6320", 6251 .num_databases = 4096, 6252 .num_macs = 8192, 6253 .num_ports = 7, 6254 .num_internal_phys = 2, 6255 .internal_phys_offset = 3, 6256 .num_gpio = 15, 6257 .max_vid = 4095, 6258 .max_sid = 63, 6259 .port_base_addr = 0x10, 6260 .phy_base_addr = 0x0, 6261 .global1_addr = 0x1b, 6262 .global2_addr = 0x1c, 6263 .age_time_coeff = 15000, 6264 .g1_irqs = 8, 6265 .g2_irqs = 10, 6266 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 6267 .atu_move_port_mask = 0xf, 6268 .pvt = true, 6269 .multi_chip = true, 6270 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 6271 .ptp_support = true, 6272 .ops = &mv88e6320_ops, 6273 }, 6274 6275 [MV88E6321] = { 6276 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6321, 6277 .family = MV88E6XXX_FAMILY_6320, 6278 .name = "Marvell 88E6321", 6279 .num_databases = 4096, 6280 .num_macs = 8192, 6281 .num_ports = 7, 6282 .num_internal_phys = 2, 6283 .internal_phys_offset = 3, 6284 .num_gpio = 15, 6285 .max_vid = 4095, 6286 .max_sid = 63, 6287 .port_base_addr = 0x10, 6288 .phy_base_addr = 0x0, 6289 .global1_addr = 0x1b, 6290 .global2_addr = 0x1c, 6291 .age_time_coeff = 15000, 6292 .g1_irqs = 8, 6293 .g2_irqs = 10, 6294 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 6295 .atu_move_port_mask = 0xf, 6296 .pvt = true, 6297 .multi_chip = true, 6298 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 6299 .ptp_support = true, 6300 .ops = &mv88e6321_ops, 6301 }, 6302 6303 [MV88E6341] = { 6304 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341, 6305 .family = MV88E6XXX_FAMILY_6341, 6306 .name = "Marvell 88E6341", 6307 .num_databases = 256, 6308 .num_macs = 2048, 6309 .num_internal_phys = 5, 6310 .num_ports = 6, 6311 .num_gpio = 11, 6312 .max_vid = 4095, 6313 .max_sid = 63, 6314 .port_base_addr = 0x10, 6315 .phy_base_addr = 0x10, 6316 .global1_addr = 0x1b, 6317 .global2_addr = 0x1c, 6318 .age_time_coeff = 3750, 6319 .atu_move_port_mask = 0xf, 6320 .g1_irqs = 9, 6321 .g2_irqs = 10, 6322 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 6323 .pvt = true, 6324 .multi_chip = true, 6325 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 6326 .ptp_support = true, 6327 .ops = &mv88e6341_ops, 6328 }, 6329 6330 [MV88E6350] = { 6331 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6350, 6332 .family = MV88E6XXX_FAMILY_6351, 6333 .name = "Marvell 88E6350", 6334 .num_databases = 4096, 6335 .num_macs = 8192, 6336 .num_ports = 7, 6337 .num_internal_phys = 5, 6338 .max_vid = 4095, 6339 .max_sid = 63, 6340 .port_base_addr = 0x10, 6341 .phy_base_addr = 0x0, 6342 .global1_addr = 0x1b, 6343 .global2_addr = 0x1c, 6344 .age_time_coeff = 15000, 6345 .g1_irqs = 9, 6346 .g2_irqs = 10, 6347 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 6348 .atu_move_port_mask = 0xf, 6349 .pvt = true, 6350 .multi_chip = true, 6351 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 6352 .ops = &mv88e6350_ops, 6353 }, 6354 6355 [MV88E6351] = { 6356 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6351, 6357 .family = MV88E6XXX_FAMILY_6351, 6358 .name = "Marvell 88E6351", 6359 .num_databases = 4096, 6360 .num_macs = 8192, 6361 .num_ports = 7, 6362 .num_internal_phys = 5, 6363 .max_vid = 4095, 6364 .max_sid = 63, 6365 .port_base_addr = 0x10, 6366 .phy_base_addr = 0x0, 6367 .global1_addr = 0x1b, 6368 .global2_addr = 0x1c, 6369 .age_time_coeff = 15000, 6370 .g1_irqs = 9, 6371 .g2_irqs = 10, 6372 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 6373 .atu_move_port_mask = 0xf, 6374 .pvt = true, 6375 .multi_chip = true, 6376 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 6377 .ops = &mv88e6351_ops, 6378 }, 6379 6380 [MV88E6352] = { 6381 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6352, 6382 .family = MV88E6XXX_FAMILY_6352, 6383 .name = "Marvell 88E6352", 6384 .num_databases = 4096, 6385 .num_macs = 8192, 6386 .num_ports = 7, 6387 .num_internal_phys = 5, 6388 .num_gpio = 15, 6389 .max_vid = 4095, 6390 .max_sid = 63, 6391 .port_base_addr = 0x10, 6392 .phy_base_addr = 0x0, 6393 .global1_addr = 0x1b, 6394 .global2_addr = 0x1c, 6395 .age_time_coeff = 15000, 6396 .g1_irqs = 9, 6397 .g2_irqs = 10, 6398 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT, 6399 .atu_move_port_mask = 0xf, 6400 .pvt = true, 6401 .multi_chip = true, 6402 .edsa_support = MV88E6XXX_EDSA_SUPPORTED, 6403 .ptp_support = true, 6404 .ops = &mv88e6352_ops, 6405 }, 6406 [MV88E6361] = { 6407 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361, 6408 .family = MV88E6XXX_FAMILY_6393, 6409 .name = "Marvell 88E6361", 6410 .num_databases = 4096, 6411 .num_macs = 16384, 6412 .num_ports = 11, 6413 /* Ports 1, 2 and 8 are not routed */ 6414 .invalid_port_mask = BIT(1) | BIT(2) | BIT(8), 6415 .num_internal_phys = 5, 6416 .internal_phys_offset = 3, 6417 .max_vid = 8191, 6418 .max_sid = 63, 6419 .port_base_addr = 0x0, 6420 .phy_base_addr = 0x0, 6421 .global1_addr = 0x1b, 6422 .global2_addr = 0x1c, 6423 .age_time_coeff = 3750, 6424 .g1_irqs = 10, 6425 .g2_irqs = 14, 6426 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 6427 .atu_move_port_mask = 0x1f, 6428 .pvt = true, 6429 .multi_chip = true, 6430 .ptp_support = true, 6431 .ops = &mv88e6393x_ops, 6432 }, 6433 [MV88E6390] = { 6434 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390, 6435 .family = MV88E6XXX_FAMILY_6390, 6436 .name = "Marvell 88E6390", 6437 .num_databases = 4096, 6438 .num_macs = 16384, 6439 .num_ports = 11, /* 10 + Z80 */ 6440 .num_internal_phys = 9, 6441 .num_gpio = 16, 6442 .max_vid = 8191, 6443 .max_sid = 63, 6444 .port_base_addr = 0x0, 6445 .phy_base_addr = 0x0, 6446 .global1_addr = 0x1b, 6447 .global2_addr = 0x1c, 6448 .age_time_coeff = 3750, 6449 .g1_irqs = 9, 6450 .g2_irqs = 14, 6451 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 6452 .atu_move_port_mask = 0x1f, 6453 .pvt = true, 6454 .multi_chip = true, 6455 .edsa_support = MV88E6XXX_EDSA_UNDOCUMENTED, 6456 .ptp_support = true, 6457 .ops = &mv88e6390_ops, 6458 }, 6459 [MV88E6390X] = { 6460 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390X, 6461 .family = MV88E6XXX_FAMILY_6390, 6462 .name = "Marvell 88E6390X", 6463 .num_databases = 4096, 6464 .num_macs = 16384, 6465 .num_ports = 11, /* 10 + Z80 */ 6466 .num_internal_phys = 9, 6467 .num_gpio = 16, 6468 .max_vid = 8191, 6469 .max_sid = 63, 6470 .port_base_addr = 0x0, 6471 .phy_base_addr = 0x0, 6472 .global1_addr = 0x1b, 6473 .global2_addr = 0x1c, 6474 .age_time_coeff = 3750, 6475 .g1_irqs = 9, 6476 .g2_irqs = 14, 6477 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 6478 .atu_move_port_mask = 0x1f, 6479 .pvt = true, 6480 .multi_chip = true, 6481 .edsa_support = MV88E6XXX_EDSA_UNDOCUMENTED, 6482 .ptp_support = true, 6483 .ops = &mv88e6390x_ops, 6484 }, 6485 6486 [MV88E6393X] = { 6487 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6393X, 6488 .family = MV88E6XXX_FAMILY_6393, 6489 .name = "Marvell 88E6393X", 6490 .num_databases = 4096, 6491 .num_ports = 11, /* 10 + Z80 */ 6492 .num_internal_phys = 8, 6493 .internal_phys_offset = 1, 6494 .max_vid = 8191, 6495 .max_sid = 63, 6496 .port_base_addr = 0x0, 6497 .phy_base_addr = 0x0, 6498 .global1_addr = 0x1b, 6499 .global2_addr = 0x1c, 6500 .age_time_coeff = 3750, 6501 .g1_irqs = 10, 6502 .g2_irqs = 14, 6503 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 6504 .atu_move_port_mask = 0x1f, 6505 .pvt = true, 6506 .multi_chip = true, 6507 .ptp_support = true, 6508 .ops = &mv88e6393x_ops, 6509 }, 6510}; 6511 6512static const struct mv88e6xxx_info *mv88e6xxx_lookup_info(unsigned int prod_num) 6513{ 6514 int i; 6515 6516 for (i = 0; i < ARRAY_SIZE(mv88e6xxx_table); ++i) 6517 if (mv88e6xxx_table[i].prod_num == prod_num) 6518 return &mv88e6xxx_table[i]; 6519 6520 return NULL; 6521} 6522 6523static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip) 6524{ 6525 const struct mv88e6xxx_info *info; 6526 unsigned int prod_num, rev; 6527 u16 id; 6528 int err; 6529 6530 mv88e6xxx_reg_lock(chip); 6531 err = mv88e6xxx_port_read(chip, 0, MV88E6XXX_PORT_SWITCH_ID, &id); 6532 mv88e6xxx_reg_unlock(chip); 6533 if (err) 6534 return err; 6535 6536 prod_num = id & MV88E6XXX_PORT_SWITCH_ID_PROD_MASK; 6537 rev = id & MV88E6XXX_PORT_SWITCH_ID_REV_MASK; 6538 6539 info = mv88e6xxx_lookup_info(prod_num); 6540 if (!info) 6541 return -ENODEV; 6542 6543 /* Update the compatible info with the probed one */ 6544 chip->info = info; 6545 6546 dev_info(chip->dev, "switch 0x%x detected: %s, revision %u\n", 6547 chip->info->prod_num, chip->info->name, rev); 6548 6549 return 0; 6550} 6551 6552static int mv88e6xxx_single_chip_detect(struct mv88e6xxx_chip *chip, 6553 struct mdio_device *mdiodev) 6554{ 6555 int err; 6556 6557 /* dual_chip takes precedence over single/multi-chip modes */ 6558 if (chip->info->dual_chip) 6559 return -EINVAL; 6560 6561 /* If the mdio addr is 16 indicating the first port address of a switch 6562 * (e.g. mv88e6*41) in single chip addressing mode the device may be 6563 * configured in single chip addressing mode. Setup the smi access as 6564 * single chip addressing mode and attempt to detect the model of the 6565 * switch, if this fails the device is not configured in single chip 6566 * addressing mode. 6567 */ 6568 if (mdiodev->addr != 16) 6569 return -EINVAL; 6570 6571 err = mv88e6xxx_smi_init(chip, mdiodev->bus, 0); 6572 if (err) 6573 return err; 6574 6575 return mv88e6xxx_detect(chip); 6576} 6577 6578static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev) 6579{ 6580 struct mv88e6xxx_chip *chip; 6581 6582 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); 6583 if (!chip) 6584 return NULL; 6585 6586 chip->dev = dev; 6587 6588 mutex_init(&chip->reg_lock); 6589 INIT_LIST_HEAD(&chip->mdios); 6590 idr_init(&chip->policies); 6591 INIT_LIST_HEAD(&chip->msts); 6592 6593 return chip; 6594} 6595 6596static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds, 6597 int port, 6598 enum dsa_tag_protocol m) 6599{ 6600 struct mv88e6xxx_chip *chip = ds->priv; 6601 6602 return chip->tag_protocol; 6603} 6604 6605static int mv88e6xxx_change_tag_protocol(struct dsa_switch *ds, 6606 enum dsa_tag_protocol proto) 6607{ 6608 struct mv88e6xxx_chip *chip = ds->priv; 6609 enum dsa_tag_protocol old_protocol; 6610 struct dsa_port *cpu_dp; 6611 int err; 6612 6613 switch (proto) { 6614 case DSA_TAG_PROTO_EDSA: 6615 switch (chip->info->edsa_support) { 6616 case MV88E6XXX_EDSA_UNSUPPORTED: 6617 return -EPROTONOSUPPORT; 6618 case MV88E6XXX_EDSA_UNDOCUMENTED: 6619 dev_warn(chip->dev, "Relying on undocumented EDSA tagging behavior\n"); 6620 fallthrough; 6621 case MV88E6XXX_EDSA_SUPPORTED: 6622 break; 6623 } 6624 break; 6625 case DSA_TAG_PROTO_DSA: 6626 break; 6627 default: 6628 return -EPROTONOSUPPORT; 6629 } 6630 6631 old_protocol = chip->tag_protocol; 6632 chip->tag_protocol = proto; 6633 6634 mv88e6xxx_reg_lock(chip); 6635 dsa_switch_for_each_cpu_port(cpu_dp, ds) { 6636 err = mv88e6xxx_setup_port_mode(chip, cpu_dp->index); 6637 if (err) { 6638 mv88e6xxx_reg_unlock(chip); 6639 goto unwind; 6640 } 6641 } 6642 mv88e6xxx_reg_unlock(chip); 6643 6644 return 0; 6645 6646unwind: 6647 chip->tag_protocol = old_protocol; 6648 6649 mv88e6xxx_reg_lock(chip); 6650 dsa_switch_for_each_cpu_port_continue_reverse(cpu_dp, ds) 6651 mv88e6xxx_setup_port_mode(chip, cpu_dp->index); 6652 mv88e6xxx_reg_unlock(chip); 6653 6654 return err; 6655} 6656 6657static int mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port, 6658 const struct switchdev_obj_port_mdb *mdb, 6659 struct dsa_db db) 6660{ 6661 struct mv88e6xxx_chip *chip = ds->priv; 6662 int err; 6663 6664 mv88e6xxx_reg_lock(chip); 6665 err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid, 6666 MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC); 6667 if (err) 6668 goto out; 6669 6670 if (!mv88e6xxx_port_db_find(chip, mdb->addr, mdb->vid)) 6671 err = -ENOSPC; 6672 6673out: 6674 mv88e6xxx_reg_unlock(chip); 6675 6676 return err; 6677} 6678 6679static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port, 6680 const struct switchdev_obj_port_mdb *mdb, 6681 struct dsa_db db) 6682{ 6683 struct mv88e6xxx_chip *chip = ds->priv; 6684 int err; 6685 6686 mv88e6xxx_reg_lock(chip); 6687 err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid, 0); 6688 mv88e6xxx_reg_unlock(chip); 6689 6690 return err; 6691} 6692 6693static int mv88e6xxx_port_mirror_add(struct dsa_switch *ds, int port, 6694 struct dsa_mall_mirror_tc_entry *mirror, 6695 bool ingress, 6696 struct netlink_ext_ack *extack) 6697{ 6698 enum mv88e6xxx_egress_direction direction = ingress ? 6699 MV88E6XXX_EGRESS_DIR_INGRESS : 6700 MV88E6XXX_EGRESS_DIR_EGRESS; 6701 struct mv88e6xxx_chip *chip = ds->priv; 6702 bool other_mirrors = false; 6703 int i; 6704 int err; 6705 6706 mutex_lock(&chip->reg_lock); 6707 if ((ingress ? chip->ingress_dest_port : chip->egress_dest_port) != 6708 mirror->to_local_port) { 6709 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) 6710 other_mirrors |= ingress ? 6711 chip->ports[i].mirror_ingress : 6712 chip->ports[i].mirror_egress; 6713 6714 /* Can't change egress port when other mirror is active */ 6715 if (other_mirrors) { 6716 err = -EBUSY; 6717 goto out; 6718 } 6719 6720 err = mv88e6xxx_set_egress_port(chip, direction, 6721 mirror->to_local_port); 6722 if (err) 6723 goto out; 6724 } 6725 6726 err = mv88e6xxx_port_set_mirror(chip, port, direction, true); 6727out: 6728 mutex_unlock(&chip->reg_lock); 6729 6730 return err; 6731} 6732 6733static void mv88e6xxx_port_mirror_del(struct dsa_switch *ds, int port, 6734 struct dsa_mall_mirror_tc_entry *mirror) 6735{ 6736 enum mv88e6xxx_egress_direction direction = mirror->ingress ? 6737 MV88E6XXX_EGRESS_DIR_INGRESS : 6738 MV88E6XXX_EGRESS_DIR_EGRESS; 6739 struct mv88e6xxx_chip *chip = ds->priv; 6740 bool other_mirrors = false; 6741 int i; 6742 6743 mutex_lock(&chip->reg_lock); 6744 if (mv88e6xxx_port_set_mirror(chip, port, direction, false)) 6745 dev_err(ds->dev, "p%d: failed to disable mirroring\n", port); 6746 6747 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) 6748 other_mirrors |= mirror->ingress ? 6749 chip->ports[i].mirror_ingress : 6750 chip->ports[i].mirror_egress; 6751 6752 /* Reset egress port when no other mirror is active */ 6753 if (!other_mirrors) { 6754 if (mv88e6xxx_set_egress_port(chip, direction, 6755 dsa_upstream_port(ds, port))) 6756 dev_err(ds->dev, "failed to set egress port\n"); 6757 } 6758 6759 mutex_unlock(&chip->reg_lock); 6760} 6761 6762static int mv88e6xxx_port_pre_bridge_flags(struct dsa_switch *ds, int port, 6763 struct switchdev_brport_flags flags, 6764 struct netlink_ext_ack *extack) 6765{ 6766 struct mv88e6xxx_chip *chip = ds->priv; 6767 const struct mv88e6xxx_ops *ops; 6768 6769 if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | 6770 BR_BCAST_FLOOD | BR_PORT_LOCKED | BR_PORT_MAB)) 6771 return -EINVAL; 6772 6773 ops = chip->info->ops; 6774 6775 if ((flags.mask & BR_FLOOD) && !ops->port_set_ucast_flood) 6776 return -EINVAL; 6777 6778 if ((flags.mask & BR_MCAST_FLOOD) && !ops->port_set_mcast_flood) 6779 return -EINVAL; 6780 6781 return 0; 6782} 6783 6784static int mv88e6xxx_port_bridge_flags(struct dsa_switch *ds, int port, 6785 struct switchdev_brport_flags flags, 6786 struct netlink_ext_ack *extack) 6787{ 6788 struct mv88e6xxx_chip *chip = ds->priv; 6789 int err = 0; 6790 6791 mv88e6xxx_reg_lock(chip); 6792 6793 if (flags.mask & BR_LEARNING) { 6794 bool learning = !!(flags.val & BR_LEARNING); 6795 u16 pav = learning ? (1 << port) : 0; 6796 6797 err = mv88e6xxx_port_set_assoc_vector(chip, port, pav); 6798 if (err) 6799 goto out; 6800 } 6801 6802 if (flags.mask & BR_FLOOD) { 6803 bool unicast = !!(flags.val & BR_FLOOD); 6804 6805 err = chip->info->ops->port_set_ucast_flood(chip, port, 6806 unicast); 6807 if (err) 6808 goto out; 6809 } 6810 6811 if (flags.mask & BR_MCAST_FLOOD) { 6812 bool multicast = !!(flags.val & BR_MCAST_FLOOD); 6813 6814 err = chip->info->ops->port_set_mcast_flood(chip, port, 6815 multicast); 6816 if (err) 6817 goto out; 6818 } 6819 6820 if (flags.mask & BR_BCAST_FLOOD) { 6821 bool broadcast = !!(flags.val & BR_BCAST_FLOOD); 6822 6823 err = mv88e6xxx_port_broadcast_sync(chip, port, broadcast); 6824 if (err) 6825 goto out; 6826 } 6827 6828 if (flags.mask & BR_PORT_MAB) { 6829 bool mab = !!(flags.val & BR_PORT_MAB); 6830 6831 mv88e6xxx_port_set_mab(chip, port, mab); 6832 } 6833 6834 if (flags.mask & BR_PORT_LOCKED) { 6835 bool locked = !!(flags.val & BR_PORT_LOCKED); 6836 6837 err = mv88e6xxx_port_set_lock(chip, port, locked); 6838 if (err) 6839 goto out; 6840 } 6841out: 6842 mv88e6xxx_reg_unlock(chip); 6843 6844 return err; 6845} 6846 6847static bool mv88e6xxx_lag_can_offload(struct dsa_switch *ds, 6848 struct dsa_lag lag, 6849 struct netdev_lag_upper_info *info, 6850 struct netlink_ext_ack *extack) 6851{ 6852 struct mv88e6xxx_chip *chip = ds->priv; 6853 struct dsa_port *dp; 6854 int members = 0; 6855 6856 if (!mv88e6xxx_has_lag(chip)) { 6857 NL_SET_ERR_MSG_MOD(extack, "Chip does not support LAG offload"); 6858 return false; 6859 } 6860 6861 if (!lag.id) 6862 return false; 6863 6864 dsa_lag_foreach_port(dp, ds->dst, &lag) 6865 /* Includes the port joining the LAG */ 6866 members++; 6867 6868 if (members > 8) { 6869 NL_SET_ERR_MSG_MOD(extack, 6870 "Cannot offload more than 8 LAG ports"); 6871 return false; 6872 } 6873 6874 /* We could potentially relax this to include active 6875 * backup in the future. 6876 */ 6877 if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) { 6878 NL_SET_ERR_MSG_MOD(extack, 6879 "Can only offload LAG using hash TX type"); 6880 return false; 6881 } 6882 6883 /* Ideally we would also validate that the hash type matches 6884 * the hardware. Alas, this is always set to unknown on team 6885 * interfaces. 6886 */ 6887 return true; 6888} 6889 6890static int mv88e6xxx_lag_sync_map(struct dsa_switch *ds, struct dsa_lag lag) 6891{ 6892 struct mv88e6xxx_chip *chip = ds->priv; 6893 struct dsa_port *dp; 6894 u16 map = 0; 6895 int id; 6896 6897 /* DSA LAG IDs are one-based, hardware is zero-based */ 6898 id = lag.id - 1; 6899 6900 /* Build the map of all ports to distribute flows destined for 6901 * this LAG. This can be either a local user port, or a DSA 6902 * port if the LAG port is on a remote chip. 6903 */ 6904 dsa_lag_foreach_port(dp, ds->dst, &lag) 6905 map |= BIT(dsa_towards_port(ds, dp->ds->index, dp->index)); 6906 6907 return mv88e6xxx_g2_trunk_mapping_write(chip, id, map); 6908} 6909 6910static const u8 mv88e6xxx_lag_mask_table[8][8] = { 6911 /* Row number corresponds to the number of active members in a 6912 * LAG. Each column states which of the eight hash buckets are 6913 * mapped to the column:th port in the LAG. 6914 * 6915 * Example: In a LAG with three active ports, the second port 6916 * ([2][1]) would be selected for traffic mapped to buckets 6917 * 3,4,5 (0x38). 6918 */ 6919 { 0xff, 0, 0, 0, 0, 0, 0, 0 }, 6920 { 0x0f, 0xf0, 0, 0, 0, 0, 0, 0 }, 6921 { 0x07, 0x38, 0xc0, 0, 0, 0, 0, 0 }, 6922 { 0x03, 0x0c, 0x30, 0xc0, 0, 0, 0, 0 }, 6923 { 0x03, 0x0c, 0x30, 0x40, 0x80, 0, 0, 0 }, 6924 { 0x03, 0x0c, 0x10, 0x20, 0x40, 0x80, 0, 0 }, 6925 { 0x03, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0 }, 6926 { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, 6927}; 6928 6929static void mv88e6xxx_lag_set_port_mask(u16 *mask, int port, 6930 int num_tx, int nth) 6931{ 6932 u8 active = 0; 6933 int i; 6934 6935 num_tx = num_tx <= 8 ? num_tx : 8; 6936 if (nth < num_tx) 6937 active = mv88e6xxx_lag_mask_table[num_tx - 1][nth]; 6938 6939 for (i = 0; i < 8; i++) { 6940 if (BIT(i) & active) 6941 mask[i] |= BIT(port); 6942 } 6943} 6944 6945static int mv88e6xxx_lag_sync_masks(struct dsa_switch *ds) 6946{ 6947 struct mv88e6xxx_chip *chip = ds->priv; 6948 unsigned int id, num_tx; 6949 struct dsa_port *dp; 6950 struct dsa_lag *lag; 6951 int i, err, nth; 6952 u16 mask[8]; 6953 u16 ivec; 6954 6955 /* Assume no port is a member of any LAG. */ 6956 ivec = BIT(mv88e6xxx_num_ports(chip)) - 1; 6957 6958 /* Disable all masks for ports that _are_ members of a LAG. */ 6959 dsa_switch_for_each_port(dp, ds) { 6960 if (!dp->lag) 6961 continue; 6962 6963 ivec &= ~BIT(dp->index); 6964 } 6965 6966 for (i = 0; i < 8; i++) 6967 mask[i] = ivec; 6968 6969 /* Enable the correct subset of masks for all LAG ports that 6970 * are in the Tx set. 6971 */ 6972 dsa_lags_foreach_id(id, ds->dst) { 6973 lag = dsa_lag_by_id(ds->dst, id); 6974 if (!lag) 6975 continue; 6976 6977 num_tx = 0; 6978 dsa_lag_foreach_port(dp, ds->dst, lag) { 6979 if (dp->lag_tx_enabled) 6980 num_tx++; 6981 } 6982 6983 if (!num_tx) 6984 continue; 6985 6986 nth = 0; 6987 dsa_lag_foreach_port(dp, ds->dst, lag) { 6988 if (!dp->lag_tx_enabled) 6989 continue; 6990 6991 if (dp->ds == ds) 6992 mv88e6xxx_lag_set_port_mask(mask, dp->index, 6993 num_tx, nth); 6994 6995 nth++; 6996 } 6997 } 6998 6999 for (i = 0; i < 8; i++) { 7000 err = mv88e6xxx_g2_trunk_mask_write(chip, i, true, mask[i]); 7001 if (err) 7002 return err; 7003 } 7004 7005 return 0; 7006} 7007 7008static int mv88e6xxx_lag_sync_masks_map(struct dsa_switch *ds, 7009 struct dsa_lag lag) 7010{ 7011 int err; 7012 7013 err = mv88e6xxx_lag_sync_masks(ds); 7014 7015 if (!err) 7016 err = mv88e6xxx_lag_sync_map(ds, lag); 7017 7018 return err; 7019} 7020 7021static int mv88e6xxx_port_lag_change(struct dsa_switch *ds, int port) 7022{ 7023 struct mv88e6xxx_chip *chip = ds->priv; 7024 int err; 7025 7026 mv88e6xxx_reg_lock(chip); 7027 err = mv88e6xxx_lag_sync_masks(ds); 7028 mv88e6xxx_reg_unlock(chip); 7029 return err; 7030} 7031 7032static int mv88e6xxx_port_lag_join(struct dsa_switch *ds, int port, 7033 struct dsa_lag lag, 7034 struct netdev_lag_upper_info *info, 7035 struct netlink_ext_ack *extack) 7036{ 7037 struct mv88e6xxx_chip *chip = ds->priv; 7038 int err, id; 7039 7040 if (!mv88e6xxx_lag_can_offload(ds, lag, info, extack)) 7041 return -EOPNOTSUPP; 7042 7043 /* DSA LAG IDs are one-based */ 7044 id = lag.id - 1; 7045 7046 mv88e6xxx_reg_lock(chip); 7047 7048 err = mv88e6xxx_port_set_trunk(chip, port, true, id); 7049 if (err) 7050 goto err_unlock; 7051 7052 err = mv88e6xxx_lag_sync_masks_map(ds, lag); 7053 if (err) 7054 goto err_clear_trunk; 7055 7056 mv88e6xxx_reg_unlock(chip); 7057 return 0; 7058 7059err_clear_trunk: 7060 mv88e6xxx_port_set_trunk(chip, port, false, 0); 7061err_unlock: 7062 mv88e6xxx_reg_unlock(chip); 7063 return err; 7064} 7065 7066static int mv88e6xxx_port_lag_leave(struct dsa_switch *ds, int port, 7067 struct dsa_lag lag) 7068{ 7069 struct mv88e6xxx_chip *chip = ds->priv; 7070 int err_sync, err_trunk; 7071 7072 mv88e6xxx_reg_lock(chip); 7073 err_sync = mv88e6xxx_lag_sync_masks_map(ds, lag); 7074 err_trunk = mv88e6xxx_port_set_trunk(chip, port, false, 0); 7075 mv88e6xxx_reg_unlock(chip); 7076 return err_sync ? : err_trunk; 7077} 7078 7079static int mv88e6xxx_crosschip_lag_change(struct dsa_switch *ds, int sw_index, 7080 int port) 7081{ 7082 struct mv88e6xxx_chip *chip = ds->priv; 7083 int err; 7084 7085 mv88e6xxx_reg_lock(chip); 7086 err = mv88e6xxx_lag_sync_masks(ds); 7087 mv88e6xxx_reg_unlock(chip); 7088 return err; 7089} 7090 7091static int mv88e6xxx_crosschip_lag_join(struct dsa_switch *ds, int sw_index, 7092 int port, struct dsa_lag lag, 7093 struct netdev_lag_upper_info *info, 7094 struct netlink_ext_ack *extack) 7095{ 7096 struct mv88e6xxx_chip *chip = ds->priv; 7097 int err; 7098 7099 if (!mv88e6xxx_lag_can_offload(ds, lag, info, extack)) 7100 return -EOPNOTSUPP; 7101 7102 mv88e6xxx_reg_lock(chip); 7103 7104 err = mv88e6xxx_lag_sync_masks_map(ds, lag); 7105 if (err) 7106 goto unlock; 7107 7108 err = mv88e6xxx_pvt_map(chip, sw_index, port); 7109 7110unlock: 7111 mv88e6xxx_reg_unlock(chip); 7112 return err; 7113} 7114 7115static int mv88e6xxx_crosschip_lag_leave(struct dsa_switch *ds, int sw_index, 7116 int port, struct dsa_lag lag) 7117{ 7118 struct mv88e6xxx_chip *chip = ds->priv; 7119 int err_sync, err_pvt; 7120 7121 mv88e6xxx_reg_lock(chip); 7122 err_sync = mv88e6xxx_lag_sync_masks_map(ds, lag); 7123 err_pvt = mv88e6xxx_pvt_map(chip, sw_index, port); 7124 mv88e6xxx_reg_unlock(chip); 7125 return err_sync ? : err_pvt; 7126} 7127 7128static const struct phylink_mac_ops mv88e6xxx_phylink_mac_ops = { 7129 .mac_select_pcs = mv88e6xxx_mac_select_pcs, 7130 .mac_prepare = mv88e6xxx_mac_prepare, 7131 .mac_config = mv88e6xxx_mac_config, 7132 .mac_finish = mv88e6xxx_mac_finish, 7133 .mac_link_down = mv88e6xxx_mac_link_down, 7134 .mac_link_up = mv88e6xxx_mac_link_up, 7135}; 7136 7137static const struct dsa_switch_ops mv88e6xxx_switch_ops = { 7138 .get_tag_protocol = mv88e6xxx_get_tag_protocol, 7139 .change_tag_protocol = mv88e6xxx_change_tag_protocol, 7140 .setup = mv88e6xxx_setup, 7141 .teardown = mv88e6xxx_teardown, 7142 .port_setup = mv88e6xxx_port_setup, 7143 .port_teardown = mv88e6xxx_port_teardown, 7144 .phylink_get_caps = mv88e6xxx_get_caps, 7145 .get_strings = mv88e6xxx_get_strings, 7146 .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, 7147 .get_eth_mac_stats = mv88e6xxx_get_eth_mac_stats, 7148 .get_rmon_stats = mv88e6xxx_get_rmon_stats, 7149 .get_sset_count = mv88e6xxx_get_sset_count, 7150 .port_max_mtu = mv88e6xxx_get_max_mtu, 7151 .port_change_mtu = mv88e6xxx_change_mtu, 7152 .support_eee = dsa_supports_eee, 7153 .set_mac_eee = mv88e6xxx_set_mac_eee, 7154 .get_eeprom_len = mv88e6xxx_get_eeprom_len, 7155 .get_eeprom = mv88e6xxx_get_eeprom, 7156 .set_eeprom = mv88e6xxx_set_eeprom, 7157 .get_regs_len = mv88e6xxx_get_regs_len, 7158 .get_regs = mv88e6xxx_get_regs, 7159 .get_rxnfc = mv88e6xxx_get_rxnfc, 7160 .set_rxnfc = mv88e6xxx_set_rxnfc, 7161 .set_ageing_time = mv88e6xxx_set_ageing_time, 7162 .port_bridge_join = mv88e6xxx_port_bridge_join, 7163 .port_bridge_leave = mv88e6xxx_port_bridge_leave, 7164 .port_pre_bridge_flags = mv88e6xxx_port_pre_bridge_flags, 7165 .port_bridge_flags = mv88e6xxx_port_bridge_flags, 7166 .port_stp_state_set = mv88e6xxx_port_stp_state_set, 7167 .port_mst_state_set = mv88e6xxx_port_mst_state_set, 7168 .port_fast_age = mv88e6xxx_port_fast_age, 7169 .port_vlan_fast_age = mv88e6xxx_port_vlan_fast_age, 7170 .port_vlan_filtering = mv88e6xxx_port_vlan_filtering, 7171 .port_vlan_add = mv88e6xxx_port_vlan_add, 7172 .port_vlan_del = mv88e6xxx_port_vlan_del, 7173 .vlan_msti_set = mv88e6xxx_vlan_msti_set, 7174 .port_fdb_add = mv88e6xxx_port_fdb_add, 7175 .port_fdb_del = mv88e6xxx_port_fdb_del, 7176 .port_fdb_dump = mv88e6xxx_port_fdb_dump, 7177 .port_mdb_add = mv88e6xxx_port_mdb_add, 7178 .port_mdb_del = mv88e6xxx_port_mdb_del, 7179 .port_mirror_add = mv88e6xxx_port_mirror_add, 7180 .port_mirror_del = mv88e6xxx_port_mirror_del, 7181 .crosschip_bridge_join = mv88e6xxx_crosschip_bridge_join, 7182 .crosschip_bridge_leave = mv88e6xxx_crosschip_bridge_leave, 7183 .port_hwtstamp_set = mv88e6xxx_port_hwtstamp_set, 7184 .port_hwtstamp_get = mv88e6xxx_port_hwtstamp_get, 7185 .port_txtstamp = mv88e6xxx_port_txtstamp, 7186 .port_rxtstamp = mv88e6xxx_port_rxtstamp, 7187 .get_ts_info = mv88e6xxx_get_ts_info, 7188 .devlink_param_get = mv88e6xxx_devlink_param_get, 7189 .devlink_param_set = mv88e6xxx_devlink_param_set, 7190 .devlink_info_get = mv88e6xxx_devlink_info_get, 7191 .port_lag_change = mv88e6xxx_port_lag_change, 7192 .port_lag_join = mv88e6xxx_port_lag_join, 7193 .port_lag_leave = mv88e6xxx_port_lag_leave, 7194 .crosschip_lag_change = mv88e6xxx_crosschip_lag_change, 7195 .crosschip_lag_join = mv88e6xxx_crosschip_lag_join, 7196 .crosschip_lag_leave = mv88e6xxx_crosschip_lag_leave, 7197}; 7198 7199static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip) 7200{ 7201 struct device *dev = chip->dev; 7202 struct dsa_switch *ds; 7203 7204 ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL); 7205 if (!ds) 7206 return -ENOMEM; 7207 7208 ds->dev = dev; 7209 ds->num_ports = mv88e6xxx_num_ports(chip); 7210 ds->priv = chip; 7211 ds->dev = dev; 7212 ds->ops = &mv88e6xxx_switch_ops; 7213 ds->phylink_mac_ops = &mv88e6xxx_phylink_mac_ops; 7214 ds->ageing_time_min = chip->info->age_time_coeff; 7215 ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX; 7216 7217 /* Some chips support up to 32, but that requires enabling the 7218 * 5-bit port mode, which we do not support. 640k^W16 ought to 7219 * be enough for anyone. 7220 */ 7221 ds->num_lag_ids = mv88e6xxx_has_lag(chip) ? 16 : 0; 7222 7223 dev_set_drvdata(dev, ds); 7224 7225 return dsa_register_switch(ds); 7226} 7227 7228static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip) 7229{ 7230 dsa_unregister_switch(chip->ds); 7231} 7232 7233static const void *pdata_device_get_match_data(struct device *dev) 7234{ 7235 const struct of_device_id *matches = dev->driver->of_match_table; 7236 const struct dsa_mv88e6xxx_pdata *pdata = dev->platform_data; 7237 7238 for (; matches->name[0] || matches->type[0] || matches->compatible[0]; 7239 matches++) { 7240 if (!strcmp(pdata->compatible, matches->compatible)) 7241 return matches->data; 7242 } 7243 return NULL; 7244} 7245 7246/* There is no suspend to RAM support at DSA level yet, the switch configuration 7247 * would be lost after a power cycle so prevent it to be suspended. 7248 */ 7249static int __maybe_unused mv88e6xxx_suspend(struct device *dev) 7250{ 7251 return -EOPNOTSUPP; 7252} 7253 7254static int __maybe_unused mv88e6xxx_resume(struct device *dev) 7255{ 7256 return 0; 7257} 7258 7259static SIMPLE_DEV_PM_OPS(mv88e6xxx_pm_ops, mv88e6xxx_suspend, mv88e6xxx_resume); 7260 7261static int mv88e6xxx_probe(struct mdio_device *mdiodev) 7262{ 7263 struct dsa_mv88e6xxx_pdata *pdata = mdiodev->dev.platform_data; 7264 const struct mv88e6xxx_info *compat_info = NULL; 7265 struct device *dev = &mdiodev->dev; 7266 struct device_node *np = dev->of_node; 7267 struct mv88e6xxx_chip *chip; 7268 int port; 7269 int err; 7270 7271 if (!np && !pdata) 7272 return -EINVAL; 7273 7274 if (np) 7275 compat_info = of_device_get_match_data(dev); 7276 7277 if (pdata) { 7278 compat_info = pdata_device_get_match_data(dev); 7279 7280 if (!pdata->netdev) 7281 return -EINVAL; 7282 7283 for (port = 0; port < DSA_MAX_PORTS; port++) { 7284 if (!(pdata->enabled_ports & (1 << port))) 7285 continue; 7286 if (strcmp(pdata->cd.port_names[port], "cpu")) 7287 continue; 7288 pdata->cd.netdev[port] = &pdata->netdev->dev; 7289 break; 7290 } 7291 } 7292 7293 if (!compat_info) 7294 return -EINVAL; 7295 7296 chip = mv88e6xxx_alloc_chip(dev); 7297 if (!chip) { 7298 err = -ENOMEM; 7299 goto out; 7300 } 7301 7302 chip->info = compat_info; 7303 7304 chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); 7305 if (IS_ERR(chip->reset)) { 7306 err = PTR_ERR(chip->reset); 7307 goto out; 7308 } 7309 if (chip->reset) 7310 usleep_range(10000, 20000); 7311 7312 /* Detect if the device is configured in single chip addressing mode, 7313 * otherwise continue with address specific smi init/detection. 7314 */ 7315 err = mv88e6xxx_single_chip_detect(chip, mdiodev); 7316 if (err) { 7317 err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr); 7318 if (err) 7319 goto out; 7320 7321 err = mv88e6xxx_detect(chip); 7322 if (err) 7323 goto out; 7324 } 7325 7326 if (chip->info->edsa_support == MV88E6XXX_EDSA_SUPPORTED) 7327 chip->tag_protocol = DSA_TAG_PROTO_EDSA; 7328 else 7329 chip->tag_protocol = DSA_TAG_PROTO_DSA; 7330 7331 mv88e6xxx_phy_init(chip); 7332 7333 if (chip->info->ops->get_eeprom) { 7334 if (np) 7335 of_property_read_u32(np, "eeprom-length", 7336 &chip->eeprom_len); 7337 else 7338 chip->eeprom_len = pdata->eeprom_len; 7339 } 7340 7341 mv88e6xxx_reg_lock(chip); 7342 err = mv88e6xxx_switch_reset(chip); 7343 mv88e6xxx_reg_unlock(chip); 7344 if (err) 7345 goto out_phy; 7346 7347 if (np) { 7348 chip->irq = of_irq_get(np, 0); 7349 if (chip->irq == -EPROBE_DEFER) { 7350 err = chip->irq; 7351 goto out_phy; 7352 } 7353 } 7354 7355 if (pdata) 7356 chip->irq = pdata->irq; 7357 7358 /* Has to be performed before the MDIO bus is created, because 7359 * the PHYs will link their interrupts to these interrupt 7360 * controllers 7361 */ 7362 mv88e6xxx_reg_lock(chip); 7363 if (chip->irq > 0) 7364 err = mv88e6xxx_g1_irq_setup(chip); 7365 else 7366 err = mv88e6xxx_irq_poll_setup(chip); 7367 mv88e6xxx_reg_unlock(chip); 7368 7369 if (err) 7370 goto out_phy; 7371 7372 if (chip->info->g2_irqs > 0) { 7373 err = mv88e6xxx_g2_irq_setup(chip); 7374 if (err) 7375 goto out_g1_irq; 7376 } 7377 7378 err = mv88e6xxx_g1_atu_prob_irq_setup(chip); 7379 if (err) 7380 goto out_g2_irq; 7381 7382 err = mv88e6xxx_g1_vtu_prob_irq_setup(chip); 7383 if (err) 7384 goto out_g1_atu_prob_irq; 7385 7386 err = mv88e6xxx_register_switch(chip); 7387 if (err) 7388 goto out_g1_vtu_prob_irq; 7389 7390 return 0; 7391 7392out_g1_vtu_prob_irq: 7393 mv88e6xxx_g1_vtu_prob_irq_free(chip); 7394out_g1_atu_prob_irq: 7395 mv88e6xxx_g1_atu_prob_irq_free(chip); 7396out_g2_irq: 7397 if (chip->info->g2_irqs > 0) 7398 mv88e6xxx_g2_irq_free(chip); 7399out_g1_irq: 7400 if (chip->irq > 0) 7401 mv88e6xxx_g1_irq_free(chip); 7402 else 7403 mv88e6xxx_irq_poll_free(chip); 7404out_phy: 7405 mv88e6xxx_phy_destroy(chip); 7406out: 7407 if (pdata) 7408 dev_put(pdata->netdev); 7409 7410 return err; 7411} 7412 7413static void mv88e6xxx_remove(struct mdio_device *mdiodev) 7414{ 7415 struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev); 7416 struct mv88e6xxx_chip *chip; 7417 7418 if (!ds) 7419 return; 7420 7421 chip = ds->priv; 7422 7423 mv88e6xxx_unregister_switch(chip); 7424 7425 mv88e6xxx_g1_vtu_prob_irq_free(chip); 7426 mv88e6xxx_g1_atu_prob_irq_free(chip); 7427 7428 if (chip->info->g2_irqs > 0) 7429 mv88e6xxx_g2_irq_free(chip); 7430 7431 if (chip->irq > 0) 7432 mv88e6xxx_g1_irq_free(chip); 7433 else 7434 mv88e6xxx_irq_poll_free(chip); 7435 7436 mv88e6xxx_phy_destroy(chip); 7437} 7438 7439static void mv88e6xxx_shutdown(struct mdio_device *mdiodev) 7440{ 7441 struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev); 7442 7443 if (!ds) 7444 return; 7445 7446 dsa_switch_shutdown(ds); 7447 7448 dev_set_drvdata(&mdiodev->dev, NULL); 7449} 7450 7451static const struct of_device_id mv88e6xxx_of_match[] = { 7452 { 7453 .compatible = "marvell,mv88e6085", 7454 .data = &mv88e6xxx_table[MV88E6085], 7455 }, 7456 { 7457 .compatible = "marvell,mv88e6190", 7458 .data = &mv88e6xxx_table[MV88E6190], 7459 }, 7460 { 7461 .compatible = "marvell,mv88e6250", 7462 .data = &mv88e6xxx_table[MV88E6250], 7463 }, 7464 { /* sentinel */ }, 7465}; 7466 7467MODULE_DEVICE_TABLE(of, mv88e6xxx_of_match); 7468 7469static struct mdio_driver mv88e6xxx_driver = { 7470 .probe = mv88e6xxx_probe, 7471 .remove = mv88e6xxx_remove, 7472 .shutdown = mv88e6xxx_shutdown, 7473 .mdiodrv.driver = { 7474 .name = "mv88e6085", 7475 .of_match_table = mv88e6xxx_of_match, 7476 .pm = &mv88e6xxx_pm_ops, 7477 }, 7478}; 7479 7480mdio_module_driver(mv88e6xxx_driver); 7481 7482MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>"); 7483MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips"); 7484MODULE_LICENSE("GPL");
~/
Read-only file preview.