1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright (c) 2007-2018 Solarflare Communications Inc.
10 __checkReturn efx_rc_t
14 __out efx_family_t *efp)
16 if (venid == EFX_PCI_VENID_SFC) {
19 case EFX_PCI_DEVID_SIENA_F1_UNINIT:
21 * Hardware default for PF0 of uninitialised Siena.
22 * manftest must be able to cope with this device id.
24 *efp = EFX_FAMILY_SIENA;
27 case EFX_PCI_DEVID_BETHPAGE:
28 case EFX_PCI_DEVID_SIENA:
29 *efp = EFX_FAMILY_SIENA;
31 #endif /* EFSYS_OPT_SIENA */
33 #if EFSYS_OPT_HUNTINGTON
34 case EFX_PCI_DEVID_HUNTINGTON_PF_UNINIT:
36 * Hardware default for PF0 of uninitialised Huntington.
37 * manftest must be able to cope with this device id.
39 *efp = EFX_FAMILY_HUNTINGTON;
42 case EFX_PCI_DEVID_FARMINGDALE:
43 case EFX_PCI_DEVID_GREENPORT:
44 *efp = EFX_FAMILY_HUNTINGTON;
47 case EFX_PCI_DEVID_FARMINGDALE_VF:
48 case EFX_PCI_DEVID_GREENPORT_VF:
49 *efp = EFX_FAMILY_HUNTINGTON;
51 #endif /* EFSYS_OPT_HUNTINGTON */
54 case EFX_PCI_DEVID_MEDFORD_PF_UNINIT:
56 * Hardware default for PF0 of uninitialised Medford.
57 * manftest must be able to cope with this device id.
59 *efp = EFX_FAMILY_MEDFORD;
62 case EFX_PCI_DEVID_MEDFORD:
63 *efp = EFX_FAMILY_MEDFORD;
66 case EFX_PCI_DEVID_MEDFORD_VF:
67 *efp = EFX_FAMILY_MEDFORD;
69 #endif /* EFSYS_OPT_MEDFORD */
71 case EFX_PCI_DEVID_FALCON: /* Obsolete, not supported */
77 *efp = EFX_FAMILY_INVALID;
83 static const efx_nic_ops_t __efx_nic_siena_ops = {
84 siena_nic_probe, /* eno_probe */
85 NULL, /* eno_board_cfg */
86 NULL, /* eno_set_drv_limits */
87 siena_nic_reset, /* eno_reset */
88 siena_nic_init, /* eno_init */
89 NULL, /* eno_get_vi_pool */
90 NULL, /* eno_get_bar_region */
92 siena_nic_register_test, /* eno_register_test */
93 #endif /* EFSYS_OPT_DIAG */
94 siena_nic_fini, /* eno_fini */
95 siena_nic_unprobe, /* eno_unprobe */
98 #endif /* EFSYS_OPT_SIENA */
100 #if EFSYS_OPT_HUNTINGTON
102 static const efx_nic_ops_t __efx_nic_hunt_ops = {
103 ef10_nic_probe, /* eno_probe */
104 hunt_board_cfg, /* eno_board_cfg */
105 ef10_nic_set_drv_limits, /* eno_set_drv_limits */
106 ef10_nic_reset, /* eno_reset */
107 ef10_nic_init, /* eno_init */
108 ef10_nic_get_vi_pool, /* eno_get_vi_pool */
109 ef10_nic_get_bar_region, /* eno_get_bar_region */
111 ef10_nic_register_test, /* eno_register_test */
112 #endif /* EFSYS_OPT_DIAG */
113 ef10_nic_fini, /* eno_fini */
114 ef10_nic_unprobe, /* eno_unprobe */
117 #endif /* EFSYS_OPT_HUNTINGTON */
119 #if EFSYS_OPT_MEDFORD
121 static const efx_nic_ops_t __efx_nic_medford_ops = {
122 ef10_nic_probe, /* eno_probe */
123 medford_board_cfg, /* eno_board_cfg */
124 ef10_nic_set_drv_limits, /* eno_set_drv_limits */
125 ef10_nic_reset, /* eno_reset */
126 ef10_nic_init, /* eno_init */
127 ef10_nic_get_vi_pool, /* eno_get_vi_pool */
128 ef10_nic_get_bar_region, /* eno_get_bar_region */
130 ef10_nic_register_test, /* eno_register_test */
131 #endif /* EFSYS_OPT_DIAG */
132 ef10_nic_fini, /* eno_fini */
133 ef10_nic_unprobe, /* eno_unprobe */
136 #endif /* EFSYS_OPT_MEDFORD */
139 __checkReturn efx_rc_t
141 __in efx_family_t family,
142 __in efsys_identifier_t *esip,
143 __in efsys_bar_t *esbp,
144 __in efsys_lock_t *eslp,
145 __deref_out efx_nic_t **enpp)
150 EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID);
151 EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES);
153 /* Allocate a NIC object */
154 EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp);
161 enp->en_magic = EFX_NIC_MAGIC;
165 case EFX_FAMILY_SIENA:
166 enp->en_enop = &__efx_nic_siena_ops;
169 EFX_FEATURE_LFSR_HASH_INSERT |
170 EFX_FEATURE_LINK_EVENTS |
171 EFX_FEATURE_PERIODIC_MAC_STATS |
173 EFX_FEATURE_LOOKAHEAD_SPLIT |
174 EFX_FEATURE_MAC_HEADER_FILTERS |
175 EFX_FEATURE_TX_SRC_FILTERS;
177 #endif /* EFSYS_OPT_SIENA */
179 #if EFSYS_OPT_HUNTINGTON
180 case EFX_FAMILY_HUNTINGTON:
181 enp->en_enop = &__efx_nic_hunt_ops;
184 EFX_FEATURE_LINK_EVENTS |
185 EFX_FEATURE_PERIODIC_MAC_STATS |
187 EFX_FEATURE_MAC_HEADER_FILTERS |
188 EFX_FEATURE_MCDI_DMA |
189 EFX_FEATURE_PIO_BUFFERS |
190 EFX_FEATURE_FW_ASSISTED_TSO |
191 EFX_FEATURE_FW_ASSISTED_TSO_V2 |
192 EFX_FEATURE_PACKED_STREAM;
194 #endif /* EFSYS_OPT_HUNTINGTON */
196 #if EFSYS_OPT_MEDFORD
197 case EFX_FAMILY_MEDFORD:
198 enp->en_enop = &__efx_nic_medford_ops;
200 * FW_ASSISTED_TSO omitted as Medford only supports firmware
201 * assisted TSO version 2, not the v1 scheme used on Huntington.
205 EFX_FEATURE_LINK_EVENTS |
206 EFX_FEATURE_PERIODIC_MAC_STATS |
208 EFX_FEATURE_MAC_HEADER_FILTERS |
209 EFX_FEATURE_MCDI_DMA |
210 EFX_FEATURE_PIO_BUFFERS |
211 EFX_FEATURE_FW_ASSISTED_TSO_V2 |
212 EFX_FEATURE_PACKED_STREAM;
214 #endif /* EFSYS_OPT_MEDFORD */
221 enp->en_family = family;
235 /* Free the NIC object */
236 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
239 EFSYS_PROBE1(fail1, efx_rc_t, rc);
244 __checkReturn efx_rc_t
248 const efx_nic_ops_t *enop;
251 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
253 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
254 #endif /* EFSYS_OPT_MCDI */
255 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
258 if ((rc = enop->eno_probe(enp)) != 0)
261 if ((rc = efx_phy_probe(enp)) != 0)
264 enp->en_mod_flags |= EFX_MOD_PROBE;
271 enop->eno_unprobe(enp);
274 EFSYS_PROBE1(fail1, efx_rc_t, rc);
279 __checkReturn efx_rc_t
280 efx_nic_set_drv_limits(
281 __inout efx_nic_t *enp,
282 __in efx_drv_limits_t *edlp)
284 const efx_nic_ops_t *enop = enp->en_enop;
287 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
288 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
290 if (enop->eno_set_drv_limits != NULL) {
291 if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
298 EFSYS_PROBE1(fail1, efx_rc_t, rc);
303 __checkReturn efx_rc_t
304 efx_nic_get_bar_region(
306 __in efx_nic_region_t region,
307 __out uint32_t *offsetp,
310 const efx_nic_ops_t *enop = enp->en_enop;
313 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
314 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
315 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
317 if (enop->eno_get_bar_region == NULL) {
321 if ((rc = (enop->eno_get_bar_region)(enp,
322 region, offsetp, sizep)) != 0) {
332 EFSYS_PROBE1(fail1, efx_rc_t, rc);
338 __checkReturn efx_rc_t
341 __out uint32_t *evq_countp,
342 __out uint32_t *rxq_countp,
343 __out uint32_t *txq_countp)
345 const efx_nic_ops_t *enop = enp->en_enop;
346 efx_nic_cfg_t *encp = &enp->en_nic_cfg;
349 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
350 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
351 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
353 if (enop->eno_get_vi_pool != NULL) {
354 uint32_t vi_count = 0;
356 if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
359 *evq_countp = vi_count;
360 *rxq_countp = vi_count;
361 *txq_countp = vi_count;
363 /* Use NIC limits as default value */
364 *evq_countp = encp->enc_evq_limit;
365 *rxq_countp = encp->enc_rxq_limit;
366 *txq_countp = encp->enc_txq_limit;
372 EFSYS_PROBE1(fail1, efx_rc_t, rc);
378 __checkReturn efx_rc_t
382 const efx_nic_ops_t *enop = enp->en_enop;
385 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
386 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
388 if (enp->en_mod_flags & EFX_MOD_NIC) {
393 if ((rc = enop->eno_init(enp)) != 0)
396 enp->en_mod_flags |= EFX_MOD_NIC;
403 EFSYS_PROBE1(fail1, efx_rc_t, rc);
412 const efx_nic_ops_t *enop = enp->en_enop;
414 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
415 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
416 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC);
417 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
418 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
419 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
420 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
424 enp->en_mod_flags &= ~EFX_MOD_NIC;
431 const efx_nic_ops_t *enop = enp->en_enop;
433 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
435 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
436 #endif /* EFSYS_OPT_MCDI */
437 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
438 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
439 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
440 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
441 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
442 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
444 efx_phy_unprobe(enp);
446 enop->eno_unprobe(enp);
448 enp->en_mod_flags &= ~EFX_MOD_PROBE;
455 efsys_identifier_t *esip = enp->en_esip;
457 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
458 EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
460 enp->en_family = EFX_FAMILY_INVALID;
469 /* Free the NIC object */
470 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
473 __checkReturn efx_rc_t
477 const efx_nic_ops_t *enop = enp->en_enop;
478 unsigned int mod_flags;
481 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
482 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
484 * All modules except the MCDI, PROBE, NVRAM, VPD, MON
485 * (which we do not reset here) must have been shut down or never
488 * A rule of thumb here is: If the controller or MC reboots, is *any*
489 * state lost. If it's lost and needs reapplying, then the module
490 * *must* not be initialised during the reset.
492 mod_flags = enp->en_mod_flags;
493 mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
494 EFX_MOD_VPD | EFX_MOD_MON);
495 EFSYS_ASSERT3U(mod_flags, ==, 0);
496 if (mod_flags != 0) {
501 if ((rc = enop->eno_reset(enp)) != 0)
509 EFSYS_PROBE1(fail1, efx_rc_t, rc);
514 const efx_nic_cfg_t *
518 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
520 return (&(enp->en_nic_cfg));
523 __checkReturn efx_rc_t
524 efx_nic_get_fw_version(
526 __out efx_nic_fw_info_t *enfip)
528 uint16_t mc_fw_version[4];
536 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
537 EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
539 rc = efx_mcdi_version(enp, mc_fw_version, NULL, NULL);
543 rc = efx_mcdi_get_capabilities(enp, NULL,
544 &enfip->enfi_rx_dpcpu_fw_id,
545 &enfip->enfi_tx_dpcpu_fw_id,
548 enfip->enfi_dpcpu_fw_ids_valid = B_TRUE;
549 } else if (rc == ENOTSUP) {
550 enfip->enfi_dpcpu_fw_ids_valid = B_FALSE;
551 enfip->enfi_rx_dpcpu_fw_id = 0;
552 enfip->enfi_tx_dpcpu_fw_id = 0;
557 memcpy(enfip->enfi_mc_fw_version, mc_fw_version,
558 sizeof (mc_fw_version));
567 EFSYS_PROBE1(fail1, efx_rc_t, rc);
574 __checkReturn efx_rc_t
575 efx_nic_register_test(
578 const efx_nic_ops_t *enop = enp->en_enop;
581 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
582 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
583 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
585 if ((rc = enop->eno_register_test(enp)) != 0)
591 EFSYS_PROBE1(fail1, efx_rc_t, rc);
596 #endif /* EFSYS_OPT_DIAG */
598 #if EFSYS_OPT_LOOPBACK
602 __in efx_loopback_kind_t loopback_kind,
603 __out efx_qword_t *maskp)
607 EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS);
608 EFSYS_ASSERT(maskp != NULL);
610 /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
611 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
612 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
613 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
614 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
615 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
616 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
617 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
618 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
619 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
620 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
621 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
622 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
623 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
624 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
625 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
626 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
627 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
628 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
629 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT);
630 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS);
631 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS);
632 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR ==
633 EFX_LOOPBACK_XAUI_WS_FAR);
634 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR ==
635 EFX_LOOPBACK_XAUI_WS_NEAR);
636 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS);
637 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS);
638 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR ==
639 EFX_LOOPBACK_XFI_WS_FAR);
640 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS);
641 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT);
642 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR);
643 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR);
644 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS ==
645 EFX_LOOPBACK_PMA_INT_WS);
646 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS ==
647 EFX_LOOPBACK_SD_FEP2_WS);
648 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS ==
649 EFX_LOOPBACK_SD_FEP1_5_WS);
650 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS);
651 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS);
653 /* Build bitmask of possible loopback types */
654 EFX_ZERO_QWORD(mask);
656 if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) ||
657 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
658 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF);
661 if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) ||
662 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
664 * The "MAC" grouping has historically been used by drivers to
665 * mean loopbacks supported by on-chip hardware. Keep that
666 * meaning here, and include on-chip PHY layer loopbacks.
668 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA);
669 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC);
670 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII);
671 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS);
672 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI);
673 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII);
674 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII);
675 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR);
676 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI);
677 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR);
678 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR);
679 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR);
680 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR);
681 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT);
682 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR);
683 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR);
686 if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) ||
687 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
689 * The "PHY" grouping has historically been used by drivers to
690 * mean loopbacks supported by off-chip hardware. Keep that
693 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY);
694 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PHY_XS);
695 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS);
696 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD);
702 __checkReturn efx_rc_t
703 efx_mcdi_get_loopback_modes(
706 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
708 uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
709 MC_CMD_GET_LOOPBACK_MODES_OUT_LEN)];
714 (void) memset(payload, 0, sizeof (payload));
715 req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
716 req.emr_in_buf = payload;
717 req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
718 req.emr_out_buf = payload;
719 req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN;
721 efx_mcdi_execute(enp, &req);
723 if (req.emr_rc != 0) {
728 if (req.emr_out_length_used <
729 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
730 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) {
736 * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
737 * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link().
739 efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask);
742 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED));
744 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M);
745 EFX_AND_QWORD(modes, mask);
746 encp->enc_loopback_types[EFX_LINK_100FDX] = modes;
748 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G);
749 EFX_AND_QWORD(modes, mask);
750 encp->enc_loopback_types[EFX_LINK_1000FDX] = modes;
752 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G);
753 EFX_AND_QWORD(modes, mask);
754 encp->enc_loopback_types[EFX_LINK_10000FDX] = modes;
756 if (req.emr_out_length_used >=
757 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
758 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
759 /* Response includes 40G loopback modes */
761 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G);
762 EFX_AND_QWORD(modes, mask);
763 encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
766 EFX_ZERO_QWORD(modes);
767 EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
768 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
769 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
770 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
771 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
772 encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
779 EFSYS_PROBE1(fail1, efx_rc_t, rc);
784 #endif /* EFSYS_OPT_LOOPBACK */
786 __checkReturn efx_rc_t
787 efx_nic_calculate_pcie_link_bandwidth(
788 __in uint32_t pcie_link_width,
789 __in uint32_t pcie_link_gen,
790 __out uint32_t *bandwidth_mbpsp)
792 uint32_t lane_bandwidth;
793 uint32_t total_bandwidth;
796 if ((pcie_link_width == 0) || (pcie_link_width > 16) ||
797 !ISP2(pcie_link_width)) {
802 switch (pcie_link_gen) {
803 case EFX_PCIE_LINK_SPEED_GEN1:
804 /* 2.5 Gb/s raw bandwidth with 8b/10b encoding */
805 lane_bandwidth = 2000;
807 case EFX_PCIE_LINK_SPEED_GEN2:
808 /* 5.0 Gb/s raw bandwidth with 8b/10b encoding */
809 lane_bandwidth = 4000;
811 case EFX_PCIE_LINK_SPEED_GEN3:
812 /* 8.0 Gb/s raw bandwidth with 128b/130b encoding */
813 lane_bandwidth = 7877;
820 total_bandwidth = lane_bandwidth * pcie_link_width;
821 *bandwidth_mbpsp = total_bandwidth;
828 EFSYS_PROBE1(fail1, efx_rc_t, rc);
834 __checkReturn efx_rc_t
835 efx_nic_check_pcie_link_speed(
837 __in uint32_t pcie_link_width,
838 __in uint32_t pcie_link_gen,
839 __out efx_pcie_link_performance_t *resultp)
841 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
843 efx_pcie_link_performance_t result;
846 if ((encp->enc_required_pcie_bandwidth_mbps == 0) ||
847 (pcie_link_width == 0) || (pcie_link_width == 32) ||
848 (pcie_link_gen == 0)) {
850 * No usable info on what is required and/or in use. In virtual
851 * machines, sometimes the PCIe link width is reported as 0 or
852 * 32, or the speed as 0.
854 result = EFX_PCIE_LINK_PERFORMANCE_UNKNOWN_BANDWIDTH;
858 /* Calculate the available bandwidth in megabits per second */
859 rc = efx_nic_calculate_pcie_link_bandwidth(pcie_link_width,
860 pcie_link_gen, &bandwidth);
864 if (bandwidth < encp->enc_required_pcie_bandwidth_mbps) {
865 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_BANDWIDTH;
866 } else if (pcie_link_gen < encp->enc_max_pcie_link_gen) {
867 /* The link provides enough bandwidth but not optimal latency */
868 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_LATENCY;
870 result = EFX_PCIE_LINK_PERFORMANCE_OPTIMAL;
879 EFSYS_PROBE1(fail1, efx_rc_t, rc);