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 #if EFSYS_OPT_MEDFORD2
72 case EFX_PCI_DEVID_MEDFORD2_PF_UNINIT:
74 * Hardware default for PF0 of uninitialised Medford2.
75 * manftest must be able to cope with this device id.
77 *efp = EFX_FAMILY_MEDFORD2;
80 case EFX_PCI_DEVID_MEDFORD2:
81 *efp = EFX_FAMILY_MEDFORD2;
84 case EFX_PCI_DEVID_MEDFORD2_VF:
85 *efp = EFX_FAMILY_MEDFORD2;
87 #endif /* EFSYS_OPT_MEDFORD2 */
89 case EFX_PCI_DEVID_FALCON: /* Obsolete, not supported */
95 *efp = EFX_FAMILY_INVALID;
101 static const efx_nic_ops_t __efx_nic_siena_ops = {
102 siena_nic_probe, /* eno_probe */
103 NULL, /* eno_board_cfg */
104 NULL, /* eno_set_drv_limits */
105 siena_nic_reset, /* eno_reset */
106 siena_nic_init, /* eno_init */
107 NULL, /* eno_get_vi_pool */
108 NULL, /* eno_get_bar_region */
110 siena_nic_register_test, /* eno_register_test */
111 #endif /* EFSYS_OPT_DIAG */
112 siena_nic_fini, /* eno_fini */
113 siena_nic_unprobe, /* eno_unprobe */
116 #endif /* EFSYS_OPT_SIENA */
118 #if EFSYS_OPT_HUNTINGTON
120 static const efx_nic_ops_t __efx_nic_hunt_ops = {
121 ef10_nic_probe, /* eno_probe */
122 hunt_board_cfg, /* eno_board_cfg */
123 ef10_nic_set_drv_limits, /* eno_set_drv_limits */
124 ef10_nic_reset, /* eno_reset */
125 ef10_nic_init, /* eno_init */
126 ef10_nic_get_vi_pool, /* eno_get_vi_pool */
127 ef10_nic_get_bar_region, /* eno_get_bar_region */
129 ef10_nic_register_test, /* eno_register_test */
130 #endif /* EFSYS_OPT_DIAG */
131 ef10_nic_fini, /* eno_fini */
132 ef10_nic_unprobe, /* eno_unprobe */
135 #endif /* EFSYS_OPT_HUNTINGTON */
137 #if EFSYS_OPT_MEDFORD
139 static const efx_nic_ops_t __efx_nic_medford_ops = {
140 ef10_nic_probe, /* eno_probe */
141 medford_board_cfg, /* eno_board_cfg */
142 ef10_nic_set_drv_limits, /* eno_set_drv_limits */
143 ef10_nic_reset, /* eno_reset */
144 ef10_nic_init, /* eno_init */
145 ef10_nic_get_vi_pool, /* eno_get_vi_pool */
146 ef10_nic_get_bar_region, /* eno_get_bar_region */
148 ef10_nic_register_test, /* eno_register_test */
149 #endif /* EFSYS_OPT_DIAG */
150 ef10_nic_fini, /* eno_fini */
151 ef10_nic_unprobe, /* eno_unprobe */
154 #endif /* EFSYS_OPT_MEDFORD */
156 #if EFSYS_OPT_MEDFORD2
158 static const efx_nic_ops_t __efx_nic_medford2_ops = {
159 ef10_nic_probe, /* eno_probe */
160 medford2_board_cfg, /* eno_board_cfg */
161 ef10_nic_set_drv_limits, /* eno_set_drv_limits */
162 ef10_nic_reset, /* eno_reset */
163 ef10_nic_init, /* eno_init */
164 ef10_nic_get_vi_pool, /* eno_get_vi_pool */
165 ef10_nic_get_bar_region, /* eno_get_bar_region */
167 ef10_nic_register_test, /* eno_register_test */
168 #endif /* EFSYS_OPT_DIAG */
169 ef10_nic_fini, /* eno_fini */
170 ef10_nic_unprobe, /* eno_unprobe */
173 #endif /* EFSYS_OPT_MEDFORD2 */
176 __checkReturn efx_rc_t
178 __in efx_family_t family,
179 __in efsys_identifier_t *esip,
180 __in efsys_bar_t *esbp,
181 __in efsys_lock_t *eslp,
182 __deref_out efx_nic_t **enpp)
187 EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID);
188 EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES);
190 /* Allocate a NIC object */
191 EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp);
198 enp->en_magic = EFX_NIC_MAGIC;
202 case EFX_FAMILY_SIENA:
203 enp->en_enop = &__efx_nic_siena_ops;
206 EFX_FEATURE_LFSR_HASH_INSERT |
207 EFX_FEATURE_LINK_EVENTS |
208 EFX_FEATURE_PERIODIC_MAC_STATS |
210 EFX_FEATURE_LOOKAHEAD_SPLIT |
211 EFX_FEATURE_MAC_HEADER_FILTERS |
212 EFX_FEATURE_TX_SRC_FILTERS;
214 #endif /* EFSYS_OPT_SIENA */
216 #if EFSYS_OPT_HUNTINGTON
217 case EFX_FAMILY_HUNTINGTON:
218 enp->en_enop = &__efx_nic_hunt_ops;
221 EFX_FEATURE_LINK_EVENTS |
222 EFX_FEATURE_PERIODIC_MAC_STATS |
224 EFX_FEATURE_MAC_HEADER_FILTERS |
225 EFX_FEATURE_MCDI_DMA |
226 EFX_FEATURE_PIO_BUFFERS |
227 EFX_FEATURE_FW_ASSISTED_TSO |
228 EFX_FEATURE_FW_ASSISTED_TSO_V2 |
229 EFX_FEATURE_PACKED_STREAM;
231 #endif /* EFSYS_OPT_HUNTINGTON */
233 #if EFSYS_OPT_MEDFORD
234 case EFX_FAMILY_MEDFORD:
235 enp->en_enop = &__efx_nic_medford_ops;
237 * FW_ASSISTED_TSO omitted as Medford only supports firmware
238 * assisted TSO version 2, not the v1 scheme used on Huntington.
242 EFX_FEATURE_LINK_EVENTS |
243 EFX_FEATURE_PERIODIC_MAC_STATS |
245 EFX_FEATURE_MAC_HEADER_FILTERS |
246 EFX_FEATURE_MCDI_DMA |
247 EFX_FEATURE_PIO_BUFFERS |
248 EFX_FEATURE_FW_ASSISTED_TSO_V2 |
249 EFX_FEATURE_PACKED_STREAM;
251 #endif /* EFSYS_OPT_MEDFORD */
253 #if EFSYS_OPT_MEDFORD2
254 case EFX_FAMILY_MEDFORD2:
255 enp->en_enop = &__efx_nic_medford2_ops;
258 EFX_FEATURE_LINK_EVENTS |
259 EFX_FEATURE_PERIODIC_MAC_STATS |
261 EFX_FEATURE_MAC_HEADER_FILTERS |
262 EFX_FEATURE_MCDI_DMA |
263 EFX_FEATURE_PIO_BUFFERS |
264 EFX_FEATURE_FW_ASSISTED_TSO_V2 |
265 EFX_FEATURE_PACKED_STREAM;
267 #endif /* EFSYS_OPT_MEDFORD2 */
274 enp->en_family = family;
288 /* Free the NIC object */
289 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
292 EFSYS_PROBE1(fail1, efx_rc_t, rc);
297 __checkReturn efx_rc_t
301 const efx_nic_ops_t *enop;
304 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
306 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
307 #endif /* EFSYS_OPT_MCDI */
308 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
311 if ((rc = enop->eno_probe(enp)) != 0)
314 if ((rc = efx_phy_probe(enp)) != 0)
317 enp->en_mod_flags |= EFX_MOD_PROBE;
324 enop->eno_unprobe(enp);
327 EFSYS_PROBE1(fail1, efx_rc_t, rc);
332 __checkReturn efx_rc_t
333 efx_nic_set_drv_limits(
334 __inout efx_nic_t *enp,
335 __in efx_drv_limits_t *edlp)
337 const efx_nic_ops_t *enop = enp->en_enop;
340 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
341 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
343 if (enop->eno_set_drv_limits != NULL) {
344 if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
351 EFSYS_PROBE1(fail1, efx_rc_t, rc);
356 __checkReturn efx_rc_t
357 efx_nic_get_bar_region(
359 __in efx_nic_region_t region,
360 __out uint32_t *offsetp,
363 const efx_nic_ops_t *enop = enp->en_enop;
366 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
367 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
368 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
370 if (enop->eno_get_bar_region == NULL) {
374 if ((rc = (enop->eno_get_bar_region)(enp,
375 region, offsetp, sizep)) != 0) {
385 EFSYS_PROBE1(fail1, efx_rc_t, rc);
391 __checkReturn efx_rc_t
394 __out uint32_t *evq_countp,
395 __out uint32_t *rxq_countp,
396 __out uint32_t *txq_countp)
398 const efx_nic_ops_t *enop = enp->en_enop;
399 efx_nic_cfg_t *encp = &enp->en_nic_cfg;
402 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
403 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
404 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
406 if (enop->eno_get_vi_pool != NULL) {
407 uint32_t vi_count = 0;
409 if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
412 *evq_countp = vi_count;
413 *rxq_countp = vi_count;
414 *txq_countp = vi_count;
416 /* Use NIC limits as default value */
417 *evq_countp = encp->enc_evq_limit;
418 *rxq_countp = encp->enc_rxq_limit;
419 *txq_countp = encp->enc_txq_limit;
425 EFSYS_PROBE1(fail1, efx_rc_t, rc);
431 __checkReturn efx_rc_t
435 const efx_nic_ops_t *enop = enp->en_enop;
438 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
439 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
441 if (enp->en_mod_flags & EFX_MOD_NIC) {
446 if ((rc = enop->eno_init(enp)) != 0)
449 enp->en_mod_flags |= EFX_MOD_NIC;
456 EFSYS_PROBE1(fail1, efx_rc_t, rc);
465 const efx_nic_ops_t *enop = enp->en_enop;
467 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
468 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
469 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC);
470 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
471 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
472 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
473 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
477 enp->en_mod_flags &= ~EFX_MOD_NIC;
484 const efx_nic_ops_t *enop = enp->en_enop;
486 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
488 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
489 #endif /* EFSYS_OPT_MCDI */
490 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
491 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
492 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
493 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
494 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
495 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
497 efx_phy_unprobe(enp);
499 enop->eno_unprobe(enp);
501 enp->en_mod_flags &= ~EFX_MOD_PROBE;
508 efsys_identifier_t *esip = enp->en_esip;
510 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
511 EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
513 enp->en_family = EFX_FAMILY_INVALID;
522 /* Free the NIC object */
523 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
526 __checkReturn efx_rc_t
530 const efx_nic_ops_t *enop = enp->en_enop;
531 unsigned int mod_flags;
534 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
535 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
537 * All modules except the MCDI, PROBE, NVRAM, VPD, MON
538 * (which we do not reset here) must have been shut down or never
541 * A rule of thumb here is: If the controller or MC reboots, is *any*
542 * state lost. If it's lost and needs reapplying, then the module
543 * *must* not be initialised during the reset.
545 mod_flags = enp->en_mod_flags;
546 mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
547 EFX_MOD_VPD | EFX_MOD_MON);
548 EFSYS_ASSERT3U(mod_flags, ==, 0);
549 if (mod_flags != 0) {
554 if ((rc = enop->eno_reset(enp)) != 0)
562 EFSYS_PROBE1(fail1, efx_rc_t, rc);
567 const efx_nic_cfg_t *
571 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
573 return (&(enp->en_nic_cfg));
576 __checkReturn efx_rc_t
577 efx_nic_get_fw_version(
579 __out efx_nic_fw_info_t *enfip)
581 uint16_t mc_fw_version[4];
589 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
590 EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
592 rc = efx_mcdi_version(enp, mc_fw_version, NULL, NULL);
596 rc = efx_mcdi_get_capabilities(enp, NULL,
597 &enfip->enfi_rx_dpcpu_fw_id,
598 &enfip->enfi_tx_dpcpu_fw_id,
601 enfip->enfi_dpcpu_fw_ids_valid = B_TRUE;
602 } else if (rc == ENOTSUP) {
603 enfip->enfi_dpcpu_fw_ids_valid = B_FALSE;
604 enfip->enfi_rx_dpcpu_fw_id = 0;
605 enfip->enfi_tx_dpcpu_fw_id = 0;
610 memcpy(enfip->enfi_mc_fw_version, mc_fw_version,
611 sizeof (mc_fw_version));
620 EFSYS_PROBE1(fail1, efx_rc_t, rc);
627 __checkReturn efx_rc_t
628 efx_nic_register_test(
631 const efx_nic_ops_t *enop = enp->en_enop;
634 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
635 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
636 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
638 if ((rc = enop->eno_register_test(enp)) != 0)
644 EFSYS_PROBE1(fail1, efx_rc_t, rc);
649 #endif /* EFSYS_OPT_DIAG */
651 #if EFSYS_OPT_LOOPBACK
655 __in efx_loopback_kind_t loopback_kind,
656 __out efx_qword_t *maskp)
660 EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS);
661 EFSYS_ASSERT(maskp != NULL);
663 /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
664 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
665 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
666 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
667 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
668 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
669 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
670 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
671 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
672 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
673 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
674 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
675 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
676 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
677 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
678 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
679 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
680 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
681 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
682 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT);
683 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS);
684 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS);
685 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR ==
686 EFX_LOOPBACK_XAUI_WS_FAR);
687 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR ==
688 EFX_LOOPBACK_XAUI_WS_NEAR);
689 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS);
690 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS);
691 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR ==
692 EFX_LOOPBACK_XFI_WS_FAR);
693 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS);
694 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT);
695 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR);
696 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR);
697 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS ==
698 EFX_LOOPBACK_PMA_INT_WS);
699 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS ==
700 EFX_LOOPBACK_SD_FEP2_WS);
701 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS ==
702 EFX_LOOPBACK_SD_FEP1_5_WS);
703 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS);
704 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS);
706 /* Build bitmask of possible loopback types */
707 EFX_ZERO_QWORD(mask);
709 if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) ||
710 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
711 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF);
714 if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) ||
715 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
717 * The "MAC" grouping has historically been used by drivers to
718 * mean loopbacks supported by on-chip hardware. Keep that
719 * meaning here, and include on-chip PHY layer loopbacks.
721 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA);
722 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC);
723 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII);
724 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS);
725 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI);
726 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII);
727 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII);
728 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR);
729 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI);
730 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR);
731 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR);
732 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR);
733 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR);
734 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT);
735 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR);
736 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR);
739 if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) ||
740 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
742 * The "PHY" grouping has historically been used by drivers to
743 * mean loopbacks supported by off-chip hardware. Keep that
746 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY);
747 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PHY_XS);
748 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS);
749 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD);
755 __checkReturn efx_rc_t
756 efx_mcdi_get_loopback_modes(
759 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
761 uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
762 MC_CMD_GET_LOOPBACK_MODES_OUT_LEN)];
767 (void) memset(payload, 0, sizeof (payload));
768 req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
769 req.emr_in_buf = payload;
770 req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
771 req.emr_out_buf = payload;
772 req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN;
774 efx_mcdi_execute(enp, &req);
776 if (req.emr_rc != 0) {
781 if (req.emr_out_length_used <
782 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
783 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) {
789 * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
790 * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link().
792 efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask);
795 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED));
797 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M);
798 EFX_AND_QWORD(modes, mask);
799 encp->enc_loopback_types[EFX_LINK_100FDX] = modes;
801 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G);
802 EFX_AND_QWORD(modes, mask);
803 encp->enc_loopback_types[EFX_LINK_1000FDX] = modes;
805 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G);
806 EFX_AND_QWORD(modes, mask);
807 encp->enc_loopback_types[EFX_LINK_10000FDX] = modes;
809 if (req.emr_out_length_used >=
810 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
811 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
812 /* Response includes 40G loopback modes */
814 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G);
815 EFX_AND_QWORD(modes, mask);
816 encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
819 EFX_ZERO_QWORD(modes);
820 EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
821 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
822 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
823 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
824 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
825 encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
832 EFSYS_PROBE1(fail1, efx_rc_t, rc);
837 #endif /* EFSYS_OPT_LOOPBACK */
839 __checkReturn efx_rc_t
840 efx_nic_calculate_pcie_link_bandwidth(
841 __in uint32_t pcie_link_width,
842 __in uint32_t pcie_link_gen,
843 __out uint32_t *bandwidth_mbpsp)
845 uint32_t lane_bandwidth;
846 uint32_t total_bandwidth;
849 if ((pcie_link_width == 0) || (pcie_link_width > 16) ||
850 !ISP2(pcie_link_width)) {
855 switch (pcie_link_gen) {
856 case EFX_PCIE_LINK_SPEED_GEN1:
857 /* 2.5 Gb/s raw bandwidth with 8b/10b encoding */
858 lane_bandwidth = 2000;
860 case EFX_PCIE_LINK_SPEED_GEN2:
861 /* 5.0 Gb/s raw bandwidth with 8b/10b encoding */
862 lane_bandwidth = 4000;
864 case EFX_PCIE_LINK_SPEED_GEN3:
865 /* 8.0 Gb/s raw bandwidth with 128b/130b encoding */
866 lane_bandwidth = 7877;
873 total_bandwidth = lane_bandwidth * pcie_link_width;
874 *bandwidth_mbpsp = total_bandwidth;
881 EFSYS_PROBE1(fail1, efx_rc_t, rc);
887 __checkReturn efx_rc_t
888 efx_nic_check_pcie_link_speed(
890 __in uint32_t pcie_link_width,
891 __in uint32_t pcie_link_gen,
892 __out efx_pcie_link_performance_t *resultp)
894 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
896 efx_pcie_link_performance_t result;
899 if ((encp->enc_required_pcie_bandwidth_mbps == 0) ||
900 (pcie_link_width == 0) || (pcie_link_width == 32) ||
901 (pcie_link_gen == 0)) {
903 * No usable info on what is required and/or in use. In virtual
904 * machines, sometimes the PCIe link width is reported as 0 or
905 * 32, or the speed as 0.
907 result = EFX_PCIE_LINK_PERFORMANCE_UNKNOWN_BANDWIDTH;
911 /* Calculate the available bandwidth in megabits per second */
912 rc = efx_nic_calculate_pcie_link_bandwidth(pcie_link_width,
913 pcie_link_gen, &bandwidth);
917 if (bandwidth < encp->enc_required_pcie_bandwidth_mbps) {
918 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_BANDWIDTH;
919 } else if (pcie_link_gen < encp->enc_max_pcie_link_gen) {
920 /* The link provides enough bandwidth but not optimal latency */
921 result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_LATENCY;
923 result = EFX_PCIE_LINK_PERFORMANCE_OPTIMAL;
932 EFSYS_PROBE1(fail1, efx_rc_t, rc);