1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Marvell 88E6xxx SERDES manipulation, via SMI bus 4 * 5 * Copyright (c) 2008 Marvell Semiconductor 6 * 7 * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch> 8 */ 9 10 #include <linux/interrupt.h> 11 #include <linux/irqdomain.h> 12 #include <linux/mii.h> 13 14 #include "chip.h" 15 #include "global2.h" 16 #include "phy.h" 17 #include "port.h" 18 #include "serdes.h" 19 20 static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg, 21 u16 *val) 22 { 23 return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES, 24 MV88E6352_SERDES_PAGE_FIBER, 25 reg, val); 26 } 27 28 static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg, 29 u16 val) 30 { 31 return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES, 32 MV88E6352_SERDES_PAGE_FIBER, 33 reg, val); 34 } 35 36 static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip, 37 int lane, int device, int reg, u16 *val) 38 { 39 int reg_c45 = MII_ADDR_C45 | device << 16 | reg; 40 41 return mv88e6xxx_phy_read(chip, lane, reg_c45, val); 42 } 43 44 static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, 45 int lane, int device, int reg, u16 val) 46 { 47 int reg_c45 = MII_ADDR_C45 | device << 16 | reg; 48 49 return mv88e6xxx_phy_write(chip, lane, reg_c45, val); 50 } 51 52 static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, 53 u16 bmsr, u16 lpa, u16 status, 54 struct phylink_link_state *state) 55 { 56 state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK); 57 state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); 58 59 if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) { 60 /* The Spped and Duplex Resolved register is 1 if AN is enabled 61 * and complete, or if AN is disabled. So with disabled AN we 62 * still get here on link up. 63 */ 64 state->duplex = status & 65 MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ? 66 DUPLEX_FULL : DUPLEX_HALF; 67 68 if (status & MV88E6390_SGMII_PHY_STATUS_TX_PAUSE) 69 state->pause |= MLO_PAUSE_TX; 70 if (status & MV88E6390_SGMII_PHY_STATUS_RX_PAUSE) 71 state->pause |= MLO_PAUSE_RX; 72 73 switch (status & MV88E6390_SGMII_PHY_STATUS_SPEED_MASK) { 74 case MV88E6390_SGMII_PHY_STATUS_SPEED_1000: 75 if (state->interface == PHY_INTERFACE_MODE_2500BASEX) 76 state->speed = SPEED_2500; 77 else 78 state->speed = SPEED_1000; 79 break; 80 case MV88E6390_SGMII_PHY_STATUS_SPEED_100: 81 state->speed = SPEED_100; 82 break; 83 case MV88E6390_SGMII_PHY_STATUS_SPEED_10: 84 state->speed = SPEED_10; 85 break; 86 default: 87 dev_err(chip->dev, "invalid PHY speed\n"); 88 return -EINVAL; 89 } 90 } else if (state->link && 91 state->interface != PHY_INTERFACE_MODE_SGMII) { 92 /* If Speed and Duplex Resolved register is 0 and link is up, it 93 * means that AN was enabled, but link partner had it disabled 94 * and the PHY invoked the Auto-Negotiation Bypass feature and 95 * linked anyway. 96 */ 97 state->duplex = DUPLEX_FULL; 98 if (state->interface == PHY_INTERFACE_MODE_2500BASEX) 99 state->speed = SPEED_2500; 100 else 101 state->speed = SPEED_1000; 102 } else { 103 state->link = false; 104 } 105 106 if (state->interface == PHY_INTERFACE_MODE_2500BASEX) 107 mii_lpa_mod_linkmode_x(state->lp_advertising, lpa, 108 ETHTOOL_LINK_MODE_2500baseX_Full_BIT); 109 else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) 110 mii_lpa_mod_linkmode_x(state->lp_advertising, lpa, 111 ETHTOOL_LINK_MODE_1000baseX_Full_BIT); 112 113 return 0; 114 } 115 116 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane, 117 bool up) 118 { 119 u16 val, new_val; 120 int err; 121 122 err = mv88e6352_serdes_read(chip, MII_BMCR, &val); 123 if (err) 124 return err; 125 126 if (up) 127 new_val = val & ~BMCR_PDOWN; 128 else 129 new_val = val | BMCR_PDOWN; 130 131 if (val != new_val) 132 err = mv88e6352_serdes_write(chip, MII_BMCR, new_val); 133 134 return err; 135 } 136 137 int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, 138 int lane, unsigned int mode, 139 phy_interface_t interface, 140 const unsigned long *advertise) 141 { 142 u16 adv, bmcr, val; 143 bool changed; 144 int err; 145 146 switch (interface) { 147 case PHY_INTERFACE_MODE_SGMII: 148 adv = 0x0001; 149 break; 150 151 case PHY_INTERFACE_MODE_1000BASEX: 152 adv = linkmode_adv_to_mii_adv_x(advertise, 153 ETHTOOL_LINK_MODE_1000baseX_Full_BIT); 154 break; 155 156 default: 157 return 0; 158 } 159 160 err = mv88e6352_serdes_read(chip, MII_ADVERTISE, &val); 161 if (err) 162 return err; 163 164 changed = val != adv; 165 if (changed) { 166 err = mv88e6352_serdes_write(chip, MII_ADVERTISE, adv); 167 if (err) 168 return err; 169 } 170 171 err = mv88e6352_serdes_read(chip, MII_BMCR, &val); 172 if (err) 173 return err; 174 175 if (phylink_autoneg_inband(mode)) 176 bmcr = val | BMCR_ANENABLE; 177 else 178 bmcr = val & ~BMCR_ANENABLE; 179 180 if (bmcr == val) 181 return changed; 182 183 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr); 184 } 185 186 int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, 187 int lane, struct phylink_link_state *state) 188 { 189 u16 bmsr, lpa, status; 190 int err; 191 192 err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr); 193 if (err) { 194 dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err); 195 return err; 196 } 197 198 err = mv88e6352_serdes_read(chip, 0x11, &status); 199 if (err) { 200 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err); 201 return err; 202 } 203 204 err = mv88e6352_serdes_read(chip, MII_LPA, &lpa); 205 if (err) { 206 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err); 207 return err; 208 } 209 210 return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state); 211 } 212 213 int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port, 214 int lane) 215 { 216 u16 bmcr; 217 int err; 218 219 err = mv88e6352_serdes_read(chip, MII_BMCR, &bmcr); 220 if (err) 221 return err; 222 223 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr | BMCR_ANRESTART); 224 } 225 226 int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port, 227 int lane, int speed, int duplex) 228 { 229 u16 val, bmcr; 230 int err; 231 232 err = mv88e6352_serdes_read(chip, MII_BMCR, &val); 233 if (err) 234 return err; 235 236 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000); 237 switch (speed) { 238 case SPEED_1000: 239 bmcr |= BMCR_SPEED1000; 240 break; 241 case SPEED_100: 242 bmcr |= BMCR_SPEED100; 243 break; 244 case SPEED_10: 245 break; 246 } 247 248 if (duplex == DUPLEX_FULL) 249 bmcr |= BMCR_FULLDPLX; 250 251 if (bmcr == val) 252 return 0; 253 254 return mv88e6352_serdes_write(chip, MII_BMCR, bmcr); 255 } 256 257 int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 258 { 259 u8 cmode = chip->ports[port].cmode; 260 int lane = -ENODEV; 261 262 if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) || 263 (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) || 264 (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII)) 265 lane = 0xff; /* Unused */ 266 267 return lane; 268 } 269 270 struct mv88e6352_serdes_hw_stat { 271 char string[ETH_GSTRING_LEN]; 272 int sizeof_stat; 273 int reg; 274 }; 275 276 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = { 277 { "serdes_fibre_rx_error", 16, 21 }, 278 { "serdes_PRBS_error", 32, 24 }, 279 }; 280 281 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port) 282 { 283 int err; 284 285 err = mv88e6352_g2_scratch_port_has_serdes(chip, port); 286 if (err <= 0) 287 return err; 288 289 return ARRAY_SIZE(mv88e6352_serdes_hw_stats); 290 } 291 292 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, 293 int port, uint8_t *data) 294 { 295 struct mv88e6352_serdes_hw_stat *stat; 296 int err, i; 297 298 err = mv88e6352_g2_scratch_port_has_serdes(chip, port); 299 if (err <= 0) 300 return err; 301 302 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) { 303 stat = &mv88e6352_serdes_hw_stats[i]; 304 memcpy(data + i * ETH_GSTRING_LEN, stat->string, 305 ETH_GSTRING_LEN); 306 } 307 return ARRAY_SIZE(mv88e6352_serdes_hw_stats); 308 } 309 310 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip, 311 struct mv88e6352_serdes_hw_stat *stat) 312 { 313 u64 val = 0; 314 u16 reg; 315 int err; 316 317 err = mv88e6352_serdes_read(chip, stat->reg, ®); 318 if (err) { 319 dev_err(chip->dev, "failed to read statistic\n"); 320 return 0; 321 } 322 323 val = reg; 324 325 if (stat->sizeof_stat == 32) { 326 err = mv88e6352_serdes_read(chip, stat->reg + 1, ®); 327 if (err) { 328 dev_err(chip->dev, "failed to read statistic\n"); 329 return 0; 330 } 331 val = val << 16 | reg; 332 } 333 334 return val; 335 } 336 337 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, 338 uint64_t *data) 339 { 340 struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port]; 341 struct mv88e6352_serdes_hw_stat *stat; 342 int i, err; 343 u64 value; 344 345 err = mv88e6352_g2_scratch_port_has_serdes(chip, port); 346 if (err <= 0) 347 return err; 348 349 BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) > 350 ARRAY_SIZE(mv88e6xxx_port->serdes_stats)); 351 352 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) { 353 stat = &mv88e6352_serdes_hw_stats[i]; 354 value = mv88e6352_serdes_get_stat(chip, stat); 355 mv88e6xxx_port->serdes_stats[i] += value; 356 data[i] = mv88e6xxx_port->serdes_stats[i]; 357 } 358 359 return ARRAY_SIZE(mv88e6352_serdes_hw_stats); 360 } 361 362 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port) 363 { 364 u16 bmsr; 365 int err; 366 367 /* If the link has dropped, we want to know about it. */ 368 err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr); 369 if (err) { 370 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err); 371 return; 372 } 373 374 dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS)); 375 } 376 377 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, 378 int lane) 379 { 380 irqreturn_t ret = IRQ_NONE; 381 u16 status; 382 int err; 383 384 err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status); 385 if (err) 386 return ret; 387 388 if (status & MV88E6352_SERDES_INT_LINK_CHANGE) { 389 ret = IRQ_HANDLED; 390 mv88e6352_serdes_irq_link(chip, port); 391 } 392 393 return ret; 394 } 395 396 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane, 397 bool enable) 398 { 399 u16 val = 0; 400 401 if (enable) 402 val |= MV88E6352_SERDES_INT_LINK_CHANGE; 403 404 return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val); 405 } 406 407 unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) 408 { 409 return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ); 410 } 411 412 int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port) 413 { 414 int err; 415 416 mv88e6xxx_reg_lock(chip); 417 err = mv88e6352_g2_scratch_port_has_serdes(chip, port); 418 mv88e6xxx_reg_unlock(chip); 419 if (err <= 0) 420 return err; 421 422 return 32 * sizeof(u16); 423 } 424 425 void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p) 426 { 427 u16 *p = _p; 428 u16 reg; 429 int err; 430 int i; 431 432 err = mv88e6352_g2_scratch_port_has_serdes(chip, port); 433 if (err <= 0) 434 return; 435 436 for (i = 0 ; i < 32; i++) { 437 err = mv88e6352_serdes_read(chip, i, ®); 438 if (!err) 439 p[i] = reg; 440 } 441 } 442 443 int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 444 { 445 u8 cmode = chip->ports[port].cmode; 446 int lane = -ENODEV; 447 448 switch (port) { 449 case 5: 450 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 451 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || 452 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 453 lane = MV88E6341_PORT5_LANE; 454 break; 455 } 456 457 return lane; 458 } 459 460 int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane, 461 bool up) 462 { 463 /* The serdes power can't be controlled on this switch chip but we need 464 * to supply this function to avoid returning -EOPNOTSUPP in 465 * mv88e6xxx_serdes_power_up/mv88e6xxx_serdes_power_down 466 */ 467 return 0; 468 } 469 470 int mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 471 { 472 /* There are no configurable serdes lanes on this switch chip but we 473 * need to return a non-negative lane number so that callers of 474 * mv88e6xxx_serdes_get_lane() know this is a serdes port. 475 */ 476 switch (chip->ports[port].cmode) { 477 case MV88E6185_PORT_STS_CMODE_SERDES: 478 case MV88E6185_PORT_STS_CMODE_1000BASE_X: 479 return 0; 480 default: 481 return -ENODEV; 482 } 483 } 484 485 int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, 486 int lane, struct phylink_link_state *state) 487 { 488 int err; 489 u16 status; 490 491 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status); 492 if (err) 493 return err; 494 495 state->link = !!(status & MV88E6XXX_PORT_STS_LINK); 496 497 if (state->link) { 498 state->duplex = status & MV88E6XXX_PORT_STS_DUPLEX ? DUPLEX_FULL : DUPLEX_HALF; 499 500 switch (status & MV88E6XXX_PORT_STS_SPEED_MASK) { 501 case MV88E6XXX_PORT_STS_SPEED_1000: 502 state->speed = SPEED_1000; 503 break; 504 case MV88E6XXX_PORT_STS_SPEED_100: 505 state->speed = SPEED_100; 506 break; 507 case MV88E6XXX_PORT_STS_SPEED_10: 508 state->speed = SPEED_10; 509 break; 510 default: 511 dev_err(chip->dev, "invalid PHY speed\n"); 512 return -EINVAL; 513 } 514 } else { 515 state->duplex = DUPLEX_UNKNOWN; 516 state->speed = SPEED_UNKNOWN; 517 } 518 519 return 0; 520 } 521 522 int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane, 523 bool enable) 524 { 525 u8 cmode = chip->ports[port].cmode; 526 527 /* The serdes interrupts are enabled in the G2_INT_MASK register. We 528 * need to return 0 to avoid returning -EOPNOTSUPP in 529 * mv88e6xxx_serdes_irq_enable/mv88e6xxx_serdes_irq_disable 530 */ 531 switch (cmode) { 532 case MV88E6185_PORT_STS_CMODE_SERDES: 533 case MV88E6185_PORT_STS_CMODE_1000BASE_X: 534 return 0; 535 } 536 537 return -EOPNOTSUPP; 538 } 539 540 static void mv88e6097_serdes_irq_link(struct mv88e6xxx_chip *chip, int port) 541 { 542 u16 status; 543 int err; 544 545 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status); 546 if (err) { 547 dev_err(chip->dev, "can't read port status: %d\n", err); 548 return; 549 } 550 551 dsa_port_phylink_mac_change(chip->ds, port, !!(status & MV88E6XXX_PORT_STS_LINK)); 552 } 553 554 irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, 555 int lane) 556 { 557 u8 cmode = chip->ports[port].cmode; 558 559 switch (cmode) { 560 case MV88E6185_PORT_STS_CMODE_SERDES: 561 case MV88E6185_PORT_STS_CMODE_1000BASE_X: 562 mv88e6097_serdes_irq_link(chip, port); 563 return IRQ_HANDLED; 564 } 565 566 return IRQ_NONE; 567 } 568 569 int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 570 { 571 u8 cmode = chip->ports[port].cmode; 572 int lane = -ENODEV; 573 574 switch (port) { 575 case 9: 576 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 577 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || 578 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 579 lane = MV88E6390_PORT9_LANE0; 580 break; 581 case 10: 582 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 583 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || 584 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 585 lane = MV88E6390_PORT10_LANE0; 586 break; 587 } 588 589 return lane; 590 } 591 592 int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 593 { 594 u8 cmode_port = chip->ports[port].cmode; 595 u8 cmode_port10 = chip->ports[10].cmode; 596 u8 cmode_port9 = chip->ports[9].cmode; 597 int lane = -ENODEV; 598 599 switch (port) { 600 case 2: 601 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 602 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 603 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 604 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 605 lane = MV88E6390_PORT9_LANE1; 606 break; 607 case 3: 608 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 609 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 610 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 611 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 612 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 613 lane = MV88E6390_PORT9_LANE2; 614 break; 615 case 4: 616 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 617 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 618 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 619 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 620 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 621 lane = MV88E6390_PORT9_LANE3; 622 break; 623 case 5: 624 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 625 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 626 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) 627 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 628 lane = MV88E6390_PORT10_LANE1; 629 break; 630 case 6: 631 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 632 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 633 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 634 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 635 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 636 lane = MV88E6390_PORT10_LANE2; 637 break; 638 case 7: 639 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 640 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 641 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 642 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 643 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) 644 lane = MV88E6390_PORT10_LANE3; 645 break; 646 case 9: 647 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 648 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || 649 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 650 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI || 651 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 652 lane = MV88E6390_PORT9_LANE0; 653 break; 654 case 10: 655 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 656 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || 657 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 658 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI || 659 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) 660 lane = MV88E6390_PORT10_LANE0; 661 break; 662 } 663 664 return lane; 665 } 666 667 /* Only Ports 0, 9 and 10 have SERDES lanes. Return the SERDES lane address 668 * a port is using else Returns -ENODEV. 669 */ 670 int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 671 { 672 u8 cmode = chip->ports[port].cmode; 673 int lane = -ENODEV; 674 675 if (port != 0 && port != 9 && port != 10) 676 return -EOPNOTSUPP; 677 678 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || 679 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || 680 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX || 681 cmode == MV88E6393X_PORT_STS_CMODE_5GBASER || 682 cmode == MV88E6393X_PORT_STS_CMODE_10GBASER) 683 lane = port; 684 685 return lane; 686 } 687 688 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */ 689 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, int lane, 690 bool up) 691 { 692 u16 val, new_val; 693 int err; 694 695 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 696 MV88E6390_10G_CTRL1, &val); 697 698 if (err) 699 return err; 700 701 if (up) 702 new_val = val & ~(MDIO_CTRL1_RESET | 703 MDIO_PCS_CTRL1_LOOPBACK | 704 MDIO_CTRL1_LPOWER); 705 else 706 new_val = val | MDIO_CTRL1_LPOWER; 707 708 if (val != new_val) 709 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 710 MV88E6390_10G_CTRL1, new_val); 711 712 return err; 713 } 714 715 /* Set power up/down for SGMII and 1000Base-X */ 716 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane, 717 bool up) 718 { 719 u16 val, new_val; 720 int err; 721 722 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 723 MV88E6390_SGMII_BMCR, &val); 724 if (err) 725 return err; 726 727 if (up) 728 new_val = val & ~(BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN); 729 else 730 new_val = val | BMCR_PDOWN; 731 732 if (val != new_val) 733 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 734 MV88E6390_SGMII_BMCR, new_val); 735 736 return err; 737 } 738 739 struct mv88e6390_serdes_hw_stat { 740 char string[ETH_GSTRING_LEN]; 741 int reg; 742 }; 743 744 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = { 745 { "serdes_rx_pkts", 0xf021 }, 746 { "serdes_rx_bytes", 0xf024 }, 747 { "serdes_rx_pkts_error", 0xf027 }, 748 }; 749 750 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port) 751 { 752 if (mv88e6xxx_serdes_get_lane(chip, port) < 0) 753 return 0; 754 755 return ARRAY_SIZE(mv88e6390_serdes_hw_stats); 756 } 757 758 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip, 759 int port, uint8_t *data) 760 { 761 struct mv88e6390_serdes_hw_stat *stat; 762 int i; 763 764 if (mv88e6xxx_serdes_get_lane(chip, port) < 0) 765 return 0; 766 767 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) { 768 stat = &mv88e6390_serdes_hw_stats[i]; 769 memcpy(data + i * ETH_GSTRING_LEN, stat->string, 770 ETH_GSTRING_LEN); 771 } 772 return ARRAY_SIZE(mv88e6390_serdes_hw_stats); 773 } 774 775 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane, 776 struct mv88e6390_serdes_hw_stat *stat) 777 { 778 u16 reg[3]; 779 int err, i; 780 781 for (i = 0; i < 3; i++) { 782 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 783 stat->reg + i, ®[i]); 784 if (err) { 785 dev_err(chip->dev, "failed to read statistic\n"); 786 return 0; 787 } 788 } 789 790 return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32); 791 } 792 793 int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, 794 uint64_t *data) 795 { 796 struct mv88e6390_serdes_hw_stat *stat; 797 int lane; 798 int i; 799 800 lane = mv88e6xxx_serdes_get_lane(chip, port); 801 if (lane < 0) 802 return 0; 803 804 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) { 805 stat = &mv88e6390_serdes_hw_stats[i]; 806 data[i] = mv88e6390_serdes_get_stat(chip, lane, stat); 807 } 808 809 return ARRAY_SIZE(mv88e6390_serdes_hw_stats); 810 } 811 812 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, int lane) 813 { 814 u16 reg; 815 int err; 816 817 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 818 MV88E6390_PG_CONTROL, ®); 819 if (err) 820 return err; 821 822 reg |= MV88E6390_PG_CONTROL_ENABLE_PC; 823 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 824 MV88E6390_PG_CONTROL, reg); 825 } 826 827 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane, 828 bool up) 829 { 830 u8 cmode = chip->ports[port].cmode; 831 int err; 832 833 switch (cmode) { 834 case MV88E6XXX_PORT_STS_CMODE_SGMII: 835 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 836 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 837 err = mv88e6390_serdes_power_sgmii(chip, lane, up); 838 break; 839 case MV88E6XXX_PORT_STS_CMODE_XAUI: 840 case MV88E6XXX_PORT_STS_CMODE_RXAUI: 841 err = mv88e6390_serdes_power_10g(chip, lane, up); 842 break; 843 default: 844 err = -EINVAL; 845 break; 846 } 847 848 if (!err && up) 849 err = mv88e6390_serdes_enable_checker(chip, lane); 850 851 return err; 852 } 853 854 int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, 855 int lane, unsigned int mode, 856 phy_interface_t interface, 857 const unsigned long *advertise) 858 { 859 u16 val, bmcr, adv; 860 bool changed; 861 int err; 862 863 switch (interface) { 864 case PHY_INTERFACE_MODE_SGMII: 865 adv = 0x0001; 866 break; 867 868 case PHY_INTERFACE_MODE_1000BASEX: 869 adv = linkmode_adv_to_mii_adv_x(advertise, 870 ETHTOOL_LINK_MODE_1000baseX_Full_BIT); 871 break; 872 873 case PHY_INTERFACE_MODE_2500BASEX: 874 adv = linkmode_adv_to_mii_adv_x(advertise, 875 ETHTOOL_LINK_MODE_2500baseX_Full_BIT); 876 break; 877 878 default: 879 return 0; 880 } 881 882 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 883 MV88E6390_SGMII_ADVERTISE, &val); 884 if (err) 885 return err; 886 887 changed = val != adv; 888 if (changed) { 889 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 890 MV88E6390_SGMII_ADVERTISE, adv); 891 if (err) 892 return err; 893 } 894 895 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 896 MV88E6390_SGMII_BMCR, &val); 897 if (err) 898 return err; 899 900 if (phylink_autoneg_inband(mode)) 901 bmcr = val | BMCR_ANENABLE; 902 else 903 bmcr = val & ~BMCR_ANENABLE; 904 905 /* setting ANENABLE triggers a restart of negotiation */ 906 if (bmcr == val) 907 return changed; 908 909 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 910 MV88E6390_SGMII_BMCR, bmcr); 911 } 912 913 static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip, 914 int port, int lane, struct phylink_link_state *state) 915 { 916 u16 bmsr, lpa, status; 917 int err; 918 919 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 920 MV88E6390_SGMII_BMSR, &bmsr); 921 if (err) { 922 dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err); 923 return err; 924 } 925 926 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 927 MV88E6390_SGMII_PHY_STATUS, &status); 928 if (err) { 929 dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err); 930 return err; 931 } 932 933 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 934 MV88E6390_SGMII_LPA, &lpa); 935 if (err) { 936 dev_err(chip->dev, "can't read Serdes PHY LPA: %d\n", err); 937 return err; 938 } 939 940 return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state); 941 } 942 943 static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip, 944 int port, int lane, struct phylink_link_state *state) 945 { 946 u16 status; 947 int err; 948 949 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 950 MV88E6390_10G_STAT1, &status); 951 if (err) 952 return err; 953 954 state->link = !!(status & MDIO_STAT1_LSTATUS); 955 if (state->link) { 956 state->speed = SPEED_10000; 957 state->duplex = DUPLEX_FULL; 958 } 959 960 return 0; 961 } 962 963 static int mv88e6393x_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip, 964 int port, int lane, 965 struct phylink_link_state *state) 966 { 967 u16 status; 968 int err; 969 970 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 971 MV88E6390_10G_STAT1, &status); 972 if (err) 973 return err; 974 975 state->link = !!(status & MDIO_STAT1_LSTATUS); 976 if (state->link) { 977 if (state->interface == PHY_INTERFACE_MODE_5GBASER) 978 state->speed = SPEED_5000; 979 else 980 state->speed = SPEED_10000; 981 state->duplex = DUPLEX_FULL; 982 } 983 984 return 0; 985 } 986 987 int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, 988 int lane, struct phylink_link_state *state) 989 { 990 switch (state->interface) { 991 case PHY_INTERFACE_MODE_SGMII: 992 case PHY_INTERFACE_MODE_1000BASEX: 993 case PHY_INTERFACE_MODE_2500BASEX: 994 return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane, 995 state); 996 case PHY_INTERFACE_MODE_XAUI: 997 case PHY_INTERFACE_MODE_RXAUI: 998 return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane, 999 state); 1000 1001 default: 1002 return -EOPNOTSUPP; 1003 } 1004 } 1005 1006 int mv88e6393x_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, 1007 int lane, struct phylink_link_state *state) 1008 { 1009 switch (state->interface) { 1010 case PHY_INTERFACE_MODE_SGMII: 1011 case PHY_INTERFACE_MODE_1000BASEX: 1012 case PHY_INTERFACE_MODE_2500BASEX: 1013 return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane, 1014 state); 1015 case PHY_INTERFACE_MODE_5GBASER: 1016 case PHY_INTERFACE_MODE_10GBASER: 1017 return mv88e6393x_serdes_pcs_get_state_10g(chip, port, lane, 1018 state); 1019 1020 default: 1021 return -EOPNOTSUPP; 1022 } 1023 } 1024 1025 int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port, 1026 int lane) 1027 { 1028 u16 bmcr; 1029 int err; 1030 1031 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 1032 MV88E6390_SGMII_BMCR, &bmcr); 1033 if (err) 1034 return err; 1035 1036 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 1037 MV88E6390_SGMII_BMCR, 1038 bmcr | BMCR_ANRESTART); 1039 } 1040 1041 int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port, 1042 int lane, int speed, int duplex) 1043 { 1044 u16 val, bmcr; 1045 int err; 1046 1047 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 1048 MV88E6390_SGMII_BMCR, &val); 1049 if (err) 1050 return err; 1051 1052 bmcr = val & ~(BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_SPEED1000); 1053 switch (speed) { 1054 case SPEED_2500: 1055 case SPEED_1000: 1056 bmcr |= BMCR_SPEED1000; 1057 break; 1058 case SPEED_100: 1059 bmcr |= BMCR_SPEED100; 1060 break; 1061 case SPEED_10: 1062 break; 1063 } 1064 1065 if (duplex == DUPLEX_FULL) 1066 bmcr |= BMCR_FULLDPLX; 1067 1068 if (bmcr == val) 1069 return 0; 1070 1071 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 1072 MV88E6390_SGMII_BMCR, bmcr); 1073 } 1074 1075 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip, 1076 int port, int lane) 1077 { 1078 u16 bmsr; 1079 int err; 1080 1081 /* If the link has dropped, we want to know about it. */ 1082 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 1083 MV88E6390_SGMII_BMSR, &bmsr); 1084 if (err) { 1085 dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err); 1086 return; 1087 } 1088 1089 dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS)); 1090 } 1091 1092 static void mv88e6393x_serdes_irq_link_10g(struct mv88e6xxx_chip *chip, 1093 int port, u8 lane) 1094 { 1095 u16 status; 1096 int err; 1097 1098 /* If the link has dropped, we want to know about it. */ 1099 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 1100 MV88E6390_10G_STAT1, &status); 1101 if (err) { 1102 dev_err(chip->dev, "can't read Serdes STAT1: %d\n", err); 1103 return; 1104 } 1105 1106 dsa_port_phylink_mac_change(chip->ds, port, !!(status & MDIO_STAT1_LSTATUS)); 1107 } 1108 1109 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip, 1110 int lane, bool enable) 1111 { 1112 u16 val = 0; 1113 1114 if (enable) 1115 val |= MV88E6390_SGMII_INT_LINK_DOWN | 1116 MV88E6390_SGMII_INT_LINK_UP; 1117 1118 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 1119 MV88E6390_SGMII_INT_ENABLE, val); 1120 } 1121 1122 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane, 1123 bool enable) 1124 { 1125 u8 cmode = chip->ports[port].cmode; 1126 1127 switch (cmode) { 1128 case MV88E6XXX_PORT_STS_CMODE_SGMII: 1129 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 1130 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 1131 return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable); 1132 } 1133 1134 return 0; 1135 } 1136 1137 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip, 1138 int lane, u16 *status) 1139 { 1140 int err; 1141 1142 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 1143 MV88E6390_SGMII_INT_STATUS, status); 1144 1145 return err; 1146 } 1147 1148 static int mv88e6393x_serdes_irq_enable_10g(struct mv88e6xxx_chip *chip, 1149 u8 lane, bool enable) 1150 { 1151 u16 val = 0; 1152 1153 if (enable) 1154 val |= MV88E6393X_10G_INT_LINK_CHANGE; 1155 1156 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 1157 MV88E6393X_10G_INT_ENABLE, val); 1158 } 1159 1160 int mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, 1161 int lane, bool enable) 1162 { 1163 u8 cmode = chip->ports[port].cmode; 1164 1165 switch (cmode) { 1166 case MV88E6XXX_PORT_STS_CMODE_SGMII: 1167 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 1168 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 1169 return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable); 1170 case MV88E6393X_PORT_STS_CMODE_5GBASER: 1171 case MV88E6393X_PORT_STS_CMODE_10GBASER: 1172 return mv88e6393x_serdes_irq_enable_10g(chip, lane, enable); 1173 } 1174 1175 return 0; 1176 } 1177 1178 static int mv88e6393x_serdes_irq_status_10g(struct mv88e6xxx_chip *chip, 1179 u8 lane, u16 *status) 1180 { 1181 int err; 1182 1183 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 1184 MV88E6393X_10G_INT_STATUS, status); 1185 1186 return err; 1187 } 1188 1189 irqreturn_t mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, 1190 int lane) 1191 { 1192 u8 cmode = chip->ports[port].cmode; 1193 irqreturn_t ret = IRQ_NONE; 1194 u16 status; 1195 int err; 1196 1197 switch (cmode) { 1198 case MV88E6XXX_PORT_STS_CMODE_SGMII: 1199 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 1200 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 1201 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status); 1202 if (err) 1203 return ret; 1204 if (status & (MV88E6390_SGMII_INT_LINK_DOWN | 1205 MV88E6390_SGMII_INT_LINK_UP)) { 1206 ret = IRQ_HANDLED; 1207 mv88e6390_serdes_irq_link_sgmii(chip, port, lane); 1208 } 1209 break; 1210 case MV88E6393X_PORT_STS_CMODE_5GBASER: 1211 case MV88E6393X_PORT_STS_CMODE_10GBASER: 1212 err = mv88e6393x_serdes_irq_status_10g(chip, lane, &status); 1213 if (err) 1214 return err; 1215 if (status & MV88E6393X_10G_INT_LINK_CHANGE) { 1216 ret = IRQ_HANDLED; 1217 mv88e6393x_serdes_irq_link_10g(chip, port, lane); 1218 } 1219 break; 1220 } 1221 1222 return ret; 1223 } 1224 1225 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, 1226 int lane) 1227 { 1228 u8 cmode = chip->ports[port].cmode; 1229 irqreturn_t ret = IRQ_NONE; 1230 u16 status; 1231 int err; 1232 1233 switch (cmode) { 1234 case MV88E6XXX_PORT_STS_CMODE_SGMII: 1235 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 1236 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 1237 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status); 1238 if (err) 1239 return ret; 1240 if (status & (MV88E6390_SGMII_INT_LINK_DOWN | 1241 MV88E6390_SGMII_INT_LINK_UP)) { 1242 ret = IRQ_HANDLED; 1243 mv88e6390_serdes_irq_link_sgmii(chip, port, lane); 1244 } 1245 } 1246 1247 return ret; 1248 } 1249 1250 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) 1251 { 1252 return irq_find_mapping(chip->g2_irq.domain, port); 1253 } 1254 1255 static const u16 mv88e6390_serdes_regs[] = { 1256 /* SERDES common registers */ 1257 0xf00a, 0xf00b, 0xf00c, 1258 0xf010, 0xf011, 0xf012, 0xf013, 1259 0xf016, 0xf017, 0xf018, 1260 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f, 1261 0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027, 1262 0xf028, 0xf029, 1263 0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037, 1264 0xf038, 0xf039, 1265 /* SGMII */ 1266 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 1267 0x2008, 1268 0x200f, 1269 0xa000, 0xa001, 0xa002, 0xa003, 1270 /* 10Gbase-X */ 1271 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 1272 0x1008, 1273 0x100e, 0x100f, 1274 0x1018, 0x1019, 1275 0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 1276 0x9006, 1277 0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016, 1278 /* 10Gbase-R */ 1279 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027, 1280 0x1028, 0x1029, 0x102a, 0x102b, 1281 }; 1282 1283 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port) 1284 { 1285 if (mv88e6xxx_serdes_get_lane(chip, port) < 0) 1286 return 0; 1287 1288 return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16); 1289 } 1290 1291 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p) 1292 { 1293 u16 *p = _p; 1294 int lane; 1295 u16 reg; 1296 int err; 1297 int i; 1298 1299 lane = mv88e6xxx_serdes_get_lane(chip, port); 1300 if (lane < 0) 1301 return; 1302 1303 for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) { 1304 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 1305 mv88e6390_serdes_regs[i], ®); 1306 if (!err) 1307 p[i] = reg; 1308 } 1309 } 1310 1311 static const int mv88e6352_serdes_p2p_to_reg[] = { 1312 /* Index of value in microvolts corresponds to the register value */ 1313 14000, 112000, 210000, 308000, 406000, 504000, 602000, 700000, 1314 }; 1315 1316 int mv88e6352_serdes_set_tx_amplitude(struct mv88e6xxx_chip *chip, int port, 1317 int val) 1318 { 1319 bool found = false; 1320 u16 ctrl, reg; 1321 int err; 1322 int i; 1323 1324 err = mv88e6352_g2_scratch_port_has_serdes(chip, port); 1325 if (err <= 0) 1326 return err; 1327 1328 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_p2p_to_reg); ++i) { 1329 if (mv88e6352_serdes_p2p_to_reg[i] == val) { 1330 reg = i; 1331 found = true; 1332 break; 1333 } 1334 } 1335 1336 if (!found) 1337 return -EINVAL; 1338 1339 err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_SPEC_CTRL2, &ctrl); 1340 if (err) 1341 return err; 1342 1343 ctrl &= ~MV88E6352_SERDES_OUT_AMP_MASK; 1344 ctrl |= reg; 1345 1346 return mv88e6352_serdes_write(chip, MV88E6352_SERDES_SPEC_CTRL2, ctrl); 1347 } 1348 1349 static int mv88e6393x_serdes_power_lane(struct mv88e6xxx_chip *chip, int lane, 1350 bool on) 1351 { 1352 u16 reg; 1353 int err; 1354 1355 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 1356 MV88E6393X_SERDES_CTRL1, ®); 1357 if (err) 1358 return err; 1359 1360 if (on) 1361 reg &= ~(MV88E6393X_SERDES_CTRL1_TX_PDOWN | 1362 MV88E6393X_SERDES_CTRL1_RX_PDOWN); 1363 else 1364 reg |= MV88E6393X_SERDES_CTRL1_TX_PDOWN | 1365 MV88E6393X_SERDES_CTRL1_RX_PDOWN; 1366 1367 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 1368 MV88E6393X_SERDES_CTRL1, reg); 1369 } 1370 1371 static int mv88e6393x_serdes_erratum_4_6(struct mv88e6xxx_chip *chip, int lane) 1372 { 1373 u16 reg; 1374 int err; 1375 1376 /* mv88e6393x family errata 4.6: 1377 * Cannot clear PwrDn bit on SERDES if device is configured CPU_MGD 1378 * mode or P0_mode is configured for [x]MII. 1379 * Workaround: Set SERDES register 4.F002 bit 5=0 and bit 15=1. 1380 * 1381 * It seems that after this workaround the SERDES is automatically 1382 * powered up (the bit is cleared), so power it down. 1383 */ 1384 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 1385 MV88E6393X_SERDES_POC, ®); 1386 if (err) 1387 return err; 1388 1389 reg &= ~MV88E6393X_SERDES_POC_PDOWN; 1390 reg |= MV88E6393X_SERDES_POC_RESET; 1391 1392 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 1393 MV88E6393X_SERDES_POC, reg); 1394 if (err) 1395 return err; 1396 1397 err = mv88e6390_serdes_power_sgmii(chip, lane, false); 1398 if (err) 1399 return err; 1400 1401 return mv88e6393x_serdes_power_lane(chip, lane, false); 1402 } 1403 1404 int mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip *chip) 1405 { 1406 int err; 1407 1408 err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT0_LANE); 1409 if (err) 1410 return err; 1411 1412 err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT9_LANE); 1413 if (err) 1414 return err; 1415 1416 return mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT10_LANE); 1417 } 1418 1419 static int mv88e6393x_serdes_erratum_4_8(struct mv88e6xxx_chip *chip, int lane) 1420 { 1421 u16 reg, pcs; 1422 int err; 1423 1424 /* mv88e6393x family errata 4.8: 1425 * When a SERDES port is operating in 1000BASE-X or SGMII mode link may 1426 * not come up after hardware reset or software reset of SERDES core. 1427 * Workaround is to write SERDES register 4.F074.14=1 for only those 1428 * modes and 0 in all other modes. 1429 */ 1430 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 1431 MV88E6393X_SERDES_POC, &pcs); 1432 if (err) 1433 return err; 1434 1435 pcs &= MV88E6393X_SERDES_POC_PCS_MASK; 1436 1437 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 1438 MV88E6393X_ERRATA_4_8_REG, ®); 1439 if (err) 1440 return err; 1441 1442 if (pcs == MV88E6393X_SERDES_POC_PCS_1000BASEX || 1443 pcs == MV88E6393X_SERDES_POC_PCS_SGMII_PHY || 1444 pcs == MV88E6393X_SERDES_POC_PCS_SGMII_MAC) 1445 reg |= MV88E6393X_ERRATA_4_8_BIT; 1446 else 1447 reg &= ~MV88E6393X_ERRATA_4_8_BIT; 1448 1449 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 1450 MV88E6393X_ERRATA_4_8_REG, reg); 1451 } 1452 1453 static int mv88e6393x_serdes_erratum_5_2(struct mv88e6xxx_chip *chip, int lane, 1454 u8 cmode) 1455 { 1456 static const struct { 1457 u16 dev, reg, val, mask; 1458 } fixes[] = { 1459 { MDIO_MMD_VEND1, 0x8093, 0xcb5a, 0xffff }, 1460 { MDIO_MMD_VEND1, 0x8171, 0x7088, 0xffff }, 1461 { MDIO_MMD_VEND1, 0x80c9, 0x311a, 0xffff }, 1462 { MDIO_MMD_VEND1, 0x80a2, 0x8000, 0xff7f }, 1463 { MDIO_MMD_VEND1, 0x80a9, 0x0000, 0xfff0 }, 1464 { MDIO_MMD_VEND1, 0x80a3, 0x0000, 0xf8ff }, 1465 { MDIO_MMD_PHYXS, MV88E6393X_SERDES_POC, 1466 MV88E6393X_SERDES_POC_RESET, MV88E6393X_SERDES_POC_RESET }, 1467 }; 1468 int err, i; 1469 u16 reg; 1470 1471 /* mv88e6393x family errata 5.2: 1472 * For optimal signal integrity the following sequence should be applied 1473 * to SERDES operating in 10G mode. These registers only apply to 10G 1474 * operation and have no effect on other speeds. 1475 */ 1476 if (cmode != MV88E6393X_PORT_STS_CMODE_10GBASER) 1477 return 0; 1478 1479 for (i = 0; i < ARRAY_SIZE(fixes); ++i) { 1480 err = mv88e6390_serdes_read(chip, lane, fixes[i].dev, 1481 fixes[i].reg, ®); 1482 if (err) 1483 return err; 1484 1485 reg &= ~fixes[i].mask; 1486 reg |= fixes[i].val; 1487 1488 err = mv88e6390_serdes_write(chip, lane, fixes[i].dev, 1489 fixes[i].reg, reg); 1490 if (err) 1491 return err; 1492 } 1493 1494 return 0; 1495 } 1496 1497 static int mv88e6393x_serdes_fix_2500basex_an(struct mv88e6xxx_chip *chip, 1498 int lane, u8 cmode, bool on) 1499 { 1500 u16 reg; 1501 int err; 1502 1503 if (cmode != MV88E6XXX_PORT_STS_CMODE_2500BASEX) 1504 return 0; 1505 1506 /* Inband AN is broken on Amethyst in 2500base-x mode when set by 1507 * standard mechanism (via cmode). 1508 * We can get around this by configuring the PCS mode to 1000base-x 1509 * and then writing value 0x58 to register 1e.8000. (This must be done 1510 * while SerDes receiver and transmitter are disabled, which is, when 1511 * this function is called.) 1512 * It seem that when we do this configuration to 2500base-x mode (by 1513 * changing PCS mode to 1000base-x and frequency to 3.125 GHz from 1514 * 1.25 GHz) and then configure to sgmii or 1000base-x, the device 1515 * thinks that it already has SerDes at 1.25 GHz and does not change 1516 * the 1e.8000 register, leaving SerDes at 3.125 GHz. 1517 * To avoid this, change PCS mode back to 2500base-x when disabling 1518 * SerDes from 2500base-x mode. 1519 */ 1520 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, 1521 MV88E6393X_SERDES_POC, ®); 1522 if (err) 1523 return err; 1524 1525 reg &= ~(MV88E6393X_SERDES_POC_PCS_MASK | MV88E6393X_SERDES_POC_AN); 1526 if (on) 1527 reg |= MV88E6393X_SERDES_POC_PCS_1000BASEX | 1528 MV88E6393X_SERDES_POC_AN; 1529 else 1530 reg |= MV88E6393X_SERDES_POC_PCS_2500BASEX; 1531 reg |= MV88E6393X_SERDES_POC_RESET; 1532 1533 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, 1534 MV88E6393X_SERDES_POC, reg); 1535 if (err) 1536 return err; 1537 1538 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_VEND1, 0x8000, 0x58); 1539 if (err) 1540 return err; 1541 1542 return 0; 1543 } 1544 1545 int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane, 1546 bool on) 1547 { 1548 u8 cmode = chip->ports[port].cmode; 1549 int err; 1550 1551 if (port != 0 && port != 9 && port != 10) 1552 return -EOPNOTSUPP; 1553 1554 if (on) { 1555 err = mv88e6393x_serdes_erratum_4_8(chip, lane); 1556 if (err) 1557 return err; 1558 1559 err = mv88e6393x_serdes_erratum_5_2(chip, lane, cmode); 1560 if (err) 1561 return err; 1562 1563 err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode, 1564 true); 1565 if (err) 1566 return err; 1567 1568 err = mv88e6393x_serdes_power_lane(chip, lane, true); 1569 if (err) 1570 return err; 1571 } 1572 1573 switch (cmode) { 1574 case MV88E6XXX_PORT_STS_CMODE_SGMII: 1575 case MV88E6XXX_PORT_STS_CMODE_1000BASEX: 1576 case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 1577 err = mv88e6390_serdes_power_sgmii(chip, lane, on); 1578 break; 1579 case MV88E6393X_PORT_STS_CMODE_5GBASER: 1580 case MV88E6393X_PORT_STS_CMODE_10GBASER: 1581 err = mv88e6390_serdes_power_10g(chip, lane, on); 1582 break; 1583 default: 1584 err = -EINVAL; 1585 break; 1586 } 1587 1588 if (err) 1589 return err; 1590 1591 if (!on) { 1592 err = mv88e6393x_serdes_power_lane(chip, lane, false); 1593 if (err) 1594 return err; 1595 1596 err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode, 1597 false); 1598 } 1599 1600 return err; 1601 } 1602