1 /*
2 * AMD 10Gb Ethernet driver
3 *
4 * Copyright (c) 2014-2016,2020 Advanced Micro Devices, Inc.
5 *
6 * This file is available to you under your choice of the following two
7 * licenses:
8 *
9 * License 1: GPLv2
10 *
11 * This file is free software; you may copy, redistribute and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This file is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 *
24 * This file incorporates work covered by the following copyright and
25 * permission notice:
26 * The Synopsys DWC ETHER XGMAC Software Driver and documentation
27 * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
28 * Inc. unless otherwise expressly agreed to in writing between Synopsys
29 * and you.
30 *
31 * The Software IS NOT an item of Licensed Software or Licensed Product
32 * under any End User Software License Agreement or Agreement for Licensed
33 * Product with Synopsys or any supplement thereto. Permission is hereby
34 * granted, free of charge, to any person obtaining a copy of this software
35 * annotated with this license and the Software, to deal in the Software
36 * without restriction, including without limitation the rights to use,
37 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
38 * of the Software, and to permit persons to whom the Software is furnished
39 * to do so, subject to the following conditions:
40 *
41 * The above copyright notice and this permission notice shall be included
42 * in all copies or substantial portions of the Software.
43 *
44 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
45 * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
46 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
47 * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
48 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
49 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
50 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
51 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
52 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
54 * THE POSSIBILITY OF SUCH DAMAGE.
55 *
56 *
57 * License 2: Modified BSD
58 *
59 * Redistribution and use in source and binary forms, with or without
60 * modification, are permitted provided that the following conditions are met:
61 * * Redistributions of source code must retain the above copyright
62 * notice, this list of conditions and the following disclaimer.
63 * * Redistributions in binary form must reproduce the above copyright
64 * notice, this list of conditions and the following disclaimer in the
65 * documentation and/or other materials provided with the distribution.
66 * * Neither the name of Advanced Micro Devices, Inc. nor the
67 * names of its contributors may be used to endorse or promote products
68 * derived from this software without specific prior written permission.
69 *
70 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
71 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
72 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
73 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
74 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
79 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80 *
81 * This file incorporates work covered by the following copyright and
82 * permission notice:
83 * The Synopsys DWC ETHER XGMAC Software Driver and documentation
84 * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
85 * Inc. unless otherwise expressly agreed to in writing between Synopsys
86 * and you.
87 *
88 * The Software IS NOT an item of Licensed Software or Licensed Product
89 * under any End User Software License Agreement or Agreement for Licensed
90 * Product with Synopsys or any supplement thereto. Permission is hereby
91 * granted, free of charge, to any person obtaining a copy of this software
92 * annotated with this license and the Software, to deal in the Software
93 * without restriction, including without limitation the rights to use,
94 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
95 * of the Software, and to permit persons to whom the Software is furnished
96 * to do so, subject to the following conditions:
97 *
98 * The above copyright notice and this permission notice shall be included
99 * in all copies or substantial portions of the Software.
100 *
101 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
102 * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
103 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
104 * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
105 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
106 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
107 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
108 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
109 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
110 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
111 * THE POSSIBILITY OF SUCH DAMAGE.
112 */
113
114 #include <sys/cdefs.h>
115 #include "xgbe.h"
116 #include "xgbe-common.h"
117
118 static void xgbe_an_state_machine(struct xgbe_prv_data *pdata);
119
120 static void
xgbe_an37_clear_interrupts(struct xgbe_prv_data * pdata)121 xgbe_an37_clear_interrupts(struct xgbe_prv_data *pdata)
122 {
123 int reg;
124
125 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT);
126 reg &= ~XGBE_AN_CL37_INT_MASK;
127 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg);
128 }
129
130 static void
xgbe_an37_disable_interrupts(struct xgbe_prv_data * pdata)131 xgbe_an37_disable_interrupts(struct xgbe_prv_data *pdata)
132 {
133 int reg;
134
135 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);
136 reg &= ~XGBE_AN_CL37_INT_MASK;
137 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
138
139 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL);
140 reg &= ~XGBE_PCS_CL37_BP;
141 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL, reg);
142 }
143
144 static void
xgbe_an37_enable_interrupts(struct xgbe_prv_data * pdata)145 xgbe_an37_enable_interrupts(struct xgbe_prv_data *pdata)
146 {
147 int reg;
148
149 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL);
150 reg |= XGBE_PCS_CL37_BP;
151 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL, reg);
152
153 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);
154 reg |= XGBE_AN_CL37_INT_MASK;
155 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
156 }
157
158 static void
xgbe_an73_clear_interrupts(struct xgbe_prv_data * pdata)159 xgbe_an73_clear_interrupts(struct xgbe_prv_data *pdata)
160 {
161 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
162 }
163
164 static void
xgbe_an73_disable_interrupts(struct xgbe_prv_data * pdata)165 xgbe_an73_disable_interrupts(struct xgbe_prv_data *pdata)
166 {
167 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);
168 }
169
170 static void
xgbe_an73_enable_interrupts(struct xgbe_prv_data * pdata)171 xgbe_an73_enable_interrupts(struct xgbe_prv_data *pdata)
172 {
173 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, XGBE_AN_CL73_INT_MASK);
174 }
175
176 static void
xgbe_an_enable_interrupts(struct xgbe_prv_data * pdata)177 xgbe_an_enable_interrupts(struct xgbe_prv_data *pdata)
178 {
179 switch (pdata->an_mode) {
180 case XGBE_AN_MODE_CL73:
181 case XGBE_AN_MODE_CL73_REDRV:
182 xgbe_an73_enable_interrupts(pdata);
183 break;
184 case XGBE_AN_MODE_CL37:
185 case XGBE_AN_MODE_CL37_SGMII:
186 xgbe_an37_enable_interrupts(pdata);
187 break;
188 default:
189 break;
190 }
191 }
192
193 static void
xgbe_an_clear_interrupts_all(struct xgbe_prv_data * pdata)194 xgbe_an_clear_interrupts_all(struct xgbe_prv_data *pdata)
195 {
196 xgbe_an73_clear_interrupts(pdata);
197 xgbe_an37_clear_interrupts(pdata);
198 }
199
200 static void
xgbe_kr_mode(struct xgbe_prv_data * pdata)201 xgbe_kr_mode(struct xgbe_prv_data *pdata)
202 {
203 /* Set MAC to 10G speed */
204 pdata->hw_if.set_speed(pdata, SPEED_10000);
205
206 /* Call PHY implementation support to complete rate change */
207 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KR);
208 }
209
210 static void
xgbe_kx_2500_mode(struct xgbe_prv_data * pdata)211 xgbe_kx_2500_mode(struct xgbe_prv_data *pdata)
212 {
213 /* Set MAC to 2.5G speed */
214 pdata->hw_if.set_speed(pdata, SPEED_2500);
215
216 /* Call PHY implementation support to complete rate change */
217 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KX_2500);
218 }
219
220 static void
xgbe_kx_1000_mode(struct xgbe_prv_data * pdata)221 xgbe_kx_1000_mode(struct xgbe_prv_data *pdata)
222 {
223 /* Set MAC to 1G speed */
224 pdata->hw_if.set_speed(pdata, SPEED_1000);
225
226 /* Call PHY implementation support to complete rate change */
227 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KX_1000);
228 }
229
230 static void
xgbe_sfi_mode(struct xgbe_prv_data * pdata)231 xgbe_sfi_mode(struct xgbe_prv_data *pdata)
232 {
233 /* If a KR re-driver is present, change to KR mode instead */
234 if (pdata->kr_redrv)
235 return (xgbe_kr_mode(pdata));
236
237 /* Set MAC to 10G speed */
238 pdata->hw_if.set_speed(pdata, SPEED_10000);
239
240 /* Call PHY implementation support to complete rate change */
241 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SFI);
242 }
243
244 static void
xgbe_x_mode(struct xgbe_prv_data * pdata)245 xgbe_x_mode(struct xgbe_prv_data *pdata)
246 {
247 /* Set MAC to 1G speed */
248 pdata->hw_if.set_speed(pdata, SPEED_1000);
249
250 /* Call PHY implementation support to complete rate change */
251 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_X);
252 }
253
254 static void
xgbe_sgmii_1000_mode(struct xgbe_prv_data * pdata)255 xgbe_sgmii_1000_mode(struct xgbe_prv_data *pdata)
256 {
257 /* Set MAC to 1G speed */
258 pdata->hw_if.set_speed(pdata, SPEED_1000);
259
260 /* Call PHY implementation support to complete rate change */
261 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_1000);
262 }
263
264 static void
xgbe_sgmii_100_mode(struct xgbe_prv_data * pdata)265 xgbe_sgmii_100_mode(struct xgbe_prv_data *pdata)
266 {
267 /* Set MAC to 1G speed */
268 pdata->hw_if.set_speed(pdata, SPEED_1000);
269
270 /* Call PHY implementation support to complete rate change */
271 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_100);
272 }
273
274 static enum xgbe_mode
xgbe_cur_mode(struct xgbe_prv_data * pdata)275 xgbe_cur_mode(struct xgbe_prv_data *pdata)
276 {
277 return (pdata->phy_if.phy_impl.cur_mode(pdata));
278 }
279
280 static bool
xgbe_in_kr_mode(struct xgbe_prv_data * pdata)281 xgbe_in_kr_mode(struct xgbe_prv_data *pdata)
282 {
283 return (xgbe_cur_mode(pdata) == XGBE_MODE_KR);
284 }
285
286 static void
xgbe_change_mode(struct xgbe_prv_data * pdata,enum xgbe_mode mode)287 xgbe_change_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
288 {
289 switch (mode) {
290 case XGBE_MODE_KX_1000:
291 xgbe_kx_1000_mode(pdata);
292 break;
293 case XGBE_MODE_KX_2500:
294 xgbe_kx_2500_mode(pdata);
295 break;
296 case XGBE_MODE_KR:
297 xgbe_kr_mode(pdata);
298 break;
299 case XGBE_MODE_SGMII_100:
300 xgbe_sgmii_100_mode(pdata);
301 break;
302 case XGBE_MODE_SGMII_1000:
303 xgbe_sgmii_1000_mode(pdata);
304 break;
305 case XGBE_MODE_X:
306 xgbe_x_mode(pdata);
307 break;
308 case XGBE_MODE_SFI:
309 xgbe_sfi_mode(pdata);
310 break;
311 case XGBE_MODE_UNKNOWN:
312 break;
313 default:
314 axgbe_error("invalid operation mode requested (%u)\n", mode);
315 }
316 }
317
318 static void
xgbe_switch_mode(struct xgbe_prv_data * pdata)319 xgbe_switch_mode(struct xgbe_prv_data *pdata)
320 {
321 xgbe_change_mode(pdata, pdata->phy_if.phy_impl.switch_mode(pdata));
322 }
323
324 static bool
xgbe_set_mode(struct xgbe_prv_data * pdata,enum xgbe_mode mode)325 xgbe_set_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
326 {
327 if (mode == xgbe_cur_mode(pdata))
328 return (false);
329
330 xgbe_change_mode(pdata, mode);
331
332 return (true);
333 }
334
335 static bool
xgbe_use_mode(struct xgbe_prv_data * pdata,enum xgbe_mode mode)336 xgbe_use_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
337 {
338 return (pdata->phy_if.phy_impl.use_mode(pdata, mode));
339 }
340
341 static void
xgbe_an37_set(struct xgbe_prv_data * pdata,bool enable,bool restart)342 xgbe_an37_set(struct xgbe_prv_data *pdata, bool enable, bool restart)
343 {
344 unsigned int reg;
345
346 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_CTRL1);
347 reg &= ~MDIO_VEND2_CTRL1_AN_ENABLE;
348
349 if (enable)
350 reg |= MDIO_VEND2_CTRL1_AN_ENABLE;
351
352 if (restart)
353 reg |= MDIO_VEND2_CTRL1_AN_RESTART;
354
355 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_CTRL1, reg);
356 }
357
358 static void
xgbe_an37_restart(struct xgbe_prv_data * pdata)359 xgbe_an37_restart(struct xgbe_prv_data *pdata)
360 {
361 xgbe_an37_enable_interrupts(pdata);
362 xgbe_an37_set(pdata, true, true);
363 }
364
365 static void
xgbe_an37_disable(struct xgbe_prv_data * pdata)366 xgbe_an37_disable(struct xgbe_prv_data *pdata)
367 {
368 xgbe_an37_set(pdata, false, false);
369 xgbe_an37_disable_interrupts(pdata);
370 }
371
372 static void
xgbe_an73_set(struct xgbe_prv_data * pdata,bool enable,bool restart)373 xgbe_an73_set(struct xgbe_prv_data *pdata, bool enable, bool restart)
374 {
375 unsigned int reg;
376
377 /* Disable KR training for now */
378 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
379 reg &= ~XGBE_KR_TRAINING_ENABLE;
380 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
381
382 /* Update AN settings */
383 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1);
384 reg &= ~MDIO_AN_CTRL1_ENABLE;
385
386 if (enable)
387 reg |= MDIO_AN_CTRL1_ENABLE;
388
389 if (restart)
390 reg |= MDIO_AN_CTRL1_RESTART;
391
392 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg);
393 }
394
395 static void
xgbe_an73_restart(struct xgbe_prv_data * pdata)396 xgbe_an73_restart(struct xgbe_prv_data *pdata)
397 {
398 xgbe_an73_enable_interrupts(pdata);
399 xgbe_an73_set(pdata, true, true);
400 }
401
402 static void
xgbe_an73_disable(struct xgbe_prv_data * pdata)403 xgbe_an73_disable(struct xgbe_prv_data *pdata)
404 {
405 xgbe_an73_set(pdata, false, false);
406 xgbe_an73_disable_interrupts(pdata);
407
408 pdata->an_start = 0;
409 }
410
411 static void
xgbe_an_restart(struct xgbe_prv_data * pdata)412 xgbe_an_restart(struct xgbe_prv_data *pdata)
413 {
414 if (pdata->phy_if.phy_impl.an_pre)
415 pdata->phy_if.phy_impl.an_pre(pdata);
416
417 switch (pdata->an_mode) {
418 case XGBE_AN_MODE_CL73:
419 case XGBE_AN_MODE_CL73_REDRV:
420 xgbe_an73_restart(pdata);
421 break;
422 case XGBE_AN_MODE_CL37:
423 case XGBE_AN_MODE_CL37_SGMII:
424 xgbe_an37_restart(pdata);
425 break;
426 default:
427 break;
428 }
429 }
430
431 static void
xgbe_an_disable(struct xgbe_prv_data * pdata)432 xgbe_an_disable(struct xgbe_prv_data *pdata)
433 {
434 if (pdata->phy_if.phy_impl.an_post)
435 pdata->phy_if.phy_impl.an_post(pdata);
436
437 switch (pdata->an_mode) {
438 case XGBE_AN_MODE_CL73:
439 case XGBE_AN_MODE_CL73_REDRV:
440 xgbe_an73_disable(pdata);
441 break;
442 case XGBE_AN_MODE_CL37:
443 case XGBE_AN_MODE_CL37_SGMII:
444 xgbe_an37_disable(pdata);
445 break;
446 default:
447 break;
448 }
449 }
450
451 static void
xgbe_an_disable_all(struct xgbe_prv_data * pdata)452 xgbe_an_disable_all(struct xgbe_prv_data *pdata)
453 {
454 xgbe_an73_disable(pdata);
455 xgbe_an37_disable(pdata);
456 }
457
458 static enum xgbe_an
xgbe_an73_tx_training(struct xgbe_prv_data * pdata,enum xgbe_rx * state)459 xgbe_an73_tx_training(struct xgbe_prv_data *pdata, enum xgbe_rx *state)
460 {
461 unsigned int ad_reg, lp_reg, reg;
462
463 *state = XGBE_RX_COMPLETE;
464
465 /* If we're not in KR mode then we're done */
466 if (!xgbe_in_kr_mode(pdata))
467 return (XGBE_AN_PAGE_RECEIVED);
468
469 /* Enable/Disable FEC */
470 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
471 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
472
473 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL);
474 reg &= ~(MDIO_PMA_10GBR_FECABLE_ABLE | MDIO_PMA_10GBR_FECABLE_ERRABLE);
475 if ((ad_reg & 0xc000) && (lp_reg & 0xc000))
476 reg |= pdata->fec_ability;
477
478 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL, reg);
479
480 /* Start KR training */
481 if (pdata->phy_if.phy_impl.kr_training_pre)
482 pdata->phy_if.phy_impl.kr_training_pre(pdata);
483
484 /* Start KR training */
485 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
486 reg |= XGBE_KR_TRAINING_ENABLE;
487 reg |= XGBE_KR_TRAINING_START;
488 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
489
490 if (pdata->phy_if.phy_impl.kr_training_post)
491 pdata->phy_if.phy_impl.kr_training_post(pdata);
492
493 return (XGBE_AN_PAGE_RECEIVED);
494 }
495
496 static enum xgbe_an
xgbe_an73_tx_xnp(struct xgbe_prv_data * pdata,enum xgbe_rx * state)497 xgbe_an73_tx_xnp(struct xgbe_prv_data *pdata, enum xgbe_rx *state)
498 {
499 uint16_t msg;
500
501 *state = XGBE_RX_XNP;
502
503 msg = XGBE_XNP_MCF_NULL_MESSAGE;
504 msg |= XGBE_XNP_MP_FORMATTED;
505
506 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 2, 0);
507 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 1, 0);
508 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP, msg);
509
510 return (XGBE_AN_PAGE_RECEIVED);
511 }
512
513 static enum xgbe_an
xgbe_an73_rx_bpa(struct xgbe_prv_data * pdata,enum xgbe_rx * state)514 xgbe_an73_rx_bpa(struct xgbe_prv_data *pdata, enum xgbe_rx *state)
515 {
516 unsigned int link_support;
517 unsigned int reg, ad_reg, lp_reg;
518
519 /* Read Base Ability register 2 first */
520 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
521
522 /* Check for a supported mode, otherwise restart in a different one */
523 link_support = xgbe_in_kr_mode(pdata) ? 0x80 : 0x20;
524 if (!(reg & link_support))
525 return (XGBE_AN_INCOMPAT_LINK);
526
527 /* Check Extended Next Page support */
528 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
529 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA);
530
531 return (((ad_reg & XGBE_XNP_NP_EXCHANGE) ||
532 (lp_reg & XGBE_XNP_NP_EXCHANGE))
533 ? xgbe_an73_tx_xnp(pdata, state)
534 : xgbe_an73_tx_training(pdata, state));
535 }
536
537 static enum xgbe_an
xgbe_an73_rx_xnp(struct xgbe_prv_data * pdata,enum xgbe_rx * state)538 xgbe_an73_rx_xnp(struct xgbe_prv_data *pdata, enum xgbe_rx *state)
539 {
540 unsigned int ad_reg, lp_reg;
541
542 /* Check Extended Next Page support */
543 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_XNP);
544 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPX);
545
546 return (((ad_reg & XGBE_XNP_NP_EXCHANGE) ||
547 (lp_reg & XGBE_XNP_NP_EXCHANGE))
548 ? xgbe_an73_tx_xnp(pdata, state)
549 : xgbe_an73_tx_training(pdata, state));
550 }
551
552 static enum xgbe_an
xgbe_an73_page_received(struct xgbe_prv_data * pdata)553 xgbe_an73_page_received(struct xgbe_prv_data *pdata)
554 {
555 enum xgbe_rx *state;
556 unsigned long an_timeout;
557 enum xgbe_an ret;
558
559 if (!pdata->an_start) {
560 pdata->an_start = ticks;
561 } else {
562 an_timeout = pdata->an_start +
563 ((uint64_t)XGBE_AN_MS_TIMEOUT * (uint64_t)hz) / 1000ull;
564 if ((int)(ticks - an_timeout) > 0) {
565 /* Auto-negotiation timed out, reset state */
566 pdata->kr_state = XGBE_RX_BPA;
567 pdata->kx_state = XGBE_RX_BPA;
568
569 pdata->an_start = ticks;
570
571 axgbe_printf(2, "CL73 AN timed out, resetting state\n");
572 }
573 }
574
575 state = xgbe_in_kr_mode(pdata) ? &pdata->kr_state : &pdata->kx_state;
576
577 switch (*state) {
578 case XGBE_RX_BPA:
579 ret = xgbe_an73_rx_bpa(pdata, state);
580 break;
581
582 case XGBE_RX_XNP:
583 ret = xgbe_an73_rx_xnp(pdata, state);
584 break;
585
586 default:
587 ret = XGBE_AN_ERROR;
588 }
589
590 return (ret);
591 }
592
593 static enum xgbe_an
xgbe_an73_incompat_link(struct xgbe_prv_data * pdata)594 xgbe_an73_incompat_link(struct xgbe_prv_data *pdata)
595 {
596 /* Be sure we aren't looping trying to negotiate */
597 if (xgbe_in_kr_mode(pdata)) {
598 pdata->kr_state = XGBE_RX_ERROR;
599
600 if (!(XGBE_ADV(&pdata->phy, 1000baseKX_Full)) &&
601 !(XGBE_ADV(&pdata->phy, 2500baseX_Full)))
602 return (XGBE_AN_NO_LINK);
603
604 if (pdata->kx_state != XGBE_RX_BPA)
605 return (XGBE_AN_NO_LINK);
606 } else {
607 pdata->kx_state = XGBE_RX_ERROR;
608
609 if (!(XGBE_ADV(&pdata->phy, 10000baseKR_Full)))
610 return (XGBE_AN_NO_LINK);
611
612 if (pdata->kr_state != XGBE_RX_BPA)
613 return (XGBE_AN_NO_LINK);
614 }
615
616 xgbe_an_disable(pdata);
617
618 xgbe_switch_mode(pdata);
619
620 xgbe_an_restart(pdata);
621
622 return (XGBE_AN_INCOMPAT_LINK);
623 }
624
625 static void
xgbe_an37_isr(struct xgbe_prv_data * pdata)626 xgbe_an37_isr(struct xgbe_prv_data *pdata)
627 {
628 unsigned int reg;
629
630 /* Disable AN interrupts */
631 xgbe_an37_disable_interrupts(pdata);
632
633 /* Save the interrupt(s) that fired */
634 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT);
635 pdata->an_int = reg & XGBE_AN_CL37_INT_MASK;
636 pdata->an_status = reg & ~XGBE_AN_CL37_INT_MASK;
637
638 if (pdata->an_int) {
639 /* Clear the interrupt(s) that fired and process them */
640 reg &= ~XGBE_AN_CL37_INT_MASK;
641 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg);
642
643 xgbe_an_state_machine(pdata);
644 } else {
645 /* Enable AN interrupts */
646 xgbe_an37_enable_interrupts(pdata);
647
648 /* Reissue interrupt if status is not clear */
649 if (pdata->vdata->irq_reissue_support)
650 XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);
651 }
652 }
653
654 static void
xgbe_an73_isr(struct xgbe_prv_data * pdata)655 xgbe_an73_isr(struct xgbe_prv_data *pdata)
656 {
657 /* Disable AN interrupts */
658 xgbe_an73_disable_interrupts(pdata);
659
660 /* Save the interrupt(s) that fired */
661 pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT);
662
663 if (pdata->an_int) {
664 /* Clear the interrupt(s) that fired and process them */
665 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, ~pdata->an_int);
666
667 xgbe_an_state_machine(pdata);
668 } else {
669 /* Enable AN interrupts */
670 xgbe_an73_enable_interrupts(pdata);
671
672 /* Reissue interrupt if status is not clear */
673 if (pdata->vdata->irq_reissue_support)
674 XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);
675 }
676 }
677
678 static void
xgbe_an_isr_task(unsigned long data)679 xgbe_an_isr_task(unsigned long data)
680 {
681 struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
682
683 axgbe_printf(2, "AN interrupt received\n");
684
685 switch (pdata->an_mode) {
686 case XGBE_AN_MODE_CL73:
687 case XGBE_AN_MODE_CL73_REDRV:
688 xgbe_an73_isr(pdata);
689 break;
690 case XGBE_AN_MODE_CL37:
691 case XGBE_AN_MODE_CL37_SGMII:
692 xgbe_an37_isr(pdata);
693 break;
694 default:
695 break;
696 }
697 }
698
699 static void
xgbe_an_combined_isr(struct xgbe_prv_data * pdata)700 xgbe_an_combined_isr(struct xgbe_prv_data *pdata)
701 {
702 xgbe_an_isr_task((unsigned long)pdata);
703 }
704
705 static const char *
xgbe_state_as_string(enum xgbe_an state)706 xgbe_state_as_string(enum xgbe_an state)
707 {
708 switch (state) {
709 case XGBE_AN_READY:
710 return ("Ready");
711 case XGBE_AN_PAGE_RECEIVED:
712 return ("Page-Received");
713 case XGBE_AN_INCOMPAT_LINK:
714 return ("Incompatible-Link");
715 case XGBE_AN_COMPLETE:
716 return ("Complete");
717 case XGBE_AN_NO_LINK:
718 return ("No-Link");
719 case XGBE_AN_ERROR:
720 return ("Error");
721 default:
722 return ("Undefined");
723 }
724 }
725
726 static void
xgbe_an37_state_machine(struct xgbe_prv_data * pdata)727 xgbe_an37_state_machine(struct xgbe_prv_data *pdata)
728 {
729 enum xgbe_an cur_state = pdata->an_state;
730
731 if (!pdata->an_int)
732 return;
733
734 if (pdata->an_int & XGBE_AN_CL37_INT_CMPLT) {
735 pdata->an_state = XGBE_AN_COMPLETE;
736 pdata->an_int &= ~XGBE_AN_CL37_INT_CMPLT;
737 }
738
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
785 static void
xgbe_an73_state_machine(struct xgbe_prv_data * pdata)786 xgbe_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
793 next_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
807 again:
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
875 out:
876 /* Enable AN interrupts on the way out */
877 xgbe_an73_enable_interrupts(pdata);
878 }
879
880 static void
xgbe_an_state_machine(struct xgbe_prv_data * pdata)881 xgbe_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
905 static void
xgbe_an37_init(struct xgbe_prv_data * pdata)906 xgbe_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
960 static void
xgbe_an73_init(struct xgbe_prv_data * pdata)961 xgbe_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
1016 static void
xgbe_an_init(struct xgbe_prv_data * pdata)1017 xgbe_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
1037 static const char *
xgbe_phy_fc_string(struct xgbe_prv_data * pdata)1038 xgbe_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
1050 static const char *
xgbe_phy_speed_string(int speed)1051 xgbe_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
1069 static void
xgbe_phy_print_status(struct xgbe_prv_data * pdata)1070 xgbe_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
1082 static void
xgbe_phy_adjust_link(struct xgbe_prv_data * pdata)1083 xgbe_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
1137 static bool
xgbe_phy_valid_speed(struct xgbe_prv_data * pdata,int speed)1138 xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed)
1139 {
1140 return (pdata->phy_if.phy_impl.valid_speed(pdata, speed));
1141 }
1142
1143 static int
xgbe_phy_config_fixed(struct xgbe_prv_data * pdata)1144 xgbe_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
1178 static int
__xgbe_phy_config_aneg(struct xgbe_prv_data * pdata,bool set_mode)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
1261 out:
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
1274 static int
xgbe_phy_config_aneg(struct xgbe_prv_data * pdata)1275 xgbe_phy_config_aneg(struct xgbe_prv_data *pdata)
1276 {
1277 return (__xgbe_phy_config_aneg(pdata, true));
1278 }
1279
1280 static int
xgbe_phy_reconfig_aneg(struct xgbe_prv_data * pdata)1281 xgbe_phy_reconfig_aneg(struct xgbe_prv_data *pdata)
1282 {
1283 return (__xgbe_phy_config_aneg(pdata, false));
1284 }
1285
1286 static bool
xgbe_phy_aneg_done(struct xgbe_prv_data * pdata)1287 xgbe_phy_aneg_done(struct xgbe_prv_data *pdata)
1288 {
1289 return (pdata->an_result == XGBE_AN_COMPLETE);
1290 }
1291
1292 static void
xgbe_check_link_timeout(struct xgbe_prv_data * pdata)1293 xgbe_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
1304 static enum xgbe_mode
xgbe_phy_status_aneg(struct xgbe_prv_data * pdata)1305 xgbe_phy_status_aneg(struct xgbe_prv_data *pdata)
1306 {
1307 return (pdata->phy_if.phy_impl.an_outcome(pdata));
1308 }
1309
1310 static void
xgbe_phy_status_result(struct xgbe_prv_data * pdata)1311 xgbe_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
1353 static void
xgbe_phy_status(struct xgbe_prv_data * pdata)1354 xgbe_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
1413 adjust_link:
1414 axgbe_printf(2, "%s: Link %d\n", __func__, pdata->phy.link);
1415 xgbe_phy_adjust_link(pdata);
1416 }
1417
1418 static void
xgbe_phy_stop(struct xgbe_prv_data * pdata)1419 xgbe_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
1439 static int
xgbe_phy_start(struct xgbe_prv_data * pdata)1440 xgbe_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
1500 err_stop:
1501 pdata->phy_if.phy_impl.stop(pdata);
1502
1503 return (ret);
1504 }
1505
1506 static int
xgbe_phy_reset(struct xgbe_prv_data * pdata)1507 xgbe_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
1526 static int
xgbe_phy_best_advertised_speed(struct xgbe_prv_data * pdata)1527 xgbe_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
1548 static void
xgbe_phy_exit(struct xgbe_prv_data * pdata)1549 xgbe_phy_exit(struct xgbe_prv_data *pdata)
1550 {
1551 pdata->phy_if.phy_impl.exit(pdata);
1552 }
1553
1554 static int
xgbe_phy_init(struct xgbe_prv_data * pdata)1555 xgbe_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
1616 void
xgbe_init_function_ptrs_phy(struct xgbe_phy_if * phy_if)1617 xgbe_init_function_ptrs_phy(struct xgbe_phy_if *phy_if)
1618 {
1619 phy_if->phy_init = xgbe_phy_init;
1620 phy_if->phy_exit = xgbe_phy_exit;
1621
1622 phy_if->phy_reset = xgbe_phy_reset;
1623 phy_if->phy_start = xgbe_phy_start;
1624 phy_if->phy_stop = xgbe_phy_stop;
1625
1626 phy_if->phy_status = xgbe_phy_status;
1627 phy_if->phy_config_aneg = xgbe_phy_config_aneg;
1628
1629 phy_if->phy_valid_speed = xgbe_phy_valid_speed;
1630
1631 phy_if->an_isr = xgbe_an_combined_isr;
1632 }
1633