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