X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fsfc%2Fbase%2Fefx_rx.c;h=4fd73bab33468c7a97b498364e15db99f2ab9142;hb=9a5d5f180586d8887dc68c44b02cd8afb4b5173d;hp=41fc17e6c9cd609e140e1eb4f45219cbd6206510;hpb=cca9f9099f6548f01038980c1aa2b5c8583ed3b5;p=dpdk.git diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c index 41fc17e6c9..4fd73bab33 100644 --- a/drivers/net/sfc/base/efx_rx.c +++ b/drivers/net/sfc/base/efx_rx.c @@ -1,31 +1,7 @@ -/* - * Copyright (c) 2007-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: - * - * 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. +/* SPDX-License-Identifier: BSD-3-Clause * - * 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) 2007-2018 Solarflare Communications Inc. + * All rights reserved. */ #include "efx.h" @@ -53,6 +29,7 @@ siena_rx_scatter_enable( static __checkReturn efx_rc_t siena_rx_scale_mode_set( __in efx_nic_t *enp, + __in uint32_t rss_context, __in efx_rx_hash_alg_t alg, __in efx_rx_hash_type_t type, __in boolean_t insert); @@ -60,12 +37,14 @@ siena_rx_scale_mode_set( static __checkReturn efx_rc_t siena_rx_scale_key_set( __in efx_nic_t *enp, + __in uint32_t rss_context, __in_ecount(n) uint8_t *key, __in size_t n); static __checkReturn efx_rc_t siena_rx_scale_tbl_set( __in efx_nic_t *enp, + __in uint32_t rss_context, __in_ecount(n) unsigned int *table, __in size_t n); @@ -83,14 +62,14 @@ siena_rx_prefix_pktlen( __in uint8_t *buffer, __out uint16_t *lengthp); -static void +static void siena_rx_qpost( - __in efx_rxq_t *erp, - __in_ecount(n) efsys_dma_addr_t *addrp, - __in size_t size, - __in unsigned int n, - __in unsigned int completed, - __in unsigned int added); + __in efx_rxq_t *erp, + __in_ecount(ndescs) efsys_dma_addr_t *addrp, + __in size_t size, + __in unsigned int ndescs, + __in unsigned int completed, + __in unsigned int added); static void siena_rx_qpush( @@ -100,7 +79,7 @@ siena_rx_qpush( #if EFSYS_OPT_RX_PACKED_STREAM static void -siena_rx_qps_update_credits( +siena_rx_qpush_ps_credits( __in efx_rxq_t *erp); static __checkReturn uint8_t * @@ -128,9 +107,11 @@ siena_rx_qcreate( __in unsigned int index, __in unsigned int label, __in efx_rxq_type_t type, + __in const efx_rxq_type_data_t *type_data, __in efsys_mem_t *esmp, - __in size_t n, + __in size_t ndescs, __in uint32_t id, + __in unsigned int flags, __in efx_evq_t *eep, __in efx_rxq_t *erp); @@ -149,6 +130,8 @@ static const efx_rx_ops_t __efx_rx_siena_ops = { siena_rx_scatter_enable, /* erxo_scatter_enable */ #endif #if EFSYS_OPT_RX_SCALE + NULL, /* erxo_scale_context_alloc */ + NULL, /* erxo_scale_context_free */ siena_rx_scale_mode_set, /* erxo_scale_mode_set */ siena_rx_scale_key_set, /* erxo_scale_key_set */ siena_rx_scale_tbl_set, /* erxo_scale_tbl_set */ @@ -158,7 +141,7 @@ static const efx_rx_ops_t __efx_rx_siena_ops = { siena_rx_qpost, /* erxo_qpost */ siena_rx_qpush, /* erxo_qpush */ #if EFSYS_OPT_RX_PACKED_STREAM - siena_rx_qps_update_credits, /* erxo_qps_update_credits */ + siena_rx_qpush_ps_credits, /* erxo_qpush_ps_credits */ siena_rx_qps_packet_info, /* erxo_qps_packet_info */ #endif siena_rx_qflush, /* erxo_qflush */ @@ -168,7 +151,7 @@ static const efx_rx_ops_t __efx_rx_siena_ops = { }; #endif /* EFSYS_OPT_SIENA */ -#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD +#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 static const efx_rx_ops_t __efx_rx_ef10_ops = { ef10_rx_init, /* erxo_init */ ef10_rx_fini, /* erxo_fini */ @@ -176,6 +159,8 @@ static const efx_rx_ops_t __efx_rx_ef10_ops = { ef10_rx_scatter_enable, /* erxo_scatter_enable */ #endif #if EFSYS_OPT_RX_SCALE + ef10_rx_scale_context_alloc, /* erxo_scale_context_alloc */ + ef10_rx_scale_context_free, /* erxo_scale_context_free */ ef10_rx_scale_mode_set, /* erxo_scale_mode_set */ ef10_rx_scale_key_set, /* erxo_scale_key_set */ ef10_rx_scale_tbl_set, /* erxo_scale_tbl_set */ @@ -185,7 +170,7 @@ static const efx_rx_ops_t __efx_rx_ef10_ops = { ef10_rx_qpost, /* erxo_qpost */ ef10_rx_qpush, /* erxo_qpush */ #if EFSYS_OPT_RX_PACKED_STREAM - ef10_rx_qps_update_credits, /* erxo_qps_update_credits */ + ef10_rx_qpush_ps_credits, /* erxo_qpush_ps_credits */ ef10_rx_qps_packet_info, /* erxo_qps_packet_info */ #endif ef10_rx_qflush, /* erxo_qflush */ @@ -193,7 +178,7 @@ static const efx_rx_ops_t __efx_rx_ef10_ops = { ef10_rx_qcreate, /* erxo_qcreate */ ef10_rx_qdestroy, /* erxo_qdestroy */ }; -#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */ +#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */ __checkReturn efx_rc_t @@ -235,6 +220,12 @@ efx_rx_init( break; #endif /* EFSYS_OPT_MEDFORD */ +#if EFSYS_OPT_MEDFORD2 + case EFX_FAMILY_MEDFORD2: + erxop = &__efx_rx_ef10_ops; + break; +#endif /* EFSYS_OPT_MEDFORD2 */ + default: EFSYS_ASSERT(0); rc = ENOTSUP; @@ -303,6 +294,94 @@ fail1: #endif /* EFSYS_OPT_RX_SCATTER */ #if EFSYS_OPT_RX_SCALE + __checkReturn efx_rc_t +efx_rx_scale_hash_flags_get( + __in efx_nic_t *enp, + __in efx_rx_hash_alg_t hash_alg, + __inout_ecount(EFX_RX_HASH_NFLAGS) unsigned int *flags, + __out unsigned int *nflagsp) +{ + efx_nic_cfg_t *encp = &enp->en_nic_cfg; + boolean_t l4; + boolean_t additional_modes; + unsigned int *entryp = flags; + efx_rc_t rc; + + if (flags == NULL || nflagsp == NULL) { + rc = EINVAL; + goto fail1; + } + + l4 = encp->enc_rx_scale_l4_hash_supported; + additional_modes = encp->enc_rx_scale_additional_modes_supported; + +#define LIST_FLAGS(_entryp, _class, _l4_hashing, _additional_modes) \ + do { \ + if (_l4_hashing) { \ + *(_entryp++) = EFX_RX_HASH(_class, 4TUPLE); \ + \ + if (_additional_modes) { \ + *(_entryp++) = \ + EFX_RX_HASH(_class, 2TUPLE_DST); \ + *(_entryp++) = \ + EFX_RX_HASH(_class, 2TUPLE_SRC); \ + } \ + } \ + \ + *(_entryp++) = EFX_RX_HASH(_class, 2TUPLE); \ + \ + if (_additional_modes) { \ + *(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_DST); \ + *(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_SRC); \ + } \ + \ + *(_entryp++) = EFX_RX_HASH(_class, DISABLE); \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + + switch (hash_alg) { + case EFX_RX_HASHALG_PACKED_STREAM: + if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0) + break; + /* FALLTHRU */ + case EFX_RX_HASHALG_TOEPLITZ: + if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0) + break; + + LIST_FLAGS(entryp, IPV4_TCP, l4, additional_modes); + LIST_FLAGS(entryp, IPV6_TCP, l4, additional_modes); + + if (additional_modes) { + LIST_FLAGS(entryp, IPV4_UDP, l4, additional_modes); + LIST_FLAGS(entryp, IPV6_UDP, l4, additional_modes); + } + + LIST_FLAGS(entryp, IPV4, B_FALSE, additional_modes); + LIST_FLAGS(entryp, IPV6, B_FALSE, additional_modes); + break; + + default: + rc = EINVAL; + goto fail2; + } + +#undef LIST_FLAGS + + *nflagsp = (unsigned int)(entryp - flags); + EFSYS_ASSERT3U(*nflagsp, <=, EFX_RX_HASH_NFLAGS); + + return (0); + +fail2: + EFSYS_PROBE(fail2); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + __checkReturn efx_rc_t efx_rx_hash_default_support_get( __in efx_nic_t *enp, @@ -360,28 +439,156 @@ fail1: return (rc); } +#endif /* EFSYS_OPT_RX_SCALE */ + +#if EFSYS_OPT_RX_SCALE + __checkReturn efx_rc_t +efx_rx_scale_context_alloc( + __in efx_nic_t *enp, + __in efx_rx_scale_context_type_t type, + __in uint32_t num_queues, + __out uint32_t *rss_contextp) +{ + const efx_rx_ops_t *erxop = enp->en_erxop; + efx_rc_t rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + + if (erxop->erxo_scale_context_alloc == NULL) { + rc = ENOTSUP; + goto fail1; + } + if ((rc = erxop->erxo_scale_context_alloc(enp, type, + num_queues, rss_contextp)) != 0) { + goto fail2; + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} +#endif /* EFSYS_OPT_RX_SCALE */ + +#if EFSYS_OPT_RX_SCALE + __checkReturn efx_rc_t +efx_rx_scale_context_free( + __in efx_nic_t *enp, + __in uint32_t rss_context) +{ + const efx_rx_ops_t *erxop = enp->en_erxop; + efx_rc_t rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + + if (erxop->erxo_scale_context_free == NULL) { + rc = ENOTSUP; + goto fail1; + } + if ((rc = erxop->erxo_scale_context_free(enp, rss_context)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} +#endif /* EFSYS_OPT_RX_SCALE */ +#if EFSYS_OPT_RX_SCALE __checkReturn efx_rc_t efx_rx_scale_mode_set( __in efx_nic_t *enp, + __in uint32_t rss_context, __in efx_rx_hash_alg_t alg, __in efx_rx_hash_type_t type, __in boolean_t insert) { const efx_rx_ops_t *erxop = enp->en_erxop; + unsigned int type_flags[EFX_RX_HASH_NFLAGS]; + unsigned int type_nflags; + efx_rx_hash_type_t type_check; + unsigned int i; efx_rc_t rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + /* + * Legacy flags and modern bits cannot be + * used at the same time in the hash type. + */ + if ((type & EFX_RX_HASH_LEGACY_MASK) && + (type & ~EFX_RX_HASH_LEGACY_MASK)) { + rc = EINVAL; + goto fail1; + } + + /* + * Translate legacy flags to the new representation + * so that chip-specific handlers will consider the + * new flags only. + */ + if (type & EFX_RX_HASH_IPV4) { + type |= EFX_RX_HASH(IPV4, 2TUPLE); + type |= EFX_RX_HASH(IPV4_TCP, 2TUPLE); + type |= EFX_RX_HASH(IPV4_UDP, 2TUPLE); + } + + if (type & EFX_RX_HASH_TCPIPV4) + type |= EFX_RX_HASH(IPV4_TCP, 4TUPLE); + + if (type & EFX_RX_HASH_IPV6) { + type |= EFX_RX_HASH(IPV6, 2TUPLE); + type |= EFX_RX_HASH(IPV6_TCP, 2TUPLE); + type |= EFX_RX_HASH(IPV6_UDP, 2TUPLE); + } + + if (type & EFX_RX_HASH_TCPIPV6) + type |= EFX_RX_HASH(IPV6_TCP, 4TUPLE); + + type &= ~EFX_RX_HASH_LEGACY_MASK; + type_check = type; + + /* + * Get the list of supported hash flags and sanitise the input. + */ + rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags, &type_nflags); + if (rc != 0) + goto fail2; + + for (i = 0; i < type_nflags; ++i) { + if ((type_check & type_flags[i]) == type_flags[i]) + type_check &= ~(type_flags[i]); + } + + if (type_check != 0) { + rc = EINVAL; + goto fail3; + } + if (erxop->erxo_scale_mode_set != NULL) { - if ((rc = erxop->erxo_scale_mode_set(enp, alg, + if ((rc = erxop->erxo_scale_mode_set(enp, rss_context, alg, type, insert)) != 0) - goto fail1; + 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); @@ -392,6 +599,7 @@ fail1: __checkReturn efx_rc_t efx_rx_scale_key_set( __in efx_nic_t *enp, + __in uint32_t rss_context, __in_ecount(n) uint8_t *key, __in size_t n) { @@ -401,7 +609,7 @@ efx_rx_scale_key_set( EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); - if ((rc = erxop->erxo_scale_key_set(enp, key, n)) != 0) + if ((rc = erxop->erxo_scale_key_set(enp, rss_context, key, n)) != 0) goto fail1; return (0); @@ -417,6 +625,7 @@ fail1: __checkReturn efx_rc_t efx_rx_scale_tbl_set( __in efx_nic_t *enp, + __in uint32_t rss_context, __in_ecount(n) unsigned int *table, __in size_t n) { @@ -426,7 +635,7 @@ efx_rx_scale_tbl_set( EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); - if ((rc = erxop->erxo_scale_tbl_set(enp, table, n)) != 0) + if ((rc = erxop->erxo_scale_tbl_set(enp, rss_context, table, n)) != 0) goto fail1; return (0); @@ -438,27 +647,27 @@ fail1: } #endif /* EFSYS_OPT_RX_SCALE */ - void + void efx_rx_qpost( - __in efx_rxq_t *erp, - __in_ecount(n) efsys_dma_addr_t *addrp, - __in size_t size, - __in unsigned int n, - __in unsigned int completed, - __in unsigned int added) + __in efx_rxq_t *erp, + __in_ecount(ndescs) efsys_dma_addr_t *addrp, + __in size_t size, + __in unsigned int ndescs, + __in unsigned int completed, + __in unsigned int added) { efx_nic_t *enp = erp->er_enp; const efx_rx_ops_t *erxop = enp->en_erxop; EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC); - erxop->erxo_qpost(erp, addrp, size, n, completed, added); + erxop->erxo_qpost(erp, addrp, size, ndescs, completed, added); } #if EFSYS_OPT_RX_PACKED_STREAM void -efx_rx_qps_update_credits( +efx_rx_qpush_ps_credits( __in efx_rxq_t *erp) { efx_nic_t *enp = erp->er_enp; @@ -466,7 +675,7 @@ efx_rx_qps_update_credits( EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC); - erxop->erxo_qps_update_credits(erp); + erxop->erxo_qpush_ps_credits(erp); } __checkReturn uint8_t * @@ -536,15 +745,17 @@ efx_rx_qenable( erxop->erxo_qenable(erp); } - __checkReturn efx_rc_t -efx_rx_qcreate( +static __checkReturn efx_rc_t +efx_rx_qcreate_internal( __in efx_nic_t *enp, __in unsigned int index, __in unsigned int label, __in efx_rxq_type_t type, + __in const efx_rxq_type_data_t *type_data, __in efsys_mem_t *esmp, - __in size_t n, + __in size_t ndescs, __in uint32_t id, + __in unsigned int flags, __in efx_evq_t *eep, __deref_out efx_rxq_t **erpp) { @@ -566,11 +777,11 @@ efx_rx_qcreate( erp->er_magic = EFX_RXQ_MAGIC; erp->er_enp = enp; erp->er_index = index; - erp->er_mask = n - 1; + erp->er_mask = ndescs - 1; erp->er_esmp = esmp; - if ((rc = erxop->erxo_qcreate(enp, index, label, type, esmp, n, id, - eep, erp)) != 0) + if ((rc = erxop->erxo_qcreate(enp, index, label, type, type_data, esmp, + ndescs, id, flags, eep, erp)) != 0) goto fail2; enp->en_rx_qcount++; @@ -588,6 +799,101 @@ fail1: return (rc); } + __checkReturn efx_rc_t +efx_rx_qcreate( + __in efx_nic_t *enp, + __in unsigned int index, + __in unsigned int label, + __in efx_rxq_type_t type, + __in efsys_mem_t *esmp, + __in size_t ndescs, + __in uint32_t id, + __in unsigned int flags, + __in efx_evq_t *eep, + __deref_out efx_rxq_t **erpp) +{ + return efx_rx_qcreate_internal(enp, index, label, type, NULL, + esmp, ndescs, id, flags, eep, erpp); +} + +#if EFSYS_OPT_RX_PACKED_STREAM + + __checkReturn efx_rc_t +efx_rx_qcreate_packed_stream( + __in efx_nic_t *enp, + __in unsigned int index, + __in unsigned int label, + __in uint32_t ps_buf_size, + __in efsys_mem_t *esmp, + __in size_t ndescs, + __in efx_evq_t *eep, + __deref_out efx_rxq_t **erpp) +{ + efx_rxq_type_data_t type_data; + + memset(&type_data, 0, sizeof(type_data)); + + type_data.ertd_packed_stream.eps_buf_size = ps_buf_size; + + return efx_rx_qcreate_internal(enp, index, label, + EFX_RXQ_TYPE_PACKED_STREAM, &type_data, esmp, ndescs, + 0 /* id unused on EF10 */, EFX_RXQ_FLAG_NONE, eep, erpp); +} + +#endif + +#if EFSYS_OPT_RX_ES_SUPER_BUFFER + + __checkReturn efx_rc_t +efx_rx_qcreate_es_super_buffer( + __in efx_nic_t *enp, + __in unsigned int index, + __in unsigned int label, + __in uint32_t n_bufs_per_desc, + __in uint32_t max_dma_len, + __in uint32_t buf_stride, + __in uint32_t hol_block_timeout, + __in efsys_mem_t *esmp, + __in size_t ndescs, + __in unsigned int flags, + __in efx_evq_t *eep, + __deref_out efx_rxq_t **erpp) +{ + efx_rc_t rc; + efx_rxq_type_data_t type_data; + + if (hol_block_timeout > EFX_RXQ_ES_SUPER_BUFFER_HOL_BLOCK_MAX) { + rc = EINVAL; + goto fail1; + } + + memset(&type_data, 0, sizeof(type_data)); + + type_data.ertd_es_super_buffer.eessb_bufs_per_desc = n_bufs_per_desc; + type_data.ertd_es_super_buffer.eessb_max_dma_len = max_dma_len; + type_data.ertd_es_super_buffer.eessb_buf_stride = buf_stride; + type_data.ertd_es_super_buffer.eessb_hol_block_timeout = + hol_block_timeout; + + rc = efx_rx_qcreate_internal(enp, index, label, + EFX_RXQ_TYPE_ES_SUPER_BUFFER, &type_data, esmp, ndescs, + 0 /* id unused on EF10 */, flags, eep, erpp); + if (rc != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + +#endif + + void efx_rx_qdestroy( __in efx_rxq_t *erp) @@ -779,12 +1085,22 @@ fail1: static __checkReturn efx_rc_t siena_rx_scale_mode_set( __in efx_nic_t *enp, + __in uint32_t rss_context, __in efx_rx_hash_alg_t alg, __in efx_rx_hash_type_t type, __in boolean_t insert) { + efx_rx_hash_type_t type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE); + efx_rx_hash_type_t type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE); + efx_rx_hash_type_t type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE); + efx_rx_hash_type_t type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE); efx_rc_t rc; + if (rss_context != EFX_RSS_CONTEXT_DEFAULT) { + rc = EINVAL; + goto fail1; + } + switch (alg) { case EFX_RX_HASHALG_LFSR: EFX_RX_LFSR_HASH(enp, insert); @@ -792,25 +1108,27 @@ siena_rx_scale_mode_set( case EFX_RX_HASHALG_TOEPLITZ: EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert, - type & EFX_RX_HASH_IPV4, - type & EFX_RX_HASH_TCPIPV4); + (type & type_ipv4) == type_ipv4, + (type & type_ipv4_tcp) == type_ipv4_tcp); EFX_RX_TOEPLITZ_IPV6_HASH(enp, - type & EFX_RX_HASH_IPV6, - type & EFX_RX_HASH_TCPIPV6, + (type & type_ipv6) == type_ipv6, + (type & type_ipv6_tcp) == type_ipv6_tcp, rc); if (rc != 0) - goto fail1; + goto fail2; break; default: rc = EINVAL; - goto fail2; + goto fail3; } return (0); +fail3: + EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: @@ -826,6 +1144,7 @@ fail1: static __checkReturn efx_rc_t siena_rx_scale_key_set( __in efx_nic_t *enp, + __in uint32_t rss_context, __in_ecount(n) uint8_t *key, __in size_t n) { @@ -834,6 +1153,11 @@ siena_rx_scale_key_set( unsigned int offset; efx_rc_t rc; + if (rss_context != EFX_RSS_CONTEXT_DEFAULT) { + rc = EINVAL; + goto fail1; + } + byte = 0; /* Write Toeplitz IPv4 hash key */ @@ -854,7 +1178,7 @@ siena_rx_scale_key_set( --offset) { if (oword.eo_u8[offset - 1] != key[byte++]) { rc = EFAULT; - goto fail1; + goto fail2; } } @@ -903,7 +1227,7 @@ siena_rx_scale_key_set( --offset) { if (oword.eo_u8[offset - 1] != key[byte++]) { rc = EFAULT; - goto fail2; + goto fail3; } } @@ -915,7 +1239,7 @@ siena_rx_scale_key_set( --offset) { if (oword.eo_u8[offset - 1] != key[byte++]) { rc = EFAULT; - goto fail3; + goto fail4; } } @@ -927,13 +1251,15 @@ siena_rx_scale_key_set( --offset) { if (oword.eo_u8[offset - 1] != key[byte++]) { rc = EFAULT; - goto fail4; + goto fail5; } } done: return (0); +fail5: + EFSYS_PROBE(fail5); fail4: EFSYS_PROBE(fail4); fail3: @@ -951,6 +1277,7 @@ fail1: static __checkReturn efx_rc_t siena_rx_scale_tbl_set( __in efx_nic_t *enp, + __in uint32_t rss_context, __in_ecount(n) unsigned int *table, __in size_t n) { @@ -961,11 +1288,16 @@ siena_rx_scale_tbl_set( EFX_STATIC_ASSERT(EFX_RSS_TBL_SIZE == FR_BZ_RX_INDIRECTION_TBL_ROWS); EFX_STATIC_ASSERT(EFX_MAXRSS == (1 << FRF_BZ_IT_QUEUE_WIDTH)); - if (n > FR_BZ_RX_INDIRECTION_TBL_ROWS) { + if (rss_context != EFX_RSS_CONTEXT_DEFAULT) { rc = EINVAL; goto fail1; } + if (n > FR_BZ_RX_INDIRECTION_TBL_ROWS) { + rc = EINVAL; + goto fail2; + } + for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS; index++) { uint32_t byte; @@ -994,12 +1326,14 @@ siena_rx_scale_tbl_set( /* Verify the entry */ if (EFX_OWORD_FIELD(oword, FRF_BZ_IT_QUEUE) != byte) { rc = EFAULT; - goto fail2; + goto fail3; } } return (0); +fail3: + EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: @@ -1065,14 +1399,14 @@ siena_rx_prefix_pktlen( } -static void +static void siena_rx_qpost( - __in efx_rxq_t *erp, - __in_ecount(n) efsys_dma_addr_t *addrp, - __in size_t size, - __in unsigned int n, - __in unsigned int completed, - __in unsigned int added) + __in efx_rxq_t *erp, + __in_ecount(ndescs) efsys_dma_addr_t *addrp, + __in size_t size, + __in unsigned int ndescs, + __in unsigned int completed, + __in unsigned int added) { efx_qword_t qword; unsigned int i; @@ -1080,11 +1414,11 @@ siena_rx_qpost( unsigned int id; /* The client driver must not overfill the queue */ - EFSYS_ASSERT3U(added - completed + n, <=, + EFSYS_ASSERT3U(added - completed + ndescs, <=, EFX_RXQ_LIMIT(erp->er_mask + 1)); id = added & (erp->er_mask); - for (i = 0; i < n; i++) { + for (i = 0; i < ndescs; i++) { EFSYS_PROBE4(rx_post, unsigned int, erp->er_index, unsigned int, id, efsys_dma_addr_t, addrp[i], size_t, size); @@ -1137,7 +1471,7 @@ siena_rx_qpush( #if EFSYS_OPT_RX_PACKED_STREAM static void -siena_rx_qps_update_credits( +siena_rx_qpush_ps_credits( __in efx_rxq_t *erp) { /* Not supported by Siena hardware */ @@ -1205,19 +1539,22 @@ siena_rx_qcreate( __in unsigned int index, __in unsigned int label, __in efx_rxq_type_t type, + __in const efx_rxq_type_data_t *type_data, __in efsys_mem_t *esmp, - __in size_t n, + __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_oword_t oword; uint32_t size; - boolean_t jumbo; + boolean_t jumbo = B_FALSE; efx_rc_t rc; _NOTE(ARGUNUSED(esmp)) + _NOTE(ARGUNUSED(type_data)) EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS == (1 << FRF_AZ_RX_DESCQ_LABEL_WIDTH)); @@ -1227,7 +1564,8 @@ siena_rx_qcreate( EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS)); EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS)); - if (!ISP2(n) || (n < EFX_RXQ_MINNDESCS) || (n > EFX_RXQ_MAXNDESCS)) { + if (!ISP2(ndescs) || + (ndescs < EFX_RXQ_MINNDESCS) || (ndescs > EFX_RXQ_MAXNDESCS)) { rc = EINVAL; goto fail1; } @@ -1237,7 +1575,7 @@ siena_rx_qcreate( } for (size = 0; (1 << size) <= (EFX_RXQ_MAXNDESCS / EFX_RXQ_MINNDESCS); size++) - if ((1 << size) == (int)(n / EFX_RXQ_MINNDESCS)) + if ((1 << size) == (int)(ndescs / EFX_RXQ_MINNDESCS)) break; if (id + (1 << size) >= encp->enc_buftbl_limit) { rc = EINVAL; @@ -1246,24 +1584,22 @@ siena_rx_qcreate( switch (type) { case EFX_RXQ_TYPE_DEFAULT: - jumbo = B_FALSE; - break; - -#if EFSYS_OPT_RX_SCATTER - case EFX_RXQ_TYPE_SCATTER: - if (enp->en_family < EFX_FAMILY_SIENA) { - rc = EINVAL; - goto fail4; - } - jumbo = B_TRUE; break; -#endif /* EFSYS_OPT_RX_SCATTER */ default: rc = EINVAL; goto fail4; } + if (flags & EFX_RXQ_FLAG_SCATTER) { +#if EFSYS_OPT_RX_SCATTER + jumbo = B_TRUE; +#else + rc = EINVAL; + goto fail5; +#endif /* EFSYS_OPT_RX_SCATTER */ + } + /* Set up the new descriptor queue */ EFX_POPULATE_OWORD_7(oword, FRF_AZ_RX_DESCQ_BUF_BASE_ID, id, @@ -1279,6 +1615,10 @@ siena_rx_qcreate( return (0); +#if !EFSYS_OPT_RX_SCATTER +fail5: + EFSYS_PROBE(fail5); +#endif fail4: EFSYS_PROBE(fail4); fail3: