xref: /freebsd/sys/dev/axgbe/xgbe-mdio.c (revision 22cf89c938886d14f5796fc49f9f020c23ea8eaf)
1 /*
2  * AMD 10Gb Ethernet driver
3  *
4  * Copyright (c) 2014-2016,2020 Advanced Micro Devices, Inc.
5  *
6  * This file is available to you under your choice of the following two
7  * licenses:
8  *
9  * License 1: GPLv2
10  *
11  * This file is free software; you may copy, redistribute and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 2 of the License, or (at
14  * your option) any later version.
15  *
16  * This file is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23  *
24  * This file incorporates work covered by the following copyright and
25  * permission notice:
26  *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
27  *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
28  *     Inc. unless otherwise expressly agreed to in writing between Synopsys
29  *     and you.
30  *
31  *     The Software IS NOT an item of Licensed Software or Licensed Product
32  *     under any End User Software License Agreement or Agreement for Licensed
33  *     Product with Synopsys or any supplement thereto.  Permission is hereby
34  *     granted, free of charge, to any person obtaining a copy of this software
35  *     annotated with this license and the Software, to deal in the Software
36  *     without restriction, including without limitation the rights to use,
37  *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
38  *     of the Software, and to permit persons to whom the Software is furnished
39  *     to do so, subject to the following conditions:
40  *
41  *     The above copyright notice and this permission notice shall be included
42  *     in all copies or substantial portions of the Software.
43  *
44  *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
45  *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
46  *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
47  *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
48  *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
49  *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
50  *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
51  *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
52  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53  *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
54  *     THE POSSIBILITY OF SUCH DAMAGE.
55  *
56  *
57  * License 2: Modified BSD
58  *
59  * Redistribution and use in source and binary forms, with or without
60  * modification, are permitted provided that the following conditions are met:
61  *     * Redistributions of source code must retain the above copyright
62  *       notice, this list of conditions and the following disclaimer.
63  *     * Redistributions in binary form must reproduce the above copyright
64  *       notice, this list of conditions and the following disclaimer in the
65  *       documentation and/or other materials provided with the distribution.
66  *     * Neither the name of Advanced Micro Devices, Inc. nor the
67  *       names of its contributors may be used to endorse or promote products
68  *       derived from this software without specific prior written permission.
69  *
70  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
71  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
72  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
73  * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
74  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
79  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80  *
81  * This file incorporates work covered by the following copyright and
82  * permission notice:
83  *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
84  *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
85  *     Inc. unless otherwise expressly agreed to in writing between Synopsys
86  *     and you.
87  *
88  *     The Software IS NOT an item of Licensed Software or Licensed Product
89  *     under any End User Software License Agreement or Agreement for Licensed
90  *     Product with Synopsys or any supplement thereto.  Permission is hereby
91  *     granted, free of charge, to any person obtaining a copy of this software
92  *     annotated with this license and the Software, to deal in the Software
93  *     without restriction, including without limitation the rights to use,
94  *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
95  *     of the Software, and to permit persons to whom the Software is furnished
96  *     to do so, subject to the following conditions:
97  *
98  *     The above copyright notice and this permission notice shall be included
99  *     in all copies or substantial portions of the Software.
100  *
101  *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
102  *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
103  *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
104  *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
105  *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
106  *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
107  *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
108  *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
109  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
110  *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
111  *     THE POSSIBILITY OF SUCH DAMAGE.
112  */
113 
114 #include <sys/cdefs.h>
115 #include "xgbe.h"
116 #include "xgbe-common.h"
117 
118 static void xgbe_an_state_machine(struct xgbe_prv_data *pdata);
119 
120 static void
121 xgbe_an37_clear_interrupts(struct xgbe_prv_data *pdata)
122 {
123 	int reg;
124 
125 	reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT);
126 	reg &= ~XGBE_AN_CL37_INT_MASK;
127 	XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg);
128 }
129 
130 static void
131 xgbe_an37_disable_interrupts(struct xgbe_prv_data *pdata)
132 {
133 	int reg;
134 
135 	reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);
136 	reg &= ~XGBE_AN_CL37_INT_MASK;
137 	XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
138 
139 	reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL);
140 	reg &= ~XGBE_PCS_CL37_BP;
141 	XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL, reg);
142 }
143 
144 static void
145 xgbe_an37_enable_interrupts(struct xgbe_prv_data *pdata)
146 {
147 	int reg;
148 
149 	reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL);
150 	reg |= XGBE_PCS_CL37_BP;
151 	XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL, reg);
152 
153 	reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);
154 	reg |= XGBE_AN_CL37_INT_MASK;
155 	XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
156 }
157 
158 static void
159 xgbe_an73_clear_interrupts(struct xgbe_prv_data *pdata)
160 {
161 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
162 }
163 
164 static void
165 xgbe_an73_disable_interrupts(struct xgbe_prv_data *pdata)
166 {
167 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);
168 }
169 
170 static void
171 xgbe_an73_enable_interrupts(struct xgbe_prv_data *pdata)
172 {
173 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, XGBE_AN_CL73_INT_MASK);
174 }
175 
176 static void
177 xgbe_an_enable_interrupts(struct xgbe_prv_data *pdata)
178 {
179 	switch (pdata->an_mode) {
180 	case XGBE_AN_MODE_CL73:
181 	case XGBE_AN_MODE_CL73_REDRV:
182 		xgbe_an73_enable_interrupts(pdata);
183 		break;
184 	case XGBE_AN_MODE_CL37:
185 	case XGBE_AN_MODE_CL37_SGMII:
186 		xgbe_an37_enable_interrupts(pdata);
187 		break;
188 	default:
189 		break;
190 	}
191 }
192 
193 static void
194 xgbe_an_clear_interrupts_all(struct xgbe_prv_data *pdata)
195 {
196 	xgbe_an73_clear_interrupts(pdata);
197 	xgbe_an37_clear_interrupts(pdata);
198 }
199 
200 static void
201 xgbe_kr_mode(struct xgbe_prv_data *pdata)
202 {
203 	/* Set MAC to 10G speed */
204 	pdata->hw_if.set_speed(pdata, SPEED_10000);
205 
206 	/* Call PHY implementation support to complete rate change */
207 	pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KR);
208 }
209 
210 static void
211 xgbe_kx_2500_mode(struct xgbe_prv_data *pdata)
212 {
213 	/* Set MAC to 2.5G speed */
214 	pdata->hw_if.set_speed(pdata, SPEED_2500);
215 
216 	/* Call PHY implementation support to complete rate change */
217 	pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KX_2500);
218 }
219 
220 static void
221 xgbe_kx_1000_mode(struct xgbe_prv_data *pdata)
222 {
223 	/* Set MAC to 1G speed */
224 	pdata->hw_if.set_speed(pdata, SPEED_1000);
225 
226 	/* Call PHY implementation support to complete rate change */
227 	pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KX_1000);
228 }
229 
230 static void
231 xgbe_sfi_mode(struct xgbe_prv_data *pdata)
232 {
233 	/* If a KR re-driver is present, change to KR mode instead */
234 	if (pdata->kr_redrv)
235 		return (xgbe_kr_mode(pdata));
236 
237 	/* Set MAC to 10G speed */
238 	pdata->hw_if.set_speed(pdata, SPEED_10000);
239 
240 	/* Call PHY implementation support to complete rate change */
241 	pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SFI);
242 }
243 
244 static void
245 xgbe_x_mode(struct xgbe_prv_data *pdata)
246 {
247 	/* Set MAC to 1G speed */
248 	pdata->hw_if.set_speed(pdata, SPEED_1000);
249 
250 	/* Call PHY implementation support to complete rate change */
251 	pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_X);
252 }
253 
254 static void
255 xgbe_sgmii_1000_mode(struct xgbe_prv_data *pdata)
256 {
257 	/* Set MAC to 1G speed */
258 	pdata->hw_if.set_speed(pdata, SPEED_1000);
259 
260 	/* Call PHY implementation support to complete rate change */
261 	pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_1000);
262 }
263 
264 static void
265 xgbe_sgmii_100_mode(struct xgbe_prv_data *pdata)
266 {
267 	/* Set MAC to 1G speed */
268 	pdata->hw_if.set_speed(pdata, SPEED_1000);
269 
270 	/* Call PHY implementation support to complete rate change */
271 	pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_100);
272 }
273 
274 static enum xgbe_mode
275 xgbe_cur_mode(struct xgbe_prv_data *pdata)
276 {
277 	return (pdata->phy_if.phy_impl.cur_mode(pdata));
278 }
279 
280 static bool
281 xgbe_in_kr_mode(struct xgbe_prv_data *pdata)
282 {
283 	return (xgbe_cur_mode(pdata) == XGBE_MODE_KR);
284 }
285 
286 static void
287 xgbe_change_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
288 {
289 	switch (mode) {
290 	case XGBE_MODE_KX_1000:
291 		xgbe_kx_1000_mode(pdata);
292 		break;
293 	case XGBE_MODE_KX_2500:
294 		xgbe_kx_2500_mode(pdata);
295 		break;
296 	case XGBE_MODE_KR:
297 		xgbe_kr_mode(pdata);
298 		break;
299 	case XGBE_MODE_SGMII_100:
300 		xgbe_sgmii_100_mode(pdata);
301 		break;
302 	case XGBE_MODE_SGMII_1000:
303 		xgbe_sgmii_1000_mode(pdata);
304 		break;
305 	case XGBE_MODE_X:
306 		xgbe_x_mode(pdata);
307 		break;
308 	case XGBE_MODE_SFI:
309 		xgbe_sfi_mode(pdata);
310 		break;
311 	case XGBE_MODE_UNKNOWN:
312 		break;
313 	default:
314 		axgbe_error("invalid operation mode requested (%u)\n", mode);
315 	}
316 }
317 
318 static void
319 xgbe_switch_mode(struct xgbe_prv_data *pdata)
320 {
321 	xgbe_change_mode(pdata, pdata->phy_if.phy_impl.switch_mode(pdata));
322 }
323 
324 static bool
325 xgbe_set_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
326 {
327 	if (mode == xgbe_cur_mode(pdata))
328 		return (false);
329 
330 	xgbe_change_mode(pdata, mode);
331 
332 	return (true);
333 }
334 
335 static bool
336 xgbe_use_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
337 {
338 	return (pdata->phy_if.phy_impl.use_mode(pdata, mode));
339 }
340 
341 static void
342 xgbe_an37_set(struct xgbe_prv_data *pdata, bool enable, bool restart)
343 {
344 	unsigned int reg;
345 
346 	reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_CTRL1);
347 	reg &= ~MDIO_VEND2_CTRL1_AN_ENABLE;
348 
349 	if (enable)
350 		reg |= MDIO_VEND2_CTRL1_AN_ENABLE;
351 
352 	if (restart)
353 		reg |= MDIO_VEND2_CTRL1_AN_RESTART;
354 
355 	XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_CTRL1, reg);
356 }
357 
358 static void
359 xgbe_an37_restart(struct xgbe_prv_data *pdata)
360 {
361 	xgbe_an37_enable_interrupts(pdata);
362 	xgbe_an37_set(pdata, true, true);
363 }
364 
365 static void
366 xgbe_an37_disable(struct xgbe_prv_data *pdata)
367 {
368 	xgbe_an37_set(pdata, false, false);
369 	xgbe_an37_disable_interrupts(pdata);
370 }
371 
372 static void
373 xgbe_an73_set(struct xgbe_prv_data *pdata, bool enable, bool restart)
374 {
375 	unsigned int reg;
376 
377 	/* Disable KR training for now */
378 	reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
379 	reg &= ~XGBE_KR_TRAINING_ENABLE;
380 	XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
381 
382 	/* Update AN settings */
383 	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1);
384 	reg &= ~MDIO_AN_CTRL1_ENABLE;
385 
386 	if (enable)
387 		reg |= MDIO_AN_CTRL1_ENABLE;
388 
389 	if (restart)
390 		reg |= MDIO_AN_CTRL1_RESTART;
391 
392 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg);
393 }
394 
395 static void
396 xgbe_an73_restart(struct xgbe_prv_data *pdata)
397 {
398 	xgbe_an73_enable_interrupts(pdata);
399 	xgbe_an73_set(pdata, true, true);
400 }
401 
402 static void
403 xgbe_an73_disable(struct xgbe_prv_data *pdata)
404 {
405 	xgbe_an73_set(pdata, false, false);
406 	xgbe_an73_disable_interrupts(pdata);
407 
408 	pdata->an_start = 0;
409 }
410 
411 static void
412 xgbe_an_restart(struct xgbe_prv_data *pdata)
413 {
414 	if (pdata->phy_if.phy_impl.an_pre)
415 		pdata->phy_if.phy_impl.an_pre(pdata);
416 
417 	switch (pdata->an_mode) {
418 	case XGBE_AN_MODE_CL73:
419 	case XGBE_AN_MODE_CL73_REDRV:
420 		xgbe_an73_restart(pdata);
421 		break;
422 	case XGBE_AN_MODE_CL37:
423 	case XGBE_AN_MODE_CL37_SGMII:
424 		xgbe_an37_restart(pdata);
425 		break;
426 	default:
427 		break;
428 	}
429 }
430 
431 static void
432 xgbe_an_disable(struct xgbe_prv_data *pdata)
433 {
434 	if (pdata->phy_if.phy_impl.an_post)
435 		pdata->phy_if.phy_impl.an_post(pdata);
436 
437 	switch (pdata->an_mode) {
438 	case XGBE_AN_MODE_CL73:
439 	case XGBE_AN_MODE_CL73_REDRV:
440 		xgbe_an73_disable(pdata);
441 		break;
442 	case XGBE_AN_MODE_CL37:
443 	case XGBE_AN_MODE_CL37_SGMII:
444 		xgbe_an37_disable(pdata);
445 		break;
446 	default:
447 		break;
448 	}
449 }
450 
451 static void
452 xgbe_an_disable_all(struct xgbe_prv_data *pdata)
453 {
454 	xgbe_an73_disable(pdata);
455 	xgbe_an37_disable(pdata);
456 }
457 
458 static enum xgbe_an
459 xgbe_an73_tx_training(struct xgbe_prv_data *pdata, enum xgbe_rx *state)
460 {
461 	unsigned int ad_reg, lp_reg, reg;
462 
463 	*state = XGBE_RX_COMPLETE;
464 
465 	/* If we're not in KR mode then we're done */
466 	if (!xgbe_in_kr_mode(pdata))
467 		return (XGBE_AN_PAGE_RECEIVED);
468 
469 	/* Enable/Disable FEC */
470 	ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
471 	lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
472 
473 	reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL);
474 	reg &= ~(MDIO_PMA_10GBR_FECABLE_ABLE | MDIO_PMA_10GBR_FECABLE_ERRABLE);
475 	if ((ad_reg & 0xc000) && (lp_reg & 0xc000))
476 		reg |= pdata->fec_ability;
477 
478 	XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL, reg);
479 
480 	/* Start KR training */
481 	if (pdata->phy_if.phy_impl.kr_training_pre)
482 		pdata->phy_if.phy_impl.kr_training_pre(pdata);
483 
484 	/* Start KR training */
485 	reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
486 	reg |= XGBE_KR_TRAINING_ENABLE;
487 	reg |= XGBE_KR_TRAINING_START;
488 	XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
489 
490 	if (pdata->phy_if.phy_impl.kr_training_post)
491 		pdata->phy_if.phy_impl.kr_training_post(pdata);
492 
493 	return (XGBE_AN_PAGE_RECEIVED);
494 }
495 
496 static enum xgbe_an
497 xgbe_an73_tx_xnp(struct xgbe_prv_data *pdata, enum xgbe_rx *state)
498 {
499 	uint16_t msg;
500 
501 	*state = XGBE_RX_XNP;
502 
503 	msg = XGBE_XNP_MCF_NULL_MESSAGE;
504 	msg |= XGBE_XNP_MP_FORMATTED;
505 
506 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 2, 0);
507 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 1, 0);
508 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP, msg);
509 
510 	return (XGBE_AN_PAGE_RECEIVED);
511 }
512 
513 static enum xgbe_an
514 xgbe_an73_rx_bpa(struct xgbe_prv_data *pdata, enum xgbe_rx *state)
515 {
516 	unsigned int link_support;
517 	unsigned int reg, ad_reg, lp_reg;
518 
519 	/* Read Base Ability register 2 first */
520 	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
521 
522 	/* Check for a supported mode, otherwise restart in a different one */
523 	link_support = xgbe_in_kr_mode(pdata) ? 0x80 : 0x20;
524 	if (!(reg & link_support))
525 		return (XGBE_AN_INCOMPAT_LINK);
526 
527 	/* Check Extended Next Page support */
528 	ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
529 	lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA);
530 
531 	return (((ad_reg & XGBE_XNP_NP_EXCHANGE) ||
532 		(lp_reg & XGBE_XNP_NP_EXCHANGE))
533 	       ? xgbe_an73_tx_xnp(pdata, state)
534 	       : xgbe_an73_tx_training(pdata, state));
535 }
536 
537 static enum xgbe_an
538 xgbe_an73_rx_xnp(struct xgbe_prv_data *pdata, enum xgbe_rx *state)
539 {
540 	unsigned int ad_reg, lp_reg;
541 
542 	/* Check Extended Next Page support */
543 	ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_XNP);
544 	lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPX);
545 
546 	return (((ad_reg & XGBE_XNP_NP_EXCHANGE) ||
547 		(lp_reg & XGBE_XNP_NP_EXCHANGE))
548 	       ? xgbe_an73_tx_xnp(pdata, state)
549 	       : xgbe_an73_tx_training(pdata, state));
550 }
551 
552 static enum xgbe_an
553 xgbe_an73_page_received(struct xgbe_prv_data *pdata)
554 {
555 	enum xgbe_rx *state;
556 	unsigned long an_timeout;
557 	enum xgbe_an ret;
558 
559 	if (!pdata->an_start) {
560 		pdata->an_start = ticks;
561 	} else {
562 		an_timeout = pdata->an_start +
563 		    ((uint64_t)XGBE_AN_MS_TIMEOUT * (uint64_t)hz) / 1000ull;
564 		if ((int)(ticks - an_timeout) > 0) {
565 			/* Auto-negotiation timed out, reset state */
566 			pdata->kr_state = XGBE_RX_BPA;
567 			pdata->kx_state = XGBE_RX_BPA;
568 
569 			pdata->an_start = ticks;
570 
571 			axgbe_printf(2, "CL73 AN timed out, resetting state\n");
572 		}
573 	}
574 
575 	state = xgbe_in_kr_mode(pdata) ? &pdata->kr_state : &pdata->kx_state;
576 
577 	switch (*state) {
578 	case XGBE_RX_BPA:
579 		ret = xgbe_an73_rx_bpa(pdata, state);
580 		break;
581 
582 	case XGBE_RX_XNP:
583 		ret = xgbe_an73_rx_xnp(pdata, state);
584 		break;
585 
586 	default:
587 		ret = XGBE_AN_ERROR;
588 	}
589 
590 	return (ret);
591 }
592 
593 static enum xgbe_an
594 xgbe_an73_incompat_link(struct xgbe_prv_data *pdata)
595 {
596 	/* Be sure we aren't looping trying to negotiate */
597 	if (xgbe_in_kr_mode(pdata)) {
598 		pdata->kr_state = XGBE_RX_ERROR;
599 
600 		if (!(XGBE_ADV(&pdata->phy, 1000baseKX_Full)) &&
601 		    !(XGBE_ADV(&pdata->phy, 2500baseX_Full)))
602 			return (XGBE_AN_NO_LINK);
603 
604 		if (pdata->kx_state != XGBE_RX_BPA)
605 			return (XGBE_AN_NO_LINK);
606 	} else {
607 		pdata->kx_state = XGBE_RX_ERROR;
608 
609 		if (!(XGBE_ADV(&pdata->phy, 10000baseKR_Full)))
610 			return (XGBE_AN_NO_LINK);
611 
612 		if (pdata->kr_state != XGBE_RX_BPA)
613 			return (XGBE_AN_NO_LINK);
614 	}
615 
616 	xgbe_an_disable(pdata);
617 
618 	xgbe_switch_mode(pdata);
619 
620 	xgbe_an_restart(pdata);
621 
622 	return (XGBE_AN_INCOMPAT_LINK);
623 }
624 
625 static void
626 xgbe_an37_isr(struct xgbe_prv_data *pdata)
627 {
628 	unsigned int reg;
629 
630 	/* Disable AN interrupts */
631 	xgbe_an37_disable_interrupts(pdata);
632 
633 	/* Save the interrupt(s) that fired */
634 	reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT);
635 	pdata->an_int = reg & XGBE_AN_CL37_INT_MASK;
636 	pdata->an_status = reg & ~XGBE_AN_CL37_INT_MASK;
637 
638 	if (pdata->an_int) {
639 		/* Clear the interrupt(s) that fired and process them */
640 		reg &= ~XGBE_AN_CL37_INT_MASK;
641 		XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg);
642 
643 		xgbe_an_state_machine(pdata);
644 	} else {
645 		/* Enable AN interrupts */
646 		xgbe_an37_enable_interrupts(pdata);
647 
648 		/* Reissue interrupt if status is not clear */
649 		if (pdata->vdata->irq_reissue_support)
650 			XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);
651 	}
652 }
653 
654 static void
655 xgbe_an73_isr(struct xgbe_prv_data *pdata)
656 {
657 	/* Disable AN interrupts */
658 	xgbe_an73_disable_interrupts(pdata);
659 
660 	/* Save the interrupt(s) that fired */
661 	pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT);
662 
663 	if (pdata->an_int) {
664 		/* Clear the interrupt(s) that fired and process them */
665 		XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, ~pdata->an_int);
666 
667 		xgbe_an_state_machine(pdata);
668 	} else {
669 		/* Enable AN interrupts */
670 		xgbe_an73_enable_interrupts(pdata);
671 
672 		/* Reissue interrupt if status is not clear */
673 		if (pdata->vdata->irq_reissue_support)
674 			XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);
675 	}
676 }
677 
678 static void
679 xgbe_an_isr_task(unsigned long data)
680 {
681 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
682 
683 	axgbe_printf(2, "AN interrupt received\n");
684 
685 	switch (pdata->an_mode) {
686 	case XGBE_AN_MODE_CL73:
687 	case XGBE_AN_MODE_CL73_REDRV:
688 		xgbe_an73_isr(pdata);
689 		break;
690 	case XGBE_AN_MODE_CL37:
691 	case XGBE_AN_MODE_CL37_SGMII:
692 		xgbe_an37_isr(pdata);
693 		break;
694 	default:
695 		break;
696 	}
697 }
698 
699 static void
700 xgbe_an_combined_isr(struct xgbe_prv_data *pdata)
701 {
702 	xgbe_an_isr_task((unsigned long)pdata);
703 }
704 
705 static const char *
706 xgbe_state_as_string(enum xgbe_an state)
707 {
708 	switch (state) {
709 	case XGBE_AN_READY:
710 		return ("Ready");
711 	case XGBE_AN_PAGE_RECEIVED:
712 		return ("Page-Received");
713 	case XGBE_AN_INCOMPAT_LINK:
714 		return ("Incompatible-Link");
715 	case XGBE_AN_COMPLETE:
716 		return ("Complete");
717 	case XGBE_AN_NO_LINK:
718 		return ("No-Link");
719 	case XGBE_AN_ERROR:
720 		return ("Error");
721 	default:
722 		return ("Undefined");
723 	}
724 }
725 
726 static void
727 xgbe_an37_state_machine(struct xgbe_prv_data *pdata)
728 {
729 	enum xgbe_an cur_state = pdata->an_state;
730 
731 	if (!pdata->an_int)
732 		return;
733 
734 	if (pdata->an_int & XGBE_AN_CL37_INT_CMPLT) {
735 		pdata->an_state = XGBE_AN_COMPLETE;
736 		pdata->an_int &= ~XGBE_AN_CL37_INT_CMPLT;
737 
738 		/* If SGMII is enabled, check the link status */
739 		if ((pdata->an_mode == XGBE_AN_MODE_CL37_SGMII) &&
740 		    !(pdata->an_status & XGBE_SGMII_AN_LINK_STATUS))
741 			pdata->an_state = XGBE_AN_NO_LINK;
742 	}
743 
744 	axgbe_printf(2, "%s: CL37 AN %s\n", __func__,
745 	    xgbe_state_as_string(pdata->an_state));
746 
747 	cur_state = pdata->an_state;
748 
749 	switch (pdata->an_state) {
750 	case XGBE_AN_READY:
751 		break;
752 
753 	case XGBE_AN_COMPLETE:
754 		axgbe_printf(2, "Auto negotiation successful\n");
755 		break;
756 
757 	case XGBE_AN_NO_LINK:
758 		break;
759 
760 	default:
761 		pdata->an_state = XGBE_AN_ERROR;
762 	}
763 
764 	if (pdata->an_state == XGBE_AN_ERROR) {
765 		axgbe_printf(2, "error during auto-negotiation, state=%u\n",
766 		    cur_state);
767 
768 		pdata->an_int = 0;
769 		xgbe_an37_clear_interrupts(pdata);
770 	}
771 
772 	if (pdata->an_state >= XGBE_AN_COMPLETE) {
773 		pdata->an_result = pdata->an_state;
774 		pdata->an_state = XGBE_AN_READY;
775 
776 		if (pdata->phy_if.phy_impl.an_post)
777 			pdata->phy_if.phy_impl.an_post(pdata);
778 
779 		axgbe_printf(2, "CL37 AN result: %s\n",
780 		    xgbe_state_as_string(pdata->an_result));
781 	}
782 
783 	axgbe_printf(2, "%s: an_state %d an_int %d an_mode %d an_status %d\n",
784 	     __func__, pdata->an_state, pdata->an_int, pdata->an_mode,
785 	     pdata->an_status);
786 
787 	xgbe_an37_enable_interrupts(pdata);
788 }
789 
790 static void
791 xgbe_an73_state_machine(struct xgbe_prv_data *pdata)
792 {
793 	enum xgbe_an cur_state = pdata->an_state;
794 
795 	if (!pdata->an_int)
796 		goto out;
797 
798 next_int:
799 	if (pdata->an_int & XGBE_AN_CL73_PG_RCV) {
800 		pdata->an_state = XGBE_AN_PAGE_RECEIVED;
801 		pdata->an_int &= ~XGBE_AN_CL73_PG_RCV;
802 	} else if (pdata->an_int & XGBE_AN_CL73_INC_LINK) {
803 		pdata->an_state = XGBE_AN_INCOMPAT_LINK;
804 		pdata->an_int &= ~XGBE_AN_CL73_INC_LINK;
805 	} else if (pdata->an_int & XGBE_AN_CL73_INT_CMPLT) {
806 		pdata->an_state = XGBE_AN_COMPLETE;
807 		pdata->an_int &= ~XGBE_AN_CL73_INT_CMPLT;
808 	} else {
809 		pdata->an_state = XGBE_AN_ERROR;
810 	}
811 
812 again:
813 	axgbe_printf(2, "CL73 AN %s\n",
814 	    xgbe_state_as_string(pdata->an_state));
815 
816 	cur_state = pdata->an_state;
817 
818 	switch (pdata->an_state) {
819 	case XGBE_AN_READY:
820 		pdata->an_supported = 0;
821 		break;
822 
823 	case XGBE_AN_PAGE_RECEIVED:
824 		pdata->an_state = xgbe_an73_page_received(pdata);
825 		pdata->an_supported++;
826 		break;
827 
828 	case XGBE_AN_INCOMPAT_LINK:
829 		pdata->an_supported = 0;
830 		pdata->parallel_detect = 0;
831 		pdata->an_state = xgbe_an73_incompat_link(pdata);
832 		break;
833 
834 	case XGBE_AN_COMPLETE:
835 		pdata->parallel_detect = pdata->an_supported ? 0 : 1;
836 		axgbe_printf(2, "%s successful\n",
837 		    pdata->an_supported ? "Auto negotiation"
838 		    : "Parallel detection");
839 		break;
840 
841 	case XGBE_AN_NO_LINK:
842 		break;
843 
844 	default:
845 		pdata->an_state = XGBE_AN_ERROR;
846 	}
847 
848 	if (pdata->an_state == XGBE_AN_NO_LINK) {
849 		pdata->an_int = 0;
850 		xgbe_an73_clear_interrupts(pdata);
851 	} else if (pdata->an_state == XGBE_AN_ERROR) {
852 		axgbe_printf(2,
853 		    "error during auto-negotiation, state=%u\n",
854 		    cur_state);
855 
856 		pdata->an_int = 0;
857 		xgbe_an73_clear_interrupts(pdata);
858 	}
859 
860 	if (pdata->an_state >= XGBE_AN_COMPLETE) {
861 		pdata->an_result = pdata->an_state;
862 		pdata->an_state = XGBE_AN_READY;
863 		pdata->kr_state = XGBE_RX_BPA;
864 		pdata->kx_state = XGBE_RX_BPA;
865 		pdata->an_start = 0;
866 
867 		if (pdata->phy_if.phy_impl.an_post)
868 			pdata->phy_if.phy_impl.an_post(pdata);
869 
870 		axgbe_printf(2,  "CL73 AN result: %s\n",
871 		    xgbe_state_as_string(pdata->an_result));
872 	}
873 
874 	if (cur_state != pdata->an_state)
875 		goto again;
876 
877 	if (pdata->an_int)
878 		goto next_int;
879 
880 out:
881 	/* Enable AN interrupts on the way out */
882 	xgbe_an73_enable_interrupts(pdata);
883 }
884 
885 static void
886 xgbe_an_state_machine(struct xgbe_prv_data *pdata)
887 {
888 	sx_xlock(&pdata->an_mutex);
889 
890 	switch (pdata->an_mode) {
891 	case XGBE_AN_MODE_CL73:
892 	case XGBE_AN_MODE_CL73_REDRV:
893 		xgbe_an73_state_machine(pdata);
894 		break;
895 	case XGBE_AN_MODE_CL37:
896 	case XGBE_AN_MODE_CL37_SGMII:
897 		xgbe_an37_state_machine(pdata);
898 		break;
899 	default:
900 		break;
901 	}
902 
903 	/* Reissue interrupt if status is not clear */
904 	if (pdata->vdata->irq_reissue_support)
905 		XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);
906 
907 	sx_xunlock(&pdata->an_mutex);
908 }
909 
910 static void
911 xgbe_an37_init(struct xgbe_prv_data *pdata)
912 {
913 	struct xgbe_phy local_phy;
914 	unsigned int reg;
915 
916 	pdata->phy_if.phy_impl.an_advertising(pdata, &local_phy);
917 
918 	axgbe_printf(2, "%s: advertising 0x%x\n", __func__, local_phy.advertising);
919 
920 	/* Set up Advertisement register */
921 	reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE);
922 	if (XGBE_ADV(&local_phy, Pause))
923 		reg |= 0x100;
924 	else
925 		reg &= ~0x100;
926 
927 	if (XGBE_ADV(&local_phy, Asym_Pause))
928 		reg |= 0x80;
929 	else
930 		reg &= ~0x80;
931 
932 	/* Full duplex, but not half */
933 	reg |= XGBE_AN_CL37_FD_MASK;
934 	reg &= ~XGBE_AN_CL37_HD_MASK;
935 
936 	axgbe_printf(2, "%s: Writing reg: 0x%x\n", __func__, reg);
937 	XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE, reg);
938 
939 	/* Set up the Control register */
940 	reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);
941 	axgbe_printf(2, "%s: AN_ADVERTISE reg 0x%x an_mode %d\n", __func__,
942 	    reg, pdata->an_mode);
943 	reg &= ~XGBE_AN_CL37_TX_CONFIG_MASK;
944 	reg &= ~XGBE_AN_CL37_PCS_MODE_MASK;
945 
946 	switch (pdata->an_mode) {
947 	case XGBE_AN_MODE_CL37:
948 		reg |= XGBE_AN_CL37_PCS_MODE_BASEX;
949 		break;
950 	case XGBE_AN_MODE_CL37_SGMII:
951 		reg |= XGBE_AN_CL37_PCS_MODE_SGMII;
952 		break;
953 	default:
954 		break;
955 	}
956 
957 	reg |= XGBE_AN_CL37_MII_CTRL_8BIT;
958 	axgbe_printf(2, "%s: Writing reg: 0x%x\n", __func__, reg);
959 	XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
960 
961 	axgbe_printf(2, "CL37 AN (%s) initialized\n",
962 	    (pdata->an_mode == XGBE_AN_MODE_CL37) ? "BaseX" : "SGMII");
963 }
964 
965 static void
966 xgbe_an73_init(struct xgbe_prv_data *pdata)
967 {
968 	/*
969 	 * This local_phy is needed because phy-v2 alters the
970 	 * advertising flag variable. so phy-v1 an_advertising is just copying
971 	 */
972 	struct xgbe_phy local_phy;
973 	unsigned int reg;
974 
975 	pdata->phy_if.phy_impl.an_advertising(pdata, &local_phy);
976 
977 	/* Set up Advertisement register 3 first */
978 	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
979 	if (XGBE_ADV(&local_phy, 10000baseR_FEC))
980 		reg |= 0xc000;
981 	else
982 		reg &= ~0xc000;
983 
984 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, reg);
985 
986 	/* Set up Advertisement register 2 next */
987 	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
988 	if (XGBE_ADV(&local_phy, 10000baseKR_Full))
989 		reg |= 0x80;
990 	else
991 		reg &= ~0x80;
992 
993 	if (XGBE_ADV(&local_phy, 1000baseKX_Full) ||
994 	    XGBE_ADV(&local_phy, 2500baseX_Full))
995 		reg |= 0x20;
996 	else
997 		reg &= ~0x20;
998 
999 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, reg);
1000 
1001 	/* Set up Advertisement register 1 last */
1002 	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
1003 	if (XGBE_ADV(&local_phy, Pause))
1004 		reg |= 0x400;
1005 	else
1006 		reg &= ~0x400;
1007 
1008 	if (XGBE_ADV(&local_phy, Asym_Pause))
1009 		reg |= 0x800;
1010 	else
1011 		reg &= ~0x800;
1012 
1013 	/* We don't intend to perform XNP */
1014 	reg &= ~XGBE_XNP_NP_EXCHANGE;
1015 
1016 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
1017 
1018 	axgbe_printf(2, "CL73 AN initialized\n");
1019 }
1020 
1021 static void
1022 xgbe_an_init(struct xgbe_prv_data *pdata)
1023 {
1024 	/* Set up advertisement registers based on current settings */
1025 	pdata->an_mode = pdata->phy_if.phy_impl.an_mode(pdata);
1026 	axgbe_printf(2, "%s: setting up an_mode %d\n", __func__, pdata->an_mode);
1027 
1028 	switch (pdata->an_mode) {
1029 	case XGBE_AN_MODE_CL73:
1030 	case XGBE_AN_MODE_CL73_REDRV:
1031 		xgbe_an73_init(pdata);
1032 		break;
1033 	case XGBE_AN_MODE_CL37:
1034 	case XGBE_AN_MODE_CL37_SGMII:
1035 		xgbe_an37_init(pdata);
1036 		break;
1037 	default:
1038 		break;
1039 	}
1040 }
1041 
1042 static const char *
1043 xgbe_phy_fc_string(struct xgbe_prv_data *pdata)
1044 {
1045 	if (pdata->tx_pause && pdata->rx_pause)
1046 		return ("rx/tx");
1047 	else if (pdata->rx_pause)
1048 		return ("rx");
1049 	else if (pdata->tx_pause)
1050 		return ("tx");
1051 	else
1052 		return ("off");
1053 }
1054 
1055 static const char *
1056 xgbe_phy_speed_string(int speed)
1057 {
1058 	switch (speed) {
1059 	case SPEED_100:
1060 		return ("100Mbps");
1061 	case SPEED_1000:
1062 		return ("1Gbps");
1063 	case SPEED_2500:
1064 		return ("2.5Gbps");
1065 	case SPEED_10000:
1066 		return ("10Gbps");
1067 	case SPEED_UNKNOWN:
1068 		return ("Unknown");
1069 	default:
1070 		return ("Unsupported");
1071 	}
1072 }
1073 
1074 static void
1075 xgbe_phy_print_status(struct xgbe_prv_data *pdata)
1076 {
1077 	if (pdata->phy.link)
1078 		axgbe_printf(0,
1079 		    "Link is UP - %s/%s - flow control %s\n",
1080 		    xgbe_phy_speed_string(pdata->phy.speed),
1081 		    pdata->phy.duplex == DUPLEX_FULL ? "Full" : "Half",
1082 		    xgbe_phy_fc_string(pdata));
1083 	else
1084 		axgbe_printf(0, "Link is DOWN\n");
1085 }
1086 
1087 static void
1088 xgbe_phy_adjust_link(struct xgbe_prv_data *pdata)
1089 {
1090 	int new_state = 0;
1091 
1092 	axgbe_printf(1, "link %d/%d tx %d/%d rx %d/%d speed %d/%d autoneg %d/%d\n",
1093 	    pdata->phy_link, pdata->phy.link,
1094 	    pdata->tx_pause, pdata->phy.tx_pause,
1095 	    pdata->rx_pause, pdata->phy.rx_pause,
1096 	    pdata->phy_speed, pdata->phy.speed,
1097 	    pdata->pause_autoneg, pdata->phy.pause_autoneg);
1098 
1099 	if (pdata->phy.link) {
1100 		/* Flow control support */
1101 		pdata->pause_autoneg = pdata->phy.pause_autoneg;
1102 
1103 		if (pdata->tx_pause != pdata->phy.tx_pause) {
1104 			new_state = 1;
1105 			axgbe_printf(2, "tx pause %d/%d\n", pdata->tx_pause,
1106 			    pdata->phy.tx_pause);
1107 			pdata->tx_pause = pdata->phy.tx_pause;
1108 			pdata->hw_if.config_tx_flow_control(pdata);
1109 		}
1110 
1111 		if (pdata->rx_pause != pdata->phy.rx_pause) {
1112 			new_state = 1;
1113 			axgbe_printf(2, "rx pause %d/%d\n", pdata->rx_pause,
1114 			    pdata->phy.rx_pause);
1115 			pdata->rx_pause = pdata->phy.rx_pause;
1116 			pdata->hw_if.config_rx_flow_control(pdata);
1117 		}
1118 
1119 		/* Speed support */
1120 		if (pdata->phy_speed != pdata->phy.speed) {
1121 			new_state = 1;
1122 			pdata->phy_speed = pdata->phy.speed;
1123 		}
1124 
1125 		if (pdata->phy_link != pdata->phy.link) {
1126 			new_state = 1;
1127 			pdata->phy_link = pdata->phy.link;
1128 		}
1129 	} else if (pdata->phy_link) {
1130 		new_state = 1;
1131 		pdata->phy_link = 0;
1132 		pdata->phy_speed = SPEED_UNKNOWN;
1133 	}
1134 
1135 	axgbe_printf(2, "phy_link %d Link %d new_state %d\n", pdata->phy_link,
1136 	    pdata->phy.link, new_state);
1137 
1138 	if (new_state)
1139 		xgbe_phy_print_status(pdata);
1140 }
1141 
1142 static bool
1143 xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed)
1144 {
1145 	return (pdata->phy_if.phy_impl.valid_speed(pdata, speed));
1146 }
1147 
1148 static int
1149 xgbe_phy_config_fixed(struct xgbe_prv_data *pdata)
1150 {
1151 	enum xgbe_mode mode;
1152 
1153 	axgbe_printf(2, "fixed PHY configuration\n");
1154 
1155 	/* Disable auto-negotiation */
1156 	xgbe_an_disable(pdata);
1157 
1158 	/* Set specified mode for specified speed */
1159 	mode = pdata->phy_if.phy_impl.get_mode(pdata, pdata->phy.speed);
1160 	switch (mode) {
1161 	case XGBE_MODE_KX_1000:
1162 	case XGBE_MODE_KX_2500:
1163 	case XGBE_MODE_KR:
1164 	case XGBE_MODE_SGMII_100:
1165 	case XGBE_MODE_SGMII_1000:
1166 	case XGBE_MODE_X:
1167 	case XGBE_MODE_SFI:
1168 		break;
1169 	case XGBE_MODE_UNKNOWN:
1170 	default:
1171 		return (-EINVAL);
1172 	}
1173 
1174 	/* Validate duplex mode */
1175 	if (pdata->phy.duplex != DUPLEX_FULL)
1176 		return (-EINVAL);
1177 
1178 	xgbe_set_mode(pdata, mode);
1179 
1180 	return (0);
1181 }
1182 
1183 static int
1184 __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata, bool set_mode)
1185 {
1186 	int ret;
1187 	unsigned int reg = 0;
1188 
1189 	sx_xlock(&pdata->an_mutex);
1190 
1191 	set_bit(XGBE_LINK_INIT, &pdata->dev_state);
1192 	pdata->link_check = ticks;
1193 
1194 	ret = pdata->phy_if.phy_impl.an_config(pdata);
1195 	if (ret) {
1196 		axgbe_error("%s: an_config fail %d\n", __func__, ret);
1197 		goto out;
1198 	}
1199 
1200 	if (pdata->phy.autoneg != AUTONEG_ENABLE) {
1201 		ret = xgbe_phy_config_fixed(pdata);
1202 		if (ret || !pdata->kr_redrv) {
1203 			if (ret)
1204 				axgbe_error("%s: fix conf fail %d\n", __func__, ret);
1205 			goto out;
1206 		}
1207 
1208 		axgbe_printf(2, "AN redriver support\n");
1209 	} else
1210 		axgbe_printf(2, "AN PHY configuration\n");
1211 
1212 	/* Disable auto-negotiation interrupt */
1213 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);
1214 	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK);
1215 	axgbe_printf(2, "%s: set_mode %d AN int reg value 0x%x\n", __func__,
1216 	    set_mode, reg);
1217 
1218 	/* Clear any auto-negotitation interrupts */
1219 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
1220 
1221 	/* Start auto-negotiation in a supported mode */
1222 	if (set_mode) {
1223 		/* Start auto-negotiation in a supported mode */
1224 		if (xgbe_use_mode(pdata, XGBE_MODE_KR)) {
1225 			xgbe_set_mode(pdata, XGBE_MODE_KR);
1226 		} else if (xgbe_use_mode(pdata, XGBE_MODE_KX_2500)) {
1227 			xgbe_set_mode(pdata, XGBE_MODE_KX_2500);
1228 		} else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) {
1229 			xgbe_set_mode(pdata, XGBE_MODE_KX_1000);
1230 		} else if (xgbe_use_mode(pdata, XGBE_MODE_SFI)) {
1231 			xgbe_set_mode(pdata, XGBE_MODE_SFI);
1232 		} else if (xgbe_use_mode(pdata, XGBE_MODE_X)) {
1233 			xgbe_set_mode(pdata, XGBE_MODE_X);
1234 		} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_1000)) {
1235 			xgbe_set_mode(pdata, XGBE_MODE_SGMII_1000);
1236 		} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {
1237 			xgbe_set_mode(pdata, XGBE_MODE_SGMII_100);
1238 		} else {
1239 			XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07);
1240 			ret = -EINVAL;
1241 			goto out;
1242 		}
1243 	}
1244 
1245 	/* Disable and stop any in progress auto-negotiation */
1246 	xgbe_an_disable_all(pdata);
1247 
1248 	/* Clear any auto-negotitation interrupts */
1249 	xgbe_an_clear_interrupts_all(pdata);
1250 
1251 	pdata->an_result = XGBE_AN_READY;
1252 	pdata->an_state = XGBE_AN_READY;
1253 	pdata->kr_state = XGBE_RX_BPA;
1254 	pdata->kx_state = XGBE_RX_BPA;
1255 
1256 	/* Re-enable auto-negotiation interrupt */
1257 	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07);
1258 	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK);
1259 
1260 	/* Set up advertisement registers based on current settings */
1261 	xgbe_an_init(pdata);
1262 
1263 	/* Enable and start auto-negotiation */
1264 	xgbe_an_restart(pdata);
1265 
1266 out:
1267 	if (ret) {
1268 		axgbe_printf(0, "%s: set_mode %d AN int reg value 0x%x ret value %d\n",
1269 		   __func__, set_mode, reg, ret);
1270 		set_bit(XGBE_LINK_ERR, &pdata->dev_state);
1271 	} else
1272 		clear_bit(XGBE_LINK_ERR, &pdata->dev_state);
1273 
1274 	sx_unlock(&pdata->an_mutex);
1275 
1276 	return (ret);
1277 }
1278 
1279 static int
1280 xgbe_phy_config_aneg(struct xgbe_prv_data *pdata)
1281 {
1282 	return (__xgbe_phy_config_aneg(pdata, true));
1283 }
1284 
1285 static int
1286 xgbe_phy_reconfig_aneg(struct xgbe_prv_data *pdata)
1287 {
1288 	return (__xgbe_phy_config_aneg(pdata, false));
1289 }
1290 
1291 static bool
1292 xgbe_phy_aneg_done(struct xgbe_prv_data *pdata)
1293 {
1294 	return (pdata->an_result == XGBE_AN_COMPLETE);
1295 }
1296 
1297 static void
1298 xgbe_check_link_timeout(struct xgbe_prv_data *pdata)
1299 {
1300 	unsigned long link_timeout;
1301 
1302 	link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * hz);
1303 	if ((int)(ticks - link_timeout) > 0) {
1304 		axgbe_printf(2, "AN link timeout\n");
1305 		xgbe_phy_config_aneg(pdata);
1306 	}
1307 }
1308 
1309 static enum xgbe_mode
1310 xgbe_phy_status_aneg(struct xgbe_prv_data *pdata)
1311 {
1312 	return (pdata->phy_if.phy_impl.an_outcome(pdata));
1313 }
1314 
1315 static void
1316 xgbe_phy_status_result(struct xgbe_prv_data *pdata)
1317 {
1318 	enum xgbe_mode mode;
1319 
1320 	XGBE_ZERO_LP_ADV(&pdata->phy);
1321 
1322 	if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect)
1323 		mode = xgbe_cur_mode(pdata);
1324 	else
1325 		mode = xgbe_phy_status_aneg(pdata);
1326 
1327 	axgbe_printf(3, "%s: xgbe mode %d\n", __func__, mode);
1328 	switch (mode) {
1329 	case XGBE_MODE_SGMII_100:
1330 		pdata->phy.speed = SPEED_100;
1331 		break;
1332 	case XGBE_MODE_X:
1333 	case XGBE_MODE_KX_1000:
1334 	case XGBE_MODE_SGMII_1000:
1335 		pdata->phy.speed = SPEED_1000;
1336 		break;
1337 	case XGBE_MODE_KX_2500:
1338 		pdata->phy.speed = SPEED_2500;
1339 		break;
1340 	case XGBE_MODE_KR:
1341 	case XGBE_MODE_SFI:
1342 		pdata->phy.speed = SPEED_10000;
1343 		break;
1344 	case XGBE_MODE_UNKNOWN:
1345 	default:
1346 		axgbe_printf(1, "%s: unknown mode\n", __func__);
1347 		pdata->phy.speed = SPEED_UNKNOWN;
1348 	}
1349 
1350 	pdata->phy.duplex = DUPLEX_FULL;
1351 	axgbe_printf(2, "%s: speed %d duplex %d\n", __func__, pdata->phy.speed,
1352 	    pdata->phy.duplex);
1353 
1354 	if (xgbe_set_mode(pdata, mode) && pdata->an_again)
1355 		xgbe_phy_reconfig_aneg(pdata);
1356 }
1357 
1358 static void
1359 xgbe_phy_status(struct xgbe_prv_data *pdata)
1360 {
1361 	bool link_aneg;
1362 	int an_restart;
1363 
1364 	if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) {
1365 		axgbe_error("%s: LINK_ERR\n", __func__);
1366 		pdata->phy.link = 0;
1367 		goto adjust_link;
1368 	}
1369 
1370 	link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE);
1371 	axgbe_printf(3, "link_aneg - %d\n", link_aneg);
1372 
1373 	/* Get the link status. Link status is latched low, so read
1374 	 * once to clear and then read again to get current state
1375 	 */
1376 	pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata,
1377 	    &an_restart);
1378 
1379 	axgbe_printf(1, "link_status returned Link:%d an_restart:%d aneg:%d\n",
1380 	    pdata->phy.link, an_restart, link_aneg);
1381 
1382 	if (an_restart) {
1383 		xgbe_phy_config_aneg(pdata);
1384 		return;
1385 	}
1386 
1387 	if (pdata->phy.link) {
1388 		axgbe_printf(2, "Link Active\n");
1389 		if (link_aneg && !xgbe_phy_aneg_done(pdata)) {
1390 			axgbe_printf(1, "phy_link set check timeout\n");
1391 			xgbe_check_link_timeout(pdata);
1392 			return;
1393 		}
1394 
1395 		axgbe_printf(2, "%s: Link write phy_status result\n", __func__);
1396 		xgbe_phy_status_result(pdata);
1397 
1398 		if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))
1399 			clear_bit(XGBE_LINK_INIT, &pdata->dev_state);
1400 
1401 	} else {
1402 		axgbe_printf(2, "Link Deactive\n");
1403 		if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) {
1404 			axgbe_printf(1, "phy_link not set check timeout\n");
1405 			xgbe_check_link_timeout(pdata);
1406 
1407 			if (link_aneg) {
1408 				axgbe_printf(2, "link_aneg case\n");
1409 				return;
1410 			}
1411 		}
1412 
1413 		xgbe_phy_status_result(pdata);
1414 
1415 	}
1416 
1417 adjust_link:
1418 	axgbe_printf(2, "%s: Link %d\n", __func__, pdata->phy.link);
1419 	xgbe_phy_adjust_link(pdata);
1420 }
1421 
1422 static void
1423 xgbe_phy_stop(struct xgbe_prv_data *pdata)
1424 {
1425 	axgbe_printf(2, "stopping PHY\n");
1426 
1427 	if (!pdata->phy_started)
1428 		return;
1429 
1430 	/* Indicate the PHY is down */
1431 	pdata->phy_started = 0;
1432 
1433 	/* Disable auto-negotiation */
1434 	xgbe_an_disable_all(pdata);
1435 
1436 	pdata->phy_if.phy_impl.stop(pdata);
1437 
1438 	pdata->phy.link = 0;
1439 
1440 	xgbe_phy_adjust_link(pdata);
1441 }
1442 
1443 static int
1444 xgbe_phy_start(struct xgbe_prv_data *pdata)
1445 {
1446 	int ret;
1447 
1448 	DBGPR("-->xgbe_phy_start\n");
1449 
1450 	ret = pdata->phy_if.phy_impl.start(pdata);
1451 	if (ret) {
1452 		axgbe_error("%s: impl start ret %d\n", __func__, ret);
1453 		return (ret);
1454 	}
1455 
1456 	/* Set initial mode - call the mode setting routines
1457 	 * directly to insure we are properly configured
1458 	 */
1459 	if (xgbe_use_mode(pdata, XGBE_MODE_KR)) {
1460 		axgbe_printf(2, "%s: KR\n", __func__);
1461 		xgbe_kr_mode(pdata);
1462 	} else if (xgbe_use_mode(pdata, XGBE_MODE_KX_2500)) {
1463 		axgbe_printf(2, "%s: KX 2500\n", __func__);
1464 		xgbe_kx_2500_mode(pdata);
1465 	} else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) {
1466 		axgbe_printf(2, "%s: KX 1000\n", __func__);
1467 		xgbe_kx_1000_mode(pdata);
1468 	} else if (xgbe_use_mode(pdata, XGBE_MODE_SFI)) {
1469 		axgbe_printf(2, "%s: SFI\n", __func__);
1470 		xgbe_sfi_mode(pdata);
1471 	} else if (xgbe_use_mode(pdata, XGBE_MODE_X)) {
1472 		axgbe_printf(2, "%s: X\n", __func__);
1473 		xgbe_x_mode(pdata);
1474 	} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_1000)) {
1475 		axgbe_printf(2, "%s: SGMII 1000\n", __func__);
1476 		xgbe_sgmii_1000_mode(pdata);
1477 	} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {
1478 		axgbe_printf(2, "%s: SGMII 100\n", __func__);
1479 		xgbe_sgmii_100_mode(pdata);
1480 	} else {
1481 		axgbe_error("%s: invalid mode\n", __func__);
1482 		ret = -EINVAL;
1483 		goto err_stop;
1484 	}
1485 
1486 	/* Indicate the PHY is up and running */
1487 	pdata->phy_started = 1;
1488 
1489 	/* Set up advertisement registers based on current settings */
1490 	xgbe_an_init(pdata);
1491 
1492 	/* Enable auto-negotiation interrupts */
1493 	xgbe_an_enable_interrupts(pdata);
1494 
1495 	ret = xgbe_phy_config_aneg(pdata);
1496 	if (ret)
1497 		axgbe_error("%s: phy_config_aneg %d\n", __func__, ret);
1498 
1499 	return (ret);
1500 
1501 err_stop:
1502 	pdata->phy_if.phy_impl.stop(pdata);
1503 
1504 	return (ret);
1505 }
1506 
1507 static int
1508 xgbe_phy_reset(struct xgbe_prv_data *pdata)
1509 {
1510 	int ret;
1511 
1512 	ret = pdata->phy_if.phy_impl.reset(pdata);
1513 	if (ret) {
1514 		axgbe_error("%s: impl phy reset %d\n", __func__, ret);
1515 		return (ret);
1516 	}
1517 
1518 	/* Disable auto-negotiation for now */
1519 	xgbe_an_disable_all(pdata);
1520 
1521 	/* Clear auto-negotiation interrupts */
1522 	xgbe_an_clear_interrupts_all(pdata);
1523 
1524 	return (0);
1525 }
1526 
1527 static int
1528 xgbe_phy_best_advertised_speed(struct xgbe_prv_data *pdata)
1529 {
1530 
1531 	if (XGBE_ADV(&pdata->phy, 10000baseKR_Full))
1532 		return (SPEED_10000);
1533 	else if (XGBE_ADV(&pdata->phy, 10000baseT_Full))
1534 		return (SPEED_10000);
1535 	else if (XGBE_ADV(&pdata->phy, 2500baseX_Full))
1536 		return (SPEED_2500);
1537 	else if (XGBE_ADV(&pdata->phy, 2500baseT_Full))
1538 		return (SPEED_2500);
1539 	else if (XGBE_ADV(&pdata->phy, 1000baseKX_Full))
1540 		return (SPEED_1000);
1541 	else if (XGBE_ADV(&pdata->phy, 1000baseT_Full))
1542 		return (SPEED_1000);
1543 	else if (XGBE_ADV(&pdata->phy, 100baseT_Full))
1544 		return (SPEED_100);
1545 
1546 	return (SPEED_UNKNOWN);
1547 }
1548 
1549 static void
1550 xgbe_phy_exit(struct xgbe_prv_data *pdata)
1551 {
1552 	pdata->phy_if.phy_impl.exit(pdata);
1553 }
1554 
1555 static int
1556 xgbe_phy_init(struct xgbe_prv_data *pdata)
1557 {
1558 	int ret = 0;
1559 
1560 	DBGPR("-->xgbe_phy_init\n");
1561 
1562 	sx_init(&pdata->an_mutex, "axgbe AN lock");
1563 	pdata->mdio_mmd = MDIO_MMD_PCS;
1564 
1565 	/* Initialize supported features */
1566 	pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD,
1567 					MDIO_PMA_10GBR_FECABLE);
1568 	pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE |
1569 			       MDIO_PMA_10GBR_FECABLE_ERRABLE);
1570 
1571 	/* Setup the phy (including supported features) */
1572 	ret = pdata->phy_if.phy_impl.init(pdata);
1573 	if (ret)
1574 		return (ret);
1575 
1576 	/* Copy supported link modes to advertising link modes */
1577 	XGBE_LM_COPY(&pdata->phy, advertising, &pdata->phy, supported);
1578 
1579 	pdata->phy.address = 0;
1580 
1581 	if (XGBE_ADV(&pdata->phy, Autoneg)) {
1582 		pdata->phy.autoneg = AUTONEG_ENABLE;
1583 		pdata->phy.speed = SPEED_UNKNOWN;
1584 		pdata->phy.duplex = DUPLEX_UNKNOWN;
1585 	} else {
1586 		pdata->phy.autoneg = AUTONEG_DISABLE;
1587 		pdata->phy.speed = xgbe_phy_best_advertised_speed(pdata);
1588 		pdata->phy.duplex = DUPLEX_FULL;
1589 	}
1590 
1591 	pdata->phy.link = 0;
1592 
1593 	pdata->phy.pause_autoneg = pdata->pause_autoneg;
1594 	pdata->phy.tx_pause = pdata->tx_pause;
1595 	pdata->phy.rx_pause = pdata->rx_pause;
1596 
1597 	/* Fix up Flow Control advertising */
1598 	XGBE_CLR_ADV(&pdata->phy, Pause);
1599 	XGBE_CLR_ADV(&pdata->phy, Asym_Pause);
1600 
1601 	if (pdata->rx_pause) {
1602 		XGBE_SET_ADV(&pdata->phy, Pause);
1603 		XGBE_SET_ADV(&pdata->phy, Asym_Pause);
1604 	}
1605 
1606 	if (pdata->tx_pause) {
1607 		if (XGBE_ADV(&pdata->phy, Asym_Pause))
1608 			XGBE_CLR_ADV(&pdata->phy, Asym_Pause);
1609 		else
1610 			XGBE_SET_ADV(&pdata->phy, Asym_Pause);
1611 	}
1612 
1613 	return (0);
1614 }
1615 
1616 void
1617 xgbe_init_function_ptrs_phy(struct xgbe_phy_if *phy_if)
1618 {
1619 	phy_if->phy_init	= xgbe_phy_init;
1620 	phy_if->phy_exit	= xgbe_phy_exit;
1621 
1622 	phy_if->phy_reset       = xgbe_phy_reset;
1623 	phy_if->phy_start       = xgbe_phy_start;
1624 	phy_if->phy_stop	= xgbe_phy_stop;
1625 
1626 	phy_if->phy_status      = xgbe_phy_status;
1627 	phy_if->phy_config_aneg = xgbe_phy_config_aneg;
1628 
1629 	phy_if->phy_valid_speed = xgbe_phy_valid_speed;
1630 
1631 	phy_if->an_isr		= xgbe_an_combined_isr;
1632 }
1633