siena_nic_init, /* eno_init */
NULL, /* eno_get_vi_pool */
NULL, /* eno_get_bar_region */
+ NULL, /* eno_hw_unavailable */
+ NULL, /* eno_set_hw_unavailable */
#if EFSYS_OPT_DIAG
siena_nic_register_test, /* eno_register_test */
#endif /* EFSYS_OPT_DIAG */
ef10_nic_init, /* eno_init */
ef10_nic_get_vi_pool, /* eno_get_vi_pool */
ef10_nic_get_bar_region, /* eno_get_bar_region */
+ ef10_nic_hw_unavailable, /* eno_hw_unavailable */
+ ef10_nic_set_hw_unavailable, /* eno_set_hw_unavailable */
#if EFSYS_OPT_DIAG
ef10_nic_register_test, /* eno_register_test */
#endif /* EFSYS_OPT_DIAG */
ef10_nic_init, /* eno_init */
ef10_nic_get_vi_pool, /* eno_get_vi_pool */
ef10_nic_get_bar_region, /* eno_get_bar_region */
+ ef10_nic_hw_unavailable, /* eno_hw_unavailable */
+ ef10_nic_set_hw_unavailable, /* eno_set_hw_unavailable */
#if EFSYS_OPT_DIAG
ef10_nic_register_test, /* eno_register_test */
#endif /* EFSYS_OPT_DIAG */
ef10_nic_init, /* eno_init */
ef10_nic_get_vi_pool, /* eno_get_vi_pool */
ef10_nic_get_bar_region, /* eno_get_bar_region */
+ ef10_nic_hw_unavailable, /* eno_hw_unavailable */
+ ef10_nic_set_hw_unavailable, /* eno_set_hw_unavailable */
#if EFSYS_OPT_DIAG
ef10_nic_register_test, /* eno_register_test */
#endif /* EFSYS_OPT_DIAG */
EFX_FEATURE_PIO_BUFFERS |
EFX_FEATURE_FW_ASSISTED_TSO |
EFX_FEATURE_FW_ASSISTED_TSO_V2 |
- EFX_FEATURE_PACKED_STREAM;
+ EFX_FEATURE_PACKED_STREAM |
+ EFX_FEATURE_TXQ_CKSUM_OP_DESC;
break;
#endif /* EFSYS_OPT_HUNTINGTON */
EFX_FEATURE_MCDI_DMA |
EFX_FEATURE_PIO_BUFFERS |
EFX_FEATURE_FW_ASSISTED_TSO_V2 |
- EFX_FEATURE_PACKED_STREAM;
+ EFX_FEATURE_PACKED_STREAM |
+ EFX_FEATURE_TXQ_CKSUM_OP_DESC;
break;
#endif /* EFSYS_OPT_MEDFORD */
EFX_FEATURE_MCDI_DMA |
EFX_FEATURE_PIO_BUFFERS |
EFX_FEATURE_FW_ASSISTED_TSO_V2 |
- EFX_FEATURE_PACKED_STREAM;
+ EFX_FEATURE_PACKED_STREAM |
+ EFX_FEATURE_TXQ_CKSUM_OP_DESC;
break;
#endif /* EFSYS_OPT_MEDFORD2 */
__checkReturn efx_rc_t
efx_nic_probe(
- __in efx_nic_t *enp)
+ __in efx_nic_t *enp,
+ __in efx_fw_variant_t efv)
{
const efx_nic_ops_t *enop;
efx_rc_t rc;
#endif /* EFSYS_OPT_MCDI */
EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
+ /* Ensure FW variant codes match with MC_CMD_FW codes */
+ EFX_STATIC_ASSERT(EFX_FW_VARIANT_FULL_FEATURED ==
+ MC_CMD_FW_FULL_FEATURED);
+ EFX_STATIC_ASSERT(EFX_FW_VARIANT_LOW_LATENCY ==
+ MC_CMD_FW_LOW_LATENCY);
+ EFX_STATIC_ASSERT(EFX_FW_VARIANT_PACKED_STREAM ==
+ MC_CMD_FW_PACKED_STREAM);
+ EFX_STATIC_ASSERT(EFX_FW_VARIANT_HIGH_TX_RATE ==
+ MC_CMD_FW_HIGH_TX_RATE);
+ EFX_STATIC_ASSERT(EFX_FW_VARIANT_PACKED_STREAM_HASH_MODE_1 ==
+ MC_CMD_FW_PACKED_STREAM_HASH_MODE_1);
+ EFX_STATIC_ASSERT(EFX_FW_VARIANT_RULES_ENGINE ==
+ MC_CMD_FW_RULES_ENGINE);
+ EFX_STATIC_ASSERT(EFX_FW_VARIANT_DPDK ==
+ MC_CMD_FW_DPDK);
+ EFX_STATIC_ASSERT(EFX_FW_VARIANT_DONT_CARE ==
+ (int)MC_CMD_FW_DONT_CARE);
+
enop = enp->en_enop;
+ enp->efv = efv;
+
if ((rc = enop->eno_probe(enp)) != 0)
goto fail1;
return (rc);
}
+ __checkReturn efx_rc_t
+efx_nic_set_drv_version(
+ __inout efx_nic_t *enp,
+ __in_ecount(length) char const *verp,
+ __in size_t length)
+{
+ efx_rc_t rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
+
+ /*
+ * length is the string content length in bytes.
+ * Accept any content which fits into the version
+ * buffer, excluding the last byte. This is reserved
+ * for an appended NUL terminator.
+ */
+ if (length >= sizeof (enp->en_drv_version)) {
+ rc = E2BIG;
+ goto fail1;
+ }
+
+ (void) memset(enp->en_drv_version, 0,
+ sizeof (enp->en_drv_version));
+ memcpy(enp->en_drv_version, verp, length);
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+
__checkReturn efx_rc_t
efx_nic_get_bar_region(
__in efx_nic_t *enp,
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
/*
- * All modules except the MCDI, PROBE, NVRAM, VPD, MON
+ * All modules except the MCDI, PROBE, NVRAM, VPD, MON, TUNNEL
* (which we do not reset here) must have been shut down or never
* initialized.
*
*/
mod_flags = enp->en_mod_flags;
mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
- EFX_MOD_VPD | EFX_MOD_MON);
+ EFX_MOD_VPD | EFX_MOD_MON);
+#if EFSYS_OPT_TUNNEL
+ mod_flags &= ~EFX_MOD_TUNNEL;
+#endif /* EFSYS_OPT_TUNNEL */
EFSYS_ASSERT3U(mod_flags, ==, 0);
if (mod_flags != 0) {
rc = EINVAL;
const efx_nic_cfg_t *
efx_nic_cfg_get(
- __in efx_nic_t *enp)
+ __in const efx_nic_t *enp)
{
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
return (&(enp->en_nic_cfg));
}
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
+ /* Ensure RXDP_FW_ID codes match with MC_CMD_GET_CAPABILITIES codes */
+ EFX_STATIC_ASSERT(EFX_RXDP_FULL_FEATURED_FW_ID ==
+ MC_CMD_GET_CAPABILITIES_OUT_RXDP);
+ EFX_STATIC_ASSERT(EFX_RXDP_LOW_LATENCY_FW_ID ==
+ MC_CMD_GET_CAPABILITIES_OUT_RXDP_LOW_LATENCY);
+ EFX_STATIC_ASSERT(EFX_RXDP_PACKED_STREAM_FW_ID ==
+ MC_CMD_GET_CAPABILITIES_OUT_RXDP_PACKED_STREAM);
+ EFX_STATIC_ASSERT(EFX_RXDP_RULES_ENGINE_FW_ID ==
+ MC_CMD_GET_CAPABILITIES_OUT_RXDP_RULES_ENGINE);
+ EFX_STATIC_ASSERT(EFX_RXDP_DPDK_FW_ID ==
+ MC_CMD_GET_CAPABILITIES_OUT_RXDP_DPDK);
+
rc = efx_mcdi_version(enp, mc_fw_version, NULL, NULL);
if (rc != 0)
goto fail2;
return (rc);
}
+ __checkReturn boolean_t
+efx_nic_hw_unavailable(
+ __in efx_nic_t *enp)
+{
+ const efx_nic_ops_t *enop = enp->en_enop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ /* NOTE: can be used by MCDI before NIC probe */
+
+ if (enop->eno_hw_unavailable != NULL) {
+ if ((enop->eno_hw_unavailable)(enp) != B_FALSE)
+ goto unavail;
+ }
+
+ return (B_FALSE);
+
+unavail:
+ return (B_TRUE);
+}
+
+ void
+efx_nic_set_hw_unavailable(
+ __in efx_nic_t *enp)
+{
+ const efx_nic_ops_t *enop = enp->en_enop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+ if (enop->eno_set_hw_unavailable != NULL)
+ enop->eno_set_hw_unavailable(enp);
+}
+
+
#if EFSYS_OPT_DIAG
__checkReturn efx_rc_t
LOOPBACK_CHECK(SD_FEP1_5_WS, SD_FEP1_5_WS);
LOOPBACK_CHECK(SD_FEP_WS, SD_FEP_WS);
LOOPBACK_CHECK(SD_FES_WS, SD_FES_WS);
+ LOOPBACK_CHECK(AOE_INT_NEAR, AOE_INT_NEAR);
+ LOOPBACK_CHECK(DATA_WS, DATA_WS);
+ LOOPBACK_CHECK(FORCE_EXT_LINK, FORCE_EXT_LINK);
#undef LOOPBACK_CHECK
/* Build bitmask of possible loopback types */
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
- MC_CMD_GET_LOOPBACK_MODES_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
+ MC_CMD_GET_LOOPBACK_MODES_OUT_V2_LEN);
efx_qword_t mask;
efx_qword_t modes;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN;
+ req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_V2_LEN;
efx_mcdi_execute(enp, &req);
MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
/* Response includes 40G loopback modes */
- modes =
- *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G);
+ modes = *MCDI_OUT2(req, efx_qword_t,
+ GET_LOOPBACK_MODES_OUT_40G);
EFX_AND_QWORD(modes, mask);
encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
}
+ if (req.emr_out_length_used >=
+ MC_CMD_GET_LOOPBACK_MODES_OUT_V2_25G_OFST +
+ MC_CMD_GET_LOOPBACK_MODES_OUT_V2_25G_LEN) {
+ /* Response includes 25G loopback modes */
+ modes = *MCDI_OUT2(req, efx_qword_t,
+ GET_LOOPBACK_MODES_OUT_V2_25G);
+ EFX_AND_QWORD(modes, mask);
+ encp->enc_loopback_types[EFX_LINK_25000FDX] = modes;
+ }
+
+ if (req.emr_out_length_used >=
+ MC_CMD_GET_LOOPBACK_MODES_OUT_V2_50G_OFST +
+ MC_CMD_GET_LOOPBACK_MODES_OUT_V2_50G_LEN) {
+ /* Response includes 50G loopback modes */
+ modes = *MCDI_OUT2(req, efx_qword_t,
+ GET_LOOPBACK_MODES_OUT_V2_50G);
+ EFX_AND_QWORD(modes, mask);
+ encp->enc_loopback_types[EFX_LINK_50000FDX] = modes;
+ }
+
+ if (req.emr_out_length_used >=
+ MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100G_OFST +
+ MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100G_LEN) {
+ /* Response includes 100G loopback modes */
+ modes = *MCDI_OUT2(req, efx_qword_t,
+ GET_LOOPBACK_MODES_OUT_V2_100G);
+ EFX_AND_QWORD(modes, mask);
+ encp->enc_loopback_types[EFX_LINK_100000FDX] = modes;
+ }
+
EFX_ZERO_QWORD(modes);
EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
+ EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_25000FDX]);
+ EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_50000FDX]);
+ EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100000FDX]);
encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
return (0);
return (rc);
}
+#if EFSYS_OPT_FW_SUBVARIANT_AWARE
+
+ __checkReturn efx_rc_t
+efx_nic_get_fw_subvariant(
+ __in efx_nic_t *enp,
+ __out efx_nic_fw_subvariant_t *subvariantp)
+{
+ efx_rc_t rc;
+ uint32_t value;
+
+ rc = efx_mcdi_get_nic_global(enp,
+ MC_CMD_SET_NIC_GLOBAL_IN_FIRMWARE_SUBVARIANT, &value);
+ if (rc != 0)
+ goto fail1;
+
+ /* Mapping is not required since values match MCDI */
+ EFX_STATIC_ASSERT(EFX_NIC_FW_SUBVARIANT_DEFAULT ==
+ MC_CMD_SET_NIC_GLOBAL_IN_FW_SUBVARIANT_DEFAULT);
+ EFX_STATIC_ASSERT(EFX_NIC_FW_SUBVARIANT_NO_TX_CSUM ==
+ MC_CMD_SET_NIC_GLOBAL_IN_FW_SUBVARIANT_NO_TX_CSUM);
+
+ switch (value) {
+ case MC_CMD_SET_NIC_GLOBAL_IN_FW_SUBVARIANT_DEFAULT:
+ case MC_CMD_SET_NIC_GLOBAL_IN_FW_SUBVARIANT_NO_TX_CSUM:
+ *subvariantp = value;
+ break;
+ default:
+ rc = EINVAL;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+efx_nic_set_fw_subvariant(
+ __in efx_nic_t *enp,
+ __in efx_nic_fw_subvariant_t subvariant)
+{
+ efx_rc_t rc;
+
+ switch (subvariant) {
+ case EFX_NIC_FW_SUBVARIANT_DEFAULT:
+ case EFX_NIC_FW_SUBVARIANT_NO_TX_CSUM:
+ /* Mapping is not required since values match MCDI */
+ break;
+ default:
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ rc = efx_mcdi_set_nic_global(enp,
+ MC_CMD_SET_NIC_GLOBAL_IN_FIRMWARE_SUBVARIANT, subvariant);
+ if (rc != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_FW_SUBVARIANT_AWARE */
__checkReturn efx_rc_t
efx_nic_check_pcie_link_speed(