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 19 #include "chip.h" 20 #include "port.h" 21 22 int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg, 23 u16 *val) 24 { 25 int addr = chip->info->port_base_addr + port; 26 27 return mv88e6xxx_read(chip, addr, reg, val); 28 } 29 30 int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg, 31 u16 val) 32 { 33 int addr = chip->info->port_base_addr + port; 34 35 return mv88e6xxx_write(chip, addr, reg, val); 36 } 37 38 /* Offset 0x01: MAC (or PCS or Physical) Control Register 39 * 40 * Link, Duplex and Flow Control have one force bit, one value bit. 41 * 42 * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value. 43 * Alternative values require the 200BASE (or AltSpeed) bit 12 set. 44 * Newer chips need a ForcedSpd bit 13 set to consider the value. 45 */ 46 47 static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, 48 phy_interface_t mode) 49 { 50 u16 reg; 51 int err; 52 53 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®); 54 if (err) 55 return err; 56 57 reg &= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK | 58 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK); 59 60 switch (mode) { 61 case PHY_INTERFACE_MODE_RGMII_RXID: 62 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK; 63 break; 64 case PHY_INTERFACE_MODE_RGMII_TXID: 65 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK; 66 break; 67 case PHY_INTERFACE_MODE_RGMII_ID: 68 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK | 69 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK; 70 break; 71 case PHY_INTERFACE_MODE_RGMII: 72 break; 73 default: 74 return 0; 75 } 76 77 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg); 78 if (err) 79 return err; 80 81 dev_dbg(chip->dev, "p%d: delay RXCLK %s, TXCLK %s\n", port, 82 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK ? "yes" : "no", 83 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK ? "yes" : "no"); 84 85 return 0; 86 } 87 88 int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, 89 phy_interface_t mode) 90 { 91 if (port < 5) 92 return -EOPNOTSUPP; 93 94 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode); 95 } 96 97 int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, 98 phy_interface_t mode) 99 { 100 if (port != 0) 101 return -EOPNOTSUPP; 102 103 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode); 104 } 105 106 int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link) 107 { 108 u16 reg; 109 int err; 110 111 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®); 112 if (err) 113 return err; 114 115 reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK | 116 MV88E6XXX_PORT_MAC_CTL_LINK_UP); 117 118 switch (link) { 119 case LINK_FORCED_DOWN: 120 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK; 121 break; 122 case LINK_FORCED_UP: 123 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK | 124 MV88E6XXX_PORT_MAC_CTL_LINK_UP; 125 break; 126 case LINK_UNFORCED: 127 /* normal link detection */ 128 break; 129 default: 130 return -EINVAL; 131 } 132 133 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg); 134 if (err) 135 return err; 136 137 dev_dbg(chip->dev, "p%d: %s link %s\n", port, 138 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_LINK ? "Force" : "Unforce", 139 reg & MV88E6XXX_PORT_MAC_CTL_LINK_UP ? "up" : "down"); 140 141 return 0; 142 } 143 144 int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup) 145 { 146 u16 reg; 147 int err; 148 149 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®); 150 if (err) 151 return err; 152 153 reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX | 154 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL); 155 156 switch (dup) { 157 case DUPLEX_HALF: 158 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX; 159 break; 160 case DUPLEX_FULL: 161 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX | 162 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL; 163 break; 164 case DUPLEX_UNFORCED: 165 /* normal duplex detection */ 166 break; 167 default: 168 return -EINVAL; 169 } 170 171 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg); 172 if (err) 173 return err; 174 175 dev_dbg(chip->dev, "p%d: %s %s duplex\n", port, 176 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce", 177 reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half"); 178 179 return 0; 180 } 181 182 static int mv88e6xxx_port_set_speed(struct mv88e6xxx_chip *chip, int port, 183 int speed, bool alt_bit, bool force_bit) 184 { 185 u16 reg, ctrl; 186 int err; 187 188 switch (speed) { 189 case 10: 190 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10; 191 break; 192 case 100: 193 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100; 194 break; 195 case 200: 196 if (alt_bit) 197 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 | 198 MV88E6390_PORT_MAC_CTL_ALTSPEED; 199 else 200 ctrl = MV88E6065_PORT_MAC_CTL_SPEED_200; 201 break; 202 case 1000: 203 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000; 204 break; 205 case 2500: 206 ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 | 207 MV88E6390_PORT_MAC_CTL_ALTSPEED; 208 break; 209 case 10000: 210 /* all bits set, fall through... */ 211 case SPEED_UNFORCED: 212 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED; 213 break; 214 default: 215 return -EOPNOTSUPP; 216 } 217 218 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®); 219 if (err) 220 return err; 221 222 reg &= ~MV88E6XXX_PORT_MAC_CTL_SPEED_MASK; 223 if (alt_bit) 224 reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED; 225 if (force_bit) { 226 reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED; 227 if (speed != SPEED_UNFORCED) 228 ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED; 229 } 230 reg |= ctrl; 231 232 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg); 233 if (err) 234 return err; 235 236 if (speed) 237 dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed); 238 else 239 dev_dbg(chip->dev, "p%d: Speed unforced\n", port); 240 241 return 0; 242 } 243 244 /* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */ 245 int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 246 { 247 if (speed == SPEED_MAX) 248 speed = 200; 249 250 if (speed > 200) 251 return -EOPNOTSUPP; 252 253 /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */ 254 return mv88e6xxx_port_set_speed(chip, port, speed, false, false); 255 } 256 257 /* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */ 258 int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 259 { 260 if (speed == SPEED_MAX) 261 speed = 1000; 262 263 if (speed == 200 || speed > 1000) 264 return -EOPNOTSUPP; 265 266 return mv88e6xxx_port_set_speed(chip, port, speed, false, false); 267 } 268 269 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */ 270 int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 271 { 272 if (speed == SPEED_MAX) 273 speed = 1000; 274 275 if (speed > 1000) 276 return -EOPNOTSUPP; 277 278 if (speed == 200 && port < 5) 279 return -EOPNOTSUPP; 280 281 return mv88e6xxx_port_set_speed(chip, port, speed, true, false); 282 } 283 284 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */ 285 int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 286 { 287 if (speed == SPEED_MAX) 288 speed = port < 9 ? 1000 : 2500; 289 290 if (speed > 2500) 291 return -EOPNOTSUPP; 292 293 if (speed == 200 && port != 0) 294 return -EOPNOTSUPP; 295 296 if (speed == 2500 && port < 9) 297 return -EOPNOTSUPP; 298 299 return mv88e6xxx_port_set_speed(chip, port, speed, true, true); 300 } 301 302 /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */ 303 int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 304 { 305 if (speed == SPEED_MAX) 306 speed = port < 9 ? 1000 : 10000; 307 308 if (speed == 200 && port != 0) 309 return -EOPNOTSUPP; 310 311 if (speed >= 2500 && port < 9) 312 return -EOPNOTSUPP; 313 314 return mv88e6xxx_port_set_speed(chip, port, speed, true, true); 315 } 316 317 int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, 318 phy_interface_t mode) 319 { 320 u16 reg; 321 u16 cmode; 322 int err; 323 324 if (mode == PHY_INTERFACE_MODE_NA) 325 return 0; 326 327 if (port != 9 && port != 10) 328 return -EOPNOTSUPP; 329 330 switch (mode) { 331 case PHY_INTERFACE_MODE_1000BASEX: 332 cmode = MV88E6XXX_PORT_STS_CMODE_1000BASE_X; 333 break; 334 case PHY_INTERFACE_MODE_SGMII: 335 cmode = MV88E6XXX_PORT_STS_CMODE_SGMII; 336 break; 337 case PHY_INTERFACE_MODE_2500BASEX: 338 cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX; 339 break; 340 case PHY_INTERFACE_MODE_XGMII: 341 cmode = MV88E6XXX_PORT_STS_CMODE_XAUI; 342 break; 343 case PHY_INTERFACE_MODE_RXAUI: 344 cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI; 345 break; 346 default: 347 cmode = 0; 348 } 349 350 if (cmode) { 351 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 352 if (err) 353 return err; 354 355 reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK; 356 reg |= cmode; 357 358 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg); 359 if (err) 360 return err; 361 } 362 363 return 0; 364 } 365 366 int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) 367 { 368 int err; 369 u16 reg; 370 371 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); 372 if (err) 373 return err; 374 375 *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK; 376 377 return 0; 378 } 379 380 /* Offset 0x02: Jamming Control 381 * 382 * Do not limit the period of time that this port can be paused for by 383 * the remote end or the period of time that this port can pause the 384 * remote end. 385 */ 386 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in, 387 u8 out) 388 { 389 return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL, 390 out << 8 | in); 391 } 392 393 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in, 394 u8 out) 395 { 396 int err; 397 398 err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL, 399 MV88E6390_PORT_FLOW_CTL_UPDATE | 400 MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in); 401 if (err) 402 return err; 403 404 return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL, 405 MV88E6390_PORT_FLOW_CTL_UPDATE | 406 MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out); 407 } 408 409 /* Offset 0x04: Port Control Register */ 410 411 static const char * const mv88e6xxx_port_state_names[] = { 412 [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled", 413 [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening", 414 [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning", 415 [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding", 416 }; 417 418 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state) 419 { 420 u16 reg; 421 int err; 422 423 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 424 if (err) 425 return err; 426 427 reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK; 428 429 switch (state) { 430 case BR_STATE_DISABLED: 431 state = MV88E6XXX_PORT_CTL0_STATE_DISABLED; 432 break; 433 case BR_STATE_BLOCKING: 434 case BR_STATE_LISTENING: 435 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING; 436 break; 437 case BR_STATE_LEARNING: 438 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING; 439 break; 440 case BR_STATE_FORWARDING: 441 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING; 442 break; 443 default: 444 return -EINVAL; 445 } 446 447 reg |= state; 448 449 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 450 if (err) 451 return err; 452 453 dev_dbg(chip->dev, "p%d: PortState set to %s\n", port, 454 mv88e6xxx_port_state_names[state]); 455 456 return 0; 457 } 458 459 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port, 460 enum mv88e6xxx_egress_mode mode) 461 { 462 int err; 463 u16 reg; 464 465 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 466 if (err) 467 return err; 468 469 reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK; 470 471 switch (mode) { 472 case MV88E6XXX_EGRESS_MODE_UNMODIFIED: 473 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED; 474 break; 475 case MV88E6XXX_EGRESS_MODE_UNTAGGED: 476 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED; 477 break; 478 case MV88E6XXX_EGRESS_MODE_TAGGED: 479 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED; 480 break; 481 case MV88E6XXX_EGRESS_MODE_ETHERTYPE: 482 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA; 483 break; 484 default: 485 return -EINVAL; 486 } 487 488 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 489 } 490 491 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port, 492 enum mv88e6xxx_frame_mode mode) 493 { 494 int err; 495 u16 reg; 496 497 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 498 if (err) 499 return err; 500 501 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK; 502 503 switch (mode) { 504 case MV88E6XXX_FRAME_MODE_NORMAL: 505 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL; 506 break; 507 case MV88E6XXX_FRAME_MODE_DSA: 508 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA; 509 break; 510 default: 511 return -EINVAL; 512 } 513 514 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 515 } 516 517 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port, 518 enum mv88e6xxx_frame_mode mode) 519 { 520 int err; 521 u16 reg; 522 523 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 524 if (err) 525 return err; 526 527 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK; 528 529 switch (mode) { 530 case MV88E6XXX_FRAME_MODE_NORMAL: 531 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL; 532 break; 533 case MV88E6XXX_FRAME_MODE_DSA: 534 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA; 535 break; 536 case MV88E6XXX_FRAME_MODE_PROVIDER: 537 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER; 538 break; 539 case MV88E6XXX_FRAME_MODE_ETHERTYPE: 540 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA; 541 break; 542 default: 543 return -EINVAL; 544 } 545 546 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 547 } 548 549 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip, 550 int port, bool unicast) 551 { 552 int err; 553 u16 reg; 554 555 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 556 if (err) 557 return err; 558 559 if (unicast) 560 reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN; 561 else 562 reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN; 563 564 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 565 } 566 567 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port, 568 bool unicast, bool multicast) 569 { 570 int err; 571 u16 reg; 572 573 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®); 574 if (err) 575 return err; 576 577 reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK; 578 579 if (unicast && multicast) 580 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA; 581 else if (unicast) 582 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA; 583 else if (multicast) 584 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA; 585 else 586 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA; 587 588 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); 589 } 590 591 /* Offset 0x05: Port Control 1 */ 592 593 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port, 594 bool message_port) 595 { 596 u16 val; 597 int err; 598 599 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val); 600 if (err) 601 return err; 602 603 if (message_port) 604 val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT; 605 else 606 val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT; 607 608 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val); 609 } 610 611 /* Offset 0x06: Port Based VLAN Map */ 612 613 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map) 614 { 615 const u16 mask = mv88e6xxx_port_mask(chip); 616 u16 reg; 617 int err; 618 619 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®); 620 if (err) 621 return err; 622 623 reg &= ~mask; 624 reg |= map & mask; 625 626 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg); 627 if (err) 628 return err; 629 630 dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map); 631 632 return 0; 633 } 634 635 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid) 636 { 637 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4; 638 u16 reg; 639 int err; 640 641 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */ 642 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®); 643 if (err) 644 return err; 645 646 *fid = (reg & 0xf000) >> 12; 647 648 /* Port's default FID upper bits are located in reg 0x05, offset 0 */ 649 if (upper_mask) { 650 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, 651 ®); 652 if (err) 653 return err; 654 655 *fid |= (reg & upper_mask) << 4; 656 } 657 658 return 0; 659 } 660 661 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid) 662 { 663 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4; 664 u16 reg; 665 int err; 666 667 if (fid >= mv88e6xxx_num_databases(chip)) 668 return -EINVAL; 669 670 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */ 671 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®); 672 if (err) 673 return err; 674 675 reg &= 0x0fff; 676 reg |= (fid & 0x000f) << 12; 677 678 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg); 679 if (err) 680 return err; 681 682 /* Port's default FID upper bits are located in reg 0x05, offset 0 */ 683 if (upper_mask) { 684 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, 685 ®); 686 if (err) 687 return err; 688 689 reg &= ~upper_mask; 690 reg |= (fid >> 4) & upper_mask; 691 692 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, 693 reg); 694 if (err) 695 return err; 696 } 697 698 dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid); 699 700 return 0; 701 } 702 703 /* Offset 0x07: Default Port VLAN ID & Priority */ 704 705 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid) 706 { 707 u16 reg; 708 int err; 709 710 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 711 ®); 712 if (err) 713 return err; 714 715 *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK; 716 717 return 0; 718 } 719 720 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid) 721 { 722 u16 reg; 723 int err; 724 725 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 726 ®); 727 if (err) 728 return err; 729 730 reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK; 731 reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK; 732 733 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 734 reg); 735 if (err) 736 return err; 737 738 dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid); 739 740 return 0; 741 } 742 743 /* Offset 0x08: Port Control 2 Register */ 744 745 static const char * const mv88e6xxx_port_8021q_mode_names[] = { 746 [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled", 747 [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback", 748 [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check", 749 [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure", 750 }; 751 752 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip, 753 int port, bool multicast) 754 { 755 int err; 756 u16 reg; 757 758 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 759 if (err) 760 return err; 761 762 if (multicast) 763 reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD; 764 else 765 reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD; 766 767 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 768 } 769 770 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port, 771 bool unicast, bool multicast) 772 { 773 int err; 774 775 err = mv88e6185_port_set_forward_unknown(chip, port, unicast); 776 if (err) 777 return err; 778 779 return mv88e6185_port_set_default_forward(chip, port, multicast); 780 } 781 782 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port, 783 int upstream_port) 784 { 785 int err; 786 u16 reg; 787 788 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 789 if (err) 790 return err; 791 792 reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK; 793 reg |= upstream_port; 794 795 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 796 } 797 798 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port, 799 u16 mode) 800 { 801 u16 reg; 802 int err; 803 804 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 805 if (err) 806 return err; 807 808 reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK; 809 reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK; 810 811 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 812 if (err) 813 return err; 814 815 dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port, 816 mv88e6xxx_port_8021q_mode_names[mode]); 817 818 return 0; 819 } 820 821 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port) 822 { 823 u16 reg; 824 int err; 825 826 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 827 if (err) 828 return err; 829 830 reg |= MV88E6XXX_PORT_CTL2_MAP_DA; 831 832 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 833 } 834 835 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port, 836 size_t size) 837 { 838 u16 reg; 839 int err; 840 841 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®); 842 if (err) 843 return err; 844 845 reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK; 846 847 if (size <= 1522) 848 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522; 849 else if (size <= 2048) 850 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048; 851 else if (size <= 10240) 852 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240; 853 else 854 return -ERANGE; 855 856 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg); 857 } 858 859 /* Offset 0x09: Port Rate Control */ 860 861 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port) 862 { 863 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1, 864 0x0000); 865 } 866 867 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port) 868 { 869 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1, 870 0x0001); 871 } 872 873 /* Offset 0x0C: Port ATU Control */ 874 875 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port) 876 { 877 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0); 878 } 879 880 /* Offset 0x0D: (Priority) Override Register */ 881 882 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port) 883 { 884 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0); 885 } 886 887 /* Offset 0x0f: Port Ether type */ 888 889 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port, 890 u16 etype) 891 { 892 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype); 893 } 894 895 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3] 896 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7] 897 */ 898 899 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port) 900 { 901 int err; 902 903 /* Use a direct priority mapping for all IEEE tagged frames */ 904 err = mv88e6xxx_port_write(chip, port, 905 MV88E6095_PORT_IEEE_PRIO_REMAP_0123, 906 0x3210); 907 if (err) 908 return err; 909 910 return mv88e6xxx_port_write(chip, port, 911 MV88E6095_PORT_IEEE_PRIO_REMAP_4567, 912 0x7654); 913 } 914 915 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip, 916 int port, u16 table, u8 ptr, u16 data) 917 { 918 u16 reg; 919 920 reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table | 921 (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) | 922 (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK); 923 924 return mv88e6xxx_port_write(chip, port, 925 MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg); 926 } 927 928 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port) 929 { 930 int err, i; 931 u16 table; 932 933 for (i = 0; i <= 7; i++) { 934 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP; 935 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, 936 (i | i << 4)); 937 if (err) 938 return err; 939 940 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP; 941 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i); 942 if (err) 943 return err; 944 945 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP; 946 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i); 947 if (err) 948 return err; 949 950 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP; 951 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i); 952 if (err) 953 return err; 954 } 955 956 return 0; 957 } 958