X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcommon%2Fsfc_efx%2Fbase%2Fef10_rx.c;h=1b4f3f0152186bd94e9180f814e5c8759f0f2f3f;hb=40f94ce9fa6217ba33cda0c42fd732b77aaf4791;hp=bfa55337c270449070f5b55fc7db639d50adf22d;hpb=5e111ed87999b2df4084b4d9c95643c98df1ba48;p=dpdk.git diff --git a/drivers/common/sfc_efx/base/ef10_rx.c b/drivers/common/sfc_efx/base/ef10_rx.c index bfa55337c2..1b4f3f0152 100644 --- a/drivers/common/sfc_efx/base/ef10_rx.c +++ b/drivers/common/sfc_efx/base/ef10_rx.c @@ -8,191 +8,7 @@ #include "efx_impl.h" -#if EFX_OPTS_EF10() - - -static __checkReturn efx_rc_t -efx_mcdi_init_rxq( - __in efx_nic_t *enp, - __in uint32_t ndescs, - __in efx_evq_t *eep, - __in uint32_t label, - __in uint32_t instance, - __in efsys_mem_t *esmp, - __in boolean_t disable_scatter, - __in boolean_t want_inner_classes, - __in uint32_t buf_size, - __in uint32_t ps_bufsize, - __in uint32_t es_bufs_per_desc, - __in uint32_t es_max_dma_len, - __in uint32_t es_buf_stride, - __in uint32_t hol_block_timeout) -{ - efx_nic_cfg_t *encp = &(enp->en_nic_cfg); - efx_mcdi_req_t req; - EFX_MCDI_DECLARE_BUF(payload, MC_CMD_INIT_RXQ_V4_IN_LEN, - MC_CMD_INIT_RXQ_V4_OUT_LEN); - int npages = efx_rxq_nbufs(enp, ndescs); - int i; - efx_qword_t *dma_addr; - uint64_t addr; - efx_rc_t rc; - uint32_t dma_mode; - boolean_t want_outer_classes; - boolean_t no_cont_ev; - - EFSYS_ASSERT3U(ndescs, <=, encp->enc_rxq_max_ndescs); - - if ((esmp == NULL) || - (EFSYS_MEM_SIZE(esmp) < efx_rxq_size(enp, ndescs))) { - rc = EINVAL; - goto fail1; - } - - no_cont_ev = (eep->ee_flags & EFX_EVQ_FLAGS_NO_CONT_EV); - if ((no_cont_ev == B_TRUE) && (disable_scatter == B_FALSE)) { - /* TODO: Support scatter in NO_CONT_EV mode */ - rc = EINVAL; - goto fail2; - } - - if (ps_bufsize > 0) - dma_mode = MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM; - else if (es_bufs_per_desc > 0) - dma_mode = MC_CMD_INIT_RXQ_V3_IN_EQUAL_STRIDE_SUPER_BUFFER; - else - dma_mode = MC_CMD_INIT_RXQ_EXT_IN_SINGLE_PACKET; - - if (encp->enc_tunnel_encapsulations_supported != 0 && - !want_inner_classes) { - /* - * WANT_OUTER_CLASSES can only be specified on hardware which - * supports tunnel encapsulation offloads, even though it is - * effectively the behaviour the hardware gives. - * - * Also, on hardware which does support such offloads, older - * firmware rejects the flag if the offloads are not supported - * by the current firmware variant, which means this may fail if - * the capabilities are not updated when the firmware variant - * changes. This is not an issue on newer firmware, as it was - * changed in bug 69842 (v6.4.2.1007) to permit this flag to be - * specified on all firmware variants. - */ - want_outer_classes = B_TRUE; - } else { - want_outer_classes = B_FALSE; - } - - req.emr_cmd = MC_CMD_INIT_RXQ; - req.emr_in_buf = payload; - req.emr_in_length = MC_CMD_INIT_RXQ_V4_IN_LEN; - req.emr_out_buf = payload; - req.emr_out_length = MC_CMD_INIT_RXQ_V4_OUT_LEN; - - MCDI_IN_SET_DWORD(req, INIT_RXQ_EXT_IN_SIZE, ndescs); - MCDI_IN_SET_DWORD(req, INIT_RXQ_EXT_IN_TARGET_EVQ, eep->ee_index); - MCDI_IN_SET_DWORD(req, INIT_RXQ_EXT_IN_LABEL, label); - MCDI_IN_SET_DWORD(req, INIT_RXQ_EXT_IN_INSTANCE, instance); - MCDI_IN_POPULATE_DWORD_10(req, INIT_RXQ_EXT_IN_FLAGS, - INIT_RXQ_EXT_IN_FLAG_BUFF_MODE, 0, - INIT_RXQ_EXT_IN_FLAG_HDR_SPLIT, 0, - INIT_RXQ_EXT_IN_FLAG_TIMESTAMP, 0, - INIT_RXQ_EXT_IN_CRC_MODE, 0, - INIT_RXQ_EXT_IN_FLAG_PREFIX, 1, - INIT_RXQ_EXT_IN_FLAG_DISABLE_SCATTER, disable_scatter, - INIT_RXQ_EXT_IN_DMA_MODE, - dma_mode, - INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE, ps_bufsize, - INIT_RXQ_EXT_IN_FLAG_WANT_OUTER_CLASSES, want_outer_classes, - INIT_RXQ_EXT_IN_FLAG_NO_CONT_EV, no_cont_ev); - MCDI_IN_SET_DWORD(req, INIT_RXQ_EXT_IN_OWNER_ID, 0); - MCDI_IN_SET_DWORD(req, INIT_RXQ_EXT_IN_PORT_ID, enp->en_vport_id); - - if (es_bufs_per_desc > 0) { - MCDI_IN_SET_DWORD(req, - INIT_RXQ_V3_IN_ES_PACKET_BUFFERS_PER_BUCKET, - es_bufs_per_desc); - MCDI_IN_SET_DWORD(req, - INIT_RXQ_V3_IN_ES_MAX_DMA_LEN, es_max_dma_len); - MCDI_IN_SET_DWORD(req, - INIT_RXQ_V3_IN_ES_PACKET_STRIDE, es_buf_stride); - MCDI_IN_SET_DWORD(req, - INIT_RXQ_V3_IN_ES_HEAD_OF_LINE_BLOCK_TIMEOUT, - hol_block_timeout); - } - - if (encp->enc_init_rxq_with_buffer_size) - MCDI_IN_SET_DWORD(req, INIT_RXQ_V4_IN_BUFFER_SIZE_BYTES, - buf_size); - - dma_addr = MCDI_IN2(req, efx_qword_t, INIT_RXQ_IN_DMA_ADDR); - addr = EFSYS_MEM_ADDR(esmp); - - for (i = 0; i < npages; i++) { - EFX_POPULATE_QWORD_2(*dma_addr, - EFX_DWORD_1, (uint32_t)(addr >> 32), - EFX_DWORD_0, (uint32_t)(addr & 0xffffffff)); - - dma_addr++; - addr += EFX_BUF_SIZE; - } - - efx_mcdi_execute(enp, &req); - - if (req.emr_rc != 0) { - rc = req.emr_rc; - goto fail3; - } - - return (0); - -fail3: - EFSYS_PROBE(fail3); -fail2: - EFSYS_PROBE(fail2); -fail1: - EFSYS_PROBE1(fail1, efx_rc_t, rc); - - return (rc); -} - -static __checkReturn efx_rc_t -efx_mcdi_fini_rxq( - __in efx_nic_t *enp, - __in uint32_t instance) -{ - efx_mcdi_req_t req; - EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FINI_RXQ_IN_LEN, - MC_CMD_FINI_RXQ_OUT_LEN); - efx_rc_t rc; - - req.emr_cmd = MC_CMD_FINI_RXQ; - req.emr_in_buf = payload; - req.emr_in_length = MC_CMD_FINI_RXQ_IN_LEN; - req.emr_out_buf = payload; - req.emr_out_length = MC_CMD_FINI_RXQ_OUT_LEN; - - MCDI_IN_SET_DWORD(req, FINI_RXQ_IN_INSTANCE, instance); - - efx_mcdi_execute_quiet(enp, &req); - - if (req.emr_rc != 0) { - rc = req.emr_rc; - goto fail1; - } - - return (0); - -fail1: - /* - * EALREADY is not an error, but indicates that the MC has rebooted and - * that the RXQ has already been destroyed. - */ - if (rc != EALREADY) - EFSYS_PROBE1(fail1, efx_rc_t, rc); - - return (rc); -} +#if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() #if EFSYS_OPT_RX_SCALE static __checkReturn efx_rc_t @@ -559,6 +375,8 @@ ef10_rx_init( return (0); } +#if EFX_OPTS_EF10() + #if EFSYS_OPT_RX_SCATTER __checkReturn efx_rc_t ef10_rx_scatter_enable( @@ -570,6 +388,8 @@ ef10_rx_scatter_enable( } #endif /* EFSYS_OPT_RX_SCATTER */ +#endif /* EFX_OPTS_EF10() */ + #if EFSYS_OPT_RX_SCALE __checkReturn efx_rc_t ef10_rx_scale_context_alloc( @@ -726,10 +546,11 @@ fail1: } #endif /* EFSYS_OPT_RX_SCALE */ +#if EFX_OPTS_EF10() /* - * EF10 RX pseudo-header - * --------------------- + * EF10 RX pseudo-header (aka Rx prefix) + * ------------------------------------- * * Receive packets are prefixed by an (optional) 14 byte pseudo-header: * @@ -745,7 +566,77 @@ fail1: * (32bit little-endian) * * See "The RX Pseudo-header" in SF-109306-TC. + * + * EF10 does not support Rx prefix choice using MC_CMD_GET_RX_PREFIX_ID + * and query its layout using MC_CMD_QUERY_RX_PREFIX_ID. + */ +static const efx_rx_prefix_layout_t ef10_default_rx_prefix_layout = { + .erpl_id = 0, + .erpl_length = 14, + .erpl_fields = { + [EFX_RX_PREFIX_FIELD_RSS_HASH] = + { 0, 32, B_FALSE }, + [EFX_RX_PREFIX_FIELD_VLAN_STRIP_TCI] = + { 32, 16, B_TRUE }, + [EFX_RX_PREFIX_FIELD_INNER_VLAN_STRIP_TCI] = + { 48, 16, B_TRUE }, + [EFX_RX_PREFIX_FIELD_LENGTH] = + { 64, 16, B_FALSE }, + [EFX_RX_PREFIX_FIELD_PARTIAL_TSTAMP] = + { 80, 32, B_FALSE }, + } +}; + +#if EFSYS_OPT_RX_PACKED_STREAM + +/* + * EF10 packed stream Rx prefix layout. + * + * See SF-112241-TC Full speed capture for Huntington and Medford section 4.5. + */ +static const efx_rx_prefix_layout_t ef10_packed_stream_rx_prefix_layout = { + .erpl_id = 0, + .erpl_length = 8, + .erpl_fields = { +#define EF10_PS_RX_PREFIX_FIELD(_efx, _ef10) \ + EFX_RX_PREFIX_FIELD(_efx, ES_DZ_PS_RX_PREFIX_ ## _ef10, B_FALSE) + + EF10_PS_RX_PREFIX_FIELD(PARTIAL_TSTAMP, TSTAMP), + EF10_PS_RX_PREFIX_FIELD(LENGTH, CAP_LEN), + EF10_PS_RX_PREFIX_FIELD(ORIG_LENGTH, ORIG_LEN), + +#undef EF10_PS_RX_PREFIX_FIELD + } +}; + +#endif /* EFSYS_OPT_RX_PACKED_STREAM */ + +#if EFSYS_OPT_RX_ES_SUPER_BUFFER + +/* + * EF10 equal stride super-buffer Rx prefix layout. + * + * See SF-119419-TC DPDK Firmware Driver Interface section 3.4. */ +static const efx_rx_prefix_layout_t ef10_essb_rx_prefix_layout = { + .erpl_id = 0, + .erpl_length = ES_EZ_ESSB_RX_PREFIX_LEN, + .erpl_fields = { +#define EF10_ESSB_RX_PREFIX_FIELD(_efx, _ef10) \ + EFX_RX_PREFIX_FIELD(_efx, ES_EZ_ESSB_RX_PREFIX_ ## _ef10, B_FALSE) + + EF10_ESSB_RX_PREFIX_FIELD(LENGTH, DATA_LEN), + EF10_ESSB_RX_PREFIX_FIELD(USER_MARK, MARK), + EF10_ESSB_RX_PREFIX_FIELD(RSS_HASH_VALID, HASH_VALID), + EF10_ESSB_RX_PREFIX_FIELD(USER_MARK_VALID, MARK_VALID), + EF10_ESSB_RX_PREFIX_FIELD(USER_FLAG, MATCH_FLAG), + EF10_ESSB_RX_PREFIX_FIELD(RSS_HASH, HASH), + +#undef EF10_ESSB_RX_PREFIX_FIELD + } +}; + +#endif /* EFSYS_OPT_RX_ES_SUPER_BUFFER */ __checkReturn efx_rc_t ef10_rx_prefix_pktlen( @@ -872,7 +763,7 @@ ef10_rx_qpush( /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */ EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1, - wptr, pushed & erp->er_mask); + EF10_RXQ_DESC_SIZE, wptr, pushed & erp->er_mask); EFSYS_PIO_WRITE_BARRIER(); EFX_BAR_VI_WRITED(enp, ER_DZ_RX_DESC_UPD_REG, erp->er_index, &dword, B_FALSE); @@ -1015,79 +906,85 @@ ef10_rx_qcreate( __in efx_rxq_t *erp) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_mcdi_init_rxq_params_t params; + const efx_rx_prefix_layout_t *erpl; efx_rc_t rc; - boolean_t disable_scatter; - boolean_t want_inner_classes; - unsigned int ps_buf_size; - uint32_t es_bufs_per_desc = 0; - uint32_t es_max_dma_len = 0; - uint32_t es_buf_stride = 0; - uint32_t hol_block_timeout = 0; _NOTE(ARGUNUSED(id, erp)) EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS == (1 << ESF_DZ_RX_QLABEL_WIDTH)); EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS); - EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit); - if (index >= encp->enc_rxq_limit) { - rc = EINVAL; - goto fail1; - } + memset(¶ms, 0, sizeof (params)); + params.buf_size = erp->er_buf_size; switch (type) { case EFX_RXQ_TYPE_DEFAULT: + erpl = &ef10_default_rx_prefix_layout; if (type_data == NULL) { rc = EINVAL; - goto fail2; + goto fail1; } erp->er_buf_size = type_data->ertd_default.ed_buf_size; - ps_buf_size = 0; + /* + * Ignore EFX_RXQ_FLAG_RSS_HASH since if RSS hash is calculated + * it is always delivered from HW in the pseudo-header. + */ break; #if EFSYS_OPT_RX_PACKED_STREAM case EFX_RXQ_TYPE_PACKED_STREAM: + erpl = &ef10_packed_stream_rx_prefix_layout; if (type_data == NULL) { rc = EINVAL; - goto fail3; + goto fail2; } switch (type_data->ertd_packed_stream.eps_buf_size) { case EFX_RXQ_PACKED_STREAM_BUF_SIZE_1M: - ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M; + params.ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M; break; case EFX_RXQ_PACKED_STREAM_BUF_SIZE_512K: - ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_512K; + params.ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_512K; break; case EFX_RXQ_PACKED_STREAM_BUF_SIZE_256K: - ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_256K; + params.ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_256K; break; case EFX_RXQ_PACKED_STREAM_BUF_SIZE_128K: - ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_128K; + params.ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_128K; break; case EFX_RXQ_PACKED_STREAM_BUF_SIZE_64K: - ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_64K; + params.ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_64K; break; default: rc = ENOTSUP; - goto fail4; + goto fail3; } erp->er_buf_size = type_data->ertd_packed_stream.eps_buf_size; + /* Packed stream pseudo header does not have RSS hash value */ + if (flags & EFX_RXQ_FLAG_RSS_HASH) { + rc = ENOTSUP; + goto fail4; + } break; #endif /* EFSYS_OPT_RX_PACKED_STREAM */ #if EFSYS_OPT_RX_ES_SUPER_BUFFER case EFX_RXQ_TYPE_ES_SUPER_BUFFER: + erpl = &ef10_essb_rx_prefix_layout; if (type_data == NULL) { rc = EINVAL; goto fail5; } - ps_buf_size = 0; - es_bufs_per_desc = + params.es_bufs_per_desc = type_data->ertd_es_super_buffer.eessb_bufs_per_desc; - es_max_dma_len = + params.es_max_dma_len = type_data->ertd_es_super_buffer.eessb_max_dma_len; - es_buf_stride = + params.es_buf_stride = type_data->ertd_es_super_buffer.eessb_buf_stride; - hol_block_timeout = + params.hol_block_timeout = type_data->ertd_es_super_buffer.eessb_hol_block_timeout; + /* + * Ignore EFX_RXQ_FLAG_RSS_HASH since if RSS hash is calculated + * it is always delivered from HW in the pseudo-header. + */ break; #endif /* EFSYS_OPT_RX_ES_SUPER_BUFFER */ default: @@ -1096,59 +993,57 @@ ef10_rx_qcreate( } #if EFSYS_OPT_RX_PACKED_STREAM - if (ps_buf_size != 0) { + if (params.ps_buf_size != 0) { /* Check if datapath firmware supports packed stream mode */ if (encp->enc_rx_packed_stream_supported == B_FALSE) { rc = ENOTSUP; goto fail7; } /* Check if packed stream allows configurable buffer sizes */ - if ((ps_buf_size != MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M) && + if ((params.ps_buf_size != MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M) && (encp->enc_rx_var_packed_stream_supported == B_FALSE)) { rc = ENOTSUP; goto fail8; } } #else /* EFSYS_OPT_RX_PACKED_STREAM */ - EFSYS_ASSERT(ps_buf_size == 0); + EFSYS_ASSERT(params.ps_buf_size == 0); #endif /* EFSYS_OPT_RX_PACKED_STREAM */ #if EFSYS_OPT_RX_ES_SUPER_BUFFER - if (es_bufs_per_desc > 0) { + if (params.es_bufs_per_desc > 0) { if (encp->enc_rx_es_super_buffer_supported == B_FALSE) { rc = ENOTSUP; goto fail9; } - if (!EFX_IS_P2ALIGNED(uint32_t, es_max_dma_len, + if (!EFX_IS_P2ALIGNED(uint32_t, params.es_max_dma_len, EFX_RX_ES_SUPER_BUFFER_BUF_ALIGNMENT)) { rc = EINVAL; goto fail10; } - if (!EFX_IS_P2ALIGNED(uint32_t, es_buf_stride, + if (!EFX_IS_P2ALIGNED(uint32_t, params.es_buf_stride, EFX_RX_ES_SUPER_BUFFER_BUF_ALIGNMENT)) { rc = EINVAL; goto fail11; } } #else /* EFSYS_OPT_RX_ES_SUPER_BUFFER */ - EFSYS_ASSERT(es_bufs_per_desc == 0); + EFSYS_ASSERT(params.es_bufs_per_desc == 0); #endif /* EFSYS_OPT_RX_ES_SUPER_BUFFER */ /* Scatter can only be disabled if the firmware supports doing so */ if (flags & EFX_RXQ_FLAG_SCATTER) - disable_scatter = B_FALSE; + params.disable_scatter = B_FALSE; else - disable_scatter = encp->enc_rx_disable_scatter_supported; + params.disable_scatter = encp->enc_rx_disable_scatter_supported; if (flags & EFX_RXQ_FLAG_INNER_CLASSES) - want_inner_classes = B_TRUE; + params.want_inner_classes = B_TRUE; else - want_inner_classes = B_FALSE; + params.want_inner_classes = B_FALSE; if ((rc = efx_mcdi_init_rxq(enp, ndescs, eep, label, index, - esmp, disable_scatter, want_inner_classes, erp->er_buf_size, - ps_buf_size, es_bufs_per_desc, es_max_dma_len, - es_buf_stride, hol_block_timeout)) != 0) + esmp, ¶ms)) != 0) goto fail12; erp->er_eep = eep; @@ -1158,6 +1053,8 @@ ef10_rx_qcreate( erp->er_ev_qstate = &erp->er_eep->ee_rxq_state[label]; + erp->er_prefix_layout = *erpl; + return (0); fail12: @@ -1187,9 +1084,9 @@ fail4: EFSYS_PROBE(fail4); fail3: EFSYS_PROBE(fail3); -#endif /* EFSYS_OPT_RX_PACKED_STREAM */ fail2: EFSYS_PROBE(fail2); +#endif /* EFSYS_OPT_RX_PACKED_STREAM */ fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); @@ -1200,18 +1097,14 @@ fail1: ef10_rx_qdestroy( __in efx_rxq_t *erp) { - efx_nic_t *enp = erp->er_enp; efx_evq_t *eep = erp->er_eep; unsigned int label = erp->er_label; ef10_ev_rxlabel_fini(eep, label); - - EFSYS_ASSERT(enp->en_rx_qcount != 0); - --enp->en_rx_qcount; - - EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp); } +#endif /* EFX_OPTS_EF10() */ + void ef10_rx_fini( __in efx_nic_t *enp) @@ -1226,4 +1119,4 @@ ef10_rx_fini( #endif /* EFSYS_OPT_RX_SCALE */ } -#endif /* EFX_OPTS_EF10() */ +#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */