]> git.droids-corp.org - dpdk.git/commitdiff
common/sfc_efx/base: support selecting RSS table entry count
authorIvan Malov <ivan.malov@oktetlabs.ru>
Tue, 1 Feb 2022 08:49:59 +0000 (11:49 +0300)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 2 Feb 2022 17:37:31 +0000 (18:37 +0100)
On Riverhead boards, the client can control how many entries
to have in the indirection table of an exclusive RSS context.

Provide the new parameter to clients and indicate its bounds.
Extend the API for writing the table to have the flexibility.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
drivers/common/sfc_efx/base/ef10_impl.h
drivers/common/sfc_efx/base/ef10_nic.c
drivers/common/sfc_efx/base/ef10_rx.c
drivers/common/sfc_efx/base/efx.h
drivers/common/sfc_efx/base/efx_impl.h
drivers/common/sfc_efx/base/efx_mcdi.h
drivers/common/sfc_efx/base/efx_rx.c
drivers/common/sfc_efx/base/rhead_impl.h
drivers/common/sfc_efx/base/rhead_rx.c
drivers/common/sfc_efx/version.map

index 597dd24909527a04821068eb63558fb11a57faf8..342a9a2006022cc3228860752ab8779546f8352b 100644 (file)
@@ -1137,6 +1137,7 @@ ef10_rx_scale_context_alloc(
        __in            efx_nic_t *enp,
        __in            efx_rx_scale_context_type_t type,
        __in            uint32_t num_queues,
+       __in            uint32_t table_nentries,
        __out           uint32_t *rss_contextp);
 
 LIBEFX_INTERNAL
index d9f7c0f36256325e26fdd83f9436ae3d1613c894..cca31bc725c3eb91046a4e3be9967292cd29e071 100644 (file)
@@ -1409,6 +1409,11 @@ ef10_get_datapath_caps(
                 */
                encp->enc_rx_scale_l4_hash_supported = B_TRUE;
        }
+
+       if (CAP_FLAGS3(req, RSS_SELECTABLE_TABLE_SIZE))
+               encp->enc_rx_scale_tbl_entry_count_is_selectable = B_TRUE;
+       else
+               encp->enc_rx_scale_tbl_entry_count_is_selectable = B_FALSE;
 #endif /* EFSYS_OPT_RX_SCALE */
 
        /* Check if the firmware supports "FLAG" and "MARK" filter actions */
@@ -1471,8 +1476,16 @@ ef10_get_datapath_caps(
                encp->enc_rx_scale_indirection_max_nqueues =
                    MCDI_OUT_DWORD(req,
                        GET_CAPABILITIES_V9_OUT_RSS_MAX_INDIRECTION_QUEUES);
+               encp->enc_rx_scale_tbl_min_nentries =
+                   MCDI_OUT_DWORD(req,
+                       GET_CAPABILITIES_V9_OUT_RSS_MIN_INDIRECTION_TABLE_SIZE);
+               encp->enc_rx_scale_tbl_max_nentries =
+                   MCDI_OUT_DWORD(req,
+                       GET_CAPABILITIES_V9_OUT_RSS_MAX_INDIRECTION_TABLE_SIZE);
        } else {
                encp->enc_rx_scale_indirection_max_nqueues = EFX_MAXRSS;
+               encp->enc_rx_scale_tbl_min_nentries = EFX_RSS_TBL_SIZE;
+               encp->enc_rx_scale_tbl_max_nentries = EFX_RSS_TBL_SIZE;
        }
 #endif /* EFSYS_OPT_RX_SCALE */
 
index 5008139a3f0b1d432e906bceca65c7894d0742e5..78af7300a0db08d64a7dde44cf3db1de4a3c118f 100644 (file)
@@ -16,11 +16,12 @@ efx_mcdi_rss_context_alloc(
        __in            efx_nic_t *enp,
        __in            efx_rx_scale_context_type_t type,
        __in            uint32_t num_queues,
+       __in            uint32_t table_nentries,
        __out           uint32_t *rss_contextp)
 {
        const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
        efx_mcdi_req_t req;
-       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN,
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_LEN,
                MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN);
        uint32_t rss_context;
        uint32_t context_type;
@@ -31,6 +32,13 @@ efx_mcdi_rss_context_alloc(
                goto fail1;
        }
 
