xref: /dpdk/drivers/net/axgbe/axgbe_mdio.c (revision 68a03efeed657e6e05f281479b33b51102797e15)
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 	PMD_DRV_LOG(DEBUG, "CL73 AN enabled/restarted\n");
305 }
306 
307 static void axgbe_an73_disable(struct axgbe_port *pdata)
308 {
309 	axgbe_an73_set(pdata, false, false);
310 	axgbe_an73_disable_interrupts(pdata);
311 	pdata->an_start = 0;
312 
313 	PMD_DRV_LOG(DEBUG, "CL73 AN disabled\n");
314 }
315 
316 static void axgbe_an_restart(struct axgbe_port *pdata)
317 {
318 	if (pdata->phy_if.phy_impl.an_pre)
319 		pdata->phy_if.phy_impl.an_pre(pdata);
320 
321 	switch (pdata->an_mode) {
322 	case AXGBE_AN_MODE_CL73:
323 	case AXGBE_AN_MODE_CL73_REDRV:
324 		axgbe_an73_restart(pdata);
325 		break;
326 	case AXGBE_AN_MODE_CL37:
327 	case AXGBE_AN_MODE_CL37_SGMII:
328 		axgbe_an37_restart(pdata);
329 		break;
330 	default:
331 		break;
332 	}
333 }
334 
335 static void axgbe_an_disable(struct axgbe_port *pdata)
336 {
337 	if (pdata->phy_if.phy_impl.an_post)
338 		pdata->phy_if.phy_impl.an_post(pdata);
339 
340 	switch (pdata->an_mode) {
341 	case AXGBE_AN_MODE_CL73:
342 	case AXGBE_AN_MODE_CL73_REDRV:
343 		axgbe_an73_disable(pdata);
344 		break;
345 	case AXGBE_AN_MODE_CL37:
346 	case AXGBE_AN_MODE_CL37_SGMII:
347 		axgbe_an37_disable(pdata);
348 		break;
349 	default:
350 		break;
351 	}
352 }
353 
354 static void axgbe_an_disable_all(struct axgbe_port *pdata)
355 {
356 	axgbe_an73_disable(pdata);
357 	axgbe_an37_disable(pdata);
358 }
359 
360 static enum axgbe_an axgbe_an73_tx_training(struct axgbe_port *pdata,
361 					    enum axgbe_rx *state)
362 {
363 	unsigned int ad_reg, lp_reg, reg;
364 
365 	*state = AXGBE_RX_COMPLETE;
366 
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;
370 
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);
374 
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);
380 
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);
386 
387 		reg |= AXGBE_KR_TRAINING_START;
388 		XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL,
389 			    reg);
390 
391 		PMD_DRV_LOG(DEBUG, "KR training initiated\n");
392 
393 		if (pdata->phy_if.phy_impl.kr_training_post)
394 			pdata->phy_if.phy_impl.kr_training_post(pdata);
395 	}
396 
397 	return AXGBE_AN_PAGE_RECEIVED;
398 }
399 
400 static enum axgbe_an axgbe_an73_tx_xnp(struct axgbe_port *pdata,
401 				       enum axgbe_rx *state)
402 {
403 	u16 msg;
404 
405 	*state = AXGBE_RX_XNP;
406 
407 	msg = AXGBE_XNP_MCF_NULL_MESSAGE;
408 	msg |= AXGBE_XNP_MP_FORMATTED;
409 
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);
413 
414 	return AXGBE_AN_PAGE_RECEIVED;
415 }
416 
417 static enum axgbe_an axgbe_an73_rx_bpa(struct axgbe_port *pdata,
418 				       enum axgbe_rx *state)
419 {
420 	unsigned int link_support;
421 	unsigned int reg, ad_reg, lp_reg;
422 
423 	/* Read Base Ability register 2 first */
424 	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
425 
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;
430 
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);
434 
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);
439 }
440 
441 static enum axgbe_an axgbe_an73_rx_xnp(struct axgbe_port *pdata,
442 				       enum axgbe_rx *state)
443 {
444 	unsigned int ad_reg, lp_reg;
445 
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);
449 
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);
454 }
455 
456 static enum axgbe_an axgbe_an73_page_received(struct axgbe_port *pdata)
457 {
458 	enum axgbe_rx *state;
459 	unsigned long an_timeout;
460 	enum axgbe_an ret;
461 	unsigned long ticks;
462 
463 	if (!pdata->an_start) {
464 		pdata->an_start = rte_get_timer_cycles();
465 	} else {
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;
473 
474 			pdata->an_start = rte_get_timer_cycles();
475 
476 			PMD_DRV_LOG(NOTICE,
477 				    "CL73 AN timed out, resetting state\n");
478 		}
479 	}
480 
481 	state = axgbe_in_kr_mode(pdata) ? &pdata->kr_state
482 		: &pdata->kx_state;
483 
484 	switch (*state) {
485 	case AXGBE_RX_BPA:
486 		ret = axgbe_an73_rx_bpa(pdata, state);
487 		break;
488 	case AXGBE_RX_XNP:
489 		ret = axgbe_an73_rx_xnp(pdata, state);
490 		break;
491 	default:
492 		ret = AXGBE_AN_ERROR;
493 	}
494 
495 	return ret;
496 }
497 
498 static enum axgbe_an axgbe_an73_incompat_link(struct axgbe_port *pdata)
499 {
500 	/* Be sure we aren't looping trying to negotiate */
501 	if (axgbe_in_kr_mode(pdata)) {
502 		pdata->kr_state = AXGBE_RX_ERROR;
503 
504 		if (!(pdata->phy.advertising & ADVERTISED_1000baseKX_Full) &&
505 		    !(pdata->phy.advertising & ADVERTISED_2500baseX_Full))
506 			return AXGBE_AN_NO_LINK;
507 
508 		if (pdata->kx_state != AXGBE_RX_BPA)
509 			return AXGBE_AN_NO_LINK;
510 	} else {
511 		pdata->kx_state = AXGBE_RX_ERROR;
512 
513 		if (!(pdata->phy.advertising & ADVERTISED_10000baseKR_Full))
514 			return AXGBE_AN_NO_LINK;
515 
516 		if (pdata->kr_state != AXGBE_RX_BPA)
517 			return AXGBE_AN_NO_LINK;
518 	}
519 
520 	axgbe_an_disable(pdata);
521 	axgbe_switch_mode(pdata);
522 	axgbe_an_restart(pdata);
523 
524 	return AXGBE_AN_INCOMPAT_LINK;
525 }
526 
527 static const char *axgbe_state_as_string(enum axgbe_an state)
528 {
529 	switch (state) {
530 	case AXGBE_AN_READY:
531 		return "Ready";
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:
537 		return "Complete";
538 	case AXGBE_AN_NO_LINK:
539 		return "No-Link";
540 	case AXGBE_AN_ERROR:
541 		return "Error";
542 	default:
543 		return "Undefined";
544 	}
545 }
546 
547 static void axgbe_an73_state_machine(struct axgbe_port *pdata)
548 {
549 	enum axgbe_an cur_state = pdata->an_state;
550 
551 	if (!pdata->an_int)
552 		return;
553 
554 next_int:
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;
564 	} else {
565 		pdata->an_state = AXGBE_AN_ERROR;
566 	}
567 
568 	PMD_DRV_LOG(DEBUG, "CL73 AN : %s\n",
569 		    axgbe_state_as_string(pdata->an_state));
570 
571 again:
572 	cur_state = pdata->an_state;
573 
574 	switch (pdata->an_state) {
575 	case AXGBE_AN_READY:
576 		pdata->an_supported = 0;
577 		break;
578 	case AXGBE_AN_PAGE_RECEIVED:
579 		pdata->an_state = axgbe_an73_page_received(pdata);
580 		pdata->an_supported++;
581 		break;
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);
586 		break;
587 	case AXGBE_AN_COMPLETE:
588 		pdata->parallel_detect = pdata->an_supported ? 0 : 1;
589 		break;
590 	case AXGBE_AN_NO_LINK:
591 		break;
592 	default:
593 		pdata->an_state = AXGBE_AN_ERROR;
594 	}
595 
596 	if (pdata->an_state == AXGBE_AN_NO_LINK) {
597 		pdata->an_int = 0;
598 		axgbe_an73_clear_interrupts(pdata);
599 		pdata->eth_dev->data->dev_link.link_status =
600 			ETH_LINK_DOWN;
601 	} else if (pdata->an_state == AXGBE_AN_ERROR) {
602 		PMD_DRV_LOG(ERR, "error during auto-negotiation, state=%u\n",
603 			    cur_state);
604 		pdata->an_int = 0;
605 		axgbe_an73_clear_interrupts(pdata);
606 	}
607 
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;
613 		pdata->an_start = 0;
614 		if (pdata->phy_if.phy_impl.an_post)
615 			pdata->phy_if.phy_impl.an_post(pdata);
616 
617 		PMD_DRV_LOG(DEBUG, "CL73 AN result: %s\n",
618 			    axgbe_state_as_string(pdata->an_result));
619 	}
620 
621 	if (cur_state != pdata->an_state)
622 		goto again;
623 
624 	if (pdata->an_int)
625 		goto next_int;
626 
627 	axgbe_an73_enable_interrupts(pdata);
628 }
629 
630 static void axgbe_an37_state_machine(struct axgbe_port *pdata)
631 {
632 	enum axgbe_an cur_state = pdata->an_state;
633 
634 	if (!pdata->an_int)
635 		return;
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;
639 
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;
644 	}
645 
646 	cur_state = pdata->an_state;
647 
648 	switch (pdata->an_state) {
649 	case AXGBE_AN_READY:
650 		break;
651 	case AXGBE_AN_COMPLETE:
652 		break;
653 	case AXGBE_AN_NO_LINK:
654 		break;
655 	default:
656 		pdata->an_state = AXGBE_AN_ERROR;
657 		break;
658 	}
659 
660 	if (pdata->an_state == AXGBE_AN_ERROR) {
661 		PMD_DRV_LOG(ERR, "error during auto-negotiation, state=%u\n",
662 			    cur_state);
663 		pdata->an_int = 0;
664 		axgbe_an37_clear_interrupts(pdata);
665 	}
666 
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);
672 	}
673 
674 	axgbe_an37_enable_interrupts(pdata);
675 }
676 
677 static void axgbe_an73_isr(struct axgbe_port *pdata)
678 {
679 	/* Disable AN interrupts */
680 	axgbe_an73_disable_interrupts(pdata);
681 
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);
685 
686 	if (pdata->an_int) {
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);
692 	} else {
693 		/* Enable AN interrupts */
694 		axgbe_an73_enable_interrupts(pdata);
695 	}
696 }
697 
698 static void axgbe_an37_isr(struct axgbe_port *pdata)
699 {
700 	unsigned int reg = 0;
701 	/* Disable AN interrupts */
702 	axgbe_an37_disable_interrupts(pdata);
703 
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);
709 
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);
715 	} else {
716 		/* Enable AN interrupts */
717 		axgbe_an37_enable_interrupts(pdata);
718 	}
719 }
720 
721 static void axgbe_an_isr(struct axgbe_port *pdata)
722 {
723 	PMD_DRV_LOG(DEBUG, "AN interrupt received\n");
724 
725 	switch (pdata->an_mode) {
726 	case AXGBE_AN_MODE_CL73:
727 	case AXGBE_AN_MODE_CL73_REDRV:
728 		axgbe_an73_isr(pdata);
729 		break;
730 	case AXGBE_AN_MODE_CL37:
731 	case AXGBE_AN_MODE_CL37_SGMII:
732 		axgbe_an37_isr(pdata);
733 		break;
734 	default:
735 		break;
736 	}
737 }
738 
739 static void axgbe_an_combined_isr(struct axgbe_port *pdata)
740 {
741 	axgbe_an_isr(pdata);
742 }
743 
744 static void axgbe_an37_init(struct axgbe_port *pdata)
745 {
746 	unsigned int advertising;
747 	unsigned int reg = 0;
748 
749 	advertising = pdata->phy_if.phy_impl.an_advertising(pdata);
750 
751 	reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE);
752 	if (advertising & ADVERTISED_Pause)
753 		reg |= 0x100;
754 	else
755 		reg &= ~0x100;
756 	if (advertising & ADVERTISED_Asym_Pause)
757 		reg |= 0x80;
758 	else
759 		reg &= ~0x80;
760 
761 	/* Full duplex, but not half */
762 	reg |= AXGBE_AN_CL37_FD_MASK;
763 	reg &= ~AXGBE_AN_CL37_HD_MASK;
764 
765 	XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE, reg);
766 
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;
771 
772 	switch (pdata->an_mode) {
773 	case AXGBE_AN_MODE_CL37:
774 		reg |= AXGBE_AN_CL37_PCS_MODE_BASEX;
775 		break;
776 	case AXGBE_AN_MODE_CL37_SGMII:
777 		reg |= AXGBE_AN_CL37_PCS_MODE_SGMII;
778 		break;
779 	default:
780 		break;
781 	}
782 	reg |= AXGBE_AN_CL37_MII_CTRL_8BIT;
783 	XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
784 }
785 
786 static void axgbe_an73_init(struct axgbe_port *pdata)
787 {
788 	unsigned int advertising, reg;
789 
790 	advertising = pdata->phy_if.phy_impl.an_advertising(pdata);
791 
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)
795 		reg |= 0xc000;
796 	else
797 		reg &= ~0xc000;
798 
799 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, reg);
800 
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)
804 		reg |= 0x80;
805 	else
806 		reg &= ~0x80;
807 
808 	if ((advertising & ADVERTISED_1000baseKX_Full) ||
809 	    (advertising & ADVERTISED_2500baseX_Full))
810 		reg |= 0x20;
811 	else
812 		reg &= ~0x20;
813 
814 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, reg);
815 
816 	/* Set up Advertisement register 1 last */
817 	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
818 	if (advertising & ADVERTISED_Pause)
819 		reg |= 0x400;
820 	else
821 		reg &= ~0x400;
822 
823 	if (advertising & ADVERTISED_Asym_Pause)
824 		reg |= 0x800;
825 	else
826 		reg &= ~0x800;
827 
828 	/* We don't intend to perform XNP */
829 	reg &= ~AXGBE_XNP_NP_EXCHANGE;
830 
831 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
832 
833 	PMD_DRV_LOG(DEBUG, "CL73 AN initialized\n");
834 }
835 
836 static void axgbe_an_init(struct axgbe_port *pdata)
837 {
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);
844 		break;
845 	case AXGBE_AN_MODE_CL37:
846 	case AXGBE_AN_MODE_CL37_SGMII:
847 		axgbe_an37_init(pdata);
848 		break;
849 	default:
850 		break;
851 	}
852 }
853 
854 static void axgbe_phy_adjust_link(struct axgbe_port *pdata)
855 {
856 	if (pdata->phy.link) {
857 		/* Flow control support */
858 		pdata->pause_autoneg = pdata->phy.pause_autoneg;
859 
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;
863 		}
864 
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;
868 		}
869 
870 		/* Speed support */
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) {
876 		pdata->phy_link = 0;
877 		pdata->phy_speed = SPEED_UNKNOWN;
878 	}
879 }
880 
881 static int axgbe_phy_config_fixed(struct axgbe_port *pdata)
882 {
883 	enum axgbe_mode mode;
884 
885 	PMD_DRV_LOG(DEBUG, "fixed PHY configuration\n");
886 
887 	/* Disable auto-negotiation */
888 	axgbe_an_disable(pdata);
889 
890 	/* Set specified mode for specified speed */
891 	mode = pdata->phy_if.phy_impl.get_mode(pdata, pdata->phy.speed);
892 	switch (mode) {
893 	case AXGBE_MODE_KX_1000:
894 	case AXGBE_MODE_KX_2500:
895 	case AXGBE_MODE_KR:
896 	case AXGBE_MODE_SGMII_100:
897 	case AXGBE_MODE_SGMII_1000:
898 	case AXGBE_MODE_X:
899 	case AXGBE_MODE_SFI:
900 		break;
901 	case AXGBE_MODE_UNKNOWN:
902 	default:
903 		return -EINVAL;
904 	}
905 
906 	/* Validate duplex mode */
907 	if (pdata->phy.duplex != DUPLEX_FULL)
908 		return -EINVAL;
909 
910 	axgbe_set_mode(pdata, mode);
911 
912 	return 0;
913 }
914 
915 static int __axgbe_phy_config_aneg(struct axgbe_port *pdata)
916 {
917 	int ret;
918 
919 	rte_bit_relaxed_set32(AXGBE_LINK_INIT, &pdata->dev_state);
920 	pdata->link_check = rte_get_timer_cycles();
921 
922 	ret = pdata->phy_if.phy_impl.an_config(pdata);
923 	if (ret)
924 		return ret;
925 
926 	if (pdata->phy.autoneg != AUTONEG_ENABLE) {
927 		ret = axgbe_phy_config_fixed(pdata);
928 		if (ret || !pdata->kr_redrv)
929 			return ret;
930 		PMD_DRV_LOG(DEBUG, "AN redriver support\n");
931 	} else {
932 		PMD_DRV_LOG(DEBUG, "AN PHY configuration\n");
933 	}
934 
935 	/* Disable auto-negotiation interrupt */
936 	rte_intr_disable(&pdata->pci_dev->intr_handle);
937 
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);
953 	} else {
954 		rte_intr_enable(&pdata->pci_dev->intr_handle);
955 		return -EINVAL;
956 	}
957 
958 	/* Disable and stop any in progress auto-negotiation */
959 	axgbe_an_disable_all(pdata);
960 
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;
965 
966 	/* Re-enable auto-negotiation interrupt */
967 	rte_intr_enable(&pdata->pci_dev->intr_handle);
968 	axgbe_an37_enable_interrupts(pdata);
969 
970 	axgbe_an_init(pdata);
971 	axgbe_an_restart(pdata);
972 
973 	return 0;
974 }
975 
976 static int axgbe_phy_config_aneg(struct axgbe_port *pdata)
977 {
978 	int ret;
979 
980 	pthread_mutex_lock(&pdata->an_mutex);
981 
982 	ret = __axgbe_phy_config_aneg(pdata);
983 	if (ret)
984 		rte_bit_relaxed_set32(AXGBE_LINK_ERR, &pdata->dev_state);
985 	else
986 		rte_bit_relaxed_clear32(AXGBE_LINK_ERR, &pdata->dev_state);
987 
988 	pthread_mutex_unlock(&pdata->an_mutex);
989 
990 	return ret;
991 }
992 
993 static bool axgbe_phy_aneg_done(struct axgbe_port *pdata)
994 {
995 	return pdata->an_result == AXGBE_AN_COMPLETE;
996 }
997 
998 static void axgbe_check_link_timeout(struct axgbe_port *pdata)
999 {
1000 	unsigned long link_timeout;
1001 	unsigned long ticks;
1002 
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);
1009 	}
1010 }
1011 
1012 static enum axgbe_mode axgbe_phy_status_aneg(struct axgbe_port *pdata)
1013 {
1014 	return pdata->phy_if.phy_impl.an_outcome(pdata);
1015 }
1016 
1017 static void axgbe_phy_status_result(struct axgbe_port *pdata)
1018 {
1019 	enum axgbe_mode mode;
1020 
1021 	pdata->phy.lp_advertising = 0;
1022 
1023 	if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect)
1024 		mode = axgbe_cur_mode(pdata);
1025 	else
1026 		mode = axgbe_phy_status_aneg(pdata);
1027 
1028 	switch (mode) {
1029 	case AXGBE_MODE_SGMII_100:
1030 		pdata->phy.speed = SPEED_100;
1031 		break;
1032 	case AXGBE_MODE_X:
1033 	case AXGBE_MODE_KX_1000:
1034 	case AXGBE_MODE_SGMII_1000:
1035 		pdata->phy.speed = SPEED_1000;
1036 		break;
1037 	case AXGBE_MODE_KX_2500:
1038 		pdata->phy.speed = SPEED_2500;
1039 		break;
1040 	case AXGBE_MODE_KR:
1041 	case AXGBE_MODE_SFI:
1042 		pdata->phy.speed = SPEED_10000;
1043 		break;
1044 	case AXGBE_MODE_UNKNOWN:
1045 	default:
1046 		pdata->phy.speed = SPEED_UNKNOWN;
1047 	}
1048 
1049 	pdata->phy.duplex = DUPLEX_FULL;
1050 
1051 	axgbe_set_mode(pdata, mode);
1052 }
1053 
1054 static int autoneg_time_out(unsigned long autoneg_start_time)
1055 {
1056 	unsigned long autoneg_timeout;
1057 	unsigned long ticks;
1058 
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))
1063 		return 1;
1064 	else
1065 		return 0;
1066 }
1067 
1068 static void axgbe_phy_status(struct axgbe_port *pdata)
1069 {
1070 	unsigned int link_aneg;
1071 	int an_restart, ret;
1072 	unsigned int reg = 0;
1073 	unsigned long autoneg_start_time;
1074 
1075 	if (rte_bit_relaxed_get32(AXGBE_LINK_ERR, &pdata->dev_state)) {
1076 		pdata->phy.link = 0;
1077 		goto adjust_link;
1078 	}
1079 
1080 	link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE);
1081 
1082 	pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata,
1083 							     &an_restart);
1084 	if (an_restart) {
1085 		axgbe_phy_config_aneg(pdata);
1086 		return;
1087 	}
1088 
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)) {
1101 					ret =
1102 					autoneg_time_out(autoneg_start_time);
1103 					if (ret)
1104 						break;
1105 					reg = XMDIO_READ(pdata,
1106 							 MDIO_MMD_VEND2,
1107 							 MDIO_VEND2_AN_STAT);
1108 					if (reg & AXGBE_AN_CL37_INT_CMPLT) {
1109 						axgbe_an37_isr(pdata);
1110 						break;
1111 					}
1112 				}
1113 			} else {
1114 				axgbe_check_link_timeout(pdata);
1115 				return;
1116 			}
1117 		}
1118 		axgbe_phy_status_result(pdata);
1119 		if (rte_bit_relaxed_get32(AXGBE_LINK_INIT, &pdata->dev_state))
1120 			rte_bit_relaxed_clear32(AXGBE_LINK_INIT,
1121 						&pdata->dev_state);
1122 	} else {
1123 		if (rte_bit_relaxed_get32(AXGBE_LINK_INIT, &pdata->dev_state)) {
1124 			axgbe_check_link_timeout(pdata);
1125 
1126 			if (link_aneg)
1127 				return;
1128 		}
1129 		axgbe_phy_status_result(pdata);
1130 	}
1131 
1132 adjust_link:
1133 	axgbe_phy_adjust_link(pdata);
1134 }
1135 
1136 static void axgbe_phy_stop(struct axgbe_port *pdata)
1137 {
1138 	PMD_DRV_LOG(DEBUG, "stopping PHY\n");
1139 	if (!pdata->phy_started)
1140 		return;
1141 	/* Indicate the PHY is down */
1142 	pdata->phy_started = 0;
1143 	/* Disable auto-negotiation */
1144 	axgbe_an_disable_all(pdata);
1145 	pdata->phy_if.phy_impl.stop(pdata);
1146 	pdata->phy.link = 0;
1147 	axgbe_phy_adjust_link(pdata);
1148 }
1149 
1150 static int axgbe_phy_start(struct axgbe_port *pdata)
1151 {
1152 	int ret;
1153 
1154 	PMD_DRV_LOG(DEBUG, "starting PHY\n");
1155 
1156 	ret = pdata->phy_if.phy_impl.start(pdata);
1157 	if (ret)
1158 		return ret;
1159 	/* Set initial mode - call the mode setting routines
1160 	 * directly to insure we are properly configured
1161 	 */
1162 	if (axgbe_use_mode(pdata, AXGBE_MODE_KR)) {
1163 		axgbe_kr_mode(pdata);
1164 	} else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_2500)) {
1165 		axgbe_kx_2500_mode(pdata);
1166 	} else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_1000)) {
1167 		axgbe_kx_1000_mode(pdata);
1168 	} else if (axgbe_use_mode(pdata, AXGBE_MODE_SFI)) {
1169 		axgbe_sfi_mode(pdata);
1170 	} else if (axgbe_use_mode(pdata, AXGBE_MODE_X)) {
1171 		axgbe_x_mode(pdata);
1172 	} else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_1000)) {
1173 		axgbe_sgmii_1000_mode(pdata);
1174 	} else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_100)) {
1175 		axgbe_sgmii_100_mode(pdata);
1176 	} else {
1177 		ret = -EINVAL;
1178 		goto err_stop;
1179 	}
1180 	/* Indicate the PHY is up and running */
1181 	pdata->phy_started = 1;
1182 	axgbe_an_init(pdata);
1183 	axgbe_an_enable_interrupts(pdata);
1184 	return axgbe_phy_config_aneg(pdata);
1185 
1186 err_stop:
1187 	pdata->phy_if.phy_impl.stop(pdata);
1188 
1189 	return ret;
1190 }
1191 
1192 static int axgbe_phy_reset(struct axgbe_port *pdata)
1193 {
1194 	int ret;
1195 
1196 	ret = pdata->phy_if.phy_impl.reset(pdata);
1197 	if (ret)
1198 		return ret;
1199 
1200 	/* Disable auto-negotiation for now */
1201 	axgbe_an_disable_all(pdata);
1202 
1203 	/* Clear auto-negotiation interrupts */
1204 	axgbe_an_clear_interrupts_all(pdata);
1205 
1206 	return 0;
1207 }
1208 
1209 static int axgbe_phy_best_advertised_speed(struct axgbe_port *pdata)
1210 {
1211 	if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full)
1212 		return SPEED_10000;
1213 	else if (pdata->phy.advertising & ADVERTISED_10000baseT_Full)
1214 		return SPEED_10000;
1215 	else if (pdata->phy.advertising & ADVERTISED_2500baseX_Full)
1216 		return SPEED_2500;
1217 	else if (pdata->phy.advertising & ADVERTISED_1000baseKX_Full)
1218 		return SPEED_1000;
1219 	else if (pdata->phy.advertising & ADVERTISED_1000baseT_Full)
1220 		return SPEED_1000;
1221 	else if (pdata->phy.advertising & ADVERTISED_100baseT_Full)
1222 		return SPEED_100;
1223 
1224 	return SPEED_UNKNOWN;
1225 }
1226 
1227 static int axgbe_phy_init(struct axgbe_port *pdata)
1228 {
1229 	int ret;
1230 
1231 	pdata->mdio_mmd = MDIO_MMD_PCS;
1232 
1233 	/* Check for FEC support */
1234 	pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD,
1235 					MDIO_PMA_10GBR_FECABLE);
1236 	pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE |
1237 			       MDIO_PMA_10GBR_FECABLE_ERRABLE);
1238 
1239 	/* Setup the phy (including supported features) */
1240 	ret = pdata->phy_if.phy_impl.init(pdata);
1241 	if (ret)
1242 		return ret;
1243 	pdata->phy.advertising = pdata->phy.supported;
1244 
1245 	pdata->phy.address = 0;
1246 
1247 	if (pdata->phy.advertising & ADVERTISED_Autoneg) {
1248 		pdata->phy.autoneg = AUTONEG_ENABLE;
1249 		pdata->phy.speed = SPEED_UNKNOWN;
1250 		pdata->phy.duplex = DUPLEX_UNKNOWN;
1251 	} else {
1252 		pdata->phy.autoneg = AUTONEG_DISABLE;
1253 		pdata->phy.speed = axgbe_phy_best_advertised_speed(pdata);
1254 		pdata->phy.duplex = DUPLEX_FULL;
1255 	}
1256 
1257 	pdata->phy.link = 0;
1258 
1259 	pdata->phy.pause_autoneg = pdata->pause_autoneg;
1260 	pdata->phy.tx_pause = pdata->tx_pause;
1261 	pdata->phy.rx_pause = pdata->rx_pause;
1262 
1263 	/* Fix up Flow Control advertising */
1264 	pdata->phy.advertising &= ~ADVERTISED_Pause;
1265 	pdata->phy.advertising &= ~ADVERTISED_Asym_Pause;
1266 
1267 	if (pdata->rx_pause) {
1268 		pdata->phy.advertising |= ADVERTISED_Pause;
1269 		pdata->phy.advertising |= ADVERTISED_Asym_Pause;
1270 	}
1271 
1272 	if (pdata->tx_pause)
1273 		pdata->phy.advertising ^= ADVERTISED_Asym_Pause;
1274 	return 0;
1275 }
1276 
1277 void axgbe_init_function_ptrs_phy(struct axgbe_phy_if *phy_if)
1278 {
1279 	phy_if->phy_init        = axgbe_phy_init;
1280 	phy_if->phy_reset       = axgbe_phy_reset;
1281 	phy_if->phy_start       = axgbe_phy_start;
1282 	phy_if->phy_stop        = axgbe_phy_stop;
1283 	phy_if->phy_status      = axgbe_phy_status;
1284 	phy_if->phy_config_aneg = axgbe_phy_config_aneg;
1285 	phy_if->an_isr          = axgbe_an_combined_isr;
1286 }
1287