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