1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2020 Synopsys, Inc. and/or its affiliates. 4 * Synopsys DesignWare XPCS helpers 5 * 6 * Author: Jose Abreu <Jose.Abreu@synopsys.com> 7 */ 8 9 #include <linux/delay.h> 10 #include <linux/pcs/pcs-xpcs.h> 11 #include <linux/mdio.h> 12 #include <linux/phylink.h> 13 #include <linux/workqueue.h> 14 #include "pcs-xpcs.h" 15 16 #define phylink_pcs_to_xpcs(pl_pcs) \ 17 container_of((pl_pcs), struct dw_xpcs, pcs) 18 19 static const int xpcs_usxgmii_features[] = { 20 ETHTOOL_LINK_MODE_Pause_BIT, 21 ETHTOOL_LINK_MODE_Asym_Pause_BIT, 22 ETHTOOL_LINK_MODE_Autoneg_BIT, 23 ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, 24 ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, 25 ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, 26 ETHTOOL_LINK_MODE_2500baseX_Full_BIT, 27 __ETHTOOL_LINK_MODE_MASK_NBITS, 28 }; 29 30 static const int xpcs_10gkr_features[] = { 31 ETHTOOL_LINK_MODE_Pause_BIT, 32 ETHTOOL_LINK_MODE_Asym_Pause_BIT, 33 ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, 34 __ETHTOOL_LINK_MODE_MASK_NBITS, 35 }; 36 37 static const int xpcs_xlgmii_features[] = { 38 ETHTOOL_LINK_MODE_Pause_BIT, 39 ETHTOOL_LINK_MODE_Asym_Pause_BIT, 40 ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, 41 ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, 42 ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, 43 ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, 44 ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, 45 ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, 46 ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, 47 ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, 48 ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, 49 ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, 50 ETHTOOL_LINK_MODE_50000baseKR_Full_BIT, 51 ETHTOOL_LINK_MODE_50000baseSR_Full_BIT, 52 ETHTOOL_LINK_MODE_50000baseCR_Full_BIT, 53 ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT, 54 ETHTOOL_LINK_MODE_50000baseDR_Full_BIT, 55 ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, 56 ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, 57 ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, 58 ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, 59 ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT, 60 ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT, 61 ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT, 62 ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT, 63 ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT, 64 __ETHTOOL_LINK_MODE_MASK_NBITS, 65 }; 66 67 static const int xpcs_sgmii_features[] = { 68 ETHTOOL_LINK_MODE_Pause_BIT, 69 ETHTOOL_LINK_MODE_Asym_Pause_BIT, 70 ETHTOOL_LINK_MODE_Autoneg_BIT, 71 ETHTOOL_LINK_MODE_10baseT_Half_BIT, 72 ETHTOOL_LINK_MODE_10baseT_Full_BIT, 73 ETHTOOL_LINK_MODE_100baseT_Half_BIT, 74 ETHTOOL_LINK_MODE_100baseT_Full_BIT, 75 ETHTOOL_LINK_MODE_1000baseT_Half_BIT, 76 ETHTOOL_LINK_MODE_1000baseT_Full_BIT, 77 __ETHTOOL_LINK_MODE_MASK_NBITS, 78 }; 79 80 static const int xpcs_1000basex_features[] = { 81 ETHTOOL_LINK_MODE_Pause_BIT, 82 ETHTOOL_LINK_MODE_Asym_Pause_BIT, 83 ETHTOOL_LINK_MODE_Autoneg_BIT, 84 ETHTOOL_LINK_MODE_1000baseX_Full_BIT, 85 __ETHTOOL_LINK_MODE_MASK_NBITS, 86 }; 87 88 static const int xpcs_2500basex_features[] = { 89 ETHTOOL_LINK_MODE_Pause_BIT, 90 ETHTOOL_LINK_MODE_Asym_Pause_BIT, 91 ETHTOOL_LINK_MODE_Autoneg_BIT, 92 ETHTOOL_LINK_MODE_2500baseX_Full_BIT, 93 ETHTOOL_LINK_MODE_2500baseT_Full_BIT, 94 __ETHTOOL_LINK_MODE_MASK_NBITS, 95 }; 96 97 static const phy_interface_t xpcs_usxgmii_interfaces[] = { 98 PHY_INTERFACE_MODE_USXGMII, 99 }; 100 101 static const phy_interface_t xpcs_10gkr_interfaces[] = { 102 PHY_INTERFACE_MODE_10GKR, 103 }; 104 105 static const phy_interface_t xpcs_xlgmii_interfaces[] = { 106 PHY_INTERFACE_MODE_XLGMII, 107 }; 108 109 static const phy_interface_t xpcs_sgmii_interfaces[] = { 110 PHY_INTERFACE_MODE_SGMII, 111 }; 112 113 static const phy_interface_t xpcs_1000basex_interfaces[] = { 114 PHY_INTERFACE_MODE_1000BASEX, 115 }; 116 117 static const phy_interface_t xpcs_2500basex_interfaces[] = { 118 PHY_INTERFACE_MODE_2500BASEX, 119 PHY_INTERFACE_MODE_MAX, 120 }; 121 122 enum { 123 DW_XPCS_USXGMII, 124 DW_XPCS_10GKR, 125 DW_XPCS_XLGMII, 126 DW_XPCS_SGMII, 127 DW_XPCS_1000BASEX, 128 DW_XPCS_2500BASEX, 129 DW_XPCS_INTERFACE_MAX, 130 }; 131 132 struct xpcs_compat { 133 const int *supported; 134 const phy_interface_t *interface; 135 int num_interfaces; 136 int an_mode; 137 int (*pma_config)(struct dw_xpcs *xpcs); 138 }; 139 140 struct xpcs_id { 141 u32 id; 142 u32 mask; 143 const struct xpcs_compat *compat; 144 }; 145 146 static const struct xpcs_compat *xpcs_find_compat(const struct xpcs_id *id, 147 phy_interface_t interface) 148 { 149 int i, j; 150 151 for (i = 0; i < DW_XPCS_INTERFACE_MAX; i++) { 152 const struct xpcs_compat *compat = &id->compat[i]; 153 154 for (j = 0; j < compat->num_interfaces; j++) 155 if (compat->interface[j] == interface) 156 return compat; 157 } 158 159 return NULL; 160 } 161 162 int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface) 163 { 164 const struct xpcs_compat *compat; 165 166 compat = xpcs_find_compat(xpcs->id, interface); 167 if (!compat) 168 return -ENODEV; 169 170 return compat->an_mode; 171 } 172 EXPORT_SYMBOL_GPL(xpcs_get_an_mode); 173 174 static bool __xpcs_linkmode_supported(const struct xpcs_compat *compat, 175 enum ethtool_link_mode_bit_indices linkmode) 176 { 177 int i; 178 179 for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++) 180 if (compat->supported[i] == linkmode) 181 return true; 182 183 return false; 184 } 185 186 #define xpcs_linkmode_supported(compat, mode) \ 187 __xpcs_linkmode_supported(compat, ETHTOOL_LINK_MODE_ ## mode ## _BIT) 188 189 int xpcs_read(struct dw_xpcs *xpcs, int dev, u32 reg) 190 { 191 struct mii_bus *bus = xpcs->mdiodev->bus; 192 int addr = xpcs->mdiodev->addr; 193 194 return mdiobus_c45_read(bus, addr, dev, reg); 195 } 196 197 int xpcs_write(struct dw_xpcs *xpcs, int dev, u32 reg, u16 val) 198 { 199 struct mii_bus *bus = xpcs->mdiodev->bus; 200 int addr = xpcs->mdiodev->addr; 201 202 return mdiobus_c45_write(bus, addr, dev, reg, val); 203 } 204 205 static int xpcs_modify_changed(struct dw_xpcs *xpcs, int dev, u32 reg, 206 u16 mask, u16 set) 207 { 208 u32 reg_addr = mdiobus_c45_addr(dev, reg); 209 210 return mdiodev_modify_changed(xpcs->mdiodev, reg_addr, mask, set); 211 } 212 213 static int xpcs_read_vendor(struct dw_xpcs *xpcs, int dev, u32 reg) 214 { 215 return xpcs_read(xpcs, dev, DW_VENDOR | reg); 216 } 217 218 static int xpcs_write_vendor(struct dw_xpcs *xpcs, int dev, int reg, 219 u16 val) 220 { 221 return xpcs_write(xpcs, dev, DW_VENDOR | reg, val); 222 } 223 224 static int xpcs_read_vpcs(struct dw_xpcs *xpcs, int reg) 225 { 226 return xpcs_read_vendor(xpcs, MDIO_MMD_PCS, reg); 227 } 228 229 static int xpcs_write_vpcs(struct dw_xpcs *xpcs, int reg, u16 val) 230 { 231 return xpcs_write_vendor(xpcs, MDIO_MMD_PCS, reg, val); 232 } 233 234 static int xpcs_poll_reset(struct dw_xpcs *xpcs, int dev) 235 { 236 /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */ 237 unsigned int retries = 12; 238 int ret; 239 240 do { 241 msleep(50); 242 ret = xpcs_read(xpcs, dev, MDIO_CTRL1); 243 if (ret < 0) 244 return ret; 245 } while (ret & MDIO_CTRL1_RESET && --retries); 246 247 return (ret & MDIO_CTRL1_RESET) ? -ETIMEDOUT : 0; 248 } 249 250 static int xpcs_soft_reset(struct dw_xpcs *xpcs, 251 const struct xpcs_compat *compat) 252 { 253 int ret, dev; 254 255 switch (compat->an_mode) { 256 case DW_AN_C73: 257 dev = MDIO_MMD_PCS; 258 break; 259 case DW_AN_C37_SGMII: 260 case DW_2500BASEX: 261 case DW_AN_C37_1000BASEX: 262 dev = MDIO_MMD_VEND2; 263 break; 264 default: 265 return -1; 266 } 267 268 ret = xpcs_write(xpcs, dev, MDIO_CTRL1, MDIO_CTRL1_RESET); 269 if (ret < 0) 270 return ret; 271 272 return xpcs_poll_reset(xpcs, dev); 273 } 274 275 #define xpcs_warn(__xpcs, __state, __args...) \ 276 ({ \ 277 if ((__state)->link) \ 278 dev_warn(&(__xpcs)->mdiodev->dev, ##__args); \ 279 }) 280 281 static int xpcs_read_fault_c73(struct dw_xpcs *xpcs, 282 struct phylink_link_state *state) 283 { 284 int ret; 285 286 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT1); 287 if (ret < 0) 288 return ret; 289 290 if (ret & MDIO_STAT1_FAULT) { 291 xpcs_warn(xpcs, state, "Link fault condition detected!\n"); 292 return -EFAULT; 293 } 294 295 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT2); 296 if (ret < 0) 297 return ret; 298 299 if (ret & MDIO_STAT2_RXFAULT) 300 xpcs_warn(xpcs, state, "Receiver fault detected!\n"); 301 if (ret & MDIO_STAT2_TXFAULT) 302 xpcs_warn(xpcs, state, "Transmitter fault detected!\n"); 303 304 ret = xpcs_read_vendor(xpcs, MDIO_MMD_PCS, DW_VR_XS_PCS_DIG_STS); 305 if (ret < 0) 306 return ret; 307 308 if (ret & DW_RXFIFO_ERR) { 309 xpcs_warn(xpcs, state, "FIFO fault condition detected!\n"); 310 return -EFAULT; 311 } 312 313 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1); 314 if (ret < 0) 315 return ret; 316 317 if (!(ret & MDIO_PCS_10GBRT_STAT1_BLKLK)) 318 xpcs_warn(xpcs, state, "Link is not locked!\n"); 319 320 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT2); 321 if (ret < 0) 322 return ret; 323 324 if (ret & MDIO_PCS_10GBRT_STAT2_ERR) { 325 xpcs_warn(xpcs, state, "Link has errors!\n"); 326 return -EFAULT; 327 } 328 329 return 0; 330 } 331 332 static int xpcs_read_link_c73(struct dw_xpcs *xpcs, bool an) 333 { 334 bool link = true; 335 int ret; 336 337 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT1); 338 if (ret < 0) 339 return ret; 340 341 if (!(ret & MDIO_STAT1_LSTATUS)) 342 link = false; 343 344 if (an) { 345 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1); 346 if (ret < 0) 347 return ret; 348 349 if (!(ret & MDIO_STAT1_LSTATUS)) 350 link = false; 351 } 352 353 return link; 354 } 355 356 static int xpcs_get_max_usxgmii_speed(const unsigned long *supported) 357 { 358 int max = SPEED_UNKNOWN; 359 360 if (phylink_test(supported, 1000baseKX_Full)) 361 max = SPEED_1000; 362 if (phylink_test(supported, 2500baseX_Full)) 363 max = SPEED_2500; 364 if (phylink_test(supported, 10000baseKX4_Full)) 365 max = SPEED_10000; 366 if (phylink_test(supported, 10000baseKR_Full)) 367 max = SPEED_10000; 368 369 return max; 370 } 371 372 static void xpcs_config_usxgmii(struct dw_xpcs *xpcs, int speed) 373 { 374 int ret, speed_sel; 375 376 switch (speed) { 377 case SPEED_10: 378 speed_sel = DW_USXGMII_10; 379 break; 380 case SPEED_100: 381 speed_sel = DW_USXGMII_100; 382 break; 383 case SPEED_1000: 384 speed_sel = DW_USXGMII_1000; 385 break; 386 case SPEED_2500: 387 speed_sel = DW_USXGMII_2500; 388 break; 389 case SPEED_5000: 390 speed_sel = DW_USXGMII_5000; 391 break; 392 case SPEED_10000: 393 speed_sel = DW_USXGMII_10000; 394 break; 395 default: 396 /* Nothing to do here */ 397 return; 398 } 399 400 ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1); 401 if (ret < 0) 402 goto out; 403 404 ret = xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_EN); 405 if (ret < 0) 406 goto out; 407 408 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1); 409 if (ret < 0) 410 goto out; 411 412 ret &= ~DW_USXGMII_SS_MASK; 413 ret |= speed_sel | DW_USXGMII_FULL; 414 415 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret); 416 if (ret < 0) 417 goto out; 418 419 ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1); 420 if (ret < 0) 421 goto out; 422 423 ret = xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_RST); 424 if (ret < 0) 425 goto out; 426 427 return; 428 429 out: 430 pr_err("%s: XPCS access returned %pe\n", __func__, ERR_PTR(ret)); 431 } 432 433 static int _xpcs_config_aneg_c73(struct dw_xpcs *xpcs, 434 const struct xpcs_compat *compat) 435 { 436 int ret, adv; 437 438 /* By default, in USXGMII mode XPCS operates at 10G baud and 439 * replicates data to achieve lower speeds. Hereby, in this 440 * default configuration we need to advertise all supported 441 * modes and not only the ones we want to use. 442 */ 443 444 /* SR_AN_ADV3 */ 445 adv = 0; 446 if (xpcs_linkmode_supported(compat, 2500baseX_Full)) 447 adv |= DW_C73_2500KX; 448 449 /* TODO: 5000baseKR */ 450 451 ret = xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV3, adv); 452 if (ret < 0) 453 return ret; 454 455 /* SR_AN_ADV2 */ 456 adv = 0; 457 if (xpcs_linkmode_supported(compat, 1000baseKX_Full)) 458 adv |= DW_C73_1000KX; 459 if (xpcs_linkmode_supported(compat, 10000baseKX4_Full)) 460 adv |= DW_C73_10000KX4; 461 if (xpcs_linkmode_supported(compat, 10000baseKR_Full)) 462 adv |= DW_C73_10000KR; 463 464 ret = xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV2, adv); 465 if (ret < 0) 466 return ret; 467 468 /* SR_AN_ADV1 */ 469 adv = DW_C73_AN_ADV_SF; 470 if (xpcs_linkmode_supported(compat, Pause)) 471 adv |= DW_C73_PAUSE; 472 if (xpcs_linkmode_supported(compat, Asym_Pause)) 473 adv |= DW_C73_ASYM_PAUSE; 474 475 return xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV1, adv); 476 } 477 478 static int xpcs_config_aneg_c73(struct dw_xpcs *xpcs, 479 const struct xpcs_compat *compat) 480 { 481 int ret; 482 483 ret = _xpcs_config_aneg_c73(xpcs, compat); 484 if (ret < 0) 485 return ret; 486 487 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_CTRL1); 488 if (ret < 0) 489 return ret; 490 491 ret |= MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART; 492 493 return xpcs_write(xpcs, MDIO_MMD_AN, MDIO_CTRL1, ret); 494 } 495 496 static int xpcs_aneg_done_c73(struct dw_xpcs *xpcs, 497 struct phylink_link_state *state, 498 const struct xpcs_compat *compat) 499 { 500 int ret; 501 502 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1); 503 if (ret < 0) 504 return ret; 505 506 if (ret & MDIO_AN_STAT1_COMPLETE) { 507 ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL1); 508 if (ret < 0) 509 return ret; 510 511 /* Check if Aneg outcome is valid */ 512 if (!(ret & DW_C73_AN_ADV_SF)) { 513 xpcs_config_aneg_c73(xpcs, compat); 514 return 0; 515 } 516 517 return 1; 518 } 519 520 return 0; 521 } 522 523 static int xpcs_read_lpa_c73(struct dw_xpcs *xpcs, 524 struct phylink_link_state *state) 525 { 526 int ret; 527 528 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1); 529 if (ret < 0) 530 return ret; 531 532 if (!(ret & MDIO_AN_STAT1_LPABLE)) { 533 phylink_clear(state->lp_advertising, Autoneg); 534 return 0; 535 } 536 537 phylink_set(state->lp_advertising, Autoneg); 538 539 /* Clause 73 outcome */ 540 ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL3); 541 if (ret < 0) 542 return ret; 543 544 if (ret & DW_C73_2500KX) 545 phylink_set(state->lp_advertising, 2500baseX_Full); 546 547 ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL2); 548 if (ret < 0) 549 return ret; 550 551 if (ret & DW_C73_1000KX) 552 phylink_set(state->lp_advertising, 1000baseKX_Full); 553 if (ret & DW_C73_10000KX4) 554 phylink_set(state->lp_advertising, 10000baseKX4_Full); 555 if (ret & DW_C73_10000KR) 556 phylink_set(state->lp_advertising, 10000baseKR_Full); 557 558 ret = xpcs_read(xpcs, MDIO_MMD_AN, DW_SR_AN_LP_ABL1); 559 if (ret < 0) 560 return ret; 561 562 if (ret & DW_C73_PAUSE) 563 phylink_set(state->lp_advertising, Pause); 564 if (ret & DW_C73_ASYM_PAUSE) 565 phylink_set(state->lp_advertising, Asym_Pause); 566 567 linkmode_and(state->lp_advertising, state->lp_advertising, 568 state->advertising); 569 return 0; 570 } 571 572 static void xpcs_resolve_lpa_c73(struct dw_xpcs *xpcs, 573 struct phylink_link_state *state) 574 { 575 int max_speed = xpcs_get_max_usxgmii_speed(state->lp_advertising); 576 577 state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX; 578 state->speed = max_speed; 579 state->duplex = DUPLEX_FULL; 580 } 581 582 static int xpcs_get_max_xlgmii_speed(struct dw_xpcs *xpcs, 583 struct phylink_link_state *state) 584 { 585 unsigned long *adv = state->advertising; 586 int speed = SPEED_UNKNOWN; 587 int bit; 588 589 for_each_set_bit(bit, adv, __ETHTOOL_LINK_MODE_MASK_NBITS) { 590 int new_speed = SPEED_UNKNOWN; 591 592 switch (bit) { 593 case ETHTOOL_LINK_MODE_25000baseCR_Full_BIT: 594 case ETHTOOL_LINK_MODE_25000baseKR_Full_BIT: 595 case ETHTOOL_LINK_MODE_25000baseSR_Full_BIT: 596 new_speed = SPEED_25000; 597 break; 598 case ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT: 599 case ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT: 600 case ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT: 601 case ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT: 602 new_speed = SPEED_40000; 603 break; 604 case ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT: 605 case ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT: 606 case ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT: 607 case ETHTOOL_LINK_MODE_50000baseKR_Full_BIT: 608 case ETHTOOL_LINK_MODE_50000baseSR_Full_BIT: 609 case ETHTOOL_LINK_MODE_50000baseCR_Full_BIT: 610 case ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT: 611 case ETHTOOL_LINK_MODE_50000baseDR_Full_BIT: 612 new_speed = SPEED_50000; 613 break; 614 case ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT: 615 case ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT: 616 case ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT: 617 case ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT: 618 case ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT: 619 case ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT: 620 case ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT: 621 case ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT: 622 case ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT: 623 new_speed = SPEED_100000; 624 break; 625 default: 626 continue; 627 } 628 629 if (new_speed > speed) 630 speed = new_speed; 631 } 632 633 return speed; 634 } 635 636 static void xpcs_resolve_pma(struct dw_xpcs *xpcs, 637 struct phylink_link_state *state) 638 { 639 state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX; 640 state->duplex = DUPLEX_FULL; 641 642 switch (state->interface) { 643 case PHY_INTERFACE_MODE_10GKR: 644 state->speed = SPEED_10000; 645 break; 646 case PHY_INTERFACE_MODE_XLGMII: 647 state->speed = xpcs_get_max_xlgmii_speed(xpcs, state); 648 break; 649 default: 650 state->speed = SPEED_UNKNOWN; 651 break; 652 } 653 } 654 655 static int xpcs_validate(struct phylink_pcs *pcs, unsigned long *supported, 656 const struct phylink_link_state *state) 657 { 658 __ETHTOOL_DECLARE_LINK_MODE_MASK(xpcs_supported) = { 0, }; 659 const struct xpcs_compat *compat; 660 struct dw_xpcs *xpcs; 661 int i; 662 663 xpcs = phylink_pcs_to_xpcs(pcs); 664 compat = xpcs_find_compat(xpcs->id, state->interface); 665 666 /* Populate the supported link modes for this PHY interface type. 667 * FIXME: what about the port modes and autoneg bit? This masks 668 * all those away. 669 */ 670 if (compat) 671 for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++) 672 set_bit(compat->supported[i], xpcs_supported); 673 674 linkmode_and(supported, supported, xpcs_supported); 675 676 return 0; 677 } 678 679 void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces) 680 { 681 int i, j; 682 683 for (i = 0; i < DW_XPCS_INTERFACE_MAX; i++) { 684 const struct xpcs_compat *compat = &xpcs->id->compat[i]; 685 686 for (j = 0; j < compat->num_interfaces; j++) 687 if (compat->interface[j] < PHY_INTERFACE_MODE_MAX) 688 __set_bit(compat->interface[j], interfaces); 689 } 690 } 691 EXPORT_SYMBOL_GPL(xpcs_get_interfaces); 692 693 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) 694 { 695 int ret; 696 697 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0); 698 if (ret < 0) 699 return ret; 700 701 if (enable) { 702 /* Enable EEE */ 703 ret = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | 704 DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN | 705 DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | 706 mult_fact_100ns << DW_VR_MII_EEE_MULT_FACT_100NS_SHIFT; 707 } else { 708 ret &= ~(DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | 709 DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN | 710 DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | 711 DW_VR_MII_EEE_MULT_FACT_100NS); 712 } 713 714 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0, ret); 715 if (ret < 0) 716 return ret; 717 718 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1); 719 if (ret < 0) 720 return ret; 721 722 if (enable) 723 ret |= DW_VR_MII_EEE_TRN_LPI; 724 else 725 ret &= ~DW_VR_MII_EEE_TRN_LPI; 726 727 return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, ret); 728 } 729 EXPORT_SYMBOL_GPL(xpcs_config_eee); 730 731 static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) 732 { 733 int ret, mdio_ctrl; 734 735 /* For AN for C37 SGMII mode, the settings are :- 736 * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable SGMII AN in case 737 it is already enabled) 738 * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN) 739 * 3) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII) 740 * DW xPCS used with DW EQoS MAC is always MAC side SGMII. 741 * 4) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic 742 * speed/duplex mode change by HW after SGMII AN complete) 743 * 5) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable SGMII AN) 744 * 745 * Note: Since it is MAC side SGMII, there is no need to set 746 * SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from 747 * PHY about the link state change after C28 AN is completed 748 * between PHY and Link Partner. There is also no need to 749 * trigger AN restart for MAC-side SGMII. 750 */ 751 mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL); 752 if (mdio_ctrl < 0) 753 return mdio_ctrl; 754 755 if (mdio_ctrl & AN_CL37_EN) { 756 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, 757 mdio_ctrl & ~AN_CL37_EN); 758 if (ret < 0) 759 return ret; 760 } 761 762 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL); 763 if (ret < 0) 764 return ret; 765 766 ret &= ~(DW_VR_MII_PCS_MODE_MASK | DW_VR_MII_TX_CONFIG_MASK); 767 ret |= (DW_VR_MII_PCS_MODE_C37_SGMII << 768 DW_VR_MII_AN_CTRL_PCS_MODE_SHIFT & 769 DW_VR_MII_PCS_MODE_MASK); 770 ret |= (DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII << 771 DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT & 772 DW_VR_MII_TX_CONFIG_MASK); 773 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret); 774 if (ret < 0) 775 return ret; 776 777 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1); 778 if (ret < 0) 779 return ret; 780 781 if (phylink_autoneg_inband(mode)) 782 ret |= DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; 783 else 784 ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; 785 786 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); 787 if (ret < 0) 788 return ret; 789 790 if (phylink_autoneg_inband(mode)) 791 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, 792 mdio_ctrl | AN_CL37_EN); 793 794 return ret; 795 } 796 797 static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs, unsigned int mode, 798 const unsigned long *advertising) 799 { 800 phy_interface_t interface = PHY_INTERFACE_MODE_1000BASEX; 801 int ret, mdio_ctrl, adv; 802 bool changed = 0; 803 804 /* According to Chap 7.12, to set 1000BASE-X C37 AN, AN must 805 * be disabled first:- 806 * 1) VR_MII_MMD_CTRL Bit(12)[AN_ENABLE] = 0b 807 * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 00b (1000BASE-X C37) 808 */ 809 mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL); 810 if (mdio_ctrl < 0) 811 return mdio_ctrl; 812 813 if (mdio_ctrl & AN_CL37_EN) { 814 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, 815 mdio_ctrl & ~AN_CL37_EN); 816 if (ret < 0) 817 return ret; 818 } 819 820 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL); 821 if (ret < 0) 822 return ret; 823 824 ret &= ~DW_VR_MII_PCS_MODE_MASK; 825 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret); 826 if (ret < 0) 827 return ret; 828 829 /* Check for advertising changes and update the C45 MII ADV 830 * register accordingly. 831 */ 832 adv = phylink_mii_c22_pcs_encode_advertisement(interface, 833 advertising); 834 if (adv >= 0) { 835 ret = xpcs_modify_changed(xpcs, MDIO_MMD_VEND2, 836 MII_ADVERTISE, 0xffff, adv); 837 if (ret < 0) 838 return ret; 839 840 changed = ret; 841 } 842 843 /* Clear CL37 AN complete status */ 844 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0); 845 if (ret < 0) 846 return ret; 847 848 if (phylink_autoneg_inband(mode) && 849 linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, advertising)) { 850 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, 851 mdio_ctrl | AN_CL37_EN); 852 if (ret < 0) 853 return ret; 854 } 855 856 return changed; 857 } 858 859 static int xpcs_config_2500basex(struct dw_xpcs *xpcs) 860 { 861 int ret; 862 863 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1); 864 if (ret < 0) 865 return ret; 866 ret |= DW_VR_MII_DIG_CTRL1_2G5_EN; 867 ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; 868 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); 869 if (ret < 0) 870 return ret; 871 872 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL); 873 if (ret < 0) 874 return ret; 875 ret &= ~AN_CL37_EN; 876 ret |= SGMII_SPEED_SS6; 877 ret &= ~SGMII_SPEED_SS13; 878 return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ret); 879 } 880 881 int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface, 882 unsigned int mode, const unsigned long *advertising) 883 { 884 const struct xpcs_compat *compat; 885 int ret; 886 887 compat = xpcs_find_compat(xpcs->id, interface); 888 if (!compat) 889 return -ENODEV; 890 891 switch (compat->an_mode) { 892 case DW_AN_C73: 893 if (phylink_autoneg_inband(mode)) { 894 ret = xpcs_config_aneg_c73(xpcs, compat); 895 if (ret) 896 return ret; 897 } 898 break; 899 case DW_AN_C37_SGMII: 900 ret = xpcs_config_aneg_c37_sgmii(xpcs, mode); 901 if (ret) 902 return ret; 903 break; 904 case DW_AN_C37_1000BASEX: 905 ret = xpcs_config_aneg_c37_1000basex(xpcs, mode, 906 advertising); 907 if (ret) 908 return ret; 909 break; 910 case DW_2500BASEX: 911 ret = xpcs_config_2500basex(xpcs); 912 if (ret) 913 return ret; 914 break; 915 default: 916 return -1; 917 } 918 919 if (compat->pma_config) { 920 ret = compat->pma_config(xpcs); 921 if (ret) 922 return ret; 923 } 924 925 return 0; 926 } 927 EXPORT_SYMBOL_GPL(xpcs_do_config); 928 929 static int xpcs_config(struct phylink_pcs *pcs, unsigned int mode, 930 phy_interface_t interface, 931 const unsigned long *advertising, 932 bool permit_pause_to_mac) 933 { 934 struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); 935 936 return xpcs_do_config(xpcs, interface, mode, advertising); 937 } 938 939 static int xpcs_get_state_c73(struct dw_xpcs *xpcs, 940 struct phylink_link_state *state, 941 const struct xpcs_compat *compat) 942 { 943 int ret; 944 945 /* Link needs to be read first ... */ 946 state->link = xpcs_read_link_c73(xpcs, state->an_enabled) > 0 ? 1 : 0; 947 948 /* ... and then we check the faults. */ 949 ret = xpcs_read_fault_c73(xpcs, state); 950 if (ret) { 951 ret = xpcs_soft_reset(xpcs, compat); 952 if (ret) 953 return ret; 954 955 state->link = 0; 956 957 return xpcs_do_config(xpcs, state->interface, MLO_AN_INBAND, NULL); 958 } 959 960 if (state->an_enabled && xpcs_aneg_done_c73(xpcs, state, compat)) { 961 state->an_complete = true; 962 xpcs_read_lpa_c73(xpcs, state); 963 xpcs_resolve_lpa_c73(xpcs, state); 964 } else if (state->an_enabled) { 965 state->link = 0; 966 } else if (state->link) { 967 xpcs_resolve_pma(xpcs, state); 968 } 969 970 return 0; 971 } 972 973 static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs, 974 struct phylink_link_state *state) 975 { 976 int ret; 977 978 /* Reset link_state */ 979 state->link = false; 980 state->speed = SPEED_UNKNOWN; 981 state->duplex = DUPLEX_UNKNOWN; 982 state->pause = 0; 983 984 /* For C37 SGMII mode, we check DW_VR_MII_AN_INTR_STS for link 985 * status, speed and duplex. 986 */ 987 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS); 988 if (ret < 0) 989 return ret; 990 991 if (ret & DW_VR_MII_C37_ANSGM_SP_LNKSTS) { 992 int speed_value; 993 994 state->link = true; 995 996 speed_value = (ret & DW_VR_MII_AN_STS_C37_ANSGM_SP) >> 997 DW_VR_MII_AN_STS_C37_ANSGM_SP_SHIFT; 998 if (speed_value == DW_VR_MII_C37_ANSGM_SP_1000) 999 state->speed = SPEED_1000; 1000 else if (speed_value == DW_VR_MII_C37_ANSGM_SP_100) 1001 state->speed = SPEED_100; 1002 else 1003 state->speed = SPEED_10; 1004 1005 if (ret & DW_VR_MII_AN_STS_C37_ANSGM_FD) 1006 state->duplex = DUPLEX_FULL; 1007 else 1008 state->duplex = DUPLEX_HALF; 1009 } 1010 1011 return 0; 1012 } 1013 1014 static int xpcs_get_state_c37_1000basex(struct dw_xpcs *xpcs, 1015 struct phylink_link_state *state) 1016 { 1017 int lpa, bmsr; 1018 1019 if (state->an_enabled) { 1020 /* Reset link state */ 1021 state->link = false; 1022 1023 lpa = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_LPA); 1024 if (lpa < 0 || lpa & LPA_RFAULT) 1025 return lpa; 1026 1027 bmsr = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_BMSR); 1028 if (bmsr < 0) 1029 return bmsr; 1030 1031 phylink_mii_c22_pcs_decode_state(state, bmsr, lpa); 1032 } 1033 1034 return 0; 1035 } 1036 1037 static void xpcs_get_state(struct phylink_pcs *pcs, 1038 struct phylink_link_state *state) 1039 { 1040 struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); 1041 const struct xpcs_compat *compat; 1042 int ret; 1043 1044 compat = xpcs_find_compat(xpcs->id, state->interface); 1045 if (!compat) 1046 return; 1047 1048 switch (compat->an_mode) { 1049 case DW_AN_C73: 1050 ret = xpcs_get_state_c73(xpcs, state, compat); 1051 if (ret) { 1052 pr_err("xpcs_get_state_c73 returned %pe\n", 1053 ERR_PTR(ret)); 1054 return; 1055 } 1056 break; 1057 case DW_AN_C37_SGMII: 1058 ret = xpcs_get_state_c37_sgmii(xpcs, state); 1059 if (ret) { 1060 pr_err("xpcs_get_state_c37_sgmii returned %pe\n", 1061 ERR_PTR(ret)); 1062 } 1063 break; 1064 case DW_AN_C37_1000BASEX: 1065 ret = xpcs_get_state_c37_1000basex(xpcs, state); 1066 if (ret) { 1067 pr_err("xpcs_get_state_c37_1000basex returned %pe\n", 1068 ERR_PTR(ret)); 1069 } 1070 break; 1071 default: 1072 return; 1073 } 1074 } 1075 1076 static void xpcs_link_up_sgmii(struct dw_xpcs *xpcs, unsigned int mode, 1077 int speed, int duplex) 1078 { 1079 int val, ret; 1080 1081 if (phylink_autoneg_inband(mode)) 1082 return; 1083 1084 val = mii_bmcr_encode_fixed(speed, duplex); 1085 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, val); 1086 if (ret) 1087 pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret)); 1088 } 1089 1090 static void xpcs_link_up_1000basex(struct dw_xpcs *xpcs, unsigned int mode, 1091 int speed, int duplex) 1092 { 1093 int val, ret; 1094 1095 if (phylink_autoneg_inband(mode)) 1096 return; 1097 1098 switch (speed) { 1099 case SPEED_1000: 1100 val = BMCR_SPEED1000; 1101 break; 1102 case SPEED_100: 1103 case SPEED_10: 1104 default: 1105 pr_err("%s: speed = %d\n", __func__, speed); 1106 return; 1107 } 1108 1109 if (duplex == DUPLEX_FULL) 1110 val |= BMCR_FULLDPLX; 1111 else 1112 pr_err("%s: half duplex not supported\n", __func__); 1113 1114 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, val); 1115 if (ret) 1116 pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret)); 1117 } 1118 1119 void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode, 1120 phy_interface_t interface, int speed, int duplex) 1121 { 1122 struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); 1123 1124 if (interface == PHY_INTERFACE_MODE_USXGMII) 1125 return xpcs_config_usxgmii(xpcs, speed); 1126 if (interface == PHY_INTERFACE_MODE_SGMII) 1127 return xpcs_link_up_sgmii(xpcs, mode, speed, duplex); 1128 if (interface == PHY_INTERFACE_MODE_1000BASEX) 1129 return xpcs_link_up_1000basex(xpcs, mode, speed, duplex); 1130 } 1131 EXPORT_SYMBOL_GPL(xpcs_link_up); 1132 1133 static void xpcs_an_restart(struct phylink_pcs *pcs) 1134 { 1135 struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); 1136 int ret; 1137 1138 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1); 1139 if (ret >= 0) { 1140 ret |= BMCR_ANRESTART; 1141 xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret); 1142 } 1143 } 1144 1145 static u32 xpcs_get_id(struct dw_xpcs *xpcs) 1146 { 1147 int ret; 1148 u32 id; 1149 1150 /* First, search C73 PCS using PCS MMD */ 1151 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID1); 1152 if (ret < 0) 1153 return 0xffffffff; 1154 1155 id = ret << 16; 1156 1157 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID2); 1158 if (ret < 0) 1159 return 0xffffffff; 1160 1161 /* If Device IDs are not all zeros or all ones, 1162 * we found C73 AN-type device 1163 */ 1164 if ((id | ret) && (id | ret) != 0xffffffff) 1165 return id | ret; 1166 1167 /* Next, search C37 PCS using Vendor-Specific MII MMD */ 1168 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID1); 1169 if (ret < 0) 1170 return 0xffffffff; 1171 1172 id = ret << 16; 1173 1174 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID2); 1175 if (ret < 0) 1176 return 0xffffffff; 1177 1178 /* If Device IDs are not all zeros, we found C37 AN-type device */ 1179 if (id | ret) 1180 return id | ret; 1181 1182 return 0xffffffff; 1183 } 1184 1185 static const struct xpcs_compat synopsys_xpcs_compat[DW_XPCS_INTERFACE_MAX] = { 1186 [DW_XPCS_USXGMII] = { 1187 .supported = xpcs_usxgmii_features, 1188 .interface = xpcs_usxgmii_interfaces, 1189 .num_interfaces = ARRAY_SIZE(xpcs_usxgmii_interfaces), 1190 .an_mode = DW_AN_C73, 1191 }, 1192 [DW_XPCS_10GKR] = { 1193 .supported = xpcs_10gkr_features, 1194 .interface = xpcs_10gkr_interfaces, 1195 .num_interfaces = ARRAY_SIZE(xpcs_10gkr_interfaces), 1196 .an_mode = DW_AN_C73, 1197 }, 1198 [DW_XPCS_XLGMII] = { 1199 .supported = xpcs_xlgmii_features, 1200 .interface = xpcs_xlgmii_interfaces, 1201 .num_interfaces = ARRAY_SIZE(xpcs_xlgmii_interfaces), 1202 .an_mode = DW_AN_C73, 1203 }, 1204 [DW_XPCS_SGMII] = { 1205 .supported = xpcs_sgmii_features, 1206 .interface = xpcs_sgmii_interfaces, 1207 .num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces), 1208 .an_mode = DW_AN_C37_SGMII, 1209 }, 1210 [DW_XPCS_1000BASEX] = { 1211 .supported = xpcs_1000basex_features, 1212 .interface = xpcs_1000basex_interfaces, 1213 .num_interfaces = ARRAY_SIZE(xpcs_1000basex_interfaces), 1214 .an_mode = DW_AN_C37_1000BASEX, 1215 }, 1216 [DW_XPCS_2500BASEX] = { 1217 .supported = xpcs_2500basex_features, 1218 .interface = xpcs_2500basex_interfaces, 1219 .num_interfaces = ARRAY_SIZE(xpcs_2500basex_features), 1220 .an_mode = DW_2500BASEX, 1221 }, 1222 }; 1223 1224 static const struct xpcs_compat nxp_sja1105_xpcs_compat[DW_XPCS_INTERFACE_MAX] = { 1225 [DW_XPCS_SGMII] = { 1226 .supported = xpcs_sgmii_features, 1227 .interface = xpcs_sgmii_interfaces, 1228 .num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces), 1229 .an_mode = DW_AN_C37_SGMII, 1230 .pma_config = nxp_sja1105_sgmii_pma_config, 1231 }, 1232 }; 1233 1234 static const struct xpcs_compat nxp_sja1110_xpcs_compat[DW_XPCS_INTERFACE_MAX] = { 1235 [DW_XPCS_SGMII] = { 1236 .supported = xpcs_sgmii_features, 1237 .interface = xpcs_sgmii_interfaces, 1238 .num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces), 1239 .an_mode = DW_AN_C37_SGMII, 1240 .pma_config = nxp_sja1110_sgmii_pma_config, 1241 }, 1242 [DW_XPCS_2500BASEX] = { 1243 .supported = xpcs_2500basex_features, 1244 .interface = xpcs_2500basex_interfaces, 1245 .num_interfaces = ARRAY_SIZE(xpcs_2500basex_interfaces), 1246 .an_mode = DW_2500BASEX, 1247 .pma_config = nxp_sja1110_2500basex_pma_config, 1248 }, 1249 }; 1250 1251 static const struct xpcs_id xpcs_id_list[] = { 1252 { 1253 .id = SYNOPSYS_XPCS_ID, 1254 .mask = SYNOPSYS_XPCS_MASK, 1255 .compat = synopsys_xpcs_compat, 1256 }, { 1257 .id = NXP_SJA1105_XPCS_ID, 1258 .mask = SYNOPSYS_XPCS_MASK, 1259 .compat = nxp_sja1105_xpcs_compat, 1260 }, { 1261 .id = NXP_SJA1110_XPCS_ID, 1262 .mask = SYNOPSYS_XPCS_MASK, 1263 .compat = nxp_sja1110_xpcs_compat, 1264 }, 1265 }; 1266 1267 static const struct phylink_pcs_ops xpcs_phylink_ops = { 1268 .pcs_validate = xpcs_validate, 1269 .pcs_config = xpcs_config, 1270 .pcs_get_state = xpcs_get_state, 1271 .pcs_an_restart = xpcs_an_restart, 1272 .pcs_link_up = xpcs_link_up, 1273 }; 1274 1275 struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev, 1276 phy_interface_t interface) 1277 { 1278 struct dw_xpcs *xpcs; 1279 u32 xpcs_id; 1280 int i, ret; 1281 1282 xpcs = kzalloc(sizeof(*xpcs), GFP_KERNEL); 1283 if (!xpcs) 1284 return ERR_PTR(-ENOMEM); 1285 1286 xpcs->mdiodev = mdiodev; 1287 1288 xpcs_id = xpcs_get_id(xpcs); 1289 1290 for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) { 1291 const struct xpcs_id *entry = &xpcs_id_list[i]; 1292 const struct xpcs_compat *compat; 1293 1294 if ((xpcs_id & entry->mask) != entry->id) 1295 continue; 1296 1297 xpcs->id = entry; 1298 1299 compat = xpcs_find_compat(entry, interface); 1300 if (!compat) { 1301 ret = -ENODEV; 1302 goto out; 1303 } 1304 1305 xpcs->pcs.ops = &xpcs_phylink_ops; 1306 xpcs->pcs.poll = true; 1307 1308 ret = xpcs_soft_reset(xpcs, compat); 1309 if (ret) 1310 goto out; 1311 1312 return xpcs; 1313 } 1314 1315 ret = -ENODEV; 1316 1317 out: 1318 kfree(xpcs); 1319 1320 return ERR_PTR(ret); 1321 } 1322 EXPORT_SYMBOL_GPL(xpcs_create); 1323 1324 void xpcs_destroy(struct dw_xpcs *xpcs) 1325 { 1326 kfree(xpcs); 1327 } 1328 EXPORT_SYMBOL_GPL(xpcs_destroy); 1329 1330 MODULE_LICENSE("GPL v2"); 1331