[v5,23/31] net/ice: support RSS

Message ID 1545032259-77179-24-git-send-email-wenzhuo.lu@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Qi Zhang
Headers
Series A new net PMD - ICE |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Wenzhuo Lu Dec. 17, 2018, 7:37 a.m. UTC
  Add below ops,
reta_update
reta_query
rss_hash_update
rss_hash_conf_get

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Signed-off-by: Qiming Yang <qiming.yang@intel.com>
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/nics/features/ice.ini |   3 +
 drivers/net/ice/ice_ethdev.c     | 242 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 245 insertions(+)
  

Comments

Ferruh Yigit Dec. 17, 2018, 10:47 p.m. UTC | #1
On 12/17/2018 7:37 AM, Wenzhuo Lu wrote:
> Add below ops,
> reta_update
> reta_query
> rss_hash_update
> rss_hash_conf_get
> 
> Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
> Signed-off-by: Qiming Yang <qiming.yang@intel.com>
> Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
> Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> ---
>  doc/guides/nics/features/ice.ini |   3 +
>  drivers/net/ice/ice_ethdev.c     | 242 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 245 insertions(+)
> 
> diff --git a/doc/guides/nics/features/ice.ini b/doc/guides/nics/features/ice.ini
> index 5ac8e56..953a869 100644
> --- a/doc/guides/nics/features/ice.ini
> +++ b/doc/guides/nics/features/ice.ini
> @@ -12,6 +12,9 @@ MTU update           = Y
>  Jumbo frame          = Y
>  Unicast MAC filter   = Y
>  Multicast MAC filter = Y
> +RSS hash             = Y
> +RSS key update       = Y
> +RSS reta update      = Y

Similar comment here, to claim RSS support data path also needs to be updated,
to set proper mbuf fields.

Perhaps it can be simpler to move RSS and VLAN patches after basic Rx/Tx support
patch and update data path for those features added, what do you think?
  

Patch

diff --git a/doc/guides/nics/features/ice.ini b/doc/guides/nics/features/ice.ini
index 5ac8e56..953a869 100644
--- a/doc/guides/nics/features/ice.ini
+++ b/doc/guides/nics/features/ice.ini
@@ -12,6 +12,9 @@  MTU update           = Y
 Jumbo frame          = Y
 Unicast MAC filter   = Y
 Multicast MAC filter = Y
