net/sfc: fix power of 2 round up when align has smaller type
[dpdk.git] / drivers / net / sfc / base / ef10_rx.c
index d1971e3..b087a5d 100644 (file)
@@ -8,42 +8,58 @@
 #include "efx_impl.h"
 
 
-#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
+#if EFX_OPTS_EF10()
 
 
 static __checkReturn   efx_rc_t
 efx_mcdi_init_rxq(
        __in            efx_nic_t *enp,
        __in            uint32_t ndescs,
-       __in            uint32_t target_evq,
+       __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 ps_bufsize)
+       __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;
-       uint8_t payload[MAX(MC_CMD_INIT_RXQ_EXT_IN_LEN,
-                           MC_CMD_INIT_RXQ_EXT_OUT_LEN)];
-       int npages = EFX_RXQ_NBUFS(ndescs);
+       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, <=, EFX_RXQ_MAXNDESCS);
+       EFSYS_ASSERT3U(ndescs, <=, encp->enc_rxq_max_ndescs);
 
-       if ((esmp == NULL) || (EFSYS_MEM_SIZE(esmp) < EFX_RXQ_SIZE(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;
 
@@ -67,18 +83,17 @@ efx_mcdi_init_rxq(
                want_outer_classes = B_FALSE;
        }
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_INIT_RXQ;
        req.emr_in_buf = payload;
-       req.emr_in_length = MC_CMD_INIT_RXQ_EXT_IN_LEN;
+       req.emr_in_length = MC_CMD_INIT_RXQ_V4_IN_LEN;
        req.emr_out_buf = payload;
-       req.emr_out_length = MC_CMD_INIT_RXQ_EXT_OUT_LEN;
+       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, target_evq);
+       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_9(req, INIT_RXQ_EXT_IN_FLAGS,
+       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,
@@ -88,9 +103,27 @@ efx_mcdi_init_rxq(
            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_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, EVB_PORT_ID_ASSIGNED);
+       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);
@@ -108,11 +141,13 @@ efx_mcdi_init_rxq(
 
        if (req.emr_rc != 0) {
                rc = req.emr_rc;
-               goto fail2;
+               goto fail3;
        }
 
        return (0);
 
+fail3:
+       EFSYS_PROBE(fail3);
 fail2:
        EFSYS_PROBE(fail2);
 fail1:
@@ -127,11 +162,10 @@ efx_mcdi_fini_rxq(
        __in            uint32_t instance)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_FINI_RXQ_IN_LEN,
-                           MC_CMD_FINI_RXQ_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FINI_RXQ_IN_LEN,
+               MC_CMD_FINI_RXQ_OUT_LEN);
        efx_rc_t rc;
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_FINI_RXQ;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_FINI_RXQ_IN_LEN;
@@ -169,8 +203,8 @@ efx_mcdi_rss_context_alloc(
        __out           uint32_t *rss_contextp)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN,
-                           MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN,
+               MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN);
        uint32_t rss_context;
        uint32_t context_type;
        efx_rc_t rc;
@@ -192,7 +226,6 @@ efx_mcdi_rss_context_alloc(
                goto fail2;
        }
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_RSS_CONTEXT_ALLOC;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN;
@@ -200,7 +233,7 @@ efx_mcdi_rss_context_alloc(
        req.emr_out_length = MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN;
 
        MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID,
-           EVB_PORT_ID_ASSIGNED);
+               enp->en_vport_id);
        MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_TYPE, context_type);
 
        /*
@@ -255,8 +288,8 @@ efx_mcdi_rss_context_free(
        __in            uint32_t rss_context)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_FREE_IN_LEN,
-                           MC_CMD_RSS_CONTEXT_FREE_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_FREE_IN_LEN,
+               MC_CMD_RSS_CONTEXT_FREE_OUT_LEN);
        efx_rc_t rc;
 
        if (rss_context == EF10_RSS_CONTEXT_INVALID) {
@@ -264,7 +297,6 @@ efx_mcdi_rss_context_free(
                goto fail1;
        }
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_RSS_CONTEXT_FREE;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_RSS_CONTEXT_FREE_IN_LEN;
@@ -298,13 +330,10 @@ efx_mcdi_rss_context_set_flags(
        __in            uint32_t rss_context,
        __in            efx_rx_hash_type_t type)
 {
-       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_nic_cfg_t *encp = &enp->en_nic_cfg;
        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_MCDI_DECLARE_BUF(payload, 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 ==
@@ -329,7 +358,6 @@ efx_mcdi_rss_context_set_flags(
                goto fail1;
        }
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_FLAGS;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN;
@@ -339,20 +367,38 @@ efx_mcdi_rss_context_set_flags(
        MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID,
            rss_context);
 
-       type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE) | EFX_RX_HASH(IPV4_TCP, 2TUPLE);
-       type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE);
-       type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE) | EFX_RX_HASH(IPV6_TCP, 2TUPLE);
-       type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE);
+       /*
+        * 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)
+               type &= EFX_RX_HASH_LEGACY_MASK;
 
-       MCDI_IN_POPULATE_DWORD_4(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS,
+       MCDI_IN_POPULATE_DWORD_10(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS,
            RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN,
-           ((type & type_ipv4) == type_ipv4) ? 1 : 0,
+           (type & EFX_RX_HASH_IPV4) ? 1 : 0,
            RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN,
-           ((type & type_ipv4_tcp) == type_ipv4_tcp) ? 1 : 0,
+           (type & EFX_RX_HASH_TCPIPV4) ? 1 : 0,
            RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN,
-           ((type & type_ipv6) == type_ipv6) ? 1 : 0,
+           (type & EFX_RX_HASH_IPV6) ? 1 : 0,
            RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN,
-           ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0);
+           (type & EFX_RX_HASH_TCPIPV6) ? 1 : 0,
+           RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE,
+           (type >> EFX_RX_CLASS_IPV4_TCP_LBN) &
+           EFX_MASK32(EFX_RX_CLASS_IPV4_TCP),
+           RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE,
+           (type >> EFX_RX_CLASS_IPV4_UDP_LBN) &
+           EFX_MASK32(EFX_RX_CLASS_IPV4_UDP),
+           RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE,
+           (type >> EFX_RX_CLASS_IPV4_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV4),
+           RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE,
+           (type >> EFX_RX_CLASS_IPV6_TCP_LBN) &
+           EFX_MASK32(EFX_RX_CLASS_IPV6_TCP),
+           RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE,
+           (type >> EFX_RX_CLASS_IPV6_UDP_LBN) &
+           EFX_MASK32(EFX_RX_CLASS_IPV6_UDP),
+           RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE,
+           (type >> EFX_RX_CLASS_IPV6_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV6));
 
        efx_mcdi_execute(enp, &req);
 
@@ -381,8 +427,8 @@ efx_mcdi_rss_context_set_key(
        __in            size_t n)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN,
-                           MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN,
+               MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN);
        efx_rc_t rc;
 
        if (rss_context == EF10_RSS_CONTEXT_INVALID) {
@@ -390,7 +436,6 @@ efx_mcdi_rss_context_set_key(
                goto fail1;
        }
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_KEY;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN;
@@ -438,8 +483,8 @@ efx_mcdi_rss_context_set_table(
        __in            size_t n)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN,
-                           MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN,
+               MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN);
        uint8_t *req_table;
        int i, rc;
 
@@ -448,7 +493,6 @@ efx_mcdi_rss_context_set_table(
                goto fail1;
        }
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_TABLE;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN;
@@ -577,12 +621,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;
        }
@@ -731,6 +776,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) |
@@ -901,8 +947,9 @@ ef10_rx_qps_packet_info(
        *lengthp   = EFX_QWORD_FIELD(*qwordp, ES_DZ_PS_RX_PREFIX_ORIG_LEN);
        buf_len    = EFX_QWORD_FIELD(*qwordp, ES_DZ_PS_RX_PREFIX_CAP_LEN);
 
-       buf_len = P2ROUNDUP(buf_len + EFX_RX_PACKED_STREAM_RX_PREFIX_SIZE,
-                           EFX_RX_PACKED_STREAM_ALIGNMENT);
+       buf_len = EFX_P2ROUNDUP(uint16_t,
+           buf_len + EFX_RX_PACKED_STREAM_RX_PREFIX_SIZE,
+           EFX_RX_PACKED_STREAM_ALIGNMENT);
        *next_offsetp =
            current_offset + buf_len + EFX_RX_PACKED_STREAM_ALIGNMENT;
 
@@ -959,7 +1006,7 @@ ef10_rx_qcreate(
        __in            unsigned int index,
        __in            unsigned int label,
        __in            efx_rxq_type_t type,
-       __in            uint32_t type_data,
+       __in_opt        const efx_rxq_type_data_t *type_data,
        __in            efsys_mem_t *esmp,
        __in            size_t ndescs,
        __in            uint32_t id,
@@ -972,33 +1019,38 @@ ef10_rx_qcreate(
        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, type_data))
+       _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);
 
-       EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS));
-       EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS));
-
-       if (!ISP2(ndescs) ||
-           (ndescs < EFX_RXQ_MINNDESCS) || (ndescs > EFX_RXQ_MAXNDESCS)) {
-               rc = EINVAL;
-               goto fail1;
-       }
        if (index >= encp->enc_rxq_limit) {
                rc = EINVAL;
-               goto fail2;
+               goto fail1;
        }
 
        switch (type) {
        case EFX_RXQ_TYPE_DEFAULT:
+               if (type_data == NULL) {
+                       rc = EINVAL;
+                       goto fail2;
+               }
+               erp->er_buf_size = type_data->ertd_default.ed_buf_size;
                ps_buf_size = 0;
                break;
 #if EFSYS_OPT_RX_PACKED_STREAM
        case EFX_RXQ_TYPE_PACKED_STREAM:
-               switch (type_data) {
+               if (type_data == NULL) {
+                       rc = EINVAL;
+                       goto fail3;
+               }
+               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;
                        break;
@@ -1016,13 +1068,31 @@ ef10_rx_qcreate(
                        break;
                default:
                        rc = ENOTSUP;
-                       goto fail3;
+                       goto fail4;
                }
+               erp->er_buf_size = type_data->ertd_packed_stream.eps_buf_size;
                break;
 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
+#if EFSYS_OPT_RX_ES_SUPER_BUFFER
+       case EFX_RXQ_TYPE_ES_SUPER_BUFFER:
+               if (type_data == NULL) {
+                       rc = EINVAL;
+                       goto fail5;
+               }
+               ps_buf_size = 0;
+               es_bufs_per_desc =
+                   type_data->ertd_es_super_buffer.eessb_bufs_per_desc;
+               es_max_dma_len =
+                   type_data->ertd_es_super_buffer.eessb_max_dma_len;
+               es_buf_stride =
+                   type_data->ertd_es_super_buffer.eessb_buf_stride;
+               hol_block_timeout =
+                   type_data->ertd_es_super_buffer.eessb_hol_block_timeout;
+               break;
+#endif /* EFSYS_OPT_RX_ES_SUPER_BUFFER */
        default:
                rc = ENOTSUP;
