P7 adapters support XOR based and checksum based RSS hashing.
Add support for checksum and XOR based RSS hash for these adapters.

Signed-off-by: Ajit Khaparde <ajit.khapa...@broadcom.com>
Reviewed-by: Damodharam Ammepalli <damodharam.ammepa...@broadcom.com>
---
 drivers/net/bnxt/bnxt.h        |  15 +--
 drivers/net/bnxt/bnxt_ethdev.c |  72 ++++++---------
 drivers/net/bnxt/bnxt_flow.c   |  37 +++++++-
 drivers/net/bnxt/bnxt_hwrm.c   |   6 ++
 drivers/net/bnxt/bnxt_reps.c   |   2 +-
 drivers/net/bnxt/bnxt_vnic.c   | 161 +++++++++++++++++++++++++++++++--
 drivers/net/bnxt/bnxt_vnic.h   |  18 +++-
 7 files changed, 242 insertions(+), 69 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index cd85a944e8..e7b288c849 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -638,15 +638,6 @@ struct bnxt_rep_info {
 #define BNXT_FW_STATUS_HEALTHY         0x8000
 #define BNXT_FW_STATUS_SHUTDOWN                0x100000
 
-#define BNXT_ETH_RSS_SUPPORT ( \
-       RTE_ETH_RSS_IPV4 |              \
-       RTE_ETH_RSS_NONFRAG_IPV4_TCP |  \
-       RTE_ETH_RSS_NONFRAG_IPV4_UDP |  \
-       RTE_ETH_RSS_IPV6 |              \
-       RTE_ETH_RSS_NONFRAG_IPV6_TCP |  \
-       RTE_ETH_RSS_NONFRAG_IPV6_UDP |  \
-       RTE_ETH_RSS_LEVEL_MASK)
-
 #define BNXT_HWRM_SHORT_REQ_LEN                sizeof(struct hwrm_short_input)
 
 struct bnxt_flow_stat_info {
@@ -815,7 +806,10 @@ struct bnxt {
 #define BNXT_VNIC_CAP_VLAN_RX_STRIP    BIT(3)
 #define BNXT_RX_VLAN_STRIP_EN(bp)      ((bp)->vnic_cap_flags & 
BNXT_VNIC_CAP_VLAN_RX_STRIP)
 #define BNXT_VNIC_CAP_OUTER_RSS_TRUSTED_VF     BIT(4)
-#define BNXT_VNIC_CAP_L2_CQE_MODE              BIT(8)
+#define BNXT_VNIC_CAP_XOR_MODE         BIT(5)
+#define BNXT_VNIC_CAP_CHKSM_MODE       BIT(6)
+#define BNXT_VNIC_CAP_L2_CQE_MODE      BIT(8)
+
        unsigned int            rx_nr_rings;
        unsigned int            rx_cp_nr_rings;
        unsigned int            rx_num_qs_per_vnic;
@@ -1176,4 +1170,5 @@ void bnxt_handle_vf_cfg_change(void *arg);
 int bnxt_flow_meter_ops_get(struct rte_eth_dev *eth_dev, void *arg);
 struct bnxt_vnic_info *bnxt_get_default_vnic(struct bnxt *bp);
 struct tf *bnxt_get_tfp_session(struct bnxt *bp, enum bnxt_session_type type);
+uint64_t bnxt_eth_rss_support(struct bnxt *bp);
 #endif
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 0f1c4326c4..ef5e65ff16 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -982,6 +982,25 @@ uint32_t bnxt_get_speed_capabilities(struct bnxt *bp)
        return speed_capa;
 }
 
+uint64_t bnxt_eth_rss_support(struct bnxt *bp)
+{
+       uint64_t support;
+
+       support = RTE_ETH_RSS_IPV4 |
+                 RTE_ETH_RSS_NONFRAG_IPV4_TCP |
+                 RTE_ETH_RSS_NONFRAG_IPV4_UDP |
+                 RTE_ETH_RSS_IPV6 |
+                 RTE_ETH_RSS_NONFRAG_IPV6_TCP |
+                 RTE_ETH_RSS_NONFRAG_IPV6_UDP |
+                 RTE_ETH_RSS_LEVEL_MASK;
+
+       if (bp->vnic_cap_flags & BNXT_VNIC_CAP_CHKSM_MODE)
+               support |= (RTE_ETH_RSS_IPV4_CHKSUM |
+                           RTE_ETH_RSS_L4_CHKSUM);
+
+       return support;
+}
+
 static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
                                struct rte_eth_dev_info *dev_info)
 {
@@ -1023,7 +1042,7 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev 
*eth_dev,
        dev_info->tx_queue_offload_capa = RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
        dev_info->tx_offload_capa = bnxt_get_tx_port_offloads(bp) |
                                    dev_info->tx_queue_offload_capa;
-       dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT;
+       dev_info->flow_type_rss_offloads = bnxt_eth_rss_support(bp);
 
        dev_info->speed_capa = bnxt_get_speed_capabilities(bp);
        dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
@@ -2175,7 +2194,7 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev 
*eth_dev,
                if (!rss_conf->rss_hf)
                        PMD_DRV_LOG(ERR, "Hash type NONE\n");
        } else {
-               if (rss_conf->rss_hf & BNXT_ETH_RSS_SUPPORT)
+               if (rss_conf->rss_hf & bnxt_eth_rss_support(bp))
                        return -EINVAL;
        }
 
@@ -2185,6 +2204,12 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev 
*eth_dev,
        vnic->hash_mode =
                bnxt_rte_to_hwrm_hash_level(bp, rss_conf->rss_hf,
                                            
RTE_ETH_RSS_LEVEL(rss_conf->rss_hf));
+       rc = bnxt_rte_eth_to_hwrm_ring_select_mode(bp, rss_conf->rss_hf, vnic);
+       if (rc != 0)
+               return rc;
+
+       /* Cache the hash function */
+       bp->rss_conf.rss_hf = rss_conf->rss_hf;
 
        /* Cache the hash function */
        bp->rss_conf.rss_hf = rss_conf->rss_hf;
@@ -2218,60 +2243,21 @@ static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev 
*eth_dev,
        struct bnxt *bp = eth_dev->data->dev_private;
        struct bnxt_vnic_info *vnic = bnxt_get_default_vnic(bp);
        int len, rc;
-       uint32_t hash_types;
 
        rc = is_bnxt_in_error(bp);
        if (rc)
                return rc;
 
-       /* RSS configuration is the same for all VNICs */
+       /* Return the RSS configuration of the default VNIC. */
        if (vnic && vnic->rss_hash_key) {
                if (rss_conf->rss_key) {
                        len = rss_conf->rss_key_len <= HW_HASH_KEY_SIZE ?
                              rss_conf->rss_key_len : HW_HASH_KEY_SIZE;
                        memcpy(rss_conf->rss_key, vnic->rss_hash_key, len);
                }
-
-               hash_types = vnic->hash_type;
-               rss_conf->rss_hf = 0;
-               if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4) {
-                       rss_conf->rss_hf |= RTE_ETH_RSS_IPV4;
-                       hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
-               }
-               if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4) {
-                       rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP;
-                       hash_types &=
-                               ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
-               }
-               if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4) {
-                       rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP;
-                       hash_types &=
-                               ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4;
-               }
-               if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6) {
-                       rss_conf->rss_hf |= RTE_ETH_RSS_IPV6;
-                       hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
-               }
-               if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6) {
-                       rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP;
-                       hash_types &=
-                               ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
-               }
-               if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6) {
-                       rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP;
-                       hash_types &=
-                               ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
-               }
-
+               bnxt_hwrm_rss_to_rte_hash_conf(vnic, &rss_conf->rss_hf);
                rss_conf->rss_hf |=
                        bnxt_hwrm_to_rte_rss_level(bp, vnic->hash_mode);
-
-               if (hash_types) {
-                       PMD_DRV_LOG(ERR,
-                               "Unknown RSS config from firmware (%08x), RSS 
disabled",
-                               vnic->hash_type);
-                       return -ENOTSUP;
-               }
        } else {
                rss_conf->rss_hf = 0;
        }
diff --git a/drivers/net/bnxt/bnxt_flow.c b/drivers/net/bnxt/bnxt_flow.c
index 15f0e1b308..2d707b48d2 100644
--- a/drivers/net/bnxt/bnxt_flow.c
+++ b/drivers/net/bnxt/bnxt_flow.c
@@ -881,6 +881,7 @@ static void bnxt_vnic_cleanup(struct bnxt *bp, struct 
bnxt_vnic_info *vnic)
        vnic->fw_grp_ids = NULL;
 
        vnic->rx_queue_cnt = 0;
