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_an37_enable_interrupts(struct axgbe_port *pdata)
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);
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);
45 static void axgbe_an73_clear_interrupts(struct axgbe_port *pdata)
47 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
50 static void axgbe_an73_disable_interrupts(struct axgbe_port *pdata)
52 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);
55 static void axgbe_an73_enable_interrupts(struct axgbe_port *pdata)
57 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK,
58 AXGBE_AN_CL73_INT_MASK);
61 static void axgbe_an_enable_interrupts(struct axgbe_port *pdata)
63 switch (pdata->an_mode) {
64 case AXGBE_AN_MODE_CL73:
65 case AXGBE_AN_MODE_CL73_REDRV:
66 axgbe_an73_enable_interrupts(pdata);
68 case AXGBE_AN_MODE_CL37:
69 case AXGBE_AN_MODE_CL37_SGMII:
70 axgbe_an37_enable_interrupts(pdata);
77 static void axgbe_an_clear_interrupts_all(struct axgbe_port *pdata)
79 axgbe_an73_clear_interrupts(pdata);
80 axgbe_an37_clear_interrupts(pdata);
83 static void axgbe_an73_enable_kr_training(struct axgbe_port *pdata)
87 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
89 reg |= AXGBE_KR_TRAINING_ENABLE;
90 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
93 static void axgbe_an73_disable_kr_training(struct axgbe_port *pdata)
97 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
99 reg &= ~AXGBE_KR_TRAINING_ENABLE;
100 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
103 static void axgbe_kr_mode(struct axgbe_port *pdata)
105 /* Enable KR training */
106 axgbe_an73_enable_kr_training(pdata);
108 /* Set MAC to 10G speed */
109 pdata->hw_if.set_speed(pdata, SPEED_10000);
111 /* Call PHY implementation support to complete rate change */
112 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_KR);
115 static void axgbe_kx_2500_mode(struct axgbe_port *pdata)
117 /* Disable KR training */
118 axgbe_an73_disable_kr_training(pdata);
120 /* Set MAC to 2.5G speed */
121 pdata->hw_if.set_speed(pdata, SPEED_2500);
123 /* Call PHY implementation support to complete rate change */
124 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_KX_2500);
127 static void axgbe_kx_1000_mode(struct axgbe_port *pdata)
129 /* Disable KR training */
130 axgbe_an73_disable_kr_training(pdata);
132 /* Set MAC to 1G speed */
133 pdata->hw_if.set_speed(pdata, SPEED_1000);
135 /* Call PHY implementation support to complete rate change */
136 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_KX_1000);
139 static void axgbe_sfi_mode(struct axgbe_port *pdata)
141 /* If a KR re-driver is present, change to KR mode instead */
143 return axgbe_kr_mode(pdata);
145 /* Disable KR training */
146 axgbe_an73_disable_kr_training(pdata);
148 /* Set MAC to 10G speed */
149 pdata->hw_if.set_speed(pdata, SPEED_10000);
151 /* Call PHY implementation support to complete rate change */
152 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SFI);
155 static void axgbe_x_mode(struct axgbe_port *pdata)
157 /* Disable KR training */
158 axgbe_an73_disable_kr_training(pdata);
160 /* Set MAC to 1G speed */
161 pdata->hw_if.set_speed(pdata, SPEED_1000);
163 /* Call PHY implementation support to complete rate change */
164 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_X);
167 static void axgbe_sgmii_1000_mode(struct axgbe_port *pdata)
169 /* Disable KR training */
170 axgbe_an73_disable_kr_training(pdata);
172 /* Set MAC to 1G speed */
173 pdata->hw_if.set_speed(pdata, SPEED_1000);
175 /* Call PHY implementation support to complete rate change */
176 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SGMII_1000);
179 static void axgbe_sgmii_100_mode(struct axgbe_port *pdata)
181 /* Disable KR training */
182 axgbe_an73_disable_kr_training(pdata);
184 /* Set MAC to 1G speed */
185 pdata->hw_if.set_speed(pdata, SPEED_1000);
187 /* Call PHY implementation support to complete rate change */
188 pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SGMII_100);
191 static enum axgbe_mode axgbe_cur_mode(struct axgbe_port *pdata)
193 return pdata->phy_if.phy_impl.cur_mode(pdata);
196 static bool axgbe_in_kr_mode(struct axgbe_port *pdata)
198 return axgbe_cur_mode(pdata) == AXGBE_MODE_KR;
201 static void axgbe_change_mode(struct axgbe_port *pdata,
202 enum axgbe_mode mode)
205 case AXGBE_MODE_KX_1000:
206 axgbe_kx_1000_mode(pdata);
208 case AXGBE_MODE_KX_2500:
209 axgbe_kx_2500_mode(pdata);
212 axgbe_kr_mode(pdata);
214 case AXGBE_MODE_SGMII_100:
215 axgbe_sgmii_100_mode(pdata);
217 case AXGBE_MODE_SGMII_1000:
218 axgbe_sgmii_1000_mode(pdata);
224 axgbe_sfi_mode(pdata);
226 case AXGBE_MODE_UNKNOWN:
229 PMD_DRV_LOG(ERR, "invalid operation mode requested (%u)\n", mode);
233 static void axgbe_switch_mode(struct axgbe_port *pdata)
235 axgbe_change_mode(pdata, pdata->phy_if.phy_impl.switch_mode(pdata));
238 static void axgbe_set_mode(struct axgbe_port *pdata,
239 enum axgbe_mode mode)
241 if (mode == axgbe_cur_mode(pdata))
244 axgbe_change_mode(pdata, mode);
247 static bool axgbe_use_mode(struct axgbe_port *pdata,
248 enum axgbe_mode mode)
250 return pdata->phy_if.phy_impl.use_mode(pdata, mode);
253 static void axgbe_an37_set(struct axgbe_port *pdata, bool enable,
258 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_CTRL1);
259 reg &= ~MDIO_VEND2_CTRL1_AN_ENABLE;
262 reg |= MDIO_VEND2_CTRL1_AN_ENABLE;
265 reg |= MDIO_VEND2_CTRL1_AN_RESTART;
267 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_CTRL1, reg);
270 static void axgbe_an37_restart(struct axgbe_port *pdata)
272 axgbe_an37_enable_interrupts(pdata);
273 axgbe_an37_set(pdata, true, true);
276 static void axgbe_an37_disable(struct axgbe_port *pdata)
278 axgbe_an37_set(pdata, false, false);
279 axgbe_an37_disable_interrupts(pdata);
282 static void axgbe_an73_set(struct axgbe_port *pdata, bool enable,
287 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1);
288 reg &= ~MDIO_AN_CTRL1_ENABLE;
291 reg |= MDIO_AN_CTRL1_ENABLE;
294 reg |= MDIO_AN_CTRL1_RESTART;
296 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg);
299 static void axgbe_an73_restart(struct axgbe_port *pdata)
301 axgbe_an73_enable_interrupts(pdata);
302 axgbe_an73_set(pdata, true, true);
305 static void axgbe_an73_disable(struct axgbe_port *pdata)
307 axgbe_an73_set(pdata, false, false);
308 axgbe_an73_disable_interrupts(pdata);
312 static void axgbe_an_restart(struct axgbe_port *pdata)
314 if (pdata->phy_if.phy_impl.an_pre)
315 pdata->phy_if.phy_impl.an_pre(pdata);
317 switch (pdata->an_mode) {
318 case AXGBE_AN_MODE_CL73:
319 case AXGBE_AN_MODE_CL73_REDRV:
320 axgbe_an73_restart(pdata);
322 case AXGBE_AN_MODE_CL37:
323 case AXGBE_AN_MODE_CL37_SGMII:
324 axgbe_an37_restart(pdata);
331 static void axgbe_an_disable(struct axgbe_port *pdata)
333 if (pdata->phy_if.phy_impl.an_post)
334 pdata->phy_if.phy_impl.an_post(pdata);
336 switch (pdata->an_mode) {
337 case AXGBE_AN_MODE_CL73:
338 case AXGBE_AN_MODE_CL73_REDRV:
339 axgbe_an73_disable(pdata);
341 case AXGBE_AN_MODE_CL37:
342 case AXGBE_AN_MODE_CL37_SGMII:
343 axgbe_an37_disable(pdata);
350 static void axgbe_an_disable_all(struct axgbe_port *pdata)
352 axgbe_an73_disable(pdata);
353 axgbe_an37_disable(pdata);
356 static enum axgbe_an axgbe_an73_tx_training(struct axgbe_port *pdata,
357 enum axgbe_rx *state)
359 unsigned int ad_reg, lp_reg, reg;
361 *state = AXGBE_RX_COMPLETE;
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;
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);
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);
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);
383 reg |= AXGBE_KR_TRAINING_START;
384 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL,
387 if (pdata->phy_if.phy_impl.kr_training_post)
388 pdata->phy_if.phy_impl.kr_training_post(pdata);
391 return AXGBE_AN_PAGE_RECEIVED;
394 static enum axgbe_an axgbe_an73_tx_xnp(struct axgbe_port *pdata,
395 enum axgbe_rx *state)
399 *state = AXGBE_RX_XNP;
401 msg = AXGBE_XNP_MCF_NULL_MESSAGE;
402 msg |= AXGBE_XNP_MP_FORMATTED;
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);
408 return AXGBE_AN_PAGE_RECEIVED;
411 static enum axgbe_an axgbe_an73_rx_bpa(struct axgbe_port *pdata,
412 enum axgbe_rx *state)
414 unsigned int link_support;
415 unsigned int reg, ad_reg, lp_reg;
417 /* Read Base Ability register 2 first */
418 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
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;
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);
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);
435 static enum axgbe_an axgbe_an73_rx_xnp(struct axgbe_port *pdata,
436 enum axgbe_rx *state)
438 unsigned int ad_reg, lp_reg;
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);
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);
450 static enum axgbe_an axgbe_an73_page_received(struct axgbe_port *pdata)
452 enum axgbe_rx *state;
453 unsigned long an_timeout;
457 if (!pdata->an_start) {
458 pdata->an_start = rte_get_timer_cycles();
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;
468 pdata->an_start = rte_get_timer_cycles();
472 state = axgbe_in_kr_mode(pdata) ? &pdata->kr_state
477 ret = axgbe_an73_rx_bpa(pdata, state);
480 ret = axgbe_an73_rx_xnp(pdata, state);
483 ret = AXGBE_AN_ERROR;
489 static enum axgbe_an axgbe_an73_incompat_link(struct axgbe_port *pdata)
491 /* Be sure we aren't looping trying to negotiate */
492 if (axgbe_in_kr_mode(pdata)) {
493 pdata->kr_state = AXGBE_RX_ERROR;
495 if (!(pdata->phy.advertising & ADVERTISED_1000baseKX_Full) &&
496 !(pdata->phy.advertising & ADVERTISED_2500baseX_Full))
497 return AXGBE_AN_NO_LINK;
499 if (pdata->kx_state != AXGBE_RX_BPA)
500 return AXGBE_AN_NO_LINK;
502 pdata->kx_state = AXGBE_RX_ERROR;
504 if (!(pdata->phy.advertising & ADVERTISED_10000baseKR_Full))
505 return AXGBE_AN_NO_LINK;
507 if (pdata->kr_state != AXGBE_RX_BPA)
508 return AXGBE_AN_NO_LINK;
511 axgbe_an_disable(pdata);
512 axgbe_switch_mode(pdata);
513 axgbe_an_restart(pdata);
515 return AXGBE_AN_INCOMPAT_LINK;
518 static void axgbe_an73_state_machine(struct axgbe_port *pdata)
520 enum axgbe_an cur_state = pdata->an_state;
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;
536 pdata->an_state = AXGBE_AN_ERROR;
540 cur_state = pdata->an_state;
542 switch (pdata->an_state) {
544 pdata->an_supported = 0;
546 case AXGBE_AN_PAGE_RECEIVED:
547 pdata->an_state = axgbe_an73_page_received(pdata);
548 pdata->an_supported++;
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);
555 case AXGBE_AN_COMPLETE:
556 pdata->parallel_detect = pdata->an_supported ? 0 : 1;
558 case AXGBE_AN_NO_LINK:
561 pdata->an_state = AXGBE_AN_ERROR;
564 if (pdata->an_state == AXGBE_AN_NO_LINK) {
566 axgbe_an73_clear_interrupts(pdata);
567 pdata->eth_dev->data->dev_link.link_status =
569 } else if (pdata->an_state == AXGBE_AN_ERROR) {
570 PMD_DRV_LOG(ERR, "error during auto-negotiation, state=%u\n",
573 axgbe_an73_clear_interrupts(pdata);
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;
582 if (pdata->phy_if.phy_impl.an_post)
583 pdata->phy_if.phy_impl.an_post(pdata);
586 if (cur_state != pdata->an_state)
592 axgbe_an73_enable_interrupts(pdata);
595 static void axgbe_an37_state_machine(struct axgbe_port *pdata)
597 enum axgbe_an cur_state = pdata->an_state;
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;
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;
611 cur_state = pdata->an_state;
613 switch (pdata->an_state) {
616 case AXGBE_AN_COMPLETE:
618 case AXGBE_AN_NO_LINK:
621 pdata->an_state = AXGBE_AN_ERROR;
625 if (pdata->an_state == AXGBE_AN_ERROR) {
626 PMD_DRV_LOG(ERR, "error during auto-negotiation, state=%u\n",
629 axgbe_an37_clear_interrupts(pdata);
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);
639 axgbe_an37_enable_interrupts(pdata);
642 static void axgbe_an73_isr(struct axgbe_port *pdata)
644 /* Disable AN interrupts */
645 axgbe_an73_disable_interrupts(pdata);
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);
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);
658 /* Enable AN interrupts */
659 axgbe_an73_enable_interrupts(pdata);
663 static void axgbe_an37_isr(struct axgbe_port *pdata)
665 unsigned int reg = 0;
666 /* Disable AN interrupts */
667 axgbe_an37_disable_interrupts(pdata);
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);
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);
681 /* Enable AN interrupts */
682 axgbe_an37_enable_interrupts(pdata);
686 static void axgbe_an_isr(struct axgbe_port *pdata)
688 switch (pdata->an_mode) {
689 case AXGBE_AN_MODE_CL73:
690 case AXGBE_AN_MODE_CL73_REDRV:
691 axgbe_an73_isr(pdata);
693 case AXGBE_AN_MODE_CL37:
694 case AXGBE_AN_MODE_CL37_SGMII:
695 axgbe_an37_isr(pdata);
702 static void axgbe_an_combined_isr(struct axgbe_port *pdata)
707 static void axgbe_an37_init(struct axgbe_port *pdata)
709 unsigned int advertising;
710 unsigned int reg = 0;
712 advertising = pdata->phy_if.phy_impl.an_advertising(pdata);
714 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE);
715 if (advertising & ADVERTISED_Pause)
719 if (advertising & ADVERTISED_Asym_Pause)
724 /* Full duplex, but not half */
725 reg |= AXGBE_AN_CL37_FD_MASK;
726 reg &= ~AXGBE_AN_CL37_HD_MASK;
728 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE, reg);
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;
735 switch (pdata->an_mode) {
736 case AXGBE_AN_MODE_CL37:
737 reg |= AXGBE_AN_CL37_PCS_MODE_BASEX;
739 case AXGBE_AN_MODE_CL37_SGMII:
740 reg |= AXGBE_AN_CL37_PCS_MODE_SGMII;
745 reg |= AXGBE_AN_CL37_MII_CTRL_8BIT;
746 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
749 static void axgbe_an73_init(struct axgbe_port *pdata)
751 unsigned int advertising, reg;
753 advertising = pdata->phy_if.phy_impl.an_advertising(pdata);
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)
762 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, reg);
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)
771 if ((advertising & ADVERTISED_1000baseKX_Full) ||
772 (advertising & ADVERTISED_2500baseX_Full))
777 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, reg);
779 /* Set up Advertisement register 1 last */
780 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
781 if (advertising & ADVERTISED_Pause)
786 if (advertising & ADVERTISED_Asym_Pause)
791 /* We don't intend to perform XNP */
792 reg &= ~AXGBE_XNP_NP_EXCHANGE;
794 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
797 static void axgbe_an_init(struct axgbe_port *pdata)
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);
806 case AXGBE_AN_MODE_CL37:
807 case AXGBE_AN_MODE_CL37_SGMII:
808 axgbe_an37_init(pdata);
815 static void axgbe_phy_adjust_link(struct axgbe_port *pdata)
817 if (pdata->phy.link) {
818 /* Flow control support */
819 pdata->pause_autoneg = pdata->phy.pause_autoneg;
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;
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;
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) {
838 pdata->phy_speed = SPEED_UNKNOWN;
842 static int axgbe_phy_config_fixed(struct axgbe_port *pdata)
844 enum axgbe_mode mode;
846 /* Disable auto-negotiation */
847 axgbe_an_disable(pdata);
849 /* Set specified mode for specified speed */
850 mode = pdata->phy_if.phy_impl.get_mode(pdata, pdata->phy.speed);
852 case AXGBE_MODE_KX_1000:
853 case AXGBE_MODE_KX_2500:
855 case AXGBE_MODE_SGMII_100:
856 case AXGBE_MODE_SGMII_1000:
860 case AXGBE_MODE_UNKNOWN:
865 /* Validate duplex mode */
866 if (pdata->phy.duplex != DUPLEX_FULL)
869 axgbe_set_mode(pdata, mode);
874 static int __axgbe_phy_config_aneg(struct axgbe_port *pdata)
878 axgbe_set_bit(AXGBE_LINK_INIT, &pdata->dev_state);
879 pdata->link_check = rte_get_timer_cycles();
881 ret = pdata->phy_if.phy_impl.an_config(pdata);
885 if (pdata->phy.autoneg != AUTONEG_ENABLE) {
886 ret = axgbe_phy_config_fixed(pdata);
887 if (ret || !pdata->kr_redrv)
891 /* Disable auto-negotiation interrupt */
892 rte_intr_disable(&pdata->pci_dev->intr_handle);
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);
910 rte_intr_enable(&pdata->pci_dev->intr_handle);
914 /* Disable and stop any in progress auto-negotiation */
915 axgbe_an_disable_all(pdata);
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;
922 /* Re-enable auto-negotiation interrupt */
923 rte_intr_enable(&pdata->pci_dev->intr_handle);
924 axgbe_an37_enable_interrupts(pdata);
926 axgbe_an_init(pdata);
927 axgbe_an_restart(pdata);
932 static int axgbe_phy_config_aneg(struct axgbe_port *pdata)
936 pthread_mutex_lock(&pdata->an_mutex);
938 ret = __axgbe_phy_config_aneg(pdata);
940 axgbe_set_bit(AXGBE_LINK_ERR, &pdata->dev_state);
942 axgbe_clear_bit(AXGBE_LINK_ERR, &pdata->dev_state);
944 pthread_mutex_unlock(&pdata->an_mutex);
949 static bool axgbe_phy_aneg_done(struct axgbe_port *pdata)
951 return pdata->an_result == AXGBE_AN_COMPLETE;
954 static void axgbe_check_link_timeout(struct axgbe_port *pdata)
956 unsigned long link_timeout;
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);
966 static enum axgbe_mode axgbe_phy_status_aneg(struct axgbe_port *pdata)
968 return pdata->phy_if.phy_impl.an_outcome(pdata);
971 static void axgbe_phy_status_result(struct axgbe_port *pdata)
973 enum axgbe_mode mode;
975 pdata->phy.lp_advertising = 0;
977 if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect)
978 mode = axgbe_cur_mode(pdata);
980 mode = axgbe_phy_status_aneg(pdata);
983 case AXGBE_MODE_SGMII_100:
984 pdata->phy.speed = SPEED_100;
987 case AXGBE_MODE_KX_1000:
988 case AXGBE_MODE_SGMII_1000:
989 pdata->phy.speed = SPEED_1000;
991 case AXGBE_MODE_KX_2500:
992 pdata->phy.speed = SPEED_2500;
996 pdata->phy.speed = SPEED_10000;
998 case AXGBE_MODE_UNKNOWN:
1000 pdata->phy.speed = SPEED_UNKNOWN;
1003 pdata->phy.duplex = DUPLEX_FULL;
1005 axgbe_set_mode(pdata, mode);
1008 static int autoneg_time_out(unsigned long autoneg_start_time)
1010 unsigned long autoneg_timeout;
1011 unsigned long ticks;
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))
1022 static void axgbe_phy_status(struct axgbe_port *pdata)
1024 unsigned int link_aneg;
1025 int an_restart, ret;
1026 unsigned int reg = 0;
1027 unsigned long autoneg_start_time;
1029 if (axgbe_test_bit(AXGBE_LINK_ERR, &pdata->dev_state)) {
1030 pdata->phy.link = 0;
1034 link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE);
1036 pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata,
1039 axgbe_phy_config_aneg(pdata);
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)) {
1056 autoneg_time_out(autoneg_start_time);
1059 reg = XMDIO_READ(pdata,
1061 MDIO_VEND2_AN_STAT);
1062 if (reg & AXGBE_AN_CL37_INT_CMPLT) {
1063 axgbe_an37_isr(pdata);
1068 axgbe_check_link_timeout(pdata);
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);
1076 if (axgbe_test_bit(AXGBE_LINK_INIT, &pdata->dev_state)) {
1077 axgbe_check_link_timeout(pdata);
1082 axgbe_phy_status_result(pdata);
1086 axgbe_phy_adjust_link(pdata);
1089 static void axgbe_phy_stop(struct axgbe_port *pdata)
1091 if (!pdata->phy_started)
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);
1102 static int axgbe_phy_start(struct axgbe_port *pdata)
1106 ret = pdata->phy_if.phy_impl.start(pdata);
1109 /* Set initial mode - call the mode setting routines
1110 * directly to insure we are properly configured
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);
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);
1137 pdata->phy_if.phy_impl.stop(pdata);
1142 static int axgbe_phy_reset(struct axgbe_port *pdata)
1146 ret = pdata->phy_if.phy_impl.reset(pdata);
1150 /* Disable auto-negotiation for now */
1151 axgbe_an_disable_all(pdata);
1153 /* Clear auto-negotiation interrupts */
1154 axgbe_an_clear_interrupts_all(pdata);
1159 static int axgbe_phy_best_advertised_speed(struct axgbe_port *pdata)
1161 if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full)
1163 else if (pdata->phy.advertising & ADVERTISED_10000baseT_Full)
1165 else if (pdata->phy.advertising & ADVERTISED_2500baseX_Full)
1167 else if (pdata->phy.advertising & ADVERTISED_1000baseKX_Full)
1169 else if (pdata->phy.advertising & ADVERTISED_1000baseT_Full)
1171 else if (pdata->phy.advertising & ADVERTISED_100baseT_Full)
1174 return SPEED_UNKNOWN;
1177 static int axgbe_phy_init(struct axgbe_port *pdata)
1181 pdata->mdio_mmd = MDIO_MMD_PCS;
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);
1189 /* Setup the phy (including supported features) */
1190 ret = pdata->phy_if.phy_impl.init(pdata);
1193 pdata->phy.advertising = pdata->phy.supported;
1195 pdata->phy.address = 0;
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;
1202 pdata->phy.autoneg = AUTONEG_DISABLE;
1203 pdata->phy.speed = axgbe_phy_best_advertised_speed(pdata);
1204 pdata->phy.duplex = DUPLEX_FULL;
1207 pdata->phy.link = 0;
1209 pdata->phy.pause_autoneg = pdata->pause_autoneg;
1210 pdata->phy.tx_pause = pdata->tx_pause;
1211 pdata->phy.rx_pause = pdata->rx_pause;
1213 /* Fix up Flow Control advertising */
1214 pdata->phy.advertising &= ~ADVERTISED_Pause;
1215 pdata->phy.advertising &= ~ADVERTISED_Asym_Pause;
1217 if (pdata->rx_pause) {
1218 pdata->phy.advertising |= ADVERTISED_Pause;
1219 pdata->phy.advertising |= ADVERTISED_Asym_Pause;
1222 if (pdata->tx_pause)
1223 pdata->phy.advertising ^= ADVERTISED_Asym_Pause;
1227 void axgbe_init_function_ptrs_phy(struct axgbe_phy_if *phy_if)
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;