+       if (table_nentries < encp->enc_rx_scale_tbl_min_nentries ||
+           table_nentries > encp->enc_rx_scale_tbl_max_nentries ||
+           !ISP2(table_nentries)) {
+               rc = EINVAL;
+               goto fail2;
+       }
+
        switch (type) {
        case EFX_RX_SCALE_EXCLUSIVE:
                context_type = MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE;
@@ -40,12 +48,15 @@ efx_mcdi_rss_context_alloc(
                break;
        default:
                rc = EINVAL;
-               goto fail2;
+               goto fail3;
        }
 
        req.emr_cmd = MC_CMD_RSS_CONTEXT_ALLOC;
        req.emr_in_buf = payload;
-       req.emr_in_length = MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN;
+       req.emr_in_length =
+           (encp->enc_rx_scale_tbl_entry_count_is_selectable != B_FALSE) ?
+           MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_LEN :
+           MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN;
        req.emr_out_buf = payload;
        req.emr_out_length = MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN;
 
@@ -61,28 +72,36 @@ efx_mcdi_rss_context_alloc(
         */
        MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_NUM_QUEUES, num_queues);
 
+       if (encp->enc_rx_scale_tbl_entry_count_is_selectable != B_FALSE) {
+               MCDI_IN_SET_DWORD(req,
+                   RSS_CONTEXT_ALLOC_V2_IN_INDIRECTION_TABLE_SIZE,
+                   table_nentries);
+       }
+
        efx_mcdi_execute(enp, &req);
 
        if (req.emr_rc != 0) {
                rc = req.emr_rc;
-               goto fail3;
+               goto fail4;
        }
 
        if (req.emr_out_length_used < MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN) {
                rc = EMSGSIZE;
-               goto fail4;
+               goto fail5;
        }
 
        rss_context = MCDI_OUT_DWORD(req, RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID);
        if (rss_context == EF10_RSS_CONTEXT_INVALID) {
                rc = ENOENT;
-               goto fail5;
+               goto fail6;
        }
 
        *rss_contextp = rss_context;
 
        return (0);
 
+fail6:
+       EFSYS_PROBE(fail6);
 fail5:
        EFSYS_PROBE(fail5);
 fail4:
@@ -347,6 +366,76 @@ fail1:
 }
 #endif /* EFSYS_OPT_RX_SCALE */
 