-               goto fail4;
+               goto fail6;
        }
 
 #if EFSYS_OPT_RX_PACKED_STREAM
@@ -1030,19 +1100,40 @@ ef10_rx_qcreate(
                /* Check if datapath firmware supports packed stream mode */
                if (encp->enc_rx_packed_stream_supported == B_FALSE) {
                        rc = ENOTSUP;
-                       goto fail5;
+                       goto fail7;
                }
                /* Check if packed stream allows configurable buffer sizes */
                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 fail6;
+                       goto fail8;
                }
        }
 #else /* EFSYS_OPT_RX_PACKED_STREAM */
        EFSYS_ASSERT(ps_buf_size == 0);
 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
 
+#if EFSYS_OPT_RX_ES_SUPER_BUFFER
+       if (es_bufs_per_desc > 0) {
+               if (encp->enc_rx_es_super_buffer_supported == B_FALSE) {
+                       rc = ENOTSUP;
+                       goto fail9;
+               }
+               if (!IS_P2ALIGNED(es_max_dma_len,
+                           EFX_RX_ES_SUPER_BUFFER_BUF_ALIGNMENT)) {
+                       rc = EINVAL;
+                       goto fail10;
+               }
+               if (!IS_P2ALIGNED(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);
+#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;
@@ -1054,10 +1145,11 @@ ef10_rx_qcreate(
        else
                want_inner_classes = B_FALSE;
 
-       if ((rc = efx_mcdi_init_rxq(enp, ndescs, eep->ee_index, label, index,
-                   esmp, disable_scatter, want_inner_classes,
-                   ps_buf_size)) != 0)
-               goto fail7;
+       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)
+               goto fail12;
 
        erp->er_eep = eep;
        erp->er_label = label;
@@ -1068,17 +1160,31 @@ ef10_rx_qcreate(
 
        return (0);
 
+fail12:
+       EFSYS_PROBE(fail12);
+#if EFSYS_OPT_RX_ES_SUPER_BUFFER
+fail11:
+       EFSYS_PROBE(fail11);
+fail10:
+       EFSYS_PROBE(fail10);
+fail9:
+       EFSYS_PROBE(fail9);
+#endif /* EFSYS_OPT_RX_ES_SUPER_BUFFER */
+#if EFSYS_OPT_RX_PACKED_STREAM
+fail8:
+       EFSYS_PROBE(fail8);
 fail7:
        EFSYS_PROBE(fail7);
-#if EFSYS_OPT_RX_PACKED_STREAM
+#endif /* EFSYS_OPT_RX_PACKED_STREAM */
 fail6:
        EFSYS_PROBE(fail6);
+#if EFSYS_OPT_RX_ES_SUPER_BUFFER
 fail5:
        EFSYS_PROBE(fail5);
-#endif /* EFSYS_OPT_RX_PACKED_STREAM */
+#endif /* EFSYS_OPT_RX_ES_SUPER_BUFFER */
+#if EFSYS_OPT_RX_PACKED_STREAM
 fail4:
        EFSYS_PROBE(fail4);
-#if EFSYS_OPT_RX_PACKED_STREAM
 fail3:
        EFSYS_PROBE(fail3);
 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
@@ -1120,4 +1226,4 @@ ef10_rx_fini(
 #endif /* EFSYS_OPT_RX_SCALE */
 }
 
-#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
+#endif /* EFX_OPTS_EF10() */