1 /*-
2 * Copyright (c) 2007-2015 Solarflare Communications Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * The views and conclusions contained in the software and documentation are
27 * those of the authors and should not be interpreted as representing official
28 * policies, either expressed or implied, of the FreeBSD Project.
29 */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include "efsys.h"
35 #include "efx.h"
36 #include "efx_types.h"
37 #include "efx_regs.h"
38 #include "efx_impl.h"
39 #if EFSYS_OPT_FALCON
40 #include "falcon_nvram.h"
41 #endif
42
43 #if EFSYS_OPT_MAC_FALCON_XMAC
44 #include "falcon_xmac.h"
45 #endif
46
47 #if EFSYS_OPT_MAC_FALCON_GMAC
48 #include "falcon_gmac.h"
49 #endif
50
51 #if EFSYS_OPT_PHY_NULL
52 #include "nullphy.h"
53 #endif
54
55 #if EFSYS_OPT_PHY_QT2022C2
56 #include "qt2022c2.h"
57 #endif
58
59 #if EFSYS_OPT_PHY_SFX7101
60 #include "sfx7101.h"
61 #endif
62
63 #if EFSYS_OPT_PHY_TXC43128
64 #include "txc43128.h"
65 #endif
66
67 #if EFSYS_OPT_PHY_SFT9001
68 #include "sft9001.h"
69 #endif
70
71 #if EFSYS_OPT_PHY_QT2025C
72 #include "qt2025c.h"
73 #endif
74
75 #if EFSYS_OPT_PHY_NULL
76 static efx_phy_ops_t __efx_phy_null_ops = {
77 NULL, /* epo_power */
78 nullphy_reset, /* epo_reset */
79 nullphy_reconfigure, /* epo_reconfigure */
80 nullphy_verify, /* epo_verify */
81 NULL, /* epo_uplink_check */
82 nullphy_downlink_check, /* epo_downlink_check */
83 nullphy_oui_get, /* epo_oui_get */
84 #if EFSYS_OPT_PHY_STATS
85 nullphy_stats_update, /* epo_stats_update */
86 #endif /* EFSYS_OPT_PHY_STATS */
87 #if EFSYS_OPT_PHY_PROPS
88 #if EFSYS_OPT_NAMES
89 nullphy_prop_name, /* epo_prop_name */
90 #endif
91 nullphy_prop_get, /* epo_prop_get */
92 nullphy_prop_set, /* epo_prop_set */
93 #endif /* EFSYS_OPT_PHY_PROPS */
94 #if EFSYS_OPT_BIST
95 NULL, /* epo_bist_enable_offline */
96 NULL, /* epo_bist_start */
97 NULL, /* epo_bist_poll */
98 NULL, /* epo_bist_stop */
99 #endif /* EFSYS_OPT_BIST */
100 };
101 #endif /* EFSYS_OPT_PHY_NULL */
102
103 #if EFSYS_OPT_PHY_QT2022C2
104 static efx_phy_ops_t __efx_phy_qt2022c2_ops = {
105 NULL, /* epo_power */
106 qt2022c2_reset, /* epo_reset */
107 qt2022c2_reconfigure, /* epo_reconfigure */
108 qt2022c2_verify, /* epo_verify */
109 qt2022c2_uplink_check, /* epo_uplink_check */
110 qt2022c2_downlink_check, /* epo_downlink_check */
111 qt2022c2_oui_get, /* epo_oui_get */
112 #if EFSYS_OPT_PHY_STATS
113 qt2022c2_stats_update, /* epo_stats_update */
114 #endif /* EFSYS_OPT_PHY_STATS */
115 #if EFSYS_OPT_PHY_PROPS
116 #if EFSYS_OPT_NAMES
117 qt2022c2_prop_name, /* epo_prop_name */
118 #endif
119 qt2022c2_prop_get, /* epo_prop_get */
120 qt2022c2_prop_set, /* epo_prop_set */
121 #endif /* EFSYS_OPT_PHY_PROPS */
122 #if EFSYS_OPT_BIST
123 NULL, /* epo_bist_enable_offline */
124 NULL, /* epo_bist_start */
125 NULL, /* epo_bist_poll */
126 NULL, /* epo_bist_stop */
127 #endif /* EFSYS_OPT_BIST */
128 };
129 #endif /* EFSYS_OPT_PHY_QT2022C2 */
130
131 #if EFSYS_OPT_PHY_SFX7101
132 static efx_phy_ops_t __efx_phy_sfx7101_ops = {
133 sfx7101_power, /* epo_power */
134 sfx7101_reset, /* epo_reset */
135 sfx7101_reconfigure, /* epo_reconfigure */
136 sfx7101_verify, /* epo_verify */
137 sfx7101_uplink_check, /* epo_uplink_check */
138 sfx7101_downlink_check, /* epo_downlink_check */
139 sfx7101_oui_get, /* epo_oui_get */
140 #if EFSYS_OPT_PHY_STATS
141 sfx7101_stats_update, /* epo_stats_update */
142 #endif /* EFSYS_OPT_PHY_STATS */
143 #if EFSYS_OPT_PHY_PROPS
144 #if EFSYS_OPT_NAMES
145 sfx7101_prop_name, /* epo_prop_name */
146 #endif
147 sfx7101_prop_get, /* epo_prop_get */
148 sfx7101_prop_set, /* epo_prop_set */
149 #endif /* EFSYS_OPT_PHY_PROPS */
150 #if EFSYS_OPT_BIST
151 NULL, /* epo_bist_enable_offline */
152 NULL, /* epo_bist_start */
153 NULL, /* epo_bist_poll */
154 NULL, /* epo_bist_stop */
155 #endif /* EFSYS_OPT_BIST */
156 };
157 #endif /* EFSYS_OPT_PHY_SFX7101 */
158
159 #if EFSYS_OPT_PHY_TXC43128
160 static efx_phy_ops_t __efx_phy_txc43128_ops = {
161 NULL, /* epo_power */
162 txc43128_reset, /* epo_reset */
163 txc43128_reconfigure, /* epo_reconfigure */
164 txc43128_verify, /* epo_verify */
165 txc43128_uplink_check, /* epo_uplink_check */
166 txc43128_downlink_check, /* epo_downlink_check */
167 txc43128_oui_get, /* epo_oui_get */
168 #if EFSYS_OPT_PHY_STATS
169 txc43128_stats_update, /* epo_stats_update */
170 #endif /* EFSYS_OPT_PHY_STATS */
171 #if EFSYS_OPT_PHY_PROPS
172 #if EFSYS_OPT_NAMES
173 txc43128_prop_name, /* epo_prop_name */
174 #endif
175 txc43128_prop_get, /* epo_prop_get */
176 txc43128_prop_set, /* epo_prop_set */
177 #endif /* EFSYS_OPT_PHY_PROPS */
178 #if EFSYS_OPT_BIST
179 NULL, /* epo_bist_enable_offline */
180 NULL, /* epo_bist_start */
181 NULL, /* epo_bist_poll */
182 NULL, /* epo_bist_stop */
183 #endif /* EFSYS_OPT_BIST */
184 };
185 #endif /* EFSYS_OPT_PHY_TXC43128 */
186
187 #if EFSYS_OPT_PHY_SFT9001
188 static efx_phy_ops_t __efx_phy_sft9001_ops = {
189 NULL, /* epo_power */
190 sft9001_reset, /* epo_reset */
191 sft9001_reconfigure, /* epo_reconfigure */
192 sft9001_verify, /* epo_verify */
193 sft9001_uplink_check, /* epo_uplink_check */
194 sft9001_downlink_check, /* epo_downlink_check */
195 sft9001_oui_get, /* epo_oui_get */
196 #if EFSYS_OPT_PHY_STATS
197 sft9001_stats_update, /* epo_stats_update */
198 #endif /* EFSYS_OPT_PHY_STATS */
199 #if EFSYS_OPT_PHY_PROPS
200 #if EFSYS_OPT_NAMES
201 sft9001_prop_name, /* epo_prop_name */
202 #endif
203 sft9001_prop_get, /* epo_prop_get */
204 sft9001_prop_set, /* epo_prop_set */
205 #endif /* EFSYS_OPT_PHY_PROPS */
206 #if EFSYS_OPT_BIST
207 NULL, /* epo_bist_enable_offline */
208 sft9001_bist_start, /* epo_bist_start */
209 sft9001_bist_poll, /* epo_bist_poll */
210 sft9001_bist_stop, /* epo_bist_stop */
211 #endif /* EFSYS_OPT_BIST */
212 };
213 #endif /* EFSYS_OPT_PHY_SFT9001 */
214
215 #if EFSYS_OPT_PHY_QT2025C
216 static efx_phy_ops_t __efx_phy_qt2025c_ops = {
217 NULL, /* epo_power */
218 qt2025c_reset, /* epo_reset */
219 qt2025c_reconfigure, /* epo_reconfigure */
220 qt2025c_verify, /* epo_verify */
221 qt2025c_uplink_check, /* epo_uplink_check */
222 qt2025c_downlink_check, /* epo_downlink_check */
223 qt2025c_oui_get, /* epo_oui_get */
224 #if EFSYS_OPT_PHY_STATS
225 qt2025c_stats_update, /* epo_stats_update */
226 #endif /* EFSYS_OPT_PHY_STATS */
227 #if EFSYS_OPT_PHY_PROPS
228 #if EFSYS_OPT_NAMES
229 qt2025c_prop_name, /* epo_prop_name */
230 #endif
231 qt2025c_prop_get, /* epo_prop_get */
232 qt2025c_prop_set, /* epo_prop_set */
233 #endif /* EFSYS_OPT_PHY_PROPS */
234 #if EFSYS_OPT_BIST
235 NULL, /* epo_bist_enable_offline */
236 NULL, /* epo_bist_start */
237 NULL, /* epo_bist_poll */
238 NULL, /* epo_bist_stop */
239 #endif /* EFSYS_OPT_BIST */
240 };
241 #endif /* EFSYS_OPT_PHY_QT2025C */
242
243 #if EFSYS_OPT_SIENA
244 static efx_phy_ops_t __efx_phy_siena_ops = {
245 siena_phy_power, /* epo_power */
246 NULL, /* epo_reset */
247 siena_phy_reconfigure, /* epo_reconfigure */
248 siena_phy_verify, /* epo_verify */
249 NULL, /* epo_uplink_check */
250 NULL, /* epo_downlink_check */
251 siena_phy_oui_get, /* epo_oui_get */
252 #if EFSYS_OPT_PHY_STATS
253 siena_phy_stats_update, /* epo_stats_update */
254 #endif /* EFSYS_OPT_PHY_STATS */
255 #if EFSYS_OPT_PHY_PROPS
256 #if EFSYS_OPT_NAMES
257 siena_phy_prop_name, /* epo_prop_name */
258 #endif
259 siena_phy_prop_get, /* epo_prop_get */
260 siena_phy_prop_set, /* epo_prop_set */
261 #endif /* EFSYS_OPT_PHY_PROPS */
262 #if EFSYS_OPT_BIST
263 NULL, /* epo_bist_enable_offline */
264 siena_phy_bist_start, /* epo_bist_start */
265 siena_phy_bist_poll, /* epo_bist_poll */
266 siena_phy_bist_stop, /* epo_bist_stop */
267 #endif /* EFSYS_OPT_BIST */
268 };
269 #endif /* EFSYS_OPT_SIENA */
270
271 #if EFSYS_OPT_HUNTINGTON
272 static efx_phy_ops_t __efx_phy_hunt_ops = {
273 hunt_phy_power, /* epo_power */
274 NULL, /* epo_reset */
275 hunt_phy_reconfigure, /* epo_reconfigure */
276 hunt_phy_verify, /* epo_verify */
277 NULL, /* epo_uplink_check */
278 NULL, /* epo_downlink_check */
279 hunt_phy_oui_get, /* epo_oui_get */
280 #if EFSYS_OPT_PHY_STATS
281 hunt_phy_stats_update, /* epo_stats_update */
282 #endif /* EFSYS_OPT_PHY_STATS */
283 #if EFSYS_OPT_PHY_PROPS
284 #if EFSYS_OPT_NAMES
285 hunt_phy_prop_name, /* epo_prop_name */
286 #endif
287 hunt_phy_prop_get, /* epo_prop_get */
288 hunt_phy_prop_set, /* epo_prop_set */
289 #endif /* EFSYS_OPT_PHY_PROPS */
290 #if EFSYS_OPT_BIST
291 hunt_bist_enable_offline, /* epo_bist_enable_offline */
292 hunt_bist_start, /* epo_bist_start */
293 hunt_bist_poll, /* epo_bist_poll */
294 hunt_bist_stop, /* epo_bist_stop */
295 #endif /* EFSYS_OPT_BIST */
296 };
297 #endif /* EFSYS_OPT_HUNTINGTON */
298
299 __checkReturn efx_rc_t
efx_phy_probe(__in efx_nic_t * enp)300 efx_phy_probe(
301 __in efx_nic_t *enp)
302 {
303 efx_port_t *epp = &(enp->en_port);
304 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
305 efx_phy_ops_t *epop;
306 efx_rc_t rc;
307
308 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
309
310 epp->ep_port = encp->enc_port;
311 epp->ep_phy_type = encp->enc_phy_type;
312
313 /* Hook in operations structure */
314 switch (enp->en_family) {
315 #if EFSYS_OPT_FALCON
316 case EFX_FAMILY_FALCON:
317 switch (epp->ep_phy_type) {
318 #if EFSYS_OPT_PHY_NULL
319 case PHY_TYPE_NONE_DECODE:
320 epop = (efx_phy_ops_t *)&__efx_phy_null_ops;
321 break;
322 #endif
323 #if EFSYS_OPT_PHY_QT2022C2
324 case PHY_TYPE_QT2022C2_DECODE:
325 epop = (efx_phy_ops_t *)&__efx_phy_qt2022c2_ops;
326 break;
327 #endif
328 #if EFSYS_OPT_PHY_SFX7101
329 case PHY_TYPE_SFX7101_DECODE:
330 epop = (efx_phy_ops_t *)&__efx_phy_sfx7101_ops;
331 break;
332 #endif
333 #if EFSYS_OPT_PHY_TXC43128
334 case PHY_TYPE_TXC43128_DECODE:
335 epop = (efx_phy_ops_t *)&__efx_phy_txc43128_ops;
336 break;
337 #endif
338 #if EFSYS_OPT_PHY_SFT9001
339 case PHY_TYPE_SFT9001A_DECODE:
340 case PHY_TYPE_SFT9001B_DECODE:
341 epop = (efx_phy_ops_t *)&__efx_phy_sft9001_ops;
342 break;
343 #endif
344 #if EFSYS_OPT_PHY_QT2025C
345 case EFX_PHY_QT2025C:
346 epop = (efx_phy_ops_t *)&__efx_phy_qt2025c_ops;
347 break;
348 #endif
349 default:
350 rc = ENOTSUP;
351 goto fail1;
352 }
353 break;
354 #endif /* EFSYS_OPT_FALCON */
355 #if EFSYS_OPT_SIENA
356 case EFX_FAMILY_SIENA:
357 epop = (efx_phy_ops_t *)&__efx_phy_siena_ops;
358 break;
359 #endif /* EFSYS_OPT_SIENA */
360 #if EFSYS_OPT_HUNTINGTON
361 case EFX_FAMILY_HUNTINGTON:
362 epop = (efx_phy_ops_t *)&__efx_phy_hunt_ops;
363 break;
364 #endif /* EFSYS_OPT_HUNTINGTON */
365 default:
366 rc = ENOTSUP;
367 goto fail1;
368 }
369
370 epp->ep_epop = epop;
371
372 return (0);
373
374 fail1:
375 EFSYS_PROBE1(fail1, efx_rc_t, rc);
376
377 epp->ep_port = 0;
378 epp->ep_phy_type = 0;
379
380 return (rc);
381 }
382
383 __checkReturn efx_rc_t
efx_phy_verify(__in efx_nic_t * enp)384 efx_phy_verify(
385 __in efx_nic_t *enp)
386 {
387 efx_port_t *epp = &(enp->en_port);
388 efx_phy_ops_t *epop = epp->ep_epop;
389
390 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
391 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
392
393 return (epop->epo_verify(enp));
394 }
395
396 #if EFSYS_OPT_PHY_LED_CONTROL
397
398 __checkReturn efx_rc_t
efx_phy_led_set(__in efx_nic_t * enp,__in efx_phy_led_mode_t mode)399 efx_phy_led_set(
400 __in efx_nic_t *enp,
401 __in efx_phy_led_mode_t mode)
402 {
403 efx_nic_cfg_t *encp = (&enp->en_nic_cfg);
404 efx_port_t *epp = &(enp->en_port);
405 efx_phy_ops_t *epop = epp->ep_epop;
406 uint32_t mask;
407 efx_rc_t rc;
408
409 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
410 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
411
412 if (epp->ep_phy_led_mode == mode)
413 goto done;
414
415 mask = (1 << EFX_PHY_LED_DEFAULT);
416 mask |= encp->enc_led_mask;
417
418 if (!((1 << mode) & mask)) {
419 rc = ENOTSUP;
420 goto fail1;
421 }
422
423 EFSYS_ASSERT3U(mode, <, EFX_PHY_LED_NMODES);
424 epp->ep_phy_led_mode = mode;
425
426 if ((rc = epop->epo_reconfigure(enp)) != 0)
427 goto fail2;
428
429 done:
430 return (0);
431
432 fail2:
433 EFSYS_PROBE(fail2);
434 fail1:
435 EFSYS_PROBE1(fail1, efx_rc_t, rc);
436
437 return (rc);
438 }
439 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
440
441 void
efx_phy_adv_cap_get(__in efx_nic_t * enp,__in uint32_t flag,__out uint32_t * maskp)442 efx_phy_adv_cap_get(
443 __in efx_nic_t *enp,
444 __in uint32_t flag,
445 __out uint32_t *maskp)
446 {
447 efx_port_t *epp = &(enp->en_port);
448
449 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
450 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
451
452 switch (flag) {
453 case EFX_PHY_CAP_CURRENT:
454 *maskp = epp->ep_adv_cap_mask;
455 break;
456 case EFX_PHY_CAP_DEFAULT:
457 *maskp = epp->ep_default_adv_cap_mask;
458 break;
459 case EFX_PHY_CAP_PERM:
460 *maskp = epp->ep_phy_cap_mask;
461 break;
462 default:
463 EFSYS_ASSERT(B_FALSE);
464 break;
465 }
466 }
467
468 __checkReturn efx_rc_t
efx_phy_adv_cap_set(__in efx_nic_t * enp,__in uint32_t mask)469 efx_phy_adv_cap_set(
470 __in efx_nic_t *enp,
471 __in uint32_t mask)
472 {
473 efx_port_t *epp = &(enp->en_port);
474 efx_phy_ops_t *epop = epp->ep_epop;
475 uint32_t old_mask;
476 efx_rc_t rc;
477
478 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
479 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
480
481 if ((mask & ~epp->ep_phy_cap_mask) != 0) {
482 rc = ENOTSUP;
483 goto fail1;
484 }
485
486 if (epp->ep_adv_cap_mask == mask)
487 goto done;
488
489 old_mask = epp->ep_adv_cap_mask;
490 epp->ep_adv_cap_mask = mask;
491
492 if ((rc = epop->epo_reconfigure(enp)) != 0)
493 goto fail2;
494
495 done:
496 return (0);
497
498 fail2:
499 EFSYS_PROBE(fail2);
500
501 epp->ep_adv_cap_mask = old_mask;
502 /* Reconfigure for robustness */
503 if (epop->epo_reconfigure(enp) != 0) {
504 /*
505 * We may have an inconsistent view of our advertised speed
506 * capabilities.
507 */
508 EFSYS_ASSERT(0);
509 }
510
511 fail1:
512 EFSYS_PROBE1(fail1, efx_rc_t, rc);
513
514 return (rc);
515 }
516
517 void
efx_phy_lp_cap_get(__in efx_nic_t * enp,__out uint32_t * maskp)518 efx_phy_lp_cap_get(
519 __in efx_nic_t *enp,
520 __out uint32_t *maskp)
521 {
522 efx_port_t *epp = &(enp->en_port);
523
524 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
525 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
526
527 *maskp = epp->ep_lp_cap_mask;
528 }
529
530 __checkReturn efx_rc_t
efx_phy_oui_get(__in efx_nic_t * enp,__out uint32_t * ouip)531 efx_phy_oui_get(
532 __in efx_nic_t *enp,
533 __out uint32_t *ouip)
534 {
535 efx_port_t *epp = &(enp->en_port);
536 efx_phy_ops_t *epop = epp->ep_epop;
537
538 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
539 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
540
541 return (epop->epo_oui_get(enp, ouip));
542 }
543
544 void
efx_phy_media_type_get(__in efx_nic_t * enp,__out efx_phy_media_type_t * typep)545 efx_phy_media_type_get(
546 __in efx_nic_t *enp,
547 __out efx_phy_media_type_t *typep)
548 {
549 efx_port_t *epp = &(enp->en_port);
550
551 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
552 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
553
554 if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID)
555 *typep = epp->ep_module_type;
556 else
557 *typep = epp->ep_fixed_port_type;
558 }
559
560 #if EFSYS_OPT_PHY_STATS
561
562 #if EFSYS_OPT_NAMES
563
564 /* START MKCONFIG GENERATED PhyStatNamesBlock d5f79b4bc2c050fe */
565 static const char *__efx_phy_stat_name[] = {
566 "oui",
567 "pma_pmd_link_up",
568 "pma_pmd_rx_fault",
569 "pma_pmd_tx_fault",
570 "pma_pmd_rev_a",
571 "pma_pmd_rev_b",
572 "pma_pmd_rev_c",
573 "pma_pmd_rev_d",
574 "pcs_link_up",
575 "pcs_rx_fault",
576 "pcs_tx_fault",
577 "pcs_ber",
578 "pcs_block_errors",
579 "phy_xs_link_up",
580 "phy_xs_rx_fault",
581 "phy_xs_tx_fault",
582 "phy_xs_align",
583 "phy_xs_sync_a",
584 "phy_xs_sync_b",
585 "phy_xs_sync_c",
586 "phy_xs_sync_d",
587 "an_link_up",
588 "an_master",
589 "an_local_rx_ok",
590 "an_remote_rx_ok",
591 "cl22ext_link_up",
592 "snr_a",
593 "snr_b",
594 "snr_c",
595 "snr_d",
596 "pma_pmd_signal_a",
597 "pma_pmd_signal_b",
598 "pma_pmd_signal_c",
599 "pma_pmd_signal_d",
600 "an_complete",
601 "pma_pmd_rev_major",
602 "pma_pmd_rev_minor",
603 "pma_pmd_rev_micro",
604 "pcs_fw_version_0",
605 "pcs_fw_version_1",
606 "pcs_fw_version_2",
607 "pcs_fw_version_3",
608 "pcs_fw_build_yy",
609 "pcs_fw_build_mm",
610 "pcs_fw_build_dd",
611 "pcs_op_mode",
612 };
613
614 /* END MKCONFIG GENERATED PhyStatNamesBlock */
615
616 const char *
efx_phy_stat_name(__in efx_nic_t * enp,__in efx_phy_stat_t type)617 efx_phy_stat_name(
618 __in efx_nic_t *enp,
619 __in efx_phy_stat_t type)
620 {
621 _NOTE(ARGUNUSED(enp))
622 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
623 EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS);
624
625 return (__efx_phy_stat_name[type]);
626 }
627
628 #endif /* EFSYS_OPT_NAMES */
629
630 __checkReturn efx_rc_t
efx_phy_stats_update(__in efx_nic_t * enp,__in efsys_mem_t * esmp,__inout_ecount (EFX_PHY_NSTATS)uint32_t * stat)631 efx_phy_stats_update(
632 __in efx_nic_t *enp,
633 __in efsys_mem_t *esmp,
634 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat)
635 {
636 efx_port_t *epp = &(enp->en_port);
637 efx_phy_ops_t *epop = epp->ep_epop;
638
639 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
640 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
641
642 return (epop->epo_stats_update(enp, esmp, stat));
643 }
644
645 #endif /* EFSYS_OPT_PHY_STATS */
646
647 #if EFSYS_OPT_PHY_PROPS
648
649 #if EFSYS_OPT_NAMES
650 const char *
efx_phy_prop_name(__in efx_nic_t * enp,__in unsigned int id)651 efx_phy_prop_name(
652 __in efx_nic_t *enp,
653 __in unsigned int id)
654 {
655 efx_port_t *epp = &(enp->en_port);
656 efx_phy_ops_t *epop = epp->ep_epop;
657
658 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
659 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
660
661 return (epop->epo_prop_name(enp, id));
662 }
663 #endif /* EFSYS_OPT_NAMES */
664
665 __checkReturn efx_rc_t
efx_phy_prop_get(__in efx_nic_t * enp,__in unsigned int id,__in uint32_t flags,__out uint32_t * valp)666 efx_phy_prop_get(
667 __in efx_nic_t *enp,
668 __in unsigned int id,
669 __in uint32_t flags,
670 __out uint32_t *valp)
671 {
672 efx_port_t *epp = &(enp->en_port);
673 efx_phy_ops_t *epop = epp->ep_epop;
674
675 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
676 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
677
678 return (epop->epo_prop_get(enp, id, flags, valp));
679 }
680
681 __checkReturn efx_rc_t
efx_phy_prop_set(__in efx_nic_t * enp,__in unsigned int id,__in uint32_t val)682 efx_phy_prop_set(
683 __in efx_nic_t *enp,
684 __in unsigned int id,
685 __in uint32_t val)
686 {
687 efx_port_t *epp = &(enp->en_port);
688 efx_phy_ops_t *epop = epp->ep_epop;
689
690 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
691 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
692
693 return (epop->epo_prop_set(enp, id, val));
694 }
695 #endif /* EFSYS_OPT_PHY_STATS */
696
697 #if EFSYS_OPT_BIST
698
699 __checkReturn efx_rc_t
efx_bist_enable_offline(__in efx_nic_t * enp)700 efx_bist_enable_offline(
701 __in efx_nic_t *enp)
702 {
703 efx_port_t *epp = &(enp->en_port);
704 efx_phy_ops_t *epop = epp->ep_epop;
705 efx_rc_t rc;
706
707 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
708
709 if (epop->epo_bist_enable_offline == NULL) {
710 rc = ENOTSUP;
711 goto fail1;
712 }
713
714 if ((rc = epop->epo_bist_enable_offline(enp)) != 0)
715 goto fail2;
716
717 return (0);
718
719 fail2:
720 EFSYS_PROBE(fail2);
721 fail1:
722 EFSYS_PROBE1(fail1, efx_rc_t, rc);
723
724 return (rc);
725
726 }
727
728 __checkReturn efx_rc_t
efx_bist_start(__in efx_nic_t * enp,__in efx_bist_type_t type)729 efx_bist_start(
730 __in efx_nic_t *enp,
731 __in efx_bist_type_t type)
732 {
733 efx_port_t *epp = &(enp->en_port);
734 efx_phy_ops_t *epop = epp->ep_epop;
735 efx_rc_t rc;
736
737 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
738
739 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
740 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
741 EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_BIST_TYPE_UNKNOWN);
742
743 if (epop->epo_bist_start == NULL) {
744 rc = ENOTSUP;
745 goto fail1;
746 }
747
748 if ((rc = epop->epo_bist_start(enp, type)) != 0)
749 goto fail2;
750
751 epp->ep_current_bist = type;
752
753 return (0);
754
755 fail2:
756 EFSYS_PROBE(fail2);
757 fail1:
758 EFSYS_PROBE1(fail1, efx_rc_t, rc);
759
760 return (rc);
761 }
762
763 __checkReturn efx_rc_t
efx_bist_poll(__in efx_nic_t * enp,__in efx_bist_type_t type,__out efx_bist_result_t * resultp,__out_opt uint32_t * value_maskp,__out_ecount_opt (count)unsigned long * valuesp,__in size_t count)764 efx_bist_poll(
765 __in efx_nic_t *enp,
766 __in efx_bist_type_t type,
767 __out efx_bist_result_t *resultp,
768 __out_opt uint32_t *value_maskp,
769 __out_ecount_opt(count) unsigned long *valuesp,
770 __in size_t count)
771 {
772 efx_port_t *epp = &(enp->en_port);
773 efx_phy_ops_t *epop = epp->ep_epop;
774 efx_rc_t rc;
775
776 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
777
778 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
779 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
780 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
781
782 EFSYS_ASSERT(epop->epo_bist_poll != NULL);
783 if (epop->epo_bist_poll == NULL) {
784 rc = ENOTSUP;
785 goto fail1;
786 }
787
788 if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp,
789 valuesp, count)) != 0)
790 goto fail2;
791
792 return (0);
793
794 fail2:
795 EFSYS_PROBE(fail2);
796 fail1:
797 EFSYS_PROBE1(fail1, efx_rc_t, rc);
798
799 return (rc);
800 }
801
802 void
efx_bist_stop(__in efx_nic_t * enp,__in efx_bist_type_t type)803 efx_bist_stop(
804 __in efx_nic_t *enp,
805 __in efx_bist_type_t type)
806 {
807 efx_port_t *epp = &(enp->en_port);
808 efx_phy_ops_t *epop = epp->ep_epop;
809
810 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
811
812 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
813 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
814 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
815
816 EFSYS_ASSERT(epop->epo_bist_stop != NULL);
817
818 if (epop->epo_bist_stop != NULL)
819 epop->epo_bist_stop(enp, type);
820
821 epp->ep_current_bist = EFX_BIST_TYPE_UNKNOWN;
822 }
823
824 #endif /* EFSYS_OPT_BIST */
825 void
efx_phy_unprobe(__in efx_nic_t * enp)826 efx_phy_unprobe(
827 __in efx_nic_t *enp)
828 {
829 efx_port_t *epp = &(enp->en_port);
830
831 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
832
833 epp->ep_epop = NULL;
834
835 epp->ep_adv_cap_mask = 0;
836
837 epp->ep_port = 0;
838 epp->ep_phy_type = 0;
839 }
840