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