This patch adds support to configure RSS hash level in the hardware,
if the firmware advertises such a capability.

Signed-off-by: Ajit Khaparde <ajit.khapa...@broadcom.com>
---
 drivers/net/bnxt/bnxt.h        |  1 +
 drivers/net/bnxt/bnxt_ethdev.c |  7 ++++
 drivers/net/bnxt/bnxt_hwrm.c   |  9 +++-
 drivers/net/bnxt/bnxt_rxq.c    |  3 ++
 drivers/net/bnxt/bnxt_vnic.c   | 75 ++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_vnic.h   |  4 ++
 6 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index e259c8239..d796ac539 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -536,6 +536,7 @@ struct bnxt {
 
        uint32_t                vnic_cap_flags;
 #define BNXT_VNIC_CAP_COS_CLASSIFY     BIT(0)
+#define BNXT_VNIC_CAP_OUTER_RSS                BIT(1)
        unsigned int            rx_nr_rings;
        unsigned int            rx_cp_nr_rings;
        unsigned int            rx_num_qs_per_vnic;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index c70b072bf..a12aecc26 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -524,6 +524,8 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
        dev_info->rx_offload_capa = BNXT_DEV_RX_OFFLOAD_SUPPORT;
        if (bp->flags & BNXT_FLAG_PTP_SUPPORTED)
                dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_TIMESTAMP;
+       if (bp->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS)
+               dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_RSS_LEVEL;
        dev_info->tx_offload_capa = BNXT_DEV_TX_OFFLOAD_SUPPORT;
        dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT;
 
@@ -1404,6 +1406,8 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev 
*eth_dev,
        /* Update the default RSS VNIC(s) */
        vnic = BNXT_GET_DEFAULT_VNIC(bp);
        vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_conf->rss_hf);
+       vnic->hash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss_conf->rss_level,
+                                                     rss_conf->rss_hf);
 
        /*
         * If hashkey is not specified, use the previously configured
@@ -1438,6 +1442,9 @@ static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev 
*eth_dev,
 
        /* RSS configuration is the same for all VNICs */
        if (vnic && vnic->rss_hash_key) {
+               rss_conf->rss_level =
+                       bnxt_hwrm_to_rte_rss_level(bp, vnic->hash_mode);
+
                if (rss_conf->rss_key) {
                        len = rss_conf->rss_key_len <= HW_HASH_KEY_SIZE ?
                              rss_conf->rss_key_len : HW_HASH_KEY_SIZE;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index b1f908ee4..aba1ef34b 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -704,6 +704,7 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
 int bnxt_hwrm_vnic_qcaps(struct bnxt *bp)
 {
        int rc = 0;
+       uint32_t flags;
        struct hwrm_vnic_qcaps_input req = {.req_type = 0 };
        struct hwrm_vnic_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
 
@@ -715,12 +716,16 @@ int bnxt_hwrm_vnic_qcaps(struct bnxt *bp)
 
        HWRM_CHECK_RESULT();
 
-       if (rte_le_to_cpu_32(resp->flags) &
-           HWRM_VNIC_QCAPS_OUTPUT_FLAGS_COS_ASSIGNMENT_CAP) {
+       flags = rte_le_to_cpu_32(resp->flags);
+
+       if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_COS_ASSIGNMENT_CAP) {
                bp->vnic_cap_flags |= BNXT_VNIC_CAP_COS_CLASSIFY;
                PMD_DRV_LOG(INFO, "CoS assignment capability enabled\n");
        }
 
+       if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_OUTERMOST_RSS_CAP)
+               bp->vnic_cap_flags |= BNXT_VNIC_CAP_OUTER_RSS;
+
        bp->max_tpa_v2 = rte_le_to_cpu_16(resp->max_aggs_supported);
 
        HWRM_UNLOCK();
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 457ebede0..fabc4663c 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -177,6 +177,9 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
                        vnic = &bp->vnic_info[i];
                        vnic->hash_type =
                                bnxt_rte_to_hwrm_hash_types(rss->rss_hf);
+                       vnic->hash_mode =
+                               bnxt_rte_to_hwrm_hash_level(bp, rss->rss_level,
+                                                           rss->rss_hf);
 
                        /*
                         * Use the supplied key if the key length is
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index 104342e13..8aebb6069 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -261,3 +261,78 @@ uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type)
 
        return hwrm_type;
 }
+
+int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp,
+                               uint32_t rss_level,
+                               uint64_t hash_f)
+{
+       int mode = HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT;
+       bool l3 = !!(hash_f & (ETH_RSS_IPV4 | ETH_RSS_IPV6));
+       bool l4 = !!(hash_f & (ETH_RSS_NONFRAG_IPV4_UDP |
+                              ETH_RSS_NONFRAG_IPV6_UDP |
+                              ETH_RSS_NONFRAG_IPV4_TCP |
+                              ETH_RSS_NONFRAG_IPV6_TCP));
+       bool l3_only = l3 && !l4;
+       bool l3_and_l4 = l3 && l4;
+
+       /* If FW has not advertised capability to configure outer/inner
+        * RSS hashing , just log a message. HW will work in default RSS mode.
+        */
+       if (!(bp->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS)) {
+               PMD_DRV_LOG(ERR, "RSS hash level cannot be configured\n");
+               return mode;
+       }
+
+       switch (rss_level) {
+       case 0:
+               mode = HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT;
+               break;
+       case 1:
+               if (l3_only)
+                       mode =
+                       HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_2;
+               else if (l3_and_l4)
+                       mode =
+                       HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_4;
+               break;
+       case 2:
+               if (l3_only)
+                       mode =
+                       HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_2;
+               else if (l3_and_l4)
+                       mode =
+                       HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_4;
+               break;
+       default:
+               PMD_DRV_LOG(ERR,
+                           "No support for RSS hash level %d. Using default\n",
+                           rss_level);
+               break;
+       }
+
+       return mode;
+}
+
+int bnxt_hwrm_to_rte_rss_level(struct bnxt *bp, uint32_t hash_mode)
+{
+       int rss_level;
+
+       if (hash_mode == HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_2 ||
+           hash_mode == HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_4)
+               rss_level = 1;
+       else if (hash_mode ==
+                HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_2 ||
+                hash_mode ==
+                HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_4)
+               rss_level = 2;
+       else
+               rss_level = 0;
+
+       /* If FW has not advertised capability to configure inner/outer RSS
+        * return default hash mode.
+        */
+       if (!(bp->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS))
+               rss_level = 0;
+
+       return rss_level;
+}
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index a372b899b..48445b026 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -69,4 +69,8 @@ int bnxt_alloc_vnic_mem(struct bnxt *bp);
 int bnxt_vnic_grp_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 void prandom_bytes(void *dest_ptr, size_t len);
 uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type);
+int bnxt_hwrm_to_rte_rss_level(struct bnxt *bp, uint32_t hash_mode);
+int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp,
+                               uint32_t rss_level,
+                               uint64_t hash_f);
 #endif
-- 
2.21.0 (Apple Git-122.2)

Reply via email to