4a31bca438fe95aa8eb06078b038652dd8acd64f
[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 #if EFSYS_OPT_SIENA
106
107 static const efx_nic_ops_t      __efx_nic_siena_ops = {
108         siena_nic_probe,                /* eno_probe */
109         NULL,                           /* eno_board_cfg */
110         NULL,                           /* eno_set_drv_limits */
111         siena_nic_reset,                /* eno_reset */
112         siena_nic_init,                 /* eno_init */
113         NULL,                           /* eno_get_vi_pool */
114         NULL,                           /* eno_get_bar_region */
115 #if EFSYS_OPT_DIAG
116         siena_nic_register_test,        /* eno_register_test */
117 #endif  /* EFSYS_OPT_DIAG */
118         siena_nic_fini,                 /* eno_fini */
119         siena_nic_unprobe,              /* eno_unprobe */
120 };
121
122 #endif  /* EFSYS_OPT_SIENA */
123
124 #if EFSYS_OPT_HUNTINGTON
125
126 static const efx_nic_ops_t      __efx_nic_hunt_ops = {
127         ef10_nic_probe,                 /* eno_probe */
128         hunt_board_cfg,                 /* eno_board_cfg */
129         ef10_nic_set_drv_limits,        /* eno_set_drv_limits */
130         ef10_nic_reset,                 /* eno_reset */
131         ef10_nic_init,                  /* eno_init */
132         ef10_nic_get_vi_pool,           /* eno_get_vi_pool */
133         ef10_nic_get_bar_region,        /* eno_get_bar_region */
134 #if EFSYS_OPT_DIAG
135         ef10_nic_register_test,         /* eno_register_test */
136 #endif  /* EFSYS_OPT_DIAG */
137         ef10_nic_fini,                  /* eno_fini */
138         ef10_nic_unprobe,               /* eno_unprobe */
139 };
140
141 #endif  /* EFSYS_OPT_HUNTINGTON */
142
143 #if EFSYS_OPT_MEDFORD
144
145 static const efx_nic_ops_t      __efx_nic_medford_ops = {
146         ef10_nic_probe,                 /* eno_probe */
147         medford_board_cfg,              /* eno_board_cfg */
148         ef10_nic_set_drv_limits,        /* eno_set_drv_limits */
149         ef10_nic_reset,                 /* eno_reset */
150         ef10_nic_init,                  /* eno_init */
151         ef10_nic_get_vi_pool,           /* eno_get_vi_pool */
152         ef10_nic_get_bar_region,        /* eno_get_bar_region */
153 #if EFSYS_OPT_DIAG
154         ef10_nic_register_test,         /* eno_register_test */
155 #endif  /* EFSYS_OPT_DIAG */
156         ef10_nic_fini,                  /* eno_fini */
157         ef10_nic_unprobe,               /* eno_unprobe */
158 };
159
160 #endif  /* EFSYS_OPT_MEDFORD */
161
162
163         __checkReturn   efx_rc_t
164 efx_nic_create(
165         __in            efx_family_t family,
166         __in            efsys_identifier_t *esip,
167         __in            efsys_bar_t *esbp,
168         __in            efsys_lock_t *eslp,
169         __deref_out     efx_nic_t **enpp)
170 {
171         efx_nic_t *enp;
172         efx_rc_t rc;
173
174         EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID);
175         EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES);
176
177         /* Allocate a NIC object */
178         EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp);
179
180         if (enp == NULL) {
181                 rc = ENOMEM;
182                 goto fail1;
183         }
184
185         enp->en_magic = EFX_NIC_MAGIC;
186
187         switch (family) {
188 #if EFSYS_OPT_SIENA
189         case EFX_FAMILY_SIENA:
190                 enp->en_enop = &__efx_nic_siena_ops;
191                 enp->en_features =
192                     EFX_FEATURE_IPV6 |
193                     EFX_FEATURE_LFSR_HASH_INSERT |
194                     EFX_FEATURE_LINK_EVENTS |
195                     EFX_FEATURE_PERIODIC_MAC_STATS |
196                     EFX_FEATURE_MCDI |
197                     EFX_FEATURE_LOOKAHEAD_SPLIT |
198                     EFX_FEATURE_MAC_HEADER_FILTERS |
199                     EFX_FEATURE_TX_SRC_FILTERS;
200                 break;
201 #endif  /* EFSYS_OPT_SIENA */
202
203 #if EFSYS_OPT_HUNTINGTON
204         case EFX_FAMILY_HUNTINGTON:
205                 enp->en_enop = &__efx_nic_hunt_ops;
206                 enp->en_features =
207                     EFX_FEATURE_IPV6 |
208                     EFX_FEATURE_LINK_EVENTS |
209                     EFX_FEATURE_PERIODIC_MAC_STATS |
210                     EFX_FEATURE_MCDI |
211                     EFX_FEATURE_MAC_HEADER_FILTERS |
212                     EFX_FEATURE_MCDI_DMA |
213                     EFX_FEATURE_PIO_BUFFERS |
214                     EFX_FEATURE_FW_ASSISTED_TSO |
215                     EFX_FEATURE_FW_ASSISTED_TSO_V2 |
216                     EFX_FEATURE_PACKED_STREAM;
217                 break;
218 #endif  /* EFSYS_OPT_HUNTINGTON */
219
220 #if EFSYS_OPT_MEDFORD
221         case EFX_FAMILY_MEDFORD:
222                 enp->en_enop = &__efx_nic_medford_ops;
223                 /*
224                  * FW_ASSISTED_TSO omitted as Medford only supports firmware
225                  * assisted TSO version 2, not the v1 scheme used on Huntington.
226                  */
227                 enp->en_features =
228                     EFX_FEATURE_IPV6 |
229                     EFX_FEATURE_LINK_EVENTS |
230                     EFX_FEATURE_PERIODIC_MAC_STATS |
231                     EFX_FEATURE_MCDI |
232                     EFX_FEATURE_MAC_HEADER_FILTERS |
233                     EFX_FEATURE_MCDI_DMA |
234                     EFX_FEATURE_PIO_BUFFERS |
235                     EFX_FEATURE_FW_ASSISTED_TSO_V2 |
236                     EFX_FEATURE_PACKED_STREAM;
237                 break;
238 #endif  /* EFSYS_OPT_MEDFORD */
239
240         default:
241                 rc = ENOTSUP;
242                 goto fail2;
243         }
244
245         enp->en_family = family;
246         enp->en_esip = esip;
247         enp->en_esbp = esbp;
248         enp->en_eslp = eslp;
249
250         *enpp = enp;
251
252         return (0);
253
254 fail2:
255         EFSYS_PROBE(fail2);
256
257         enp->en_magic = 0;
258
259         /* Free the NIC object */
260         EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
261
262 fail1:
263         EFSYS_PROBE1(fail1, efx_rc_t, rc);
264
265         return (rc);
266 }
267
268         __checkReturn   efx_rc_t
269 efx_nic_probe(
270         __in            efx_nic_t *enp)
271 {
272         const efx_nic_ops_t *enop;
273         efx_rc_t rc;
274
275         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
276 #if EFSYS_OPT_MCDI
277         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
278 #endif  /* EFSYS_OPT_MCDI */
279         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
280
281         enop = enp->en_enop;
282         if ((rc = enop->eno_probe(enp)) != 0)
283                 goto fail1;
284
285         if ((rc = efx_phy_probe(enp)) != 0)
286                 goto fail2;
287
288         enp->en_mod_flags |= EFX_MOD_PROBE;
289
290         return (0);
291
292 fail2:
293         EFSYS_PROBE(fail2);
294
295         enop->eno_unprobe(enp);
296
297 fail1:
298         EFSYS_PROBE1(fail1, efx_rc_t, rc);
299
300         return (rc);
301 }
302
303         __checkReturn   efx_rc_t
304 efx_nic_set_drv_limits(
305         __inout         efx_nic_t *enp,
306         __in            efx_drv_limits_t *edlp)
307 {
308         const efx_nic_ops_t *enop = enp->en_enop;
309         efx_rc_t rc;
310
311         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
312         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
313
314         if (enop->eno_set_drv_limits != NULL) {
315                 if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
316                         goto fail1;
317         }
318
319         return (0);
320
321 fail1:
322         EFSYS_PROBE1(fail1, efx_rc_t, rc);
323
324         return (rc);
325 }
326
327         __checkReturn   efx_rc_t
328 efx_nic_get_bar_region(
329         __in            efx_nic_t *enp,
330         __in            efx_nic_region_t region,
331         __out           uint32_t *offsetp,
332         __out           size_t *sizep)
333 {
334         const efx_nic_ops_t *enop = enp->en_enop;
335         efx_rc_t rc;
336
337         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
338         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
339         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
340
341         if (enop->eno_get_bar_region == NULL) {
342                 rc = ENOTSUP;
343                 goto fail1;
344         }
345         if ((rc = (enop->eno_get_bar_region)(enp,
346                     region, offsetp, sizep)) != 0) {
347                 goto fail2;
348         }
349
350         return (0);
351
352 fail2:
353         EFSYS_PROBE(fail2);
354
355 fail1:
356         EFSYS_PROBE1(fail1, efx_rc_t, rc);
357
358         return (rc);
359 }
360
361
362         __checkReturn   efx_rc_t
363 efx_nic_get_vi_pool(
364         __in            efx_nic_t *enp,
365         __out           uint32_t *evq_countp,
366         __out           uint32_t *rxq_countp,
367         __out           uint32_t *txq_countp)
368 {
369         const efx_nic_ops_t *enop = enp->en_enop;
370         efx_nic_cfg_t *encp = &enp->en_nic_cfg;
371         efx_rc_t rc;
372
373         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
374         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
375         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
376
377         if (enop->eno_get_vi_pool != NULL) {
378                 uint32_t vi_count = 0;
379
380                 if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
381                         goto fail1;
382
383                 *evq_countp = vi_count;
384                 *rxq_countp = vi_count;
385                 *txq_countp = vi_count;
386         } else {
387                 /* Use NIC limits as default value */
388                 *evq_countp = encp->enc_evq_limit;
389                 *rxq_countp = encp->enc_rxq_limit;
390                 *txq_countp = encp->enc_txq_limit;
391         }
392
393         return (0);
394
395 fail1:
396         EFSYS_PROBE1(fail1, efx_rc_t, rc);
397
398         return (rc);
399 }
400
401
402         __checkReturn   efx_rc_t
403 efx_nic_init(
404         __in            efx_nic_t *enp)
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
412         if (enp->en_mod_flags & EFX_MOD_NIC) {
413                 rc = EINVAL;
414                 goto fail1;
415         }
416
417         if ((rc = enop->eno_init(enp)) != 0)
418                 goto fail2;
419
420         enp->en_mod_flags |= EFX_MOD_NIC;
421
422         return (0);
423
424 fail2:
425         EFSYS_PROBE(fail2);
426 fail1:
427         EFSYS_PROBE1(fail1, efx_rc_t, rc);
428
429         return (rc);
430 }
431
432                         void
433 efx_nic_fini(
434         __in            efx_nic_t *enp)
435 {
436         const efx_nic_ops_t *enop = enp->en_enop;
437
438         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
439         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
440         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC);
441         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
442         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
443         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
444         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
445
446         enop->eno_fini(enp);
447
448         enp->en_mod_flags &= ~EFX_MOD_NIC;
449 }
450
451                         void
452 efx_nic_unprobe(
453         __in            efx_nic_t *enp)
454 {
455         const efx_nic_ops_t *enop = enp->en_enop;
456
457         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
458 #if EFSYS_OPT_MCDI
459         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
460 #endif  /* EFSYS_OPT_MCDI */
461         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
462         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
463         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
464         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
465         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
466         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
467
468         efx_phy_unprobe(enp);
469
470         enop->eno_unprobe(enp);
471
472         enp->en_mod_flags &= ~EFX_MOD_PROBE;
473 }
474
475                         void
476 efx_nic_destroy(
477         __in    efx_nic_t *enp)
478 {
479         efsys_identifier_t *esip = enp->en_esip;
480
481         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
482         EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
483
484         enp->en_family = EFX_FAMILY_INVALID;
485         enp->en_esip = NULL;
486         enp->en_esbp = NULL;
487         enp->en_eslp = NULL;
488
489         enp->en_enop = NULL;
490
491         enp->en_magic = 0;
492
493         /* Free the NIC object */
494         EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
495 }
496
497         __checkReturn   efx_rc_t
498 efx_nic_reset(
499         __in            efx_nic_t *enp)
500 {
501         const efx_nic_ops_t *enop = enp->en_enop;
502         unsigned int mod_flags;
503         efx_rc_t rc;
504
505         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
506         EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
507         /*
508          * All modules except the MCDI, PROBE, NVRAM, VPD, MON
509          * (which we do not reset here) must have been shut down or never
510          * initialized.
511          *
512          * A rule of thumb here is: If the controller or MC reboots, is *any*
513          * state lost. If it's lost and needs reapplying, then the module
514          * *must* not be initialised during the reset.
515          */
516         mod_flags = enp->en_mod_flags;
517         mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
518                     EFX_MOD_VPD | EFX_MOD_MON);
519         EFSYS_ASSERT3U(mod_flags, ==, 0);
520         if (mod_flags != 0) {
521                 rc = EINVAL;
522                 goto fail1;
523         }
524
525         if ((rc = enop->eno_reset(enp)) != 0)
526                 goto fail2;
527
528         return (0);
529
530 fail2:
531         EFSYS_PROBE(fail2);
532 fail1:
533         EFSYS_PROBE1(fail1, efx_rc_t, rc);
534
535         return (rc);
536 }
537
538                         const efx_nic_cfg_t *
539 efx_nic_cfg_get(
540         __in            efx_nic_t *enp)
541 {
542         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
543
544         return (&(enp->en_nic_cfg));
545 }
546
547         __checkReturn           efx_rc_t
548 efx_nic_get_fw_version(
549         __in                    efx_nic_t *enp,
550         __out                   efx_nic_fw_info_t *enfip)
551 {
552         uint16_t mc_fw_version[4];
553         efx_rc_t rc;
554
555         if (enfip == NULL) {
556                 rc = EINVAL;
557                 goto fail1;
558         }
559
560         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
561         EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
562
563         rc = efx_mcdi_version(enp, mc_fw_version, NULL, NULL);
564         if (rc != 0)
565                 goto fail2;
566
567         rc = efx_mcdi_get_capabilities(enp, NULL,
568             &enfip->enfi_rx_dpcpu_fw_id,
569             &enfip->enfi_tx_dpcpu_fw_id,
570             NULL, NULL);
571         if (rc == 0) {
572                 enfip->enfi_dpcpu_fw_ids_valid = B_TRUE;
573         } else if (rc == ENOTSUP) {
574                 enfip->enfi_dpcpu_fw_ids_valid = B_FALSE;
575                 enfip->enfi_rx_dpcpu_fw_id = 0;
576                 enfip->enfi_tx_dpcpu_fw_id = 0;
577         } else {
578                 goto fail3;
579         }
580
581         memcpy(enfip->enfi_mc_fw_version, mc_fw_version,
582             sizeof (mc_fw_version));
583
584         return (0);
585
586 fail3:
587         EFSYS_PROBE(fail3);
588 fail2:
589         EFSYS_PROBE(fail2);
590 fail1:
591         EFSYS_PROBE1(fail1, efx_rc_t, rc);
592
593         return (rc);
594 }
595
596 #if EFSYS_OPT_DIAG
597
598         __checkReturn   efx_rc_t
599 efx_nic_register_test(
600         __in            efx_nic_t *enp)
601 {
602         const efx_nic_ops_t *enop = enp->en_enop;
603         efx_rc_t rc;
604
605         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
606         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
607         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
608
609         if ((rc = enop->eno_register_test(enp)) != 0)
610                 goto fail1;
611
612         return (0);
613
614 fail1:
615         EFSYS_PROBE1(fail1, efx_rc_t, rc);
616
617         return (rc);
618 }
619
620 #endif  /* EFSYS_OPT_DIAG */
621
622 #if EFSYS_OPT_LOOPBACK
623
624 extern                  void
625 efx_loopback_mask(
626         __in    efx_loopback_kind_t loopback_kind,
627         __out   efx_qword_t *maskp)
628 {
629         efx_qword_t mask;
630
631         EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS);
632         EFSYS_ASSERT(maskp != NULL);
633
634         /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
635         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
636         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
637         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
638         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
639         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
640         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
641         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
642         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
643         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
644         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
645         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
646         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
647         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
648         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
649         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
650         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
651         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
652         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
653         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT);
654         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS);
655         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS);
656         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR ==
657             EFX_LOOPBACK_XAUI_WS_FAR);
658         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR ==
659             EFX_LOOPBACK_XAUI_WS_NEAR);
660         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS);
661         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS);
662         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR ==
663             EFX_LOOPBACK_XFI_WS_FAR);
664         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS);
665         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT);
666         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR);
667         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR);
668         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS ==
669             EFX_LOOPBACK_PMA_INT_WS);
670         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS ==
671             EFX_LOOPBACK_SD_FEP2_WS);
672         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS ==
673             EFX_LOOPBACK_SD_FEP1_5_WS);
674         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS);
675         EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS);
676
677         /* Build bitmask of possible loopback types */
678         EFX_ZERO_QWORD(mask);
679
680         if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) ||
681             (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
682                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF);
683         }
684
685         if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) ||
686             (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
687                 /*
688                  * The "MAC" grouping has historically been used by drivers to
689                  * mean loopbacks supported by on-chip hardware. Keep that
690                  * meaning here, and include on-chip PHY layer loopbacks.
691                  */
692                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA);
693                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC);
694                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII);
695                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS);
696                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI);
697                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII);
698                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII);
699                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR);
700                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI);
701                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR);
702                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR);
703                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR);
704                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR);
705                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT);
706                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR);
707                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR);
708         }
709
710         if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) ||
711             (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
712                 /*
713                  * The "PHY" grouping has historically been used by drivers to
714                  * mean loopbacks supported by off-chip hardware. Keep that
715                  * meaning here.
716                  */
717                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY);
718                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PHY_XS);
719                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS);
720                 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD);
721         }
722
723         *maskp = mask;
724 }
725
726         __checkReturn   efx_rc_t
727 efx_mcdi_get_loopback_modes(
728         __in            efx_nic_t *enp)
729 {
730         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
731         efx_mcdi_req_t req;
732         uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
733                             MC_CMD_GET_LOOPBACK_MODES_OUT_LEN)];
734         efx_qword_t mask;
735         efx_qword_t modes;
736         efx_rc_t rc;
737
738         (void) memset(payload, 0, sizeof (payload));
739         req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
740         req.emr_in_buf = payload;
741         req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
742         req.emr_out_buf = payload;
743         req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN;
744
745         efx_mcdi_execute(enp, &req);
746
747         if (req.emr_rc != 0) {
748                 rc = req.emr_rc;
749                 goto fail1;
750         }
751
752         if (req.emr_out_length_used <
753             MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
754             MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) {
755                 rc = EMSGSIZE;
756                 goto fail2;
757         }
758
759         /*
760          * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
761          * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link().
762          */
763         efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask);
764
765         EFX_AND_QWORD(mask,
766             *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED));
767
768         modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M);
769         EFX_AND_QWORD(modes, mask);
770         encp->enc_loopback_types[EFX_LINK_100FDX] = modes;
771
772         modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G);
773         EFX_AND_QWORD(modes, mask);
774         encp->enc_loopback_types[EFX_LINK_1000FDX] = modes;
775
776         modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G);
777         EFX_AND_QWORD(modes, mask);
778         encp->enc_loopback_types[EFX_LINK_10000FDX] = modes;
779
780         if (req.emr_out_length_used >=
781             MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
782             MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
783                 /* Response includes 40G loopback modes */
784                 modes =
785                     *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G);
786                 EFX_AND_QWORD(modes, mask);
787                 encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
788         }
789
790         EFX_ZERO_QWORD(modes);
791         EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
792         EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
793         EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
794         EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
795         EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
796         encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
797
798         return (0);
799
800 fail2:
801         EFSYS_PROBE(fail2);
802 fail1:
803         EFSYS_PROBE1(fail1, efx_rc_t, rc);
804
805         return (rc);
806 }
807
808 #endif /* EFSYS_OPT_LOOPBACK */
809
810         __checkReturn   efx_rc_t
811 efx_nic_calculate_pcie_link_bandwidth(
812         __in            uint32_t pcie_link_width,
813         __in            uint32_t pcie_link_gen,
814         __out           uint32_t *bandwidth_mbpsp)
815 {
816         uint32_t lane_bandwidth;
817         uint32_t total_bandwidth;
818         efx_rc_t rc;
819
820         if ((pcie_link_width == 0) || (pcie_link_width > 16) ||
821             !ISP2(pcie_link_width)) {
822                 rc = EINVAL;
823                 goto fail1;
824         }
825
826         switch (pcie_link_gen) {
827         case EFX_PCIE_LINK_SPEED_GEN1:
828                 /* 2.5 Gb/s raw bandwidth with 8b/10b encoding */
829                 lane_bandwidth = 2000;
830                 break;
831         case EFX_PCIE_LINK_SPEED_GEN2:
832                 /* 5.0 Gb/s raw bandwidth with 8b/10b encoding */
833                 lane_bandwidth = 4000;
834                 break;
835         case EFX_PCIE_LINK_SPEED_GEN3:
836                 /* 8.0 Gb/s raw bandwidth with 128b/130b encoding */
837                 lane_bandwidth = 7877;
838                 break;
839         default:
840                 rc = EINVAL;
841                 goto fail2;
842         }
843
844         total_bandwidth = lane_bandwidth * pcie_link_width;
845         *bandwidth_mbpsp = total_bandwidth;
846
847         return (0);
848
849 fail2:
850         EFSYS_PROBE(fail2);
851 fail1:
852         EFSYS_PROBE1(fail1, efx_rc_t, rc);
853
854         return (rc);
855 }
856
857
858         __checkReturn   efx_rc_t
859 efx_nic_check_pcie_link_speed(
860         __in            efx_nic_t *enp,
861         __in            uint32_t pcie_link_width,
862         __in            uint32_t pcie_link_gen,
863         __out           efx_pcie_link_performance_t *resultp)
864 {
865         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
866         uint32_t bandwidth;
867         efx_pcie_link_performance_t result;
868         efx_rc_t rc;
869
870         if ((encp->enc_required_pcie_bandwidth_mbps == 0) ||
871             (pcie_link_width == 0) || (pcie_link_width == 32) ||
872             (pcie_link_gen == 0)) {
873                 /*
874                  * No usable info on what is required and/or in use. In virtual
875                  * machines, sometimes the PCIe link width is reported as 0 or
876                  * 32, or the speed as 0.
877                  */
878                 result = EFX_PCIE_LINK_PERFORMANCE_UNKNOWN_BANDWIDTH;
879                 goto out;
880         }
881
882         /* Calculate the available bandwidth in megabits per second */
883         rc = efx_nic_calculate_pcie_link_bandwidth(pcie_link_width,
884                                             pcie_link_gen, &bandwidth);
885         if (rc != 0)
886                 goto fail1;
887
888         if (bandwidth < encp->enc_required_pcie_bandwidth_mbps) {
889                 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_BANDWIDTH;
890         } else if (pcie_link_gen < encp->enc_max_pcie_link_gen) {
891                 /* The link provides enough bandwidth but not optimal latency */
892                 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_LATENCY;
893         } else {
894                 result = EFX_PCIE_LINK_PERFORMANCE_OPTIMAL;
895         }
896
897 out:
898         *resultp = result;
899
900         return (0);
901
902 fail1:
903         EFSYS_PROBE1(fail1, efx_rc_t, rc);
904
905         return (rc);
906 }