Add support of storing lookup table and RSS
configuration in SW.

Signed-off-by: Beilei Xing <beilei.x...@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 39 ++++++++++++++++++++++++++++++++++-----
 drivers/net/i40e/i40e_ethdev.h |  6 ++++++
 2 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index c38536f..521e7bb 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1356,6 +1356,9 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
        if (hw->adapter_stopped == 0)
                i40e_dev_close(dev);
 
+       if (pf->hash.reta)
+               rte_free(pf->hash.reta);
+
        /* Remove all ethertype director rules and hash */
        if (ethertype_info->hash_map)
                rte_free(ethertype_info->hash_map);
@@ -3453,6 +3456,8 @@ i40e_dev_rss_reta_update(struct rte_eth_dev *dev,
        }
        ret = i40e_set_rss_lut(pf->main_vsi, lut, reta_size);
 
+       /* Store updated lut */
+       rte_memcpy(pf->hash.reta, lut, sizeof(*lut) * reta_size);
 out:
        rte_free(lut);
 
@@ -6959,6 +6964,8 @@ i40e_pf_config_rss(struct i40e_pf *pf)
        struct rte_eth_rss_conf rss_conf;
        uint32_t i, lut = 0;
        uint16_t j, num;
+       uint16_t reta_size = hw->func_caps.rss_table_size;
+       int ret = -EINVAL;
 
        /*
         * If both VMDQ and RSS enabled, not all of PF queues are configured.
@@ -6978,7 +6985,7 @@ i40e_pf_config_rss(struct i40e_pf *pf)
                return -ENOTSUP;
        }
 
-       for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) {
+       for (i = 0, j = 0; i < reta_size; i++, j++) {
                if (j == num)
                        j = 0;
                lut = (lut << 8) | (j & ((0x1 <<
@@ -6987,6 +6994,19 @@ i40e_pf_config_rss(struct i40e_pf *pf)
                        I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut);
        }
 
+       /* Store lut into SW */
+       uint8_t *reta;
+
+       reta = rte_zmalloc("i40e_rss_reta", reta_size, 0);
+       if (!reta) {
+               PMD_DRV_LOG(ERR, "No memory can be allocated");
+               return -ENOMEM;
+       }
+       pf->hash.reta = reta;
+       ret = i40e_get_rss_lut(pf->main_vsi, reta, reta_size);
+       if (ret < 0)
+               return ret;
+
        rss_conf = pf->dev_data->dev_conf.rx_adv_conf.rss_conf;
        if ((rss_conf.rss_hf & I40E_RSS_OFFLOAD_ALL) == 0) {
                i40e_pf_disable_rss(pf);
@@ -7005,7 +7025,15 @@ i40e_pf_config_rss(struct i40e_pf *pf)
                                                        sizeof(uint32_t);
        }
 
-       return i40e_hw_rss_hash_set(pf, &rss_conf);
+       ret = i40e_hw_rss_hash_set(pf, &rss_conf);
+       if (ret < 0)
+               return ret;
+
+       /* store rss configuration into SW */
+       ret = i40e_dev_rss_hash_conf_get(
+               I40E_VSI_TO_ETH_DEV(pf->main_vsi), &pf->hash.rss_conf);
+
+       return ret;
 }
 
 static int
@@ -7158,9 +7186,10 @@ i40e_pf_config_mq_rx(struct i40e_pf *pf)
        enum rte_eth_rx_mq_mode mq_mode = pf->dev_data->dev_conf.rxmode.mq_mode;
 
        /* RSS setup */
-       if (mq_mode & ETH_MQ_RX_RSS_FLAG)
-               ret = i40e_pf_config_rss(pf);
-       else
+       if (mq_mode & ETH_MQ_RX_RSS_FLAG) {
+               if (!pf->hash.reta)
+                       ret = i40e_pf_config_rss(pf);
+       } else
                i40e_pf_disable_rss(pf);
 
        return ret;
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index b6eed6a..d40010a 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -466,6 +466,11 @@ struct i40e_tunnel_info {
        struct rte_hash *hash_table;
 };
 
+struct i40e_hash_info {
+       uint8_t *reta;
+       struct rte_eth_rss_conf rss_conf;
+};
+
 #define I40E_MIRROR_MAX_ENTRIES_PER_RULE   64
 #define I40E_MAX_MIRROR_RULES           64
 /*
@@ -538,6 +543,7 @@ struct i40e_pf {
        struct i40e_fdir_info fdir; /* flow director info */
        struct i40e_ethertype_info ethertype; /* Ethertype filter info */
        struct i40e_tunnel_info tunnel; /* Tunnel filter info */
+       struct i40e_hash_info hash; /* Hash filter info */
        struct i40e_fc_conf fc_conf; /* Flow control conf */
        struct i40e_mirror_rule_list mirror_list;
        uint16_t nb_mirror_rule;   /* The number of mirror rules */
-- 
2.5.5

Reply via email to