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