[dpdk-dev,04/24] net/i40e: store RSS hash info

Message ID 1480679625-4157-5-git-send-email-beilei.xing@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers

Checks

Context Check Description
checkpatch/checkpatch warning coding style issues

Commit Message

Xing, Beilei Dec. 2, 2016, 11:53 a.m. UTC
  Add support of storing lookup table and RSS
configuration in SW.

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

Patch

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 */