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
118static void xgbe_an_state_machine(struct xgbe_prv_data *pdata);
119
120static void
121xgbe_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
130static void
131xgbe_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
144static void
145xgbe_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
158static void
159xgbe_an73_clear_interrupts(struct xgbe_prv_data *pdata)
160{
161	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
162}
163
164static void
165xgbe_an73_disable_interrupts(struct xgbe_prv_data *pdata)
166{
167	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);
168}
169
170static void
171xgbe_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
176static void
177xgbe_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
193static void
194xgbe_an_clear_interrupts_all(struct xgbe_prv_data *pdata)
195{
196	xgbe_an73_clear_interrupts(pdata);
197	xgbe_an37_clear_interrupts(pdata);
198}
199
200static void
201xgbe_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
210static void
211xgbe_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
220static void
221xgbe_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
230static void
231xgbe_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
244static void
245xgbe_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
254static void
255xgbe_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
264static void
265xgbe_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
274static enum xgbe_mode
275xgbe_cur_mode(struct xgbe_prv_data *pdata)
276{
277	return (pdata->phy_if.phy_impl.cur_mode(pdata));
278}
279
280static bool
281xgbe_in_kr_mode(struct xgbe_prv_data *pdata)
282{
283	return (xgbe_cur_mode(pdata) == XGBE_MODE_KR);
284}
285
286static void
287xgbe_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
318static void
319xgbe_switch_mode(struct xgbe_prv_data *pdata)
320{
321	xgbe_change_mode(pdata, pdata->phy_if.phy_impl.switch_mode(pdata));
322}
323
324static bool
325xgbe_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
335static bool
336xgbe_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
341static void
342xgbe_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
358static void
359xgbe_an37_restart(struct xgbe_prv_data *pdata)
360{
361	xgbe_an37_enable_interrupts(pdata);
362	xgbe_an37_set(pdata, true, true);
363}
364
365static void
366xgbe_an37_disable(struct xgbe_prv_data *pdata)
367{
368	xgbe_an37_set(pdata, false, false);
369	xgbe_an37_disable_interrupts(pdata);
370}
371
372static void
373xgbe_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
395static void
396xgbe_an73_restart(struct xgbe_prv_data *pdata)
397{
398	xgbe_an73_enable_interrupts(pdata);
399	xgbe_an73_set(pdata, true, true);
400}
401
402static void
403xgbe_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
411static void
412xgbe_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
431static void
432xgbe_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
451static void
452xgbe_an_disable_all(struct xgbe_prv_data *pdata)
453{
454	xgbe_an73_disable(pdata);
455	xgbe_an37_disable(pdata);
456}
457
458static enum xgbe_an
459xgbe_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
496static enum xgbe_an
497xgbe_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
513static enum xgbe_an
514xgbe_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
537static enum xgbe_an
538xgbe_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
552static enum xgbe_an
553xgbe_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
593static enum xgbe_an
594xgbe_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
625static void
626xgbe_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
654static void
655xgbe_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
678static void
679xgbe_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
699static void
700xgbe_an_combined_isr(struct xgbe_prv_data *pdata)
701{
702	xgbe_an_isr_task((unsigned long)pdata);
703}
704
705static const char *
706xgbe_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
726static void
727xgbe_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
739	axgbe_printf(2, "%s: CL37 AN %s\n", __func__,
740	    xgbe_state_as_string(pdata->an_state));
741
742	cur_state = pdata->an_state;
743
744	switch (pdata->an_state) {
745	case XGBE_AN_READY:
746		break;
747
748	case XGBE_AN_COMPLETE:
749		axgbe_printf(2, "Auto negotiation successful\n");
750		break;
751
752	case XGBE_AN_NO_LINK:
753		break;
754
755	default:
756		pdata->an_state = XGBE_AN_ERROR;
757	}
758
759	if (pdata->an_state == XGBE_AN_ERROR) {
760		axgbe_printf(2, "error during auto-negotiation, state=%u\n",
761		    cur_state);
762
763		pdata->an_int = 0;
764		xgbe_an37_clear_interrupts(pdata);
765	}
766
767	if (pdata->an_state >= XGBE_AN_COMPLETE) {
768		pdata->an_result = pdata->an_state;
769		pdata->an_state = XGBE_AN_READY;
770
771		if (pdata->phy_if.phy_impl.an_post)
772			pdata->phy_if.phy_impl.an_post(pdata);
773
774		axgbe_printf(2, "CL37 AN result: %s\n",
775		    xgbe_state_as_string(pdata->an_result));
776	}
777
778	axgbe_printf(2, "%s: an_state %d an_int %d an_mode %d an_status %d\n",
779	     __func__, pdata->an_state, pdata->an_int, pdata->an_mode,
780	     pdata->an_status);
781
782	xgbe_an37_enable_interrupts(pdata);
783}
784
785static void
786xgbe_an73_state_machine(struct xgbe_prv_data *pdata)
787{
788	enum xgbe_an cur_state = pdata->an_state;
789
790	if (!pdata->an_int)
791		goto out;
792
793next_int:
794	if (pdata->an_int & XGBE_AN_CL73_PG_RCV) {
795		pdata->an_state = XGBE_AN_PAGE_RECEIVED;
796		pdata->an_int &= ~XGBE_AN_CL73_PG_RCV;
797	} else if (pdata->an_int & XGBE_AN_CL73_INC_LINK) {
798		pdata->an_state = XGBE_AN_INCOMPAT_LINK;
799		pdata->an_int &= ~XGBE_AN_CL73_INC_LINK;
800	} else if (pdata->an_int & XGBE_AN_CL73_INT_CMPLT) {
801		pdata->an_state = XGBE_AN_COMPLETE;
802		pdata->an_int &= ~XGBE_AN_CL73_INT_CMPLT;
803	} else {
804		pdata->an_state = XGBE_AN_ERROR;
805	}
806
807again:
808	axgbe_printf(2, "CL73 AN %s\n",
809	    xgbe_state_as_string(pdata->an_state));
810
811	cur_state = pdata->an_state;
812
813	switch (pdata->an_state) {
814	case XGBE_AN_READY:
815		pdata->an_supported = 0;
816		break;
817
818	case XGBE_AN_PAGE_RECEIVED:
819		pdata->an_state = xgbe_an73_page_received(pdata);
820		pdata->an_supported++;
821		break;
822
823	case XGBE_AN_INCOMPAT_LINK:
824		pdata->an_supported = 0;
825		pdata->parallel_detect = 0;
826		pdata->an_state = xgbe_an73_incompat_link(pdata);
827		break;
828
829	case XGBE_AN_COMPLETE:
830		pdata->parallel_detect = pdata->an_supported ? 0 : 1;
831		axgbe_printf(2, "%s successful\n",
832		    pdata->an_supported ? "Auto negotiation"
833		    : "Parallel detection");
834		break;
835
836	case XGBE_AN_NO_LINK:
837		break;
838
839	default:
840		pdata->an_state = XGBE_AN_ERROR;
841	}
842
843	if (pdata->an_state == XGBE_AN_NO_LINK) {
844		pdata->an_int = 0;
845		xgbe_an73_clear_interrupts(pdata);
846	} else if (pdata->an_state == XGBE_AN_ERROR) {
847		axgbe_printf(2,
848		    "error during auto-negotiation, state=%u\n",
849		    cur_state);
850
851		pdata->an_int = 0;
852		xgbe_an73_clear_interrupts(pdata);
853	}
854
855	if (pdata->an_state >= XGBE_AN_COMPLETE) {
856		pdata->an_result = pdata->an_state;
857		pdata->an_state = XGBE_AN_READY;
858		pdata->kr_state = XGBE_RX_BPA;
859		pdata->kx_state = XGBE_RX_BPA;
860		pdata->an_start = 0;
861
862		if (pdata->phy_if.phy_impl.an_post)
863			pdata->phy_if.phy_impl.an_post(pdata);
864
865		axgbe_printf(2,  "CL73 AN result: %s\n",
866		    xgbe_state_as_string(pdata->an_result));
867	}
868
869	if (cur_state != pdata->an_state)
870		goto again;
871
872	if (pdata->an_int)
873		goto next_int;
874
875out:
876	/* Enable AN interrupts on the way out */
877	xgbe_an73_enable_interrupts(pdata);
878}
879
880static void
881xgbe_an_state_machine(struct xgbe_prv_data *pdata)
882{
883	sx_xlock(&pdata->an_mutex);
884
885	switch (pdata->an_mode) {
886	case XGBE_AN_MODE_CL73:
887	case XGBE_AN_MODE_CL73_REDRV:
888		xgbe_an73_state_machine(pdata);
889		break;
890	case XGBE_AN_MODE_CL37:
891	case XGBE_AN_MODE_CL37_SGMII:
892		xgbe_an37_state_machine(pdata);
893		break;
894	default:
895		break;
896	}
897
898	/* Reissue interrupt if status is not clear */
899	if (pdata->vdata->irq_reissue_support)
900		XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);
901
902	sx_xunlock(&pdata->an_mutex);
903}
904
905static void
906xgbe_an37_init(struct xgbe_prv_data *pdata)
907{
908	struct xgbe_phy local_phy;
909	unsigned int reg;
910
911	pdata->phy_if.phy_impl.an_advertising(pdata, &local_phy);
912
913	axgbe_printf(2, "%s: advertising 0x%x\n", __func__, local_phy.advertising);
914
915	/* Set up Advertisement register */
916	reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE);
917	if (XGBE_ADV(&local_phy, Pause))
918		reg |= 0x100;
919	else
920		reg &= ~0x100;
921
922	if (XGBE_ADV(&local_phy, Asym_Pause))
923		reg |= 0x80;
924	else
925		reg &= ~0x80;
926
927	/* Full duplex, but not half */
928	reg |= XGBE_AN_CL37_FD_MASK;
929	reg &= ~XGBE_AN_CL37_HD_MASK;
930
931	axgbe_printf(2, "%s: Writing reg: 0x%x\n", __func__, reg);
932	XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE, reg);
933
934	/* Set up the Control register */
935	reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);
936	axgbe_printf(2, "%s: AN_ADVERTISE reg 0x%x an_mode %d\n", __func__,
937	    reg, pdata->an_mode);
938	reg &= ~XGBE_AN_CL37_TX_CONFIG_MASK;
939	reg &= ~XGBE_AN_CL37_PCS_MODE_MASK;
940
941	switch (pdata->an_mode) {
942	case XGBE_AN_MODE_CL37:
943		reg |= XGBE_AN_CL37_PCS_MODE_BASEX;
944		break;
945	case XGBE_AN_MODE_CL37_SGMII:
946		reg |= XGBE_AN_CL37_PCS_MODE_SGMII;
947		break;
948	default:
949		break;
950	}
951
952	reg |= XGBE_AN_CL37_MII_CTRL_8BIT;
953	axgbe_printf(2, "%s: Writing reg: 0x%x\n", __func__, reg);
954	XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
955
956	axgbe_printf(2, "CL37 AN (%s) initialized\n",
957	    (pdata->an_mode == XGBE_AN_MODE_CL37) ? "BaseX" : "SGMII");
958}
959
960static void
961xgbe_an73_init(struct xgbe_prv_data *pdata)
962{
963	/*
964	 * This local_phy is needed because phy-v2 alters the
965	 * advertising flag variable. so phy-v1 an_advertising is just copying
966	 */
967	struct xgbe_phy local_phy;
968	unsigned int reg;
969
970	pdata->phy_if.phy_impl.an_advertising(pdata, &local_phy);
971
972	/* Set up Advertisement register 3 first */
973	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
974	if (XGBE_ADV(&local_phy, 10000baseR_FEC))
975		reg |= 0xc000;
976	else
977		reg &= ~0xc000;
978
979	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, reg);
980
981	/* Set up Advertisement register 2 next */
982	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
983	if (XGBE_ADV(&local_phy, 10000baseKR_Full))
984		reg |= 0x80;
985	else
986		reg &= ~0x80;
987
988	if (XGBE_ADV(&local_phy, 1000baseKX_Full) ||
989	    XGBE_ADV(&local_phy, 2500baseX_Full))
990		reg |= 0x20;
991	else
992		reg &= ~0x20;
993
994	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, reg);
995
996	/* Set up Advertisement register 1 last */
997	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
998	if (XGBE_ADV(&local_phy, Pause))
999		reg |= 0x400;
1000	else
1001		reg &= ~0x400;
1002
1003	if (XGBE_ADV(&local_phy, Asym_Pause))
1004		reg |= 0x800;
1005	else
1006		reg &= ~0x800;
1007
1008	/* We don't intend to perform XNP */
1009	reg &= ~XGBE_XNP_NP_EXCHANGE;
1010
1011	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
1012
1013	axgbe_printf(2, "CL73 AN initialized\n");
1014}
1015
1016static void
1017xgbe_an_init(struct xgbe_prv_data *pdata)
1018{
1019	/* Set up advertisement registers based on current settings */
1020	pdata->an_mode = pdata->phy_if.phy_impl.an_mode(pdata);
1021	axgbe_printf(2, "%s: setting up an_mode %d\n", __func__, pdata->an_mode);
1022
1023	switch (pdata->an_mode) {
1024	case XGBE_AN_MODE_CL73:
1025	case XGBE_AN_MODE_CL73_REDRV:
1026		xgbe_an73_init(pdata);
1027		break;
1028	case XGBE_AN_MODE_CL37:
1029	case XGBE_AN_MODE_CL37_SGMII:
1030		xgbe_an37_init(pdata);
1031		break;
1032	default:
1033		break;
1034	}
1035}
1036
1037static const char *
1038xgbe_phy_fc_string(struct xgbe_prv_data *pdata)
1039{
1040	if (pdata->tx_pause && pdata->rx_pause)
1041		return ("rx/tx");
1042	else if (pdata->rx_pause)
1043		return ("rx");
1044	else if (pdata->tx_pause)
1045		return ("tx");
1046	else
1047		return ("off");
1048}
1049
1050static const char *
1051xgbe_phy_speed_string(int speed)
1052{
1053	switch (speed) {
1054	case SPEED_100:
1055		return ("100Mbps");
1056	case SPEED_1000:
1057		return ("1Gbps");
1058	case SPEED_2500:
1059		return ("2.5Gbps");
1060	case SPEED_10000:
1061		return ("10Gbps");
1062	case SPEED_UNKNOWN:
1063		return ("Unknown");
1064	default:
1065		return ("Unsupported");
1066	}
1067}
1068
1069static void
1070xgbe_phy_print_status(struct xgbe_prv_data *pdata)
1071{
1072	if (pdata->phy.link)
1073		axgbe_printf(0,
1074		    "Link is UP - %s/%s - flow control %s\n",
1075		    xgbe_phy_speed_string(pdata->phy.speed),
1076		    pdata->phy.duplex == DUPLEX_FULL ? "Full" : "Half",
1077		    xgbe_phy_fc_string(pdata));
1078	else
1079		axgbe_printf(0, "Link is DOWN\n");
1080}
1081
1082static void
1083xgbe_phy_adjust_link(struct xgbe_prv_data *pdata)
1084{
1085	int new_state = 0;
1086
1087	axgbe_printf(1, "link %d/%d tx %d/%d rx %d/%d speed %d/%d autoneg %d/%d\n",
1088	    pdata->phy_link, pdata->phy.link,
1089	    pdata->tx_pause, pdata->phy.tx_pause,
1090	    pdata->rx_pause, pdata->phy.rx_pause,
1091	    pdata->phy_speed, pdata->phy.speed,
1092	    pdata->pause_autoneg, pdata->phy.pause_autoneg);
1093
1094	if (pdata->phy.link) {
1095		/* Flow control support */
1096		pdata->pause_autoneg = pdata->phy.pause_autoneg;
1097
1098		if (pdata->tx_pause != pdata->phy.tx_pause) {
1099			new_state = 1;
1100			axgbe_printf(2, "tx pause %d/%d\n", pdata->tx_pause,
1101			    pdata->phy.tx_pause);
1102			pdata->tx_pause = pdata->phy.tx_pause;
1103			pdata->hw_if.config_tx_flow_control(pdata);
1104		}
1105
1106		if (pdata->rx_pause != pdata->phy.rx_pause) {
1107			new_state = 1;
1108			axgbe_printf(2, "rx pause %d/%d\n", pdata->rx_pause,
1109			    pdata->phy.rx_pause);
1110			pdata->rx_pause = pdata->phy.rx_pause;
1111			pdata->hw_if.config_rx_flow_control(pdata);
1112		}
1113
1114		/* Speed support */
1115		if (pdata->phy_speed != pdata->phy.speed) {
1116			new_state = 1;
1117			pdata->phy_speed = pdata->phy.speed;
1118		}
1119
1120		if (pdata->phy_link != pdata->phy.link) {
1121			new_state = 1;
1122			pdata->phy_link = pdata->phy.link;
1123		}
1124	} else if (pdata->phy_link) {
1125		new_state = 1;
1126		pdata->phy_link = 0;
1127		pdata->phy_speed = SPEED_UNKNOWN;
1128	}
1129
1130	axgbe_printf(2, "phy_link %d Link %d new_state %d\n", pdata->phy_link,
1131	    pdata->phy.link, new_state);
1132
1133	if (new_state)
1134		xgbe_phy_print_status(pdata);
1135}
1136
1137static bool
1138xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed)
1139{
1140	return (pdata->phy_if.phy_impl.valid_speed(pdata, speed));
1141}
1142
1143static int
1144xgbe_phy_config_fixed(struct xgbe_prv_data *pdata)
1145{
1146	enum xgbe_mode mode;
1147
1148	axgbe_printf(2, "fixed PHY configuration\n");
1149
1150	/* Disable auto-negotiation */
1151	xgbe_an_disable(pdata);
1152
1153	/* Set specified mode for specified speed */
1154	mode = pdata->phy_if.phy_impl.get_mode(pdata, pdata->phy.speed);
1155	switch (mode) {
1156	case XGBE_MODE_KX_1000:
1157	case XGBE_MODE_KX_2500:
1158	case XGBE_MODE_KR:
1159	case XGBE_MODE_SGMII_100:
1160	case XGBE_MODE_SGMII_1000:
1161	case XGBE_MODE_X:
1162	case XGBE_MODE_SFI:
1163		break;
1164	case XGBE_MODE_UNKNOWN:
1165	default:
1166		return (-EINVAL);
1167	}
1168
1169	/* Validate duplex mode */
1170	if (pdata->phy.duplex != DUPLEX_FULL)
1171		return (-EINVAL);
1172
1173	xgbe_set_mode(pdata, mode);
1174
1175	return (0);
1176}
1177
1178static int
1179__xgbe_phy_config_aneg(struct xgbe_prv_data *pdata, bool set_mode)
1180{
1181	int ret;
1182	unsigned int reg = 0;
1183
1184	sx_xlock(&pdata->an_mutex);
1185
1186	set_bit(XGBE_LINK_INIT, &pdata->dev_state);
1187	pdata->link_check = ticks;
1188
1189	ret = pdata->phy_if.phy_impl.an_config(pdata);
1190	if (ret) {
1191		axgbe_error("%s: an_config fail %d\n", __func__, ret);
1192		goto out;
1193	}
1194
1195	if (pdata->phy.autoneg != AUTONEG_ENABLE) {
1196		ret = xgbe_phy_config_fixed(pdata);
1197		if (ret || !pdata->kr_redrv) {
1198			if (ret)
1199				axgbe_error("%s: fix conf fail %d\n", __func__, ret);
1200			goto out;
1201		}
1202
1203		axgbe_printf(2, "AN redriver support\n");
1204	} else
1205		axgbe_printf(2, "AN PHY configuration\n");
1206
1207	/* Disable auto-negotiation interrupt */
1208	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);
1209	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK);
1210	axgbe_printf(2, "%s: set_mode %d AN int reg value 0x%x\n", __func__,
1211	    set_mode, reg);
1212
1213	/* Clear any auto-negotitation interrupts */
1214	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
1215
1216	/* Start auto-negotiation in a supported mode */
1217	if (set_mode) {
1218		/* Start auto-negotiation in a supported mode */
1219		if (xgbe_use_mode(pdata, XGBE_MODE_KR)) {
1220			xgbe_set_mode(pdata, XGBE_MODE_KR);
1221		} else if (xgbe_use_mode(pdata, XGBE_MODE_KX_2500)) {
1222			xgbe_set_mode(pdata, XGBE_MODE_KX_2500);
1223		} else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) {
1224			xgbe_set_mode(pdata, XGBE_MODE_KX_1000);
1225		} else if (xgbe_use_mode(pdata, XGBE_MODE_SFI)) {
1226			xgbe_set_mode(pdata, XGBE_MODE_SFI);
1227		} else if (xgbe_use_mode(pdata, XGBE_MODE_X)) {
1228			xgbe_set_mode(pdata, XGBE_MODE_X);
1229		} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_1000)) {
1230			xgbe_set_mode(pdata, XGBE_MODE_SGMII_1000);
1231		} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {
1232			xgbe_set_mode(pdata, XGBE_MODE_SGMII_100);
1233		} else {
1234			XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07);
1235			ret = -EINVAL;
1236			goto out;
1237		}
1238	}
1239
1240	/* Disable and stop any in progress auto-negotiation */
1241	xgbe_an_disable_all(pdata);
1242
1243	/* Clear any auto-negotitation interrupts */
1244	xgbe_an_clear_interrupts_all(pdata);
1245
1246	pdata->an_result = XGBE_AN_READY;
1247	pdata->an_state = XGBE_AN_READY;
1248	pdata->kr_state = XGBE_RX_BPA;
1249	pdata->kx_state = XGBE_RX_BPA;
1250
1251	/* Re-enable auto-negotiation interrupt */
1252	XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07);
1253	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK);
1254
1255	/* Set up advertisement registers based on current settings */
1256	xgbe_an_init(pdata);
1257
1258	/* Enable and start auto-negotiation */
1259	xgbe_an_restart(pdata);
1260
1261out:
1262	if (ret) {
1263		axgbe_printf(0, "%s: set_mode %d AN int reg value 0x%x ret value %d\n",
1264		   __func__, set_mode, reg, ret);
1265		set_bit(XGBE_LINK_ERR, &pdata->dev_state);
1266	} else
1267		clear_bit(XGBE_LINK_ERR, &pdata->dev_state);
1268
1269	sx_unlock(&pdata->an_mutex);
1270
1271	return (ret);
1272}
1273
1274static int
1275xgbe_phy_config_aneg(struct xgbe_prv_data *pdata)
1276{
1277	return (__xgbe_phy_config_aneg(pdata, true));
1278}
1279
1280static int
1281xgbe_phy_reconfig_aneg(struct xgbe_prv_data *pdata)
1282{
1283	return (__xgbe_phy_config_aneg(pdata, false));
1284}
1285
1286static bool
1287xgbe_phy_aneg_done(struct xgbe_prv_data *pdata)
1288{
1289	return (pdata->an_result == XGBE_AN_COMPLETE);
1290}
1291
1292static void
1293xgbe_check_link_timeout(struct xgbe_prv_data *pdata)
1294{
1295	unsigned long link_timeout;
1296
1297	link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * hz);
1298	if ((int)(ticks - link_timeout) > 0) {
1299		axgbe_printf(2, "AN link timeout\n");
1300		xgbe_phy_config_aneg(pdata);
1301	}
1302}
1303
1304static enum xgbe_mode
1305xgbe_phy_status_aneg(struct xgbe_prv_data *pdata)
1306{
1307	return (pdata->phy_if.phy_impl.an_outcome(pdata));
1308}
1309
1310static void
1311xgbe_phy_status_result(struct xgbe_prv_data *pdata)
1312{
1313	enum xgbe_mode mode;
1314
1315	XGBE_ZERO_LP_ADV(&pdata->phy);
1316
1317	if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect)
1318		mode = xgbe_cur_mode(pdata);
1319	else
1320		mode = xgbe_phy_status_aneg(pdata);
1321
1322	axgbe_printf(3, "%s: xgbe mode %d\n", __func__, mode);
1323	switch (mode) {
1324	case XGBE_MODE_SGMII_100:
1325		pdata->phy.speed = SPEED_100;
1326		break;
1327	case XGBE_MODE_X:
1328	case XGBE_MODE_KX_1000:
1329	case XGBE_MODE_SGMII_1000:
1330		pdata->phy.speed = SPEED_1000;
1331		break;
1332	case XGBE_MODE_KX_2500:
1333		pdata->phy.speed = SPEED_2500;
1334		break;
1335	case XGBE_MODE_KR:
1336	case XGBE_MODE_SFI:
1337		pdata->phy.speed = SPEED_10000;
1338		break;
1339	case XGBE_MODE_UNKNOWN:
1340	default:
1341		axgbe_printf(1, "%s: unknown mode\n", __func__);
1342		pdata->phy.speed = SPEED_UNKNOWN;
1343	}
1344
1345	pdata->phy.duplex = DUPLEX_FULL;
1346	axgbe_printf(2, "%s: speed %d duplex %d\n", __func__, pdata->phy.speed,
1347	    pdata->phy.duplex);
1348
1349	if (xgbe_set_mode(pdata, mode) && pdata->an_again)
1350		xgbe_phy_reconfig_aneg(pdata);
1351}
1352
1353static void
1354xgbe_phy_status(struct xgbe_prv_data *pdata)
1355{
1356	bool link_aneg;
1357	int an_restart;
1358
1359	if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) {
1360		axgbe_error("%s: LINK_ERR\n", __func__);
1361		pdata->phy.link = 0;
1362		clear_bit(XGBE_LINK_ERR, &pdata->dev_state);
1363		goto adjust_link;
1364	}
1365
1366	link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE);
1367	axgbe_printf(3, "link_aneg - %d\n", link_aneg);
1368
1369	/* Get the link status. Link status is latched low, so read
1370	 * once to clear and then read again to get current state
1371	 */
1372	pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata,
1373	    &an_restart);
1374
1375	axgbe_printf(1, "link_status returned Link:%d an_restart:%d aneg:%d\n",
1376	    pdata->phy.link, an_restart, link_aneg);
1377
1378	if (an_restart) {
1379		xgbe_phy_config_aneg(pdata);
1380		return;
1381	}
1382
1383	if (pdata->phy.link) {
1384		axgbe_printf(2, "Link Active\n");
1385		if (link_aneg && !xgbe_phy_aneg_done(pdata)) {
1386			axgbe_printf(1, "phy_link set check timeout\n");
1387			xgbe_check_link_timeout(pdata);
1388			return;
1389		}
1390
1391		axgbe_printf(2, "%s: Link write phy_status result\n", __func__);
1392		xgbe_phy_status_result(pdata);
1393
1394		if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))
1395			clear_bit(XGBE_LINK_INIT, &pdata->dev_state);
1396
1397	} else {
1398		axgbe_printf(2, "Link Deactive\n");
1399		if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) {
1400			axgbe_printf(1, "phy_link not set check timeout\n");
1401			xgbe_check_link_timeout(pdata);
1402
1403			if (link_aneg) {
1404				axgbe_printf(2, "link_aneg case\n");
1405				return;
1406			}
1407		}
1408
1409		xgbe_phy_status_result(pdata);
1410
1411	}
1412
1413adjust_link:
1414	axgbe_printf(2, "%s: Link %d\n", __func__, pdata->phy.link);
1415	xgbe_phy_adjust_link(pdata);
1416}
1417
1418static void
1419xgbe_phy_stop(struct xgbe_prv_data *pdata)
1420{
1421	axgbe_printf(2, "stopping PHY\n");
1422
1423	if (!pdata->phy_started)
1424		return;
1425
1426	/* Indicate the PHY is down */
1427	pdata->phy_started = 0;
1428
1429	/* Disable auto-negotiation */
1430	xgbe_an_disable_all(pdata);
1431
1432	pdata->phy_if.phy_impl.stop(pdata);
1433
1434	pdata->phy.link = 0;
1435
1436	xgbe_phy_adjust_link(pdata);
1437}
1438
1439static int
1440xgbe_phy_start(struct xgbe_prv_data *pdata)
1441{
1442	int ret = 0;
1443
1444	if (pdata->phy_started)
1445		return (ret);
1446
1447	DBGPR("-->xgbe_phy_start\n");
1448
1449	ret = pdata->phy_if.phy_impl.start(pdata);
1450	if (ret) {
1451		axgbe_error("%s: impl start ret %d\n", __func__, ret);
1452		return (ret);
1453	}
1454
1455	/* Set initial mode - call the mode setting routines
1456	 * directly to insure we are properly configured
1457	 */
1458	if (xgbe_use_mode(pdata, XGBE_MODE_KR)) {
1459		axgbe_printf(2, "%s: KR\n", __func__);
1460		xgbe_kr_mode(pdata);
1461	} else if (xgbe_use_mode(pdata, XGBE_MODE_KX_2500)) {
1462		axgbe_printf(2, "%s: KX 2500\n", __func__);
1463		xgbe_kx_2500_mode(pdata);
1464	} else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) {
1465		axgbe_printf(2, "%s: KX 1000\n", __func__);
1466		xgbe_kx_1000_mode(pdata);
1467	} else if (xgbe_use_mode(pdata, XGBE_MODE_SFI)) {
1468		axgbe_printf(2, "%s: SFI\n", __func__);
1469		xgbe_sfi_mode(pdata);
1470	} else if (xgbe_use_mode(pdata, XGBE_MODE_X)) {
1471		axgbe_printf(2, "%s: X\n", __func__);
1472		xgbe_x_mode(pdata);
1473	} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_1000)) {
1474		axgbe_printf(2, "%s: SGMII 1000\n", __func__);
1475		xgbe_sgmii_1000_mode(pdata);
1476	} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {
1477		axgbe_printf(2, "%s: SGMII 100\n", __func__);
1478		xgbe_sgmii_100_mode(pdata);
1479	} else {
1480		axgbe_error("%s: invalid mode\n", __func__);
1481		ret = -EINVAL;
1482		goto err_stop;
1483	}
1484
1485	/* Indicate the PHY is up and running */
1486	pdata->phy_started = 1;
1487
1488	/* Set up advertisement registers based on current settings */
1489	xgbe_an_init(pdata);
1490
1491	/* Enable auto-negotiation interrupts */
1492	xgbe_an_enable_interrupts(pdata);
1493
1494	ret = xgbe_phy_config_aneg(pdata);
1495	if (ret)
1496		axgbe_error("%s: phy_config_aneg %d\n", __func__, ret);
1497
1498	return (ret);
1499
1500err_stop:
1501	pdata->phy_if.phy_impl.stop(pdata);
1502
1503	return (ret);
1504}
1505
1506static int
1507xgbe_phy_reset(struct xgbe_prv_data *pdata)
1508{
1509	int ret;
1510
1511	ret = pdata->phy_if.phy_impl.reset(pdata);
1512	if (ret) {
1513		axgbe_error("%s: impl phy reset %d\n", __func__, ret);
1514		return (ret);
1515	}
1516
1517	/* Disable auto-negotiation for now */
1518	xgbe_an_disable_all(pdata);
1519
1520	/* Clear auto-negotiation interrupts */
1521	xgbe_an_clear_interrupts_all(pdata);
1522
1523	return (0);
1524}
1525
1526static int
1527xgbe_phy_best_advertised_speed(struct xgbe_prv_data *pdata)
1528{
1529
1530	if (XGBE_ADV(&pdata->phy, 10000baseKR_Full))
1531		return (SPEED_10000);
1532	else if (XGBE_ADV(&pdata->phy, 10000baseT_Full))
1533		return (SPEED_10000);
1534	else if (XGBE_ADV(&pdata->phy, 2500baseX_Full))
1535		return (SPEED_2500);
1536	else if (XGBE_ADV(&pdata->phy, 2500baseT_Full))
1537		return (SPEED_2500);
1538	else if (XGBE_ADV(&pdata->phy, 1000baseKX_Full))
1539		return (SPEED_1000);
1540	else if (XGBE_ADV(&pdata->phy, 1000baseT_Full))
1541		return (SPEED_1000);
1542	else if (XGBE_ADV(&pdata->phy, 100baseT_Full))
1543		return (SPEED_100);
1544
1545	return (SPEED_UNKNOWN);
1546}
1547
1548static void
1549xgbe_phy_exit(struct xgbe_prv_data *pdata)
1550{
1551	pdata->phy_if.phy_impl.exit(pdata);
1552}
1553
1554static int
1555xgbe_phy_init(struct xgbe_prv_data *pdata)
1556{
1557	int ret = 0;
1558
1559	DBGPR("-->xgbe_phy_init\n");
1560
1561	sx_init(&pdata->an_mutex, "axgbe AN lock");
1562	pdata->mdio_mmd = MDIO_MMD_PCS;
1563
1564	/* Initialize supported features */
1565	pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD,
1566					MDIO_PMA_10GBR_FECABLE);
1567	pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE |
1568			       MDIO_PMA_10GBR_FECABLE_ERRABLE);
1569
1570	/* Setup the phy (including supported features) */
1571	ret = pdata->phy_if.phy_impl.init(pdata);
1572	if (ret)
1573		return (ret);
1574
1575	/* Copy supported link modes to advertising link modes */
1576	XGBE_LM_COPY(&pdata->phy, advertising, &pdata->phy, supported);
1577
1578	pdata->phy.address = 0;
1579
1580	if (XGBE_ADV(&pdata->phy, Autoneg)) {
1581		pdata->phy.autoneg = AUTONEG_ENABLE;
1582		pdata->phy.speed = SPEED_UNKNOWN;
1583		pdata->phy.duplex = DUPLEX_UNKNOWN;
1584	} else {
1585		pdata->phy.autoneg = AUTONEG_DISABLE;
1586		pdata->phy.speed = xgbe_phy_best_advertised_speed(pdata);
1587		pdata->phy.duplex = DUPLEX_FULL;
1588	}
1589
1590	pdata->phy_started = 0;
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
1616void
1617xgbe_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