-/*
- * 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"
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);
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);
__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(
#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 *
__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);
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 */
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 */
};
#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 */
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 */
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 */
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
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;
#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 *flagsp,
+ __out unsigned int *nflagsp)
+{
+ efx_nic_cfg_t *encp = &enp->en_nic_cfg;
+ boolean_t l4;
+ boolean_t additional_modes;
+ unsigned int *entryp = flagsp;
+ efx_rc_t rc;
+
+ if (flagsp == NULL || nflagsp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0) {
+ *nflagsp = 0;
+ return 0;
+ }
+
+ 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)
+
+ 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);
+
+#undef LIST_FLAGS
+
+ *nflagsp = (unsigned int)(entryp - flagsp);
+ EFSYS_ASSERT3U(*nflagsp, <=, EFX_RX_HASH_NFLAGS);
+
+ return (0);
+
+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,
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);
__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)
{
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);
__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)
{
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);
}
#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;
EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
- erxop->erxo_qps_update_credits(erp);
+ erxop->erxo_qpush_ps_credits(erp);
}
__checkReturn uint8_t *
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)
{
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++;
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)
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);
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:
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)
{
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 */
--offset) {
if (oword.eo_u8[offset - 1] != key[byte++]) {
rc = EFAULT;
- goto fail1;
+ goto fail2;
}
}
--offset) {
if (oword.eo_u8[offset - 1] != key[byte++]) {
rc = EFAULT;
- goto fail2;
+ goto fail3;
}
}
--offset) {
if (oword.eo_u8[offset - 1] != key[byte++]) {
rc = EFAULT;
- goto fail3;
+ goto fail4;
}
}
--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:
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)
{
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;
/* 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:
}
-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;
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);
#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 */
__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));
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;
}
}
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;
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,
return (0);
+#if !EFSYS_OPT_RX_SCATTER
+fail5:
+ EFSYS_PROBE(fail5);
+#endif
fail4:
EFSYS_PROBE(fail4);
fail3: