#include "mcdi_mon.h"
#endif
-#if EFX_OPTS_EF10()
+#if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10()
#include "ef10_tlv_layout.h"
MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN);
efx_rc_t rc;
- EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
+ EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp));
req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
req.emr_in_buf = payload;
MC_CMD_GET_PORT_MODES_OUT_LEN);
efx_rc_t rc;
- EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
+ EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp));
req.emr_cmd = MC_CMD_GET_PORT_MODES;
req.emr_in_buf = payload;
return (rc);
}
+#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */
+
+#if EFX_OPTS_EF10()
+
__checkReturn efx_rc_t
efx_mcdi_vadaptor_alloc(
__in efx_nic_t *enp,
return (rc);
}
+#endif /* EFX_OPTS_EF10() */
+
+#if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10()
+
__checkReturn efx_rc_t
efx_mcdi_get_mac_address_pf(
__in efx_nic_t *enp,
MC_CMD_GET_MAC_ADDRESSES_OUT_LEN);
efx_rc_t rc;
- EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
+ EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp));
req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
req.emr_in_buf = payload;
MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX);
efx_rc_t rc;
- EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
+ EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp));
req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES;
req.emr_in_buf = payload;
MC_CMD_GET_CLOCK_OUT_LEN);
efx_rc_t rc;
- EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
+ EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp));
req.emr_cmd = MC_CMD_GET_CLOCK;
req.emr_in_buf = payload;
return (rc);
}
-static __checkReturn efx_rc_t
+ __checkReturn efx_rc_t
efx_mcdi_alloc_vis(
__in efx_nic_t *enp,
__in uint32_t min_vi_count,
}
-static __checkReturn efx_rc_t
+ __checkReturn efx_rc_t
efx_mcdi_free_vis(
__in efx_nic_t *enp)
{
return (rc);
}
+#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */
+
+#if EFX_OPTS_EF10()
static __checkReturn efx_rc_t
efx_mcdi_alloc_piobuf(
return (efx_mcdi_unlink_piobuf(enp, vi_index));
}
+#endif /* EFX_OPTS_EF10() */
+
+#if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10()
+
static __checkReturn efx_rc_t
ef10_mcdi_get_pf_count(
__in efx_nic_t *enp,
MC_CMD_GET_CAPABILITIES_V5_OUT_LEN);
efx_rc_t rc;
- if ((rc = ef10_mcdi_get_pf_count(enp, &encp->enc_hw_pf_count)) != 0)
- goto fail1;
-
-
req.emr_cmd = MC_CMD_GET_CAPABILITIES;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN;
if (req.emr_rc != 0) {
rc = req.emr_rc;
- goto fail2;
+ goto fail1;
}
if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_OUT_LEN) {
rc = EMSGSIZE;
- goto fail3;
+ goto fail2;
}
#define CAP_FLAGS1(_req, _flag) \
(MCDI_OUT_DWORD((_req), GET_CAPABILITIES_V2_OUT_FLAGS2) & \
(1u << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## _flag ## _LBN))))
- /*
- * Huntington RXDP firmware inserts a 0 or 14 byte prefix.
- * We only support the 14 byte prefix here.
- */
- if (CAP_FLAGS1(req, RX_PREFIX_LEN_14) == 0) {
- rc = ENOTSUP;
- goto fail4;
- }
- encp->enc_rx_prefix_size = 14;
+ /* Check if RXDP firmware inserts 14 byte prefix */
+ if (CAP_FLAGS1(req, RX_PREFIX_LEN_14))
+ encp->enc_rx_prefix_size = 14;
+ else
+ encp->enc_rx_prefix_size = 0;
#if EFSYS_OPT_RX_SCALE
/* Check if the firmware supports additional RSS modes */
default:
rc = EINVAL;
- goto fail5;
+ goto fail3;
}
/* Port numbers cannot contribute to the hash value */
return (0);
#if EFSYS_OPT_RX_SCALE
-fail5:
- EFSYS_PROBE(fail5);
-#endif /* EFSYS_OPT_RX_SCALE */
-fail4:
- EFSYS_PROBE(fail4);
fail3:
EFSYS_PROBE(fail3);
+#endif /* EFSYS_OPT_RX_SCALE */
fail2:
EFSYS_PROBE(fail2);
fail1:
(1U << TLV_PORT_MODE_NA_2x2), /* mode 14 */
{ EFX_EXT_PORT_NA, 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA }
},
+ /*
+ * Modes that on Riverhead allocate each port number to a separate
+ * cage.
+ * port 0 -> cage 1
+ * port 1 -> cage 2
+ */
+ {
+ EFX_FAMILY_RIVERHEAD,
+ (1U << TLV_PORT_MODE_1x1_NA) | /* mode 0 */
+ (1U << TLV_PORT_MODE_1x4_NA) | /* mode 1 */
+ (1U << TLV_PORT_MODE_1x1_1x1), /* mode 2 */
+ { 0, 1, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA }
+ },
};
static __checkReturn efx_rc_t
return (rc);
}
-static __checkReturn efx_rc_t
-ef10_set_workaround_bug26807(
- __in efx_nic_t *enp)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint32_t flags;
- efx_rc_t rc;
-
- /*
- * If the bug26807 workaround is enabled, then firmware has enabled
- * support for chained multicast filters. Firmware will reset (FLR)
- * functions which have filters in the hardware filter table when the
- * workaround is enabled/disabled.
- *
- * We must recheck if the workaround is enabled after inserting the
- * first hardware filter, in case it has been changed since this check.
- */
- rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG26807,
- B_TRUE, &flags);
- if (rc == 0) {
- encp->enc_bug26807_workaround = B_TRUE;
- if (flags & (1 << MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN)) {
- /*
- * Other functions had installed filters before the
- * workaround was enabled, and they have been reset
- * by firmware.
- */
- EFSYS_PROBE(bug26807_workaround_flr_done);
- /* FIXME: bump MC warm boot count ? */
- }
- } else if (rc == EACCES) {
- /*
- * Unprivileged functions cannot enable the workaround in older
- * firmware.
- */
- encp->enc_bug26807_workaround = B_FALSE;
- } else if ((rc == ENOTSUP) || (rc == ENOENT)) {
- encp->enc_bug26807_workaround = B_FALSE;
- } else {
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-static __checkReturn efx_rc_t
-ef10_nic_board_cfg(
+ __checkReturn efx_rc_t
+efx_mcdi_nic_board_cfg(
__in efx_nic_t *enp)
{
- const efx_nic_ops_t *enop = enp->en_enop;
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
ef10_link_state_t els;
encp->enc_pf = pf;
encp->enc_vf = vf;
+ if ((rc = ef10_mcdi_get_pf_count(enp, &encp->enc_hw_pf_count)) != 0)
+ goto fail4;
+
/* MAC address for this function */
if (EFX_PCI_FUNCTION_IS_PF(encp)) {
rc = efx_mcdi_get_mac_address_pf(enp, mac_addr);
rc = efx_mcdi_get_mac_address_vf(enp, mac_addr);
}
if (rc != 0)
- goto fail4;
+ goto fail5;
EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
if (rc == EACCES)
board_type = 0;
else
- goto fail5;
+ goto fail6;
}
encp->enc_board_type = board_type;
- encp->enc_clk_mult = 1; /* not used for EF10 */
/* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
- goto fail6;
+ goto fail7;
/*
* Firmware with support for *_FEC capability bits does not
/* Obtain the default PHY advertised capabilities */
if ((rc = ef10_phy_get_link(enp, &els)) != 0)
- goto fail7;
+ goto fail8;
epp->ep_default_adv_cap_mask = els.epls.epls_adv_cap_mask;
epp->ep_adv_cap_mask = els.epls.epls_adv_cap_mask;
/* Check capabilities of running datapath firmware */
if ((rc = ef10_get_datapath_caps(enp)) != 0)
- goto fail8;
-
- /* Alignment for WPTR updates */
- encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN;
-
- encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT);
- /* No boundary crossing limits */
- encp->enc_tx_dma_desc_boundary = 0;
-
- /*
- * Maximum number of bytes into the frame the TCP header can start for
- * firmware assisted TSO to work.
- */
- encp->enc_tx_tso_tcp_header_offset_limit = EF10_TCP_HEADER_OFFSET_LIMIT;
-
- /*
- * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
- * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
- * resources (allocated to this PCIe function), which is zero until
- * after we have allocated VIs.
- */
- encp->enc_evq_limit = 1024;
- encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
- encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
-
- encp->enc_buftbl_limit = UINT32_MAX;
+ goto fail9;
/* Get interrupt vector limits */
if ((rc = efx_mcdi_get_vector_cfg(enp, &base, &nvec, NULL)) != 0) {
if (EFX_PCI_FUNCTION_IS_PF(encp))
- goto fail9;
+ goto fail10;
/* Ignore error (cannot query vector limits from a VF). */
base = 0;
* can result in time-of-check/time-of-use bugs.
*/
if ((rc = ef10_get_privilege_mask(enp, &mask)) != 0)
- goto fail10;
- encp->enc_privilege_mask = mask;
-
- if ((rc = ef10_set_workaround_bug26807(enp)) != 0)
goto fail11;
-
- /* Get remaining controller-specific board config */
- if ((rc = enop->eno_board_cfg(enp)) != 0)
- if (rc != EACCES)
- goto fail12;
+ encp->enc_privilege_mask = mask;
return (0);
-fail12:
- EFSYS_PROBE(fail12);
fail11:
EFSYS_PROBE(fail11);
fail10:
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+efx_mcdi_entity_reset(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ENTITY_RESET_IN_LEN,
+ MC_CMD_ENTITY_RESET_OUT_LEN);
+ efx_rc_t rc;
+
+ req.emr_cmd = MC_CMD_ENTITY_RESET;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN;
+
+ MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG,
+ ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */
+
+#if EFX_OPTS_EF10()
+
+static __checkReturn efx_rc_t
+ef10_set_workaround_bug26807(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint32_t flags;
+ efx_rc_t rc;
+
+ /*
+ * If the bug26807 workaround is enabled, then firmware has enabled
+ * support for chained multicast filters. Firmware will reset (FLR)
+ * functions which have filters in the hardware filter table when the
+ * workaround is enabled/disabled.
+ *
+ * We must recheck if the workaround is enabled after inserting the
+ * first hardware filter, in case it has been changed since this check.
+ */
+ rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG26807,
+ B_TRUE, &flags);
+ if (rc == 0) {
+ encp->enc_bug26807_workaround = B_TRUE;
+ if (flags & (1 << MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN)) {
+ /*
+ * Other functions had installed filters before the
+ * workaround was enabled, and they have been reset
+ * by firmware.
+ */
+ EFSYS_PROBE(bug26807_workaround_flr_done);
+ /* FIXME: bump MC warm boot count ? */
+ }
+ } else if (rc == EACCES) {
+ /*
+ * Unprivileged functions cannot enable the workaround in older
+ * firmware.
+ */
+ encp->enc_bug26807_workaround = B_FALSE;
+ } else if ((rc == ENOTSUP) || (rc == ENOENT)) {
+ encp->enc_bug26807_workaround = B_FALSE;
+ } else {
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+static __checkReturn efx_rc_t
+ef10_nic_board_cfg(
+ __in efx_nic_t *enp)
+{
+ const efx_nic_ops_t *enop = enp->en_enop;
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_rc_t rc;
+
+ if ((rc = efx_mcdi_nic_board_cfg(enp)) != 0)
+ goto fail1;
+
+ /*
+ * Huntington RXDP firmware inserts a 0 or 14 byte prefix.
+ * We only support the 14 byte prefix here.
+ */
+ if (encp->enc_rx_prefix_size != 14) {
+ rc = ENOTSUP;
+ goto fail2;
+ }
+
+ encp->enc_clk_mult = 1; /* not used for EF10 */
+
+ /* Alignment for WPTR updates */
+ encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN;
+
+ encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT);
+ /* No boundary crossing limits */
+ encp->enc_tx_dma_desc_boundary = 0;
+
+ /*
+ * Maximum number of bytes into the frame the TCP header can start for
+ * firmware assisted TSO to work.
+ */
+ encp->enc_tx_tso_tcp_header_offset_limit = EF10_TCP_HEADER_OFFSET_LIMIT;
+
+ /*
+ * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
+ * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
+ * resources (allocated to this PCIe function), which is zero until
+ * after we have allocated VIs.
+ */
+ encp->enc_evq_limit = 1024;
+ encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
+ encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
+
+ encp->enc_buftbl_limit = UINT32_MAX;
+
+ if ((rc = ef10_set_workaround_bug26807(enp)) != 0)
+ goto fail3;
+
+ /* Get remaining controller-specific board config */
+ if ((rc = enop->eno_board_cfg(enp)) != 0)
+ if (rc != EACCES)
+ goto fail4;
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
return (rc);
}
}
#endif
- encp->enc_features = enp->en_features;
-
return (0);
#if EFSYS_OPT_MON_STATS
ef10_nic_reset(
__in efx_nic_t *enp)
{
- efx_mcdi_req_t req;
- EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ENTITY_RESET_IN_LEN,
- MC_CMD_ENTITY_RESET_OUT_LEN);
efx_rc_t rc;
/* ef10_nic_reset() is called to recover from BADASSERT failures. */
if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
goto fail2;
- req.emr_cmd = MC_CMD_ENTITY_RESET;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN;
-
- MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG,
- ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_entity_reset(enp)) != 0)
goto fail3;
- }
/* Clear RX/TX DMA queue errors */
enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR);