net/i40e: fix VF runtime queues RSS config
authorXiao Zhang <xiao.zhang@intel.com>
Tue, 13 Aug 2019 22:17:45 +0000 (06:17 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 26 Aug 2019 10:43:23 +0000 (12:43 +0200)
I40evf queue can not work properly with kernel pf driver for X722 vf.
Eg. when configure 8 queues pair, only 4 queues can receive packets,
and half packets will be lost if using 2 queues pair.

This issue is caused by misconfiguration of look up table, the original
code of LUT configuration did not work for X722 vf, use aq command to
setup the LUT to make it work properly.

Fixes: cea7a51c1750 ("i40evf: support RSS")
Cc: stable@dpdk.org
Acked-by: Beilei Xing <beilei.xing@intel.com>
Signed-off-by: Xiao Zhang <xiao.zhang@intel.com>
drivers/net/i40e/i40e_ethdev_vf.c

index 308fb98..c77b30c 100644 (file)
@@ -2598,7 +2598,10 @@ i40evf_config_rss(struct i40e_vf *vf)
        struct i40e_hw *hw = I40E_VF_TO_HW(vf);
        struct rte_eth_rss_conf rss_conf;
        uint32_t i, j, lut = 0, nb_q = (I40E_VFQF_HLUT_MAX_INDEX + 1) * 4;
+       uint32_t rss_lut_size = (I40E_VFQF_HLUT1_MAX_INDEX + 1) * 4;
        uint16_t num;
+       uint8_t *lut_info;
+       int ret;
 
        if (vf->dev_data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_RSS) {
                i40evf_disable_rss(vf);
@@ -2608,12 +2611,29 @@ i40evf_config_rss(struct i40e_vf *vf)
 
        num = RTE_MIN(vf->dev_data->nb_rx_queues, I40E_MAX_QP_NUM_PER_VF);
        /* Fill out the look up table */
-       for (i = 0, j = 0; i < nb_q; i++, j++) {
-               if (j >= num)
-                       j = 0;
-               lut = (lut << 8) | j;
-               if ((i & 3) == 3)
-                       I40E_WRITE_REG(hw, I40E_VFQF_HLUT(i >> 2), lut);
+       if (!(vf->flags & I40E_FLAG_RSS_AQ_CAPABLE)) {
+               for (i = 0, j = 0; i < nb_q; i++, j++) {
+                       if (j >= num)
+                               j = 0;
+                       lut = (lut << 8) | j;
+                       if ((i & 3) == 3)
+                               I40E_WRITE_REG(hw, I40E_VFQF_HLUT(i >> 2), lut);
+               }
+       } else {
+               lut_info = rte_zmalloc("i40e_rss_lut", rss_lut_size, 0);
+               if (!lut_info) {
+                       PMD_DRV_LOG(ERR, "No memory can be allocated");
+                       return -ENOMEM;
+               }
+
+               for (i = 0; i < rss_lut_size; i++)
+                       lut_info[i] = i % vf->num_queue_pairs;
+
+               ret = i40evf_set_rss_lut(&vf->vsi, lut_info,
+                                        rss_lut_size);
+               rte_free(lut_info);
+               if (ret)
+                       return ret;
        }
 
        rss_conf = vf->dev_data->dev_conf.rx_adv_conf.rss_conf;