+       vnic->hash_type = 0;
 }
 
 static int bnxt_vnic_prep(struct bnxt *bp, struct bnxt_vnic_info *vnic,
@@ -1067,7 +1068,7 @@ bnxt_vnic_rss_cfg_update(struct bnxt *bp,
 {
        const struct rte_flow_action_rss *rss;
        unsigned int rss_idx, i, j, fw_idx;
-       uint16_t hash_type;
+       uint32_t hash_type;
        uint64_t types;
        int rc;
 
@@ -1115,9 +1116,9 @@ bnxt_vnic_rss_cfg_update(struct bnxt *bp,
                }
        }
 
-       /* Currently only Toeplitz hash is supported. */
-       if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT &&
-           rss->func != RTE_ETH_HASH_FUNCTION_TOEPLITZ) {
+       if (BNXT_IS_HASH_FUNC_DEFAULT(rss->func) &&
+           BNXT_IS_HASH_FUNC_TOEPLITZ(rss->func) &&
+           BNXT_IS_HASH_FUNC_SIMPLE_XOR(bp, rss->func)) {
                rte_flow_error_set(error,
                                   ENOTSUP,
                                   RTE_FLOW_ERROR_TYPE_ACTION,
@@ -1175,6 +1176,34 @@ bnxt_vnic_rss_cfg_update(struct bnxt *bp,
        vnic->hash_mode =
                bnxt_rte_to_hwrm_hash_level(bp, rss->types, rss->level);
 
+       /* For P7 chips update the hash_type if hash_type not explicitly passed.
+        * TODO: For P5 chips.
+        */
+       if (BNXT_CHIP_P7(bp) &&
+           vnic->hash_mode == BNXT_HASH_MODE_DEFAULT && !hash_type)
+               vnic->hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 |
+                       HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+
+       /* TODO:
+        * hash will be performed on the L3 and L4 packet headers.
+        * specific RSS hash types like IPv4-TCP etc... or L4-chksum or 
IPV4-chksum
+        * will NOT have any bearing and will not be honored.
+        * Check and reject flow create accordingly. TODO.
+        */
+
+       rc = bnxt_rte_flow_to_hwrm_ring_select_mode(rss->func,
+                                                   rss->types,
+                                                   bp, vnic);
+       if (rc) {
+               rte_flow_error_set(error,
+                                  ENOTSUP,
+                                  RTE_FLOW_ERROR_TYPE_ACTION,
+                                  act,
+                                  "Unsupported RSS hash parameters");
+               rc = -rte_errno;
+               goto ret;
+       }
+
        /* Update RSS key only if key_len != 0 */
        if (rss->key_len != 0)
                memcpy(vnic->rss_hash_key, rss->key, rss->key_len);
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index d649f217ec..587433a878 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1025,6 +1025,12 @@ int bnxt_hwrm_vnic_qcaps(struct bnxt *bp)
                PMD_DRV_LOG(DEBUG, "Rx VLAN strip capability enabled\n");
        }
 
+       if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RING_SELECT_MODE_XOR_CAP)
+               bp->vnic_cap_flags |= BNXT_VNIC_CAP_XOR_MODE;
+
+       if (flags & 
HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RING_SELECT_MODE_TOEPLITZ_CHKSM_CAP)
+               bp->vnic_cap_flags |= BNXT_VNIC_CAP_CHKSM_MODE;
+
        bp->max_tpa_v2 = rte_le_to_cpu_16(resp->max_aggs_supported);
 
        HWRM_UNLOCK();
diff --git a/drivers/net/bnxt/bnxt_reps.c b/drivers/net/bnxt/bnxt_reps.c
index 78337431af..d96d972904 100644
--- a/drivers/net/bnxt/bnxt_reps.c
+++ b/drivers/net/bnxt/bnxt_reps.c
@@ -569,7 +569,7 @@ int bnxt_rep_dev_info_get_op(struct rte_eth_dev *eth_dev,
 
        dev_info->rx_offload_capa = bnxt_get_rx_port_offloads(parent_bp);
        dev_info->tx_offload_capa = bnxt_get_tx_port_offloads(parent_bp);
-       dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT;
+       dev_info->flow_type_rss_offloads = bnxt_eth_rss_support(parent_bp);
 
        dev_info->switch_info.name = eth_dev->device->name;
        dev_info->switch_info.domain_id = rep_bp->switch_domain_id;
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index bf93120d28..6a57f85ea7 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -256,10 +256,15 @@ int bnxt_vnic_grp_alloc(struct bnxt *bp, struct 
bnxt_vnic_info *vnic)
        return 0;
 }
 
-uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type)
+uint32_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type)
 {
-       uint16_t hwrm_type = 0;
+       uint32_t hwrm_type = 0;
 
+       if (rte_type & RTE_ETH_RSS_IPV4_CHKSUM)
+               hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
+       if (rte_type & RTE_ETH_RSS_L4_CHKSUM)
+               hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 |
+                            HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
        if ((rte_type & RTE_ETH_RSS_IPV4) ||
            (rte_type & RTE_ETH_RSS_ECPRI))
                hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
@@ -273,6 +278,9 @@ uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type)
                hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
        if (rte_type & RTE_ETH_RSS_NONFRAG_IPV6_UDP)
                hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
+       if (rte_type & RTE_ETH_RSS_IPV4_CHKSUM)
+               hwrm_type |=
+                       
HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ_CHECKSUM;
 
        return hwrm_type;
 }
@@ -287,6 +295,8 @@ int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t 
hash_f, uint32_t lvl)
                             RTE_ETH_RSS_NONFRAG_IPV6_TCP));
        bool l3_only = l3 && !l4;
        bool l3_and_l4 = l3 && l4;
+       bool cksum = !!(hash_f &
+                       (RTE_ETH_RSS_IPV4_CHKSUM | RTE_ETH_RSS_L4_CHKSUM));
 
        /* If FW has not advertised capability to configure outer/inner
         * RSS hashing , just log a message. HW will work in default RSS mode.
@@ -302,12 +312,12 @@ int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t 
hash_f, uint32_t lvl)
        switch (lvl) {
        case BNXT_RSS_LEVEL_INNERMOST:
                /* Irrespective of what RTE says, FW always does 4 tuple */
-               if (l3_and_l4 || l4 || l3_only)
+               if (l3_and_l4 || l4 || l3_only || cksum)
                        mode = BNXT_HASH_MODE_INNERMOST;
                break;
        case BNXT_RSS_LEVEL_OUTERMOST:
                /* Irrespective of what RTE says, FW always does 4 tuple */
-               if (l3_and_l4 || l4 || l3_only)
+               if (l3_and_l4 || l4 || l3_only || cksum)
                        mode = BNXT_HASH_MODE_OUTERMOST;
                break;
        default:
@@ -733,6 +743,16 @@ bnxt_vnic_rss_create(struct bnxt *bp,
                goto fail_cleanup;
        }
 
+       /* Remove unsupported types */
+       rss_info->rss_types &= bnxt_eth_rss_support(bp);
+
+       /* If only unsupported type(s) are specified then quit */
+       if (rss_info->rss_types == 0) {
+               PMD_DRV_LOG(ERR,
+                           "Unsupported RSS hash type(s)\n");
+               goto fail_cleanup;
+       }
+
        /* hwrm_type conversion */
        vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_info->rss_types);
        vnic->hash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss_info->rss_types,
