]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - sys/dev/sfxge/common/efx_nic.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_nic.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
37         __checkReturn   efx_rc_t
38 efx_family(
39         __in            uint16_t venid,
40         __in            uint16_t devid,
41         __out           efx_family_t *efp)
42 {
43         if (venid == EFX_PCI_VENID_SFC) {
44                 switch (devid) {
45 #if EFSYS_OPT_FALCON
46                 case EFX_PCI_DEVID_FALCON:
47                         *efp = EFX_FAMILY_FALCON;
48                         return (0);
49 #endif /* EFSYS_OPT_FALCON */
50
51 #if EFSYS_OPT_SIENA
52                 case EFX_PCI_DEVID_SIENA_F1_UNINIT:
53                         /*
54                          * Hardware default for PF0 of uninitialised Siena.
55                          * manftest must be able to cope with this device id.
56                          */
57                         *efp = EFX_FAMILY_SIENA;
58                         return (0);
59
60                 case EFX_PCI_DEVID_BETHPAGE:
61                 case EFX_PCI_DEVID_SIENA:
62                         *efp = EFX_FAMILY_SIENA;
63                         return (0);
64 #endif /* EFSYS_OPT_SIENA */
65
66 #if EFSYS_OPT_HUNTINGTON
67                 case EFX_PCI_DEVID_HUNTINGTON_PF_UNINIT:
68                         /*
69                          * Hardware default for PF0 of uninitialised Huntington.
70                          * manftest must be able to cope with this device id.
71                          */
72                         *efp = EFX_FAMILY_HUNTINGTON;
73                         return (0);
74
75                 case EFX_PCI_DEVID_FARMINGDALE:
76                 case EFX_PCI_DEVID_GREENPORT:
77                         *efp = EFX_FAMILY_HUNTINGTON;
78                         return (0);
79
80                 case EFX_PCI_DEVID_FARMINGDALE_VF:
81                 case EFX_PCI_DEVID_GREENPORT_VF:
82                         *efp = EFX_FAMILY_HUNTINGTON;
83                         return (0);
84 #endif /* EFSYS_OPT_HUNTINGTON */
85
86 #if EFSYS_OPT_MEDFORD
87                 case EFX_PCI_DEVID_MEDFORD_PF_UNINIT:
88                         /*
89                          * Hardware default for PF0 of uninitialised Medford.
90                          * manftest must be able to cope with this device id.
91                          */
92                         *efp = EFX_FAMILY_MEDFORD;
93                         return (0);
94
95                 case EFX_PCI_DEVID_MEDFORD:
96                         *efp = EFX_FAMILY_MEDFORD;
97                         return (0);
98
99                 case EFX_PCI_DEVID_MEDFORD_VF:
100                         *efp = EFX_FAMILY_MEDFORD;
101                         return (0);
102 #endif /* EFSYS_OPT_MEDFORD */
103
104                 default:
105                         break;
106                 }
107         }
108
109         *efp = EFX_FAMILY_INVALID;
110         return (ENOTSUP);
111 }
112
113 /*
114  * To support clients which aren't provided with any PCI context infer
115  * the hardware family by inspecting the hardware. Obviously the caller
116  * must be damn sure they're really talking to a supported device.
117  */
118         __checkReturn   efx_rc_t
119 efx_infer_family(
120         __in            efsys_bar_t *esbp,
121         __out           efx_family_t *efp)
122 {
123         efx_family_t family;
124         efx_oword_t oword;
125         unsigned int portnum;
126         efx_rc_t rc;
127
128         EFSYS_BAR_READO(esbp, FR_AZ_CS_DEBUG_REG_OFST, &oword, B_TRUE);
129         portnum = EFX_OWORD_FIELD(oword, FRF_CZ_CS_PORT_NUM);
130         if ((portnum == 1) || (portnum == 2)) {
131 #if EFSYS_OPT_SIENA
132                 family = EFX_FAMILY_SIENA;
133                 goto out;
134 #endif
135         } else if (portnum == 0) {
136                 efx_dword_t dword;
137                 uint32_t hw_rev;
138
139                 EFSYS_BAR_READD(esbp, ER_DZ_BIU_HW_REV_ID_REG_OFST, &dword,
140                     B_TRUE);
141                 hw_rev = EFX_DWORD_FIELD(dword, ERF_DZ_HW_REV_ID);
142                 if (hw_rev == ER_DZ_BIU_HW_REV_ID_REG_RESET) {
143 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
144                         /*
145                          * BIU_HW_REV_ID is the same for Huntington and Medford.
146                          * Assume Huntington, as Medford is very similar.
147                          */
148                         family = EFX_FAMILY_HUNTINGTON;
149                         goto out;
150 #endif
151                 } else {
152 #if EFSYS_OPT_FALCON
153                         family = EFX_FAMILY_FALCON;
154                         goto out;
155 #endif
156                 }
157         }
158         rc = ENOTSUP;
159         goto fail1;
160
161 out:
162         if (efp != NULL)
163                 *efp = family;
164         return (0);
165
166 fail1:
167         EFSYS_PROBE1(fail1, efx_rc_t, rc);
168
169         return (rc);
170 }
171
172 #define EFX_BIU_MAGIC0  0x01234567
173 #define EFX_BIU_MAGIC1  0xfedcba98
174
175         __checkReturn   efx_rc_t
176 efx_nic_biu_test(
177         __in            efx_nic_t *enp)
178 {
179         efx_oword_t oword;
180         efx_rc_t rc;
181
182         /*
183          * Write magic values to scratch registers 0 and 1, then
184          * verify that the values were written correctly.  Interleave
185          * the accesses to ensure that the BIU is not just reading
186          * back the cached value that was last written.
187          */
188         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0);
189         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
190
191         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1);
192         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
193
194         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
195         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) {
196                 rc = EIO;
197                 goto fail1;
198         }
199
200         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
201         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) {
202                 rc = EIO;
203                 goto fail2;
204         }
205
206         /*
207          * Perform the same test, with the values swapped.  This
208          * ensures that subsequent tests don't start with the correct
209          * values already written into the scratch registers.
210          */
211         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1);
212         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
213
214         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0);
215         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
216
217         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
218         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) {
219                 rc = EIO;
220                 goto fail3;
221         }
222
223         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
224         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) {
225                 rc = EIO;
226                 goto fail4;
227         }
228
229         return (0);
230
231 fail4:
232         EFSYS_PROBE(fail4);
233 fail3:
234         EFSYS_PROBE(fail3);
235 fail2:
236         EFSYS_PROBE(fail2);
237 fail1:
238         EFSYS_PROBE1(fail1, efx_rc_t, rc);
239
240         return (rc);
241 }
242
243 #if EFSYS_OPT_FALCON
244
245 static efx_nic_ops_t    __efx_nic_falcon_ops = {
246         falcon_nic_probe,               /* eno_probe */
247         NULL,                           /* eno_board_cfg */
248         NULL,                           /* eno_set_drv_limits */
249         falcon_nic_reset,               /* eno_reset */
250         falcon_nic_init,                /* eno_init */
251         NULL,                           /* eno_get_vi_pool */
252         NULL,                           /* eno_get_bar_region */
253 #if EFSYS_OPT_DIAG
254         falcon_sram_test,               /* eno_sram_test */
255         falcon_nic_register_test,       /* eno_register_test */
256 #endif  /* EFSYS_OPT_DIAG */
257         falcon_nic_fini,                /* eno_fini */
258         falcon_nic_unprobe,             /* eno_unprobe */
259 };
260
261 #endif  /* EFSYS_OPT_FALCON */
262
263 #if EFSYS_OPT_SIENA
264
265 static efx_nic_ops_t    __efx_nic_siena_ops = {
266         siena_nic_probe,                /* eno_probe */
267         NULL,                           /* eno_board_cfg */
268         NULL,                           /* eno_set_drv_limits */
269         siena_nic_reset,                /* eno_reset */
270         siena_nic_init,                 /* eno_init */
271         NULL,                           /* eno_get_vi_pool */
272         NULL,                           /* eno_get_bar_region */
273 #if EFSYS_OPT_DIAG
274         siena_sram_test,                /* eno_sram_test */
275         siena_nic_register_test,        /* eno_register_test */
276 #endif  /* EFSYS_OPT_DIAG */
277         siena_nic_fini,                 /* eno_fini */
278         siena_nic_unprobe,              /* eno_unprobe */
279 };
280
281 #endif  /* EFSYS_OPT_SIENA */
282
283 #if EFSYS_OPT_HUNTINGTON
284
285 static efx_nic_ops_t    __efx_nic_hunt_ops = {
286         ef10_nic_probe,                 /* eno_probe */
287         hunt_board_cfg,                 /* eno_board_cfg */
288         ef10_nic_set_drv_limits,        /* eno_set_drv_limits */
289         ef10_nic_reset,                 /* eno_reset */
290         ef10_nic_init,                  /* eno_init */
291         ef10_nic_get_vi_pool,           /* eno_get_vi_pool */
292         ef10_nic_get_bar_region,        /* eno_get_bar_region */
293 #if EFSYS_OPT_DIAG
294         ef10_sram_test,                 /* eno_sram_test */
295         ef10_nic_register_test,         /* eno_register_test */
296 #endif  /* EFSYS_OPT_DIAG */
297         ef10_nic_fini,                  /* eno_fini */
298         ef10_nic_unprobe,               /* eno_unprobe */
299 };
300
301 #endif  /* EFSYS_OPT_HUNTINGTON */
302
303 #if EFSYS_OPT_MEDFORD
304
305 static efx_nic_ops_t    __efx_nic_medford_ops = {
306         ef10_nic_probe,                 /* eno_probe */
307         medford_board_cfg,              /* eno_board_cfg */
308         ef10_nic_set_drv_limits,        /* eno_set_drv_limits */
309         ef10_nic_reset,                 /* eno_reset */
310         ef10_nic_init,                  /* eno_init */
311         ef10_nic_get_vi_pool,           /* eno_get_vi_pool */
312         ef10_nic_get_bar_region,        /* eno_get_bar_region */
313 #if EFSYS_OPT_DIAG
314         ef10_sram_test,                 /* eno_sram_test */
315         ef10_nic_register_test,         /* eno_register_test */
316 #endif  /* EFSYS_OPT_DIAG */
317         ef10_nic_fini,                  /* eno_fini */
318         ef10_nic_unprobe,               /* eno_unprobe */
319 };
320
321 #endif  /* EFSYS_OPT_MEDFORD */
322
323
324         __checkReturn   efx_rc_t
325 efx_nic_create(
326         __in            efx_family_t family,
327         __in            efsys_identifier_t *esip,
328         __in            efsys_bar_t *esbp,
329         __in            efsys_lock_t *eslp,
330         __deref_out     efx_nic_t **enpp)
331 {
332         efx_nic_t *enp;
333         efx_rc_t rc;
334
335         EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID);
336         EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES);
337
338         /* Allocate a NIC object */
339         EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp);
340
341         if (enp == NULL) {
342                 rc = ENOMEM;
343                 goto fail1;
344         }
345
346         enp->en_magic = EFX_NIC_MAGIC;
347
348         switch (family) {
349 #if EFSYS_OPT_FALCON
350         case EFX_FAMILY_FALCON:
351                 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_falcon_ops;
352                 enp->en_features = 0;
353                 break;
354 #endif  /* EFSYS_OPT_FALCON */
355
356 #if EFSYS_OPT_SIENA
357         case EFX_FAMILY_SIENA:
358                 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_siena_ops;
359                 enp->en_features =
360                     EFX_FEATURE_IPV6 |
361                     EFX_FEATURE_LFSR_HASH_INSERT |
362                     EFX_FEATURE_LINK_EVENTS |
363                     EFX_FEATURE_PERIODIC_MAC_STATS |
364                     EFX_FEATURE_WOL |
365                     EFX_FEATURE_MCDI |
366                     EFX_FEATURE_LOOKAHEAD_SPLIT |
367                     EFX_FEATURE_MAC_HEADER_FILTERS |
368                     EFX_FEATURE_TX_SRC_FILTERS;
369                 break;
370 #endif  /* EFSYS_OPT_SIENA */
371
372 #if EFSYS_OPT_HUNTINGTON
373         case EFX_FAMILY_HUNTINGTON:
374                 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_hunt_ops;
375                 /* FIXME: Add WOL support */
376                 enp->en_features =
377                     EFX_FEATURE_IPV6 |
378                     EFX_FEATURE_LINK_EVENTS |
379                     EFX_FEATURE_PERIODIC_MAC_STATS |
380                     EFX_FEATURE_MCDI |
381                     EFX_FEATURE_MAC_HEADER_FILTERS |
382                     EFX_FEATURE_MCDI_DMA |
383                     EFX_FEATURE_PIO_BUFFERS |
384                     EFX_FEATURE_FW_ASSISTED_TSO |
385                     EFX_FEATURE_FW_ASSISTED_TSO_V2;
386                 break;
387 #endif  /* EFSYS_OPT_HUNTINGTON */
388
389 #if EFSYS_OPT_MEDFORD
390         case EFX_FAMILY_MEDFORD:
391                 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_medford_ops;
392                 /*
393                  * FW_ASSISTED_TSO ommitted as Medford only supports firmware
394                  * assisted TSO version 2, not the v1 scheme used on Huntington.
395                  */
396                 enp->en_features =
397                     EFX_FEATURE_IPV6 |
398                     EFX_FEATURE_LINK_EVENTS |
399                     EFX_FEATURE_PERIODIC_MAC_STATS |
400                     EFX_FEATURE_MCDI |
401                     EFX_FEATURE_MAC_HEADER_FILTERS |
402                     EFX_FEATURE_MCDI_DMA |
403                     EFX_FEATURE_PIO_BUFFERS;
404                 break;
405 #endif  /* EFSYS_OPT_MEDFORD */
406
407         default:
408                 rc = ENOTSUP;
409                 goto fail2;
410         }
411
412         enp->en_family = family;
413         enp->en_esip = esip;
414         enp->en_esbp = esbp;
415         enp->en_eslp = eslp;
416
417         *enpp = enp;
418
419         return (0);
420
421 fail2:
422         EFSYS_PROBE(fail2);
423
424         enp->en_magic = 0;
425
426         /* Free the NIC object */
427         EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
428
429 fail1:
430         EFSYS_PROBE1(fail1, efx_rc_t, rc);
431
432         return (rc);
433 }
434
435         __checkReturn   efx_rc_t
436 efx_nic_probe(
437         __in            efx_nic_t *enp)
438 {
439         efx_nic_ops_t *enop;
440         efx_rc_t rc;
441
442         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
443 #if EFSYS_OPT_MCDI
444         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
445 #endif  /* EFSYS_OPT_MCDI */
446         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
447
448         enop = enp->en_enop;
449         if ((rc = enop->eno_probe(enp)) != 0)
450                 goto fail1;
451
452         if ((rc = efx_phy_probe(enp)) != 0)
453                 goto fail2;
454
455         enp->en_mod_flags |= EFX_MOD_PROBE;
456
457         return (0);
458
459 fail2:
460         EFSYS_PROBE(fail2);
461
462         enop->eno_unprobe(enp);
463
464 fail1:
465         EFSYS_PROBE1(fail1, efx_rc_t, rc);
466
467         return (rc);
468 }
469
470 #if EFSYS_OPT_PCIE_TUNE
471
472         __checkReturn   efx_rc_t
473 efx_nic_pcie_tune(
474         __in            efx_nic_t *enp,
475         unsigned int    nlanes)
476 {
477         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
478         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
479         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
480
481 #if EFSYS_OPT_FALCON
482         if (enp->en_family == EFX_FAMILY_FALCON)
483                 return (falcon_nic_pcie_tune(enp, nlanes));
484 #endif
485         return (ENOTSUP);
486 }
487
488         __checkReturn   efx_rc_t
489 efx_nic_pcie_extended_sync(
490         __in            efx_nic_t *enp)
491 {
492         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
493         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
494         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
495
496 #if EFSYS_OPT_SIENA
497         if (enp->en_family == EFX_FAMILY_SIENA)
498                 return (siena_nic_pcie_extended_sync(enp));
499 #endif
500
501         return (ENOTSUP);
502 }
503
504 #endif  /* EFSYS_OPT_PCIE_TUNE */
505
506         __checkReturn   efx_rc_t
507 efx_nic_set_drv_limits(
508         __inout         efx_nic_t *enp,
509         __in            efx_drv_limits_t *edlp)
510 {
511         efx_nic_ops_t *enop = enp->en_enop;
512         efx_rc_t rc;
513
514         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
515         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
516
517         if (enop->eno_set_drv_limits != NULL) {
518                 if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
519                         goto fail1;
520         }
521
522         return (0);
523
524 fail1:
525         EFSYS_PROBE1(fail1, efx_rc_t, rc);
526
527         return (rc);
528 }
529
530         __checkReturn   efx_rc_t
531 efx_nic_get_bar_region(
532         __in            efx_nic_t *enp,
533         __in            efx_nic_region_t region,
534         __out           uint32_t *offsetp,
535         __out           size_t *sizep)
536 {
537         efx_nic_ops_t *enop = enp->en_enop;
538         efx_rc_t rc;
539
540         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
541         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
542         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
543
544         if (enop->eno_get_bar_region == NULL) {
545                 rc = ENOTSUP;
546                 goto fail1;
547         }
548         if ((rc = (enop->eno_get_bar_region)(enp,
549                     region, offsetp, sizep)) != 0) {
550                 goto fail2;
551         }
552
553         return (0);
554
555 fail2:
556         EFSYS_PROBE(fail2);
557
558 fail1:
559         EFSYS_PROBE1(fail1, efx_rc_t, rc);
560
561         return (rc);
562 }
563
564
565         __checkReturn   efx_rc_t
566 efx_nic_get_vi_pool(
567         __in            efx_nic_t *enp,
568         __out           uint32_t *evq_countp,
569         __out           uint32_t *rxq_countp,
570         __out           uint32_t *txq_countp)
571 {
572         efx_nic_ops_t *enop = enp->en_enop;
573         efx_nic_cfg_t *encp = &enp->en_nic_cfg;
574         efx_rc_t rc;
575
576         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
577         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
578         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
579
580         if (enop->eno_get_vi_pool != NULL) {
581                 uint32_t vi_count = 0;
582
583                 if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
584                         goto fail1;
585
586                 *evq_countp = vi_count;
587                 *rxq_countp = vi_count;
588                 *txq_countp = vi_count;
589         } else {
590                 /* Use NIC limits as default value */
591                 *evq_countp = encp->enc_evq_limit;
592                 *rxq_countp = encp->enc_rxq_limit;
593                 *txq_countp = encp->enc_txq_limit;
594         }
595
596         return (0);
597
598 fail1:
599         EFSYS_PROBE1(fail1, efx_rc_t, rc);
600
601         return (rc);
602 }
603
604
605         __checkReturn   efx_rc_t
606 efx_nic_init(
607         __in            efx_nic_t *enp)
608 {
609         efx_nic_ops_t *enop = enp->en_enop;
610         efx_rc_t rc;
611
612         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
613         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
614
615         if (enp->en_mod_flags & EFX_MOD_NIC) {
616                 rc = EINVAL;
617                 goto fail1;
618         }
619
620         if ((rc = enop->eno_init(enp)) != 0)
621                 goto fail2;
622
623         enp->en_mod_flags |= EFX_MOD_NIC;
624
625         return (0);
626
627 fail2:
628         EFSYS_PROBE(fail2);
629 fail1:
630         EFSYS_PROBE1(fail1, efx_rc_t, rc);
631
632         return (rc);
633 }
634
635                         void
636 efx_nic_fini(
637         __in            efx_nic_t *enp)
638 {
639         efx_nic_ops_t *enop = enp->en_enop;
640
641         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
642         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
643         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC);
644         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
645         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
646         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
647         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
648
649         enop->eno_fini(enp);
650
651         enp->en_mod_flags &= ~EFX_MOD_NIC;
652 }
653
654                         void
655 efx_nic_unprobe(
656         __in            efx_nic_t *enp)
657 {
658         efx_nic_ops_t *enop = enp->en_enop;
659
660         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
661 #if EFSYS_OPT_MCDI
662         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
663 #endif  /* EFSYS_OPT_MCDI */
664         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
665         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
666         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
667         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
668         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
669         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
670
671         efx_phy_unprobe(enp);
672
673         enop->eno_unprobe(enp);
674
675         enp->en_mod_flags &= ~EFX_MOD_PROBE;
676 }
677
678                         void
679 efx_nic_destroy(
680         __in    efx_nic_t *enp)
681 {
682         efsys_identifier_t *esip = enp->en_esip;
683
684         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
685         EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
686
687         enp->en_family = 0;
688         enp->en_esip = NULL;
689         enp->en_esbp = NULL;
690         enp->en_eslp = NULL;
691
692         enp->en_enop = NULL;
693
694         enp->en_magic = 0;
695
696         /* Free the NIC object */
697         EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
698 }
699
700         __checkReturn   efx_rc_t
701 efx_nic_reset(
702         __in            efx_nic_t *enp)
703 {
704         efx_nic_ops_t *enop = enp->en_enop;
705         unsigned int mod_flags;
706         efx_rc_t rc;
707
708         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
709         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
710         /*
711          * All modules except the MCDI, PROBE, NVRAM, VPD, MON, LIC
712          * (which we do not reset here) must have been shut down or never
713          * initialized.
714          *
715          * A rule of thumb here is: If the controller or MC reboots, is *any*
716          * state lost. If it's lost and needs reapplying, then the module
717          * *must* not be initialised during the reset.
718          */
719         mod_flags = enp->en_mod_flags;
720         mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
721                     EFX_MOD_VPD | EFX_MOD_MON | EFX_MOD_LIC);
722         EFSYS_ASSERT3U(mod_flags, ==, 0);
723         if (mod_flags != 0) {
724                 rc = EINVAL;
725                 goto fail1;
726         }
727
728         if ((rc = enop->eno_reset(enp)) != 0)
729                 goto fail2;
730
731         enp->en_reset_flags |= EFX_RESET_MAC;
732
733         return (0);
734
735 fail2:
736         EFSYS_PROBE(fail2);
737 fail1:
738         EFSYS_PROBE1(fail1, efx_rc_t, rc);
739
740         return (rc);
741 }
742
743                         const efx_nic_cfg_t *
744 efx_nic_cfg_get(
745         __in            efx_nic_t *enp)
746 {
747         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
748
749         return (&(enp->en_nic_cfg));
750 }
751
752 #if EFSYS_OPT_DIAG
753
754         __checkReturn   efx_rc_t
755 efx_nic_register_test(
756         __in            efx_nic_t *enp)
757 {
758         efx_nic_ops_t *enop = enp->en_enop;
759         efx_rc_t rc;
760
761         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
762         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
763         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
764
765         if ((rc = enop->eno_register_test(enp)) != 0)
766                 goto fail1;
767
768         return (0);
769
770 fail1:
771         EFSYS_PROBE1(fail1, efx_rc_t, rc);
772
773         return (rc);
774 }
775
776         __checkReturn   efx_rc_t
777 efx_nic_test_registers(
778         __in            efx_nic_t *enp,
779         __in            efx_register_set_t *rsp,
780         __in            size_t count)
781 {
782         unsigned int bit;
783         efx_oword_t original;
784         efx_oword_t reg;
785         efx_oword_t buf;
786         efx_rc_t rc;
787
788         while (count > 0) {
789                 /* This function is only suitable for registers */
790                 EFSYS_ASSERT(rsp->rows == 1);
791
792                 /* bit sweep on and off */
793                 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
794                             B_TRUE);
795                 for (bit = 0; bit < 128; bit++) {
796                         /* Is this bit in the mask? */
797                         if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
798                                 continue;
799
800                         /* Test this bit can be set in isolation */
801                         reg = original;
802                         EFX_AND_OWORD(reg, rsp->mask);
803                         EFX_SET_OWORD_BIT(reg, bit);
804
805                         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
806                                     B_TRUE);
807                         EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
808                                     B_TRUE);
809
810                         EFX_AND_OWORD(buf, rsp->mask);
811                         if (memcmp(&reg, &buf, sizeof (reg))) {
812                                 rc = EIO;
813                                 goto fail1;
814                         }
815
816                         /* Test this bit can be cleared in isolation */
817                         EFX_OR_OWORD(reg, rsp->mask);
818                         EFX_CLEAR_OWORD_BIT(reg, bit);
819
820                         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
821                                     B_TRUE);
822                         EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
823                                     B_TRUE);
824
825                         EFX_AND_OWORD(buf, rsp->mask);
826                         if (memcmp(&reg, &buf, sizeof (reg))) {
827                                 rc = EIO;
828                                 goto fail2;
829                         }
830                 }
831
832                 /* Restore the old value */
833                 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
834                             B_TRUE);
835
836                 --count;
837                 ++rsp;
838         }
839
840         return (0);
841
842 fail2:
843         EFSYS_PROBE(fail2);
844 fail1:
845         EFSYS_PROBE1(fail1, efx_rc_t, rc);
846
847         /* Restore the old value */
848         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
849
850         return (rc);
851 }
852
853         __checkReturn   efx_rc_t
854 efx_nic_test_tables(
855         __in            efx_nic_t *enp,
856         __in            efx_register_set_t *rsp,
857         __in            efx_pattern_type_t pattern,
858         __in            size_t count)
859 {
860         efx_sram_pattern_fn_t func;
861         unsigned int index;
862         unsigned int address;
863         efx_oword_t reg;
864         efx_oword_t buf;
865         efx_rc_t rc;
866
867         EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
868         func = __efx_sram_pattern_fns[pattern];
869
870         while (count > 0) {
871                 /* Write */
872                 address = rsp->address;
873                 for (index = 0; index < rsp->rows; ++index) {
874                         func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
875                         func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
876                         EFX_AND_OWORD(reg, rsp->mask);
877                         EFSYS_BAR_WRITEO(enp->en_esbp, address, &reg, B_TRUE);
878
879                         address += rsp->step;
880                 }
881
882                 /* Read */
883                 address = rsp->address;
884                 for (index = 0; index < rsp->rows; ++index) {
885                         func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
886                         func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
887                         EFX_AND_OWORD(reg, rsp->mask);
888                         EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
889                         if (memcmp(&reg, &buf, sizeof (reg))) {
890                                 rc = EIO;
891                                 goto fail1;
892                         }
893
894                         address += rsp->step;
895                 }
896
897                 ++rsp;
898                 --count;
899         }
900
901         return (0);
902
903 fail1:
904         EFSYS_PROBE1(fail1, efx_rc_t, rc);
905
906         return (rc);
907 }
908
909 #endif  /* EFSYS_OPT_DIAG */
910
911 #if EFSYS_OPT_LOOPBACK
912
913 extern                  void
914 efx_loopback_mask(
915         __in    efx_loopback_kind_t loopback_kind,
916         __out   efx_qword_t *maskp)
917 {
918         efx_qword_t mask;
919
920         EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS);
921         EFSYS_ASSERT(maskp != NULL);
922
923         /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
924         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
925         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
926         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
927         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
928         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
929         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
930         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
931         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
932         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
933         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
934         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
935         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
936         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
937         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
938         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
939         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
940         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
941         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
942         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT);
943         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS);
944         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS);
945         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR ==
946             EFX_LOOPBACK_XAUI_WS_FAR);
947         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR ==
948             EFX_LOOPBACK_XAUI_WS_NEAR);
949         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS);
950         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS);
951         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR ==
952             EFX_LOOPBACK_XFI_WS_FAR);
953         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS);
954         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT);
955         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR);
956         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR);
957         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS ==
958             EFX_LOOPBACK_PMA_INT_WS);
959         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS ==
960             EFX_LOOPBACK_SD_FEP2_WS);
961         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS ==
962             EFX_LOOPBACK_SD_FEP1_5_WS);
963         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS);
964         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS);
965
966         /* Build bitmask of possible loopback types */
967         EFX_ZERO_QWORD(mask);
968
969         if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) ||
970             (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
971                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF);
972         }
973
974         if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) ||
975             (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
976                 /*
977                  * The "MAC" grouping has historically been used by drivers to
978                  * mean loopbacks supported by on-chip hardware. Keep that
979                  * meaning here, and include on-chip PHY layer loopbacks.
980                  */
981                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA);
982                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC);
983                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII);
984                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS);
985                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI);
986                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII);
987                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII);
988                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR);
989                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI);
990                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR);
991                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR);
992                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR);
993                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR);
994                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT);
995                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR);
996                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR);
997         }
998
999         if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) ||
1000             (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
1001                 /*
1002                  * The "PHY" grouping has historically been used by drivers to
1003                  * mean loopbacks supported by off-chip hardware. Keep that
1004                  * meaning here.
1005                  */
1006                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY);
1007                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PHY_XS);
1008                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS);
1009                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD);
1010         }
1011
1012         *maskp = mask;
1013 }
1014
1015         __checkReturn   efx_rc_t
1016 efx_mcdi_get_loopback_modes(
1017         __in            efx_nic_t *enp)
1018 {
1019         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1020         efx_mcdi_req_t req;
1021         uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
1022                             MC_CMD_GET_LOOPBACK_MODES_OUT_LEN)];
1023         efx_qword_t mask;
1024         efx_qword_t modes;
1025         efx_rc_t rc;
1026
1027         (void) memset(payload, 0, sizeof (payload));
1028         req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
1029         req.emr_in_buf = payload;
1030         req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
1031         req.emr_out_buf = payload;
1032         req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN;
1033
1034         efx_mcdi_execute(enp, &req);
1035
1036         if (req.emr_rc != 0) {
1037                 rc = req.emr_rc;
1038                 goto fail1;
1039         }
1040
1041         if (req.emr_out_length_used <
1042             MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
1043             MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) {
1044                 rc = EMSGSIZE;
1045                 goto fail2;
1046         }
1047
1048         /*
1049          * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
1050          * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link().
1051          */
1052         efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask);
1053
1054         EFX_AND_QWORD(mask,
1055             *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED));
1056
1057         modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M);
1058         EFX_AND_QWORD(modes, mask);
1059         encp->enc_loopback_types[EFX_LINK_100FDX] = modes;
1060
1061         modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G);
1062         EFX_AND_QWORD(modes, mask);
1063         encp->enc_loopback_types[EFX_LINK_1000FDX] = modes;
1064
1065         modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G);
1066         EFX_AND_QWORD(modes, mask);
1067         encp->enc_loopback_types[EFX_LINK_10000FDX] = modes;
1068
1069         if (req.emr_out_length_used >=
1070             MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
1071             MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
1072                 /* Response includes 40G loopback modes */
1073                 modes =
1074                     *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G);
1075                 EFX_AND_QWORD(modes, mask);
1076                 encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
1077         }
1078
1079         EFX_ZERO_QWORD(modes);
1080         EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
1081         EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
1082         EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
1083         EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
1084         EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
1085         encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
1086
1087         return (0);
1088
1089 fail2:
1090         EFSYS_PROBE(fail2);
1091 fail1:
1092         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1093
1094         return (rc);
1095 }
1096
1097 #endif /* EFSYS_OPT_LOOPBACK */