X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcommon%2Fsfc_efx%2Fbase%2Fefx_rx.c;h=7c6fecf9255c2a807d2a618ebe1c7aafe668f044;hb=3dee345ab31a8cc685c9fe5ba3f90aa322ee1d48;hp=cce34cfce997adb5b0cd570274dade5ec5a36c45;hpb=5e111ed87999b2df4084b4d9c95643c98df1ba48;p=dpdk.git diff --git a/drivers/common/sfc_efx/base/efx_rx.c b/drivers/common/sfc_efx/base/efx_rx.c index cce34cfce9..7c6fecf925 100644 --- a/drivers/common/sfc_efx/base/efx_rx.c +++ b/drivers/common/sfc_efx/base/efx_rx.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2019-2020 Xilinx, Inc. + * Copyright(c) 2019-2021 Xilinx, Inc. * Copyright(c) 2007-2019 Solarflare Communications Inc. */ @@ -180,6 +180,35 @@ static const efx_rx_ops_t __efx_rx_ef10_ops = { }; #endif /* EFX_OPTS_EF10() */ +#if EFSYS_OPT_RIVERHEAD +static const efx_rx_ops_t __efx_rx_rhead_ops = { + rhead_rx_init, /* erxo_init */ + rhead_rx_fini, /* erxo_fini */ +#if EFSYS_OPT_RX_SCATTER + rhead_rx_scatter_enable, /* erxo_scatter_enable */ +#endif +#if EFSYS_OPT_RX_SCALE + rhead_rx_scale_context_alloc, /* erxo_scale_context_alloc */ + rhead_rx_scale_context_free, /* erxo_scale_context_free */ + rhead_rx_scale_mode_set, /* erxo_scale_mode_set */ + rhead_rx_scale_key_set, /* erxo_scale_key_set */ + rhead_rx_scale_tbl_set, /* erxo_scale_tbl_set */ + rhead_rx_prefix_hash, /* erxo_prefix_hash */ +#endif + rhead_rx_prefix_pktlen, /* erxo_prefix_pktlen */ + rhead_rx_qpost, /* erxo_qpost */ + rhead_rx_qpush, /* erxo_qpush */ +#if EFSYS_OPT_RX_PACKED_STREAM + NULL, /* erxo_qpush_ps_credits */ + NULL, /* erxo_qps_packet_info */ +#endif + rhead_rx_qflush, /* erxo_qflush */ + rhead_rx_qenable, /* erxo_qenable */ + rhead_rx_qcreate, /* erxo_qcreate */ + rhead_rx_qdestroy, /* erxo_qdestroy */ +}; +#endif /* EFSYS_OPT_RIVERHEAD */ + __checkReturn efx_rc_t efx_rx_init( @@ -226,6 +255,12 @@ efx_rx_init( break; #endif /* EFSYS_OPT_MEDFORD2 */ +#if EFSYS_OPT_RIVERHEAD + case EFX_FAMILY_RIVERHEAD: + erxop = &__efx_rx_rhead_ops; + break; +#endif /* EFSYS_OPT_RIVERHEAD */ + default: EFSYS_ASSERT(0); rc = ENOTSUP; @@ -819,14 +854,21 @@ efx_rx_qcreate_internal( EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit); + EFSYS_ASSERT(ISP2(encp->enc_rxq_max_ndescs)); EFSYS_ASSERT(ISP2(encp->enc_rxq_min_ndescs)); + if (index >= encp->enc_rxq_limit) { + rc = EINVAL; + goto fail1; + } + if (!ISP2(ndescs) || ndescs < encp->enc_rxq_min_ndescs || ndescs > encp->enc_rxq_max_ndescs) { rc = EINVAL; - goto fail1; + goto fail2; } /* Allocate an RXQ object */ @@ -834,7 +876,7 @@ efx_rx_qcreate_internal( if (erp == NULL) { rc = ENOMEM; - goto fail2; + goto fail3; } erp->er_magic = EFX_RXQ_MAGIC; @@ -845,17 +887,34 @@ efx_rx_qcreate_internal( if ((rc = erxop->erxo_qcreate(enp, index, label, type, type_data, esmp, ndescs, id, flags, eep, erp)) != 0) - goto fail3; + goto fail4; + + /* Sanity check queue creation result */ + if (flags & EFX_RXQ_FLAG_RSS_HASH) { + const efx_rx_prefix_layout_t *erplp = &erp->er_prefix_layout; + const efx_rx_prefix_field_info_t *rss_hash_field; + + rss_hash_field = + &erplp->erpl_fields[EFX_RX_PREFIX_FIELD_RSS_HASH]; + if (rss_hash_field->erpfi_width_bits == 0) + goto fail5; + } enp->en_rx_qcount++; *erpp = erp; return (0); -fail3: - EFSYS_PROBE(fail3); +fail5: + EFSYS_PROBE(fail5); + + erxop->erxo_qdestroy(erp); +fail4: + EFSYS_PROBE(fail4); EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp); +fail3: + EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: @@ -975,7 +1034,13 @@ efx_rx_qdestroy( EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC); + EFSYS_ASSERT(enp->en_rx_qcount != 0); + --enp->en_rx_qcount; + erxop->erxo_qdestroy(erp); + + /* Free the RXQ object */ + EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp); } __checkReturn efx_rc_t @@ -1009,6 +1074,18 @@ efx_pseudo_hdr_hash_get( } #endif /* EFSYS_OPT_RX_SCALE */ + __checkReturn efx_rc_t +efx_rx_prefix_get_layout( + __in const efx_rxq_t *erp, + __out efx_rx_prefix_layout_t *erplp) +{ + EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC); + + *erplp = erp->er_prefix_layout; + + return (0); +} + #if EFSYS_OPT_SIENA static __checkReturn efx_rc_t @@ -1427,6 +1504,21 @@ fail1: * LL.LL LFSR hash (16-bit big-endian) */ +/* + * Provide Rx prefix layout with Toeplitz hash only since LSFR is + * used by no supported drivers. + * + * Siena does not support Rx prefix choice via MC_CMD_GET_RX_PREFIX_ID + * and query its layout using MC_CMD_QUERY_RX_PREFIX_ID. + */ +static const efx_rx_prefix_layout_t siena_toeplitz_rx_prefix_layout = { + .erpl_id = 0, + .erpl_length = 16, + .erpl_fields = { + [EFX_RX_PREFIX_FIELD_RSS_HASH] = { 12 * 8, 32, B_TRUE }, + } +}; + #if EFSYS_OPT_RX_SCALE static __checkReturn uint32_t siena_rx_prefix_hash( @@ -1531,7 +1623,7 @@ siena_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); + SIENA_RXQ_DESC_SIZE, wptr, pushed & erp->er_mask); EFSYS_PIO_WRITE_BARRIER(); EFX_BAR_TBL_WRITED3(enp, FR_BZ_RX_DESC_UPD_REGP0, erp->er_index, &dword, B_FALSE); @@ -1626,12 +1718,7 @@ siena_rx_qcreate( EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS == (1 << FRF_AZ_RX_DESCQ_LABEL_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; - } for (size = 0; (1U << size) <= encp->enc_rxq_max_ndescs / encp->enc_rxq_min_ndescs; size++) @@ -1639,17 +1726,21 @@ siena_rx_qcreate( break; if (id + (1 << size) >= encp->enc_buftbl_limit) { rc = EINVAL; - goto fail2; + goto fail1; } switch (type) { case EFX_RXQ_TYPE_DEFAULT: erp->er_buf_size = type_data->ertd_default.ed_buf_size; + /* + * Ignore EFX_RXQ_FLAG_RSS_HASH since if RSS hash is calculated + * it is always delivered from HW in the pseudo-header. + */ break; default: rc = EINVAL; - goto fail3; + goto fail2; } if (flags & EFX_RXQ_FLAG_SCATTER) { @@ -1657,7 +1748,7 @@ siena_rx_qcreate( jumbo = B_TRUE; #else rc = EINVAL; - goto fail4; + goto fail3; #endif /* EFSYS_OPT_RX_SCATTER */ } @@ -1674,14 +1765,14 @@ siena_rx_qcreate( EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL, erp->er_index, &oword, B_TRUE); + erp->er_prefix_layout = siena_toeplitz_rx_prefix_layout; + return (0); #if !EFSYS_OPT_RX_SCATTER -fail4: - EFSYS_PROBE(fail4); -#endif fail3: EFSYS_PROBE(fail3); +#endif fail2: EFSYS_PROBE(fail2); fail1: @@ -1697,17 +1788,11 @@ siena_rx_qdestroy( efx_nic_t *enp = erp->er_enp; efx_oword_t oword; - EFSYS_ASSERT(enp->en_rx_qcount != 0); - --enp->en_rx_qcount; - /* Purge descriptor queue */ EFX_ZERO_OWORD(oword); EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL, erp->er_index, &oword, B_TRUE); - - /* Free the RXQ object */ - EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp); } static void @@ -1718,3 +1803,43 @@ siena_rx_fini( } #endif /* EFSYS_OPT_SIENA */ + +static __checkReturn boolean_t +efx_rx_prefix_layout_fields_match( + __in const efx_rx_prefix_field_info_t *erpfip1, + __in const efx_rx_prefix_field_info_t *erpfip2) +{ + if (erpfip1->erpfi_offset_bits != erpfip2->erpfi_offset_bits) + return (B_FALSE); + + if (erpfip1->erpfi_width_bits != erpfip2->erpfi_width_bits) + return (B_FALSE); + + if (erpfip1->erpfi_big_endian != erpfip2->erpfi_big_endian) + return (B_FALSE); + + return (B_TRUE); +} + + __checkReturn uint32_t +efx_rx_prefix_layout_check( + __in const efx_rx_prefix_layout_t *available, + __in const efx_rx_prefix_layout_t *wanted) +{ + uint32_t result = 0; + unsigned int i; + + EFX_STATIC_ASSERT(EFX_RX_PREFIX_NFIELDS < sizeof (result) * 8); + for (i = 0; i < EFX_RX_PREFIX_NFIELDS; ++i) { + /* Skip the field if driver does not want to use it */ + if (wanted->erpl_fields[i].erpfi_width_bits == 0) + continue; + + if (efx_rx_prefix_layout_fields_match( + &available->erpl_fields[i], + &wanted->erpl_fields[i]) == B_FALSE) + result |= (1U << i); + } + + return (result); +}