@@ -803,9 +823,11 @@ bnxt_vnic_rss_hash_algo_update(struct bnxt *bp,
                               struct bnxt_vnic_rss_info *rss_info)
 {
        uint8_t old_rss_hash_key[HW_HASH_KEY_SIZE] = { 0 };
-       uint16_t        hash_type;
-       uint8_t         hash_mode;
+       uint32_t hash_type;
+       uint8_t hash_mode;
+       uint8_t ring_mode;
        uint32_t apply = 0;
+       int rc;
 
        /* validate key length */
        if (rss_info->key_len != 0 && rss_info->key_len != HW_HASH_KEY_SIZE) {
@@ -815,12 +837,40 @@ bnxt_vnic_rss_hash_algo_update(struct bnxt *bp,
                return -EINVAL;
        }
 
+       /* Remove unsupported types */
+       rss_info->rss_types &= bnxt_eth_rss_support(bp);
+
+       /* If only unsupported type(s) are specified then quit */
+       if (!rss_info->rss_types) {
+               PMD_DRV_LOG(ERR,
+                           "Unsupported RSS hash type\n");
+               return -EINVAL;
+       }
+
        /* hwrm_type conversion */
        hash_type = bnxt_rte_to_hwrm_hash_types(rss_info->rss_types);
        hash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss_info->rss_types,
                                                rss_info->rss_level);
+       ring_mode = vnic->ring_select_mode;
+
+       /* For P7 chips update the hash_type if hash_type not explicitly passed.
+        * TODO: For P5 chips.
+        */
+       if (BNXT_CHIP_P7(bp) &&
+           hash_mode == BNXT_HASH_MODE_DEFAULT && !hash_type)
+               vnic->hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 |
+                       HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+
+       rc = bnxt_rte_flow_to_hwrm_ring_select_mode(rss_info->rss_func,
+                                                   rss_info->rss_types,
+                                                   bp,
+                                                   vnic);
+       if (rc)
+               return -EINVAL;
+
        if (vnic->hash_mode != hash_mode ||
-           vnic->hash_type != hash_type) {
+           vnic->hash_type != hash_type ||
+           vnic->ring_select_mode != ring_mode) {
                apply = 1;
                vnic->hash_mode = hash_mode;
                vnic->hash_type = hash_type;
@@ -839,10 +889,10 @@ bnxt_vnic_rss_hash_algo_update(struct bnxt *bp,
        if (apply) {
                if (bnxt_hwrm_vnic_rss_cfg(bp, vnic)) {
                        memcpy(vnic->rss_hash_key, old_rss_hash_key, 
HW_HASH_KEY_SIZE);
-                       BNXT_TF_DBG(ERR, "Error configuring vnic RSS config\n");
+                       PMD_DRV_LOG(ERR, "Error configuring vnic RSS config\n");
                        return -EINVAL;
                }
-               BNXT_TF_DBG(INFO, "Rss config successfully applied\n");
+               PMD_DRV_LOG(INFO, "Rss config successfully applied\n");
        }
        return 0;
 }
@@ -1245,3 +1295,96 @@ bnxt_get_default_vnic(struct bnxt *bp)
 {
        return &bp->vnic_info[bp->vnic_queue_db.dflt_vnic_id];
 }
+
+uint8_t _bnxt_rte_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f)
+{
+       /* If RTE_ETH_HASH_FUNCTION_DEFAULT || RTE_ETH_HASH_FUNCTION_TOEPLITZ */
+       uint8_t mode = HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ;
+
+       if (hash_f == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR)
+               mode = HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_XOR;
+
+       return mode;
+}
+
+int bnxt_rte_flow_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f,
+                                          uint64_t types, struct bnxt *bp,
+                                          struct bnxt_vnic_info *vnic)
+{
+       if (hash_f != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
+           hash_f != RTE_ETH_HASH_FUNCTION_DEFAULT) {
+               if (hash_f == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ ||
+                   (!BNXT_CHIP_P7(bp) && hash_f == 
RTE_ETH_HASH_FUNCTION_SIMPLE_XOR)) {
+                       PMD_DRV_LOG(ERR, "Unsupported hash function\n");
+                       return -ENOTSUP;
+               }
+       }
+
+       if (types & RTE_ETH_RSS_IPV4_CHKSUM || types & RTE_ETH_RSS_L4_CHKSUM) {
+               if ((bp->vnic_cap_flags & BNXT_VNIC_CAP_CHKSM_MODE) &&
+                       (hash_f == RTE_ETH_HASH_FUNCTION_DEFAULT ||
+                        hash_f == RTE_ETH_HASH_FUNCTION_TOEPLITZ)) {
+                       /* Checksum mode cannot with hash func makes no sense */
+                       vnic->ring_select_mode =
+                               
HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ_CHECKSUM;
+                       /* shadow copy types as !hash_f is always true with 
default func */
+                       return 0;
+               }
+               PMD_DRV_LOG(ERR, "Hash function not supported with checksun 
type\n");
+               return -ENOTSUP;
+       }
+
+       vnic->ring_select_mode = _bnxt_rte_to_hwrm_ring_select_mode(hash_f);
+       return 0;
+}
+
+int bnxt_rte_eth_to_hwrm_ring_select_mode(struct bnxt *bp, uint64_t types,
+                                         struct bnxt_vnic_info *vnic)
+{
+       /* If the config update comes via ethdev, there is no way to
+        * specify anything for hash function.
+        * So its either TOEPLITZ or the Checksum mode.
+        * Note that checksum mode is not supported on older devices.
+        */
+       if (types == RTE_ETH_RSS_IPV4_CHKSUM) {
+               if (bp->vnic_cap_flags & BNXT_VNIC_CAP_CHKSM_MODE)
+                       vnic->ring_select_mode =
+                       
HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ_CHECKSUM;
+               else
+                       return -ENOTSUP;
+       }
+
+       /* Older devices can support TOEPLITZ only.
+        * Thor2 supports other hash functions, but can't change using this 
path.
+        */
+       vnic->ring_select_mode =
+               HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ;
+       return 0;
+}
+
+void bnxt_hwrm_rss_to_rte_hash_conf(struct bnxt_vnic_info *vnic,
+                                   uint64_t *rss_conf)
+{
+       uint32_t hash_types;
+
+       hash_types = vnic->hash_type;
+       *rss_conf = 0;
+       if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4)
+               *rss_conf |= RTE_ETH_RSS_IPV4;
+       if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4)
+               *rss_conf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP;
+       if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4)
+               *rss_conf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP;
+       if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6)
+               *rss_conf |= RTE_ETH_RSS_IPV6;
+       if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6)
+               *rss_conf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP;
+       if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6)
+               *rss_conf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP;
+       if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV6 ||
+           hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV4)
+               *rss_conf |= RTE_ETH_RSS_AH;
+       if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV6 ||
+           hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV4)
+               *rss_conf |= RTE_ETH_RSS_ESP;
+}
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index 7a6a0aa739..d01c9ebdb4 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -31,6 +31,11 @@
         (BNXT_VF(bp) && BNXT_VF_IS_TRUSTED(bp) &&                              
\
          !((bp)->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS_TRUSTED_VF)) ||      
