net/sfc/base: import RSS support
[dpdk.git] / drivers / net / sfc / base / efx_nic.c
1 /*
2  * Copyright (c) 2007-2016 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 "efx.h"
32 #include "efx_impl.h"
33
34         __checkReturn   efx_rc_t
35 efx_family(
36         __in            uint16_t venid,
37         __in            uint16_t devid,
38         __out           efx_family_t *efp)
39 {
40         if (venid == EFX_PCI_VENID_SFC) {
41                 switch (devid) {
42 #if EFSYS_OPT_SIENA
43                 case EFX_PCI_DEVID_SIENA_F1_UNINIT:
44                         /*
45                          * Hardware default for PF0 of uninitialised Siena.
46                          * manftest must be able to cope with this device id.
47                          */
48                         *efp = EFX_FAMILY_SIENA;
49                         return (0);
50
51                 case EFX_PCI_DEVID_BETHPAGE:
52                 case EFX_PCI_DEVID_SIENA:
53                         *efp = EFX_FAMILY_SIENA;
54                         return (0);
55 #endif /* EFSYS_OPT_SIENA */
56
57 #if EFSYS_OPT_HUNTINGTON
58                 case EFX_PCI_DEVID_HUNTINGTON_PF_UNINIT:
59                         /*
60                          * Hardware default for PF0 of uninitialised Huntington.
61                          * manftest must be able to cope with this device id.
62                          */
63                         *efp = EFX_FAMILY_HUNTINGTON;
64                         return (0);
65
66                 case EFX_PCI_DEVID_FARMINGDALE:
67                 case EFX_PCI_DEVID_GREENPORT:
68                         *efp = EFX_FAMILY_HUNTINGTON;
69                         return (0);
70
71                 case EFX_PCI_DEVID_FARMINGDALE_VF:
72                 case EFX_PCI_DEVID_GREENPORT_VF:
73                         *efp = EFX_FAMILY_HUNTINGTON;
74                         return (0);
75 #endif /* EFSYS_OPT_HUNTINGTON */
76
77 #if EFSYS_OPT_MEDFORD
78                 case EFX_PCI_DEVID_MEDFORD_PF_UNINIT:
79                         /*
80                          * Hardware default for PF0 of uninitialised Medford.
81                          * manftest must be able to cope with this device id.
82                          */
83                         *efp = EFX_FAMILY_MEDFORD;
84                         return (0);
85
86                 case EFX_PCI_DEVID_MEDFORD:
87                         *efp = EFX_FAMILY_MEDFORD;
88                         return (0);
89
90                 case EFX_PCI_DEVID_MEDFORD_VF:
91                         *efp = EFX_FAMILY_MEDFORD;
92                         return (0);
93 #endif /* EFSYS_OPT_MEDFORD */
94
95                 case EFX_PCI_DEVID_FALCON:      /* Obsolete, not supported */
96                 default:
97                         break;
98                 }
99         }
100
101         *efp = EFX_FAMILY_INVALID;
102         return (ENOTSUP);
103 }
104
105
106 #define EFX_BIU_MAGIC0  0x01234567
107 #define EFX_BIU_MAGIC1  0xfedcba98
108
109         __checkReturn   efx_rc_t
110 efx_nic_biu_test(
111         __in            efx_nic_t *enp)
112 {
113         efx_oword_t oword;
114         efx_rc_t rc;
115
116         /*
117          * Write magic values to scratch registers 0 and 1, then
118          * verify that the values were written correctly.  Interleave
119          * the accesses to ensure that the BIU is not just reading
120          * back the cached value that was last written.
121          */
122         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0);
123         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
124
125         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1);
126         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
127
128         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
129         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) {
130                 rc = EIO;
131                 goto fail1;
132         }
133
134         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
135         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) {
136                 rc = EIO;
137                 goto fail2;
138         }
139
140         /*
141          * Perform the same test, with the values swapped.  This
142          * ensures that subsequent tests don't start with the correct
143          * values already written into the scratch registers.
144          */
145         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1);
146         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
147
148         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0);
149         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
150
151         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
152         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) {
153                 rc = EIO;
154                 goto fail3;
155         }
156
157         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
158         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) {
159                 rc = EIO;
160                 goto fail4;
161         }
162
163         return (0);
164
165 fail4:
166         EFSYS_PROBE(fail4);
167 fail3:
168         EFSYS_PROBE(fail3);
169 fail2:
170         EFSYS_PROBE(fail2);
171 fail1:
172         EFSYS_PROBE1(fail1, efx_rc_t, rc);
173
174         return (rc);
175 }
176
177 #if EFSYS_OPT_SIENA
178
179 static const efx_nic_ops_t      __efx_nic_siena_ops = {
180         siena_nic_probe,                /* eno_probe */
181         NULL,                           /* eno_board_cfg */
182         NULL,                           /* eno_set_drv_limits */
183         siena_nic_reset,                /* eno_reset */
184         siena_nic_init,                 /* eno_init */
185         NULL,                           /* eno_get_vi_pool */
186         NULL,                           /* eno_get_bar_region */
187 #if EFSYS_OPT_DIAG
188         siena_nic_register_test,        /* eno_register_test */
189 #endif  /* EFSYS_OPT_DIAG */
190         siena_nic_fini,                 /* eno_fini */
191         siena_nic_unprobe,              /* eno_unprobe */
192 };
193
194 #endif  /* EFSYS_OPT_SIENA */
195
196 #if EFSYS_OPT_HUNTINGTON
197
198 static const efx_nic_ops_t      __efx_nic_hunt_ops = {
199         ef10_nic_probe,                 /* eno_probe */
200         hunt_board_cfg,                 /* eno_board_cfg */
201         ef10_nic_set_drv_limits,        /* eno_set_drv_limits */
202         ef10_nic_reset,                 /* eno_reset */
203         ef10_nic_init,                  /* eno_init */
204         ef10_nic_get_vi_pool,           /* eno_get_vi_pool */
205         ef10_nic_get_bar_region,        /* eno_get_bar_region */
206 #if EFSYS_OPT_DIAG
207         ef10_nic_register_test,         /* eno_register_test */
208 #endif  /* EFSYS_OPT_DIAG */
209         ef10_nic_fini,                  /* eno_fini */
210         ef10_nic_unprobe,               /* eno_unprobe */
211 };
212
213 #endif  /* EFSYS_OPT_HUNTINGTON */
214
215 #if EFSYS_OPT_MEDFORD
216
217 static const efx_nic_ops_t      __efx_nic_medford_ops = {
218         ef10_nic_probe,                 /* eno_probe */
219         medford_board_cfg,              /* eno_board_cfg */
220         ef10_nic_set_drv_limits,        /* eno_set_drv_limits */
221         ef10_nic_reset,                 /* eno_reset */
222         ef10_nic_init,                  /* eno_init */
223         ef10_nic_get_vi_pool,           /* eno_get_vi_pool */
224         ef10_nic_get_bar_region,        /* eno_get_bar_region */
225 #if EFSYS_OPT_DIAG
226         ef10_nic_register_test,         /* eno_register_test */
227 #endif  /* EFSYS_OPT_DIAG */
228         ef10_nic_fini,                  /* eno_fini */
229         ef10_nic_unprobe,               /* eno_unprobe */
230 };
231
232 #endif  /* EFSYS_OPT_MEDFORD */
233
234
235         __checkReturn   efx_rc_t
236 efx_nic_create(
237         __in            efx_family_t family,
238         __in            efsys_identifier_t *esip,
239         __in            efsys_bar_t *esbp,
240         __in            efsys_lock_t *eslp,
241         __deref_out     efx_nic_t **enpp)
242 {
243         efx_nic_t *enp;
244         efx_rc_t rc;
245
246         EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID);
247         EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES);
248
249         /* Allocate a NIC object */
250         EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp);
251
252         if (enp == NULL) {
253                 rc = ENOMEM;
254                 goto fail1;
255         }
256
257         enp->en_magic = EFX_NIC_MAGIC;
258
259         switch (family) {
260 #if EFSYS_OPT_SIENA
261         case EFX_FAMILY_SIENA:
262                 enp->en_enop = &__efx_nic_siena_ops;
263                 enp->en_features =
264                     EFX_FEATURE_IPV6 |
265                     EFX_FEATURE_LFSR_HASH_INSERT |
266                     EFX_FEATURE_LINK_EVENTS |
267                     EFX_FEATURE_PERIODIC_MAC_STATS |
268                     EFX_FEATURE_MCDI |
269                     EFX_FEATURE_LOOKAHEAD_SPLIT |
270                     EFX_FEATURE_MAC_HEADER_FILTERS |
271                     EFX_FEATURE_TX_SRC_FILTERS;
272                 break;
273 #endif  /* EFSYS_OPT_SIENA */
274
275 #if EFSYS_OPT_HUNTINGTON
276         case EFX_FAMILY_HUNTINGTON:
277                 enp->en_enop = &__efx_nic_hunt_ops;
278                 enp->en_features =
279                     EFX_FEATURE_IPV6 |
280                     EFX_FEATURE_LINK_EVENTS |
281                     EFX_FEATURE_PERIODIC_MAC_STATS |
282                     EFX_FEATURE_MCDI |
283                     EFX_FEATURE_MAC_HEADER_FILTERS |
284                     EFX_FEATURE_MCDI_DMA |
285                     EFX_FEATURE_PIO_BUFFERS |
286                     EFX_FEATURE_FW_ASSISTED_TSO |
287                     EFX_FEATURE_FW_ASSISTED_TSO_V2 |
288                     EFX_FEATURE_PACKED_STREAM;
289                 break;
290 #endif  /* EFSYS_OPT_HUNTINGTON */
291
292 #if EFSYS_OPT_MEDFORD
293         case EFX_FAMILY_MEDFORD:
294                 enp->en_enop = &__efx_nic_medford_ops;
295                 /*
296                  * FW_ASSISTED_TSO omitted as Medford only supports firmware
297                  * assisted TSO version 2, not the v1 scheme used on Huntington.
298                  */
299                 enp->en_features =
300                     EFX_FEATURE_IPV6 |
301                     EFX_FEATURE_LINK_EVENTS |
302                     EFX_FEATURE_PERIODIC_MAC_STATS |
303                     EFX_FEATURE_MCDI |
304                     EFX_FEATURE_MAC_HEADER_FILTERS |
305                     EFX_FEATURE_MCDI_DMA |
306                     EFX_FEATURE_PIO_BUFFERS |
307                     EFX_FEATURE_FW_ASSISTED_TSO_V2 |
308                     EFX_FEATURE_PACKED_STREAM;
309                 break;
310 #endif  /* EFSYS_OPT_MEDFORD */
311
312         default:
313                 rc = ENOTSUP;
314                 goto fail2;
315         }
316
317         enp->en_family = family;
318         enp->en_esip = esip;
319         enp->en_esbp = esbp;
320         enp->en_eslp = eslp;
321
322         *enpp = enp;
323
324         return (0);
325
326 fail2:
327         EFSYS_PROBE(fail2);
328
329         enp->en_magic = 0;
330
331         /* Free the NIC object */
332         EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
333
334 fail1:
335         EFSYS_PROBE1(fail1, efx_rc_t, rc);
336
337         return (rc);
338 }
339
340         __checkReturn   efx_rc_t
341 efx_nic_probe(
342         __in            efx_nic_t *enp)
343 {
344         const efx_nic_ops_t *enop;
345         efx_rc_t rc;
346
347         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
348 #if EFSYS_OPT_MCDI
349         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
350 #endif  /* EFSYS_OPT_MCDI */
351         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
352
353         enop = enp->en_enop;
354         if ((rc = enop->eno_probe(enp)) != 0)
355                 goto fail1;
356
357         if ((rc = efx_phy_probe(enp)) != 0)
358                 goto fail2;
359
360         enp->en_mod_flags |= EFX_MOD_PROBE;
361
362         return (0);
363
364 fail2:
365         EFSYS_PROBE(fail2);
366
367         enop->eno_unprobe(enp);
368
369 fail1:
370         EFSYS_PROBE1(fail1, efx_rc_t, rc);
371
372         return (rc);
373 }
374
375         __checkReturn   efx_rc_t
376 efx_nic_set_drv_limits(
377         __inout         efx_nic_t *enp,
378         __in            efx_drv_limits_t *edlp)
379 {
380         const efx_nic_ops_t *enop = enp->en_enop;
381         efx_rc_t rc;
382
383         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
384         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
385
386         if (enop->eno_set_drv_limits != NULL) {
387                 if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
388                         goto fail1;
389         }
390
391         return (0);
392
393 fail1:
394         EFSYS_PROBE1(fail1, efx_rc_t, rc);
395
396         return (rc);
397 }
398
399         __checkReturn   efx_rc_t
400 efx_nic_get_bar_region(
401         __in            efx_nic_t *enp,
402         __in            efx_nic_region_t region,
403         __out           uint32_t *offsetp,
404         __out           size_t *sizep)
405 {
406         const efx_nic_ops_t *enop = enp->en_enop;
407         efx_rc_t rc;
408
409         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
410         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
411         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
412
413         if (enop->eno_get_bar_region == NULL) {
414                 rc = ENOTSUP;
415                 goto fail1;
416         }
417         if ((rc = (enop->eno_get_bar_region)(enp,
418                     region, offsetp, sizep)) != 0) {
419                 goto fail2;
420         }
421
422         return (0);
423
424 fail2:
425         EFSYS_PROBE(fail2);
426
427 fail1:
428         EFSYS_PROBE1(fail1, efx_rc_t, rc);
429
430         return (rc);
431 }
432
433
434         __checkReturn   efx_rc_t
435 efx_nic_get_vi_pool(
436         __in            efx_nic_t *enp,
437         __out           uint32_t *evq_countp,
438         __out           uint32_t *rxq_countp,
439         __out           uint32_t *txq_countp)
440 {
441         const efx_nic_ops_t *enop = enp->en_enop;
442         efx_nic_cfg_t *encp = &enp->en_nic_cfg;
443         efx_rc_t rc;
444
445         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
446         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
447         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
448
449         if (enop->eno_get_vi_pool != NULL) {
450                 uint32_t vi_count = 0;
451
452                 if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
453                         goto fail1;
454
455                 *evq_countp = vi_count;
456                 *rxq_countp = vi_count;
457                 *txq_countp = vi_count;
458         } else {
459                 /* Use NIC limits as default value */
460                 *evq_countp = encp->enc_evq_limit;
461                 *rxq_countp = encp->enc_rxq_limit;
462                 *txq_countp = encp->enc_txq_limit;
463         }
464
465         return (0);
466
467 fail1:
468         EFSYS_PROBE1(fail1, efx_rc_t, rc);
469
470         return (rc);
471 }
472
473
474         __checkReturn   efx_rc_t
475 efx_nic_init(
476         __in            efx_nic_t *enp)
477 {
478         const efx_nic_ops_t *enop = enp->en_enop;
479         efx_rc_t rc;
480
481         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
482         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
483
484         if (enp->en_mod_flags & EFX_MOD_NIC) {
485                 rc = EINVAL;
486                 goto fail1;
487         }
488
489         if ((rc = enop->eno_init(enp)) != 0)
490                 goto fail2;
491
492         enp->en_mod_flags |= EFX_MOD_NIC;
493
494         return (0);
495
496 fail2:
497         EFSYS_PROBE(fail2);
498 fail1:
499         EFSYS_PROBE1(fail1, efx_rc_t, rc);
500
501         return (rc);
502 }
503
504                         void
505 efx_nic_fini(
506         __in            efx_nic_t *enp)
507 {
508         const efx_nic_ops_t *enop = enp->en_enop;
509
510         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
511         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
512         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC);
513         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
514         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
515         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
516         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
517
518         enop->eno_fini(enp);
519
520         enp->en_mod_flags &= ~EFX_MOD_NIC;
521 }
522
523                         void
524 efx_nic_unprobe(
525         __in            efx_nic_t *enp)
526 {
527         const efx_nic_ops_t *enop = enp->en_enop;
528
529         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
530 #if EFSYS_OPT_MCDI
531         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
532 #endif  /* EFSYS_OPT_MCDI */
533         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
534         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
535         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
536         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
537         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
538         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
539
540         efx_phy_unprobe(enp);
541
542         enop->eno_unprobe(enp);
543
544         enp->en_mod_flags &= ~EFX_MOD_PROBE;
545 }
546
547                         void
548 efx_nic_destroy(
549         __in    efx_nic_t *enp)
550 {
551         efsys_identifier_t *esip = enp->en_esip;
552
553         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
554         EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
555
556         enp->en_family = EFX_FAMILY_INVALID;
557         enp->en_esip = NULL;
558         enp->en_esbp = NULL;
559         enp->en_eslp = NULL;
560
561         enp->en_enop = NULL;
562
563         enp->en_magic = 0;
564
565         /* Free the NIC object */
566         EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
567 }
568
569         __checkReturn   efx_rc_t
570 efx_nic_reset(
571         __in            efx_nic_t *enp)
572 {
573         const efx_nic_ops_t *enop = enp->en_enop;
574         unsigned int mod_flags;
575         efx_rc_t rc;
576
577         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
578         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
579         /*
580          * All modules except the MCDI, PROBE, NVRAM, VPD, MON
581          * (which we do not reset here) must have been shut down or never
582          * initialized.
583          *
584          * A rule of thumb here is: If the controller or MC reboots, is *any*
585          * state lost. If it's lost and needs reapplying, then the module
586          * *must* not be initialised during the reset.
587          */
588         mod_flags = enp->en_mod_flags;
589         mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
590                     EFX_MOD_VPD | EFX_MOD_MON);
591         EFSYS_ASSERT3U(mod_flags, ==, 0);
592         if (mod_flags != 0) {
593                 rc = EINVAL;
594                 goto fail1;
595         }
596
597         if ((rc = enop->eno_reset(enp)) != 0)
598                 goto fail2;
599
600         return (0);
601
602 fail2:
603         EFSYS_PROBE(fail2);
604 fail1:
605         EFSYS_PROBE1(fail1, efx_rc_t, rc);
606
607         return (rc);
608 }
609
610                         const efx_nic_cfg_t *
611 efx_nic_cfg_get(
612         __in            efx_nic_t *enp)
613 {
614         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
615
616         return (&(enp->en_nic_cfg));
617 }
618
619 #if EFSYS_OPT_DIAG
620
621         __checkReturn   efx_rc_t
622 efx_nic_register_test(
623         __in            efx_nic_t *enp)
624 {
625         const efx_nic_ops_t *enop = enp->en_enop;
626         efx_rc_t rc;
627
628         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
629         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
630         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
631
632         if ((rc = enop->eno_register_test(enp)) != 0)
633                 goto fail1;
634
635         return (0);
636
637 fail1:
638         EFSYS_PROBE1(fail1, efx_rc_t, rc);
639
640         return (rc);
641 }
642
643         __checkReturn   efx_rc_t
644 efx_nic_test_registers(
645         __in            efx_nic_t *enp,
646         __in            efx_register_set_t *rsp,
647         __in            size_t count)
648 {
649         unsigned int bit;
650         efx_oword_t original;
651         efx_oword_t reg;
652         efx_oword_t buf;
653         efx_rc_t rc;
654
655         while (count > 0) {
656                 /* This function is only suitable for registers */
657                 EFSYS_ASSERT(rsp->rows == 1);
658
659                 /* bit sweep on and off */
660                 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
661                             B_TRUE);
662                 for (bit = 0; bit < 128; bit++) {
663                         /* Is this bit in the mask? */
664                         if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
665                                 continue;
666
667                         /* Test this bit can be set in isolation */
668                         reg = original;
669                         EFX_AND_OWORD(reg, rsp->mask);
670                         EFX_SET_OWORD_BIT(reg, bit);
671
672                         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
673                                     B_TRUE);
674                         EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
675                                     B_TRUE);
676
677                         EFX_AND_OWORD(buf, rsp->mask);
678                         if (memcmp(&reg, &buf, sizeof (reg))) {
679                                 rc = EIO;
680                                 goto fail1;
681                         }
682
683                         /* Test this bit can be cleared in isolation */
684                         EFX_OR_OWORD(reg, rsp->mask);
685                         EFX_CLEAR_OWORD_BIT(reg, bit);
686
687                         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
688                                     B_TRUE);
689                         EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
690                                     B_TRUE);
691
692                         EFX_AND_OWORD(buf, rsp->mask);
693                         if (memcmp(&reg, &buf, sizeof (reg))) {
694                                 rc = EIO;
695                                 goto fail2;
696                         }
697                 }
698
699                 /* Restore the old value */
700                 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
701                             B_TRUE);
702
703                 --count;
704                 ++rsp;
705         }
706
707         return (0);
708
709 fail2:
710         EFSYS_PROBE(fail2);
711 fail1:
712         EFSYS_PROBE1(fail1, efx_rc_t, rc);
713
714         /* Restore the old value */
715         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
716
717         return (rc);
718 }
719
720         __checkReturn   efx_rc_t
721 efx_nic_test_tables(
722         __in            efx_nic_t *enp,
723         __in            efx_register_set_t *rsp,
724         __in            efx_pattern_type_t pattern,
725         __in            size_t count)
726 {
727         efx_sram_pattern_fn_t func;
728         unsigned int index;
729         unsigned int address;
730         efx_oword_t reg;
731         efx_oword_t buf;
732         efx_rc_t rc;
733
734         EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
735         func = __efx_sram_pattern_fns[pattern];
736
737         while (count > 0) {
738                 /* Write */
739                 address = rsp->address;
740                 for (index = 0; index < rsp->rows; ++index) {
741                         func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
742                         func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
743                         EFX_AND_OWORD(reg, rsp->mask);
744                         EFSYS_BAR_WRITEO(enp->en_esbp, address, &reg, B_TRUE);
745
746                         address += rsp->step;
747                 }
748
749                 /* Read */
750                 address = rsp->address;
751                 for (index = 0; index < rsp->rows; ++index) {
752                         func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
753                         func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
754                         EFX_AND_OWORD(reg, rsp->mask);
755                         EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
756                         if (memcmp(&reg, &buf, sizeof (reg))) {
757                                 rc = EIO;
758                                 goto fail1;
759                         }
760
761                         address += rsp->step;
762                 }
763
764                 ++rsp;
765                 --count;
766         }
767
768         return (0);
769
770 fail1:
771         EFSYS_PROBE1(fail1, efx_rc_t, rc);
772
773         return (rc);
774 }
775
776 #endif  /* EFSYS_OPT_DIAG */
777
778         __checkReturn   efx_rc_t
779 efx_nic_calculate_pcie_link_bandwidth(
780         __in            uint32_t pcie_link_width,
781         __in            uint32_t pcie_link_gen,
782         __out           uint32_t *bandwidth_mbpsp)
783 {
784         uint32_t lane_bandwidth;
785         uint32_t total_bandwidth;
786         efx_rc_t rc;
787
788         if ((pcie_link_width == 0) || (pcie_link_width > 16) ||
789             !ISP2(pcie_link_width)) {
790                 rc = EINVAL;
791                 goto fail1;
792         }
793
794         switch (pcie_link_gen) {
795         case EFX_PCIE_LINK_SPEED_GEN1:
796                 /* 2.5 Gb/s raw bandwidth with 8b/10b encoding */
797                 lane_bandwidth = 2000;
798                 break;
799         case EFX_PCIE_LINK_SPEED_GEN2:
800                 /* 5.0 Gb/s raw bandwidth with 8b/10b encoding */
801                 lane_bandwidth = 4000;
802                 break;
803         case EFX_PCIE_LINK_SPEED_GEN3:
804                 /* 8.0 Gb/s raw bandwidth with 128b/130b encoding */
805                 lane_bandwidth = 7877;
806                 break;
807         default:
808                 rc = EINVAL;
809                 goto fail2;
810         }
811
812         total_bandwidth = lane_bandwidth * pcie_link_width;
813         *bandwidth_mbpsp = total_bandwidth;
814
815         return (0);
816
817 fail2:
818         EFSYS_PROBE(fail2);
819 fail1:
820         EFSYS_PROBE1(fail1, efx_rc_t, rc);
821
822         return (rc);
823 }
824
825
826         __checkReturn   efx_rc_t
827 efx_nic_check_pcie_link_speed(
828         __in            efx_nic_t *enp,
829         __in            uint32_t pcie_link_width,
830         __in            uint32_t pcie_link_gen,
831         __out           efx_pcie_link_performance_t *resultp)
832 {
833         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
834         uint32_t bandwidth;
835         efx_pcie_link_performance_t result;
836         efx_rc_t rc;
837
838         if ((encp->enc_required_pcie_bandwidth_mbps == 0) ||
839             (pcie_link_width == 0) || (pcie_link_width == 32) ||
840             (pcie_link_gen == 0)) {
841                 /*
842                  * No usable info on what is required and/or in use. In virtual
843                  * machines, sometimes the PCIe link width is reported as 0 or
844                  * 32, or the speed as 0.
845                  */
846                 result = EFX_PCIE_LINK_PERFORMANCE_UNKNOWN_BANDWIDTH;
847                 goto out;
848         }
849
850         /* Calculate the available bandwidth in megabits per second */
851         rc = efx_nic_calculate_pcie_link_bandwidth(pcie_link_width,
852                                             pcie_link_gen, &bandwidth);
853         if (rc != 0)
854                 goto fail1;
855
856         if (bandwidth < encp->enc_required_pcie_bandwidth_mbps) {
857                 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_BANDWIDTH;
858         } else if (pcie_link_gen < encp->enc_max_pcie_link_gen) {
859                 /* The link provides enough bandwidth but not optimal latency */
860                 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_LATENCY;
861         } else {
862                 result = EFX_PCIE_LINK_PERFORMANCE_OPTIMAL;
863         }
864
865 out:
866         *resultp = result;
867
868         return (0);
869
870 fail1:
871         EFSYS_PROBE1(fail1, efx_rc_t, rc);
872
873         return (rc);
874 }