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