+#if EFSYS_OPT_RX_SCALE
+static __checkReturn           efx_rc_t
+efx_mcdi_rss_context_write_table(
+       __in                    efx_nic_t *enp,
+       __in                    uint32_t context,
+       __in                    unsigned int start_idx,
+       __in_ecount(nentries)   unsigned int *table,
+       __in                    unsigned int nentries)
+{
+       const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
+       efx_mcdi_req_t req;
+       EFX_MCDI_DECLARE_BUF(payload,
+            MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_LENMAX_MCDI2,
+            MC_CMD_RSS_CONTEXT_WRITE_TABLE_OUT_LEN);
+       unsigned int i;
+       int rc;
+
+       if (nentries >
+           MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_ENTRIES_MAXNUM_MCDI2) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       if (start_idx + nentries >
+           encp->enc_rx_scale_tbl_max_nentries) {
+               rc = EINVAL;
+               goto fail2;
+       }
+
+       req.emr_cmd = MC_CMD_RSS_CONTEXT_WRITE_TABLE;
+       req.emr_in_buf = payload;
+       req.emr_in_length = MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_LEN(nentries);
+       req.emr_out_buf = payload;
+       req.emr_out_length = MC_CMD_RSS_CONTEXT_WRITE_TABLE_OUT_LEN;
+
+       MCDI_IN_SET_DWORD(req,
+           RSS_CONTEXT_WRITE_TABLE_IN_RSS_CONTEXT_ID, context);
+
+       for (i = 0; i < nentries; ++i) {
+               if (table[i] >= encp->enc_rx_scale_indirection_max_nqueues) {
+                       rc = EINVAL;
+                       goto fail3;
+               }
+
+               MCDI_IN_POPULATE_INDEXED_DWORD_2(req,
+                   RSS_CONTEXT_WRITE_TABLE_IN_ENTRIES, i,
+                   RSS_CONTEXT_WRITE_TABLE_ENTRY_INDEX, start_idx + i,
+                   RSS_CONTEXT_WRITE_TABLE_ENTRY_VALUE, table[i]);
+       }
+
+       efx_mcdi_execute(enp, &req);
+       if (req.emr_rc != 0) {
+               rc = req.emr_rc;
+               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);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
 
        __checkReturn   efx_rc_t
 ef10_rx_init(
@@ -355,7 +444,7 @@ ef10_rx_init(
 #if EFSYS_OPT_RX_SCALE
 
        if (efx_mcdi_rss_context_alloc(enp, EFX_RX_SCALE_EXCLUSIVE, EFX_MAXRSS,
-               &enp->en_rss_context) == 0) {
+               EFX_RSS_TBL_SIZE, &enp->en_rss_context) == 0) {
                /*
                 * Allocated an exclusive RSS context, which allows both the
                 * indirection table and key to be modified.
@@ -398,11 +487,13 @@ ef10_rx_scale_context_alloc(
        __in            efx_nic_t *enp,
        __in            efx_rx_scale_context_type_t type,
        __in            uint32_t num_queues,
+       __in            uint32_t table_nentries,
        __out           uint32_t *rss_contextp)
 {
        efx_rc_t rc;
 
-       rc = efx_mcdi_rss_context_alloc(enp, type, num_queues, rss_contextp);
+       rc = efx_mcdi_rss_context_alloc(enp, type, num_queues, table_nentries,
+                                       rss_contextp);
        if (rc != 0)
                goto fail1;
 
@@ -522,6 +613,7 @@ ef10_rx_scale_tbl_set(
        __in_ecount(nentries)   unsigned int *table,
        __in                    size_t nentries)
 {
+       const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
        efx_rc_t rc;
 
 
@@ -533,12 +625,34 @@ ef10_rx_scale_tbl_set(
                rss_context = enp->en_rss_context;
        }
 
-       if ((rc = efx_mcdi_rss_context_set_table(enp,
-                   rss_context, table, nentries)) != 0)
-               goto fail2;
+       if (encp->enc_rx_scale_tbl_entry_count_is_selectable != B_FALSE) {
+               uint32_t index, remain, batch;
+
+               batch = MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_ENTRIES_MAXNUM_MCDI2;
+               index = 0;
+
+               for (remain = nentries; remain > 0; remain -= batch) {
+                       if (batch > remain)
+                               batch = remain;
+
+                       rc = efx_mcdi_rss_context_write_table(enp, rss_context,
+                                   index, &table[index], batch);
+                       if (rc != 0)
+                               goto fail2;
+
+                       index += batch;
+               }
+       } else {
+               rc = efx_mcdi_rss_context_set_table(enp, rss_context, table,
+                           nentries);
+               if (rc != 0)
+                       goto fail3;
+       }
 
        return (0);
 
+fail3:
+       EFSYS_PROBE(fail3);
 fail2:
        EFSYS_PROBE(fail2);
 fail1:
index a35e29ebcf9bb07a34d42284f7603fe403253556..4523829eb264704346fbb4150a8f5e70357058fa 100644 (file)
@@ -1502,6 +1502,10 @@ typedef struct efx_nic_cfg_s {
         * This means that the maximum offset has to be less than this value.
         */
        uint32_t                enc_rx_scale_indirection_max_nqueues;
+       /* Minimum number of entries an RSS indirection table can contain. */
+       uint32_t                enc_rx_scale_tbl_min_nentries;
+       /* Maximum number of entries an RSS indirection table can contain. */
+       uint32_t                enc_rx_scale_tbl_max_nentries;
        uint32_t                enc_rx_scale_max_exclusive_contexts;
        /*
         * Mask of supported hash algorithms.
@@ -1514,6 +1518,11 @@ typedef struct efx_nic_cfg_s {
         */
        boolean_t               enc_rx_scale_l4_hash_supported;
        boolean_t               enc_rx_scale_additional_modes_supported;
+       /*
+        * Indicates whether the user can decide how many entries to
+        * have in the indirection table of an exclusive RSS context.
+        */
+       boolean_t               enc_rx_scale_tbl_entry_count_is_selectable;
 #endif /* EFSYS_OPT_RX_SCALE */
 #if EFSYS_OPT_LOOPBACK
        efx_qword_t             enc_loopback_types[EFX_LINK_NMODES];
@@ -2887,6 +2896,15 @@ efx_rx_scale_context_alloc(
        __in            uint32_t num_queues,
        __out           uint32_t *rss_contextp);
 
+LIBEFX_API
+extern __checkReturn   efx_rc_t
+efx_rx_scale_context_alloc_v2(
+       __in            efx_nic_t *enp,
+       __in            efx_rx_scale_context_type_t type,
+       __in            uint32_t num_queues,
+       __in            uint32_t table_nentries,
+       __out           uint32_t *rss_contextp);
+
 LIBEFX_API
 extern __checkReturn   efx_rc_t
 efx_rx_scale_context_free(
index e2802e6672b4cee4772527694c88668ffd08736d..7dfe30b69516dba7cc6254ee417addee3809a61d 100644 (file)
@@ -173,7 +173,8 @@ typedef struct efx_rx_ops_s {
 #if EFSYS_OPT_RX_SCALE
        efx_rc_t        (*erxo_scale_context_alloc)(efx_nic_t *,
                                                    efx_rx_scale_context_type_t,
-                                                   uint32_t, uint32_t *);
+                                                   uint32_t, uint32_t,
+                                                   uint32_t *);
        efx_rc_t        (*erxo_scale_context_free)(efx_nic_t *, uint32_t);
        efx_rc_t        (*erxo_scale_mode_set)(efx_nic_t *, uint32_t,
                                               efx_rx_hash_alg_t,
index c91ea419115a9c294f214c87e96695f188593920..14a3833567a92e52f7e133cf49b29dac261a5032 100644 (file)
@@ -315,6 +315,10 @@ efx_mcdi_set_nic_addr_regions(
 #define        MCDI_IN2(_emr, _type, _ofst)                                    \
        MCDI_IN(_emr, _type, MC_CMD_ ## _ofst ## _OFST)
 
+#define        MCDI_INDEXED_IN2(_emr, _type, _ofst, _idx)                      \
+       MCDI_IN(_emr, _type, MC_CMD_ ## _ofst ## _OFST +                \
+               _idx * MC_CMD_ ## _ofst ## _LEN)
+
 #define        MCDI_IN_SET_BYTE(_emr, _ofst, _value)                           \
        EFX_POPULATE_BYTE_1(*MCDI_IN2(_emr, efx_byte_t, _ofst),         \
                EFX_BYTE_0, _value)
@@ -356,6 +360,13 @@ efx_mcdi_set_nic_addr_regions(
                MC_CMD_ ## _field1, _value1,                            \
                MC_CMD_ ## _field2, _value2)
 
+#define        MCDI_IN_POPULATE_INDEXED_DWORD_2(_emr, _ofst, _idx,             \
+               _field1, _value1, _field2, _value2)                     \
+       EFX_POPULATE_DWORD_2(                                           \
+               *MCDI_INDEXED_IN2(_emr, efx_dword_t, _ofst, _idx),      \
+               MC_CMD_ ## _field1, _value1,                            \
+               MC_CMD_ ## _field2, _value2)
+
 #define        MCDI_IN_POPULATE_DWORD_3(_emr, _ofst, _field1, _value1,         \
                _field2, _value2, _field3, _value3)                     \
        EFX_POPULATE_DWORD_3(*MCDI_IN2(_emr, efx_dword_t, _ofst),       \
index eb3f736f6384d6f35225cd94f6f7dec649c9d20e..d10b99025911a70785a91188f02d6f6697fc1a1f 100644 (file)
@@ -514,8 +514,44 @@ efx_rx_scale_context_alloc(
                rc = ENOTSUP;
                goto fail1;
        }
+
+       if ((rc = erxop->erxo_scale_context_alloc(enp, type, num_queues,
+                           EFX_RSS_TBL_SIZE, 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_alloc_v2(
+       __in            efx_nic_t *enp,
+       __in            efx_rx_scale_context_type_t type,
+       __in            uint32_t num_queues,
+       __in            uint32_t table_nentries,
+       __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) {
+                           num_queues, table_nentries, rss_contextp)) != 0) {
                goto fail2;
        }
 
index e0d95ba2aa8ed9298dbef9fd7c0aedc55005e570..fb0ecca79dca7a3437388debf02e228f31ce516c 100644 (file)
@@ -261,6 +261,7 @@ rhead_rx_scale_context_alloc(
        __in            efx_nic_t *enp,
        __in            efx_rx_scale_context_type_t type,
        __in            uint32_t num_queues,
+       __in            uint32_t table_nentries,
        __out           uint32_t *rss_contextp);
 
 LIBEFX_INTERNAL
index d28f936ab79c9c4886374ccfb2c6465ef9eb4f4c..d0ac5c02f85d9921a3cf19d8e204e0efc2f3f410 100644 (file)
@@ -88,11 +88,13 @@ rhead_rx_scale_context_alloc(
        __in            efx_nic_t *enp,
        __in            efx_rx_scale_context_type_t type,
        __in            uint32_t num_queues,
+       __in            uint32_t table_nentries,
        __out           uint32_t *rss_contextp)
 {
        efx_rc_t rc;
 
-       rc = ef10_rx_scale_context_alloc(enp, type, num_queues, rss_contextp);
+       rc = ef10_rx_scale_context_alloc(enp, type, num_queues, table_nentries,
+                   rss_contextp);
        if (rc != 0)
                goto fail1;
 
index 97dd943ec4add3240bd382a0fd2a7c413dbfee64..9510897b83d8c0c61ff6a66df974611376bab605 100644 (file)
@@ -216,6 +216,7 @@ INTERNAL {
        efx_rx_qpost;
        efx_rx_qpush;
        efx_rx_scale_context_alloc;
+       efx_rx_scale_context_alloc_v2;
        efx_rx_scale_context_free;
        efx_rx_scale_default_support_get;
        efx_rx_scale_hash_flags_get;