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) 431 return lane; 432 433 if (chip->ports[port].serdes_irq) { 434 err = mv88e6390_serdes_irq_disable(chip, port, lane); 435 if (err) 436 return err; 437 } 438 439 err = mv88e6390x_serdes_power(chip, port, false); 440 if (err) 441 return err; 442 443 if (cmode) { 444 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 445 if (err) 446 return err; 447 448 reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK; 449 reg |= cmode; 450 451 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg); 452 if (err) 453 return err; 454 455 err = mv88e6390x_serdes_power(chip, port, true); 456 if (err) 457 return err; 458 459 if (chip->ports[port].serdes_irq) { 460 err = mv88e6390_serdes_irq_enable(chip, port, lane); 461 if (err) 462 return err; 463 } 464 } 465 466 chip->ports[port].cmode = cmode; 467 468 return 0; 469 } 470 471 int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, 472 phy_interface_t mode) 473 { 474 switch (mode) { 475 case PHY_INTERFACE_MODE_NA: 476 return 0; 477 case PHY_INTERFACE_MODE_XGMII: 478 case PHY_INTERFACE_MODE_XAUI: 479 case PHY_INTERFACE_MODE_RXAUI: 480 return -EINVAL; 481 default: 482 break; 483 } 484 485 return mv88e6390x_port_set_cmode(chip, port, mode); 486 } 487 488 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) 489 { 490 int err; 491 u16 reg; 492 493 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 494 if (err) 495 return err; 496 497 *cmode = reg & MV88E6185_PORT_STS_CMODE_MASK; 498 499 return 0; 500 } 501 502 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) 503 { 504 int err; 505 u16 reg; 506 507 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 508 if (err) 509 return err; 510 511 *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK; 512 513 return 0; 514 } 515 516 int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port, 517 struct phylink_link_state *state) 518 { 519 int err; 520 u16 reg; 521 522 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 523 if (err) 524 return err; 525 526 switch (reg & MV88E6XXX_PORT_STS_SPEED_MASK) { 527 case MV88E6XXX_PORT_STS_SPEED_10: 528 state->speed = SPEED_10; 529 break; 530 case MV88E6XXX_PORT_STS_SPEED_100: 531 state->speed = SPEED_100; 532 break; 533 case MV88E6XXX_PORT_STS_SPEED_1000: 534 state->speed = SPEED_1000; 535 break; 536 case MV88E6XXX_PORT_STS_SPEED_10000: 537 if ((reg & MV88E6XXX_PORT_STS_CMODE_MASK) == 538 MV88E6XXX_PORT_STS_CMODE_2500BASEX) 539 state->speed = SPEED_2500; 540 else 541 state->speed = SPEED_10000; 542 break; 543 } 544 545 state->duplex = reg & MV88E6XXX_PORT_STS_DUPLEX ? 546 DUPLEX_FULL : DUPLEX_HALF; 547 state->link = !!(reg & MV88E6XXX_PORT_STS_LINK); 548 state->an_enabled = 1; 549 state->an_complete = state->link; 550 551 return 0; 552 } 553 554 int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port, 555 struct phylink_link_state *state) 556 { 557 if (state->interface == PHY_INTERFACE_MODE_1000BASEX) { 558 u8 cmode = chip->ports[port].cmode; 559 560 /* When a port is in "Cross-chip serdes" mode, it uses 561 * 1000Base-X full duplex mode, but there is no automatic 562 * link detection. Use the sync OK status for link (as it 563 * would do for 1000Base-X mode.) 564 */ 565 if (cmode == MV88E6185_PORT_STS_CMODE_SERDES) { 566 u16 mac; 567 int err; 568 569 err = mv88e6xxx_port_read(chip, port, 570 MV88E6XXX_PORT_MAC_CTL, &mac); 571 if (err) 572 return err; 573 574 state->link = !!(mac & MV88E6185_PORT_MAC_CTL_SYNC_OK); 575 state->an_enabled = 1; 576 state->an_complete = 577 !!(mac & MV88E6185_PORT_MAC_CTL_AN_DONE); 578 state->duplex = 579 state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN; 580 state->speed = 581 state->link ? SPEED_1000 : SPEED_UNKNOWN; 582 583 return 0; 584 } 585 } 586 587 return mv88e6352_port_link_state(chip, port, state); 588 } 589 590 /* Offset 0x02: Jamming Control 591 * 592 * Do not limit the period of time that this port can be paused for by 593 * the remote end or the period of time that this port can pause the 594 * remote end. 595 */ 596 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in, 597 u8 out) 598 { 599 return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL, 600 out << 8 | in); 601 } 602 603 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in, 604 u8 out) 605 { 606 int err; 607 608 err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL, 609 MV88E6390_PORT_FLOW_CTL_UPDATE | 610 MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in); 611 if (err) 612 return err; 613 614 return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL, 615 MV88E6390_PORT_FLOW_CTL_UPDATE | 616 MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out); 617 } 618 619 /* Offset 0x04: Port Control Register */ 620 621 static const char * const mv88e6xxx_port_state_names[] = { 622 [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled", 623 [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening", 624 [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning", 625 [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding", 626 }; 627 628 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state) 629 { 630 u16 reg; 631 int err; 632 633 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 634 if (err) 635 return err; 636 637 reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK; 638 639 switch (state) { 640 case BR_STATE_DISABLED: 641 state = MV88E6XXX_PORT_CTL0_STATE_DISABLED; 642 break; 643 case BR_STATE_BLOCKING: 644 case BR_STATE_LISTENING: 645 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING; 646 break; 647 case BR_STATE_LEARNING: 648 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING; 649 break; 650 case BR_STATE_FORWARDING: 651 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING; 652 break; 653 default: 654 return -EINVAL; 655 } 656 657 reg |= state; 658 659 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 660 if (err) 661 return err; 662 663 dev_dbg(chip->dev, "p%d: PortState set to %s\n", port, 664 mv88e6xxx_port_state_names[state]); 665 666 return 0; 667 } 668 669 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port, 670 enum mv88e6xxx_egress_mode mode) 671 { 672 int err; 673 u16 reg; 674 675 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 676 if (err) 677 return err; 678 679 reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK; 680 681 switch (mode) { 682 case MV88E6XXX_EGRESS_MODE_UNMODIFIED: 683 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED; 684 break; 685 case MV88E6XXX_EGRESS_MODE_UNTAGGED: 686 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED; 687 break; 688 case MV88E6XXX_EGRESS_MODE_TAGGED: 689 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED; 690 break; 691 case MV88E6XXX_EGRESS_MODE_ETHERTYPE: 692 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA; 693 break; 694 default: 695 return -EINVAL; 696 } 697 698 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 699 } 700 701 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port, 702 enum mv88e6xxx_frame_mode mode) 703 { 704 int err; 705 u16 reg; 706 707 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 708 if (err) 709 return err; 710 711 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK; 712 713 switch (mode) { 714 case MV88E6XXX_FRAME_MODE_NORMAL: 715 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL; 716 break; 717 case MV88E6XXX_FRAME_MODE_DSA: 718 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA; 719 break; 720 default: 721 return -EINVAL; 722 } 723 724 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 725 } 726 727 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port, 728 enum mv88e6xxx_frame_mode mode) 729 { 730 int err; 731 u16 reg; 732 733 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 734 if (err) 735 return err; 736 737 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK; 738 739 switch (mode) { 740 case MV88E6XXX_FRAME_MODE_NORMAL: 741 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL; 742 break; 743 case MV88E6XXX_FRAME_MODE_DSA: 744 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA; 745 break; 746 case MV88E6XXX_FRAME_MODE_PROVIDER: 747 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER; 748 break; 749 case MV88E6XXX_FRAME_MODE_ETHERTYPE: 750 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA; 751 break; 752 default: 753 return -EINVAL; 754 } 755 756 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 757 } 758 759 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip, 760 int port, bool unicast) 761 { 762 int err; 763 u16 reg; 764 765 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 766 if (err) 767 return err; 768 769 if (unicast) 770 reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN; 771 else 772 reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN; 773 774 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 775 } 776 777 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port, 778 bool unicast, bool multicast) 779 { 780 int err; 781 u16 reg; 782 783 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 784 if (err) 785 return err; 786 787 reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK; 788 789 if (unicast && multicast) 790 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA; 791 else if (unicast) 792 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA; 793 else if (multicast) 794 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA; 795 else 796 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA; 797 798 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 799 } 800 801 /* Offset 0x05: Port Control 1 */ 802 803 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port, 804 bool message_port) 805 { 806 u16 val; 807 int err; 808 809 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val); 810 if (err) 811 return err; 812 813 if (message_port) 814 val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT; 815 else 816 val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT; 817 818 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val); 819 } 820 821 /* Offset 0x06: Port Based VLAN Map */ 822 823 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map) 824 { 825 const u16 mask = mv88e6xxx_port_mask(chip); 826 u16 reg; 827 int err; 828 829 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®); 830 if (err) 831 return err; 832 833 reg &= ~mask; 834 reg |= map & mask; 835 836 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg); 837 if (err) 838 return err; 839 840 dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map); 841 842 return 0; 843 } 844 845 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid) 846 { 847 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4; 848 u16 reg; 849 int err; 850 851 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */ 852 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®); 853 if (err) 854 return err; 855 856 *fid = (reg & 0xf000) >> 12; 857 858 /* Port's default FID upper bits are located in reg 0x05, offset 0 */ 859 if (upper_mask) { 860 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, 861 ®); 862 if (err) 863 return err; 864 865 *fid |= (reg & upper_mask) << 4; 866 } 867 868 return 0; 869 } 870 871 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid) 872 { 873 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4; 874 u16 reg; 875 int err; 876 877 if (fid >= mv88e6xxx_num_databases(chip)) 878 return -EINVAL; 879 880 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */ 881 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®); 882 if (err) 883 return err; 884 885 reg &= 0x0fff; 886 reg |= (fid & 0x000f) << 12; 887 888 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg); 889 if (err) 890 return err; 891 892 /* Port's default FID upper bits are located in reg 0x05, offset 0 */ 893 if (upper_mask) { 894 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, 895 ®); 896 if (err) 897 return err; 898 899 reg &= ~upper_mask; 900 reg |= (fid >> 4) & upper_mask; 901 902 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, 903 reg); 904 if (err) 905 return err; 906 } 907 908 dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid); 909 910 return 0; 911 } 912 913 /* Offset 0x07: Default Port VLAN ID & Priority */ 914 915 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid) 916 { 917 u16 reg; 918 int err; 919 920 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 921 ®); 922 if (err) 923 return err; 924 925 *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK; 926 927 return 0; 928 } 929 930 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid) 931 { 932 u16 reg; 933 int err; 934 935 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 936 ®); 937 if (err) 938 return err; 939 940 reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK; 941 reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK; 942 943 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 944 reg); 945 if (err) 946 return err; 947 948 dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid); 949 950 return 0; 951 } 952 953 /* Offset 0x08: Port Control 2 Register */ 954 955 static const char * const mv88e6xxx_port_8021q_mode_names[] = { 956 [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled", 957 [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback", 958 [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check", 959 [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure", 960 }; 961 962 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip, 963 int port, bool multicast) 964 { 965 int err; 966 u16 reg; 967 968 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 969 if (err) 970 return err; 971 972 if (multicast) 973 reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD; 974 else 975 reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD; 976 977 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 978 } 979 980 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port, 981 bool unicast, bool multicast) 982 { 983 int err; 984 985 err = mv88e6185_port_set_forward_unknown(chip, port, unicast); 986 if (err) 987 return err; 988 989 return mv88e6185_port_set_default_forward(chip, port, multicast); 990 } 991 992 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port, 993 int upstream_port) 994 { 995 int err; 996 u16 reg; 997 998 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 999 if (err) 1000 return err; 1001 1002 reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK; 1003 reg |= upstream_port; 1004 1005 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 1006 } 1007 1008 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port, 1009 u16 mode) 1010 { 1011 u16 reg; 1012 int err; 1013 1014 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 1015 if (err) 1016 return err; 1017 1018 reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK; 1019 reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK; 1020 1021 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 1022 if (err) 1023 return err; 1024 1025 dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port, 1026 mv88e6xxx_port_8021q_mode_names[mode]); 1027 1028 return 0; 1029 } 1030 1031 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port) 1032 { 1033 u16 reg; 1034 int err; 1035 1036 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 1037 if (err) 1038 return err; 1039 1040 reg |= MV88E6XXX_PORT_CTL2_MAP_DA; 1041 1042 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 1043 } 1044 1045 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port, 1046 size_t size) 1047 { 1048 u16 reg; 1049 int err; 1050 1051 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 1052 if (err) 1053 return err; 1054 1055 reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK; 1056 1057 if (size <= 1522) 1058 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522; 1059 else if (size <= 2048) 1060 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048; 1061 else if (size <= 10240) 1062 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240; 1063 else 1064 return -ERANGE; 1065 1066 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 1067 } 1068 1069 /* Offset 0x09: Port Rate Control */ 1070 1071 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port) 1072 { 1073 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1, 1074 0x0000); 1075 } 1076 1077 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port) 1078 { 1079 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1, 1080 0x0001); 1081 } 1082 1083 /* Offset 0x0C: Port ATU Control */ 1084 1085 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port) 1086 { 1087 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0); 1088 } 1089 1090 /* Offset 0x0D: (Priority) Override Register */ 1091 1092 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port) 1093 { 1094 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0); 1095 } 1096 1097 /* Offset 0x0f: Port Ether type */ 1098 1099 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port, 1100 u16 etype) 1101 { 1102 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype); 1103 } 1104 1105 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3] 1106 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7] 1107 */ 1108 1109 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port) 1110 { 1111 int err; 1112 1113 /* Use a direct priority mapping for all IEEE tagged frames */ 1114 err = mv88e6xxx_port_write(chip, port, 1115 MV88E6095_PORT_IEEE_PRIO_REMAP_0123, 1116 0x3210); 1117 if (err) 1118 return err; 1119 1120 return mv88e6xxx_port_write(chip, port, 1121 MV88E6095_PORT_IEEE_PRIO_REMAP_4567, 1122 0x7654); 1123 } 1124 1125 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip, 1126 int port, u16 table, u8 ptr, u16 data) 1127 { 1128 u16 reg; 1129 1130 reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table | 1131 (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) | 1132 (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK); 1133 1134 return mv88e6xxx_port_write(chip, port, 1135 MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg); 1136 } 1137 1138 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port) 1139 { 1140 int err, i; 1141 u16 table; 1142 1143 for (i = 0; i <= 7; i++) { 1144 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP; 1145 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, 1146 (i | i << 4)); 1147 if (err) 1148 return err; 1149 1150 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP; 1151 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i); 1152 if (err) 1153 return err; 1154 1155 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP; 1156 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i); 1157 if (err) 1158 return err; 1159 1160 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP; 1161 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i); 1162 if (err) 1163 return err; 1164 } 1165 1166 return 0; 1167 } 1168