]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - sys/dev/sfxge/common/efx_phy.c
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.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         __checkReturn   efx_rc_t
564 efx_phy_module_get_info(
565         __in                    efx_nic_t *enp,
566         __in                    uint8_t dev_addr,
567         __in                    uint8_t offset,
568         __in                    uint8_t len,
569         __out_bcount(len)       uint8_t *data)
570 {
571         efx_rc_t rc;
572
573         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
574         EFSYS_ASSERT(data != NULL);
575
576         if ((uint32_t)offset + len > 0xff) {
577                 rc = EINVAL;
578                 goto fail1;
579         }
580
581         if ((rc = efx_mcdi_phy_module_get_info(enp, dev_addr,
582             offset, len, data)) != 0)
583                 goto fail2;
584
585         return (0);
586
587 fail2:
588         EFSYS_PROBE(fail2);
589 fail1:
590         EFSYS_PROBE1(fail1, efx_rc_t, rc);
591
592         return (rc);
593 }
594
595 #if EFSYS_OPT_PHY_STATS
596
597 #if EFSYS_OPT_NAMES
598
599 /* START MKCONFIG GENERATED PhyStatNamesBlock d5f79b4bc2c050fe */
600 static const char       *__efx_phy_stat_name[] = {
601         "oui",
602         "pma_pmd_link_up",
603         "pma_pmd_rx_fault",
604         "pma_pmd_tx_fault",
605         "pma_pmd_rev_a",
606         "pma_pmd_rev_b",
607         "pma_pmd_rev_c",
608         "pma_pmd_rev_d",
609         "pcs_link_up",
610         "pcs_rx_fault",
611         "pcs_tx_fault",
612         "pcs_ber",
613         "pcs_block_errors",
614         "phy_xs_link_up",
615         "phy_xs_rx_fault",
616         "phy_xs_tx_fault",
617         "phy_xs_align",
618         "phy_xs_sync_a",
619         "phy_xs_sync_b",
620         "phy_xs_sync_c",
621         "phy_xs_sync_d",
622         "an_link_up",
623         "an_master",
624         "an_local_rx_ok",
625         "an_remote_rx_ok",
626         "cl22ext_link_up",
627         "snr_a",
628         "snr_b",
629         "snr_c",
630         "snr_d",
631         "pma_pmd_signal_a",
632         "pma_pmd_signal_b",
633         "pma_pmd_signal_c",
634         "pma_pmd_signal_d",
635         "an_complete",
636         "pma_pmd_rev_major",
637         "pma_pmd_rev_minor",
638         "pma_pmd_rev_micro",
639         "pcs_fw_version_0",
640         "pcs_fw_version_1",
641         "pcs_fw_version_2",
642         "pcs_fw_version_3",
643         "pcs_fw_build_yy",
644         "pcs_fw_build_mm",
645         "pcs_fw_build_dd",
646         "pcs_op_mode",
647 };
648
649 /* END MKCONFIG GENERATED PhyStatNamesBlock */
650
651                                         const char *
652 efx_phy_stat_name(
653         __in                            efx_nic_t *enp,
654         __in                            efx_phy_stat_t type)
655 {
656         _NOTE(ARGUNUSED(enp))
657         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
658         EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS);
659
660         return (__efx_phy_stat_name[type]);
661 }
662
663 #endif  /* EFSYS_OPT_NAMES */
664
665         __checkReturn                   efx_rc_t
666 efx_phy_stats_update(
667         __in                            efx_nic_t *enp,
668         __in                            efsys_mem_t *esmp,
669         __inout_ecount(EFX_PHY_NSTATS)  uint32_t *stat)
670 {
671         efx_port_t *epp = &(enp->en_port);
672         efx_phy_ops_t *epop = epp->ep_epop;
673
674         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
675         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
676
677         return (epop->epo_stats_update(enp, esmp, stat));
678 }
679
680 #endif  /* EFSYS_OPT_PHY_STATS */
681
682 #if EFSYS_OPT_PHY_PROPS
683
684 #if EFSYS_OPT_NAMES
685                 const char *
686 efx_phy_prop_name(
687         __in    efx_nic_t *enp,
688         __in    unsigned int id)
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_PROBE);
695
696         return (epop->epo_prop_name(enp, id));
697 }
698 #endif  /* EFSYS_OPT_NAMES */
699
700         __checkReturn   efx_rc_t
701 efx_phy_prop_get(
702         __in            efx_nic_t *enp,
703         __in            unsigned int id,
704         __in            uint32_t flags,
705         __out           uint32_t *valp)
706 {
707         efx_port_t *epp = &(enp->en_port);
708         efx_phy_ops_t *epop = epp->ep_epop;
709
710         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
711         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
712
713         return (epop->epo_prop_get(enp, id, flags, valp));
714 }
715
716         __checkReturn   efx_rc_t
717 efx_phy_prop_set(
718         __in            efx_nic_t *enp,
719         __in            unsigned int id,
720         __in            uint32_t val)
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         return (epop->epo_prop_set(enp, id, val));
729 }
730 #endif  /* EFSYS_OPT_PHY_STATS */
731
732 #if EFSYS_OPT_BIST
733
734         __checkReturn           efx_rc_t
735 efx_bist_enable_offline(
736         __in                    efx_nic_t *enp)
737 {
738         efx_port_t *epp = &(enp->en_port);
739         efx_phy_ops_t *epop = epp->ep_epop;
740         efx_rc_t rc;
741
742         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
743
744         if (epop->epo_bist_enable_offline == NULL) {
745                 rc = ENOTSUP;
746                 goto fail1;
747         }
748
749         if ((rc = epop->epo_bist_enable_offline(enp)) != 0)
750                 goto fail2;
751
752         return (0);
753
754 fail2:
755         EFSYS_PROBE(fail2);
756 fail1:
757         EFSYS_PROBE1(fail1, efx_rc_t, rc);
758
759         return (rc);
760
761 }
762
763         __checkReturn           efx_rc_t
764 efx_bist_start(
765         __in                    efx_nic_t *enp,
766         __in                    efx_bist_type_t type)
767 {
768         efx_port_t *epp = &(enp->en_port);
769         efx_phy_ops_t *epop = epp->ep_epop;
770         efx_rc_t rc;
771
772         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
773
774         EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
775         EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
776         EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_BIST_TYPE_UNKNOWN);
777
778         if (epop->epo_bist_start == NULL) {
779                 rc = ENOTSUP;
780                 goto fail1;
781         }
782
783         if ((rc = epop->epo_bist_start(enp, type)) != 0)
784                 goto fail2;
785
786         epp->ep_current_bist = type;
787
788         return (0);
789
790 fail2:
791         EFSYS_PROBE(fail2);
792 fail1:
793         EFSYS_PROBE1(fail1, efx_rc_t, rc);
794
795         return (rc);
796 }
797
798         __checkReturn           efx_rc_t
799 efx_bist_poll(
800         __in                    efx_nic_t *enp,
801         __in                    efx_bist_type_t type,
802         __out                   efx_bist_result_t *resultp,
803         __out_opt               uint32_t *value_maskp,
804         __out_ecount_opt(count) unsigned long *valuesp,
805         __in                    size_t count)
806 {
807         efx_port_t *epp = &(enp->en_port);
808         efx_phy_ops_t *epop = epp->ep_epop;
809         efx_rc_t rc;
810
811         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
812
813         EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
814         EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
815         EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
816
817         EFSYS_ASSERT(epop->epo_bist_poll != NULL);
818         if (epop->epo_bist_poll == NULL) {
819                 rc = ENOTSUP;
820                 goto fail1;
821         }
822
823         if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp,
824             valuesp, count)) != 0)
825                 goto fail2;
826
827         return (0);
828
829 fail2:
830         EFSYS_PROBE(fail2);
831 fail1:
832         EFSYS_PROBE1(fail1, efx_rc_t, rc);
833
834         return (rc);
835 }
836
837                         void
838 efx_bist_stop(
839         __in            efx_nic_t *enp,
840         __in            efx_bist_type_t type)
841 {
842         efx_port_t *epp = &(enp->en_port);
843         efx_phy_ops_t *epop = epp->ep_epop;
844
845         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
846
847         EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
848         EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
849         EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
850
851         EFSYS_ASSERT(epop->epo_bist_stop != NULL);
852
853         if (epop->epo_bist_stop != NULL)
854                 epop->epo_bist_stop(enp, type);
855
856         epp->ep_current_bist = EFX_BIST_TYPE_UNKNOWN;
857 }
858
859 #endif  /* EFSYS_OPT_BIST */
860                         void
861 efx_phy_unprobe(
862         __in    efx_nic_t *enp)
863 {
864         efx_port_t *epp = &(enp->en_port);
865
866         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
867
868         epp->ep_epop = NULL;
869
870         epp->ep_adv_cap_mask = 0;
871
872         epp->ep_port = 0;
873         epp->ep_phy_type = 0;
874 }