1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved. 3 * Copyright(c) 2018 Synopsys, Inc. All rights reserved. 4 */ 5 6 #include "axgbe_ethdev.h" 7 #include "axgbe_common.h" 8 #include "axgbe_phy.h" 9 10 static void axgbe_an37_clear_interrupts(struct axgbe_port *pdata) 11 { 12 int reg; 13 14 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT); 15 reg &= ~AXGBE_AN_CL37_INT_MASK; 16 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg); 17 } 18 19 static void axgbe_an37_disable_interrupts(struct axgbe_port *pdata) 20 { 21 int reg; 22 23 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL); 24 reg &= ~AXGBE_AN_CL37_INT_MASK; 25 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg); 26 27 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL); 28 reg &= ~AXGBE_PCS_CL37_BP; 29 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL, reg); 30 } 31 32 static void axgbe_an37_enable_interrupts(struct axgbe_port *pdata) 33 { 34 unsigned int reg; 35 36 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL); 37 reg |= AXGBE_PCS_CL37_BP; 38 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL, reg); 39 40 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL); 41 reg |= AXGBE_AN_CL37_INT_MASK; 42 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg); 43 } 44 45 static void axgbe_an73_clear_interrupts(struct axgbe_port *pdata) 46 { 47 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); 48 } 49 50 static void axgbe_an73_disable_interrupts(struct axgbe_port *pdata) 51 { 52 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0); 53 } 54 55 static void axgbe_an73_enable_interrupts(struct axgbe_port *pdata) 56 { 57 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 58 AXGBE_AN_CL73_INT_MASK); 59 } 60 61 static void axgbe_an_enable_interrupts(struct axgbe_port *pdata) 62 { 63 switch (pdata->an_mode) { 64 case AXGBE_AN_MODE_CL73: 65 case AXGBE_AN_MODE_CL73_REDRV: 66 axgbe_an73_enable_interrupts(pdata); 67 break; 68 case AXGBE_AN_MODE_CL37: 69 case AXGBE_AN_MODE_CL37_SGMII: 70 axgbe_an37_enable_interrupts(pdata); 71 break; 72 default: 73 break; 74 } 75 } 76 77 static void axgbe_an_clear_interrupts_all(struct axgbe_port *pdata) 78 { 79 axgbe_an73_clear_interrupts(pdata); 80 axgbe_an37_clear_interrupts(pdata); 81 } 82 83 static void axgbe_an73_enable_kr_training(struct axgbe_port *pdata) 84 { 85 unsigned int reg; 86 87 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL); 88 89 reg |= AXGBE_KR_TRAINING_ENABLE; 90 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg); 91 } 92 93 static void axgbe_an73_disable_kr_training(struct axgbe_port *pdata) 94 { 95 unsigned int reg; 96 97 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL); 98 99 reg &= ~AXGBE_KR_TRAINING_ENABLE; 100 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg); 101 } 102 103 static void axgbe_kr_mode(struct axgbe_port *pdata) 104 { 105 /* Enable KR training */ 106 axgbe_an73_enable_kr_training(pdata); 107 108 /* Set MAC to 10G speed */ 109 pdata->hw_if.set_speed(pdata, SPEED_10000); 110 111 /* Call PHY implementation support to complete rate change */ 112 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_KR); 113 } 114 115 static void axgbe_kx_2500_mode(struct axgbe_port *pdata) 116 { 117 /* Disable KR training */ 118 axgbe_an73_disable_kr_training(pdata); 119 120 /* Set MAC to 2.5G speed */ 121 pdata->hw_if.set_speed(pdata, SPEED_2500); 122 123 /* Call PHY implementation support to complete rate change */ 124 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_KX_2500); 125 } 126 127 static void axgbe_kx_1000_mode(struct axgbe_port *pdata) 128 { 129 /* Disable KR training */ 130 axgbe_an73_disable_kr_training(pdata); 131 132 /* Set MAC to 1G speed */ 133 pdata->hw_if.set_speed(pdata, SPEED_1000); 134 135 /* Call PHY implementation support to complete rate change */ 136 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_KX_1000); 137 } 138 139 static void axgbe_sfi_mode(struct axgbe_port *pdata) 140 { 141 /* If a KR re-driver is present, change to KR mode instead */ 142 if (pdata->kr_redrv) 143 return axgbe_kr_mode(pdata); 144 145 /* Disable KR training */ 146 axgbe_an73_disable_kr_training(pdata); 147 148 /* Set MAC to 10G speed */ 149 pdata->hw_if.set_speed(pdata, SPEED_10000); 150 151 /* Call PHY implementation support to complete rate change */ 152 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SFI); 153 } 154 155 static void axgbe_x_mode(struct axgbe_port *pdata) 156 { 157 /* Disable KR training */ 158 axgbe_an73_disable_kr_training(pdata); 159 160 /* Set MAC to 1G speed */ 161 pdata->hw_if.set_speed(pdata, SPEED_1000); 162 163 /* Call PHY implementation support to complete rate change */ 164 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_X); 165 } 166 167 static void axgbe_sgmii_1000_mode(struct axgbe_port *pdata) 168 { 169 /* Disable KR training */ 170 axgbe_an73_disable_kr_training(pdata); 171 172 /* Set MAC to 1G speed */ 173 pdata->hw_if.set_speed(pdata, SPEED_1000); 174 175 /* Call PHY implementation support to complete rate change */ 176 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SGMII_1000); 177 } 178 179 static void axgbe_sgmii_100_mode(struct axgbe_port *pdata) 180 { 181 /* Disable KR training */ 182 axgbe_an73_disable_kr_training(pdata); 183 184 /* Set MAC to 1G speed */ 185 pdata->hw_if.set_speed(pdata, SPEED_1000); 186 187 /* Call PHY implementation support to complete rate change */ 188 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SGMII_100); 189 } 190 191 static enum axgbe_mode axgbe_cur_mode(struct axgbe_port *pdata) 192 { 193 return pdata->phy_if.phy_impl.cur_mode(pdata); 194 } 195 196 static bool axgbe_in_kr_mode(struct axgbe_port *pdata) 197 { 198 return axgbe_cur_mode(pdata) == AXGBE_MODE_KR; 199 } 200 201 static void axgbe_change_mode(struct axgbe_port *pdata, 202 enum axgbe_mode mode) 203 { 204 switch (mode) { 205 case AXGBE_MODE_KX_1000: 206 axgbe_kx_1000_mode(pdata); 207 break; 208 case AXGBE_MODE_KX_2500: 209 axgbe_kx_2500_mode(pdata); 210 break; 211 case AXGBE_MODE_KR: 212 axgbe_kr_mode(pdata); 213 break; 214 case AXGBE_MODE_SGMII_100: 215 axgbe_sgmii_100_mode(pdata); 216 break; 217 case AXGBE_MODE_SGMII_1000: 218 axgbe_sgmii_1000_mode(pdata); 219 break; 220 case AXGBE_MODE_X: 221 axgbe_x_mode(pdata); 222 break; 223 case AXGBE_MODE_SFI: 224 axgbe_sfi_mode(pdata); 225 break; 226 case AXGBE_MODE_UNKNOWN: 227 break; 228 default: 229 PMD_DRV_LOG(ERR, "invalid operation mode requested (%u)\n", mode); 230 } 231 } 232 233 static void axgbe_switch_mode(struct axgbe_port *pdata) 234 { 235 axgbe_change_mode(pdata, pdata->phy_if.phy_impl.switch_mode(pdata)); 236 } 237 238 static void axgbe_set_mode(struct axgbe_port *pdata, 239 enum axgbe_mode mode) 240 { 241 if (mode == axgbe_cur_mode(pdata)) 242 return; 243 244 axgbe_change_mode(pdata, mode); 245 } 246 247 static bool axgbe_use_mode(struct axgbe_port *pdata, 248 enum axgbe_mode mode) 249 { 250 return pdata->phy_if.phy_impl.use_mode(pdata, mode); 251 } 252 253 static void axgbe_an37_set(struct axgbe_port *pdata, bool enable, 254 bool restart) 255 { 256 unsigned int reg; 257 258 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_CTRL1); 259 reg &= ~MDIO_VEND2_CTRL1_AN_ENABLE; 260 261 if (enable) 262 reg |= MDIO_VEND2_CTRL1_AN_ENABLE; 263 264 if (restart) 265 reg |= MDIO_VEND2_CTRL1_AN_RESTART; 266 267 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_CTRL1, reg); 268 } 269 270 static void axgbe_an37_restart(struct axgbe_port *pdata) 271 { 272 axgbe_an37_enable_interrupts(pdata); 273 axgbe_an37_set(pdata, true, true); 274 } 275 276 static void axgbe_an37_disable(struct axgbe_port *pdata) 277 { 278 axgbe_an37_set(pdata, false, false); 279 axgbe_an37_disable_interrupts(pdata); 280 } 281 282 static void axgbe_an73_set(struct axgbe_port *pdata, bool enable, 283 bool restart) 284 { 285 unsigned int reg; 286 287 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1); 288 reg &= ~MDIO_AN_CTRL1_ENABLE; 289 290 if (enable) 291 reg |= MDIO_AN_CTRL1_ENABLE; 292 293 if (restart) 294 reg |= MDIO_AN_CTRL1_RESTART; 295 296 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg); 297 } 298 299 static void axgbe_an73_restart(struct axgbe_port *pdata) 300 { 301 axgbe_an73_enable_interrupts(pdata); 302 axgbe_an73_set(pdata, true, true); 303 304 PMD_DRV_LOG(DEBUG, "CL73 AN enabled/restarted\n"); 305 } 306 307 static void axgbe_an73_disable(struct axgbe_port *pdata) 308 { 309 axgbe_an73_set(pdata, false, false); 310 axgbe_an73_disable_interrupts(pdata); 311 pdata->an_start = 0; 312 313 PMD_DRV_LOG(DEBUG, "CL73 AN disabled\n"); 314 } 315 316 static void axgbe_an_restart(struct axgbe_port *pdata) 317 { 318 if (pdata->phy_if.phy_impl.an_pre) 319 pdata->phy_if.phy_impl.an_pre(pdata); 320 321 switch (pdata->an_mode) { 322 case AXGBE_AN_MODE_CL73: 323 case AXGBE_AN_MODE_CL73_REDRV: 324 axgbe_an73_restart(pdata); 325 break; 326 case AXGBE_AN_MODE_CL37: 327 case AXGBE_AN_MODE_CL37_SGMII: 328 axgbe_an37_restart(pdata); 329 break; 330 default: 331 break; 332 } 333 } 334 335 static void axgbe_an_disable(struct axgbe_port *pdata) 336 { 337 if (pdata->phy_if.phy_impl.an_post) 338 pdata->phy_if.phy_impl.an_post(pdata); 339 340 switch (pdata->an_mode) { 341 case AXGBE_AN_MODE_CL73: 342 case AXGBE_AN_MODE_CL73_REDRV: 343 axgbe_an73_disable(pdata); 344 break; 345 case AXGBE_AN_MODE_CL37: 346 case AXGBE_AN_MODE_CL37_SGMII: 347 axgbe_an37_disable(pdata); 348 break; 349 default: 350 break; 351 } 352 } 353 354 static void axgbe_an_disable_all(struct axgbe_port *pdata) 355 { 356 axgbe_an73_disable(pdata); 357 axgbe_an37_disable(pdata); 358 } 359 360 static enum axgbe_an axgbe_an73_tx_training(struct axgbe_port *pdata, 361 enum axgbe_rx *state) 362 { 363 unsigned int ad_reg, lp_reg, reg; 364 365 *state = AXGBE_RX_COMPLETE; 366 367 /* If we're not in KR mode then we're done */ 368 if (!axgbe_in_kr_mode(pdata)) 369 return AXGBE_AN_PAGE_RECEIVED; 370 371 /* Enable/Disable FEC */ 372 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); 373 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2); 374 375 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL); 376 reg &= ~(MDIO_PMA_10GBR_FECABLE_ABLE | MDIO_PMA_10GBR_FECABLE_ERRABLE); 377 if ((ad_reg & 0xc000) && (lp_reg & 0xc000)) 378 reg |= pdata->fec_ability; 379 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL, reg); 380 381 /* Start KR training */ 382 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL); 383 if (reg & AXGBE_KR_TRAINING_ENABLE) { 384 if (pdata->phy_if.phy_impl.kr_training_pre) 385 pdata->phy_if.phy_impl.kr_training_pre(pdata); 386 387 reg |= AXGBE_KR_TRAINING_START; 388 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, 389 reg); 390 391 PMD_DRV_LOG(DEBUG, "KR training initiated\n"); 392 393 if (pdata->phy_if.phy_impl.kr_training_post) 394 pdata->phy_if.phy_impl.kr_training_post(pdata); 395 } 396 397 return AXGBE_AN_PAGE_RECEIVED; 398 } 399 400 static enum axgbe_an axgbe_an73_tx_xnp(struct axgbe_port *pdata, 401 enum axgbe_rx *state) 402 { 403 u16 msg; 404 405 *state = AXGBE_RX_XNP; 406 407 msg = AXGBE_XNP_MCF_NULL_MESSAGE; 408 msg |= AXGBE_XNP_MP_FORMATTED; 409 410 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 2, 0); 411 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 1, 0); 412 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP, msg); 413 414 return AXGBE_AN_PAGE_RECEIVED; 415 } 416 417 static enum axgbe_an axgbe_an73_rx_bpa(struct axgbe_port *pdata, 418 enum axgbe_rx *state) 419 { 420 unsigned int link_support; 421 unsigned int reg, ad_reg, lp_reg; 422 423 /* Read Base Ability register 2 first */ 424 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1); 425 426 /* Check for a supported mode, otherwise restart in a different one */ 427 link_support = axgbe_in_kr_mode(pdata) ? 0x80 : 0x20; 428 if (!(reg & link_support)) 429 return AXGBE_AN_INCOMPAT_LINK; 430 431 /* Check Extended Next Page support */ 432 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); 433 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA); 434 435 return ((ad_reg & AXGBE_XNP_NP_EXCHANGE) || 436 (lp_reg & AXGBE_XNP_NP_EXCHANGE)) 437 ? axgbe_an73_tx_xnp(pdata, state) 438 : axgbe_an73_tx_training(pdata, state); 439 } 440 441 static enum axgbe_an axgbe_an73_rx_xnp(struct axgbe_port *pdata, 442 enum axgbe_rx *state) 443 { 444 unsigned int ad_reg, lp_reg; 445 446 /* Check Extended Next Page support */ 447 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_XNP); 448 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPX); 449 450 return ((ad_reg & AXGBE_XNP_NP_EXCHANGE) || 451 (lp_reg & AXGBE_XNP_NP_EXCHANGE)) 452 ? axgbe_an73_tx_xnp(pdata, state) 453 : axgbe_an73_tx_training(pdata, state); 454 } 455 456 static enum axgbe_an axgbe_an73_page_received(struct axgbe_port *pdata) 457 { 458 enum axgbe_rx *state; 459 unsigned long an_timeout; 460 enum axgbe_an ret; 461 unsigned long ticks; 462 463 if (!pdata->an_start) { 464 pdata->an_start = rte_get_timer_cycles(); 465 } else { 466 an_timeout = pdata->an_start + 467 msecs_to_timer_cycles(AXGBE_AN_MS_TIMEOUT); 468 ticks = rte_get_timer_cycles(); 469 if (time_after(ticks, an_timeout)) { 470 /* Auto-negotiation timed out, reset state */ 471 pdata->kr_state = AXGBE_RX_BPA; 472 pdata->kx_state = AXGBE_RX_BPA; 473 474 pdata->an_start = rte_get_timer_cycles(); 475 476 PMD_DRV_LOG(NOTICE, 477 "CL73 AN timed out, resetting state\n"); 478 } 479 } 480 481 state = axgbe_in_kr_mode(pdata) ? &pdata->kr_state 482 : &pdata->kx_state; 483 484 switch (*state) { 485 case AXGBE_RX_BPA: 486 ret = axgbe_an73_rx_bpa(pdata, state); 487 break; 488 case AXGBE_RX_XNP: 489 ret = axgbe_an73_rx_xnp(pdata, state); 490 break; 491 default: 492 ret = AXGBE_AN_ERROR; 493 } 494 495 return ret; 496 } 497 498 static enum axgbe_an axgbe_an73_incompat_link(struct axgbe_port *pdata) 499 { 500 /* Be sure we aren't looping trying to negotiate */ 501 if (axgbe_in_kr_mode(pdata)) { 502 pdata->kr_state = AXGBE_RX_ERROR; 503 504 if (!(pdata->phy.advertising & ADVERTISED_1000baseKX_Full) && 505 !(pdata->phy.advertising & ADVERTISED_2500baseX_Full)) 506 return AXGBE_AN_NO_LINK; 507 508 if (pdata->kx_state != AXGBE_RX_BPA) 509 return AXGBE_AN_NO_LINK; 510 } else { 511 pdata->kx_state = AXGBE_RX_ERROR; 512 513 if (!(pdata->phy.advertising & ADVERTISED_10000baseKR_Full)) 514 return AXGBE_AN_NO_LINK; 515 516 if (pdata->kr_state != AXGBE_RX_BPA) 517 return AXGBE_AN_NO_LINK; 518 } 519 520 axgbe_an_disable(pdata); 521 axgbe_switch_mode(pdata); 522 axgbe_an_restart(pdata); 523 524 return AXGBE_AN_INCOMPAT_LINK; 525 } 526 527 static const char *axgbe_state_as_string(enum axgbe_an state) 528 { 529 switch (state) { 530 case AXGBE_AN_READY: 531 return "Ready"; 532 case AXGBE_AN_PAGE_RECEIVED: 533 return "Page-Received"; 534 case AXGBE_AN_INCOMPAT_LINK: 535 return "Incompatible-Link"; 536 case AXGBE_AN_COMPLETE: 537 return "Complete"; 538 case AXGBE_AN_NO_LINK: 539 return "No-Link"; 540 case AXGBE_AN_ERROR: 541 return "Error"; 542 default: 543 return "Undefined"; 544 } 545 } 546 547 static void axgbe_an73_state_machine(struct axgbe_port *pdata) 548 { 549 enum axgbe_an cur_state = pdata->an_state; 550 551 if (!pdata->an_int) 552 return; 553 554 next_int: 555 if (pdata->an_int & AXGBE_AN_CL73_PG_RCV) { 556 pdata->an_state = AXGBE_AN_PAGE_RECEIVED; 557 pdata->an_int &= ~AXGBE_AN_CL73_PG_RCV; 558 } else if (pdata->an_int & AXGBE_AN_CL73_INC_LINK) { 559 pdata->an_state = AXGBE_AN_INCOMPAT_LINK; 560 pdata->an_int &= ~AXGBE_AN_CL73_INC_LINK; 561 } else if (pdata->an_int & AXGBE_AN_CL73_INT_CMPLT) { 562 pdata->an_state = AXGBE_AN_COMPLETE; 563 pdata->an_int &= ~AXGBE_AN_CL73_INT_CMPLT; 564 } else { 565 pdata->an_state = AXGBE_AN_ERROR; 566 } 567 568 PMD_DRV_LOG(DEBUG, "CL73 AN : %s\n", 569 axgbe_state_as_string(pdata->an_state)); 570 571 again: 572 cur_state = pdata->an_state; 573 574 switch (pdata->an_state) { 575 case AXGBE_AN_READY: 576 pdata->an_supported = 0; 577 break; 578 case AXGBE_AN_PAGE_RECEIVED: 579 pdata->an_state = axgbe_an73_page_received(pdata); 580 pdata->an_supported++; 581 break; 582 case AXGBE_AN_INCOMPAT_LINK: 583 pdata->an_supported = 0; 584 pdata->parallel_detect = 0; 585 pdata->an_state = axgbe_an73_incompat_link(pdata); 586 break; 587 case AXGBE_AN_COMPLETE: 588 pdata->parallel_detect = pdata->an_supported ? 0 : 1; 589 break; 590 case AXGBE_AN_NO_LINK: 591 break; 592 default: 593 pdata->an_state = AXGBE_AN_ERROR; 594 } 595 596 if (pdata->an_state == AXGBE_AN_NO_LINK) { 597 pdata->an_int = 0; 598 axgbe_an73_clear_interrupts(pdata); 599 pdata->eth_dev->data->dev_link.link_status = 600 ETH_LINK_DOWN; 601 } else if (pdata->an_state == AXGBE_AN_ERROR) { 602 PMD_DRV_LOG(ERR, "error during auto-negotiation, state=%u\n", 603 cur_state); 604 pdata->an_int = 0; 605 axgbe_an73_clear_interrupts(pdata); 606 } 607 608 if (pdata->an_state >= AXGBE_AN_COMPLETE) { 609 pdata->an_result = pdata->an_state; 610 pdata->an_state = AXGBE_AN_READY; 611 pdata->kr_state = AXGBE_RX_BPA; 612 pdata->kx_state = AXGBE_RX_BPA; 613 pdata->an_start = 0; 614 if (pdata->phy_if.phy_impl.an_post) 615 pdata->phy_if.phy_impl.an_post(pdata); 616 617 PMD_DRV_LOG(DEBUG, "CL73 AN result: %s\n", 618 axgbe_state_as_string(pdata->an_result)); 619 } 620 621 if (cur_state != pdata->an_state) 622 goto again; 623 624 if (pdata->an_int) 625 goto next_int; 626 627 axgbe_an73_enable_interrupts(pdata); 628 } 629 630 static void axgbe_an37_state_machine(struct axgbe_port *pdata) 631 { 632 enum axgbe_an cur_state = pdata->an_state; 633 634 if (!pdata->an_int) 635 return; 636 if (pdata->an_int & AXGBE_AN_CL37_INT_CMPLT) { 637 pdata->an_state = AXGBE_AN_COMPLETE; 638 pdata->an_int &= ~AXGBE_AN_CL37_INT_CMPLT; 639 640 /* If SGMII is enabled, check the link status */ 641 if (pdata->an_mode == AXGBE_AN_MODE_CL37_SGMII && 642 !(pdata->an_status & AXGBE_SGMII_AN_LINK_STATUS)) 643 pdata->an_state = AXGBE_AN_NO_LINK; 644 } 645 646 cur_state = pdata->an_state; 647 648 switch (pdata->an_state) { 649 case AXGBE_AN_READY: 650 break; 651 case AXGBE_AN_COMPLETE: 652 break; 653 case AXGBE_AN_NO_LINK: 654 break; 655 default: 656 pdata->an_state = AXGBE_AN_ERROR; 657 break; 658 } 659 660 if (pdata->an_state == AXGBE_AN_ERROR) { 661 PMD_DRV_LOG(ERR, "error during auto-negotiation, state=%u\n", 662 cur_state); 663 pdata->an_int = 0; 664 axgbe_an37_clear_interrupts(pdata); 665 } 666 667 if (pdata->an_state >= AXGBE_AN_COMPLETE) { 668 pdata->an_result = pdata->an_state; 669 pdata->an_state = AXGBE_AN_READY; 670 if (pdata->phy_if.phy_impl.an_post) 671 pdata->phy_if.phy_impl.an_post(pdata); 672 } 673 674 axgbe_an37_enable_interrupts(pdata); 675 } 676 677 static void axgbe_an73_isr(struct axgbe_port *pdata) 678 { 679 /* Disable AN interrupts */ 680 axgbe_an73_disable_interrupts(pdata); 681 682 /* Save the interrupt(s) that fired */ 683 pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT); 684 axgbe_an73_clear_interrupts(pdata); 685 686 if (pdata->an_int) { 687 /* Clear the interrupt(s) that fired and process them */ 688 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, ~pdata->an_int); 689 pthread_mutex_lock(&pdata->an_mutex); 690 axgbe_an73_state_machine(pdata); 691 pthread_mutex_unlock(&pdata->an_mutex); 692 } else { 693 /* Enable AN interrupts */ 694 axgbe_an73_enable_interrupts(pdata); 695 } 696 } 697 698 static void axgbe_an37_isr(struct axgbe_port *pdata) 699 { 700 unsigned int reg = 0; 701 /* Disable AN interrupts */ 702 axgbe_an37_disable_interrupts(pdata); 703 704 /* Save the interrupt(s) that fired */ 705 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT); 706 pdata->an_int = reg & AXGBE_AN_CL37_INT_MASK; 707 pdata->an_status = reg & ~AXGBE_AN_CL37_INT_MASK; 708 axgbe_an37_clear_interrupts(pdata); 709 710 if (pdata->an_int & 0x01) { 711 /* Clear the interrupt(s) that fired and process them */ 712 reg &= ~AXGBE_AN_CL37_INT_MASK; 713 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg); 714 axgbe_an37_state_machine(pdata); 715 } else { 716 /* Enable AN interrupts */ 717 axgbe_an37_enable_interrupts(pdata); 718 } 719 } 720 721 static void axgbe_an_isr(struct axgbe_port *pdata) 722 { 723 PMD_DRV_LOG(DEBUG, "AN interrupt received\n"); 724 725 switch (pdata->an_mode) { 726 case AXGBE_AN_MODE_CL73: 727 case AXGBE_AN_MODE_CL73_REDRV: 728 axgbe_an73_isr(pdata); 729 break; 730 case AXGBE_AN_MODE_CL37: 731 case AXGBE_AN_MODE_CL37_SGMII: 732 axgbe_an37_isr(pdata); 733 break; 734 default: 735 break; 736 } 737 } 738 739 static void axgbe_an_combined_isr(struct axgbe_port *pdata) 740 { 741 axgbe_an_isr(pdata); 742 } 743 744 static void axgbe_an37_init(struct axgbe_port *pdata) 745 { 746 unsigned int advertising; 747 unsigned int reg = 0; 748 749 advertising = pdata->phy_if.phy_impl.an_advertising(pdata); 750 751 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE); 752 if (advertising & ADVERTISED_Pause) 753 reg |= 0x100; 754 else 755 reg &= ~0x100; 756 if (advertising & ADVERTISED_Asym_Pause) 757 reg |= 0x80; 758 else 759 reg &= ~0x80; 760 761 /* Full duplex, but not half */ 762 reg |= AXGBE_AN_CL37_FD_MASK; 763 reg &= ~AXGBE_AN_CL37_HD_MASK; 764 765 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE, reg); 766 767 /* Set up the Control register */ 768 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL); 769 reg &= ~AXGBE_AN_CL37_TX_CONFIG_MASK; 770 reg &= ~AXGBE_AN_CL37_PCS_MODE_MASK; 771 772 switch (pdata->an_mode) { 773 case AXGBE_AN_MODE_CL37: 774 reg |= AXGBE_AN_CL37_PCS_MODE_BASEX; 775 break; 776 case AXGBE_AN_MODE_CL37_SGMII: 777 reg |= AXGBE_AN_CL37_PCS_MODE_SGMII; 778 break; 779 default: 780 break; 781 } 782 reg |= AXGBE_AN_CL37_MII_CTRL_8BIT; 783 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg); 784 } 785 786 static void axgbe_an73_init(struct axgbe_port *pdata) 787 { 788 unsigned int advertising, reg; 789 790 advertising = pdata->phy_if.phy_impl.an_advertising(pdata); 791 792 /* Set up Advertisement register 3 first */ 793 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); 794 if (advertising & ADVERTISED_10000baseR_FEC) 795 reg |= 0xc000; 796 else 797 reg &= ~0xc000; 798 799 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, reg); 800 801 /* Set up Advertisement register 2 next */ 802 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); 803 if (advertising & ADVERTISED_10000baseKR_Full) 804 reg |= 0x80; 805 else 806 reg &= ~0x80; 807 808 if ((advertising & ADVERTISED_1000baseKX_Full) || 809 (advertising & ADVERTISED_2500baseX_Full)) 810 reg |= 0x20; 811 else 812 reg &= ~0x20; 813 814 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, reg); 815 816 /* Set up Advertisement register 1 last */ 817 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); 818 if (advertising & ADVERTISED_Pause) 819 reg |= 0x400; 820 else 821 reg &= ~0x400; 822 823 if (advertising & ADVERTISED_Asym_Pause) 824 reg |= 0x800; 825 else 826 reg &= ~0x800; 827 828 /* We don't intend to perform XNP */ 829 reg &= ~AXGBE_XNP_NP_EXCHANGE; 830 831 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); 832 833 PMD_DRV_LOG(DEBUG, "CL73 AN initialized\n"); 834 } 835 836 static void axgbe_an_init(struct axgbe_port *pdata) 837 { 838 /* Set up advertisement registers based on current settings */ 839 pdata->an_mode = pdata->phy_if.phy_impl.an_mode(pdata); 840 switch (pdata->an_mode) { 841 case AXGBE_AN_MODE_CL73: 842 case AXGBE_AN_MODE_CL73_REDRV: 843 axgbe_an73_init(pdata); 844 break; 845 case AXGBE_AN_MODE_CL37: 846 case AXGBE_AN_MODE_CL37_SGMII: 847 axgbe_an37_init(pdata); 848 break; 849 default: 850 break; 851 } 852 } 853 854 static void axgbe_phy_adjust_link(struct axgbe_port *pdata) 855 { 856 if (pdata->phy.link) { 857 /* Flow control support */ 858 pdata->pause_autoneg = pdata->phy.pause_autoneg; 859 860 if (pdata->tx_pause != (unsigned int)pdata->phy.tx_pause) { 861 pdata->hw_if.config_tx_flow_control(pdata); 862 pdata->tx_pause = pdata->phy.tx_pause; 863 } 864 865 if (pdata->rx_pause != (unsigned int)pdata->phy.rx_pause) { 866 pdata->hw_if.config_rx_flow_control(pdata); 867 pdata->rx_pause = pdata->phy.rx_pause; 868 } 869 870 /* Speed support */ 871 if (pdata->phy_speed != pdata->phy.speed) 872 pdata->phy_speed = pdata->phy.speed; 873 if (pdata->phy_link != pdata->phy.link) 874 pdata->phy_link = pdata->phy.link; 875 } else if (pdata->phy_link) { 876 pdata->phy_link = 0; 877 pdata->phy_speed = SPEED_UNKNOWN; 878 } 879 } 880 881 static int axgbe_phy_config_fixed(struct axgbe_port *pdata) 882 { 883 enum axgbe_mode mode; 884 885 PMD_DRV_LOG(DEBUG, "fixed PHY configuration\n"); 886 887 /* Disable auto-negotiation */ 888 axgbe_an_disable(pdata); 889 890 /* Set specified mode for specified speed */ 891 mode = pdata->phy_if.phy_impl.get_mode(pdata, pdata->phy.speed); 892 switch (mode) { 893 case AXGBE_MODE_KX_1000: 894 case AXGBE_MODE_KX_2500: 895 case AXGBE_MODE_KR: 896 case AXGBE_MODE_SGMII_100: 897 case AXGBE_MODE_SGMII_1000: 898 case AXGBE_MODE_X: 899 case AXGBE_MODE_SFI: 900 break; 901 case AXGBE_MODE_UNKNOWN: 902 default: 903 return -EINVAL; 904 } 905 906 /* Validate duplex mode */ 907 if (pdata->phy.duplex != DUPLEX_FULL) 908 return -EINVAL; 909 910 axgbe_set_mode(pdata, mode); 911 912 return 0; 913 } 914 915 static int __axgbe_phy_config_aneg(struct axgbe_port *pdata) 916 { 917 int ret; 918 919 rte_bit_relaxed_set32(AXGBE_LINK_INIT, &pdata->dev_state); 920 pdata->link_check = rte_get_timer_cycles(); 921 922 ret = pdata->phy_if.phy_impl.an_config(pdata); 923 if (ret) 924 return ret; 925 926 if (pdata->phy.autoneg != AUTONEG_ENABLE) { 927 ret = axgbe_phy_config_fixed(pdata); 928 if (ret || !pdata->kr_redrv) 929 return ret; 930 PMD_DRV_LOG(DEBUG, "AN redriver support\n"); 931 } else { 932 PMD_DRV_LOG(DEBUG, "AN PHY configuration\n"); 933 } 934 935 /* Disable auto-negotiation interrupt */ 936 rte_intr_disable(&pdata->pci_dev->intr_handle); 937 938 /* Start auto-negotiation in a supported mode */ 939 if (axgbe_use_mode(pdata, AXGBE_MODE_KR)) { 940 axgbe_set_mode(pdata, AXGBE_MODE_KR); 941 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_2500)) { 942 axgbe_set_mode(pdata, AXGBE_MODE_KX_2500); 943 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_1000)) { 944 axgbe_set_mode(pdata, AXGBE_MODE_KX_1000); 945 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SFI)) { 946 axgbe_set_mode(pdata, AXGBE_MODE_SFI); 947 } else if (axgbe_use_mode(pdata, AXGBE_MODE_X)) { 948 axgbe_set_mode(pdata, AXGBE_MODE_X); 949 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_1000)) { 950 axgbe_set_mode(pdata, AXGBE_MODE_SGMII_1000); 951 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_100)) { 952 axgbe_set_mode(pdata, AXGBE_MODE_SGMII_100); 953 } else { 954 rte_intr_enable(&pdata->pci_dev->intr_handle); 955 return -EINVAL; 956 } 957 958 /* Disable and stop any in progress auto-negotiation */ 959 axgbe_an_disable_all(pdata); 960 961 pdata->an_result = AXGBE_AN_READY; 962 pdata->an_state = AXGBE_AN_READY; 963 pdata->kr_state = AXGBE_RX_BPA; 964 pdata->kx_state = AXGBE_RX_BPA; 965 966 /* Re-enable auto-negotiation interrupt */ 967 rte_intr_enable(&pdata->pci_dev->intr_handle); 968 axgbe_an37_enable_interrupts(pdata); 969 970 axgbe_an_init(pdata); 971 axgbe_an_restart(pdata); 972 973 return 0; 974 } 975 976 static int axgbe_phy_config_aneg(struct axgbe_port *pdata) 977 { 978 int ret; 979 980 pthread_mutex_lock(&pdata->an_mutex); 981 982 ret = __axgbe_phy_config_aneg(pdata); 983 if (ret) 984 rte_bit_relaxed_set32(AXGBE_LINK_ERR, &pdata->dev_state); 985 else 986 rte_bit_relaxed_clear32(AXGBE_LINK_ERR, &pdata->dev_state); 987 988 pthread_mutex_unlock(&pdata->an_mutex); 989 990 return ret; 991 } 992 993 static bool axgbe_phy_aneg_done(struct axgbe_port *pdata) 994 { 995 return pdata->an_result == AXGBE_AN_COMPLETE; 996 } 997 998 static void axgbe_check_link_timeout(struct axgbe_port *pdata) 999 { 1000 unsigned long link_timeout; 1001 unsigned long ticks; 1002 1003 link_timeout = pdata->link_check + (AXGBE_LINK_TIMEOUT * 1004 2 * rte_get_timer_hz()); 1005 ticks = rte_get_timer_cycles(); 1006 if (time_after(ticks, link_timeout)) { 1007 PMD_DRV_LOG(NOTICE, "AN link timeout\n"); 1008 axgbe_phy_config_aneg(pdata); 1009 } 1010 } 1011 1012 static enum axgbe_mode axgbe_phy_status_aneg(struct axgbe_port *pdata) 1013 { 1014 return pdata->phy_if.phy_impl.an_outcome(pdata); 1015 } 1016 1017 static void axgbe_phy_status_result(struct axgbe_port *pdata) 1018 { 1019 enum axgbe_mode mode; 1020 1021 pdata->phy.lp_advertising = 0; 1022 1023 if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect) 1024 mode = axgbe_cur_mode(pdata); 1025 else 1026 mode = axgbe_phy_status_aneg(pdata); 1027 1028 switch (mode) { 1029 case AXGBE_MODE_SGMII_100: 1030 pdata->phy.speed = SPEED_100; 1031 break; 1032 case AXGBE_MODE_X: 1033 case AXGBE_MODE_KX_1000: 1034 case AXGBE_MODE_SGMII_1000: 1035 pdata->phy.speed = SPEED_1000; 1036 break; 1037 case AXGBE_MODE_KX_2500: 1038 pdata->phy.speed = SPEED_2500; 1039 break; 1040 case AXGBE_MODE_KR: 1041 case AXGBE_MODE_SFI: 1042 pdata->phy.speed = SPEED_10000; 1043 break; 1044 case AXGBE_MODE_UNKNOWN: 1045 default: 1046 pdata->phy.speed = SPEED_UNKNOWN; 1047 } 1048 1049 pdata->phy.duplex = DUPLEX_FULL; 1050 1051 axgbe_set_mode(pdata, mode); 1052 } 1053 1054 static int autoneg_time_out(unsigned long autoneg_start_time) 1055 { 1056 unsigned long autoneg_timeout; 1057 unsigned long ticks; 1058 1059 autoneg_timeout = autoneg_start_time + (AXGBE_LINK_TIMEOUT * 1060 2 * rte_get_timer_hz()); 1061 ticks = rte_get_timer_cycles(); 1062 if (time_after(ticks, autoneg_timeout)) 1063 return 1; 1064 else 1065 return 0; 1066 } 1067 1068 static void axgbe_phy_status(struct axgbe_port *pdata) 1069 { 1070 unsigned int link_aneg; 1071 int an_restart, ret; 1072 unsigned int reg = 0; 1073 unsigned long autoneg_start_time; 1074 1075 if (rte_bit_relaxed_get32(AXGBE_LINK_ERR, &pdata->dev_state)) { 1076 pdata->phy.link = 0; 1077 goto adjust_link; 1078 } 1079 1080 link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE); 1081 1082 pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata, 1083 &an_restart); 1084 if (an_restart) { 1085 axgbe_phy_config_aneg(pdata); 1086 return; 1087 } 1088 1089 if (pdata->phy.link) { 1090 if (link_aneg && !axgbe_phy_aneg_done(pdata)) { 1091 if (axgbe_cur_mode(pdata) == AXGBE_MODE_SGMII_1000) { 1092 /* autoneg not complete, so re-initializing */ 1093 /* and restarting it */ 1094 axgbe_an_init(pdata); 1095 axgbe_an_restart(pdata); 1096 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, 1097 MDIO_VEND2_AN_STAT); 1098 autoneg_start_time = rte_get_timer_cycles(); 1099 /* poll for autoneg to complete */ 1100 while (!(reg & AXGBE_AN_CL37_INT_CMPLT)) { 1101 ret = 1102 autoneg_time_out(autoneg_start_time); 1103 if (ret) 1104 break; 1105 reg = XMDIO_READ(pdata, 1106 MDIO_MMD_VEND2, 1107 MDIO_VEND2_AN_STAT); 1108 if (reg & AXGBE_AN_CL37_INT_CMPLT) { 1109 axgbe_an37_isr(pdata); 1110 break; 1111 } 1112 } 1113 } else { 1114 axgbe_check_link_timeout(pdata); 1115 return; 1116 } 1117 } 1118 axgbe_phy_status_result(pdata); 1119 if (rte_bit_relaxed_get32(AXGBE_LINK_INIT, &pdata->dev_state)) 1120 rte_bit_relaxed_clear32(AXGBE_LINK_INIT, 1121 &pdata->dev_state); 1122 } else { 1123 if (rte_bit_relaxed_get32(AXGBE_LINK_INIT, &pdata->dev_state)) { 1124 axgbe_check_link_timeout(pdata); 1125 1126 if (link_aneg) 1127 return; 1128 } 1129 axgbe_phy_status_result(pdata); 1130 } 1131 1132 adjust_link: 1133 axgbe_phy_adjust_link(pdata); 1134 } 1135 1136 static void axgbe_phy_stop(struct axgbe_port *pdata) 1137 { 1138 PMD_DRV_LOG(DEBUG, "stopping PHY\n"); 1139 if (!pdata->phy_started) 1140 return; 1141 /* Indicate the PHY is down */ 1142 pdata->phy_started = 0; 1143 /* Disable auto-negotiation */ 1144 axgbe_an_disable_all(pdata); 1145 pdata->phy_if.phy_impl.stop(pdata); 1146 pdata->phy.link = 0; 1147 axgbe_phy_adjust_link(pdata); 1148 } 1149 1150 static int axgbe_phy_start(struct axgbe_port *pdata) 1151 { 1152 int ret; 1153 1154 PMD_DRV_LOG(DEBUG, "starting PHY\n"); 1155 1156 ret = pdata->phy_if.phy_impl.start(pdata); 1157 if (ret) 1158 return ret; 1159 /* Set initial mode - call the mode setting routines 1160 * directly to insure we are properly configured 1161 */ 1162 if (axgbe_use_mode(pdata, AXGBE_MODE_KR)) { 1163 axgbe_kr_mode(pdata); 1164 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_2500)) { 1165 axgbe_kx_2500_mode(pdata); 1166 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_1000)) { 1167 axgbe_kx_1000_mode(pdata); 1168 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SFI)) { 1169 axgbe_sfi_mode(pdata); 1170 } else if (axgbe_use_mode(pdata, AXGBE_MODE_X)) { 1171 axgbe_x_mode(pdata); 1172 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_1000)) { 1173 axgbe_sgmii_1000_mode(pdata); 1174 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_100)) { 1175 axgbe_sgmii_100_mode(pdata); 1176 } else { 1177 ret = -EINVAL; 1178 goto err_stop; 1179 } 1180 /* Indicate the PHY is up and running */ 1181 pdata->phy_started = 1; 1182 axgbe_an_init(pdata); 1183 axgbe_an_enable_interrupts(pdata); 1184 return axgbe_phy_config_aneg(pdata); 1185 1186 err_stop: 1187 pdata->phy_if.phy_impl.stop(pdata); 1188 1189 return ret; 1190 } 1191 1192 static int axgbe_phy_reset(struct axgbe_port *pdata) 1193 { 1194 int ret; 1195 1196 ret = pdata->phy_if.phy_impl.reset(pdata); 1197 if (ret) 1198 return ret; 1199 1200 /* Disable auto-negotiation for now */ 1201 axgbe_an_disable_all(pdata); 1202 1203 /* Clear auto-negotiation interrupts */ 1204 axgbe_an_clear_interrupts_all(pdata); 1205 1206 return 0; 1207 } 1208 1209 static int axgbe_phy_best_advertised_speed(struct axgbe_port *pdata) 1210 { 1211 if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full) 1212 return SPEED_10000; 1213 else if (pdata->phy.advertising & ADVERTISED_10000baseT_Full) 1214 return SPEED_10000; 1215 else if (pdata->phy.advertising & ADVERTISED_2500baseX_Full) 1216 return SPEED_2500; 1217 else if (pdata->phy.advertising & ADVERTISED_1000baseKX_Full) 1218 return SPEED_1000; 1219 else if (pdata->phy.advertising & ADVERTISED_1000baseT_Full) 1220 return SPEED_1000; 1221 else if (pdata->phy.advertising & ADVERTISED_100baseT_Full) 1222 return SPEED_100; 1223 1224 return SPEED_UNKNOWN; 1225 } 1226 1227 static int axgbe_phy_init(struct axgbe_port *pdata) 1228 { 1229 int ret; 1230 1231 pdata->mdio_mmd = MDIO_MMD_PCS; 1232 1233 /* Check for FEC support */ 1234 pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, 1235 MDIO_PMA_10GBR_FECABLE); 1236 pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE | 1237 MDIO_PMA_10GBR_FECABLE_ERRABLE); 1238 1239 /* Setup the phy (including supported features) */ 1240 ret = pdata->phy_if.phy_impl.init(pdata); 1241 if (ret) 1242 return ret; 1243 pdata->phy.advertising = pdata->phy.supported; 1244 1245 pdata->phy.address = 0; 1246 1247 if (pdata->phy.advertising & ADVERTISED_Autoneg) { 1248 pdata->phy.autoneg = AUTONEG_ENABLE; 1249 pdata->phy.speed = SPEED_UNKNOWN; 1250 pdata->phy.duplex = DUPLEX_UNKNOWN; 1251 } else { 1252 pdata->phy.autoneg = AUTONEG_DISABLE; 1253 pdata->phy.speed = axgbe_phy_best_advertised_speed(pdata); 1254 pdata->phy.duplex = DUPLEX_FULL; 1255 } 1256 1257 pdata->phy.link = 0; 1258 1259 pdata->phy.pause_autoneg = pdata->pause_autoneg; 1260 pdata->phy.tx_pause = pdata->tx_pause; 1261 pdata->phy.rx_pause = pdata->rx_pause; 1262 1263 /* Fix up Flow Control advertising */ 1264 pdata->phy.advertising &= ~ADVERTISED_Pause; 1265 pdata->phy.advertising &= ~ADVERTISED_Asym_Pause; 1266 1267 if (pdata->rx_pause) { 1268 pdata->phy.advertising |= ADVERTISED_Pause; 1269 pdata->phy.advertising |= ADVERTISED_Asym_Pause; 1270 } 1271 1272 if (pdata->tx_pause) 1273 pdata->phy.advertising ^= ADVERTISED_Asym_Pause; 1274 return 0; 1275 } 1276 1277 void axgbe_init_function_ptrs_phy(struct axgbe_phy_if *phy_if) 1278 { 1279 phy_if->phy_init = axgbe_phy_init; 1280 phy_if->phy_reset = axgbe_phy_reset; 1281 phy_if->phy_start = axgbe_phy_start; 1282 phy_if->phy_stop = axgbe_phy_stop; 1283 phy_if->phy_status = axgbe_phy_status; 1284 phy_if->phy_config_aneg = axgbe_phy_config_aneg; 1285 phy_if->an_isr = axgbe_an_combined_isr; 1286 } 1287