]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/dev/sfxge/common/efx_nic.c
MFC r299254
[FreeBSD/stable/10.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         __checkReturn   efx_rc_t
471 efx_nic_set_drv_limits(
472         __inout         efx_nic_t *enp,
473         __in            efx_drv_limits_t *edlp)
474 {
475         efx_nic_ops_t *enop = enp->en_enop;
476         efx_rc_t rc;
477
478         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
479         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
480
481         if (enop->eno_set_drv_limits != NULL) {
482                 if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
483                         goto fail1;
484         }
485
486         return (0);
487
488 fail1:
489         EFSYS_PROBE1(fail1, efx_rc_t, rc);
490
491         return (rc);
492 }
493
494         __checkReturn   efx_rc_t
495 efx_nic_get_bar_region(
496         __in            efx_nic_t *enp,
497         __in            efx_nic_region_t region,
498         __out           uint32_t *offsetp,
499         __out           size_t *sizep)
500 {
501         efx_nic_ops_t *enop = enp->en_enop;
502         efx_rc_t rc;
503
504         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
505         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
506         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
507
508         if (enop->eno_get_bar_region == NULL) {
509                 rc = ENOTSUP;
510                 goto fail1;
511         }
512         if ((rc = (enop->eno_get_bar_region)(enp,
513                     region, offsetp, sizep)) != 0) {
514                 goto fail2;
515         }
516
517         return (0);
518
519 fail2:
520         EFSYS_PROBE(fail2);
521
522 fail1:
523         EFSYS_PROBE1(fail1, efx_rc_t, rc);
524
525         return (rc);
526 }
527
528
529         __checkReturn   efx_rc_t
530 efx_nic_get_vi_pool(
531         __in            efx_nic_t *enp,
532         __out           uint32_t *evq_countp,
533         __out           uint32_t *rxq_countp,
534         __out           uint32_t *txq_countp)
535 {
536         efx_nic_ops_t *enop = enp->en_enop;
537         efx_nic_cfg_t *encp = &enp->en_nic_cfg;
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_vi_pool != NULL) {
545                 uint32_t vi_count = 0;
546
547                 if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
548                         goto fail1;
549
550                 *evq_countp = vi_count;
551                 *rxq_countp = vi_count;
552                 *txq_countp = vi_count;
553         } else {
554                 /* Use NIC limits as default value */
555                 *evq_countp = encp->enc_evq_limit;
556                 *rxq_countp = encp->enc_rxq_limit;
557                 *txq_countp = encp->enc_txq_limit;
558         }
559
560         return (0);
561
562 fail1:
563         EFSYS_PROBE1(fail1, efx_rc_t, rc);
564
565         return (rc);
566 }
567
568
569         __checkReturn   efx_rc_t
570 efx_nic_init(
571         __in            efx_nic_t *enp)
572 {
573         efx_nic_ops_t *enop = enp->en_enop;
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
579         if (enp->en_mod_flags & EFX_MOD_NIC) {
580                 rc = EINVAL;
581                 goto fail1;
582         }
583
584         if ((rc = enop->eno_init(enp)) != 0)
585                 goto fail2;
586
587         enp->en_mod_flags |= EFX_MOD_NIC;
588
589         return (0);
590
591 fail2:
592         EFSYS_PROBE(fail2);
593 fail1:
594         EFSYS_PROBE1(fail1, efx_rc_t, rc);
595
596         return (rc);
597 }
598
599                         void
600 efx_nic_fini(
601         __in            efx_nic_t *enp)
602 {
603         efx_nic_ops_t *enop = enp->en_enop;
604
605         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
606         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
607         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC);
608         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
609         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
610         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
611         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
612
613         enop->eno_fini(enp);
614
615         enp->en_mod_flags &= ~EFX_MOD_NIC;
616 }
617
618                         void
619 efx_nic_unprobe(
620         __in            efx_nic_t *enp)
621 {
622         efx_nic_ops_t *enop = enp->en_enop;
623
624         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
625 #if EFSYS_OPT_MCDI
626         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
627 #endif  /* EFSYS_OPT_MCDI */
628         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
629         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
630         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
631         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
632         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
633         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
634
635         efx_phy_unprobe(enp);
636
637         enop->eno_unprobe(enp);
638
639         enp->en_mod_flags &= ~EFX_MOD_PROBE;
640 }
641
642                         void
643 efx_nic_destroy(
644         __in    efx_nic_t *enp)
645 {
646         efsys_identifier_t *esip = enp->en_esip;
647
648         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
649         EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
650
651         enp->en_family = 0;
652         enp->en_esip = NULL;
653         enp->en_esbp = NULL;
654         enp->en_eslp = NULL;
655
656         enp->en_enop = NULL;
657
658         enp->en_magic = 0;
659
660         /* Free the NIC object */
661         EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
662 }
663
664         __checkReturn   efx_rc_t
665 efx_nic_reset(
666         __in            efx_nic_t *enp)
667 {
668         efx_nic_ops_t *enop = enp->en_enop;
669         unsigned int mod_flags;
670         efx_rc_t rc;
671
672         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
673         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
674         /*
675          * All modules except the MCDI, PROBE, NVRAM, VPD, MON, LIC
676          * (which we do not reset here) must have been shut down or never
677          * initialized.
678          *
679          * A rule of thumb here is: If the controller or MC reboots, is *any*
680          * state lost. If it's lost and needs reapplying, then the module
681          * *must* not be initialised during the reset.
682          */
683         mod_flags = enp->en_mod_flags;
684         mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
685                     EFX_MOD_VPD | EFX_MOD_MON | EFX_MOD_LIC);
686         EFSYS_ASSERT3U(mod_flags, ==, 0);
687         if (mod_flags != 0) {
688                 rc = EINVAL;
689                 goto fail1;
690         }
691
692         if ((rc = enop->eno_reset(enp)) != 0)
693                 goto fail2;
694
695         enp->en_reset_flags |= EFX_RESET_MAC;
696
697         return (0);
698
699 fail2:
700         EFSYS_PROBE(fail2);
701 fail1:
702         EFSYS_PROBE1(fail1, efx_rc_t, rc);
703
704         return (rc);
705 }
706
707                         const efx_nic_cfg_t *
708 efx_nic_cfg_get(
709         __in            efx_nic_t *enp)
710 {
711         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
712
713         return (&(enp->en_nic_cfg));
714 }
715
716 #if EFSYS_OPT_DIAG
717
718         __checkReturn   efx_rc_t
719 efx_nic_register_test(
720         __in            efx_nic_t *enp)
721 {
722         efx_nic_ops_t *enop = enp->en_enop;
723         efx_rc_t rc;
724
725         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
726         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
727         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
728
729         if ((rc = enop->eno_register_test(enp)) != 0)
730                 goto fail1;
731
732         return (0);
733
734 fail1:
735         EFSYS_PROBE1(fail1, efx_rc_t, rc);
736
737         return (rc);
738 }
739
740         __checkReturn   efx_rc_t
741 efx_nic_test_registers(
742         __in            efx_nic_t *enp,
743         __in            efx_register_set_t *rsp,
744         __in            size_t count)
745 {
746         unsigned int bit;
747         efx_oword_t original;
748         efx_oword_t reg;
749         efx_oword_t buf;
750         efx_rc_t rc;
751
752         while (count > 0) {
753                 /* This function is only suitable for registers */
754                 EFSYS_ASSERT(rsp->rows == 1);
755
756                 /* bit sweep on and off */
757                 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
758                             B_TRUE);
759                 for (bit = 0; bit < 128; bit++) {
760                         /* Is this bit in the mask? */
761                         if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
762                                 continue;
763
764                         /* Test this bit can be set in isolation */
765                         reg = original;
766                         EFX_AND_OWORD(reg, rsp->mask);
767                         EFX_SET_OWORD_BIT(reg, bit);
768
769                         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
770                                     B_TRUE);
771                         EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
772                                     B_TRUE);
773
774                         EFX_AND_OWORD(buf, rsp->mask);
775                         if (memcmp(&reg, &buf, sizeof (reg))) {
776                                 rc = EIO;
777                                 goto fail1;
778                         }
779
780                         /* Test this bit can be cleared in isolation */
781                         EFX_OR_OWORD(reg, rsp->mask);
782                         EFX_CLEAR_OWORD_BIT(reg, bit);
783
784                         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
785                                     B_TRUE);
786                         EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
787                                     B_TRUE);
788
789                         EFX_AND_OWORD(buf, rsp->mask);
790                         if (memcmp(&reg, &buf, sizeof (reg))) {
791                                 rc = EIO;
792                                 goto fail2;
793                         }
794                 }
795
796                 /* Restore the old value */
797                 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
798                             B_TRUE);
799
800                 --count;
801                 ++rsp;
802         }
803
804         return (0);
805
806 fail2:
807         EFSYS_PROBE(fail2);
808 fail1:
809         EFSYS_PROBE1(fail1, efx_rc_t, rc);
810
811         /* Restore the old value */
812         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
813
814         return (rc);
815 }
816
817         __checkReturn   efx_rc_t
818 efx_nic_test_tables(
819         __in            efx_nic_t *enp,
820         __in            efx_register_set_t *rsp,
821         __in            efx_pattern_type_t pattern,
822         __in            size_t count)
823 {
824         efx_sram_pattern_fn_t func;
825         unsigned int index;
826         unsigned int address;
827         efx_oword_t reg;
828         efx_oword_t buf;
829         efx_rc_t rc;
830
831         EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
832         func = __efx_sram_pattern_fns[pattern];
833
834         while (count > 0) {
835                 /* Write */
836                 address = rsp->address;
837                 for (index = 0; index < rsp->rows; ++index) {
838                         func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
839                         func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
840                         EFX_AND_OWORD(reg, rsp->mask);
841                         EFSYS_BAR_WRITEO(enp->en_esbp, address, &reg, B_TRUE);
842
843                         address += rsp->step;
844                 }
845
846                 /* Read */
847                 address = rsp->address;
848                 for (index = 0; index < rsp->rows; ++index) {
849                         func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
850                         func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
851                         EFX_AND_OWORD(reg, rsp->mask);
852                         EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
853                         if (memcmp(&reg, &buf, sizeof (reg))) {
854                                 rc = EIO;
855                                 goto fail1;
856                         }
857
858                         address += rsp->step;
859                 }
860
861                 ++rsp;
862                 --count;
863         }
864
865         return (0);
866
867 fail1:
868         EFSYS_PROBE1(fail1, efx_rc_t, rc);
869
870         return (rc);
871 }
872
873 #endif  /* EFSYS_OPT_DIAG */
874
875 #if EFSYS_OPT_LOOPBACK
876
877 extern                  void
878 efx_loopback_mask(
879         __in    efx_loopback_kind_t loopback_kind,
880         __out   efx_qword_t *maskp)
881 {
882         efx_qword_t mask;
883
884         EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS);
885         EFSYS_ASSERT(maskp != NULL);
886
887         /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
888         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
889         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
890         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
891         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
892         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
893         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
894         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
895         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
896         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
897         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
898         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
899         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
900         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
901         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
902         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
903         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
904         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
905         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
906         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT);
907         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS);
908         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS);
909         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR ==
910             EFX_LOOPBACK_XAUI_WS_FAR);
911         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR ==
912             EFX_LOOPBACK_XAUI_WS_NEAR);
913         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS);
914         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS);
915         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR ==
916             EFX_LOOPBACK_XFI_WS_FAR);
917         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS);
918         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT);
919         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR);
920         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR);
921         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS ==
922             EFX_LOOPBACK_PMA_INT_WS);
923         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS ==
924             EFX_LOOPBACK_SD_FEP2_WS);
925         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS ==
926             EFX_LOOPBACK_SD_FEP1_5_WS);
927         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS);
928         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS);
929
930         /* Build bitmask of possible loopback types */
931         EFX_ZERO_QWORD(mask);
932
933         if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) ||
934             (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
935                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF);
936         }
937
938         if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) ||
939             (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
940                 /*
941                  * The "MAC" grouping has historically been used by drivers to
942                  * mean loopbacks supported by on-chip hardware. Keep that
943                  * meaning here, and include on-chip PHY layer loopbacks.
944                  */
945                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA);
946                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC);
947                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII);
948                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS);
949                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI);
950                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII);
951                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII);
952                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR);
953                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI);
954                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR);
955                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR);
956                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR);
957                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR);
958                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT);
959                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR);
960                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR);
961         }
962
963         if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) ||
964             (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
965                 /*
966                  * The "PHY" grouping has historically been used by drivers to
967                  * mean loopbacks supported by off-chip hardware. Keep that
968                  * meaning here.
969                  */
970                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY);
971                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PHY_XS);
972                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS);
973                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD);
974         }
975
976         *maskp = mask;
977 }
978
979         __checkReturn   efx_rc_t
980 efx_mcdi_get_loopback_modes(
981         __in            efx_nic_t *enp)
982 {
983         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
984         efx_mcdi_req_t req;
985         uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
986                             MC_CMD_GET_LOOPBACK_MODES_OUT_LEN)];
987         efx_qword_t mask;
988         efx_qword_t modes;
989         efx_rc_t rc;
990
991         (void) memset(payload, 0, sizeof (payload));
992         req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
993         req.emr_in_buf = payload;
994         req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
995         req.emr_out_buf = payload;
996         req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN;
997
998         efx_mcdi_execute(enp, &req);
999
1000         if (req.emr_rc != 0) {
1001                 rc = req.emr_rc;
1002                 goto fail1;
1003         }
1004
1005         if (req.emr_out_length_used <
1006             MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
1007             MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) {
1008                 rc = EMSGSIZE;
1009                 goto fail2;
1010         }
1011
1012         /*
1013          * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
1014          * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link().
1015          */
1016         efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask);
1017
1018         EFX_AND_QWORD(mask,
1019             *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED));
1020
1021         modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M);
1022         EFX_AND_QWORD(modes, mask);
1023         encp->enc_loopback_types[EFX_LINK_100FDX] = modes;
1024
1025         modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G);
1026         EFX_AND_QWORD(modes, mask);
1027         encp->enc_loopback_types[EFX_LINK_1000FDX] = modes;
1028
1029         modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G);
1030         EFX_AND_QWORD(modes, mask);
1031         encp->enc_loopback_types[EFX_LINK_10000FDX] = modes;
1032
1033         if (req.emr_out_length_used >=
1034             MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
1035             MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
1036                 /* Response includes 40G loopback modes */
1037                 modes =
1038                     *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G);
1039                 EFX_AND_QWORD(modes, mask);
1040                 encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
1041         }
1042
1043         EFX_ZERO_QWORD(modes);
1044         EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
1045         EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
1046         EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
1047         EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
1048         EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
1049         encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
1050
1051         return (0);
1052
1053 fail2:
1054         EFSYS_PROBE(fail2);
1055 fail1:
1056         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1057
1058         return (rc);
1059 }
1060
1061 #endif /* EFSYS_OPT_LOOPBACK */