__out uint32_t *portp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN,
- MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN,
+ MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN);
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD ||
enp->en_family == EFX_FAMILY_MEDFORD2);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN;
efx_mcdi_get_port_modes(
__in efx_nic_t *enp,
__out uint32_t *modesp,
- __out_opt uint32_t *current_modep)
+ __out_opt uint32_t *current_modep,
+ __out_opt uint32_t *default_modep)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PORT_MODES_IN_LEN,
- MC_CMD_GET_PORT_MODES_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PORT_MODES_IN_LEN,
+ MC_CMD_GET_PORT_MODES_OUT_LEN);
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD ||
enp->en_family == EFX_FAMILY_MEDFORD2);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PORT_MODES;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_PORT_MODES_IN_LEN;
GET_PORT_MODES_OUT_CURRENT_MODE);
}
+ if (default_modep != NULL) {
+ *default_modep = MCDI_OUT_DWORD(req,
+ GET_PORT_MODES_OUT_DEFAULT_MODE);
+ }
+
return (0);
fail3:
__in uint32_t port_id)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_VADAPTOR_ALLOC_IN_LEN,
- MC_CMD_VADAPTOR_ALLOC_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_ALLOC_IN_LEN,
+ MC_CMD_VADAPTOR_ALLOC_OUT_LEN);
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_vport_id, ==, EVB_PORT_ID_NULL);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_VADAPTOR_ALLOC;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_VADAPTOR_ALLOC_IN_LEN;
__in uint32_t port_id)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_VADAPTOR_FREE_IN_LEN,
- MC_CMD_VADAPTOR_FREE_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_FREE_IN_LEN,
+ MC_CMD_VADAPTOR_FREE_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_VADAPTOR_FREE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_VADAPTOR_FREE_IN_LEN;
__out_ecount_opt(6) uint8_t mac_addrp[6])
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_MAC_ADDRESSES_IN_LEN,
- MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_MAC_ADDRESSES_IN_LEN,
+ MC_CMD_GET_MAC_ADDRESSES_OUT_LEN);
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD ||
enp->en_family == EFX_FAMILY_MEDFORD2);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_MAC_ADDRESSES_IN_LEN;
__out_ecount_opt(6) uint8_t mac_addrp[6])
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN,
- MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN,
+ MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX);
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD ||
enp->en_family == EFX_FAMILY_MEDFORD2);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN;
__out uint32_t *dpcpu_freqp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_CLOCK_IN_LEN,
- MC_CMD_GET_CLOCK_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CLOCK_IN_LEN,
+ MC_CMD_GET_CLOCK_OUT_LEN);
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD ||
enp->en_family == EFX_FAMILY_MEDFORD2);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_CLOCK;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_CLOCK_IN_LEN;
__out uint32_t *end_paddingp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_RXDP_CONFIG_IN_LEN,
- MC_CMD_GET_RXDP_CONFIG_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_RXDP_CONFIG_IN_LEN,
+ MC_CMD_GET_RXDP_CONFIG_OUT_LEN);
uint32_t end_padding;
efx_rc_t rc;
- memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_RXDP_CONFIG;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_RXDP_CONFIG_IN_LEN;
__out_opt uint32_t *vf_nvecp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_VECTOR_CFG_IN_LEN,
- MC_CMD_GET_VECTOR_CFG_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_VECTOR_CFG_IN_LEN,
+ MC_CMD_GET_VECTOR_CFG_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_VECTOR_CFG;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_VECTOR_CFG_IN_LEN;
__out uint32_t *vi_shiftp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_ALLOC_VIS_IN_LEN,
- MC_CMD_ALLOC_VIS_EXT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_VIS_IN_LEN,
+ MC_CMD_ALLOC_VIS_EXT_OUT_LEN);
efx_rc_t rc;
if (vi_countp == NULL) {
goto fail1;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_ALLOC_VIS;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_ALLOC_VIS_IN_LEN;
__out efx_piobuf_handle_t *handlep)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_ALLOC_PIOBUF_IN_LEN,
- MC_CMD_ALLOC_PIOBUF_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_PIOBUF_IN_LEN,
+ MC_CMD_ALLOC_PIOBUF_OUT_LEN);
efx_rc_t rc;
if (handlep == NULL) {
goto fail1;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_ALLOC_PIOBUF;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN;
__in efx_piobuf_handle_t handle)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_FREE_PIOBUF_IN_LEN,
- MC_CMD_FREE_PIOBUF_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FREE_PIOBUF_IN_LEN,
+ MC_CMD_FREE_PIOBUF_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_FREE_PIOBUF;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN;
__in efx_piobuf_handle_t handle)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_LINK_PIOBUF_IN_LEN,
- MC_CMD_LINK_PIOBUF_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LINK_PIOBUF_IN_LEN,
+ MC_CMD_LINK_PIOBUF_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_LINK_PIOBUF;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN;
__in uint32_t vi_index)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_UNLINK_PIOBUF_IN_LEN,
- MC_CMD_UNLINK_PIOBUF_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_UNLINK_PIOBUF_IN_LEN,
+ MC_CMD_UNLINK_PIOBUF_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_UNLINK_PIOBUF;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN;
for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
- efx_mcdi_free_piobuf(enp, *handlep);
+ (void) efx_mcdi_free_piobuf(enp, *handlep);
*handlep = EFX_PIOBUF_HANDLE_INVALID;
}
enp->en_arch.ef10.ena_piobuf_count = 0;
for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
- efx_mcdi_free_piobuf(enp, *handlep);
+ (void) efx_mcdi_free_piobuf(enp, *handlep);
*handlep = EFX_PIOBUF_HANDLE_INVALID;
}
enp->en_arch.ef10.ena_piobuf_count = 0;
__out uint32_t *pf_countp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PF_COUNT_IN_LEN,
- MC_CMD_GET_PF_COUNT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PF_COUNT_IN_LEN,
+ MC_CMD_GET_PF_COUNT_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PF_COUNT;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_PF_COUNT_IN_LEN;
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN,
- MC_CMD_GET_CAPABILITIES_V4_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CAPABILITIES_IN_LEN,
+ 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;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_CAPABILITIES;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN;
req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_GET_CAPABILITIES_V4_OUT_LEN;
+ req.emr_out_length = MC_CMD_GET_CAPABILITIES_V5_OUT_LEN;
efx_mcdi_execute_quiet(enp, &req);
}
encp->enc_rx_prefix_size = 14;
+ /* Check if the firmware supports additional RSS modes */
+ if (CAP_FLAGS1(req, ADDITIONAL_RSS_MODES))
+ encp->enc_rx_scale_additional_modes_supported = B_TRUE;
+ else
+ encp->enc_rx_scale_additional_modes_supported = B_FALSE;
+
/* Check if the firmware supports TSO */
if (CAP_FLAGS1(req, TX_TSO))
encp->enc_fw_assisted_tso_enabled = B_TRUE;
else
encp->enc_rx_var_packed_stream_supported = B_FALSE;
+ /* Check if the firmware supports equal stride super-buffer mode */
+ if (CAP_FLAGS2(req, EQUAL_STRIDE_SUPER_BUFFER))
+ encp->enc_rx_es_super_buffer_supported = B_TRUE;
+ else
+ encp->enc_rx_es_super_buffer_supported = B_FALSE;
+
/* Check if the firmware supports FW subvariant w/o Tx checksumming */
if (CAP_FLAGS2(req, FW_SUBVARIANT_NO_TX_CSUM))
encp->enc_fw_subvariant_no_tx_csum_supported = B_TRUE;
else
encp->enc_fec_counters = B_FALSE;
+ /* Check if the firmware provides head-of-line blocking counters */
+ if (CAP_FLAGS2(req, RXDP_HLB_IDLE))
+ encp->enc_hlb_counters = B_TRUE;
+ else
+ encp->enc_hlb_counters = B_FALSE;
+
+ if (CAP_FLAGS1(req, RX_RSS_LIMITED)) {
+ /* Only one exclusive RSS context is available per port. */
+ encp->enc_rx_scale_max_exclusive_contexts = 1;
+
+ switch (enp->en_family) {
+ case EFX_FAMILY_MEDFORD2:
+ encp->enc_rx_scale_hash_alg_mask =
+ (1U << EFX_RX_HASHALG_TOEPLITZ);
+ break;
+
+ case EFX_FAMILY_MEDFORD:
+ case EFX_FAMILY_HUNTINGTON:
+ /*
+ * Packed stream firmware variant maintains a
+ * non-standard algorithm for hash computation.
+ * It implies explicit XORing together
+ * source + destination IP addresses (or last
+ * four bytes in the case of IPv6) and using the
+ * resulting value as the input to a Toeplitz hash.
+ */
+ encp->enc_rx_scale_hash_alg_mask =
+ (1U << EFX_RX_HASHALG_PACKED_STREAM);
+ break;
+
+ default:
+ rc = EINVAL;
+ goto fail5;
+ }
+
+ /* Port numbers cannot contribute to the hash value */
+ encp->enc_rx_scale_l4_hash_supported = B_FALSE;
+ } else {
+ /*
+ * Maximum number of exclusive RSS contexts.
+ * EF10 hardware supports 64 in total, but 6 are reserved
+ * for shared contexts. They are a global resource so
+ * not all may be available.
+ */
+ encp->enc_rx_scale_max_exclusive_contexts = 64 - 6;
+
+ encp->enc_rx_scale_hash_alg_mask =
+ (1U << EFX_RX_HASHALG_TOEPLITZ);
+
+ /*
+ * It is possible to use port numbers as
+ * the input data for hash computation.
+ */
+ encp->enc_rx_scale_l4_hash_supported = B_TRUE;
+ }
+ /* Check if the firmware supports "FLAG" and "MARK" filter actions */
+ if (CAP_FLAGS2(req, FILTER_ACTION_FLAG))
+ encp->enc_filter_action_flag_supported = B_TRUE;
+ else
+ encp->enc_filter_action_flag_supported = B_FALSE;
+
+ if (CAP_FLAGS2(req, FILTER_ACTION_MARK))
+ encp->enc_filter_action_mark_supported = B_TRUE;
+ else
+ encp->enc_filter_action_mark_supported = B_FALSE;
+
+ /* Get maximum supported value for "MARK" filter action */
+ if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V5_OUT_LEN)
+ encp->enc_filter_action_mark_max = MCDI_OUT_DWORD(req,
+ GET_CAPABILITIES_V5_OUT_FILTER_ACTION_MARK_MAX);
+ else
+ encp->enc_filter_action_mark_max = 0;
+
#undef CAP_FLAGS1
#undef CAP_FLAGS2
return (0);
+fail5:
+ EFSYS_PROBE(fail5);
fail4:
EFSYS_PROBE(fail4);
fail3:
int32_t count = 1; /* Default 1-1 mapping */
int32_t offset = 1; /* Default starting external port number */
- if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, ¤t)) != 0) {
+ if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, ¤t,
+ NULL)) != 0) {
/*
* No current port mode information (i.e. Huntington)
* - infer mapping from available modes
*/
if ((rc = efx_mcdi_get_port_modes(enp,
- &port_modes, NULL)) != 0) {
+ &port_modes, NULL, NULL)) != 0) {
/*
* No port mode information available
* - use default mapping
/* Alignment for WPTR updates */
encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN;
- /*
- * Maximum number of exclusive RSS contexts. EF10 hardware supports 64
- * in total, but 6 are reserved for shared contexts. They are a global
- * resource so not all may be available.
- */
- encp->enc_rx_scale_max_exclusive_contexts = 64 - 6;
-
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;
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_ENTITY_RESET_IN_LEN,
- MC_CMD_ENTITY_RESET_OUT_LEN)];
+ 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;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_ENTITY_RESET;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN;
return (rc);
}
+ __checkReturn boolean_t
+ef10_nic_hw_unavailable(
+ __in efx_nic_t *enp)
+{
+ efx_dword_t dword;
+
+ if (enp->en_reset_flags & EFX_RESET_HW_UNAVAIL)
+ return (B_TRUE);
+
+ EFX_BAR_READD(enp, ER_DZ_BIU_MC_SFT_STATUS_REG, &dword, B_FALSE);
+ if (EFX_DWORD_FIELD(dword, EFX_DWORD_0) == 0xffffffff)
+ goto unavail;
+
+ return (B_FALSE);
+
+unavail:
+ ef10_nic_set_hw_unavailable(enp);
+
+ return (B_TRUE);
+}
+
+ void
+ef10_nic_set_hw_unavailable(
+ __in efx_nic_t *enp)
+{
+ EFSYS_PROBE(hw_unavail);
+ enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL;
+}
+
+
void
ef10_nic_fini(
__in efx_nic_t *enp)
__out uint32_t *valuep)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_NIC_GLOBAL_IN_LEN,
- MC_CMD_GET_NIC_GLOBAL_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_NIC_GLOBAL_IN_LEN,
+ MC_CMD_GET_NIC_GLOBAL_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_NIC_GLOBAL;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_NIC_GLOBAL_IN_LEN;
__in uint32_t value)
{
efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_SET_NIC_GLOBAL_IN_LEN];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_NIC_GLOBAL_IN_LEN, 0);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_NIC_GLOBAL;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_SET_NIC_GLOBAL_IN_LEN;