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);
304 PMD_DRV_LOG(DEBUG
, "CL73 AN enabled/restarted\n");
307 static void axgbe_an73_disable(struct axgbe_port
*pdata
)
309 axgbe_an73_set(pdata
, false, false);
310 axgbe_an73_disable_interrupts(pdata
);
313 PMD_DRV_LOG(DEBUG
, "CL73 AN disabled\n");
316 static void axgbe_an_restart(struct axgbe_port
*pdata
)
318 if (pdata
->phy_if
.phy_impl
.an_pre
)
319 pdata
->phy_if
.phy_impl
.an_pre(pdata
);
321 switch (pdata
->an_mode
) {
322 case AXGBE_AN_MODE_CL73
:
323 case AXGBE_AN_MODE_CL73_REDRV
:
324 axgbe_an73_restart(pdata
);
326 case AXGBE_AN_MODE_CL37
:
327 case AXGBE_AN_MODE_CL37_SGMII
:
328 axgbe_an37_restart(pdata
);
335 static void axgbe_an_disable(struct axgbe_port
*pdata
)
337 if (pdata
->phy_if
.phy_impl
.an_post
)
338 pdata
->phy_if
.phy_impl
.an_post(pdata
);
340 switch (pdata
->an_mode
) {
341 case AXGBE_AN_MODE_CL73
:
342 case AXGBE_AN_MODE_CL73_REDRV
:
343 axgbe_an73_disable(pdata
);
345 case AXGBE_AN_MODE_CL37
:
346 case AXGBE_AN_MODE_CL37_SGMII
:
347 axgbe_an37_disable(pdata
);
354 static void axgbe_an_disable_all(struct axgbe_port
*pdata
)
356 axgbe_an73_disable(pdata
);
357 axgbe_an37_disable(pdata
);
360 static enum axgbe_an
axgbe_an73_tx_training(struct axgbe_port
*pdata
,
361 enum axgbe_rx
*state
)
363 unsigned int ad_reg
, lp_reg
, reg
;
365 *state
= AXGBE_RX_COMPLETE
;
367 /* If we're not in KR mode then we're done */
368 if (!axgbe_in_kr_mode(pdata
))
369 return AXGBE_AN_PAGE_RECEIVED
;
371 /* Enable/Disable FEC */
372 ad_reg
= XMDIO_READ(pdata
, MDIO_MMD_AN
, MDIO_AN_ADVERTISE
+ 2);
373 lp_reg
= XMDIO_READ(pdata
, MDIO_MMD_AN
, MDIO_AN_LPA
+ 2);
375 reg
= XMDIO_READ(pdata
, MDIO_MMD_PMAPMD
, MDIO_PMA_10GBR_FECCTRL
);
376 reg
&= ~(MDIO_PMA_10GBR_FECABLE_ABLE
| MDIO_PMA_10GBR_FECABLE_ERRABLE
);
377 if ((ad_reg
& 0xc000) && (lp_reg
& 0xc000))
378 reg
|= pdata
->fec_ability
;
379 XMDIO_WRITE(pdata
, MDIO_MMD_PMAPMD
, MDIO_PMA_10GBR_FECCTRL
, reg
);
381 /* Start KR training */
382 reg
= XMDIO_READ(pdata
, MDIO_MMD_PMAPMD
, MDIO_PMA_10GBR_PMD_CTRL
);
383 if (reg
& AXGBE_KR_TRAINING_ENABLE
) {
384 if (pdata
->phy_if
.phy_impl
.kr_training_pre
)
385 pdata
->phy_if
.phy_impl
.kr_training_pre(pdata
);
387 reg
|= AXGBE_KR_TRAINING_START
;
388 XMDIO_WRITE(pdata
, MDIO_MMD_PMAPMD
, MDIO_PMA_10GBR_PMD_CTRL
,
391 PMD_DRV_LOG(DEBUG
, "KR training initiated\n");
393 if (pdata
->phy_if
.phy_impl
.kr_training_post
)
394 pdata
->phy_if
.phy_impl
.kr_training_post(pdata
);
397 return AXGBE_AN_PAGE_RECEIVED
;
400 static enum axgbe_an
axgbe_an73_tx_xnp(struct axgbe_port
*pdata
,
401 enum axgbe_rx
*state
)
405 *state
= AXGBE_RX_XNP
;
407 msg
= AXGBE_XNP_MCF_NULL_MESSAGE
;
408 msg
|= AXGBE_XNP_MP_FORMATTED
;
410 XMDIO_WRITE(pdata
, MDIO_MMD_AN
, MDIO_AN_XNP
+ 2, 0);
411 XMDIO_WRITE(pdata
, MDIO_MMD_AN
, MDIO_AN_XNP
+ 1, 0);
412 XMDIO_WRITE(pdata
, MDIO_MMD_AN
, MDIO_AN_XNP
, msg
);
414 return AXGBE_AN_PAGE_RECEIVED
;
417 static enum axgbe_an
axgbe_an73_rx_bpa(struct axgbe_port
*pdata
,
418 enum axgbe_rx
*state
)
420 unsigned int link_support
;
421 unsigned int reg
, ad_reg
, lp_reg
;
423 /* Read Base Ability register 2 first */
424 reg
= XMDIO_READ(pdata
, MDIO_MMD_AN
, MDIO_AN_LPA
+ 1);
426 /* Check for a supported mode, otherwise restart in a different one */
427 link_support
= axgbe_in_kr_mode(pdata
) ? 0x80 : 0x20;
428 if (!(reg
& link_support
))
429 return AXGBE_AN_INCOMPAT_LINK
;
431 /* Check Extended Next Page support */
432 ad_reg
= XMDIO_READ(pdata
, MDIO_MMD_AN
, MDIO_AN_ADVERTISE
);
433 lp_reg
= XMDIO_READ(pdata
, MDIO_MMD_AN
, MDIO_AN_LPA
);
435 return ((ad_reg
& AXGBE_XNP_NP_EXCHANGE
) ||
436 (lp_reg
& AXGBE_XNP_NP_EXCHANGE
))
437 ? axgbe_an73_tx_xnp(pdata
, state
)
438 : axgbe_an73_tx_training(pdata
, state
);
441 static enum axgbe_an
axgbe_an73_rx_xnp(struct axgbe_port
*pdata
,
442 enum axgbe_rx
*state
)
444 unsigned int ad_reg
, lp_reg
;
446 /* Check Extended Next Page support */
447 ad_reg
= XMDIO_READ(pdata
, MDIO_MMD_AN
, MDIO_AN_XNP
);
448 lp_reg
= XMDIO_READ(pdata
, MDIO_MMD_AN
, MDIO_AN_LPX
);
450 return ((ad_reg
& AXGBE_XNP_NP_EXCHANGE
) ||
451 (lp_reg
& AXGBE_XNP_NP_EXCHANGE
))
452 ? axgbe_an73_tx_xnp(pdata
, state
)
453 : axgbe_an73_tx_training(pdata
, state
);
456 static enum axgbe_an
axgbe_an73_page_received(struct axgbe_port
*pdata
)
458 enum axgbe_rx
*state
;
459 unsigned long an_timeout
;
463 if (!pdata
->an_start
) {
464 pdata
->an_start
= rte_get_timer_cycles();
466 an_timeout
= pdata
->an_start
+
467 msecs_to_timer_cycles(AXGBE_AN_MS_TIMEOUT
);
468 ticks
= rte_get_timer_cycles();
469 if (time_after(ticks
, an_timeout
)) {
470 /* Auto-negotiation timed out, reset state */
471 pdata
->kr_state
= AXGBE_RX_BPA
;
472 pdata
->kx_state
= AXGBE_RX_BPA
;
474 pdata
->an_start
= rte_get_timer_cycles();
477 "CL73 AN timed out, resetting state\n");
481 state
= axgbe_in_kr_mode(pdata
) ? &pdata
->kr_state
486 ret
= axgbe_an73_rx_bpa(pdata
, state
);
489 ret
= axgbe_an73_rx_xnp(pdata
, state
);
492 ret
= AXGBE_AN_ERROR
;
498 static enum axgbe_an
axgbe_an73_incompat_link(struct axgbe_port
*pdata
)
500 /* Be sure we aren't looping trying to negotiate */
501 if (axgbe_in_kr_mode(pdata
)) {
502 pdata
->kr_state
= AXGBE_RX_ERROR
;
504 if (!(pdata
->phy
.advertising
& ADVERTISED_1000baseKX_Full
) &&
505 !(pdata
->phy
.advertising
& ADVERTISED_2500baseX_Full
))
506 return AXGBE_AN_NO_LINK
;
508 if (pdata
->kx_state
!= AXGBE_RX_BPA
)
509 return AXGBE_AN_NO_LINK
;
511 pdata
->kx_state
= AXGBE_RX_ERROR
;
513 if (!(pdata
->phy
.advertising
& ADVERTISED_10000baseKR_Full
))
514 return AXGBE_AN_NO_LINK
;
516 if (pdata
->kr_state
!= AXGBE_RX_BPA
)
517 return AXGBE_AN_NO_LINK
;
520 axgbe_an_disable(pdata
);
521 axgbe_switch_mode(pdata
);
522 axgbe_an_restart(pdata
);
524 return AXGBE_AN_INCOMPAT_LINK
;
527 static const char *axgbe_state_as_string(enum axgbe_an state
)
532 case AXGBE_AN_PAGE_RECEIVED
:
533 return "Page-Received";
534 case AXGBE_AN_INCOMPAT_LINK
:
535 return "Incompatible-Link";
536 case AXGBE_AN_COMPLETE
:
538 case AXGBE_AN_NO_LINK
:
547 static void axgbe_an73_state_machine(struct axgbe_port
*pdata
)
549 enum axgbe_an cur_state
= pdata
->an_state
;
555 if (pdata
->an_int
& AXGBE_AN_CL73_PG_RCV
) {
556 pdata
->an_state
= AXGBE_AN_PAGE_RECEIVED
;
557 pdata
->an_int
&= ~AXGBE_AN_CL73_PG_RCV
;
558 } else if (pdata
->an_int
& AXGBE_AN_CL73_INC_LINK
) {
559 pdata
->an_state
= AXGBE_AN_INCOMPAT_LINK
;
560 pdata
->an_int
&= ~AXGBE_AN_CL73_INC_LINK
;
561 } else if (pdata
->an_int
& AXGBE_AN_CL73_INT_CMPLT
) {
562 pdata
->an_state
= AXGBE_AN_COMPLETE
;
563 pdata
->an_int
&= ~AXGBE_AN_CL73_INT_CMPLT
;
565 pdata
->an_state
= AXGBE_AN_ERROR
;
568 PMD_DRV_LOG(DEBUG
, "CL73 AN : %s\n",
569 axgbe_state_as_string(pdata
->an_state
));
572 cur_state
= pdata
->an_state
;
574 switch (pdata
->an_state
) {
576 pdata
->an_supported
= 0;
578 case AXGBE_AN_PAGE_RECEIVED
:
579 pdata
->an_state
= axgbe_an73_page_received(pdata
);
580 pdata
->an_supported
++;
582 case AXGBE_AN_INCOMPAT_LINK
:
583 pdata
->an_supported
= 0;
584 pdata
->parallel_detect
= 0;
585 pdata
->an_state
= axgbe_an73_incompat_link(pdata
);
587 case AXGBE_AN_COMPLETE
:
588 pdata
->parallel_detect
= pdata
->an_supported
? 0 : 1;
590 case AXGBE_AN_NO_LINK
:
593 pdata
->an_state
= AXGBE_AN_ERROR
;
596 if (pdata
->an_state
== AXGBE_AN_NO_LINK
) {
598 axgbe_an73_clear_interrupts(pdata
);
599 pdata
->eth_dev
->data
->dev_link
.link_status
=
601 } else if (pdata
->an_state
== AXGBE_AN_ERROR
) {
602 PMD_DRV_LOG(ERR
, "error during auto-negotiation, state=%u\n",
605 axgbe_an73_clear_interrupts(pdata
);
608 if (pdata
->an_state
>= AXGBE_AN_COMPLETE
) {
609 pdata
->an_result
= pdata
->an_state
;
610 pdata
->an_state
= AXGBE_AN_READY
;
611 pdata
->kr_state
= AXGBE_RX_BPA
;
612 pdata
->kx_state
= AXGBE_RX_BPA
;
614 if (pdata
->phy_if
.phy_impl
.an_post
)
615 pdata
->phy_if
.phy_impl
.an_post(pdata
);
617 PMD_DRV_LOG(DEBUG
, "CL73 AN result: %s\n",
618 axgbe_state_as_string(pdata
->an_result
));
621 if (cur_state
!= pdata
->an_state
)
627 axgbe_an73_enable_interrupts(pdata
);
630 static void axgbe_an37_state_machine(struct axgbe_port
*pdata
)
632 enum axgbe_an cur_state
= pdata
->an_state
;
636 if (pdata
->an_int
& AXGBE_AN_CL37_INT_CMPLT
) {
637 pdata
->an_state
= AXGBE_AN_COMPLETE
;
638 pdata
->an_int
&= ~AXGBE_AN_CL37_INT_CMPLT
;
640 /* If SGMII is enabled, check the link status */
641 if (pdata
->an_mode
== AXGBE_AN_MODE_CL37_SGMII
&&
642 !(pdata
->an_status
& AXGBE_SGMII_AN_LINK_STATUS
))
643 pdata
->an_state
= AXGBE_AN_NO_LINK
;
646 cur_state
= pdata
->an_state
;
648 switch (pdata
->an_state
) {
651 case AXGBE_AN_COMPLETE
:
653 case AXGBE_AN_NO_LINK
:
656 pdata
->an_state
= AXGBE_AN_ERROR
;
660 if (pdata
->an_state
== AXGBE_AN_ERROR
) {
661 PMD_DRV_LOG(ERR
, "error during auto-negotiation, state=%u\n",
664 axgbe_an37_clear_interrupts(pdata
);
667 if (pdata
->an_state
>= AXGBE_AN_COMPLETE
) {
668 pdata
->an_result
= pdata
->an_state
;
669 pdata
->an_state
= AXGBE_AN_READY
;
670 if (pdata
->phy_if
.phy_impl
.an_post
)
671 pdata
->phy_if
.phy_impl
.an_post(pdata
);
674 axgbe_an37_enable_interrupts(pdata
);
677 static void axgbe_an73_isr(struct axgbe_port
*pdata
)
679 /* Disable AN interrupts */
680 axgbe_an73_disable_interrupts(pdata
);
682 /* Save the interrupt(s) that fired */
683 pdata
->an_int
= XMDIO_READ(pdata
, MDIO_MMD_AN
, MDIO_AN_INT
);
684 axgbe_an73_clear_interrupts(pdata
);
687 /* Clear the interrupt(s) that fired and process them */
688 XMDIO_WRITE(pdata
, MDIO_MMD_AN
, MDIO_AN_INT
, ~pdata
->an_int
);
689 pthread_mutex_lock(&pdata
->an_mutex
);
690 axgbe_an73_state_machine(pdata
);
691 pthread_mutex_unlock(&pdata
->an_mutex
);
693 /* Enable AN interrupts */
694 axgbe_an73_enable_interrupts(pdata
);
698 static void axgbe_an37_isr(struct axgbe_port
*pdata
)
700 unsigned int reg
= 0;
701 /* Disable AN interrupts */
702 axgbe_an37_disable_interrupts(pdata
);
704 /* Save the interrupt(s) that fired */
705 reg
= XMDIO_READ(pdata
, MDIO_MMD_VEND2
, MDIO_VEND2_AN_STAT
);
706 pdata
->an_int
= reg
& AXGBE_AN_CL37_INT_MASK
;
707 pdata
->an_status
= reg
& ~AXGBE_AN_CL37_INT_MASK
;
708 axgbe_an37_clear_interrupts(pdata
);
710 if (pdata
->an_int
& 0x01) {
711 /* Clear the interrupt(s) that fired and process them */
712 reg
&= ~AXGBE_AN_CL37_INT_MASK
;
713 XMDIO_WRITE(pdata
, MDIO_MMD_VEND2
, MDIO_VEND2_AN_STAT
, reg
);
714 axgbe_an37_state_machine(pdata
);
716 /* Enable AN interrupts */
717 axgbe_an37_enable_interrupts(pdata
);
721 static void axgbe_an_isr(struct axgbe_port
*pdata
)
723 PMD_DRV_LOG(DEBUG
, "AN interrupt received\n");
725 switch (pdata
->an_mode
) {
726 case AXGBE_AN_MODE_CL73
:
727 case AXGBE_AN_MODE_CL73_REDRV
:
728 axgbe_an73_isr(pdata
);
730 case AXGBE_AN_MODE_CL37
:
731 case AXGBE_AN_MODE_CL37_SGMII
:
732 axgbe_an37_isr(pdata
);
739 static void axgbe_an_combined_isr(struct axgbe_port
*pdata
)
744 static void axgbe_an37_init(struct axgbe_port
*pdata
)
746 unsigned int advertising
;
747 unsigned int reg
= 0;
749 advertising
= pdata
->phy_if
.phy_impl
.an_advertising(pdata
);
751 reg
= XMDIO_READ(pdata
, MDIO_MMD_VEND2
, MDIO_VEND2_AN_ADVERTISE
);
752 if (advertising
& ADVERTISED_Pause
)
756 if (advertising
& ADVERTISED_Asym_Pause
)
761 /* Full duplex, but not half */
762 reg
|= AXGBE_AN_CL37_FD_MASK
;
763 reg
&= ~AXGBE_AN_CL37_HD_MASK
;
765 XMDIO_WRITE(pdata
, MDIO_MMD_VEND2
, MDIO_VEND2_AN_ADVERTISE
, reg
);
767 /* Set up the Control register */
768 reg
= XMDIO_READ(pdata
, MDIO_MMD_VEND2
, MDIO_VEND2_AN_CTRL
);
769 reg
&= ~AXGBE_AN_CL37_TX_CONFIG_MASK
;
770 reg
&= ~AXGBE_AN_CL37_PCS_MODE_MASK
;
772 switch (pdata
->an_mode
) {
773 case AXGBE_AN_MODE_CL37
:
774 reg
|= AXGBE_AN_CL37_PCS_MODE_BASEX
;
776 case AXGBE_AN_MODE_CL37_SGMII
:
777 reg
|= AXGBE_AN_CL37_PCS_MODE_SGMII
;
782 reg
|= AXGBE_AN_CL37_MII_CTRL_8BIT
;
783 XMDIO_WRITE(pdata
, MDIO_MMD_VEND2
, MDIO_VEND2_AN_CTRL
, reg
);
786 static void axgbe_an73_init(struct axgbe_port
*pdata
)
788 unsigned int advertising
, reg
;
790 advertising
= pdata
->phy_if
.phy_impl
.an_advertising(pdata
);
792 /* Set up Advertisement register 3 first */
793 reg
= XMDIO_READ(pdata
, MDIO_MMD_AN
, MDIO_AN_ADVERTISE
+ 2);
794 if (advertising
& ADVERTISED_10000baseR_FEC
)
799 XMDIO_WRITE(pdata
, MDIO_MMD_AN
, MDIO_AN_ADVERTISE
+ 2, reg
);
801 /* Set up Advertisement register 2 next */
802 reg
= XMDIO_READ(pdata
, MDIO_MMD_AN
, MDIO_AN_ADVERTISE
+ 1);
803 if (advertising
& ADVERTISED_10000baseKR_Full
)
808 if ((advertising
& ADVERTISED_1000baseKX_Full
) ||
809 (advertising
& ADVERTISED_2500baseX_Full
))
814 XMDIO_WRITE(pdata
, MDIO_MMD_AN
, MDIO_AN_ADVERTISE
+ 1, reg
);
816 /* Set up Advertisement register 1 last */
817 reg
= XMDIO_READ(pdata
, MDIO_MMD_AN
, MDIO_AN_ADVERTISE
);
818 if (advertising
& ADVERTISED_Pause
)
823 if (advertising
& ADVERTISED_Asym_Pause
)
828 /* We don't intend to perform XNP */
829 reg
&= ~AXGBE_XNP_NP_EXCHANGE
;
831 XMDIO_WRITE(pdata
, MDIO_MMD_AN
, MDIO_AN_ADVERTISE
, reg
);
833 PMD_DRV_LOG(DEBUG
, "CL73 AN initialized\n");
836 static void axgbe_an_init(struct axgbe_port
*pdata
)
838 /* Set up advertisement registers based on current settings */
839 pdata
->an_mode
= pdata
->phy_if
.phy_impl
.an_mode(pdata
);
840 switch (pdata
->an_mode
) {
841 case AXGBE_AN_MODE_CL73
:
842 case AXGBE_AN_MODE_CL73_REDRV
:
843 axgbe_an73_init(pdata
);
845 case AXGBE_AN_MODE_CL37
:
846 case AXGBE_AN_MODE_CL37_SGMII
:
847 axgbe_an37_init(pdata
);
854 static void axgbe_phy_adjust_link(struct axgbe_port
*pdata
)
856 if (pdata
->phy
.link
) {
857 /* Flow control support */
858 pdata
->pause_autoneg
= pdata
->phy
.pause_autoneg
;
860 if (pdata
->tx_pause
!= (unsigned int)pdata
->phy
.tx_pause
) {
861 pdata
->hw_if
.config_tx_flow_control(pdata
);
862 pdata
->tx_pause
= pdata
->phy
.tx_pause
;
865 if (pdata
->rx_pause
!= (unsigned int)pdata
->phy
.rx_pause
) {
866 pdata
->hw_if
.config_rx_flow_control(pdata
);
867 pdata
->rx_pause
= pdata
->phy
.rx_pause
;
871 if (pdata
->phy_speed
!= pdata
->phy
.speed
)
872 pdata
->phy_speed
= pdata
->phy
.speed
;
873 if (pdata
->phy_link
!= pdata
->phy
.link
)
874 pdata
->phy_link
= pdata
->phy
.link
;
875 } else if (pdata
->phy_link
) {
877 pdata
->phy_speed
= SPEED_UNKNOWN
;
881 static int axgbe_phy_config_fixed(struct axgbe_port
*pdata
)
883 enum axgbe_mode mode
;
885 PMD_DRV_LOG(DEBUG
, "fixed PHY configuration\n");
887 /* Disable auto-negotiation */
888 axgbe_an_disable(pdata
);
890 /* Set specified mode for specified speed */
891 mode
= pdata
->phy_if
.phy_impl
.get_mode(pdata
, pdata
->phy
.speed
);
893 case AXGBE_MODE_KX_1000
:
894 case AXGBE_MODE_KX_2500
:
896 case AXGBE_MODE_SGMII_100
:
897 case AXGBE_MODE_SGMII_1000
:
901 case AXGBE_MODE_UNKNOWN
:
906 /* Validate duplex mode */
907 if (pdata
->phy
.duplex
!= DUPLEX_FULL
)
910 axgbe_set_mode(pdata
, mode
);
915 static int __axgbe_phy_config_aneg(struct axgbe_port
*pdata
)
919 axgbe_set_bit(AXGBE_LINK_INIT
, &pdata
->dev_state
);
920 pdata
->link_check
= rte_get_timer_cycles();
922 ret
= pdata
->phy_if
.phy_impl
.an_config(pdata
);
926 if (pdata
->phy
.autoneg
!= AUTONEG_ENABLE
) {
927 ret
= axgbe_phy_config_fixed(pdata
);
928 if (ret
|| !pdata
->kr_redrv
)
930 PMD_DRV_LOG(DEBUG
, "AN redriver support\n");
932 PMD_DRV_LOG(DEBUG
, "AN PHY configuration\n");
935 /* Disable auto-negotiation interrupt */
936 rte_intr_disable(&pdata
->pci_dev
->intr_handle
);
938 /* Start auto-negotiation in a supported mode */
939 if (axgbe_use_mode(pdata
, AXGBE_MODE_KR
)) {
940 axgbe_set_mode(pdata
, AXGBE_MODE_KR
);
941 } else if (axgbe_use_mode(pdata
, AXGBE_MODE_KX_2500
)) {
942 axgbe_set_mode(pdata
, AXGBE_MODE_KX_2500
);
943 } else if (axgbe_use_mode(pdata
, AXGBE_MODE_KX_1000
)) {
944 axgbe_set_mode(pdata
, AXGBE_MODE_KX_1000
);
945 } else if (axgbe_use_mode(pdata
, AXGBE_MODE_SFI
)) {
946 axgbe_set_mode(pdata
, AXGBE_MODE_SFI
);
947 } else if (axgbe_use_mode(pdata
, AXGBE_MODE_X
)) {
948 axgbe_set_mode(pdata
, AXGBE_MODE_X
);
949 } else if (axgbe_use_mode(pdata
, AXGBE_MODE_SGMII_1000
)) {
950 axgbe_set_mode(pdata
, AXGBE_MODE_SGMII_1000
);
951 } else if (axgbe_use_mode(pdata
, AXGBE_MODE_SGMII_100
)) {
952 axgbe_set_mode(pdata
, AXGBE_MODE_SGMII_100
);
954 rte_intr_enable(&pdata
->pci_dev
->intr_handle
);
958 /* Disable and stop any in progress auto-negotiation */
959 axgbe_an_disable_all(pdata
);
961 pdata
->an_result
= AXGBE_AN_READY
;
962 pdata
->an_state
= AXGBE_AN_READY
;
963 pdata
->kr_state
= AXGBE_RX_BPA
;
964 pdata
->kx_state
= AXGBE_RX_BPA
;
966 /* Re-enable auto-negotiation interrupt */
967 rte_intr_enable(&pdata
->pci_dev
->intr_handle
);
968 axgbe_an37_enable_interrupts(pdata
);
970 axgbe_an_init(pdata
);
971 axgbe_an_restart(pdata
);
976 static int axgbe_phy_config_aneg(struct axgbe_port
*pdata
)
980 pthread_mutex_lock(&pdata
->an_mutex
);
982 ret
= __axgbe_phy_config_aneg(pdata
);
984 axgbe_set_bit(AXGBE_LINK_ERR
, &pdata
->dev_state
);
986 axgbe_clear_bit(AXGBE_LINK_ERR
, &pdata
->dev_state
);
988 pthread_mutex_unlock(&pdata
->an_mutex
);
993 static bool axgbe_phy_aneg_done(struct axgbe_port
*pdata
)
995 return pdata
->an_result
== AXGBE_AN_COMPLETE
;
998 static void axgbe_check_link_timeout(struct axgbe_port
*pdata
)
1000 unsigned long link_timeout
;
1001 unsigned long ticks
;
1003 link_timeout
= pdata
->link_check
+ (AXGBE_LINK_TIMEOUT
*
1004 2 * rte_get_timer_hz());
1005 ticks
= rte_get_timer_cycles();
1006 if (time_after(ticks
, link_timeout
)) {
1007 PMD_DRV_LOG(NOTICE
, "AN link timeout\n");
1008 axgbe_phy_config_aneg(pdata
);
1012 static enum axgbe_mode
axgbe_phy_status_aneg(struct axgbe_port
*pdata
)
1014 return pdata
->phy_if
.phy_impl
.an_outcome(pdata
);
1017 static void axgbe_phy_status_result(struct axgbe_port
*pdata
)
1019 enum axgbe_mode mode
;
1021 pdata
->phy
.lp_advertising
= 0;
1023 if ((pdata
->phy
.autoneg
!= AUTONEG_ENABLE
) || pdata
->parallel_detect
)
1024 mode
= axgbe_cur_mode(pdata
);
1026 mode
= axgbe_phy_status_aneg(pdata
);
1029 case AXGBE_MODE_SGMII_100
:
1030 pdata
->phy
.speed
= SPEED_100
;
1033 case AXGBE_MODE_KX_1000
:
1034 case AXGBE_MODE_SGMII_1000
:
1035 pdata
->phy
.speed
= SPEED_1000
;
1037 case AXGBE_MODE_KX_2500
:
1038 pdata
->phy
.speed
= SPEED_2500
;
1041 case AXGBE_MODE_SFI
:
1042 pdata
->phy
.speed
= SPEED_10000
;
1044 case AXGBE_MODE_UNKNOWN
:
1046 pdata
->phy
.speed
= SPEED_UNKNOWN
;
1049 pdata
->phy
.duplex
= DUPLEX_FULL
;
1051 axgbe_set_mode(pdata
, mode
);
1054 static int autoneg_time_out(unsigned long autoneg_start_time
)
1056 unsigned long autoneg_timeout
;
1057 unsigned long ticks
;
1059 autoneg_timeout
= autoneg_start_time
+ (AXGBE_LINK_TIMEOUT
*
1060 2 * rte_get_timer_hz());
1061 ticks
= rte_get_timer_cycles();
1062 if (time_after(ticks
, autoneg_timeout
))
1068 static void axgbe_phy_status(struct axgbe_port
*pdata
)
1070 unsigned int link_aneg
;
1071 int an_restart
, ret
;
1072 unsigned int reg
= 0;
1073 unsigned long autoneg_start_time
;
1075 if (axgbe_test_bit(AXGBE_LINK_ERR
, &pdata
->dev_state
)) {
1076 pdata
->phy
.link
= 0;
1080 link_aneg
= (pdata
->phy
.autoneg
== AUTONEG_ENABLE
);
1082 pdata
->phy
.link
= pdata
->phy_if
.phy_impl
.link_status(pdata
,
1085 axgbe_phy_config_aneg(pdata
);
1089 if (pdata
->phy
.link
) {
1090 if (link_aneg
&& !axgbe_phy_aneg_done(pdata
)) {
1091 if (axgbe_cur_mode(pdata
) == AXGBE_MODE_SGMII_1000
) {
1092 /* autoneg not complete, so re-initializing */
1093 /* and restarting it */
1094 axgbe_an_init(pdata
);
1095 axgbe_an_restart(pdata
);
1096 reg
= XMDIO_READ(pdata
, MDIO_MMD_VEND2
,
1097 MDIO_VEND2_AN_STAT
);
1098 autoneg_start_time
= rte_get_timer_cycles();
1099 /* poll for autoneg to complete */
1100 while (!(reg
& AXGBE_AN_CL37_INT_CMPLT
)) {
1102 autoneg_time_out(autoneg_start_time
);
1105 reg
= XMDIO_READ(pdata
,
1107 MDIO_VEND2_AN_STAT
);
1108 if (reg
& AXGBE_AN_CL37_INT_CMPLT
) {
1109 axgbe_an37_isr(pdata
);
1114 axgbe_check_link_timeout(pdata
);
1118 axgbe_phy_status_result(pdata
);
1119 if (axgbe_test_bit(AXGBE_LINK_INIT
, &pdata
->dev_state
))
1120 axgbe_clear_bit(AXGBE_LINK_INIT
, &pdata
->dev_state
);
1122 if (axgbe_test_bit(AXGBE_LINK_INIT
, &pdata
->dev_state
)) {
1123 axgbe_check_link_timeout(pdata
);
1128 axgbe_phy_status_result(pdata
);
1132 axgbe_phy_adjust_link(pdata
);
1135 static void axgbe_phy_stop(struct axgbe_port
*pdata
)
1137 PMD_DRV_LOG(DEBUG
, "stopping PHY\n");
1138 if (!pdata
->phy_started
)
1140 /* Indicate the PHY is down */
1141 pdata
->phy_started
= 0;
1142 /* Disable auto-negotiation */
1143 axgbe_an_disable_all(pdata
);
1144 pdata
->phy_if
.phy_impl
.stop(pdata
);
1145 pdata
->phy
.link
= 0;
1146 axgbe_phy_adjust_link(pdata
);
1149 static int axgbe_phy_start(struct axgbe_port
*pdata
)
1153 PMD_DRV_LOG(DEBUG
, "starting PHY\n");
1155 ret
= pdata
->phy_if
.phy_impl
.start(pdata
);
1158 /* Set initial mode - call the mode setting routines
1159 * directly to insure we are properly configured
1161 if (axgbe_use_mode(pdata
, AXGBE_MODE_KR
)) {
1162 axgbe_kr_mode(pdata
);
1163 } else if (axgbe_use_mode(pdata
, AXGBE_MODE_KX_2500
)) {
1164 axgbe_kx_2500_mode(pdata
);
1165 } else if (axgbe_use_mode(pdata
, AXGBE_MODE_KX_1000
)) {
1166 axgbe_kx_1000_mode(pdata
);
1167 } else if (axgbe_use_mode(pdata
, AXGBE_MODE_SFI
)) {
1168 axgbe_sfi_mode(pdata
);
1169 } else if (axgbe_use_mode(pdata
, AXGBE_MODE_X
)) {
1170 axgbe_x_mode(pdata
);
1171 } else if (axgbe_use_mode(pdata
, AXGBE_MODE_SGMII_1000
)) {
1172 axgbe_sgmii_1000_mode(pdata
);
1173 } else if (axgbe_use_mode(pdata
, AXGBE_MODE_SGMII_100
)) {
1174 axgbe_sgmii_100_mode(pdata
);
1179 /* Indicate the PHY is up and running */
1180 pdata
->phy_started
= 1;
1181 axgbe_an_init(pdata
);
1182 axgbe_an_enable_interrupts(pdata
);
1183 return axgbe_phy_config_aneg(pdata
);
1186 pdata
->phy_if
.phy_impl
.stop(pdata
);
1191 static int axgbe_phy_reset(struct axgbe_port
*pdata
)
1195 ret
= pdata
->phy_if
.phy_impl
.reset(pdata
);
1199 /* Disable auto-negotiation for now */
1200 axgbe_an_disable_all(pdata
);
1202 /* Clear auto-negotiation interrupts */
1203 axgbe_an_clear_interrupts_all(pdata
);
1208 static int axgbe_phy_best_advertised_speed(struct axgbe_port
*pdata
)
1210 if (pdata
->phy
.advertising
& ADVERTISED_10000baseKR_Full
)
1212 else if (pdata
->phy
.advertising
& ADVERTISED_10000baseT_Full
)
1214 else if (pdata
->phy
.advertising
& ADVERTISED_2500baseX_Full
)
1216 else if (pdata
->phy
.advertising
& ADVERTISED_1000baseKX_Full
)
1218 else if (pdata
->phy
.advertising
& ADVERTISED_1000baseT_Full
)
1220 else if (pdata
->phy
.advertising
& ADVERTISED_100baseT_Full
)
1223 return SPEED_UNKNOWN
;
1226 static int axgbe_phy_init(struct axgbe_port
*pdata
)
1230 pdata
->mdio_mmd
= MDIO_MMD_PCS
;
1232 /* Check for FEC support */
1233 pdata
->fec_ability
= XMDIO_READ(pdata
, MDIO_MMD_PMAPMD
,
1234 MDIO_PMA_10GBR_FECABLE
);
1235 pdata
->fec_ability
&= (MDIO_PMA_10GBR_FECABLE_ABLE
|
1236 MDIO_PMA_10GBR_FECABLE_ERRABLE
);
1238 /* Setup the phy (including supported features) */
1239 ret
= pdata
->phy_if
.phy_impl
.init(pdata
);
1242 pdata
->phy
.advertising
= pdata
->phy
.supported
;
1244 pdata
->phy
.address
= 0;
1246 if (pdata
->phy
.advertising
& ADVERTISED_Autoneg
) {
1247 pdata
->phy
.autoneg
= AUTONEG_ENABLE
;
1248 pdata
->phy
.speed
= SPEED_UNKNOWN
;
1249 pdata
->phy
.duplex
= DUPLEX_UNKNOWN
;
1251 pdata
->phy
.autoneg
= AUTONEG_DISABLE
;
1252 pdata
->phy
.speed
= axgbe_phy_best_advertised_speed(pdata
);
1253 pdata
->phy
.duplex
= DUPLEX_FULL
;
1256 pdata
->phy
.link
= 0;
1258 pdata
->phy
.pause_autoneg
= pdata
->pause_autoneg
;
1259 pdata
->phy
.tx_pause
= pdata
->tx_pause
;
1260 pdata
->phy
.rx_pause
= pdata
->rx_pause
;
1262 /* Fix up Flow Control advertising */
1263 pdata
->phy
.advertising
&= ~ADVERTISED_Pause
;
1264 pdata
->phy
.advertising
&= ~ADVERTISED_Asym_Pause
;
1266 if (pdata
->rx_pause
) {
1267 pdata
->phy
.advertising
|= ADVERTISED_Pause
;
1268 pdata
->phy
.advertising
|= ADVERTISED_Asym_Pause
;
1271 if (pdata
->tx_pause
)
1272 pdata
->phy
.advertising
^= ADVERTISED_Asym_Pause
;
1276 void axgbe_init_function_ptrs_phy(struct axgbe_phy_if
*phy_if
)
1278 phy_if
->phy_init
= axgbe_phy_init
;
1279 phy_if
->phy_reset
= axgbe_phy_reset
;
1280 phy_if
->phy_start
= axgbe_phy_start
;
1281 phy_if
->phy_stop
= axgbe_phy_stop
;
1282 phy_if
->phy_status
= axgbe_phy_status
;
1283 phy_if
->phy_config_aneg
= axgbe_phy_config_aneg
;
1284 phy_if
->an_isr
= axgbe_an_combined_isr
;