1 /* 2 * Marvell 88E6xxx Switch Port Registers support 3 * 4 * Copyright (c) 2008 Marvell Semiconductor 5 * 6 * Copyright (c) 2016-2017 Savoir-faire Linux Inc. 7 * Vivien Didelot <vivien.didelot@savoirfairelinux.com> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 */ 14 15 #include <linux/bitfield.h> 16 #include <linux/if_bridge.h> 17 #include <linux/phy.h> 18 #include <linux/phylink.h> 19 20 #include "chip.h" 21 #include "port.h" 22 #include "serdes.h" 23 24 int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg, 25 u16 *val) 26 { 27 int addr = chip->info->port_base_addr + port; 28 29 return mv88e6xxx_read(chip, addr, reg, val); 30 } 31 32 int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg, 33 u16 val) 34 { 35 int addr = chip->info->port_base_addr + port; 36 37 return mv88e6xxx_write(chip, addr, reg, val); 38 } 39 40 /* Offset 0x00: MAC (or PCS or Physical) Status Register 41 * 42 * For most devices, this is read only. However the 6185 has the MyPause 43 * bit read/write. 44 */ 45 int mv88e6185_port_set_pause(struct mv88e6xxx_chip *chip, int port, 46 int pause) 47 { 48 u16 reg; 49 int err; 50 51 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 52 if (err) 53 return err; 54 55 if (pause) 56 reg |= MV88E6XXX_PORT_STS_MY_PAUSE; 57 else 58 reg &= ~MV88E6XXX_PORT_STS_MY_PAUSE; 59 60 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg); 61 } 62 63 /* Offset 0x01: MAC (or PCS or Physical) Control Register 64 * 65 * Link, Duplex and Flow Control have one force bit, one value bit. 66 * 67 * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value. 68 * Alternative values require the 200BASE (or AltSpeed) bit 12 set. 69 * Newer chips need a ForcedSpd bit 13 set to consider the value. 70 */ 71 72 static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, 73 phy_interface_t mode) 74 { 75 u16 reg; 76 int err; 77 78 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®); 79 if (err) 80 return err; 81 82 reg &= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK | 83 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK); 84 85 switch (mode) { 86 case PHY_INTERFACE_MODE_RGMII_RXID: 87 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK; 88 break; 89 case PHY_INTERFACE_MODE_RGMII_TXID: 90 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK; 91 break; 92 case PHY_INTERFACE_MODE_RGMII_ID: 93 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK | 94 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK; 95 break; 96 case PHY_INTERFACE_MODE_RGMII: 97 break; 98 default: 99 return 0; 100 } 101 102 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg); 103 if (err) 104 return err; 105 106 dev_dbg(chip->dev, "p%d: delay RXCLK %s, TXCLK %s\n", port, 107 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK ? "yes" : "no", 108 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK ? "yes" : "no"); 109 110 return 0; 111 } 112 113 int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, 114 phy_interface_t mode) 115 { 116 if (port < 5) 117 return -EOPNOTSUPP; 118 119 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode); 120 } 121 122 int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, 123 phy_interface_t mode) 124 { 125 if (port != 0) 126 return -EOPNOTSUPP; 127 128 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode); 129 } 130 131 int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link) 132 { 133 u16 reg; 134 int err; 135 136 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®); 137 if (err) 138 return err; 139 140 reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK | 141 MV88E6XXX_PORT_MAC_CTL_LINK_UP); 142 143 switch (link) { 144 case LINK_FORCED_DOWN: 145 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK; 146 break; 147 case LINK_FORCED_UP: 148 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK | 149 MV88E6XXX_PORT_MAC_CTL_LINK_UP; 150 break; 151 case LINK_UNFORCED: 152 /* normal link detection */ 153 break; 154 default: 155 return -EINVAL; 156 } 157 158 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg); 159 if (err) 160 return err; 161 162 dev_dbg(chip->dev, "p%d: %s link %s\n", port, 163 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_LINK ? "Force" : "Unforce", 164 reg & MV88E6XXX_PORT_MAC_CTL_LINK_UP ? "up" : "down"); 165 166 return 0; 167 } 168 169 int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup) 170 { 171 u16 reg; 172 int err; 173 174 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®); 175 if (err) 176 return err; 177 178 reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX | 179 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL); 180 181 switch (dup) { 182 case DUPLEX_HALF: 183 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX; 184 break; 185 case DUPLEX_FULL: 186 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX | 187 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL; 188 break; 189 case DUPLEX_UNFORCED: 190 /* normal duplex detection */ 191 break; 192 default: 193 return -EOPNOTSUPP; 194 } 195 196 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg); 197 if (err) 198 return err; 199 200 dev_dbg(chip->dev, "p%d: %s %s duplex\n", port, 201 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce", 202 reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half"); 203 204 return 0; 205 } 206 207 static int mv88e6xxx_port_set_speed(struct mv88e6xxx_chip *chip, int port, 208 int speed, bool alt_bit, bool force_bit) 209 { 210 u16 reg, ctrl; 211 int err; 212 213 switch (speed) { 214 case 10: 215 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10; 216 break; 217 case 100: 218 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100; 219 break; 220 case 200: 221 if (alt_bit) 222 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 | 223 MV88E6390_PORT_MAC_CTL_ALTSPEED; 224 else 225 ctrl = MV88E6065_PORT_MAC_CTL_SPEED_200; 226 break; 227 case 1000: 228 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000; 229 break; 230 case 2500: 231 if (alt_bit) 232 ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 | 233 MV88E6390_PORT_MAC_CTL_ALTSPEED; 234 else 235 ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000; 236 break; 237 case 10000: 238 /* all bits set, fall through... */ 239 case SPEED_UNFORCED: 240 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED; 241 break; 242 default: 243 return -EOPNOTSUPP; 244 } 245 246 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®); 247 if (err) 248 return err; 249 250 reg &= ~MV88E6XXX_PORT_MAC_CTL_SPEED_MASK; 251 if (alt_bit) 252 reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED; 253 if (force_bit) { 254 reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED; 255 if (speed != SPEED_UNFORCED) 256 ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED; 257 } 258 reg |= ctrl; 259 260 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg); 261 if (err) 262 return err; 263 264 if (speed) 265 dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed); 266 else 267 dev_dbg(chip->dev, "p%d: Speed unforced\n", port); 268 269 return 0; 270 } 271 272 /* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */ 273 int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 274 { 275 if (speed == SPEED_MAX) 276 speed = 200; 277 278 if (speed > 200) 279 return -EOPNOTSUPP; 280 281 /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */ 282 return mv88e6xxx_port_set_speed(chip, port, speed, false, false); 283 } 284 285 /* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */ 286 int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 287 { 288 if (speed == SPEED_MAX) 289 speed = 1000; 290 291 if (speed == 200 || speed > 1000) 292 return -EOPNOTSUPP; 293 294 return mv88e6xxx_port_set_speed(chip, port, speed, false, false); 295 } 296 297 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6341) */ 298 int mv88e6341_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 299 { 300 if (speed == SPEED_MAX) 301 speed = port < 5 ? 1000 : 2500; 302 303 if (speed > 2500) 304 return -EOPNOTSUPP; 305 306 if (speed == 200 && port != 0) 307 return -EOPNOTSUPP; 308 309 if (speed == 2500 && port < 5) 310 return -EOPNOTSUPP; 311 312 return mv88e6xxx_port_set_speed(chip, port, speed, !port, true); 313 } 314 315 phy_interface_t mv88e6341_port_max_speed_mode(int port) 316 { 317 if (port == 5) 318 return PHY_INTERFACE_MODE_2500BASEX; 319 320 return PHY_INTERFACE_MODE_NA; 321 } 322 323 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */ 324 int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 325 { 326 if (speed == SPEED_MAX) 327 speed = 1000; 328 329 if (speed > 1000) 330 return -EOPNOTSUPP; 331 332 if (speed == 200 && port < 5) 333 return -EOPNOTSUPP; 334 335 return mv88e6xxx_port_set_speed(chip, port, speed, true, false); 336 } 337 338 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */ 339 int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 340 { 341 if (speed == SPEED_MAX) 342 speed = port < 9 ? 1000 : 2500; 343 344 if (speed > 2500) 345 return -EOPNOTSUPP; 346 347 if (speed == 200 && port != 0) 348 return -EOPNOTSUPP; 349 350 if (speed == 2500 && port < 9) 351 return -EOPNOTSUPP; 352 353 return mv88e6xxx_port_set_speed(chip, port, speed, true, true); 354 } 355 356 phy_interface_t mv88e6390_port_max_speed_mode(int port) 357 { 358 if (port == 9 || port == 10) 359 return PHY_INTERFACE_MODE_2500BASEX; 360 361 return PHY_INTERFACE_MODE_NA; 362 } 363 364 /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */ 365 int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 366 { 367 if (speed == SPEED_MAX) 368 speed = port < 9 ? 1000 : 10000; 369 370 if (speed == 200 && port != 0) 371 return -EOPNOTSUPP; 372 373 if (speed >= 2500 && port < 9) 374 return -EOPNOTSUPP; 375 376 return mv88e6xxx_port_set_speed(chip, port, speed, true, true); 377 } 378 379 phy_interface_t mv88e6390x_port_max_speed_mode(int port) 380 { 381 if (port == 9 || port == 10) 382 return PHY_INTERFACE_MODE_XAUI; 383 384 return PHY_INTERFACE_MODE_NA; 385 } 386 387 int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, 388 phy_interface_t mode) 389 { 390 int lane; 391 u16 cmode; 392 u16 reg; 393 int err; 394 395 if (port != 9 && port != 10) 396 return -EOPNOTSUPP; 397 398 /* Default to a slow mode, so freeing up SERDES interfaces for 399 * other ports which might use them for SFPs. 400 */ 401 if (mode == PHY_INTERFACE_MODE_NA) 402 mode = PHY_INTERFACE_MODE_1000BASEX; 403 404 switch (mode) { 405 case PHY_INTERFACE_MODE_1000BASEX: 406 cmode = MV88E6XXX_PORT_STS_CMODE_1000BASE_X; 407 break; 408 case PHY_INTERFACE_MODE_SGMII: 409 cmode = MV88E6XXX_PORT_STS_CMODE_SGMII; 410 break; 411 case PHY_INTERFACE_MODE_2500BASEX: 412 cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX; 413 break; 414 case PHY_INTERFACE_MODE_XGMII: 415 case PHY_INTERFACE_MODE_XAUI: 416 cmode = MV88E6XXX_PORT_STS_CMODE_XAUI; 417 break; 418 case PHY_INTERFACE_MODE_RXAUI: 419 cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI; 420 break; 421 default: 422 cmode = 0; 423 } 424 425 /* cmode doesn't change, nothing to do for us */ 426 if (cmode == chip->ports[port].cmode) 427 return 0; 428 429 lane = mv88e6390x_serdes_get_lane(chip, port); 430 if (lane < 0 && lane != -ENODEV) 431 return lane; 432 433 if (lane >= 0) { 434 if (chip->ports[port].serdes_irq) { 435 err = mv88e6390_serdes_irq_disable(chip, port, lane); 436 if (err) 437 return err; 438 } 439 440 err = mv88e6390x_serdes_power(chip, port, false); 441 if (err) 442 return err; 443 } 444 445 chip->ports[port].cmode = 0; 446 447 if (cmode) { 448 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 449 if (err) 450 return err; 451 452 reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK; 453 reg |= cmode; 454 455 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg); 456 if (err) 457 return err; 458 459 chip->ports[port].cmode = cmode; 460 461 lane = mv88e6390x_serdes_get_lane(chip, port); 462 if (lane < 0) 463 return lane; 464 465 err = mv88e6390x_serdes_power(chip, port, true); 466 if (err) 467 return err; 468 469 if (chip->ports[port].serdes_irq) { 470 err = mv88e6390_serdes_irq_enable(chip, port, lane); 471 if (err) 472 return err; 473 } 474 } 475 476 return 0; 477 } 478 479 int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, 480 phy_interface_t mode) 481 { 482 switch (mode) { 483 case PHY_INTERFACE_MODE_NA: 484 return 0; 485 case PHY_INTERFACE_MODE_XGMII: 486 case PHY_INTERFACE_MODE_XAUI: 487 case PHY_INTERFACE_MODE_RXAUI: 488 return -EINVAL; 489 default: 490 break; 491 } 492 493 return mv88e6390x_port_set_cmode(chip, port, mode); 494 } 495 496 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) 497 { 498 int err; 499 u16 reg; 500 501 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 502 if (err) 503 return err; 504 505 *cmode = reg & MV88E6185_PORT_STS_CMODE_MASK; 506 507 return 0; 508 } 509 510 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) 511 { 512 int err; 513 u16 reg; 514 515 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 516 if (err) 517 return err; 518 519 *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK; 520 521 return 0; 522 } 523 524 int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port, 525 struct phylink_link_state *state) 526 { 527 int err; 528 u16 reg; 529 530 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 531 if (err) 532 return err; 533 534 switch (reg & MV88E6XXX_PORT_STS_SPEED_MASK) { 535 case MV88E6XXX_PORT_STS_SPEED_10: 536 state->speed = SPEED_10; 537 break; 538 case MV88E6XXX_PORT_STS_SPEED_100: 539 state->speed = SPEED_100; 540 break; 541 case MV88E6XXX_PORT_STS_SPEED_1000: 542 state->speed = SPEED_1000; 543 break; 544 case MV88E6XXX_PORT_STS_SPEED_10000: 545 if ((reg & MV88E6XXX_PORT_STS_CMODE_MASK) == 546 MV88E6XXX_PORT_STS_CMODE_2500BASEX) 547 state->speed = SPEED_2500; 548 else 549 state->speed = SPEED_10000; 550 break; 551 } 552 553 state->duplex = reg & MV88E6XXX_PORT_STS_DUPLEX ? 554 DUPLEX_FULL : DUPLEX_HALF; 555 state->link = !!(reg & MV88E6XXX_PORT_STS_LINK); 556 state->an_enabled = 1; 557 state->an_complete = state->link; 558 559 return 0; 560 } 561 562 int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port, 563 struct phylink_link_state *state) 564 { 565 if (state->interface == PHY_INTERFACE_MODE_1000BASEX) { 566 u8 cmode = chip->ports[port].cmode; 567 568 /* When a port is in "Cross-chip serdes" mode, it uses 569 * 1000Base-X full duplex mode, but there is no automatic 570 * link detection. Use the sync OK status for link (as it 571 * would do for 1000Base-X mode.) 572 */ 573 if (cmode == MV88E6185_PORT_STS_CMODE_SERDES) { 574 u16 mac; 575 int err; 576 577 err = mv88e6xxx_port_read(chip, port, 578 MV88E6XXX_PORT_MAC_CTL, &mac); 579 if (err) 580 return err; 581 582 state->link = !!(mac & MV88E6185_PORT_MAC_CTL_SYNC_OK); 583 state->an_enabled = 1; 584 state->an_complete = 585 !!(mac & MV88E6185_PORT_MAC_CTL_AN_DONE); 586 state->duplex = 587 state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN; 588 state->speed = 589 state->link ? SPEED_1000 : SPEED_UNKNOWN; 590 591 return 0; 592 } 593 } 594 595 return mv88e6352_port_link_state(chip, port, state); 596 } 597 598 /* Offset 0x02: Jamming Control 599 * 600 * Do not limit the period of time that this port can be paused for by 601 * the remote end or the period of time that this port can pause the 602 * remote end. 603 */ 604 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in, 605 u8 out) 606 { 607 return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL, 608 out << 8 | in); 609 } 610 611 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in, 612 u8 out) 613 { 614 int err; 615 616 err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL, 617 MV88E6390_PORT_FLOW_CTL_UPDATE | 618 MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in); 619 if (err) 620 return err; 621 622 return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL, 623 MV88E6390_PORT_FLOW_CTL_UPDATE | 624 MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out); 625 } 626 627 /* Offset 0x04: Port Control Register */ 628 629 static const char * const mv88e6xxx_port_state_names[] = { 630 [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled", 631 [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening", 632 [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning", 633 [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding", 634 }; 635 636 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state) 637 { 638 u16 reg; 639 int err; 640 641 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 642 if (err) 643 return err; 644 645 reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK; 646 647 switch (state) { 648 case BR_STATE_DISABLED: 649 state = MV88E6XXX_PORT_CTL0_STATE_DISABLED; 650 break; 651 case BR_STATE_BLOCKING: 652 case BR_STATE_LISTENING: 653 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING; 654 break; 655 case BR_STATE_LEARNING: 656 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING; 657 break; 658 case BR_STATE_FORWARDING: 659 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING; 660 break; 661 default: 662 return -EINVAL; 663 } 664 665 reg |= state; 666 667 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 668 if (err) 669 return err; 670 671 dev_dbg(chip->dev, "p%d: PortState set to %s\n", port, 672 mv88e6xxx_port_state_names[state]); 673 674 return 0; 675 } 676 677 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port, 678 enum mv88e6xxx_egress_mode mode) 679 { 680 int err; 681 u16 reg; 682 683 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 684 if (err) 685 return err; 686 687 reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK; 688 689 switch (mode) { 690 case MV88E6XXX_EGRESS_MODE_UNMODIFIED: 691 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED; 692 break; 693 case MV88E6XXX_EGRESS_MODE_UNTAGGED: 694 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED; 695 break; 696 case MV88E6XXX_EGRESS_MODE_TAGGED: 697 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED; 698 break; 699 case MV88E6XXX_EGRESS_MODE_ETHERTYPE: 700 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA; 701 break; 702 default: 703 return -EINVAL; 704 } 705 706 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 707 } 708 709 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port, 710 enum mv88e6xxx_frame_mode mode) 711 { 712 int err; 713 u16 reg; 714 715 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 716 if (err) 717 return err; 718 719 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK; 720 721 switch (mode) { 722 case MV88E6XXX_FRAME_MODE_NORMAL: 723 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL; 724 break; 725 case MV88E6XXX_FRAME_MODE_DSA: 726 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA; 727 break; 728 default: 729 return -EINVAL; 730 } 731 732 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 733 } 734 735 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port, 736 enum mv88e6xxx_frame_mode mode) 737 { 738 int err; 739 u16 reg; 740 741 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 742 if (err) 743 return err; 744 745 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK; 746 747 switch (mode) { 748 case MV88E6XXX_FRAME_MODE_NORMAL: 749 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL; 750 break; 751 case MV88E6XXX_FRAME_MODE_DSA: 752 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA; 753 break; 754 case MV88E6XXX_FRAME_MODE_PROVIDER: 755 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER; 756 break; 757 case MV88E6XXX_FRAME_MODE_ETHERTYPE: 758 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA; 759 break; 760 default: 761 return -EINVAL; 762 } 763 764 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 765 } 766 767 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip, 768 int port, bool unicast) 769 { 770 int err; 771 u16 reg; 772 773 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 774 if (err) 775 return err; 776 777 if (unicast) 778 reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN; 779 else 780 reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN; 781 782 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 783 } 784 785 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port, 786 bool unicast, bool multicast) 787 { 788 int err; 789 u16 reg; 790 791 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 792 if (err) 793 return err; 794 795 reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK; 796 797 if (unicast && multicast) 798 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA; 799 else if (unicast) 800 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA; 801 else if (multicast) 802 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA; 803 else 804 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA; 805 806 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 807 } 808 809 /* Offset 0x05: Port Control 1 */ 810 811 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port, 812 bool message_port) 813 { 814 u16 val; 815 int err; 816 817 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val); 818 if (err) 819 return err; 820 821 if (message_port) 822 val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT; 823 else 824 val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT; 825 826 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val); 827 } 828 829 /* Offset 0x06: Port Based VLAN Map */ 830 831 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map) 832 { 833 const u16 mask = mv88e6xxx_port_mask(chip); 834 u16 reg; 835 int err; 836 837 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®); 838 if (err) 839 return err; 840 841 reg &= ~mask; 842 reg |= map & mask; 843 844 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg); 845 if (err) 846 return err; 847 848 dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map); 849 850 return 0; 851 } 852 853 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid) 854 { 855 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4; 856 u16 reg; 857 int err; 858 859 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */ 860 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®); 861 if (err) 862 return err; 863 864 *fid = (reg & 0xf000) >> 12; 865 866 /* Port's default FID upper bits are located in reg 0x05, offset 0 */ 867 if (upper_mask) { 868 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, 869 ®); 870 if (err) 871 return err; 872 873 *fid |= (reg & upper_mask) << 4; 874 } 875 876 return 0; 877 } 878 879 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid) 880 { 881 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4; 882 u16 reg; 883 int err; 884 885 if (fid >= mv88e6xxx_num_databases(chip)) 886 return -EINVAL; 887 888 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */ 889 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®); 890 if (err) 891 return err; 892 893 reg &= 0x0fff; 894 reg |= (fid & 0x000f) << 12; 895 896 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg); 897 if (err) 898 return err; 899 900 /* Port's default FID upper bits are located in reg 0x05, offset 0 */ 901 if (upper_mask) { 902 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, 903 ®); 904 if (err) 905 return err; 906 907 reg &= ~upper_mask; 908 reg |= (fid >> 4) & upper_mask; 909 910 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, 911 reg); 912 if (err) 913 return err; 914 } 915 916 dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid); 917 918 return 0; 919 } 920 921 /* Offset 0x07: Default Port VLAN ID & Priority */ 922 923 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid) 924 { 925 u16 reg; 926 int err; 927 928 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 929 ®); 930 if (err) 931 return err; 932 933 *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK; 934 935 return 0; 936 } 937 938 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid) 939 { 940 u16 reg; 941 int err; 942 943 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 944 ®); 945 if (err) 946 return err; 947 948 reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK; 949 reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK; 950 951 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 952 reg); 953 if (err) 954 return err; 955 956 dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid); 957 958 return 0; 959 } 960 961 /* Offset 0x08: Port Control 2 Register */ 962 963 static const char * const mv88e6xxx_port_8021q_mode_names[] = { 964 [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled", 965 [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback", 966 [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check", 967 [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure", 968 }; 969 970 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip, 971 int port, bool multicast) 972 { 973 int err; 974 u16 reg; 975 976 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 977 if (err) 978 return err; 979 980 if (multicast) 981 reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD; 982 else 983 reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD; 984 985 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 986 } 987 988 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port, 989 bool unicast, bool multicast) 990 { 991 int err; 992 993 err = mv88e6185_port_set_forward_unknown(chip, port, unicast); 994 if (err) 995 return err; 996 997 return mv88e6185_port_set_default_forward(chip, port, multicast); 998 } 999 1000 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port, 1001 int upstream_port) 1002 { 1003 int err; 1004 u16 reg; 1005 1006 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 1007 if (err) 1008 return err; 1009 1010 reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK; 1011 reg |= upstream_port; 1012 1013 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 1014 } 1015 1016 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port, 1017 u16 mode) 1018 { 1019 u16 reg; 1020 int err; 1021 1022 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 1023 if (err) 1024 return err; 1025 1026 reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK; 1027 reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK; 1028 1029 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 1030 if (err) 1031 return err; 1032 1033 dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port, 1034 mv88e6xxx_port_8021q_mode_names[mode]); 1035 1036 return 0; 1037 } 1038 1039 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port) 1040 { 1041 u16 reg; 1042 int err; 1043 1044 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 1045 if (err) 1046 return err; 1047 1048 reg |= MV88E6XXX_PORT_CTL2_MAP_DA; 1049 1050 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 1051 } 1052 1053 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port, 1054 size_t size) 1055 { 1056 u16 reg; 1057 int err; 1058 1059 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 1060 if (err) 1061 return err; 1062 1063 reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK; 1064 1065 if (size <= 1522) 1066 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522; 1067 else if (size <= 2048) 1068 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048; 1069 else if (size <= 10240) 1070 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240; 1071 else 1072 return -ERANGE; 1073 1074 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 1075 } 1076 1077 /* Offset 0x09: Port Rate Control */ 1078 1079 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port) 1080 { 1081 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1, 1082 0x0000); 1083 } 1084 1085 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port) 1086 { 1087 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1, 1088 0x0001); 1089 } 1090 1091 /* Offset 0x0C: Port ATU Control */ 1092 1093 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port) 1094 { 1095 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0); 1096 } 1097 1098 /* Offset 0x0D: (Priority) Override Register */ 1099 1100 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port) 1101 { 1102 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0); 1103 } 1104 1105 /* Offset 0x0f: Port Ether type */ 1106 1107 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port, 1108 u16 etype) 1109 { 1110 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype); 1111 } 1112 1113 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3] 1114 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7] 1115 */ 1116 1117 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port) 1118 { 1119 int err; 1120 1121 /* Use a direct priority mapping for all IEEE tagged frames */ 1122 err = mv88e6xxx_port_write(chip, port, 1123 MV88E6095_PORT_IEEE_PRIO_REMAP_0123, 1124 0x3210); 1125 if (err) 1126 return err; 1127 1128 return mv88e6xxx_port_write(chip, port, 1129 MV88E6095_PORT_IEEE_PRIO_REMAP_4567, 1130 0x7654); 1131 } 1132 1133 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip, 1134 int port, u16 table, u8 ptr, u16 data) 1135 { 1136 u16 reg; 1137 1138 reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table | 1139 (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) | 1140 (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK); 1141 1142 return mv88e6xxx_port_write(chip, port, 1143 MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg); 1144 } 1145 1146 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port) 1147 { 1148 int err, i; 1149 u16 table; 1150 1151 for (i = 0; i <= 7; i++) { 1152 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP; 1153 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, 1154 (i | i << 4)); 1155 if (err) 1156 return err; 1157 1158 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP; 1159 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i); 1160 if (err) 1161 return err; 1162 1163 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP; 1164 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i); 1165 if (err) 1166 return err; 1167 1168 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP; 1169 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i); 1170 if (err) 1171 return err; 1172 } 1173 1174 return 0; 1175 } 1176