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 -EINVAL; 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 ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 | 232 MV88E6390_PORT_MAC_CTL_ALTSPEED; 233 break; 234 case 10000: 235 /* all bits set, fall through... */ 236 case SPEED_UNFORCED: 237 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED; 238 break; 239 default: 240 return -EOPNOTSUPP; 241 } 242 243 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®); 244 if (err) 245 return err; 246 247 reg &= ~MV88E6XXX_PORT_MAC_CTL_SPEED_MASK; 248 if (alt_bit) 249 reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED; 250 if (force_bit) { 251 reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED; 252 if (speed != SPEED_UNFORCED) 253 ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED; 254 } 255 reg |= ctrl; 256 257 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg); 258 if (err) 259 return err; 260 261 if (speed) 262 dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed); 263 else 264 dev_dbg(chip->dev, "p%d: Speed unforced\n", port); 265 266 return 0; 267 } 268 269 /* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */ 270 int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 271 { 272 if (speed == SPEED_MAX) 273 speed = 200; 274 275 if (speed > 200) 276 return -EOPNOTSUPP; 277 278 /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */ 279 return mv88e6xxx_port_set_speed(chip, port, speed, false, false); 280 } 281 282 /* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */ 283 int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 284 { 285 if (speed == SPEED_MAX) 286 speed = 1000; 287 288 if (speed == 200 || speed > 1000) 289 return -EOPNOTSUPP; 290 291 return mv88e6xxx_port_set_speed(chip, port, speed, false, false); 292 } 293 294 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */ 295 int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 296 { 297 if (speed == SPEED_MAX) 298 speed = 1000; 299 300 if (speed > 1000) 301 return -EOPNOTSUPP; 302 303 if (speed == 200 && port < 5) 304 return -EOPNOTSUPP; 305 306 return mv88e6xxx_port_set_speed(chip, port, speed, true, false); 307 } 308 309 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */ 310 int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 311 { 312 if (speed == SPEED_MAX) 313 speed = port < 9 ? 1000 : 2500; 314 315 if (speed > 2500) 316 return -EOPNOTSUPP; 317 318 if (speed == 200 && port != 0) 319 return -EOPNOTSUPP; 320 321 if (speed == 2500 && port < 9) 322 return -EOPNOTSUPP; 323 324 return mv88e6xxx_port_set_speed(chip, port, speed, true, true); 325 } 326 327 /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */ 328 int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 329 { 330 if (speed == SPEED_MAX) 331 speed = port < 9 ? 1000 : 10000; 332 333 if (speed == 200 && port != 0) 334 return -EOPNOTSUPP; 335 336 if (speed >= 2500 && port < 9) 337 return -EOPNOTSUPP; 338 339 return mv88e6xxx_port_set_speed(chip, port, speed, true, true); 340 } 341 342 int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, 343 phy_interface_t mode) 344 { 345 int lane; 346 u16 cmode; 347 u16 reg; 348 int err; 349 350 if (mode == PHY_INTERFACE_MODE_NA) 351 return 0; 352 353 if (port != 9 && port != 10) 354 return -EOPNOTSUPP; 355 356 switch (mode) { 357 case PHY_INTERFACE_MODE_1000BASEX: 358 cmode = MV88E6XXX_PORT_STS_CMODE_1000BASE_X; 359 break; 360 case PHY_INTERFACE_MODE_SGMII: 361 cmode = MV88E6XXX_PORT_STS_CMODE_SGMII; 362 break; 363 case PHY_INTERFACE_MODE_2500BASEX: 364 cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX; 365 break; 366 case PHY_INTERFACE_MODE_XGMII: 367 case PHY_INTERFACE_MODE_XAUI: 368 cmode = MV88E6XXX_PORT_STS_CMODE_XAUI; 369 break; 370 case PHY_INTERFACE_MODE_RXAUI: 371 cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI; 372 break; 373 default: 374 cmode = 0; 375 } 376 377 lane = mv88e6390x_serdes_get_lane(chip, port); 378 if (lane < 0) 379 return lane; 380 381 if (chip->ports[port].serdes_irq) { 382 err = mv88e6390_serdes_irq_disable(chip, port, lane); 383 if (err) 384 return err; 385 } 386 387 err = mv88e6390_serdes_power(chip, port, false); 388 if (err) 389 return err; 390 391 if (cmode) { 392 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 393 if (err) 394 return err; 395 396 reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK; 397 reg |= cmode; 398 399 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg); 400 if (err) 401 return err; 402 403 err = mv88e6390_serdes_power(chip, port, true); 404 if (err) 405 return err; 406 407 if (chip->ports[port].serdes_irq) { 408 err = mv88e6390_serdes_irq_enable(chip, port, lane); 409 if (err) 410 return err; 411 } 412 } 413 414 chip->ports[port].cmode = cmode; 415 416 return 0; 417 } 418 419 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) 420 { 421 int err; 422 u16 reg; 423 424 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 425 if (err) 426 return err; 427 428 *cmode = reg & MV88E6185_PORT_STS_CMODE_MASK; 429 430 return 0; 431 } 432 433 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) 434 { 435 int err; 436 u16 reg; 437 438 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 439 if (err) 440 return err; 441 442 *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK; 443 444 return 0; 445 } 446 447 int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port, 448 struct phylink_link_state *state) 449 { 450 int err; 451 u16 reg; 452 453 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 454 if (err) 455 return err; 456 457 switch (reg & MV88E6XXX_PORT_STS_SPEED_MASK) { 458 case MV88E6XXX_PORT_STS_SPEED_10: 459 state->speed = SPEED_10; 460 break; 461 case MV88E6XXX_PORT_STS_SPEED_100: 462 state->speed = SPEED_100; 463 break; 464 case MV88E6XXX_PORT_STS_SPEED_1000: 465 state->speed = SPEED_1000; 466 break; 467 case MV88E6XXX_PORT_STS_SPEED_10000: 468 if ((reg & MV88E6XXX_PORT_STS_CMODE_MASK) == 469 MV88E6XXX_PORT_STS_CMODE_2500BASEX) 470 state->speed = SPEED_2500; 471 else 472 state->speed = SPEED_10000; 473 break; 474 } 475 476 state->duplex = reg & MV88E6XXX_PORT_STS_DUPLEX ? 477 DUPLEX_FULL : DUPLEX_HALF; 478 state->link = !!(reg & MV88E6XXX_PORT_STS_LINK); 479 state->an_enabled = 1; 480 state->an_complete = state->link; 481 482 return 0; 483 } 484 485 int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port, 486 struct phylink_link_state *state) 487 { 488 if (state->interface == PHY_INTERFACE_MODE_1000BASEX) { 489 u8 cmode = chip->ports[port].cmode; 490 491 /* When a port is in "Cross-chip serdes" mode, it uses 492 * 1000Base-X full duplex mode, but there is no automatic 493 * link detection. Use the sync OK status for link (as it 494 * would do for 1000Base-X mode.) 495 */ 496 if (cmode == MV88E6185_PORT_STS_CMODE_SERDES) { 497 u16 mac; 498 int err; 499 500 err = mv88e6xxx_port_read(chip, port, 501 MV88E6XXX_PORT_MAC_CTL, &mac); 502 if (err) 503 return err; 504 505 state->link = !!(mac & MV88E6185_PORT_MAC_CTL_SYNC_OK); 506 state->an_enabled = 1; 507 state->an_complete = 508 !!(mac & MV88E6185_PORT_MAC_CTL_AN_DONE); 509 state->duplex = 510 state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN; 511 state->speed = 512 state->link ? SPEED_1000 : SPEED_UNKNOWN; 513 514 return 0; 515 } 516 } 517 518 return mv88e6352_port_link_state(chip, port, state); 519 } 520 521 /* Offset 0x02: Jamming Control 522 * 523 * Do not limit the period of time that this port can be paused for by 524 * the remote end or the period of time that this port can pause the 525 * remote end. 526 */ 527 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in, 528 u8 out) 529 { 530 return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL, 531 out << 8 | in); 532 } 533 534 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in, 535 u8 out) 536 { 537 int err; 538 539 err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL, 540 MV88E6390_PORT_FLOW_CTL_UPDATE | 541 MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in); 542 if (err) 543 return err; 544 545 return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL, 546 MV88E6390_PORT_FLOW_CTL_UPDATE | 547 MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out); 548 } 549 550 /* Offset 0x04: Port Control Register */ 551 552 static const char * const mv88e6xxx_port_state_names[] = { 553 [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled", 554 [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening", 555 [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning", 556 [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding", 557 }; 558 559 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state) 560 { 561 u16 reg; 562 int err; 563 564 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 565 if (err) 566 return err; 567 568 reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK; 569 570 switch (state) { 571 case BR_STATE_DISABLED: 572 state = MV88E6XXX_PORT_CTL0_STATE_DISABLED; 573 break; 574 case BR_STATE_BLOCKING: 575 case BR_STATE_LISTENING: 576 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING; 577 break; 578 case BR_STATE_LEARNING: 579 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING; 580 break; 581 case BR_STATE_FORWARDING: 582 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING; 583 break; 584 default: 585 return -EINVAL; 586 } 587 588 reg |= state; 589 590 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 591 if (err) 592 return err; 593 594 dev_dbg(chip->dev, "p%d: PortState set to %s\n", port, 595 mv88e6xxx_port_state_names[state]); 596 597 return 0; 598 } 599 600 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port, 601 enum mv88e6xxx_egress_mode mode) 602 { 603 int err; 604 u16 reg; 605 606 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 607 if (err) 608 return err; 609 610 reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK; 611 612 switch (mode) { 613 case MV88E6XXX_EGRESS_MODE_UNMODIFIED: 614 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED; 615 break; 616 case MV88E6XXX_EGRESS_MODE_UNTAGGED: 617 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED; 618 break; 619 case MV88E6XXX_EGRESS_MODE_TAGGED: 620 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED; 621 break; 622 case MV88E6XXX_EGRESS_MODE_ETHERTYPE: 623 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA; 624 break; 625 default: 626 return -EINVAL; 627 } 628 629 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 630 } 631 632 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port, 633 enum mv88e6xxx_frame_mode mode) 634 { 635 int err; 636 u16 reg; 637 638 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 639 if (err) 640 return err; 641 642 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK; 643 644 switch (mode) { 645 case MV88E6XXX_FRAME_MODE_NORMAL: 646 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL; 647 break; 648 case MV88E6XXX_FRAME_MODE_DSA: 649 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA; 650 break; 651 default: 652 return -EINVAL; 653 } 654 655 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 656 } 657 658 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port, 659 enum mv88e6xxx_frame_mode mode) 660 { 661 int err; 662 u16 reg; 663 664 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 665 if (err) 666 return err; 667 668 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK; 669 670 switch (mode) { 671 case MV88E6XXX_FRAME_MODE_NORMAL: 672 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL; 673 break; 674 case MV88E6XXX_FRAME_MODE_DSA: 675 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA; 676 break; 677 case MV88E6XXX_FRAME_MODE_PROVIDER: 678 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER; 679 break; 680 case MV88E6XXX_FRAME_MODE_ETHERTYPE: 681 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA; 682 break; 683 default: 684 return -EINVAL; 685 } 686 687 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 688 } 689 690 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip, 691 int port, bool unicast) 692 { 693 int err; 694 u16 reg; 695 696 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 697 if (err) 698 return err; 699 700 if (unicast) 701 reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN; 702 else 703 reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN; 704 705 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 706 } 707 708 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port, 709 bool unicast, bool multicast) 710 { 711 int err; 712 u16 reg; 713 714 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 715 if (err) 716 return err; 717 718 reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK; 719 720 if (unicast && multicast) 721 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA; 722 else if (unicast) 723 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA; 724 else if (multicast) 725 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA; 726 else 727 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA; 728 729 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 730 } 731 732 /* Offset 0x05: Port Control 1 */ 733 734 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port, 735 bool message_port) 736 { 737 u16 val; 738 int err; 739 740 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val); 741 if (err) 742 return err; 743 744 if (message_port) 745 val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT; 746 else 747 val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT; 748 749 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val); 750 } 751 752 /* Offset 0x06: Port Based VLAN Map */ 753 754 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map) 755 { 756 const u16 mask = mv88e6xxx_port_mask(chip); 757 u16 reg; 758 int err; 759 760 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®); 761 if (err) 762 return err; 763 764 reg &= ~mask; 765 reg |= map & mask; 766 767 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg); 768 if (err) 769 return err; 770 771 dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map); 772 773 return 0; 774 } 775 776 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid) 777 { 778 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4; 779 u16 reg; 780 int err; 781 782 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */ 783 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®); 784 if (err) 785 return err; 786 787 *fid = (reg & 0xf000) >> 12; 788 789 /* Port's default FID upper bits are located in reg 0x05, offset 0 */ 790 if (upper_mask) { 791 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, 792 ®); 793 if (err) 794 return err; 795 796 *fid |= (reg & upper_mask) << 4; 797 } 798 799 return 0; 800 } 801 802 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid) 803 { 804 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4; 805 u16 reg; 806 int err; 807 808 if (fid >= mv88e6xxx_num_databases(chip)) 809 return -EINVAL; 810 811 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */ 812 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®); 813 if (err) 814 return err; 815 816 reg &= 0x0fff; 817 reg |= (fid & 0x000f) << 12; 818 819 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg); 820 if (err) 821 return err; 822 823 /* Port's default FID upper bits are located in reg 0x05, offset 0 */ 824 if (upper_mask) { 825 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, 826 ®); 827 if (err) 828 return err; 829 830 reg &= ~upper_mask; 831 reg |= (fid >> 4) & upper_mask; 832 833 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, 834 reg); 835 if (err) 836 return err; 837 } 838 839 dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid); 840 841 return 0; 842 } 843 844 /* Offset 0x07: Default Port VLAN ID & Priority */ 845 846 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid) 847 { 848 u16 reg; 849 int err; 850 851 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 852 ®); 853 if (err) 854 return err; 855 856 *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK; 857 858 return 0; 859 } 860 861 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid) 862 { 863 u16 reg; 864 int err; 865 866 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 867 ®); 868 if (err) 869 return err; 870 871 reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK; 872 reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK; 873 874 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 875 reg); 876 if (err) 877 return err; 878 879 dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid); 880 881 return 0; 882 } 883 884 /* Offset 0x08: Port Control 2 Register */ 885 886 static const char * const mv88e6xxx_port_8021q_mode_names[] = { 887 [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled", 888 [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback", 889 [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check", 890 [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure", 891 }; 892 893 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip, 894 int port, bool multicast) 895 { 896 int err; 897 u16 reg; 898 899 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 900 if (err) 901 return err; 902 903 if (multicast) 904 reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD; 905 else 906 reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD; 907 908 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 909 } 910 911 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port, 912 bool unicast, bool multicast) 913 { 914 int err; 915 916 err = mv88e6185_port_set_forward_unknown(chip, port, unicast); 917 if (err) 918 return err; 919 920 return mv88e6185_port_set_default_forward(chip, port, multicast); 921 } 922 923 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port, 924 int upstream_port) 925 { 926 int err; 927 u16 reg; 928 929 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 930 if (err) 931 return err; 932 933 reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK; 934 reg |= upstream_port; 935 936 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 937 } 938 939 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port, 940 u16 mode) 941 { 942 u16 reg; 943 int err; 944 945 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 946 if (err) 947 return err; 948 949 reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK; 950 reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK; 951 952 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 953 if (err) 954 return err; 955 956 dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port, 957 mv88e6xxx_port_8021q_mode_names[mode]); 958 959 return 0; 960 } 961 962 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port) 963 { 964 u16 reg; 965 int err; 966 967 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 968 if (err) 969 return err; 970 971 reg |= MV88E6XXX_PORT_CTL2_MAP_DA; 972 973 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 974 } 975 976 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port, 977 size_t size) 978 { 979 u16 reg; 980 int err; 981 982 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 983 if (err) 984 return err; 985 986 reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK; 987 988 if (size <= 1522) 989 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522; 990 else if (size <= 2048) 991 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048; 992 else if (size <= 10240) 993 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240; 994 else 995 return -ERANGE; 996 997 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 998 } 999 1000 /* Offset 0x09: Port Rate Control */ 1001 1002 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port) 1003 { 1004 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1, 1005 0x0000); 1006 } 1007 1008 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port) 1009 { 1010 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1, 1011 0x0001); 1012 } 1013 1014 /* Offset 0x0C: Port ATU Control */ 1015 1016 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port) 1017 { 1018 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0); 1019 } 1020 1021 /* Offset 0x0D: (Priority) Override Register */ 1022 1023 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port) 1024 { 1025 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0); 1026 } 1027 1028 /* Offset 0x0f: Port Ether type */ 1029 1030 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port, 1031 u16 etype) 1032 { 1033 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype); 1034 } 1035 1036 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3] 1037 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7] 1038 */ 1039 1040 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port) 1041 { 1042 int err; 1043 1044 /* Use a direct priority mapping for all IEEE tagged frames */ 1045 err = mv88e6xxx_port_write(chip, port, 1046 MV88E6095_PORT_IEEE_PRIO_REMAP_0123, 1047 0x3210); 1048 if (err) 1049 return err; 1050 1051 return mv88e6xxx_port_write(chip, port, 1052 MV88E6095_PORT_IEEE_PRIO_REMAP_4567, 1053 0x7654); 1054 } 1055 1056 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip, 1057 int port, u16 table, u8 ptr, u16 data) 1058 { 1059 u16 reg; 1060 1061 reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table | 1062 (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) | 1063 (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK); 1064 1065 return mv88e6xxx_port_write(chip, port, 1066 MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg); 1067 } 1068 1069 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port) 1070 { 1071 int err, i; 1072 u16 table; 1073 1074 for (i = 0; i <= 7; i++) { 1075 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP; 1076 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, 1077 (i | i << 4)); 1078 if (err) 1079 return err; 1080 1081 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP; 1082 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i); 1083 if (err) 1084 return err; 1085 1086 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP; 1087 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i); 1088 if (err) 1089 return err; 1090 1091 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP; 1092 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i); 1093 if (err) 1094 return err; 1095 } 1096 1097 return 0; 1098 } 1099