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