From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by dpdk.org (Postfix) with ESMTP id F2D041B4E9 for ; Fri, 23 Nov 2018 07:51:57 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Nov 2018 22:51:57 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,268,1539673200"; d="scan'208";a="283483478" Received: from dpdk26.sh.intel.com ([10.67.110.161]) by fmsmga006.fm.intel.com with ESMTP; 22 Nov 2018 22:51:56 -0800 From: Wenzhuo Lu To: dev@dpdk.org Cc: Wenzhuo Lu , Qiming Yang , Xiaoyun Li , Jingjing Wu Date: Fri, 23 Nov 2018 14:56:10 +0800 Message-Id: <1542956179-80951-11-git-send-email-wenzhuo.lu@intel.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1542956179-80951-1-git-send-email-wenzhuo.lu@intel.com> References: <1542956179-80951-1-git-send-email-wenzhuo.lu@intel.com> Subject: [dpdk-dev] [PATCH 10/19] net/ice: support RSS X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Nov 2018 06:51:58 -0000 Add below ops, reta_update reta_query rss_hash_update rss_hash_conf_get Signed-off-by: Wenzhuo Lu Signed-off-by: Qiming Yang Signed-off-by: Xiaoyun Li Signed-off-by: Jingjing Wu --- drivers/net/ice/ice_ethdev.c | 248 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index c6267fa..31c77e4 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, }; @@ -2073,6 +2087,240 @@ 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->vsi_id, 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->vsi_id, 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 (rte_eal_process_type() == RTE_PROC_SECONDARY) + return -E_RTE_SECONDARY; + + 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("ice_rss_lut", 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 (rte_eal_process_type() == RTE_PROC_SECONDARY) + return -E_RTE_SECONDARY; + + 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("ice_rss_lut", 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->vsi_id, 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->vsi_id, + (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; -- 1.9.3