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.
6 #include "axgbe_ethdev.h"
7 #include "axgbe_common.h"
10 static void axgbe_an37_clear_interrupts(struct axgbe_port *pdata)
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);
19 static void axgbe_an37_disable_interrupts(struct axgbe_port *pdata)
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);
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);
32 static void axgbe_an73_clear_interrupts(struct axgbe_port *pdata)
34 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
37 static void axgbe_an73_disable_interrupts(struct axgbe_port *pdata)
39 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);
42 static void axgbe_an73_enable_interrupts(struct axgbe_port *pdata)
44 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK,
45 AXGBE_AN_CL73_INT_MASK);
48 static void axgbe_an_enable_interrupts(struct axgbe_port *pdata)
50 switch (pdata->an_mode) {
51 case AXGBE_AN_MODE_CL73:
52 case AXGBE_AN_MODE_CL73_REDRV:
53 axgbe_an73_enable_interrupts(pdata);
55 case AXGBE_AN_MODE_CL37:
56 case AXGBE_AN_MODE_CL37_SGMII:
57 PMD_DRV_LOG(ERR, "Unsupported AN_MOD_37\n");
64 static void axgbe_an_clear_interrupts_all(struct axgbe_port *pdata)
66 axgbe_an73_clear_interrupts(pdata);
67 axgbe_an37_clear_interrupts(pdata);
70 static void axgbe_an73_enable_kr_training(struct axgbe_port *pdata)
74 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
76 reg |= AXGBE_KR_TRAINING_ENABLE;
77 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
80 static void axgbe_an73_disable_kr_training(struct axgbe_port *pdata)
84 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
86 reg &= ~AXGBE_KR_TRAINING_ENABLE;
87 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
90 static void axgbe_kr_mode(struct axgbe_port *pdata)
92 /* Enable KR training */
93 axgbe_an73_enable_kr_training(pdata);
95 /* Set MAC to 10G speed */
96 pdata->hw_if.set_speed(pdata, SPEED_10000);
98 /* Call PHY implementation support to complete rate change */
99 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_KR);
102 static void axgbe_kx_2500_mode(struct axgbe_port *pdata)
104 /* Disable KR training */
105 axgbe_an73_disable_kr_training(pdata);
107 /* Set MAC to 2.5G speed */
108 pdata->hw_if.set_speed(pdata, SPEED_2500);
110 /* Call PHY implementation support to complete rate change */
111 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_KX_2500);
114 static void axgbe_kx_1000_mode(struct axgbe_port *pdata)
116 /* Disable KR training */
117 axgbe_an73_disable_kr_training(pdata);
119 /* Set MAC to 1G speed */
120 pdata->hw_if.set_speed(pdata, SPEED_1000);
122 /* Call PHY implementation support to complete rate change */
123 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_KX_1000);
126 static void axgbe_sfi_mode(struct axgbe_port *pdata)
128 /* If a KR re-driver is present, change to KR mode instead */
130 return axgbe_kr_mode(pdata);
132 /* Disable KR training */
133 axgbe_an73_disable_kr_training(pdata);
135 /* Set MAC to 10G speed */
136 pdata->hw_if.set_speed(pdata, SPEED_10000);
138 /* Call PHY implementation support to complete rate change */
139 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SFI);
142 static void axgbe_x_mode(struct axgbe_port *pdata)
144 /* Disable KR training */
145 axgbe_an73_disable_kr_training(pdata);
147 /* Set MAC to 1G speed */
148 pdata->hw_if.set_speed(pdata, SPEED_1000);
150 /* Call PHY implementation support to complete rate change */
151 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_X);
154 static void axgbe_sgmii_1000_mode(struct axgbe_port *pdata)
156 /* Disable KR training */
157 axgbe_an73_disable_kr_training(pdata);
159 /* Set MAC to 1G speed */
160 pdata->hw_if.set_speed(pdata, SPEED_1000);
162 /* Call PHY implementation support to complete rate change */
163 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SGMII_1000);
166 static void axgbe_sgmii_100_mode(struct axgbe_port *pdata)
168 /* Disable KR training */
169 axgbe_an73_disable_kr_training(pdata);
171 /* Set MAC to 1G speed */
172 pdata->hw_if.set_speed(pdata, SPEED_1000);
174 /* Call PHY implementation support to complete rate change */
175 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SGMII_100);
178 static enum axgbe_mode axgbe_cur_mode(struct axgbe_port *pdata)
180 return pdata->phy_if.phy_impl.cur_mode(pdata);
183 static bool axgbe_in_kr_mode(struct axgbe_port *pdata)
185 return axgbe_cur_mode(pdata) == AXGBE_MODE_KR;
188 static void axgbe_change_mode(struct axgbe_port *pdata,
189 enum axgbe_mode mode)
192 case AXGBE_MODE_KX_1000:
193 axgbe_kx_1000_mode(pdata);
195 case AXGBE_MODE_KX_2500:
196 axgbe_kx_2500_mode(pdata);
199 axgbe_kr_mode(pdata);
201 case AXGBE_MODE_SGMII_100:
202 axgbe_sgmii_100_mode(pdata);
204 case AXGBE_MODE_SGMII_1000:
205 axgbe_sgmii_1000_mode(pdata);
211 axgbe_sfi_mode(pdata);
213 case AXGBE_MODE_UNKNOWN:
216 PMD_DRV_LOG(ERR, "invalid operation mode requested (%u)\n", mode);
220 static void axgbe_switch_mode(struct axgbe_port *pdata)
222 axgbe_change_mode(pdata, pdata->phy_if.phy_impl.switch_mode(pdata));
225 static void axgbe_set_mode(struct axgbe_port *pdata,
226 enum axgbe_mode mode)
228 if (mode == axgbe_cur_mode(pdata))
231 axgbe_change_mode(pdata, mode);
234 static bool axgbe_use_mode(struct axgbe_port *pdata,
235 enum axgbe_mode mode)
237 return pdata->phy_if.phy_impl.use_mode(pdata, mode);
240 static void axgbe_an37_set(struct axgbe_port *pdata, bool enable,
245 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_CTRL1);
246 reg &= ~MDIO_VEND2_CTRL1_AN_ENABLE;
249 reg |= MDIO_VEND2_CTRL1_AN_ENABLE;
252 reg |= MDIO_VEND2_CTRL1_AN_RESTART;
254 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_CTRL1, reg);
257 static void axgbe_an37_disable(struct axgbe_port *pdata)
259 axgbe_an37_set(pdata, false, false);
260 axgbe_an37_disable_interrupts(pdata);
263 static void axgbe_an73_set(struct axgbe_port *pdata, bool enable,
268 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1);
269 reg &= ~MDIO_AN_CTRL1_ENABLE;
272 reg |= MDIO_AN_CTRL1_ENABLE;
275 reg |= MDIO_AN_CTRL1_RESTART;
277 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg);
280 static void axgbe_an73_restart(struct axgbe_port *pdata)
282 axgbe_an73_enable_interrupts(pdata);
283 axgbe_an73_set(pdata, true, true);
286 static void axgbe_an73_disable(struct axgbe_port *pdata)
288 axgbe_an73_set(pdata, false, false);
289 axgbe_an73_disable_interrupts(pdata);
292 static void axgbe_an_restart(struct axgbe_port *pdata)
294 switch (pdata->an_mode) {
295 case AXGBE_AN_MODE_CL73:
296 case AXGBE_AN_MODE_CL73_REDRV:
297 axgbe_an73_restart(pdata);
299 case AXGBE_AN_MODE_CL37:
300 case AXGBE_AN_MODE_CL37_SGMII:
301 PMD_DRV_LOG(ERR, "Unsupported AN_MODE_CL37\n");
308 static void axgbe_an_disable(struct axgbe_port *pdata)
310 switch (pdata->an_mode) {
311 case AXGBE_AN_MODE_CL73:
312 case AXGBE_AN_MODE_CL73_REDRV:
313 axgbe_an73_disable(pdata);
315 case AXGBE_AN_MODE_CL37:
316 case AXGBE_AN_MODE_CL37_SGMII:
317 PMD_DRV_LOG(ERR, "Unsupported AN_MODE_CL37\n");
324 static void axgbe_an_disable_all(struct axgbe_port *pdata)
326 axgbe_an73_disable(pdata);
327 axgbe_an37_disable(pdata);
330 static enum axgbe_an axgbe_an73_tx_training(struct axgbe_port *pdata,
331 enum axgbe_rx *state)
333 unsigned int ad_reg, lp_reg, reg;
335 *state = AXGBE_RX_COMPLETE;
337 /* If we're not in KR mode then we're done */
338 if (!axgbe_in_kr_mode(pdata))
339 return AXGBE_AN_PAGE_RECEIVED;
341 /* Enable/Disable FEC */
342 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
343 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
345 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL);
346 reg &= ~(MDIO_PMA_10GBR_FECABLE_ABLE | MDIO_PMA_10GBR_FECABLE_ERRABLE);
347 if ((ad_reg & 0xc000) && (lp_reg & 0xc000))
348 reg |= pdata->fec_ability;
349 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL, reg);
351 /* Start KR training */
352 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
353 if (reg & AXGBE_KR_TRAINING_ENABLE) {
354 if (pdata->phy_if.phy_impl.kr_training_pre)
355 pdata->phy_if.phy_impl.kr_training_pre(pdata);
357 reg |= AXGBE_KR_TRAINING_START;
358 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL,
361 if (pdata->phy_if.phy_impl.kr_training_post)
362 pdata->phy_if.phy_impl.kr_training_post(pdata);
365 return AXGBE_AN_PAGE_RECEIVED;
368 static enum axgbe_an axgbe_an73_tx_xnp(struct axgbe_port *pdata,
369 enum axgbe_rx *state)
373 *state = AXGBE_RX_XNP;
375 msg = AXGBE_XNP_MCF_NULL_MESSAGE;
376 msg |= AXGBE_XNP_MP_FORMATTED;
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);
382 return AXGBE_AN_PAGE_RECEIVED;
385 static enum axgbe_an axgbe_an73_rx_bpa(struct axgbe_port *pdata,
386 enum axgbe_rx *state)
388 unsigned int link_support;
389 unsigned int reg, ad_reg, lp_reg;
391 /* Read Base Ability register 2 first */
392 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
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;
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);
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);
409 static enum axgbe_an axgbe_an73_rx_xnp(struct axgbe_port *pdata,
410 enum axgbe_rx *state)
412 unsigned int ad_reg, lp_reg;
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);
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);
424 static enum axgbe_an axgbe_an73_page_received(struct axgbe_port *pdata)
426 enum axgbe_rx *state;
427 unsigned long an_timeout;
431 if (!pdata->an_start) {
432 pdata->an_start = rte_get_timer_cycles();
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;
442 pdata->an_start = rte_get_timer_cycles();
446 state = axgbe_in_kr_mode(pdata) ? &pdata->kr_state
451 ret = axgbe_an73_rx_bpa(pdata, state);
454 ret = axgbe_an73_rx_xnp(pdata, state);
457 ret = AXGBE_AN_ERROR;
463 static enum axgbe_an axgbe_an73_incompat_link(struct axgbe_port *pdata)
465 /* Be sure we aren't looping trying to negotiate */
466 if (axgbe_in_kr_mode(pdata)) {
467 pdata->kr_state = AXGBE_RX_ERROR;
469 if (!(pdata->phy.advertising & ADVERTISED_1000baseKX_Full) &&
470 !(pdata->phy.advertising & ADVERTISED_2500baseX_Full))
471 return AXGBE_AN_NO_LINK;
473 if (pdata->kx_state != AXGBE_RX_BPA)
474 return AXGBE_AN_NO_LINK;
476 pdata->kx_state = AXGBE_RX_ERROR;
478 if (!(pdata->phy.advertising & ADVERTISED_10000baseKR_Full))
479 return AXGBE_AN_NO_LINK;
481 if (pdata->kr_state != AXGBE_RX_BPA)
482 return AXGBE_AN_NO_LINK;
485 axgbe_an73_disable(pdata);
486 axgbe_switch_mode(pdata);
487 axgbe_an73_restart(pdata);
489 return AXGBE_AN_INCOMPAT_LINK;
492 static void axgbe_an73_state_machine(struct axgbe_port *pdata)
494 enum axgbe_an cur_state = pdata->an_state;
500 if (pdata->an_int & AXGBE_AN_CL73_PG_RCV) {
501 pdata->an_state = AXGBE_AN_PAGE_RECEIVED;
502 pdata->an_int &= ~AXGBE_AN_CL73_PG_RCV;
503 } else if (pdata->an_int & AXGBE_AN_CL73_INC_LINK) {
504 pdata->an_state = AXGBE_AN_INCOMPAT_LINK;
505 pdata->an_int &= ~AXGBE_AN_CL73_INC_LINK;
506 } else if (pdata->an_int & AXGBE_AN_CL73_INT_CMPLT) {
507 pdata->an_state = AXGBE_AN_COMPLETE;
508 pdata->an_int &= ~AXGBE_AN_CL73_INT_CMPLT;
510 pdata->an_state = AXGBE_AN_ERROR;
514 cur_state = pdata->an_state;
516 switch (pdata->an_state) {
518 pdata->an_supported = 0;
520 case AXGBE_AN_PAGE_RECEIVED:
521 pdata->an_state = axgbe_an73_page_received(pdata);
522 pdata->an_supported++;
524 case AXGBE_AN_INCOMPAT_LINK:
525 pdata->an_supported = 0;
526 pdata->parallel_detect = 0;
527 pdata->an_state = axgbe_an73_incompat_link(pdata);
529 case AXGBE_AN_COMPLETE:
530 pdata->parallel_detect = pdata->an_supported ? 0 : 1;
532 case AXGBE_AN_NO_LINK:
535 pdata->an_state = AXGBE_AN_ERROR;
538 if (pdata->an_state == AXGBE_AN_NO_LINK) {
540 axgbe_an73_clear_interrupts(pdata);
541 pdata->eth_dev->data->dev_link.link_status =
543 } else if (pdata->an_state == AXGBE_AN_ERROR) {
544 PMD_DRV_LOG(ERR, "error during auto-negotiation, state=%u\n",
547 axgbe_an73_clear_interrupts(pdata);
550 if (pdata->an_state >= AXGBE_AN_COMPLETE) {
551 pdata->an_result = pdata->an_state;
552 pdata->an_state = AXGBE_AN_READY;
553 pdata->kr_state = AXGBE_RX_BPA;
554 pdata->kx_state = AXGBE_RX_BPA;
558 if (cur_state != pdata->an_state)
564 axgbe_an73_enable_interrupts(pdata);
567 static void axgbe_an73_isr(struct axgbe_port *pdata)
569 /* Disable AN interrupts */
570 axgbe_an73_disable_interrupts(pdata);
572 /* Save the interrupt(s) that fired */
573 pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT);
576 /* Clear the interrupt(s) that fired and process them */
577 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, ~pdata->an_int);
578 pthread_mutex_lock(&pdata->an_mutex);
579 axgbe_an73_state_machine(pdata);
580 pthread_mutex_unlock(&pdata->an_mutex);
582 /* Enable AN interrupts */
583 axgbe_an73_enable_interrupts(pdata);
587 static void axgbe_an_isr(struct axgbe_port *pdata)
589 switch (pdata->an_mode) {
590 case AXGBE_AN_MODE_CL73:
591 case AXGBE_AN_MODE_CL73_REDRV:
592 axgbe_an73_isr(pdata);
594 case AXGBE_AN_MODE_CL37:
595 case AXGBE_AN_MODE_CL37_SGMII:
596 PMD_DRV_LOG(ERR, "AN_MODE_37 not supported\n");
603 static void axgbe_an_combined_isr(struct axgbe_port *pdata)
608 static void axgbe_an73_init(struct axgbe_port *pdata)
610 unsigned int advertising, reg;
612 advertising = pdata->phy_if.phy_impl.an_advertising(pdata);
614 /* Set up Advertisement register 3 first */
615 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
616 if (advertising & ADVERTISED_10000baseR_FEC)
621 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, reg);
623 /* Set up Advertisement register 2 next */
624 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
625 if (advertising & ADVERTISED_10000baseKR_Full)
630 if ((advertising & ADVERTISED_1000baseKX_Full) ||
631 (advertising & ADVERTISED_2500baseX_Full))
636 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, reg);
638 /* Set up Advertisement register 1 last */
639 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
640 if (advertising & ADVERTISED_Pause)
645 if (advertising & ADVERTISED_Asym_Pause)
650 /* We don't intend to perform XNP */
651 reg &= ~AXGBE_XNP_NP_EXCHANGE;
653 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
656 static void axgbe_an_init(struct axgbe_port *pdata)
658 /* Set up advertisement registers based on current settings */
659 pdata->an_mode = pdata->phy_if.phy_impl.an_mode(pdata);
660 switch (pdata->an_mode) {
661 case AXGBE_AN_MODE_CL73:
662 case AXGBE_AN_MODE_CL73_REDRV:
663 axgbe_an73_init(pdata);
665 case AXGBE_AN_MODE_CL37:
666 case AXGBE_AN_MODE_CL37_SGMII:
667 PMD_DRV_LOG(ERR, "Unsupported AN_CL37\n");
674 static void axgbe_phy_adjust_link(struct axgbe_port *pdata)
676 if (pdata->phy.link) {
678 if (pdata->phy_speed != pdata->phy.speed)
679 pdata->phy_speed = pdata->phy.speed;
680 if (pdata->phy_link != pdata->phy.link)
681 pdata->phy_link = pdata->phy.link;
682 } else if (pdata->phy_link) {
684 pdata->phy_speed = SPEED_UNKNOWN;
688 static int axgbe_phy_config_fixed(struct axgbe_port *pdata)
690 enum axgbe_mode mode;
692 /* Disable auto-negotiation */
693 axgbe_an_disable(pdata);
695 /* Set specified mode for specified speed */
696 mode = pdata->phy_if.phy_impl.get_mode(pdata, pdata->phy.speed);
698 case AXGBE_MODE_KX_1000:
699 case AXGBE_MODE_KX_2500:
701 case AXGBE_MODE_SGMII_100:
702 case AXGBE_MODE_SGMII_1000:
706 case AXGBE_MODE_UNKNOWN:
711 /* Validate duplex mode */
712 if (pdata->phy.duplex != DUPLEX_FULL)
715 axgbe_set_mode(pdata, mode);
720 static int __axgbe_phy_config_aneg(struct axgbe_port *pdata)
724 axgbe_set_bit(AXGBE_LINK_INIT, &pdata->dev_state);
725 pdata->link_check = rte_get_timer_cycles();
727 ret = pdata->phy_if.phy_impl.an_config(pdata);
731 if (pdata->phy.autoneg != AUTONEG_ENABLE) {
732 ret = axgbe_phy_config_fixed(pdata);
733 if (ret || !pdata->kr_redrv)
737 /* Disable auto-negotiation interrupt */
738 rte_intr_disable(&pdata->pci_dev->intr_handle);
740 /* Start auto-negotiation in a supported mode */
741 if (axgbe_use_mode(pdata, AXGBE_MODE_KR)) {
742 axgbe_set_mode(pdata, AXGBE_MODE_KR);
743 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_2500)) {
744 axgbe_set_mode(pdata, AXGBE_MODE_KX_2500);
745 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_1000)) {
746 axgbe_set_mode(pdata, AXGBE_MODE_KX_1000);
747 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SFI)) {
748 axgbe_set_mode(pdata, AXGBE_MODE_SFI);
749 } else if (axgbe_use_mode(pdata, AXGBE_MODE_X)) {
750 axgbe_set_mode(pdata, AXGBE_MODE_X);
751 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_1000)) {
752 axgbe_set_mode(pdata, AXGBE_MODE_SGMII_1000);
753 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_100)) {
754 axgbe_set_mode(pdata, AXGBE_MODE_SGMII_100);
756 rte_intr_enable(&pdata->pci_dev->intr_handle);
760 /* Disable and stop any in progress auto-negotiation */
761 axgbe_an_disable_all(pdata);
763 /* Clear any auto-negotitation interrupts */
764 axgbe_an_clear_interrupts_all(pdata);
766 pdata->an_result = AXGBE_AN_READY;
767 pdata->an_state = AXGBE_AN_READY;
768 pdata->kr_state = AXGBE_RX_BPA;
769 pdata->kx_state = AXGBE_RX_BPA;
771 /* Re-enable auto-negotiation interrupt */
772 rte_intr_enable(&pdata->pci_dev->intr_handle);
774 axgbe_an_init(pdata);
775 axgbe_an_restart(pdata);
780 static int axgbe_phy_config_aneg(struct axgbe_port *pdata)
784 pthread_mutex_lock(&pdata->an_mutex);
786 ret = __axgbe_phy_config_aneg(pdata);
788 axgbe_set_bit(AXGBE_LINK_ERR, &pdata->dev_state);
790 axgbe_clear_bit(AXGBE_LINK_ERR, &pdata->dev_state);
792 pthread_mutex_unlock(&pdata->an_mutex);
797 static bool axgbe_phy_aneg_done(struct axgbe_port *pdata)
799 return pdata->an_result == AXGBE_AN_COMPLETE;
802 static void axgbe_check_link_timeout(struct axgbe_port *pdata)
804 unsigned long link_timeout;
807 link_timeout = pdata->link_check + (AXGBE_LINK_TIMEOUT *
808 2 * rte_get_timer_hz());
809 ticks = rte_get_timer_cycles();
810 if (time_after(ticks, link_timeout))
811 axgbe_phy_config_aneg(pdata);
814 static enum axgbe_mode axgbe_phy_status_aneg(struct axgbe_port *pdata)
816 return pdata->phy_if.phy_impl.an_outcome(pdata);
819 static void axgbe_phy_status_result(struct axgbe_port *pdata)
821 enum axgbe_mode mode;
823 pdata->phy.lp_advertising = 0;
825 if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect)
826 mode = axgbe_cur_mode(pdata);
828 mode = axgbe_phy_status_aneg(pdata);
831 case AXGBE_MODE_SGMII_100:
832 pdata->phy.speed = SPEED_100;
835 case AXGBE_MODE_KX_1000:
836 case AXGBE_MODE_SGMII_1000:
837 pdata->phy.speed = SPEED_1000;
839 case AXGBE_MODE_KX_2500:
840 pdata->phy.speed = SPEED_2500;
844 pdata->phy.speed = SPEED_10000;
846 case AXGBE_MODE_UNKNOWN:
848 pdata->phy.speed = SPEED_UNKNOWN;
851 pdata->phy.duplex = DUPLEX_FULL;
853 axgbe_set_mode(pdata, mode);
856 static void axgbe_phy_status(struct axgbe_port *pdata)
858 unsigned int link_aneg;
861 if (axgbe_test_bit(AXGBE_LINK_ERR, &pdata->dev_state)) {
866 link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE);
868 pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata,
871 axgbe_phy_config_aneg(pdata);
875 if (pdata->phy.link) {
876 if (link_aneg && !axgbe_phy_aneg_done(pdata)) {
877 axgbe_check_link_timeout(pdata);
880 axgbe_phy_status_result(pdata);
881 if (axgbe_test_bit(AXGBE_LINK_INIT, &pdata->dev_state))
882 axgbe_clear_bit(AXGBE_LINK_INIT, &pdata->dev_state);
884 if (axgbe_test_bit(AXGBE_LINK_INIT, &pdata->dev_state)) {
885 axgbe_check_link_timeout(pdata);
890 axgbe_phy_status_result(pdata);
894 axgbe_phy_adjust_link(pdata);
897 static void axgbe_phy_stop(struct axgbe_port *pdata)
899 if (!pdata->phy_started)
901 /* Indicate the PHY is down */
902 pdata->phy_started = 0;
903 /* Disable auto-negotiation */
904 axgbe_an_disable_all(pdata);
905 pdata->phy_if.phy_impl.stop(pdata);
907 axgbe_phy_adjust_link(pdata);
910 static int axgbe_phy_start(struct axgbe_port *pdata)
914 ret = pdata->phy_if.phy_impl.start(pdata);
917 /* Set initial mode - call the mode setting routines
918 * directly to insure we are properly configured
920 if (axgbe_use_mode(pdata, AXGBE_MODE_KR)) {
921 axgbe_kr_mode(pdata);
922 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_2500)) {
923 axgbe_kx_2500_mode(pdata);
924 } else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_1000)) {
925 axgbe_kx_1000_mode(pdata);
926 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SFI)) {
927 axgbe_sfi_mode(pdata);
928 } else if (axgbe_use_mode(pdata, AXGBE_MODE_X)) {
930 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_1000)) {
931 axgbe_sgmii_1000_mode(pdata);
932 } else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_100)) {
933 axgbe_sgmii_100_mode(pdata);
938 /* Indicate the PHY is up and running */
939 pdata->phy_started = 1;
940 axgbe_an_init(pdata);
941 axgbe_an_enable_interrupts(pdata);
942 return axgbe_phy_config_aneg(pdata);
945 pdata->phy_if.phy_impl.stop(pdata);
950 static int axgbe_phy_reset(struct axgbe_port *pdata)
954 ret = pdata->phy_if.phy_impl.reset(pdata);
958 /* Disable auto-negotiation for now */
959 axgbe_an_disable_all(pdata);
961 /* Clear auto-negotiation interrupts */
962 axgbe_an_clear_interrupts_all(pdata);
967 static int axgbe_phy_best_advertised_speed(struct axgbe_port *pdata)
969 if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full)
971 else if (pdata->phy.advertising & ADVERTISED_10000baseT_Full)
973 else if (pdata->phy.advertising & ADVERTISED_2500baseX_Full)
975 else if (pdata->phy.advertising & ADVERTISED_1000baseKX_Full)
977 else if (pdata->phy.advertising & ADVERTISED_1000baseT_Full)
979 else if (pdata->phy.advertising & ADVERTISED_100baseT_Full)
982 return SPEED_UNKNOWN;
985 static int axgbe_phy_init(struct axgbe_port *pdata)
989 pdata->mdio_mmd = MDIO_MMD_PCS;
991 /* Check for FEC support */
992 pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD,
993 MDIO_PMA_10GBR_FECABLE);
994 pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE |
995 MDIO_PMA_10GBR_FECABLE_ERRABLE);
997 /* Setup the phy (including supported features) */
998 ret = pdata->phy_if.phy_impl.init(pdata);
1001 pdata->phy.advertising = pdata->phy.supported;
1003 pdata->phy.address = 0;
1005 if (pdata->phy.advertising & ADVERTISED_Autoneg) {
1006 pdata->phy.autoneg = AUTONEG_ENABLE;
1007 pdata->phy.speed = SPEED_UNKNOWN;
1008 pdata->phy.duplex = DUPLEX_UNKNOWN;
1010 pdata->phy.autoneg = AUTONEG_DISABLE;
1011 pdata->phy.speed = axgbe_phy_best_advertised_speed(pdata);
1012 pdata->phy.duplex = DUPLEX_FULL;
1015 pdata->phy.link = 0;
1017 pdata->phy.pause_autoneg = pdata->pause_autoneg;
1018 pdata->phy.tx_pause = pdata->tx_pause;
1019 pdata->phy.rx_pause = pdata->rx_pause;
1021 /* Fix up Flow Control advertising */
1022 pdata->phy.advertising &= ~ADVERTISED_Pause;
1023 pdata->phy.advertising &= ~ADVERTISED_Asym_Pause;
1025 if (pdata->rx_pause) {
1026 pdata->phy.advertising |= ADVERTISED_Pause;
1027 pdata->phy.advertising |= ADVERTISED_Asym_Pause;
1030 if (pdata->tx_pause)
1031 pdata->phy.advertising ^= ADVERTISED_Asym_Pause;
1035 void axgbe_init_function_ptrs_phy(struct axgbe_phy_if *phy_if)
1037 phy_if->phy_init = axgbe_phy_init;
1038 phy_if->phy_reset = axgbe_phy_reset;
1039 phy_if->phy_start = axgbe_phy_start;
1040 phy_if->phy_stop = axgbe_phy_stop;
1041 phy_if->phy_status = axgbe_phy_status;
1042 phy_if->phy_config_aneg = axgbe_phy_config_aneg;
1043 phy_if->an_isr = axgbe_an_combined_isr;