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