X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fsfc%2Fbase%2Fef10_rx.c;h=cd35c2a7b60cc5f630ef3715cbb4b6ca2ee2d6a6;hb=3c97590830b404f1d1f6af1c70355caed23ec683;hp=5cf5910ff5c1f909189a8cee24594e5044e74cd5;hpb=698c68d6f2704517b2f0ed642c7673efb4339fc6;p=dpdk.git diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c index 5cf5910ff5..cd35c2a7b6 100644 --- a/drivers/net/sfc/base/ef10_rx.c +++ b/drivers/net/sfc/base/ef10_rx.c @@ -1,38 +1,14 @@ -/* - * Copyright (c) 2012-2016 Solarflare Communications Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: +/* SPDX-License-Identifier: BSD-3-Clause * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are - * those of the authors and should not be interpreted as representing official - * policies, either expressed or implied, of the FreeBSD Project. + * Copyright (c) 2012-2018 Solarflare Communications Inc. + * All rights reserved. */ #include "efx.h" #include "efx_impl.h" -#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD +#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 static __checkReturn efx_rc_t @@ -44,6 +20,7 @@ efx_mcdi_init_rxq( __in uint32_t instance, __in efsys_mem_t *esmp, __in boolean_t disable_scatter, + __in boolean_t want_inner_classes, __in uint32_t ps_bufsize) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); @@ -60,12 +37,18 @@ efx_mcdi_init_rxq( EFSYS_ASSERT3U(ndescs, <=, EFX_RXQ_MAXNDESCS); + if ((esmp == NULL) || (EFSYS_MEM_SIZE(esmp) < EFX_RXQ_SIZE(ndescs))) { + rc = EINVAL; + goto fail1; + } + if (ps_bufsize > 0) dma_mode = MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM; else dma_mode = MC_CMD_INIT_RXQ_EXT_IN_SINGLE_PACKET; - if (encp->enc_tunnel_encapsulations_supported != 0) { + 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 @@ -125,11 +108,13 @@ efx_mcdi_init_rxq( if (req.emr_rc != 0) { rc = req.emr_rc; - goto fail1; + goto fail2; } return (0); +fail2: + EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); @@ -217,7 +202,13 @@ efx_mcdi_rss_context_alloc( MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID, EVB_PORT_ID_ASSIGNED); MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_TYPE, context_type); - /* NUM_QUEUES is only used to validate indirection table offsets */ + + /* + * For exclusive contexts, NUM_QUEUES is only used to validate + * indirection table offsets. + * For shared contexts, the provided context will spread traffic over + * NUM_QUEUES many queues. + */ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_NUM_QUEUES, num_queues); efx_mcdi_execute(enp, &req); @@ -307,11 +298,34 @@ efx_mcdi_rss_context_set_flags( __in uint32_t rss_context, __in efx_rx_hash_type_t type) { + efx_nic_cfg_t *encp = &enp->en_nic_cfg; + efx_rx_hash_type_t type_ipv4; + efx_rx_hash_type_t type_ipv4_tcp; + efx_rx_hash_type_t type_ipv6; + efx_rx_hash_type_t type_ipv6_tcp; + efx_rx_hash_type_t modes; efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN, MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN)]; efx_rc_t rc; + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_TCP_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_TCP_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_WIDTH); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_WIDTH); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_TCP_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_TCP_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_WIDTH); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_WIDTH); + if (rss_context == EF10_RSS_CONTEXT_INVALID) { rc = EINVAL; goto fail1; @@ -327,15 +341,57 @@ efx_mcdi_rss_context_set_flags( MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID, rss_context); - MCDI_IN_POPULATE_DWORD_4(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, + type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE) | EFX_RX_HASH(IPV4_TCP, 2TUPLE) | + EFX_RX_HASH(IPV4_UDP, 2TUPLE); + type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE); + type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE) | EFX_RX_HASH(IPV6_TCP, 2TUPLE) | + EFX_RX_HASH(IPV6_UDP, 2TUPLE); + type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE); + + /* + * Create a copy of the original hash type. + * The copy will be used to fill in RSS_MODE bits and + * may be cleared beforehand. The original variable + * and, thus, EN bits will remain unaffected. + */ + modes = type; + + /* + * If the firmware lacks support for additional modes, RSS_MODE + * fields must contain zeros, otherwise the operation will fail. + */ + if (encp->enc_rx_scale_additional_modes_supported == B_FALSE) + modes = 0; + +#define EXTRACT_RSS_MODE(_type, _class) \ + (EFX_EXTRACT_NATIVE(_type, 0, 31, \ + EFX_LOW_BIT(EFX_RX_CLASS_##_class), \ + EFX_HIGH_BIT(EFX_RX_CLASS_##_class)) & \ + EFX_MASK32(EFX_RX_CLASS_##_class)) + + MCDI_IN_POPULATE_DWORD_10(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN, - (type & EFX_RX_HASH_IPV4) ? 1 : 0, + ((type & type_ipv4) == type_ipv4) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN, - (type & EFX_RX_HASH_TCPIPV4) ? 1 : 0, + ((type & type_ipv4_tcp) == type_ipv4_tcp) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN, - (type & EFX_RX_HASH_IPV6) ? 1 : 0, + ((type & type_ipv6) == type_ipv6) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN, - (type & EFX_RX_HASH_TCPIPV6) ? 1 : 0); + ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0, + RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV4_TCP), + RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV4_UDP), + RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV4), + RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV6_TCP), + RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV6_UDP), + RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV6)); + +#undef EXTRACT_RSS_MODE efx_mcdi_execute(enp, &req); @@ -560,12 +616,13 @@ ef10_rx_scale_mode_set( __in efx_rx_hash_type_t type, __in boolean_t insert) { + efx_nic_cfg_t *encp = &enp->en_nic_cfg; efx_rc_t rc; - EFSYS_ASSERT3U(alg, ==, EFX_RX_HASHALG_TOEPLITZ); EFSYS_ASSERT3U(insert, ==, B_TRUE); - if ((alg != EFX_RX_HASHALG_TOEPLITZ) || (insert == B_FALSE)) { + if ((encp->enc_rx_scale_hash_alg_mask & (1U << alg)) == 0 || + insert == B_FALSE) { rc = EINVAL; goto fail1; } @@ -714,6 +771,7 @@ ef10_rx_prefix_hash( _NOTE(ARGUNUSED(enp)) switch (func) { + case EFX_RX_HASHALG_PACKED_STREAM: case EFX_RX_HASHALG_TOEPLITZ: return (buffer[0] | (buffer[1] << 8) | @@ -811,8 +869,8 @@ ef10_rx_qpush( EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1, wptr, pushed & erp->er_mask); EFSYS_PIO_WRITE_BARRIER(); - EFX_BAR_TBL_WRITED(enp, ER_DZ_RX_DESC_UPD_REG, - erp->er_index, &dword, B_FALSE); + EFX_BAR_VI_WRITED(enp, ER_DZ_RX_DESC_UPD_REG, + erp->er_index, &dword, B_FALSE); } #if EFSYS_OPT_RX_PACKED_STREAM @@ -843,7 +901,7 @@ ef10_rx_qpush_ps_credits( ERF_DZ_RX_DESC_MAGIC_CMD, ERE_DZ_RX_DESC_MAGIC_CMD_PS_CREDITS, ERF_DZ_RX_DESC_MAGIC_DATA, credits); - EFX_BAR_TBL_WRITED(enp, ER_DZ_RX_DESC_UPD_REG, + EFX_BAR_VI_WRITED(enp, ER_DZ_RX_DESC_UPD_REG, erp->er_index, &dword, B_FALSE); rxq_state->eers_rx_packed_stream_credits = 0; @@ -942,18 +1000,21 @@ ef10_rx_qcreate( __in unsigned int index, __in unsigned int label, __in efx_rxq_type_t type, + __in uint32_t type_data, __in efsys_mem_t *esmp, __in size_t ndescs, __in uint32_t id, + __in unsigned int flags, __in efx_evq_t *eep, __in efx_rxq_t *erp) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); efx_rc_t rc; boolean_t disable_scatter; + boolean_t want_inner_classes; unsigned int ps_buf_size; - _NOTE(ARGUNUSED(id, erp)) + _NOTE(ARGUNUSED(id, erp, type_data)) EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS == (1 << ESF_DZ_RX_QLABEL_WIDTH)); EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS); @@ -974,29 +1035,35 @@ ef10_rx_qcreate( switch (type) { case EFX_RXQ_TYPE_DEFAULT: - case EFX_RXQ_TYPE_SCATTER: ps_buf_size = 0; break; #if EFSYS_OPT_RX_PACKED_STREAM - case EFX_RXQ_TYPE_PACKED_STREAM_1M: - ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M; - break; - case EFX_RXQ_TYPE_PACKED_STREAM_512K: - ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_512K; - break; - case EFX_RXQ_TYPE_PACKED_STREAM_256K: - ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_256K; - break; - case EFX_RXQ_TYPE_PACKED_STREAM_128K: - ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_128K; - break; - case EFX_RXQ_TYPE_PACKED_STREAM_64K: - ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_64K; + case EFX_RXQ_TYPE_PACKED_STREAM: + switch (type_data) { + case EFX_RXQ_PACKED_STREAM_BUF_SIZE_1M: + 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; + break; + case EFX_RXQ_PACKED_STREAM_BUF_SIZE_256K: + 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; + break; + case EFX_RXQ_PACKED_STREAM_BUF_SIZE_64K: + ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_64K; + break; + default: + rc = ENOTSUP; + goto fail3; + } break; #endif /* EFSYS_OPT_RX_PACKED_STREAM */ default: rc = ENOTSUP; - goto fail3; + goto fail4; } #if EFSYS_OPT_RX_PACKED_STREAM @@ -1004,13 +1071,13 @@ ef10_rx_qcreate( /* Check if datapath firmware supports packed stream mode */ if (encp->enc_rx_packed_stream_supported == B_FALSE) { rc = ENOTSUP; - goto fail4; + goto fail5; } /* Check if packed stream allows configurable buffer sizes */ - if ((type != EFX_RXQ_TYPE_PACKED_STREAM_1M) && + if ((ps_buf_size != MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M) && (encp->enc_rx_var_packed_stream_supported == B_FALSE)) { rc = ENOTSUP; - goto fail5; + goto fail6; } } #else /* EFSYS_OPT_RX_PACKED_STREAM */ @@ -1018,14 +1085,20 @@ ef10_rx_qcreate( #endif /* EFSYS_OPT_RX_PACKED_STREAM */ /* Scatter can only be disabled if the firmware supports doing so */ - if (type == EFX_RXQ_TYPE_SCATTER) + if (flags & EFX_RXQ_FLAG_SCATTER) disable_scatter = B_FALSE; else disable_scatter = encp->enc_rx_disable_scatter_supported; + if (flags & EFX_RXQ_FLAG_INNER_CLASSES) + want_inner_classes = B_TRUE; + else + want_inner_classes = B_FALSE; + if ((rc = efx_mcdi_init_rxq(enp, ndescs, eep->ee_index, label, index, - esmp, disable_scatter, ps_buf_size)) != 0) - goto fail6; + esmp, disable_scatter, want_inner_classes, + ps_buf_size)) != 0) + goto fail7; erp->er_eep = eep; erp->er_label = label; @@ -1036,16 +1109,20 @@ ef10_rx_qcreate( return (0); +fail7: + EFSYS_PROBE(fail7); +#if EFSYS_OPT_RX_PACKED_STREAM fail6: EFSYS_PROBE(fail6); -#if EFSYS_OPT_RX_PACKED_STREAM fail5: EFSYS_PROBE(fail5); +#endif /* EFSYS_OPT_RX_PACKED_STREAM */ fail4: EFSYS_PROBE(fail4); -#endif /* EFSYS_OPT_RX_PACKED_STREAM */ +#if EFSYS_OPT_RX_PACKED_STREAM fail3: EFSYS_PROBE(fail3); +#endif /* EFSYS_OPT_RX_PACKED_STREAM */ fail2: EFSYS_PROBE(fail2); fail1: @@ -1084,4 +1161,4 @@ ef10_rx_fini( #endif /* EFSYS_OPT_RX_SCALE */ } -#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */ +#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */