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