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 305 static void axgbe_an73_disable(struct axgbe_port *pdata) 306 { 307 axgbe_an73_set(pdata, false, false); 308 axgbe_an73_disable_interrupts(pdata); 309 pdata->an_start = 0; 310 } 311 312 static void axgbe_an_restart(struct axgbe_port *pdata) 313 { 314 if (pdata->phy_if.phy_impl.an_pre) 315 pdata->phy_if.phy_impl.an_pre(pdata); 316 317 switch (pdata->an_mode) { 318 case AXGBE_AN_MODE_CL73: 319 case AXGBE_AN_MODE_CL73_REDRV: 320 axgbe_an73_restart(pdata); 321 break; 322 case AXGBE_AN_MODE_CL37: 323 case AXGBE_AN_MODE_CL37_SGMII: 324 axgbe_an37_restart(pdata); 325 break; 326 default: 327 break; 328 } 329 } 330 331 static void axgbe_an_disable(struct axgbe_port *pdata) 332 { 333 if (pdata->phy_if.phy_impl.an_post) 334 pdata->phy_if.phy_impl.an_post(pdata); 335 336 switch (pdata->an_mode) { 337 case AXGBE_AN_MODE_CL73: 338 case AXGBE_AN_MODE_CL73_REDRV: 339 axgbe_an73_disable(pdata); 340 break; 341 case AXGBE_AN_MODE_CL37: 342 case AXGBE_AN_MODE_CL37_SGMII: 343 axgbe_an37_disable(pdata); 344 break; 345 default: 346 break; 347 } 348 } 349 350 static void axgbe_an_disable_all(struct axgbe_port *pdata) 351 { 352 axgbe_an73_disable(pdata); 353 axgbe_an37_disable(pdata); 354 } 355 356 static enum axgbe_an axgbe_an73_tx_training(struct axgbe_port *pdata, 357 enum axgbe_rx *state) 358 { 359 unsigned int ad_reg, lp_reg, reg; 360 361 *state = AXGBE_RX_COMPLETE; 362 363 /* If we're not in KR mode then we're done */ 364 if (!axgbe_in_kr_mode(pdata)) 365 return AXGBE_AN_PAGE_RECEIVED; 366 367 /* Enable/Disable FEC */ 368 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); 369 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2); 370 371 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL); 372 reg &= ~(MDIO_PMA_10GBR_FECABLE_ABLE | MDIO_PMA_10GBR_FECABLE_ERRABLE); 373 if ((ad_reg & 0xc000) && (lp_reg & 0xc000)) 374 reg |= pdata->fec_ability; 375 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL, reg); 376 377 /* Start KR training */ 378 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL); 379 if (reg & AXGBE_KR_TRAINING_ENABLE) { 380 if (pdata->phy_if.phy_impl.kr_training_pre) 381 pdata->phy_if.phy_impl.kr_training_pre(pdata); 382 383 reg |= AXGBE_KR_TRAINING_START; 384 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, 385 reg); 386 387 if (pdata->phy_if.phy_impl.kr_training_post) 388 pdata->phy_if.phy_impl.kr_training_post(pdata); 389 } 390 391 return AXGBE_AN_PAGE_RECEIVED; 392 } 393 394 static enum axgbe_an axgbe_an73_tx_xnp(struct axgbe_port *pdata, 395 enum axgbe_rx *state) 396 { 397 u16 msg; 398 399 *state = AXGBE_RX_XNP; 400 401 msg = AXGBE_XNP_MCF_NULL_MESSAGE; 402 msg |= AXGBE_XNP_MP_FORMATTED; 403 404 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 2, 0); 405 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 1, 0); 406 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP, msg); 407 408 return AXGBE_AN_PAGE_RECEIVED; 409 } 410 411 static enum axgbe_an axgbe_an73_rx_bpa(struct axgbe_port *pdata, 412 enum axgbe_rx *state) 413 { 414 unsigned int link_support; 415 unsigned int reg, ad_reg, lp_reg; 416 417 /* Read Base Ability register 2 first */ 418 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1); 419 420 /* Check for a supported mode, otherwise restart in a different one */ 421 link_support = axgbe_in_kr_mode(pdata) ? 0x80 : 0x20; 422 if (!(reg & link_support)) 423 return AXGBE_AN_INCOMPAT_LINK; 424 425 /* Check Extended Next Page support */ 426 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); 427 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA); 428 429 return ((ad_reg & AXGBE_XNP_NP_EXCHANGE) || 430 (lp_reg & AXGBE_XNP_NP_EXCHANGE)) 431 ? axgbe_an73_tx_xnp(pdata, state) 432 : axgbe_an73_tx_training(pdata, state); 433 } 434 435 static enum axgbe_an axgbe_an73_rx_xnp(struct axgbe_port *pdata, 436 enum axgbe_rx *state) 437 { 438 unsigned int ad_reg, lp_reg; 439 440 /* Check Extended Next Page support */ 441 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_XNP); 442 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPX); 443 444 return ((ad_reg & AXGBE_XNP_NP_EXCHANGE) || 445 (lp_reg & AXGBE_XNP_NP_EXCHANGE)) 446 ? axgbe_an73_tx_xnp(pdata, state) 447 : axgbe_an73_tx_training(pdata, state); 448 } 449 450 static enum axgbe_an axgbe_an73_page_received(struct axgbe_port *pdata) 451 { 452 enum axgbe_rx *state; 453 unsigned long an_timeout; 454 enum axgbe_an ret; 455 unsigned long ticks; 456 457 if (!pdata->an_start) { 458 pdata->an_start = rte_get_timer_cycles(); 459 } else { 460 an_timeout = pdata->an_start + 461 msecs_to_timer_cycles(AXGBE_AN_MS_TIMEOUT); 462 ticks = rte_get_timer_cycles(); 463 if (time_after(ticks, an_timeout)) { 464 /* Auto-negotiation timed out, reset state */ 465 pdata->kr_state = AXGBE_RX_BPA; 466 pdata->kx_state = AXGBE_RX_BPA; 467 468 pdata->an_start = rte_get_timer_cycles(); 469 } 470 } 471 472 state = axgbe_in_kr_mode(pdata) ? &pdata->kr_state 473 : &pdata->kx_state; 474 475 switch (*state) { 476 case AXGBE_RX_BPA: 477 ret = axgbe_an73_rx_bpa(pdata, state); 478 break; 479 case AXGBE_RX_XNP: 480 ret = axgbe_an73_rx_xnp(pdata, state); 481 break; 482 default: 483 ret = AXGBE_AN_ERROR; 484 } 485 486 return ret; 487 } 488 489 static enum axgbe_an axgbe_an73_incompat_link(struct axgbe_port *pdata) 490 { 491 /* Be sure we aren't looping trying to negotiate */ 492 if (axgbe_in_kr_mode(pdata)) { 493 pdata->kr_state = AXGBE_RX_ERROR; 494 495 if (!(pdata->phy.advertising & ADVERTISED_1000baseKX_Full) && 496 !(pdata->phy.advertising & ADVERTISED_2500baseX_Full)) 497 return AXGBE_AN_NO_LINK; 498 499 if (pdata->kx_state != AXGBE_RX_BPA) 500 return AXGBE_AN_NO_LINK; 501 } else { 502 pdata->kx_state = AXGBE_RX_ERROR; 503 504 if (!(pdata->phy.advertising & ADVERTISED_10000baseKR_Full)) 505 return AXGBE_AN_NO_LINK; 506 507 if (pdata->kr_state != AXGBE_RX_BPA) 508 return AXGBE_AN_NO_LINK; 509 } 510 511 axgbe_an_disable(pdata); 512 axgbe_switch_mode(pdata); 513 axgbe_an_restart(pdata); 514 515 return AXGBE_AN_INCOMPAT_LINK; 516 } 517 518 static void axgbe_an73_state_machine(struct axgbe_port *pdata) 519 { 520 enum axgbe_an cur_state = pdata->an_state; 521 522 if (!pdata->an_int) 523 return; 524 525 next_int: 526 if (pdata->an_int & AXGBE_AN_CL73_PG_RCV) { 527 pdata->an_state = AXGBE_AN_PAGE_RECEIVED; 528 pdata->an_int &= ~AXGBE_AN_CL73_PG_RCV; 529 } else if (pdata->an_int & AXGBE_AN_CL73_INC_LINK) { 530 pdata->an_state = AXGBE_AN_INCOMPAT_LINK; 531 pdata->an_int &= ~AXGBE_AN_CL73_INC_LINK; 532 } else if (pdata->an_int & AXGBE_AN_CL73_INT_CMPLT) { 533 pdata->an_state = AXGBE_AN_COMPLETE; 534 pdata->an_int &= ~AXGBE_AN_CL73_INT_CMPLT; 535 } else { 536 pdata->an_state = AXGBE_AN_ERROR; 537 } 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 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 586 if (cur_state != pdata->an_state) 587 goto again; 588 589 if (pdata->an_int) 590 goto next_int; 591 592 axgbe_an73_enable_interrupts(pdata); 593 } 594 595 static void axgbe_an37_state_machine(struct axgbe_port *pdata) 596 { 597 enum axgbe_an cur_state = pdata->an_state; 598 599 if (!pdata->an_int) 600 return; 601 if (pdata->an_int & AXGBE_AN_CL37_INT_CMPLT) { 602 pdata->an_state = AXGBE_AN_COMPLETE; 603 pdata->an_int &= ~AXGBE_AN_CL37_INT_CMPLT; 604 605 /* If SGMII is enabled, check the link status */ 606 if (pdata->an_mode == AXGBE_AN_MODE_CL37_SGMII && 607 !(pdata->an_status & AXGBE_SGMII_AN_LINK_STATUS)) 608 pdata->an_state = AXGBE_AN_NO_LINK; 609 } 610 611 cur_state = pdata->an_state; 612 613 switch (pdata->an_state) { 614 case AXGBE_AN_READY: 615 break; 616 case AXGBE_AN_COMPLETE: 617 break; 618 case AXGBE_AN_NO_LINK: 619 break; 620 default: 621 pdata->an_state = AXGBE_AN_ERROR; 622 break; 623 } 624 625 if (pdata->an_state == AXGBE_AN_ERROR) { 626 PMD_DRV_LOG(ERR, "error during auto-negotiation, state=%u\n", 627 cur_state); 628 pdata->an_int = 0; 629 axgbe_an37_clear_interrupts(pdata); 630 } 631 632 if (pdata->an_state >= AXGBE_AN_COMPLETE) { 633 pdata->an_result = pdata->an_state; 634 pdata->an_state = AXGBE_AN_READY; 635 if (pdata->phy_if.phy_impl.an_post) 636 pdata->phy_if.phy_impl.an_post(pdata); 637 } 638 639 axgbe_an37_enable_interrupts(pdata); 640 } 641 642 static void axgbe_an73_isr(struct axgbe_port *pdata) 643 { 644 /* Disable AN interrupts */ 645 axgbe_an73_disable_interrupts(pdata); 646 647 /* Save the interrupt(s) that fired */ 648 pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT); 649 axgbe_an73_clear_interrupts(pdata); 650 651 if (pdata->an_int) { 652 /* Clear the interrupt(s) that fired and process them */ 653 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, ~pdata->an_int); 654 pthread_mutex_lock(&pdata->an_mutex); 655 axgbe_an73_state_machine(pdata); 656 pthread_mutex_unlock(&pdata->an_mutex); 657 } else { 658 /* Enable AN interrupts */ 659 axgbe_an73_enable_interrupts(pdata); 660 } 661 } 662 663 static void axgbe_an37_isr(struct axgbe_port *pdata) 664 { 665 unsigned int reg = 0; 666 /* Disable AN interrupts */ 667 axgbe_an37_disable_interrupts(pdata); 668 669 /* Save the interrupt(s) that fired */ 670 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT); 671 pdata->an_int = reg & AXGBE_AN_CL37_INT_MASK; 672 pdata->an_status = reg & ~AXGBE_AN_CL37_INT_MASK; 673 axgbe_an37_clear_interrupts(pdata); 674 675 if (pdata->an_int & 0x01) { 676 /* Clear the interrupt(s) that fired and process them */ 677 reg &= ~AXGBE_AN_CL37_INT_MASK; 678 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg); 679 axgbe_an37_state_machine(pdata); 680 } else { 681 /* Enable AN interrupts */ 682 axgbe_an37_enable_interrupts(pdata); 683 } 684 } 685 686 static void axgbe_an_isr(struct axgbe_port *pdata) 687 { 688 switch (pdata->an_mode) { 689 case AXGBE_AN_MODE_CL73: 690 case AXGBE_AN_MODE_CL73_REDRV: 691 axgbe_an73_isr(pdata); 692 break; 693 case AXGBE_AN_MODE_CL37: 694 case AXGBE_AN_MODE_CL37_SGMII: 695 axgbe_an37_isr(pdata); 696 break; 697 default: 698 break; 699 } 700 } 701 702 static void axgbe_an_combined_isr(struct axgbe_port *pdata) 703 { 704 axgbe_an_isr(pdata); 705 } 706 707 static void axgbe_an37_init(struct axgbe_port *pdata) 708 { 709 unsigned int advertising; 710 unsigned int reg = 0; 711 712 advertising = pdata->phy_if.phy_impl.an_advertising(pdata); 713 714 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE); 715 if (advertising & ADVERTISED_Pause) 716 reg |= 0x100; 717 else 718 reg &= ~0x100; 719 if (advertising & ADVERTISED_Asym_Pause) 720 reg |= 0x80; 721 else 722 reg &= ~0x80; 723 724 /* Full duplex, but not half */ 725 reg |= AXGBE_AN_CL37_FD_MASK; 726 reg &= ~AXGBE_AN_CL37_HD_MASK; 727 728 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE, reg); 729 730 /* Set up the Control register */ 731 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL); 732 reg &= ~AXGBE_AN_CL37_TX_CONFIG_MASK; 733 reg &= ~AXGBE_AN_CL37_PCS_MODE_MASK; 734 735 switch (pdata->an_mode) { 736 case AXGBE_AN_MODE_CL37: 737 reg |= AXGBE_AN_CL37_PCS_MODE_BASEX; 738 break; 739 case AXGBE_AN_MODE_CL37_SGMII: 740 reg |= AXGBE_AN_CL37_PCS_MODE_SGMII; 741 break; 742 default: 743 break; 744 } 745 reg |= AXGBE_AN_CL37_MII_CTRL_8BIT; 746 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg); 747 } 748 749 static void axgbe_an73_init(struct axgbe_port *pdata) 750 { 751 unsigned int advertising, reg; 752 753 advertising = pdata->phy_if.phy_impl.an_advertising(pdata); 754 755 /* Set up Advertisement register 3 first */ 756 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); 757 if (advertising & ADVERTISED_10000baseR_FEC) 758 reg |= 0xc000; 759 else 760 reg &= ~0xc000; 761 762 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, reg); 763 764 /* Set up Advertisement register 2 next */ 765 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); 766 if (advertising & ADVERTISED_10000baseKR_Full) 767 reg |= 0x80; 768 else 769 reg &= ~0x80; 770 771 if ((advertising & ADVERTISED_1000baseKX_Full) || 772 (advertising & ADVERTISED_2500baseX_Full)) 773 reg |= 0x20; 774 else 775 reg &= ~0x20; 776 777 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, reg); 778 779 /* Set up Advertisement register 1 last */ 780 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); 781 if (advertising & ADVERTISED_Pause) 782 reg |= 0x400; 783 else 784 reg &= ~0x400; 785 786 if (advertising & ADVERTISED_Asym_Pause) 787 reg |= 0x800; 788 else 789 reg &= ~0x800; 790 791 /* We don't intend to perform XNP */ 792 reg &= ~AXGBE_XNP_NP_EXCHANGE; 793 794 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); 795 } 796 797 static void axgbe_an_init(struct axgbe_port *pdata) 798 { 799 /* Set up advertisement registers based on current settings */ 800 pdata->an_mode = pdata->phy_if.phy_impl.an_mode(pdata); 801 switch (pdata->an_mode) { 802 case AXGBE_AN_MODE_CL73: 803 case AXGBE_AN_MODE_CL73_REDRV: 804 axgbe_an73_init(pdata); 805 break; 806 case AXGBE_AN_MODE_CL37: 807 case AXGBE_AN_MODE_CL37_SGMII: 808 axgbe_an37_init(pdata); 809 break; 810 default: 811 break; 812 } 813 } 814 815 static void axgbe_phy_adjust_link(struct axgbe_port *pdata) 816 { 817 if (pdata->phy.link) { 818 /* Flow control support */ 819 pdata->pause_autoneg = pdata->phy.pause_autoneg; 820 821 if (pdata->tx_pause != (unsigned int)pdata->phy.tx_pause) { 822 pdata->hw_if.config_tx_flow_control(pdata); 823 pdata->tx_pause = pdata->phy.tx_pause; 824 } 825 826 if (pdata->rx_pause != (unsigned int)pdata->phy.rx_pause) { 827 pdata->hw_if.config_rx_flow_control(pdata); 828 pdata->rx_pause = pdata->phy.rx_pause; 829 } 830 831 /* Speed support */ 832 if (pdata->phy_speed != pdata->phy.speed) 833 pdata->phy_speed = pdata->phy.speed; 834 if (pdata->phy_link != pdata->phy.link) 835 pdata->phy_link = pdata->phy.link; 836 } else if (pdata->phy_link) { 837 pdata->phy_link = 0; 838 pdata->phy_speed = SPEED_UNKNOWN; 839 } 840 } 841 842 static int axgbe_phy_config_fixed(struct axgbe_port *pdata) 843 { 844 enum axgbe_mode mode; 845 846 /* Disable auto-negotiation */ 847 axgbe_an_disable(pdata); 848 849 /* Set specified mode for specified speed */ 850 mode = pdata->phy_if.phy_impl.get_mode(pdata, pdata->phy.speed); 851 switch (mode) { 852 case AXGBE_MODE_KX_1000: 853 case AXGBE_MODE_KX_2500: 854 case AXGBE_MODE_KR: 855 case AXGBE_MODE_SGMII_100: 856 case AXGBE_MODE_SGMII_1000: 857 case AXGBE_MODE_X: 858 case AXGBE_MODE_SFI: 859 break; 860 case AXGBE_MODE_UNKNOWN: 861 default: 862 return -EINVAL; 863 } 864 865 /* Validate duplex mode */ 866 if (pdata->phy.duplex != DUPLEX_FULL) 867 return -EINVAL; 868 869 axgbe_set_mode(pdata, mode); 870 871 return 0; 872 } 873 874 static int __axgbe_phy_config_aneg(struct axgbe_port *pdata) 875 { 876 int ret; 877 878 axgbe_set_bit(AXGBE_LINK_INIT, &pdata->dev_state); 879 pdata->link_check = rte_get_timer_cycles(); 880 881 ret = pdata->phy_if.phy_impl.an_config(pdata); 882 if (ret) 883 return ret; 884 885 if (pdata->phy.autoneg != AUTONEG_ENABLE) { 886 ret = axgbe_phy_config_fixed(pdata); 887 if (ret || !pdata->kr_redrv) 888 return ret; 889 } 890 891 /* Disable auto-negotiation interrupt */ 892 rte_intr_disable(&pdata->pci_dev->intr_handle); 893 894 /* Start auto-negotiation in a supported mode */ 895 if (axgbe_use_mode(pdata, AXGBE_MODE_KR)) { 896 axgbe_set_mode(pdata, AXGBE_MODE_KR); 897 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_2500)) { 898 axgbe_set_mode(pdata, AXGBE_MODE_KX_2500); 899 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_1000)) { 900 axgbe_set_mode(pdata, AXGBE_MODE_KX_1000); 901 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SFI)) { 902 axgbe_set_mode(pdata, AXGBE_MODE_SFI); 903 } else if (axgbe_use_mode(pdata, AXGBE_MODE_X)) { 904 axgbe_set_mode(pdata, AXGBE_MODE_X); 905 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_1000)) { 906 axgbe_set_mode(pdata, AXGBE_MODE_SGMII_1000); 907 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_100)) { 908 axgbe_set_mode(pdata, AXGBE_MODE_SGMII_100); 909 } else { 910 rte_intr_enable(&pdata->pci_dev->intr_handle); 911 return -EINVAL; 912 } 913 914 /* Disable and stop any in progress auto-negotiation */ 915 axgbe_an_disable_all(pdata); 916 917 pdata->an_result = AXGBE_AN_READY; 918 pdata->an_state = AXGBE_AN_READY; 919 pdata->kr_state = AXGBE_RX_BPA; 920 pdata->kx_state = AXGBE_RX_BPA; 921 922 /* Re-enable auto-negotiation interrupt */ 923 rte_intr_enable(&pdata->pci_dev->intr_handle); 924 axgbe_an37_enable_interrupts(pdata); 925 926 axgbe_an_init(pdata); 927 axgbe_an_restart(pdata); 928 929 return 0; 930 } 931 932 static int axgbe_phy_config_aneg(struct axgbe_port *pdata) 933 { 934 int ret; 935 936 pthread_mutex_lock(&pdata->an_mutex); 937 938 ret = __axgbe_phy_config_aneg(pdata); 939 if (ret) 940 axgbe_set_bit(AXGBE_LINK_ERR, &pdata->dev_state); 941 else 942 axgbe_clear_bit(AXGBE_LINK_ERR, &pdata->dev_state); 943 944 pthread_mutex_unlock(&pdata->an_mutex); 945 946 return ret; 947 } 948 949 static bool axgbe_phy_aneg_done(struct axgbe_port *pdata) 950 { 951 return pdata->an_result == AXGBE_AN_COMPLETE; 952 } 953 954 static void axgbe_check_link_timeout(struct axgbe_port *pdata) 955 { 956 unsigned long link_timeout; 957 unsigned long ticks; 958 959 link_timeout = pdata->link_check + (AXGBE_LINK_TIMEOUT * 960 2 * rte_get_timer_hz()); 961 ticks = rte_get_timer_cycles(); 962 if (time_after(ticks, link_timeout)) 963 axgbe_phy_config_aneg(pdata); 964 } 965 966 static enum axgbe_mode axgbe_phy_status_aneg(struct axgbe_port *pdata) 967 { 968 return pdata->phy_if.phy_impl.an_outcome(pdata); 969 } 970 971 static void axgbe_phy_status_result(struct axgbe_port *pdata) 972 { 973 enum axgbe_mode mode; 974 975 pdata->phy.lp_advertising = 0; 976 977 if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect) 978 mode = axgbe_cur_mode(pdata); 979 else 980 mode = axgbe_phy_status_aneg(pdata); 981 982 switch (mode) { 983 case AXGBE_MODE_SGMII_100: 984 pdata->phy.speed = SPEED_100; 985 break; 986 case AXGBE_MODE_X: 987 case AXGBE_MODE_KX_1000: 988 case AXGBE_MODE_SGMII_1000: 989 pdata->phy.speed = SPEED_1000; 990 break; 991 case AXGBE_MODE_KX_2500: 992 pdata->phy.speed = SPEED_2500; 993 break; 994 case AXGBE_MODE_KR: 995 case AXGBE_MODE_SFI: 996 pdata->phy.speed = SPEED_10000; 997 break; 998 case AXGBE_MODE_UNKNOWN: 999 default: 1000 pdata->phy.speed = SPEED_UNKNOWN; 1001 } 1002 1003 pdata->phy.duplex = DUPLEX_FULL; 1004 1005 axgbe_set_mode(pdata, mode); 1006 } 1007 1008 static int autoneg_time_out(unsigned long autoneg_start_time) 1009 { 1010 unsigned long autoneg_timeout; 1011 unsigned long ticks; 1012 1013 autoneg_timeout = autoneg_start_time + (AXGBE_LINK_TIMEOUT * 1014 2 * rte_get_timer_hz()); 1015 ticks = rte_get_timer_cycles(); 1016 if (time_after(ticks, autoneg_timeout)) 1017 return 1; 1018 else 1019 return 0; 1020 } 1021 1022 static void axgbe_phy_status(struct axgbe_port *pdata) 1023 { 1024 unsigned int link_aneg; 1025 int an_restart, ret; 1026 unsigned int reg = 0; 1027 unsigned long autoneg_start_time; 1028 1029 if (axgbe_test_bit(AXGBE_LINK_ERR, &pdata->dev_state)) { 1030 pdata->phy.link = 0; 1031 goto adjust_link; 1032 } 1033 1034 link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE); 1035 1036 pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata, 1037 &an_restart); 1038 if (an_restart) { 1039 axgbe_phy_config_aneg(pdata); 1040 return; 1041 } 1042 1043 if (pdata->phy.link) { 1044 if (link_aneg && !axgbe_phy_aneg_done(pdata)) { 1045 if (axgbe_cur_mode(pdata) == AXGBE_MODE_SGMII_1000) { 1046 /* autoneg not complete, so re-initializing */ 1047 /* and restarting it */ 1048 axgbe_an_init(pdata); 1049 axgbe_an_restart(pdata); 1050 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, 1051 MDIO_VEND2_AN_STAT); 1052 autoneg_start_time = rte_get_timer_cycles(); 1053 /* poll for autoneg to complete */ 1054 while (!(reg & AXGBE_AN_CL37_INT_CMPLT)) { 1055 ret = 1056 autoneg_time_out(autoneg_start_time); 1057 if (ret) 1058 break; 1059 reg = XMDIO_READ(pdata, 1060 MDIO_MMD_VEND2, 1061 MDIO_VEND2_AN_STAT); 1062 if (reg & AXGBE_AN_CL37_INT_CMPLT) { 1063 axgbe_an37_isr(pdata); 1064 break; 1065 } 1066 } 1067 } else { 1068 axgbe_check_link_timeout(pdata); 1069 return; 1070 } 1071 } 1072 axgbe_phy_status_result(pdata); 1073 if (axgbe_test_bit(AXGBE_LINK_INIT, &pdata->dev_state)) 1074 axgbe_clear_bit(AXGBE_LINK_INIT, &pdata->dev_state); 1075 } else { 1076 if (axgbe_test_bit(AXGBE_LINK_INIT, &pdata->dev_state)) { 1077 axgbe_check_link_timeout(pdata); 1078 1079 if (link_aneg) 1080 return; 1081 } 1082 axgbe_phy_status_result(pdata); 1083 } 1084 1085 adjust_link: 1086 axgbe_phy_adjust_link(pdata); 1087 } 1088 1089 static void axgbe_phy_stop(struct axgbe_port *pdata) 1090 { 1091 if (!pdata->phy_started) 1092 return; 1093 /* Indicate the PHY is down */ 1094 pdata->phy_started = 0; 1095 /* Disable auto-negotiation */ 1096 axgbe_an_disable_all(pdata); 1097 pdata->phy_if.phy_impl.stop(pdata); 1098 pdata->phy.link = 0; 1099 axgbe_phy_adjust_link(pdata); 1100 } 1101 1102 static int axgbe_phy_start(struct axgbe_port *pdata) 1103 { 1104 int ret; 1105 1106 ret = pdata->phy_if.phy_impl.start(pdata); 1107 if (ret) 1108 return ret; 1109 /* Set initial mode - call the mode setting routines 1110 * directly to insure we are properly configured 1111 */ 1112 if (axgbe_use_mode(pdata, AXGBE_MODE_KR)) { 1113 axgbe_kr_mode(pdata); 1114 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_2500)) { 1115 axgbe_kx_2500_mode(pdata); 1116 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_1000)) { 1117 axgbe_kx_1000_mode(pdata); 1118 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SFI)) { 1119 axgbe_sfi_mode(pdata); 1120 } else if (axgbe_use_mode(pdata, AXGBE_MODE_X)) { 1121 axgbe_x_mode(pdata); 1122 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_1000)) { 1123 axgbe_sgmii_1000_mode(pdata); 1124 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_100)) { 1125 axgbe_sgmii_100_mode(pdata); 1126 } else { 1127 ret = -EINVAL; 1128 goto err_stop; 1129 } 1130 /* Indicate the PHY is up and running */ 1131 pdata->phy_started = 1; 1132 axgbe_an_init(pdata); 1133 axgbe_an_enable_interrupts(pdata); 1134 return axgbe_phy_config_aneg(pdata); 1135 1136 err_stop: 1137 pdata->phy_if.phy_impl.stop(pdata); 1138 1139 return ret; 1140 } 1141 1142 static int axgbe_phy_reset(struct axgbe_port *pdata) 1143 { 1144 int ret; 1145 1146 ret = pdata->phy_if.phy_impl.reset(pdata); 1147 if (ret) 1148 return ret; 1149 1150 /* Disable auto-negotiation for now */ 1151 axgbe_an_disable_all(pdata); 1152 1153 /* Clear auto-negotiation interrupts */ 1154 axgbe_an_clear_interrupts_all(pdata); 1155 1156 return 0; 1157 } 1158 1159 static int axgbe_phy_best_advertised_speed(struct axgbe_port *pdata) 1160 { 1161 if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full) 1162 return SPEED_10000; 1163 else if (pdata->phy.advertising & ADVERTISED_10000baseT_Full) 1164 return SPEED_10000; 1165 else if (pdata->phy.advertising & ADVERTISED_2500baseX_Full) 1166 return SPEED_2500; 1167 else if (pdata->phy.advertising & ADVERTISED_1000baseKX_Full) 1168 return SPEED_1000; 1169 else if (pdata->phy.advertising & ADVERTISED_1000baseT_Full) 1170 return SPEED_1000; 1171 else if (pdata->phy.advertising & ADVERTISED_100baseT_Full) 1172 return SPEED_100; 1173 1174 return SPEED_UNKNOWN; 1175 } 1176 1177 static int axgbe_phy_init(struct axgbe_port *pdata) 1178 { 1179 int ret; 1180 1181 pdata->mdio_mmd = MDIO_MMD_PCS; 1182 1183 /* Check for FEC support */ 1184 pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, 1185 MDIO_PMA_10GBR_FECABLE); 1186 pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE | 1187 MDIO_PMA_10GBR_FECABLE_ERRABLE); 1188 1189 /* Setup the phy (including supported features) */ 1190 ret = pdata->phy_if.phy_impl.init(pdata); 1191 if (ret) 1192 return ret; 1193 pdata->phy.advertising = pdata->phy.supported; 1194 1195 pdata->phy.address = 0; 1196 1197 if (pdata->phy.advertising & ADVERTISED_Autoneg) { 1198 pdata->phy.autoneg = AUTONEG_ENABLE; 1199 pdata->phy.speed = SPEED_UNKNOWN; 1200 pdata->phy.duplex = DUPLEX_UNKNOWN; 1201 } else { 1202 pdata->phy.autoneg = AUTONEG_DISABLE; 1203 pdata->phy.speed = axgbe_phy_best_advertised_speed(pdata); 1204 pdata->phy.duplex = DUPLEX_FULL; 1205 } 1206 1207 pdata->phy.link = 0; 1208 1209 pdata->phy.pause_autoneg = pdata->pause_autoneg; 1210 pdata->phy.tx_pause = pdata->tx_pause; 1211 pdata->phy.rx_pause = pdata->rx_pause; 1212 1213 /* Fix up Flow Control advertising */ 1214 pdata->phy.advertising &= ~ADVERTISED_Pause; 1215 pdata->phy.advertising &= ~ADVERTISED_Asym_Pause; 1216 1217 if (pdata->rx_pause) { 1218 pdata->phy.advertising |= ADVERTISED_Pause; 1219 pdata->phy.advertising |= ADVERTISED_Asym_Pause; 1220 } 1221 1222 if (pdata->tx_pause) 1223 pdata->phy.advertising ^= ADVERTISED_Asym_Pause; 1224 return 0; 1225 } 1226 1227 void axgbe_init_function_ptrs_phy(struct axgbe_phy_if *phy_if) 1228 { 1229 phy_if->phy_init = axgbe_phy_init; 1230 phy_if->phy_reset = axgbe_phy_reset; 1231 phy_if->phy_start = axgbe_phy_start; 1232 phy_if->phy_stop = axgbe_phy_stop; 1233 phy_if->phy_status = axgbe_phy_status; 1234 phy_if->phy_config_aneg = axgbe_phy_config_aneg; 1235 phy_if->an_isr = axgbe_an_combined_isr; 1236 } 1237