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