1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Marvell 88E6352 family SERDES PCS support 4 * 5 * Copyright (c) 2008 Marvell Semiconductor 6 * 7 * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch> 8 */ 9 #include <linux/interrupt.h> 10 #include <linux/irqdomain.h> 11 #include <linux/mii.h> 12 13 #include "chip.h" 14 #include "global2.h" 15 #include "phy.h" 16 #include "port.h" 17 #include "serdes.h" 18 19 struct mv88e639x_pcs { 20 struct mdio_device mdio; 21 struct phylink_pcs sgmii_pcs; 22 struct phylink_pcs xg_pcs; 23 bool erratum_3_14; 24 bool supports_5g; 25 phy_interface_t interface; 26 unsigned int irq; 27 char name[64]; 28 irqreturn_t (*handle_irq)(struct mv88e639x_pcs *mpcs); 29 }; 30 31 static int mv88e639x_read(struct mv88e639x_pcs *mpcs, u16 regnum, u16 *val) 32 { 33 int err; 34 35 err = mdiodev_c45_read(&mpcs->mdio, MDIO_MMD_PHYXS, regnum); 36 if (err < 0) 37 return err; 38 39 *val = err; 40 41 return 0; 42 } 43 44 static int mv88e639x_write(struct mv88e639x_pcs *mpcs, u16 regnum, u16 val) 45 { 46 return mdiodev_c45_write(&mpcs->mdio, MDIO_MMD_PHYXS, regnum, val); 47 } 48 49 static int mv88e639x_modify(struct mv88e639x_pcs *mpcs, u16 regnum, u16 mask, 50 u16 val) 51 { 52 return mdiodev_c45_modify(&mpcs->mdio, MDIO_MMD_PHYXS, regnum, mask, 53 val); 54 } 55 56 static int mv88e639x_modify_changed(struct mv88e639x_pcs *mpcs, u16 regnum, 57 u16 mask, u16 set) 58 { 59 return mdiodev_c45_modify_changed(&mpcs->mdio, MDIO_MMD_PHYXS, regnum, 60 mask, set); 61 } 62 63 static struct mv88e639x_pcs * 64 mv88e639x_pcs_alloc(struct device *dev, struct mii_bus *bus, unsigned int addr, 65 int port) 66 { 67 struct mv88e639x_pcs *mpcs; 68 69 mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); 70 if (!mpcs) 71 return NULL; 72 73 mpcs->mdio.dev.parent = dev; 74 mpcs->mdio.bus = bus; 75 mpcs->mdio.addr = addr; 76 77 snprintf(mpcs->name, sizeof(mpcs->name), 78 "mv88e6xxx-%s-serdes-%d", dev_name(dev), port); 79 80 return mpcs; 81 } 82 83 static irqreturn_t mv88e639x_pcs_handle_irq(int irq, void *dev_id) 84 { 85 struct mv88e639x_pcs *mpcs = dev_id; 86 irqreturn_t (*handler)(struct mv88e639x_pcs *); 87 88 handler = READ_ONCE(mpcs->handle_irq); 89 if (!handler) 90 return IRQ_NONE; 91 92 return handler(mpcs); 93 } 94 95 static int mv88e639x_pcs_setup_irq(struct mv88e639x_pcs *mpcs, 96 struct mv88e6xxx_chip *chip, int port) 97 { 98 unsigned int irq; 99 100 irq = mv88e6xxx_serdes_irq_mapping(chip, port); 101 if (!irq) { 102 /* Use polling mode */ 103 mpcs->sgmii_pcs.poll = true; 104 mpcs->xg_pcs.poll = true; 105 return 0; 106 } 107 108 mpcs->irq = irq; 109 110 return request_threaded_irq(irq, NULL, mv88e639x_pcs_handle_irq, 111 IRQF_ONESHOT, mpcs->name, mpcs); 112 } 113 114 static void mv88e639x_pcs_teardown(struct mv88e6xxx_chip *chip, int port) 115 { 116 struct mv88e639x_pcs *mpcs = chip->ports[port].pcs_private; 117 118 if (!mpcs) 119 return; 120 121 if (mpcs->irq) 122 free_irq(mpcs->irq, mpcs); 123 124 kfree(mpcs); 125 126 chip->ports[port].pcs_private = NULL; 127 } 128 129 static struct mv88e639x_pcs *sgmii_pcs_to_mv88e639x_pcs(struct phylink_pcs *pcs) 130 { 131 return container_of(pcs, struct mv88e639x_pcs, sgmii_pcs); 132 } 133 134 static irqreturn_t mv88e639x_sgmii_handle_irq(struct mv88e639x_pcs *mpcs) 135 { 136 u16 int_status; 137 int err; 138 139 err = mv88e639x_read(mpcs, MV88E6390_SGMII_INT_STATUS, &int_status); 140 if (err) 141 return IRQ_NONE; 142 143 if (int_status & (MV88E6390_SGMII_INT_LINK_DOWN | 144 MV88E6390_SGMII_INT_LINK_UP)) { 145 phylink_pcs_change(&mpcs->sgmii_pcs, 146 int_status & MV88E6390_SGMII_INT_LINK_UP); 147 148 return IRQ_HANDLED; 149 } 150 151 return IRQ_NONE; 152 } 153 154 static int mv88e639x_sgmii_pcs_control_irq(struct mv88e639x_pcs *mpcs, 155 bool enable) 156 { 157 u16 val = 0; 158 159 if (enable) 160 val |= MV88E6390_SGMII_INT_LINK_DOWN | 161 MV88E6390_SGMII_INT_LINK_UP; 162 163 return mv88e639x_modify(mpcs, MV88E6390_SGMII_INT_ENABLE, 164 MV88E6390_SGMII_INT_LINK_DOWN | 165 MV88E6390_SGMII_INT_LINK_UP, val); 166 } 167 168 static int mv88e639x_sgmii_pcs_control_pwr(struct mv88e639x_pcs *mpcs, 169 bool enable) 170 { 171 u16 mask, val; 172 173 if (enable) { 174 mask = BMCR_RESET | BMCR_LOOPBACK | BMCR_PDOWN; 175 val = 0; 176 } else { 177 mask = val = BMCR_PDOWN; 178 } 179 180 return mv88e639x_modify(mpcs, MV88E6390_SGMII_BMCR, mask, val); 181 } 182 183 static int mv88e639x_sgmii_pcs_enable(struct phylink_pcs *pcs) 184 { 185 struct mv88e639x_pcs *mpcs = sgmii_pcs_to_mv88e639x_pcs(pcs); 186 187 /* power enable done in post_config */ 188 mpcs->handle_irq = mv88e639x_sgmii_handle_irq; 189 190 return mv88e639x_sgmii_pcs_control_irq(mpcs, !!mpcs->irq); 191 } 192 193 static void mv88e639x_sgmii_pcs_disable(struct phylink_pcs *pcs) 194 { 195 struct mv88e639x_pcs *mpcs = sgmii_pcs_to_mv88e639x_pcs(pcs); 196 197 mv88e639x_sgmii_pcs_control_irq(mpcs, false); 198 mv88e639x_sgmii_pcs_control_pwr(mpcs, false); 199 } 200 201 static void mv88e639x_sgmii_pcs_pre_config(struct phylink_pcs *pcs, 202 phy_interface_t interface) 203 { 204 struct mv88e639x_pcs *mpcs = sgmii_pcs_to_mv88e639x_pcs(pcs); 205 206 mv88e639x_sgmii_pcs_control_pwr(mpcs, false); 207 } 208 209 static int mv88e6390_erratum_3_14(struct mv88e639x_pcs *mpcs) 210 { 211 const int lanes[] = { MV88E6390_PORT9_LANE0, MV88E6390_PORT9_LANE1, 212 MV88E6390_PORT9_LANE2, MV88E6390_PORT9_LANE3, 213 MV88E6390_PORT10_LANE0, MV88E6390_PORT10_LANE1, 214 MV88E6390_PORT10_LANE2, MV88E6390_PORT10_LANE3 }; 215 int err, i; 216 217 /* 88e6190x and 88e6390x errata 3.14: 218 * After chip reset, SERDES reconfiguration or SERDES core 219 * Software Reset, the SERDES lanes may not be properly aligned 220 * resulting in CRC errors 221 */ 222 223 for (i = 0; i < ARRAY_SIZE(lanes); i++) { 224 err = mdiobus_c45_write(mpcs->mdio.bus, lanes[i], 225 MDIO_MMD_PHYXS, 226 0xf054, 0x400C); 227 if (err) 228 return err; 229 230 err = mdiobus_c45_write(mpcs->mdio.bus, lanes[i], 231 MDIO_MMD_PHYXS, 232 0xf054, 0x4000); 233 if (err) 234 return err; 235 } 236 237 return 0; 238 } 239 240 static int mv88e639x_sgmii_pcs_post_config(struct phylink_pcs *pcs, 241 phy_interface_t interface) 242 { 243 struct mv88e639x_pcs *mpcs = sgmii_pcs_to_mv88e639x_pcs(pcs); 244 int err; 245 246 mv88e639x_sgmii_pcs_control_pwr(mpcs, true); 247 248 if (mpcs->erratum_3_14) { 249 err = mv88e6390_erratum_3_14(mpcs); 250 if (err) 251 dev_err(mpcs->mdio.dev.parent, 252 "failed to apply erratum 3.14: %pe\n", 253 ERR_PTR(err)); 254 } 255 256 return 0; 257 } 258 259 static void mv88e639x_sgmii_pcs_get_state(struct phylink_pcs *pcs, 260 struct phylink_link_state *state) 261 { 262 struct mv88e639x_pcs *mpcs = sgmii_pcs_to_mv88e639x_pcs(pcs); 263 u16 bmsr, lpa, status; 264 int err; 265 266 err = mv88e639x_read(mpcs, MV88E6390_SGMII_BMSR, &bmsr); 267 if (err) { 268 dev_err(mpcs->mdio.dev.parent, 269 "can't read Serdes PHY %s: %pe\n", 270 "BMSR", ERR_PTR(err)); 271 state->link = false; 272 return; 273 } 274 275 err = mv88e639x_read(mpcs, MV88E6390_SGMII_LPA, &lpa); 276 if (err) { 277 dev_err(mpcs->mdio.dev.parent, 278 "can't read Serdes PHY %s: %pe\n", 279 "LPA", ERR_PTR(err)); 280 state->link = false; 281 return; 282 } 283 284 err = mv88e639x_read(mpcs, MV88E6390_SGMII_PHY_STATUS, &status); 285 if (err) { 286 dev_err(mpcs->mdio.dev.parent, 287 "can't read Serdes PHY %s: %pe\n", 288 "status", ERR_PTR(err)); 289 state->link = false; 290 return; 291 } 292 293 mv88e6xxx_pcs_decode_state(mpcs->mdio.dev.parent, bmsr, lpa, status, 294 state); 295 } 296 297 static int mv88e639x_sgmii_pcs_config(struct phylink_pcs *pcs, 298 unsigned int neg_mode, 299 phy_interface_t interface, 300 const unsigned long *advertising, 301 bool permit_pause_to_mac) 302 { 303 struct mv88e639x_pcs *mpcs = sgmii_pcs_to_mv88e639x_pcs(pcs); 304 u16 val, bmcr; 305 bool changed; 306 int adv, err; 307 308 adv = phylink_mii_c22_pcs_encode_advertisement(interface, advertising); 309 if (adv < 0) 310 return 0; 311 312 mpcs->interface = interface; 313 314 err = mv88e639x_modify_changed(mpcs, MV88E6390_SGMII_ADVERTISE, 315 0xffff, adv); 316 if (err < 0) 317 return err; 318 319 changed = err > 0; 320 321 err = mv88e639x_read(mpcs, MV88E6390_SGMII_BMCR, &val); 322 if (err) 323 return err; 324 325 if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) 326 bmcr = val | BMCR_ANENABLE; 327 else 328 bmcr = val & ~BMCR_ANENABLE; 329 330 /* setting ANENABLE triggers a restart of negotiation */ 331 if (bmcr == val) 332 return changed; 333 334 return mv88e639x_write(mpcs, MV88E6390_SGMII_BMCR, bmcr); 335 } 336 337 static void mv88e639x_sgmii_pcs_an_restart(struct phylink_pcs *pcs) 338 { 339 struct mv88e639x_pcs *mpcs = sgmii_pcs_to_mv88e639x_pcs(pcs); 340 341 mv88e639x_modify(mpcs, MV88E6390_SGMII_BMCR, 342 BMCR_ANRESTART, BMCR_ANRESTART); 343 } 344 345 static void mv88e639x_sgmii_pcs_link_up(struct phylink_pcs *pcs, 346 unsigned int mode, 347 phy_interface_t interface, 348 int speed, int duplex) 349 { 350 struct mv88e639x_pcs *mpcs = sgmii_pcs_to_mv88e639x_pcs(pcs); 351 u16 bmcr; 352 int err; 353 354 if (phylink_autoneg_inband(mode)) 355 return; 356 357 bmcr = mii_bmcr_encode_fixed(speed, duplex); 358 359 err = mv88e639x_modify(mpcs, MV88E6390_SGMII_BMCR, 360 BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX, 361 bmcr); 362 if (err) 363 dev_err(mpcs->mdio.dev.parent, 364 "can't access Serdes PHY %s: %pe\n", 365 "BMCR", ERR_PTR(err)); 366 } 367 368 static const struct phylink_pcs_ops mv88e639x_sgmii_pcs_ops = { 369 .pcs_enable = mv88e639x_sgmii_pcs_enable, 370 .pcs_disable = mv88e639x_sgmii_pcs_disable, 371 .pcs_pre_config = mv88e639x_sgmii_pcs_pre_config, 372 .pcs_post_config = mv88e639x_sgmii_pcs_post_config, 373 .pcs_get_state = mv88e639x_sgmii_pcs_get_state, 374 .pcs_an_restart = mv88e639x_sgmii_pcs_an_restart, 375 .pcs_config = mv88e639x_sgmii_pcs_config, 376 .pcs_link_up = mv88e639x_sgmii_pcs_link_up, 377 }; 378 379 static struct mv88e639x_pcs *xg_pcs_to_mv88e639x_pcs(struct phylink_pcs *pcs) 380 { 381 return container_of(pcs, struct mv88e639x_pcs, xg_pcs); 382 } 383 384 static int mv88e639x_xg_pcs_enable(struct mv88e639x_pcs *mpcs) 385 { 386 return mv88e639x_modify(mpcs, MV88E6390_10G_CTRL1, 387 MDIO_CTRL1_RESET | MDIO_PCS_CTRL1_LOOPBACK | 388 MDIO_CTRL1_LPOWER, 0); 389 } 390 391 static void mv88e639x_xg_pcs_disable(struct mv88e639x_pcs *mpcs) 392 { 393 mv88e639x_modify(mpcs, MV88E6390_10G_CTRL1, MDIO_CTRL1_LPOWER, 394 MDIO_CTRL1_LPOWER); 395 } 396 397 static void mv88e639x_xg_pcs_get_state(struct phylink_pcs *pcs, 398 struct phylink_link_state *state) 399 { 400 struct mv88e639x_pcs *mpcs = xg_pcs_to_mv88e639x_pcs(pcs); 401 u16 status; 402 int err; 403 404 state->link = false; 405 406 err = mv88e639x_read(mpcs, MV88E6390_10G_STAT1, &status); 407 if (err) { 408 dev_err(mpcs->mdio.dev.parent, 409 "can't read Serdes PHY %s: %pe\n", 410 "STAT1", ERR_PTR(err)); 411 return; 412 } 413 414 state->link = !!(status & MDIO_STAT1_LSTATUS); 415 if (state->link) { 416 switch (state->interface) { 417 case PHY_INTERFACE_MODE_5GBASER: 418 state->speed = SPEED_5000; 419 break; 420 421 case PHY_INTERFACE_MODE_10GBASER: 422 case PHY_INTERFACE_MODE_RXAUI: 423 case PHY_INTERFACE_MODE_XAUI: 424 state->speed = SPEED_10000; 425 break; 426 427 default: 428 state->link = false; 429 return; 430 } 431 432 state->duplex = DUPLEX_FULL; 433 } 434 } 435 436 static int mv88e639x_xg_pcs_config(struct phylink_pcs *pcs, 437 unsigned int neg_mode, 438 phy_interface_t interface, 439 const unsigned long *advertising, 440 bool permit_pause_to_mac) 441 { 442 return 0; 443 } 444 445 static struct phylink_pcs * 446 mv88e639x_pcs_select(struct mv88e6xxx_chip *chip, int port, 447 phy_interface_t mode) 448 { 449 struct mv88e639x_pcs *mpcs; 450 451 mpcs = chip->ports[port].pcs_private; 452 if (!mpcs) 453 return NULL; 454 455 switch (mode) { 456 case PHY_INTERFACE_MODE_SGMII: 457 case PHY_INTERFACE_MODE_1000BASEX: 458 case PHY_INTERFACE_MODE_2500BASEX: 459 return &mpcs->sgmii_pcs; 460 461 case PHY_INTERFACE_MODE_5GBASER: 462 if (!mpcs->supports_5g) 463 return NULL; 464 fallthrough; 465 case PHY_INTERFACE_MODE_10GBASER: 466 case PHY_INTERFACE_MODE_XAUI: 467 case PHY_INTERFACE_MODE_RXAUI: 468 return &mpcs->xg_pcs; 469 470 default: 471 return NULL; 472 } 473 } 474 475 /* Marvell 88E6390 Specific support */ 476 477 static irqreturn_t mv88e6390_xg_handle_irq(struct mv88e639x_pcs *mpcs) 478 { 479 u16 int_status; 480 int err; 481 482 err = mv88e639x_read(mpcs, MV88E6390_10G_INT_STATUS, &int_status); 483 if (err) 484 return IRQ_NONE; 485 486 if (int_status & (MV88E6390_10G_INT_LINK_DOWN | 487 MV88E6390_10G_INT_LINK_UP)) { 488 phylink_pcs_change(&mpcs->xg_pcs, 489 int_status & MV88E6390_10G_INT_LINK_UP); 490 491 return IRQ_HANDLED; 492 } 493 494 return IRQ_NONE; 495 } 496 497 static int mv88e6390_xg_control_irq(struct mv88e639x_pcs *mpcs, bool enable) 498 { 499 u16 val = 0; 500 501 if (enable) 502 val = MV88E6390_10G_INT_LINK_DOWN | MV88E6390_10G_INT_LINK_UP; 503 504 return mv88e639x_modify(mpcs, MV88E6390_10G_INT_ENABLE, 505 MV88E6390_10G_INT_LINK_DOWN | 506 MV88E6390_10G_INT_LINK_UP, val); 507 } 508 509 static int mv88e6390_xg_pcs_enable(struct phylink_pcs *pcs) 510 { 511 struct mv88e639x_pcs *mpcs = xg_pcs_to_mv88e639x_pcs(pcs); 512 int err; 513 514 err = mv88e639x_xg_pcs_enable(mpcs); 515 if (err) 516 return err; 517 518 mpcs->handle_irq = mv88e6390_xg_handle_irq; 519 520 return mv88e6390_xg_control_irq(mpcs, !!mpcs->irq); 521 } 522 523 static void mv88e6390_xg_pcs_disable(struct phylink_pcs *pcs) 524 { 525 struct mv88e639x_pcs *mpcs = xg_pcs_to_mv88e639x_pcs(pcs); 526 527 mv88e6390_xg_control_irq(mpcs, false); 528 mv88e639x_xg_pcs_disable(mpcs); 529 } 530 531 static const struct phylink_pcs_ops mv88e6390_xg_pcs_ops = { 532 .pcs_enable = mv88e6390_xg_pcs_enable, 533 .pcs_disable = mv88e6390_xg_pcs_disable, 534 .pcs_get_state = mv88e639x_xg_pcs_get_state, 535 .pcs_config = mv88e639x_xg_pcs_config, 536 }; 537 538 static int mv88e6390_pcs_enable_checker(struct mv88e639x_pcs *mpcs) 539 { 540 return mv88e639x_modify(mpcs, MV88E6390_PG_CONTROL, 541 MV88E6390_PG_CONTROL_ENABLE_PC, 542 MV88E6390_PG_CONTROL_ENABLE_PC); 543 } 544 545 static int mv88e6390_pcs_init(struct mv88e6xxx_chip *chip, int port) 546 { 547 struct mv88e639x_pcs *mpcs; 548 struct mii_bus *bus; 549 struct device *dev; 550 int lane, err; 551 552 lane = mv88e6xxx_serdes_get_lane(chip, port); 553 if (lane < 0) 554 return 0; 555 556 bus = mv88e6xxx_default_mdio_bus(chip); 557 dev = chip->dev; 558 559 mpcs = mv88e639x_pcs_alloc(dev, bus, lane, port); 560 if (!mpcs) 561 return -ENOMEM; 562 563 mpcs->sgmii_pcs.ops = &mv88e639x_sgmii_pcs_ops; 564 mpcs->sgmii_pcs.neg_mode = true; 565 mpcs->xg_pcs.ops = &mv88e6390_xg_pcs_ops; 566 mpcs->xg_pcs.neg_mode = true; 567 568 if (chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6190X || 569 chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6390X) 570 mpcs->erratum_3_14 = true; 571 572 err = mv88e639x_pcs_setup_irq(mpcs, chip, port); 573 if (err) 574 goto err_free; 575 576 /* 6390 and 6390x has the checker, 6393x doesn't appear to? */ 577 /* This is to enable gathering the statistics. Maybe this 578 * should call out to a helper? Or we could do this at init time. 579 */ 580 err = mv88e6390_pcs_enable_checker(mpcs); 581 if (err) 582 goto err_free; 583 584 chip->ports[port].pcs_private = mpcs; 585 586 return 0; 587 588 err_free: 589 kfree(mpcs); 590 return err; 591 } 592 593 const struct mv88e6xxx_pcs_ops mv88e6390_pcs_ops = { 594 .pcs_init = mv88e6390_pcs_init, 595 .pcs_teardown = mv88e639x_pcs_teardown, 596 .pcs_select = mv88e639x_pcs_select, 597 }; 598 599 /* Marvell 88E6393X Specific support */ 600 601 static int mv88e6393x_power_lane(struct mv88e639x_pcs *mpcs, bool enable) 602 { 603 u16 val = MV88E6393X_SERDES_CTRL1_TX_PDOWN | 604 MV88E6393X_SERDES_CTRL1_RX_PDOWN; 605 606 return mv88e639x_modify(mpcs, MV88E6393X_SERDES_CTRL1, val, 607 enable ? 0 : val); 608 } 609 610 /* mv88e6393x family errata 4.6: 611 * Cannot clear PwrDn bit on SERDES if device is configured CPU_MGD mode or 612 * P0_mode is configured for [x]MII. 613 * Workaround: Set SERDES register 4.F002 bit 5=0 and bit 15=1. 614 * 615 * It seems that after this workaround the SERDES is automatically powered up 616 * (the bit is cleared), so power it down. 617 */ 618 static int mv88e6393x_erratum_4_6(struct mv88e639x_pcs *mpcs) 619 { 620 int err; 621 622 err = mv88e639x_modify(mpcs, MV88E6393X_SERDES_POC, 623 MV88E6393X_SERDES_POC_PDOWN | 624 MV88E6393X_SERDES_POC_RESET, 625 MV88E6393X_SERDES_POC_RESET); 626 if (err) 627 return err; 628 629 err = mv88e639x_modify(mpcs, MV88E6390_SGMII_BMCR, 630 BMCR_PDOWN, BMCR_PDOWN); 631 if (err) 632 return err; 633 634 err = mv88e639x_sgmii_pcs_control_pwr(mpcs, false); 635 if (err) 636 return err; 637 638 return mv88e6393x_power_lane(mpcs, false); 639 } 640 641 /* mv88e6393x family errata 4.8: 642 * When a SERDES port is operating in 1000BASE-X or SGMII mode link may not 643 * come up after hardware reset or software reset of SERDES core. Workaround 644 * is to write SERDES register 4.F074.14=1 for only those modes and 0 in all 645 * other modes. 646 */ 647 static int mv88e6393x_erratum_4_8(struct mv88e639x_pcs *mpcs) 648 { 649 u16 reg, poc; 650 int err; 651 652 err = mv88e639x_read(mpcs, MV88E6393X_SERDES_POC, &poc); 653 if (err) 654 return err; 655 656 poc &= MV88E6393X_SERDES_POC_PCS_MASK; 657 if (poc == MV88E6393X_SERDES_POC_PCS_1000BASEX || 658 poc == MV88E6393X_SERDES_POC_PCS_SGMII_PHY || 659 poc == MV88E6393X_SERDES_POC_PCS_SGMII_MAC) 660 reg = MV88E6393X_ERRATA_4_8_BIT; 661 else 662 reg = 0; 663 664 return mv88e639x_modify(mpcs, MV88E6393X_ERRATA_4_8_REG, 665 MV88E6393X_ERRATA_4_8_BIT, reg); 666 } 667 668 /* mv88e6393x family errata 5.2: 669 * For optimal signal integrity the following sequence should be applied to 670 * SERDES operating in 10G mode. These registers only apply to 10G operation 671 * and have no effect on other speeds. 672 */ 673 static int mv88e6393x_erratum_5_2(struct mv88e639x_pcs *mpcs) 674 { 675 static const struct { 676 u16 dev, reg, val, mask; 677 } fixes[] = { 678 { MDIO_MMD_VEND1, 0x8093, 0xcb5a, 0xffff }, 679 { MDIO_MMD_VEND1, 0x8171, 0x7088, 0xffff }, 680 { MDIO_MMD_VEND1, 0x80c9, 0x311a, 0xffff }, 681 { MDIO_MMD_VEND1, 0x80a2, 0x8000, 0xff7f }, 682 { MDIO_MMD_VEND1, 0x80a9, 0x0000, 0xfff0 }, 683 { MDIO_MMD_VEND1, 0x80a3, 0x0000, 0xf8ff }, 684 { MDIO_MMD_PHYXS, MV88E6393X_SERDES_POC, 685 MV88E6393X_SERDES_POC_RESET, MV88E6393X_SERDES_POC_RESET }, 686 }; 687 int err, i; 688 689 for (i = 0; i < ARRAY_SIZE(fixes); ++i) { 690 err = mdiodev_c45_modify(&mpcs->mdio, fixes[i].dev, 691 fixes[i].reg, fixes[i].mask, 692 fixes[i].val); 693 if (err) 694 return err; 695 } 696 697 return 0; 698 } 699 700 /* Inband AN is broken on Amethyst in 2500base-x mode when set by standard 701 * mechanism (via cmode). 702 * We can get around this by configuring the PCS mode to 1000base-x and then 703 * writing value 0x58 to register 1e.8000. (This must be done while SerDes 704 * receiver and transmitter are disabled, which is, when this function is 705 * called.) 706 * It seem that when we do this configuration to 2500base-x mode (by changing 707 * PCS mode to 1000base-x and frequency to 3.125 GHz from 1.25 GHz) and then 708 * configure to sgmii or 1000base-x, the device thinks that it already has 709 * SerDes at 1.25 GHz and does not change the 1e.8000 register, leaving SerDes 710 * at 3.125 GHz. 711 * To avoid this, change PCS mode back to 2500base-x when disabling SerDes from 712 * 2500base-x mode. 713 */ 714 static int mv88e6393x_fix_2500basex_an(struct mv88e639x_pcs *mpcs, bool on) 715 { 716 u16 reg; 717 int err; 718 719 if (on) 720 reg = MV88E6393X_SERDES_POC_PCS_1000BASEX | 721 MV88E6393X_SERDES_POC_AN; 722 else 723 reg = MV88E6393X_SERDES_POC_PCS_2500BASEX; 724 725 reg |= MV88E6393X_SERDES_POC_RESET; 726 727 err = mv88e639x_modify(mpcs, MV88E6393X_SERDES_POC, 728 MV88E6393X_SERDES_POC_PCS_MASK | 729 MV88E6393X_SERDES_POC_AN | 730 MV88E6393X_SERDES_POC_RESET, reg); 731 if (err) 732 return err; 733 734 return mdiodev_c45_write(&mpcs->mdio, MDIO_MMD_VEND1, 0x8000, 0x58); 735 } 736 737 static int mv88e6393x_sgmii_apply_2500basex_an(struct mv88e639x_pcs *mpcs, 738 phy_interface_t interface, 739 bool enable) 740 { 741 int err; 742 743 if (interface != PHY_INTERFACE_MODE_2500BASEX) 744 return 0; 745 746 err = mv88e6393x_fix_2500basex_an(mpcs, enable); 747 if (err) 748 dev_err(mpcs->mdio.dev.parent, 749 "failed to %s 2500basex fix: %pe\n", 750 enable ? "enable" : "disable", ERR_PTR(err)); 751 752 return err; 753 } 754 755 static void mv88e6393x_sgmii_pcs_disable(struct phylink_pcs *pcs) 756 { 757 struct mv88e639x_pcs *mpcs = sgmii_pcs_to_mv88e639x_pcs(pcs); 758 759 mv88e639x_sgmii_pcs_disable(pcs); 760 mv88e6393x_power_lane(mpcs, false); 761 mv88e6393x_sgmii_apply_2500basex_an(mpcs, mpcs->interface, false); 762 } 763 764 static void mv88e6393x_sgmii_pcs_pre_config(struct phylink_pcs *pcs, 765 phy_interface_t interface) 766 { 767 struct mv88e639x_pcs *mpcs = sgmii_pcs_to_mv88e639x_pcs(pcs); 768 769 mv88e639x_sgmii_pcs_pre_config(pcs, interface); 770 mv88e6393x_power_lane(mpcs, false); 771 mv88e6393x_sgmii_apply_2500basex_an(mpcs, mpcs->interface, false); 772 } 773 774 static int mv88e6393x_sgmii_pcs_post_config(struct phylink_pcs *pcs, 775 phy_interface_t interface) 776 { 777 struct mv88e639x_pcs *mpcs = sgmii_pcs_to_mv88e639x_pcs(pcs); 778 int err; 779 780 err = mv88e6393x_erratum_4_8(mpcs); 781 if (err) 782 return err; 783 784 err = mv88e6393x_sgmii_apply_2500basex_an(mpcs, interface, true); 785 if (err) 786 return err; 787 788 err = mv88e6393x_power_lane(mpcs, true); 789 if (err) 790 return err; 791 792 return mv88e639x_sgmii_pcs_post_config(pcs, interface); 793 } 794 795 static const struct phylink_pcs_ops mv88e6393x_sgmii_pcs_ops = { 796 .pcs_enable = mv88e639x_sgmii_pcs_enable, 797 .pcs_disable = mv88e6393x_sgmii_pcs_disable, 798 .pcs_pre_config = mv88e6393x_sgmii_pcs_pre_config, 799 .pcs_post_config = mv88e6393x_sgmii_pcs_post_config, 800 .pcs_get_state = mv88e639x_sgmii_pcs_get_state, 801 .pcs_an_restart = mv88e639x_sgmii_pcs_an_restart, 802 .pcs_config = mv88e639x_sgmii_pcs_config, 803 .pcs_link_up = mv88e639x_sgmii_pcs_link_up, 804 }; 805 806 static irqreturn_t mv88e6393x_xg_handle_irq(struct mv88e639x_pcs *mpcs) 807 { 808 u16 int_status, stat1; 809 bool link_down; 810 int err; 811 812 err = mv88e639x_read(mpcs, MV88E6393X_10G_INT_STATUS, &int_status); 813 if (err) 814 return IRQ_NONE; 815 816 if (int_status & MV88E6393X_10G_INT_LINK_CHANGE) { 817 err = mv88e639x_read(mpcs, MV88E6390_10G_STAT1, &stat1); 818 if (err) 819 return IRQ_NONE; 820 821 link_down = !(stat1 & MDIO_STAT1_LSTATUS); 822 823 phylink_pcs_change(&mpcs->xg_pcs, !link_down); 824 825 return IRQ_HANDLED; 826 } 827 828 return IRQ_NONE; 829 } 830 831 static int mv88e6393x_xg_control_irq(struct mv88e639x_pcs *mpcs, bool enable) 832 { 833 u16 val = 0; 834 835 if (enable) 836 val = MV88E6393X_10G_INT_LINK_CHANGE; 837 838 return mv88e639x_modify(mpcs, MV88E6393X_10G_INT_ENABLE, 839 MV88E6393X_10G_INT_LINK_CHANGE, val); 840 } 841 842 static int mv88e6393x_xg_pcs_enable(struct phylink_pcs *pcs) 843 { 844 struct mv88e639x_pcs *mpcs = xg_pcs_to_mv88e639x_pcs(pcs); 845 846 mpcs->handle_irq = mv88e6393x_xg_handle_irq; 847 848 return mv88e6393x_xg_control_irq(mpcs, !!mpcs->irq); 849 } 850 851 static void mv88e6393x_xg_pcs_disable(struct phylink_pcs *pcs) 852 { 853 struct mv88e639x_pcs *mpcs = xg_pcs_to_mv88e639x_pcs(pcs); 854 855 mv88e6393x_xg_control_irq(mpcs, false); 856 mv88e639x_xg_pcs_disable(mpcs); 857 mv88e6393x_power_lane(mpcs, false); 858 } 859 860 /* The PCS has to be powered down while CMODE is changed */ 861 static void mv88e6393x_xg_pcs_pre_config(struct phylink_pcs *pcs, 862 phy_interface_t interface) 863 { 864 struct mv88e639x_pcs *mpcs = xg_pcs_to_mv88e639x_pcs(pcs); 865 866 mv88e639x_xg_pcs_disable(mpcs); 867 mv88e6393x_power_lane(mpcs, false); 868 } 869 870 static int mv88e6393x_xg_pcs_post_config(struct phylink_pcs *pcs, 871 phy_interface_t interface) 872 { 873 struct mv88e639x_pcs *mpcs = xg_pcs_to_mv88e639x_pcs(pcs); 874 int err; 875 876 if (interface == PHY_INTERFACE_MODE_10GBASER) { 877 err = mv88e6393x_erratum_5_2(mpcs); 878 if (err) 879 return err; 880 } 881 882 err = mv88e6393x_power_lane(mpcs, true); 883 if (err) 884 return err; 885 886 return mv88e639x_xg_pcs_enable(mpcs); 887 } 888 889 static const struct phylink_pcs_ops mv88e6393x_xg_pcs_ops = { 890 .pcs_enable = mv88e6393x_xg_pcs_enable, 891 .pcs_disable = mv88e6393x_xg_pcs_disable, 892 .pcs_pre_config = mv88e6393x_xg_pcs_pre_config, 893 .pcs_post_config = mv88e6393x_xg_pcs_post_config, 894 .pcs_get_state = mv88e639x_xg_pcs_get_state, 895 .pcs_config = mv88e639x_xg_pcs_config, 896 }; 897 898 static int mv88e6393x_pcs_init(struct mv88e6xxx_chip *chip, int port) 899 { 900 struct mv88e639x_pcs *mpcs; 901 struct mii_bus *bus; 902 struct device *dev; 903 int lane, err; 904 905 lane = mv88e6xxx_serdes_get_lane(chip, port); 906 if (lane < 0) 907 return 0; 908 909 bus = mv88e6xxx_default_mdio_bus(chip); 910 dev = chip->dev; 911 912 mpcs = mv88e639x_pcs_alloc(dev, bus, lane, port); 913 if (!mpcs) 914 return -ENOMEM; 915 916 mpcs->sgmii_pcs.ops = &mv88e6393x_sgmii_pcs_ops; 917 mpcs->sgmii_pcs.neg_mode = true; 918 mpcs->xg_pcs.ops = &mv88e6393x_xg_pcs_ops; 919 mpcs->xg_pcs.neg_mode = true; 920 mpcs->supports_5g = true; 921 922 err = mv88e6393x_erratum_4_6(mpcs); 923 if (err) 924 goto err_free; 925 926 err = mv88e639x_pcs_setup_irq(mpcs, chip, port); 927 if (err) 928 goto err_free; 929 930 chip->ports[port].pcs_private = mpcs; 931 932 return 0; 933 934 err_free: 935 kfree(mpcs); 936 return err; 937 } 938 939 const struct mv88e6xxx_pcs_ops mv88e6393x_pcs_ops = { 940 .pcs_init = mv88e6393x_pcs_init, 941 .pcs_teardown = mv88e639x_pcs_teardown, 942 .pcs_select = mv88e639x_pcs_select, 943 }; 944