+RSS hash             = Y
+RSS key update       = Y
+RSS reta update      = Y
 VLAN filter          = Y
 VLAN offload         = Y
 QinQ offload         = Y
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 1d3cc7a..28d0282 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -28,6 +28,16 @@  static int ice_link_update(struct rte_eth_dev *dev,
 static int ice_vlan_tpid_set(struct rte_eth_dev *dev,
 			     enum rte_vlan_type vlan_type,
 			     uint16_t tpid);
+static int ice_rss_reta_update(struct rte_eth_dev *dev,
+			       struct rte_eth_rss_reta_entry64 *reta_conf,
+			       uint16_t reta_size);
+static int ice_rss_reta_query(struct rte_eth_dev *dev,
+			      struct rte_eth_rss_reta_entry64 *reta_conf,
+			      uint16_t reta_size);
+static int ice_rss_hash_update(struct rte_eth_dev *dev,
+			       struct rte_eth_rss_conf *rss_conf);
+static int ice_rss_hash_conf_get(struct rte_eth_dev *dev,
+				 struct rte_eth_rss_conf *rss_conf);
 static int ice_vlan_filter_set(struct rte_eth_dev *dev,
 			       uint16_t vlan_id,
 			       int on);
@@ -72,6 +82,10 @@  static int ice_vlan_pvid_set(struct rte_eth_dev *dev,
 	.vlan_filter_set              = ice_vlan_filter_set,
 	.vlan_offload_set             = ice_vlan_offload_set,
 	.vlan_tpid_set                = ice_vlan_tpid_set,
+	.reta_update                  = ice_rss_reta_update,
+	.reta_query                   = ice_rss_reta_query,
+	.rss_hash_update              = ice_rss_hash_update,
+	.rss_hash_conf_get            = ice_rss_hash_conf_get,
 	.vlan_pvid_set                = ice_vlan_pvid_set,
 };
 
@@ -2006,6 +2020,234 @@  static int ice_macaddr_set(struct rte_eth_dev *dev,
 }
 
 static int
+ice_get_rss_lut(struct ice_vsi *vsi, uint8_t *lut, uint16_t lut_size)
+{
+	struct ice_pf *pf = ICE_VSI_TO_PF(vsi);
+	struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
+	int ret;
+
+	if (!lut)
+		return -EINVAL;
+
+	if (pf->flags & ICE_FLAG_RSS_AQ_CAPABLE) {
+		ret = ice_aq_get_rss_lut(hw, vsi->idx, TRUE,
+					 lut, lut_size);
+		if (ret) {
+			PMD_DRV_LOG(ERR, "Failed to get RSS lookup table");
+			return -EINVAL;
+		}
+	} else {
+		uint64_t *lut_dw = (uint64_t *)lut;
+		uint16_t i, lut_size_dw = lut_size / 4;
+
+		for (i = 0; i < lut_size_dw; i++)
+			lut_dw[i] = ICE_READ_REG(hw, PFQF_HLUT(i));
+	}
+
+	return 0;
+}
+
+static int
+ice_set_rss_lut(struct ice_vsi *vsi, uint8_t *lut, uint16_t lut_size)
+{
+	struct ice_pf *pf = ICE_VSI_TO_PF(vsi);
+	struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
+	int ret;
+
+	if (!vsi || !lut)
+		return -EINVAL;
+
+	if (pf->flags & ICE_FLAG_RSS_AQ_CAPABLE) {
+		ret = ice_aq_set_rss_lut(hw, vsi->idx, TRUE,
+					 lut, lut_size);
+		if (ret) {
+			PMD_DRV_LOG(ERR, "Failed to set RSS lookup table");
+			return -EINVAL;
+		}
+	} else {
+		uint64_t *lut_dw = (uint64_t *)lut;
+		uint16_t i, lut_size_dw = lut_size / 4;
+
+		for (i = 0; i < lut_size_dw; i++)
+			ICE_WRITE_REG(hw, PFQF_HLUT(i), lut_dw[i]);
+
+		ice_flush(hw);
+	}
+
+	return 0;
+}
+
+static int
+ice_rss_reta_update(struct rte_eth_dev *dev,
+		    struct rte_eth_rss_reta_entry64 *reta_conf,
+		    uint16_t reta_size)
+{
+	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint16_t i, lut_size = hw->func_caps.common_cap.rss_table_size;
+	uint16_t idx, shift;
+	uint8_t *lut;
+	int ret;
+
+	if (reta_size != lut_size ||
+	    reta_size > ETH_RSS_RETA_SIZE_512) {
+		PMD_DRV_LOG(ERR,
+			    "The size of hash lookup table configured (%d)"
+			    "doesn't match the number hardware can "
+			    "supported (%d)",
+			    reta_size, lut_size);
+		return -EINVAL;
+	}
+
+	lut = rte_zmalloc(NULL, reta_size, 0);
+	if (!lut) {
+		PMD_DRV_LOG(ERR, "No memory can be allocated");
+		return -ENOMEM;
+	}
+	ret = ice_get_rss_lut(pf->main_vsi, lut, reta_size);
+	if (ret)
+		goto out;
+
+	for (i = 0; i < reta_size; i++) {
+		idx = i / RTE_RETA_GROUP_SIZE;
+		shift = i % RTE_RETA_GROUP_SIZE;
+		if (reta_conf[idx].mask & (1ULL << shift))
+			lut[i] = reta_conf[idx].reta[shift];
+	}
+	ret = ice_set_rss_lut(pf->main_vsi, lut, reta_size);
+
+out:
+	rte_free(lut);
+
+	return ret;
+}
+
+static int
+ice_rss_reta_query(struct rte_eth_dev *dev,
+		   struct rte_eth_rss_reta_entry64 *reta_conf,
+		   uint16_t reta_size)
+{
+	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint16_t i, lut_size = hw->func_caps.common_cap.rss_table_size;
+	uint16_t idx, shift;
+	uint8_t *lut;
+	int ret;
+
+	if (reta_size != lut_size ||
+	    reta_size > ETH_RSS_RETA_SIZE_512) {
+		PMD_DRV_LOG(ERR,
+			    "The size of hash lookup table configured (%d)"
+			    "doesn't match the number hardware can "
+			    "supported (%d)",
+			    reta_size, lut_size);
+		return -EINVAL;
+	}
+
+	lut = rte_zmalloc(NULL, reta_size, 0);
+	if (!lut) {
+		PMD_DRV_LOG(ERR, "No memory can be allocated");
+		return -ENOMEM;
+	}
+
+	ret = ice_get_rss_lut(pf->main_vsi, lut, reta_size);
+	if (ret)
+		goto out;
+
+	for (i = 0; i < reta_size; i++) {
+		idx = i / RTE_RETA_GROUP_SIZE;
+		shift = i % RTE_RETA_GROUP_SIZE;
+		if (reta_conf[idx].mask & (1ULL << shift))
+			reta_conf[idx].reta[shift] = lut[i];
+	}
+
+out:
+	rte_free(lut);
+
+	return ret;
+}
+
+static int
+ice_set_rss_key(struct ice_vsi *vsi, uint8_t *key, uint8_t key_len)
+{
+	struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
+	int ret = 0;
+
+	if (!key || key_len == 0) {
+		PMD_DRV_LOG(DEBUG, "No key to be configured");
+		return 0;
+	} else if (key_len != (VSIQF_HKEY_MAX_INDEX + 1) *
+		   sizeof(uint32_t)) {
+		PMD_DRV_LOG(ERR, "Invalid key length %u", key_len);
+		return -EINVAL;
+	}
+
+	struct ice_aqc_get_set_rss_keys *key_dw =
+		(struct ice_aqc_get_set_rss_keys *)key;
+
+	ret = ice_aq_set_rss_key(hw, vsi->idx, key_dw);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to configure RSS key via AQ");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int
+ice_get_rss_key(struct ice_vsi *vsi, uint8_t *key, uint8_t *key_len)
+{
+	struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
+	int ret;
+
+	if (!key || !key_len)
+		return -EINVAL;
+
+	ret = ice_aq_get_rss_key
+		(hw, vsi->idx,
+		 (struct ice_aqc_get_set_rss_keys *)key);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to get RSS key via AQ");
+		return -EINVAL;
+	}
+	*key_len = (VSIQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t);
+
+	return 0;
+}
+
+static int
+ice_rss_hash_update(struct rte_eth_dev *dev,
+		    struct rte_eth_rss_conf *rss_conf)
+{
+	enum ice_status status = ICE_SUCCESS;
+	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct ice_vsi *vsi = pf->main_vsi;
+
+	/* set hash key */
+	status = ice_set_rss_key(vsi, rss_conf->rss_key, rss_conf->rss_key_len);
+	if (status)
+		return status;
+
+	/* TODO: hash enable config, ice_add_rss_cfg */
+	return 0;
+}
+
+static int
+ice_rss_hash_conf_get(struct rte_eth_dev *dev,
+		      struct rte_eth_rss_conf *rss_conf)
+{
+	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct ice_vsi *vsi = pf->main_vsi;
+
+	ice_get_rss_key(vsi, rss_conf->rss_key,
+			&rss_conf->rss_key_len);
+
+	/* TODO: default set to 0 as hf config is not supported now */
+	rss_conf->rss_hf = 0;
+	return 0;
+}
+
+static int
 ice_vsi_vlan_pvid_set(struct ice_vsi *vsi, struct ice_vsi_vlan_pvid_info *info)
 {
 	struct ice_hw *hw;