xref: /dpdk/drivers/net/axgbe/axgbe_mdio.c (revision 9e991f217fc8719e38a812dc280dba5f84db9f59)
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