\
         (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)))
+#define BNXT_IS_HASH_FUNC_DEFAULT(f)   ((f) != RTE_ETH_HASH_FUNCTION_DEFAULT)
+#define BNXT_IS_HASH_FUNC_TOEPLITZ(f)  ((f) != RTE_ETH_HASH_FUNCTION_TOEPLITZ)
+#define BNXT_IS_HASH_FUNC_SIMPLE_XOR(b, f)     \
+       ((b)->vnic_cap_flags & BNXT_VNIC_CAP_XOR_MODE && \
+        ((f) != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR))
 
 struct bnxt_vnic_info {
        STAILQ_ENTRY(bnxt_vnic_info)    next;
@@ -73,6 +78,7 @@ struct bnxt_vnic_info {
 
        STAILQ_HEAD(, bnxt_filter_info) filter;
        STAILQ_HEAD(, rte_flow) flow_list;
+       uint8_t         ring_select_mode;
 };
 
 struct bnxt_vnic_queue_db {
@@ -83,6 +89,7 @@ struct bnxt_vnic_queue_db {
 
 /* RSS structure to pass values as an structure argument*/
 struct bnxt_vnic_rss_info {
+       uint32_t rss_func;
        uint32_t rss_level;
        uint64_t rss_types;
        uint32_t key_len; /**< Hash key length in bytes. */
@@ -102,7 +109,7 @@ void bnxt_free_vnic_mem(struct bnxt *bp);
 int bnxt_alloc_vnic_mem(struct bnxt *bp);
 int bnxt_vnic_grp_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 void bnxt_prandom_bytes(void *dest_ptr, size_t len);
-uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type);
+uint32_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type);
 int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t hash_f, uint32_t 
lvl);
 uint64_t bnxt_hwrm_to_rte_rss_level(struct bnxt *bp, uint32_t mode);
 
@@ -139,5 +146,12 @@ struct bnxt_vnic_info *
 bnxt_vnic_queue_id_get_next(struct bnxt *bp, uint16_t queue_id,
                            uint16_t *vnic_idx);
 void bnxt_vnic_tpa_cfg(struct bnxt *bp, uint16_t queue_id, bool flag);
-
+uint8_t _bnxt_rte_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f);
+int bnxt_rte_flow_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f,
+                                          uint64_t types, struct bnxt *bp,
+                                          struct bnxt_vnic_info *vnic);
+int bnxt_rte_eth_to_hwrm_ring_select_mode(struct bnxt *bp, uint64_t types,
+                                         struct bnxt_vnic_info *vnic);
+void bnxt_hwrm_rss_to_rte_hash_conf(struct bnxt_vnic_info *vnic,
+                                   uint64_t *rss_conf);
 #endif
-- 
2.39.2 (Apple Git-143)

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to