]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/sfxge/common/efx_phy.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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         int rc;
431
432         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
433         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
434
435         if ((mask & ~epp->ep_phy_cap_mask) != 0) {
436                 rc = ENOTSUP;
437                 goto fail1;
438         }
439
440         if (epp->ep_adv_cap_mask == mask)
441                 goto done;
442
443         epp->ep_adv_cap_mask = mask;
444
445         if ((rc = epop->epo_reconfigure(enp)) != 0)
446                 goto fail2;
447
448 done:
449         return (0);
450
451 fail2:
452         EFSYS_PROBE(fail2);
453 fail1:
454         EFSYS_PROBE1(fail1, int, rc);
455
456         return (rc);
457 }
458
459         void
460 efx_phy_lp_cap_get(
461         __in            efx_nic_t *enp,
462         __out           uint32_t *maskp)
463 {
464         efx_port_t *epp = &(enp->en_port);
465
466         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
467         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
468
469         *maskp = epp->ep_lp_cap_mask;
470 }
471
472         __checkReturn   int
473 efx_phy_oui_get(
474         __in            efx_nic_t *enp,
475         __out           uint32_t *ouip)
476 {
477         efx_port_t *epp = &(enp->en_port);
478         efx_phy_ops_t *epop = epp->ep_epop;
479
480         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
481         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
482
483         return (epop->epo_oui_get(enp, ouip));
484 }
485
486                         void
487 efx_phy_media_type_get(
488         __in            efx_nic_t *enp,
489         __out           efx_phy_media_type_t *typep)
490 {
491         efx_port_t *epp = &(enp->en_port);
492
493         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
494         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
495
496         if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID)
497                 *typep = epp->ep_module_type;
498         else
499                 *typep = epp->ep_fixed_port_type;
500 }
501
502 #if EFSYS_OPT_PHY_STATS
503
504 #if EFSYS_OPT_NAMES
505
506 /* START MKCONFIG GENERATED PhyStatNamesBlock 271268f3da0e804f */
507 static const char       __cs * __cs __efx_phy_stat_name[] = {
508         "oui",
509         "pma_pmd_link_up",
510         "pma_pmd_rx_fault",
511         "pma_pmd_tx_fault",
512         "pma_pmd_rev_a",
513         "pma_pmd_rev_b",
514         "pma_pmd_rev_c",
515         "pma_pmd_rev_d",
516         "pcs_link_up",
517         "pcs_rx_fault",
518         "pcs_tx_fault",
519         "pcs_ber",
520         "pcs_block_errors",
521         "phy_xs_link_up",
522         "phy_xs_rx_fault",
523         "phy_xs_tx_fault",
524         "phy_xs_align",
525         "phy_xs_sync_a",
526         "phy_xs_sync_b",
527         "phy_xs_sync_c",
528         "phy_xs_sync_d",
529         "an_link_up",
530         "an_master",
531         "an_local_rx_ok",
532         "an_remote_rx_ok",
533         "cl22ext_link_up",
534         "snr_a",
535         "snr_b",
536         "snr_c",
537         "snr_d",
538         "pma_pmd_signal_a",
539         "pma_pmd_signal_b",
540         "pma_pmd_signal_c",
541         "pma_pmd_signal_d",
542         "an_complete",
543         "pma_pmd_rev_major",
544         "pma_pmd_rev_minor",
545         "pma_pmd_rev_micro",
546         "pcs_fw_version_0",
547         "pcs_fw_version_1",
548         "pcs_fw_version_2",
549         "pcs_fw_version_3",
550         "pcs_fw_build_yy",
551         "pcs_fw_build_mm",
552         "pcs_fw_build_dd",
553         "pcs_op_mode",
554 };
555
556 /* END MKCONFIG GENERATED PhyStatNamesBlock */
557
558                                         const char __cs *
559 efx_phy_stat_name(
560         __in                            efx_nic_t *enp,
561         __in                            efx_phy_stat_t type)
562 {
563         _NOTE(ARGUNUSED(enp))
564         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
565         EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS);
566
567         return (__efx_phy_stat_name[type]);
568 }
569
570 #endif  /* EFSYS_OPT_NAMES */
571
572         __checkReturn                   int
573 efx_phy_stats_update(
574         __in                            efx_nic_t *enp,
575         __in                            efsys_mem_t *esmp,
576         __out_ecount(EFX_PHY_NSTATS)    uint32_t *stat)
577 {
578         efx_port_t *epp = &(enp->en_port);
579         efx_phy_ops_t *epop = epp->ep_epop;
580
581         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
582         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
583
584         return (epop->epo_stats_update(enp, esmp, stat));
585 }
586
587 #endif  /* EFSYS_OPT_PHY_STATS */
588
589 #if EFSYS_OPT_PHY_PROPS
590
591 #if EFSYS_OPT_NAMES
592                 const char __cs *
593 efx_phy_prop_name(
594         __in    efx_nic_t *enp,
595         __in    unsigned int id)
596 {
597         efx_port_t *epp = &(enp->en_port);
598         efx_phy_ops_t *epop = epp->ep_epop;
599
600         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
601         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
602
603         return (epop->epo_prop_name(enp, id));
604 }
605 #endif  /* EFSYS_OPT_NAMES */
606
607         __checkReturn   int
608 efx_phy_prop_get(
609         __in            efx_nic_t *enp,
610         __in            unsigned int id,
611         __in            uint32_t flags,
612         __out           uint32_t *valp)
613 {
614         efx_port_t *epp = &(enp->en_port);
615         efx_phy_ops_t *epop = epp->ep_epop;
616
617         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
618         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
619
620         return (epop->epo_prop_get(enp, id, flags, valp));
621 }
622
623         __checkReturn   int
624 efx_phy_prop_set(
625         __in            efx_nic_t *enp,
626         __in            unsigned int id,
627         __in            uint32_t val)
628 {
629         efx_port_t *epp = &(enp->en_port);
630         efx_phy_ops_t *epop = epp->ep_epop;
631
632         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
633         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
634
635         return (epop->epo_prop_set(enp, id, val));
636 }
637 #endif  /* EFSYS_OPT_PHY_STATS */
638
639 #if EFSYS_OPT_PHY_BIST
640
641         __checkReturn           int
642 efx_phy_bist_start(
643         __in                    efx_nic_t *enp,
644         __in                    efx_phy_bist_type_t type)
645 {
646         efx_port_t *epp = &(enp->en_port);
647         efx_phy_ops_t *epop = epp->ep_epop;
648         int rc;
649
650         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
651         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
652
653         EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
654         EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
655         EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_PHY_BIST_TYPE_UNKNOWN);
656
657         if (epop->epo_bist_start == NULL) {
658                 rc = ENOTSUP;
659                 goto fail1;
660         }
661
662         if ((rc = epop->epo_bist_start(enp, type)) != 0)
663                 goto fail2;
664
665         epp->ep_current_bist = type;
666
667         return (0);
668
669 fail2:
670         EFSYS_PROBE(fail2);
671 fail1:
672         EFSYS_PROBE1(fail1, int, rc);
673
674         return (rc);
675 }
676
677         __checkReturn           int
678 efx_phy_bist_poll(
679         __in                    efx_nic_t *enp,
680         __in                    efx_phy_bist_type_t type,
681         __out                   efx_phy_bist_result_t *resultp,
682         __out_opt               uint32_t *value_maskp,
683         __out_ecount_opt(count) unsigned long *valuesp,
684         __in                    size_t count)
685 {
686         efx_port_t *epp = &(enp->en_port);
687         efx_phy_ops_t *epop = epp->ep_epop;
688         int rc;
689
690         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
691         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
692
693         EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
694         EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
695         EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
696
697         EFSYS_ASSERT(epop->epo_bist_poll != NULL);
698         if (epop->epo_bist_poll == NULL) {
699                 rc = ENOTSUP;
700                 goto fail1;
701         }
702
703         if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp,
704             valuesp, count)) != 0)
705                 goto fail2;
706
707         return (0);
708
709 fail2:
710         EFSYS_PROBE(fail2);
711 fail1:
712         EFSYS_PROBE1(fail1, int, rc);
713
714         return (rc);
715 }
716
717                         void
718 efx_phy_bist_stop(
719         __in            efx_nic_t *enp,
720         __in            efx_phy_bist_type_t type)
721 {
722         efx_port_t *epp = &(enp->en_port);
723         efx_phy_ops_t *epop = epp->ep_epop;
724
725         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
726         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
727
728         EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
729         EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
730         EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
731
732         EFSYS_ASSERT(epop->epo_bist_stop != NULL);
733
734         if (epop->epo_bist_stop != NULL)
735                 epop->epo_bist_stop(enp, type);
736
737         epp->ep_current_bist = EFX_PHY_BIST_TYPE_UNKNOWN;
738 }
739
740 #endif  /* EFSYS_OPT_PHY_BIST */
741                         void
742 efx_phy_unprobe(
743         __in    efx_nic_t *enp)
744 {
745         efx_port_t *epp = &(enp->en_port);
746
747         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
748
749         epp->ep_epop = NULL;
750
751         epp->ep_adv_cap_mask = 0;
752
753         epp->ep_port = 0;
754         epp->ep_phy_type = 0;
755 }