Fix the reta update function to only update table entries that are
selected by the update mask. Translate queue number to firmware
group ID when updating an entry.

Fixes: d819382543f3 ("net/bnxt: add RSS redirection table operations")
Signed-off-by: Lance Richardson <lance.richard...@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khapa...@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 39 ++++++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 2d892cd4f..d2b89a217 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -977,6 +977,15 @@ static void bnxt_allmulticast_disable_op(struct 
rte_eth_dev *eth_dev)
        bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
+/* Return bnxt_rx_queue pointer corresponding to a given rxq. */
+static struct bnxt_rx_queue *bnxt_qid_to_rxq(struct bnxt *bp, uint16_t qid)
+{
+       if (qid >= bp->rx_nr_rings)
+               return NULL;
+
+       return bp->eth_dev->data->rx_queues[qid];
+}
+
 static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,
                            struct rte_eth_rss_reta_entry64 *reta_conf,
                            uint16_t reta_size)
@@ -984,24 +993,42 @@ static int bnxt_reta_update_op(struct rte_eth_dev 
*eth_dev,
        struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
        struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
        struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+       uint16_t tbl_size = HW_HASH_INDEX_SIZE;
+       uint16_t idx, sft;
+       int i;
 
-       /* Update the default RSS VNIC */
-       if (!vnic)
-               return -EINVAL;
        if (!vnic->rss_table)
                return -EINVAL;
 
        if (!(dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG))
                return -EINVAL;
 
-       if (reta_size != HW_HASH_INDEX_SIZE) {
+       if (reta_size != tbl_size) {
                PMD_DRV_LOG(ERR, "The configured hash table lookup size "
                        "(%d) must equal the size supported by the hardware "
-                       "(%d)\n", reta_size, HW_HASH_INDEX_SIZE);
+                       "(%d)\n", reta_size, tbl_size);
                return -EINVAL;
        }
 
-       memcpy(vnic->rss_table, reta_conf, reta_size);
+       for (i = 0; i < reta_size; i++) {
+               struct bnxt_rx_queue *rxq;
+
+               idx = i / RTE_RETA_GROUP_SIZE;
+               sft = i % RTE_RETA_GROUP_SIZE;
+
+               if (!(reta_conf[idx].mask & (1ULL << sft)))
+                       continue;
+
+               rxq = bnxt_qid_to_rxq(bp, reta_conf[idx].reta[sft]);
+               if (!rxq) {
+                       PMD_DRV_LOG(ERR, "Invalid ring in reta_conf.\n");
+                       return -EINVAL;
+               }
+
+               vnic->rss_table[i] =
+                   vnic->fw_grp_ids[reta_conf[idx].reta[sft]];
+       }
+
        bnxt_hwrm_vnic_rss_cfg(bp, vnic);
        return 0;
 }
-- 
2.17.1

Reply via email to