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