2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2007-2016 Solarflare Communications Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * The views and conclusions contained in the software and documentation are
29 * those of the authors and should not be interpreted as representing official
30 * policies, either expressed or implied, of the FreeBSD Project.
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
40 __checkReturn efx_rc_t
44 __out efx_family_t *efp,
45 __out unsigned int *membarp)
47 if (venid == EFX_PCI_VENID_SFC) {
50 case EFX_PCI_DEVID_SIENA_F1_UNINIT:
52 * Hardware default for PF0 of uninitialised Siena.
53 * manftest must be able to cope with this device id.
55 case EFX_PCI_DEVID_BETHPAGE:
56 case EFX_PCI_DEVID_SIENA:
57 *efp = EFX_FAMILY_SIENA;
58 *membarp = EFX_MEM_BAR_SIENA;
60 #endif /* EFSYS_OPT_SIENA */
62 #if EFSYS_OPT_HUNTINGTON
63 case EFX_PCI_DEVID_HUNTINGTON_PF_UNINIT:
65 * Hardware default for PF0 of uninitialised Huntington.
66 * manftest must be able to cope with this device id.
68 case EFX_PCI_DEVID_FARMINGDALE:
69 case EFX_PCI_DEVID_GREENPORT:
70 *efp = EFX_FAMILY_HUNTINGTON;
71 *membarp = EFX_MEM_BAR_HUNTINGTON_PF;
74 case EFX_PCI_DEVID_FARMINGDALE_VF:
75 case EFX_PCI_DEVID_GREENPORT_VF:
76 *efp = EFX_FAMILY_HUNTINGTON;
77 *membarp = EFX_MEM_BAR_HUNTINGTON_VF;
79 #endif /* EFSYS_OPT_HUNTINGTON */
82 case EFX_PCI_DEVID_MEDFORD_PF_UNINIT:
84 * Hardware default for PF0 of uninitialised Medford.
85 * manftest must be able to cope with this device id.
87 case EFX_PCI_DEVID_MEDFORD:
88 *efp = EFX_FAMILY_MEDFORD;
89 *membarp = EFX_MEM_BAR_MEDFORD_PF;
92 case EFX_PCI_DEVID_MEDFORD_VF:
93 *efp = EFX_FAMILY_MEDFORD;
94 *membarp = EFX_MEM_BAR_MEDFORD_VF;
96 #endif /* EFSYS_OPT_MEDFORD */
98 #if EFSYS_OPT_MEDFORD2
99 case EFX_PCI_DEVID_MEDFORD2_PF_UNINIT:
101 * Hardware default for PF0 of uninitialised Medford2.
102 * manftest must be able to cope with this device id.
104 case EFX_PCI_DEVID_MEDFORD2:
105 case EFX_PCI_DEVID_MEDFORD2_VF:
106 *efp = EFX_FAMILY_MEDFORD2;
107 *membarp = EFX_MEM_BAR_MEDFORD2;
109 #endif /* EFSYS_OPT_MEDFORD2 */
111 case EFX_PCI_DEVID_FALCON: /* Obsolete, not supported */
117 *efp = EFX_FAMILY_INVALID;
124 static const efx_nic_ops_t __efx_nic_siena_ops = {
125 siena_nic_probe, /* eno_probe */
126 NULL, /* eno_board_cfg */
127 NULL, /* eno_set_drv_limits */
128 siena_nic_reset, /* eno_reset */
129 siena_nic_init, /* eno_init */
130 NULL, /* eno_get_vi_pool */
131 NULL, /* eno_get_bar_region */
132 NULL, /* eno_hw_unavailable */
133 NULL, /* eno_set_hw_unavailable */
135 siena_nic_register_test, /* eno_register_test */
136 #endif /* EFSYS_OPT_DIAG */
137 siena_nic_fini, /* eno_fini */
138 siena_nic_unprobe, /* eno_unprobe */
141 #endif /* EFSYS_OPT_SIENA */
143 #if EFSYS_OPT_HUNTINGTON
145 static const efx_nic_ops_t __efx_nic_hunt_ops = {
146 ef10_nic_probe, /* eno_probe */
147 hunt_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 ef10_nic_hw_unavailable, /* eno_hw_unavailable */
154 ef10_nic_set_hw_unavailable, /* eno_set_hw_unavailable */
156 ef10_nic_register_test, /* eno_register_test */
157 #endif /* EFSYS_OPT_DIAG */
158 ef10_nic_fini, /* eno_fini */
159 ef10_nic_unprobe, /* eno_unprobe */
162 #endif /* EFSYS_OPT_HUNTINGTON */
164 #if EFSYS_OPT_MEDFORD
166 static const efx_nic_ops_t __efx_nic_medford_ops = {
167 ef10_nic_probe, /* eno_probe */
168 medford_board_cfg, /* eno_board_cfg */
169 ef10_nic_set_drv_limits, /* eno_set_drv_limits */
170 ef10_nic_reset, /* eno_reset */
171 ef10_nic_init, /* eno_init */
172 ef10_nic_get_vi_pool, /* eno_get_vi_pool */
173 ef10_nic_get_bar_region, /* eno_get_bar_region */
174 ef10_nic_hw_unavailable, /* eno_hw_unavailable */
175 ef10_nic_set_hw_unavailable, /* eno_set_hw_unavailable */
177 ef10_nic_register_test, /* eno_register_test */
178 #endif /* EFSYS_OPT_DIAG */
179 ef10_nic_fini, /* eno_fini */
180 ef10_nic_unprobe, /* eno_unprobe */
183 #endif /* EFSYS_OPT_MEDFORD */
185 #if EFSYS_OPT_MEDFORD2
187 static const efx_nic_ops_t __efx_nic_medford2_ops = {
188 ef10_nic_probe, /* eno_probe */
189 medford2_board_cfg, /* eno_board_cfg */
190 ef10_nic_set_drv_limits, /* eno_set_drv_limits */
191 ef10_nic_reset, /* eno_reset */
192 ef10_nic_init, /* eno_init */
193 ef10_nic_get_vi_pool, /* eno_get_vi_pool */
194 ef10_nic_get_bar_region, /* eno_get_bar_region */
195 ef10_nic_hw_unavailable, /* eno_hw_unavailable */
196 ef10_nic_set_hw_unavailable, /* eno_set_hw_unavailable */
198 ef10_nic_register_test, /* eno_register_test */
199 #endif /* EFSYS_OPT_DIAG */
200 ef10_nic_fini, /* eno_fini */
201 ef10_nic_unprobe, /* eno_unprobe */
204 #endif /* EFSYS_OPT_MEDFORD2 */
207 __checkReturn efx_rc_t
209 __in efx_family_t family,
210 __in efsys_identifier_t *esip,
211 __in efsys_bar_t *esbp,
212 __in efsys_lock_t *eslp,
213 __deref_out efx_nic_t **enpp)
218 EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID);
219 EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES);
221 /* Allocate a NIC object */
222 EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp);
229 enp->en_magic = EFX_NIC_MAGIC;
233 case EFX_FAMILY_SIENA:
234 enp->en_enop = &__efx_nic_siena_ops;
237 EFX_FEATURE_LFSR_HASH_INSERT |
238 EFX_FEATURE_LINK_EVENTS |
239 EFX_FEATURE_PERIODIC_MAC_STATS |
241 EFX_FEATURE_LOOKAHEAD_SPLIT |
242 EFX_FEATURE_MAC_HEADER_FILTERS |
243 EFX_FEATURE_TX_SRC_FILTERS;
245 #endif /* EFSYS_OPT_SIENA */
247 #if EFSYS_OPT_HUNTINGTON
248 case EFX_FAMILY_HUNTINGTON:
249 enp->en_enop = &__efx_nic_hunt_ops;
252 EFX_FEATURE_LINK_EVENTS |
253 EFX_FEATURE_PERIODIC_MAC_STATS |
255 EFX_FEATURE_MAC_HEADER_FILTERS |
256 EFX_FEATURE_MCDI_DMA |
257 EFX_FEATURE_PIO_BUFFERS |
258 EFX_FEATURE_FW_ASSISTED_TSO |
259 EFX_FEATURE_FW_ASSISTED_TSO_V2 |
260 EFX_FEATURE_PACKED_STREAM |
261 EFX_FEATURE_TXQ_CKSUM_OP_DESC;
263 #endif /* EFSYS_OPT_HUNTINGTON */
265 #if EFSYS_OPT_MEDFORD
266 case EFX_FAMILY_MEDFORD:
267 enp->en_enop = &__efx_nic_medford_ops;
269 * FW_ASSISTED_TSO omitted as Medford only supports firmware
270 * assisted TSO version 2, not the v1 scheme used on Huntington.
274 EFX_FEATURE_LINK_EVENTS |
275 EFX_FEATURE_PERIODIC_MAC_STATS |
277 EFX_FEATURE_MAC_HEADER_FILTERS |
278 EFX_FEATURE_MCDI_DMA |
279 EFX_FEATURE_PIO_BUFFERS |
280 EFX_FEATURE_FW_ASSISTED_TSO_V2 |
281 EFX_FEATURE_PACKED_STREAM |
282 EFX_FEATURE_TXQ_CKSUM_OP_DESC;
284 #endif /* EFSYS_OPT_MEDFORD */
286 #if EFSYS_OPT_MEDFORD2
287 case EFX_FAMILY_MEDFORD2:
288 enp->en_enop = &__efx_nic_medford2_ops;
291 EFX_FEATURE_LINK_EVENTS |
292 EFX_FEATURE_PERIODIC_MAC_STATS |
294 EFX_FEATURE_MAC_HEADER_FILTERS |
295 EFX_FEATURE_MCDI_DMA |
296 EFX_FEATURE_PIO_BUFFERS |
297 EFX_FEATURE_FW_ASSISTED_TSO_V2 |
298 EFX_FEATURE_PACKED_STREAM |
299 EFX_FEATURE_TXQ_CKSUM_OP_DESC;
301 #endif /* EFSYS_OPT_MEDFORD2 */
308 enp->en_family = family;
322 /* Free the NIC object */
323 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
326 EFSYS_PROBE1(fail1, efx_rc_t, rc);
331 __checkReturn efx_rc_t
334 __in efx_fw_variant_t efv)
336 const efx_nic_ops_t *enop;
339 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
341 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
342 #endif /* EFSYS_OPT_MCDI */
343 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
345 /* Ensure FW variant codes match with MC_CMD_FW codes */
346 EFX_STATIC_ASSERT(EFX_FW_VARIANT_FULL_FEATURED ==
347 MC_CMD_FW_FULL_FEATURED);
348 EFX_STATIC_ASSERT(EFX_FW_VARIANT_LOW_LATENCY ==
349 MC_CMD_FW_LOW_LATENCY);
350 EFX_STATIC_ASSERT(EFX_FW_VARIANT_PACKED_STREAM ==
351 MC_CMD_FW_PACKED_STREAM);
352 EFX_STATIC_ASSERT(EFX_FW_VARIANT_HIGH_TX_RATE ==
353 MC_CMD_FW_HIGH_TX_RATE);
354 EFX_STATIC_ASSERT(EFX_FW_VARIANT_PACKED_STREAM_HASH_MODE_1 ==
355 MC_CMD_FW_PACKED_STREAM_HASH_MODE_1);
356 EFX_STATIC_ASSERT(EFX_FW_VARIANT_RULES_ENGINE ==
357 MC_CMD_FW_RULES_ENGINE);
358 EFX_STATIC_ASSERT(EFX_FW_VARIANT_DPDK ==
360 EFX_STATIC_ASSERT(EFX_FW_VARIANT_DONT_CARE ==
361 (int)MC_CMD_FW_DONT_CARE);
366 if ((rc = enop->eno_probe(enp)) != 0)
369 if ((rc = efx_phy_probe(enp)) != 0)
372 enp->en_mod_flags |= EFX_MOD_PROBE;
379 enop->eno_unprobe(enp);
382 EFSYS_PROBE1(fail1, efx_rc_t, rc);
387 __checkReturn efx_rc_t
388 efx_nic_set_drv_limits(
389 __inout efx_nic_t *enp,
390 __in efx_drv_limits_t *edlp)
392 const efx_nic_ops_t *enop = enp->en_enop;
395 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
396 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
398 if (enop->eno_set_drv_limits != NULL) {
399 if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
406 EFSYS_PROBE1(fail1, efx_rc_t, rc);
411 __checkReturn efx_rc_t
412 efx_nic_get_bar_region(
414 __in efx_nic_region_t region,
415 __out uint32_t *offsetp,
418 const efx_nic_ops_t *enop = enp->en_enop;
421 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
422 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
423 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
425 if (enop->eno_get_bar_region == NULL) {
429 if ((rc = (enop->eno_get_bar_region)(enp,
430 region, offsetp, sizep)) != 0) {
440 EFSYS_PROBE1(fail1, efx_rc_t, rc);
446 __checkReturn efx_rc_t
449 __out uint32_t *evq_countp,
450 __out uint32_t *rxq_countp,
451 __out uint32_t *txq_countp)
453 const efx_nic_ops_t *enop = enp->en_enop;
454 efx_nic_cfg_t *encp = &enp->en_nic_cfg;
457 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
458 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
459 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
461 if (enop->eno_get_vi_pool != NULL) {
462 uint32_t vi_count = 0;
464 if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
467 *evq_countp = vi_count;
468 *rxq_countp = vi_count;
469 *txq_countp = vi_count;
471 /* Use NIC limits as default value */
472 *evq_countp = encp->enc_evq_limit;
473 *rxq_countp = encp->enc_rxq_limit;
474 *txq_countp = encp->enc_txq_limit;
480 EFSYS_PROBE1(fail1, efx_rc_t, rc);
486 __checkReturn efx_rc_t
490 const efx_nic_ops_t *enop = enp->en_enop;
493 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
494 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
496 if (enp->en_mod_flags & EFX_MOD_NIC) {
501 if ((rc = enop->eno_init(enp)) != 0)
504 enp->en_mod_flags |= EFX_MOD_NIC;
511 EFSYS_PROBE1(fail1, efx_rc_t, rc);
520 const efx_nic_ops_t *enop = enp->en_enop;
522 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
523 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
524 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC);
525 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
526 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
527 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
528 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
532 enp->en_mod_flags &= ~EFX_MOD_NIC;
539 const efx_nic_ops_t *enop = enp->en_enop;
541 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
543 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
544 #endif /* EFSYS_OPT_MCDI */
545 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
546 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
547 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
548 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
549 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
550 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
552 efx_phy_unprobe(enp);
554 enop->eno_unprobe(enp);
556 enp->en_mod_flags &= ~EFX_MOD_PROBE;
563 efsys_identifier_t *esip = enp->en_esip;
565 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
566 EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
568 enp->en_family = EFX_FAMILY_INVALID;
577 /* Free the NIC object */
578 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
581 __checkReturn efx_rc_t
585 const efx_nic_ops_t *enop = enp->en_enop;
586 unsigned int mod_flags;
589 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
590 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
592 * All modules except the MCDI, PROBE, NVRAM, VPD, MON, TUNNEL
593 * (which we do not reset here) must have been shut down or never
596 * A rule of thumb here is: If the controller or MC reboots, is *any*
597 * state lost. If it's lost and needs reapplying, then the module
598 * *must* not be initialised during the reset.
600 mod_flags = enp->en_mod_flags;
601 mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
602 EFX_MOD_VPD | EFX_MOD_MON);
604 mod_flags &= ~EFX_MOD_TUNNEL;
605 #endif /* EFSYS_OPT_TUNNEL */
606 EFSYS_ASSERT3U(mod_flags, ==, 0);
607 if (mod_flags != 0) {
612 if ((rc = enop->eno_reset(enp)) != 0)
620 EFSYS_PROBE1(fail1, efx_rc_t, rc);
625 const efx_nic_cfg_t *
629 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
630 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
632 return (&(enp->en_nic_cfg));
635 __checkReturn efx_rc_t
636 efx_nic_get_fw_version(
638 __out efx_nic_fw_info_t *enfip)
640 uint16_t mc_fw_version[4];
648 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
649 EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
651 /* Ensure RXDP_FW_ID codes match with MC_CMD_GET_CAPABILITIES codes */
652 EFX_STATIC_ASSERT(EFX_RXDP_FULL_FEATURED_FW_ID ==
653 MC_CMD_GET_CAPABILITIES_OUT_RXDP);
654 EFX_STATIC_ASSERT(EFX_RXDP_LOW_LATENCY_FW_ID ==
655 MC_CMD_GET_CAPABILITIES_OUT_RXDP_LOW_LATENCY);
656 EFX_STATIC_ASSERT(EFX_RXDP_PACKED_STREAM_FW_ID ==
657 MC_CMD_GET_CAPABILITIES_OUT_RXDP_PACKED_STREAM);
658 EFX_STATIC_ASSERT(EFX_RXDP_RULES_ENGINE_FW_ID ==
659 MC_CMD_GET_CAPABILITIES_OUT_RXDP_RULES_ENGINE);
660 EFX_STATIC_ASSERT(EFX_RXDP_DPDK_FW_ID ==
661 MC_CMD_GET_CAPABILITIES_OUT_RXDP_DPDK);
663 rc = efx_mcdi_version(enp, mc_fw_version, NULL, NULL);
667 rc = efx_mcdi_get_capabilities(enp, NULL,
668 &enfip->enfi_rx_dpcpu_fw_id,
669 &enfip->enfi_tx_dpcpu_fw_id,
672 enfip->enfi_dpcpu_fw_ids_valid = B_TRUE;
673 } else if (rc == ENOTSUP) {
674 enfip->enfi_dpcpu_fw_ids_valid = B_FALSE;
675 enfip->enfi_rx_dpcpu_fw_id = 0;
676 enfip->enfi_tx_dpcpu_fw_id = 0;
681 memcpy(enfip->enfi_mc_fw_version, mc_fw_version,
682 sizeof (mc_fw_version));
691 EFSYS_PROBE1(fail1, efx_rc_t, rc);
696 __checkReturn boolean_t
697 efx_nic_hw_unavailable(
700 const efx_nic_ops_t *enop = enp->en_enop;
702 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
703 /* NOTE: can be used by MCDI before NIC probe */
705 if (enop->eno_hw_unavailable != NULL) {
706 if ((enop->eno_hw_unavailable)(enp) != B_FALSE)
717 efx_nic_set_hw_unavailable(
720 const efx_nic_ops_t *enop = enp->en_enop;
722 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
724 if (enop->eno_set_hw_unavailable != NULL)
725 enop->eno_set_hw_unavailable(enp);
731 __checkReturn efx_rc_t
732 efx_nic_register_test(
735 const efx_nic_ops_t *enop = enp->en_enop;
738 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
739 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
740 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
742 if ((rc = enop->eno_register_test(enp)) != 0)
748 EFSYS_PROBE1(fail1, efx_rc_t, rc);
753 #endif /* EFSYS_OPT_DIAG */
755 #if EFSYS_OPT_LOOPBACK
759 __in efx_loopback_kind_t loopback_kind,
760 __out efx_qword_t *maskp)
764 EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS);
765 EFSYS_ASSERT(maskp != NULL);
767 /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree */
768 #define LOOPBACK_CHECK(_mcdi, _efx) \
769 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_##_mcdi == EFX_LOOPBACK_##_efx)
771 LOOPBACK_CHECK(NONE, OFF);
772 LOOPBACK_CHECK(DATA, DATA);
773 LOOPBACK_CHECK(GMAC, GMAC);
774 LOOPBACK_CHECK(XGMII, XGMII);
775 LOOPBACK_CHECK(XGXS, XGXS);
776 LOOPBACK_CHECK(XAUI, XAUI);
777 LOOPBACK_CHECK(GMII, GMII);
778 LOOPBACK_CHECK(SGMII, SGMII);
779 LOOPBACK_CHECK(XGBR, XGBR);
780 LOOPBACK_CHECK(XFI, XFI);
781 LOOPBACK_CHECK(XAUI_FAR, XAUI_FAR);
782 LOOPBACK_CHECK(GMII_FAR, GMII_FAR);
783 LOOPBACK_CHECK(SGMII_FAR, SGMII_FAR);
784 LOOPBACK_CHECK(XFI_FAR, XFI_FAR);
785 LOOPBACK_CHECK(GPHY, GPHY);
786 LOOPBACK_CHECK(PHYXS, PHY_XS);
787 LOOPBACK_CHECK(PCS, PCS);
788 LOOPBACK_CHECK(PMAPMD, PMA_PMD);
789 LOOPBACK_CHECK(XPORT, XPORT);
790 LOOPBACK_CHECK(XGMII_WS, XGMII_WS);
791 LOOPBACK_CHECK(XAUI_WS, XAUI_WS);
792 LOOPBACK_CHECK(XAUI_WS_FAR, XAUI_WS_FAR);
793 LOOPBACK_CHECK(XAUI_WS_NEAR, XAUI_WS_NEAR);
794 LOOPBACK_CHECK(GMII_WS, GMII_WS);
795 LOOPBACK_CHECK(XFI_WS, XFI_WS);
796 LOOPBACK_CHECK(XFI_WS_FAR, XFI_WS_FAR);
797 LOOPBACK_CHECK(PHYXS_WS, PHYXS_WS);
798 LOOPBACK_CHECK(PMA_INT, PMA_INT);
799 LOOPBACK_CHECK(SD_NEAR, SD_NEAR);
800 LOOPBACK_CHECK(SD_FAR, SD_FAR);
801 LOOPBACK_CHECK(PMA_INT_WS, PMA_INT_WS);
802 LOOPBACK_CHECK(SD_FEP2_WS, SD_FEP2_WS);
803 LOOPBACK_CHECK(SD_FEP1_5_WS, SD_FEP1_5_WS);
804 LOOPBACK_CHECK(SD_FEP_WS, SD_FEP_WS);
805 LOOPBACK_CHECK(SD_FES_WS, SD_FES_WS);
806 LOOPBACK_CHECK(AOE_INT_NEAR, AOE_INT_NEAR);
807 LOOPBACK_CHECK(DATA_WS, DATA_WS);
808 LOOPBACK_CHECK(FORCE_EXT_LINK, FORCE_EXT_LINK);
809 #undef LOOPBACK_CHECK
811 /* Build bitmask of possible loopback types */
812 EFX_ZERO_QWORD(mask);
814 if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) ||
815 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
816 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF);
819 if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) ||
820 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
822 * The "MAC" grouping has historically been used by drivers to
823 * mean loopbacks supported by on-chip hardware. Keep that
824 * meaning here, and include on-chip PHY layer loopbacks.
826 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA);
827 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC);
828 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII);
829 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS);
830 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI);
831 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII);
832 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII);
833 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR);
834 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI);
835 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR);
836 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR);
837 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR);
838 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR);
839 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT);
840 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR);
841 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR);
844 if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) ||
845 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
847 * The "PHY" grouping has historically been used by drivers to
848 * mean loopbacks supported by off-chip hardware. Keep that
851 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY);
852 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PHY_XS);
853 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS);
854 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD);
860 __checkReturn efx_rc_t
861 efx_mcdi_get_loopback_modes(
864 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
866 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
867 MC_CMD_GET_LOOPBACK_MODES_OUT_V2_LEN);
872 req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
873 req.emr_in_buf = payload;
874 req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
875 req.emr_out_buf = payload;
876 req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_V2_LEN;
878 efx_mcdi_execute(enp, &req);
880 if (req.emr_rc != 0) {
885 if (req.emr_out_length_used <
886 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
887 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) {
893 * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
894 * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link().
896 efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask);
899 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED));
901 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M);
902 EFX_AND_QWORD(modes, mask);
903 encp->enc_loopback_types[EFX_LINK_100FDX] = modes;
905 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G);
906 EFX_AND_QWORD(modes, mask);
907 encp->enc_loopback_types[EFX_LINK_1000FDX] = modes;
909 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G);
910 EFX_AND_QWORD(modes, mask);
911 encp->enc_loopback_types[EFX_LINK_10000FDX] = modes;
913 if (req.emr_out_length_used >=
914 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
915 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
916 /* Response includes 40G loopback modes */
917 modes = *MCDI_OUT2(req, efx_qword_t,
918 GET_LOOPBACK_MODES_OUT_40G);
919 EFX_AND_QWORD(modes, mask);
920 encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
923 if (req.emr_out_length_used >=
924 MC_CMD_GET_LOOPBACK_MODES_OUT_V2_25G_OFST +
925 MC_CMD_GET_LOOPBACK_MODES_OUT_V2_25G_LEN) {
926 /* Response includes 25G loopback modes */
927 modes = *MCDI_OUT2(req, efx_qword_t,
928 GET_LOOPBACK_MODES_OUT_V2_25G);
929 EFX_AND_QWORD(modes, mask);
930 encp->enc_loopback_types[EFX_LINK_25000FDX] = modes;
933 if (req.emr_out_length_used >=
934 MC_CMD_GET_LOOPBACK_MODES_OUT_V2_50G_OFST +
935 MC_CMD_GET_LOOPBACK_MODES_OUT_V2_50G_LEN) {
936 /* Response includes 50G loopback modes */
937 modes = *MCDI_OUT2(req, efx_qword_t,
938 GET_LOOPBACK_MODES_OUT_V2_50G);
939 EFX_AND_QWORD(modes, mask);
940 encp->enc_loopback_types[EFX_LINK_50000FDX] = modes;
943 if (req.emr_out_length_used >=
944 MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100G_OFST +
945 MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100G_LEN) {
946 /* Response includes 100G loopback modes */
947 modes = *MCDI_OUT2(req, efx_qword_t,
948 GET_LOOPBACK_MODES_OUT_V2_100G);
949 EFX_AND_QWORD(modes, mask);
950 encp->enc_loopback_types[EFX_LINK_100000FDX] = modes;
953 EFX_ZERO_QWORD(modes);
954 EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
955 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
956 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
957 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
958 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
959 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_25000FDX]);
960 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_50000FDX]);
961 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100000FDX]);
962 encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
969 EFSYS_PROBE1(fail1, efx_rc_t, rc);
974 #endif /* EFSYS_OPT_LOOPBACK */
976 __checkReturn efx_rc_t
977 efx_nic_calculate_pcie_link_bandwidth(
978 __in uint32_t pcie_link_width,
979 __in uint32_t pcie_link_gen,
980 __out uint32_t *bandwidth_mbpsp)
982 uint32_t lane_bandwidth;
983 uint32_t total_bandwidth;
986 if ((pcie_link_width == 0) || (pcie_link_width > 16) ||
987 !ISP2(pcie_link_width)) {
992 switch (pcie_link_gen) {
993 case EFX_PCIE_LINK_SPEED_GEN1:
994 /* 2.5 Gb/s raw bandwidth with 8b/10b encoding */
995 lane_bandwidth = 2000;
997 case EFX_PCIE_LINK_SPEED_GEN2:
998 /* 5.0 Gb/s raw bandwidth with 8b/10b encoding */
999 lane_bandwidth = 4000;
1001 case EFX_PCIE_LINK_SPEED_GEN3:
1002 /* 8.0 Gb/s raw bandwidth with 128b/130b encoding */
1003 lane_bandwidth = 7877;
1010 total_bandwidth = lane_bandwidth * pcie_link_width;
1011 *bandwidth_mbpsp = total_bandwidth;
1018 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1023 #if EFSYS_OPT_FW_SUBVARIANT_AWARE
1025 __checkReturn efx_rc_t
1026 efx_nic_get_fw_subvariant(
1027 __in efx_nic_t *enp,
1028 __out efx_nic_fw_subvariant_t *subvariantp)
1033 rc = efx_mcdi_get_nic_global(enp,
1034 MC_CMD_SET_NIC_GLOBAL_IN_FIRMWARE_SUBVARIANT, &value);
1038 /* Mapping is not required since values match MCDI */
1039 EFX_STATIC_ASSERT(EFX_NIC_FW_SUBVARIANT_DEFAULT ==
1040 MC_CMD_SET_NIC_GLOBAL_IN_FW_SUBVARIANT_DEFAULT);
1041 EFX_STATIC_ASSERT(EFX_NIC_FW_SUBVARIANT_NO_TX_CSUM ==
1042 MC_CMD_SET_NIC_GLOBAL_IN_FW_SUBVARIANT_NO_TX_CSUM);
1045 case MC_CMD_SET_NIC_GLOBAL_IN_FW_SUBVARIANT_DEFAULT:
1046 case MC_CMD_SET_NIC_GLOBAL_IN_FW_SUBVARIANT_NO_TX_CSUM:
1047 *subvariantp = value;
1060 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1065 __checkReturn efx_rc_t
1066 efx_nic_set_fw_subvariant(
1067 __in efx_nic_t *enp,
1068 __in efx_nic_fw_subvariant_t subvariant)
1072 switch (subvariant) {
1073 case EFX_NIC_FW_SUBVARIANT_DEFAULT:
1074 case EFX_NIC_FW_SUBVARIANT_NO_TX_CSUM:
1075 /* Mapping is not required since values match MCDI */
1082 rc = efx_mcdi_set_nic_global(enp,
1083 MC_CMD_SET_NIC_GLOBAL_IN_FIRMWARE_SUBVARIANT, subvariant);
1093 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1098 #endif /* EFSYS_OPT_FW_SUBVARIANT_AWARE */
1100 __checkReturn efx_rc_t
1101 efx_nic_check_pcie_link_speed(
1102 __in efx_nic_t *enp,
1103 __in uint32_t pcie_link_width,
1104 __in uint32_t pcie_link_gen,
1105 __out efx_pcie_link_performance_t *resultp)
1107 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1109 efx_pcie_link_performance_t result;
1112 if ((encp->enc_required_pcie_bandwidth_mbps == 0) ||
1113 (pcie_link_width == 0) || (pcie_link_width == 32) ||
1114 (pcie_link_gen == 0)) {
1116 * No usable info on what is required and/or in use. In virtual
1117 * machines, sometimes the PCIe link width is reported as 0 or
1118 * 32, or the speed as 0.
1120 result = EFX_PCIE_LINK_PERFORMANCE_UNKNOWN_BANDWIDTH;
1124 /* Calculate the available bandwidth in megabits per second */
1125 rc = efx_nic_calculate_pcie_link_bandwidth(pcie_link_width,
1126 pcie_link_gen, &bandwidth);
1130 if (bandwidth < encp->enc_required_pcie_bandwidth_mbps) {
1131 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_BANDWIDTH;
1132 } else if (pcie_link_gen < encp->enc_max_pcie_link_gen) {
1133 /* The link provides enough bandwidth but not optimal latency */
1134 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_LATENCY;
1136 result = EFX_PCIE_LINK_PERFORMANCE_OPTIMAL;
1145 EFSYS_PROBE1(fail1, efx_rc_t, rc);