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