From patchwork Mon Mar 21 06:18:45 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingjing Wu X-Patchwork-Id: 11614 X-Patchwork-Delegate: bruce.richardson@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 4EA28377E; Mon, 21 Mar 2016 07:19:11 +0100 (CET) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id B93202C6C for ; Mon, 21 Mar 2016 07:19:05 +0100 (CET) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP; 20 Mar 2016 23:19:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,370,1455004800"; d="scan'208";a="928365468" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga001.fm.intel.com with ESMTP; 20 Mar 2016 23:19:03 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id u2L6J2Gj026989; Mon, 21 Mar 2016 14:19:02 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id u2L6IwgU012001; Mon, 21 Mar 2016 14:19:00 +0800 Received: (from wujingji@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id u2L6Iwxa011997; Mon, 21 Mar 2016 14:18:58 +0800 From: Jingjing Wu To: dev@dpdk.org Cc: jingjing.wu@intel.com, helin.zhang@intel.com Date: Mon, 21 Mar 2016 14:18:45 +0800 Message-Id: <1458541132-11953-3-git-send-email-jingjing.wu@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1458541132-11953-1-git-send-email-jingjing.wu@intel.com> References: <1457580346-18550-1-git-send-email-jingjing.wu@intel.com> <1458541132-11953-1-git-send-email-jingjing.wu@intel.com> Subject: [dpdk-dev] [PATCH v5 2/9] i40e: split function for hash and fdir input X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch split function for input set changing of hash and fdir to avoid multiple check on different situation. Signed-off-by: Jingjing Wu Acked-by: Helin Zhang --- drivers/net/i40e/i40e_ethdev.c | 235 +++++++++++++++++------------------------ drivers/net/i40e/i40e_ethdev.h | 11 +- drivers/net/i40e/i40e_fdir.c | 5 +- 3 files changed, 107 insertions(+), 144 deletions(-) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 10e0d38..faceb8b 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -7056,25 +7056,6 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem) return idx; } -static uint64_t -i40e_get_reg_inset(struct i40e_hw *hw, enum rte_filter_type filter, - enum i40e_filter_pctype pctype) -{ - uint64_t reg = 0; - - if (filter == RTE_ETH_FILTER_HASH) { - reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype)); - reg <<= I40E_32_BIT_WIDTH; - reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype)); - } else if (filter == RTE_ETH_FILTER_FDIR) { - reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1)); - reg <<= I40E_32_BIT_WIDTH; - reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0)); - } - - return reg; -} - static void i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val) { @@ -7087,105 +7068,96 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val) (uint32_t)i40e_read_rx_ctl(hw, addr)); } -static int -i40e_set_hash_inset_mask(struct i40e_hw *hw, - enum i40e_filter_pctype pctype, - enum rte_filter_input_set_op op, - uint32_t *mask_reg, - uint8_t num) +int +i40e_hash_filter_inset_select(struct i40e_hw *hw, + struct rte_eth_input_set_conf *conf) { - uint32_t reg; - uint8_t i; + struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf; + enum i40e_filter_pctype pctype; + uint64_t input_set, inset_reg = 0; + uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0}; + int ret, i, num; - if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT) + if (!conf) { + PMD_DRV_LOG(ERR, "Invalid pointer"); + return -EFAULT; + } + if (conf->op != RTE_ETH_INPUT_SET_SELECT && + conf->op != RTE_ETH_INPUT_SET_ADD) { + PMD_DRV_LOG(ERR, "Unsupported input set operation"); return -EINVAL; - - if (op == RTE_ETH_INPUT_SET_SELECT) { - for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) { - i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype), - 0); - if (i >= num) - continue; - i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype), - mask_reg[i]); - } - } else if (op == RTE_ETH_INPUT_SET_ADD) { - uint8_t j, count = 0; - - for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) { - reg = i40e_read_rx_ctl(hw, - I40E_GLQF_HASH_MSK(i, pctype)); - if (reg & I40E_GLQF_HASH_MSK_MASK_MASK) - count++; - } - if (count + num > I40E_INSET_MASK_NUM_REG) - return -EINVAL; - - for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++) - i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype), - mask_reg[j]); } - return 0; -} - -static int -i40e_set_fd_inset_mask(struct i40e_hw *hw, - enum i40e_filter_pctype pctype, - enum rte_filter_input_set_op op, - uint32_t *mask_reg, - uint8_t num) -{ - uint32_t reg; - uint8_t i; + pctype = i40e_flowtype_to_pctype(conf->flow_type); + if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) { + PMD_DRV_LOG(ERR, "Not supported flow type (%u)", + conf->flow_type); + return -EINVAL; + } - if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT) + ret = i40e_parse_input_set(&input_set, pctype, conf->field, + conf->inset_size); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to parse input set"); + return -EINVAL; + } + if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH, + input_set) != 0) { + PMD_DRV_LOG(ERR, "Invalid input set"); + return -EINVAL; + } + if (conf->op == RTE_ETH_INPUT_SET_ADD) { + /* get inset value in register */ + inset_reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype)); + inset_reg <<= I40E_32_BIT_WIDTH; + inset_reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype)); + input_set |= pf->hash_input_set[pctype]; + } + num = i40e_generate_inset_mask_reg(input_set, mask_reg, + I40E_INSET_MASK_NUM_REG); + if (num < 0) return -EINVAL; - if (op == RTE_ETH_INPUT_SET_SELECT) { - for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) { - i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype), - 0); - if (i >= num) - continue; - i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype), - mask_reg[i]); - } - } else if (op == RTE_ETH_INPUT_SET_ADD) { - uint8_t j, count = 0; - - for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) { - reg = i40e_read_rx_ctl(hw, - I40E_GLQF_FD_MSK(i, pctype)); - if (reg & I40E_GLQF_FD_MSK_MASK_MASK) - count++; - } - if (count + num > I40E_INSET_MASK_NUM_REG) - return -EINVAL; + inset_reg |= i40e_translate_input_set_reg(input_set); - for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++) - i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype), - mask_reg[j]); - } + i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype), + (uint32_t)(inset_reg & UINT32_MAX)); + i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype), + (uint32_t)((inset_reg >> + I40E_32_BIT_WIDTH) & UINT32_MAX)); + + for (i = 0; i < num; i++) + i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype), + mask_reg[i]); + /*clear unused mask registers of the pctype */ + for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) + i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype), + 0); + I40E_WRITE_FLUSH(hw); + pf->hash_input_set[pctype] = input_set; return 0; } int -i40e_filter_inset_select(struct i40e_hw *hw, - struct rte_eth_input_set_conf *conf, - enum rte_filter_type filter) +i40e_fdir_filter_inset_select(struct i40e_pf *pf, + struct rte_eth_input_set_conf *conf) { + struct i40e_hw *hw = I40E_PF_TO_HW(pf); enum i40e_filter_pctype pctype; - uint64_t inset_reg = 0, input_set; - uint32_t mask_reg[I40E_INSET_MASK_NUM_REG]; - uint8_t num; - int ret; + uint64_t input_set, inset_reg = 0; + uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0}; + int ret, i, num; if (!hw || !conf) { PMD_DRV_LOG(ERR, "Invalid pointer"); return -EFAULT; } + if (conf->op != RTE_ETH_INPUT_SET_SELECT && + conf->op != RTE_ETH_INPUT_SET_ADD) { + PMD_DRV_LOG(ERR, "Unsupported input set operation"); + return -EINVAL; + } pctype = i40e_flowtype_to_pctype(conf->flow_type); if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) { @@ -7193,60 +7165,48 @@ i40e_filter_inset_select(struct i40e_hw *hw, conf->flow_type); return -EINVAL; } - if (filter != RTE_ETH_FILTER_HASH && filter != RTE_ETH_FILTER_FDIR) { - PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter); - return -EINVAL; - } - ret = i40e_parse_input_set(&input_set, pctype, conf->field, conf->inset_size); if (ret) { PMD_DRV_LOG(ERR, "Failed to parse input set"); return -EINVAL; } - if (i40e_validate_input_set(pctype, filter, input_set) != 0) { + if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR, + input_set) != 0) { PMD_DRV_LOG(ERR, "Invalid input set"); return -EINVAL; } - if (conf->op == RTE_ETH_INPUT_SET_ADD) { - inset_reg |= i40e_get_reg_inset(hw, filter, pctype); - } else if (conf->op != RTE_ETH_INPUT_SET_SELECT) { - PMD_DRV_LOG(ERR, "Unsupported input set operation"); - return -EINVAL; - } + /* get inset value in register */ + inset_reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1)); + inset_reg <<= I40E_32_BIT_WIDTH; + inset_reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0)); + + if (conf->op == RTE_ETH_INPUT_SET_ADD) + input_set |= pf->fdir.input_set[pctype]; num = i40e_generate_inset_mask_reg(input_set, mask_reg, I40E_INSET_MASK_NUM_REG); - inset_reg |= i40e_translate_input_set_reg(input_set); - - if (filter == RTE_ETH_FILTER_HASH) { - ret = i40e_set_hash_inset_mask(hw, pctype, conf->op, mask_reg, - num); - if (ret) - return -EINVAL; + if (num < 0) + return -EINVAL; - i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype), - (uint32_t)(inset_reg & UINT32_MAX)); - i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype), - (uint32_t)((inset_reg >> - I40E_32_BIT_WIDTH) & UINT32_MAX)); - } else if (filter == RTE_ETH_FILTER_FDIR) { - ret = i40e_set_fd_inset_mask(hw, pctype, conf->op, mask_reg, - num); - if (ret) - return -EINVAL; + inset_reg |= i40e_translate_input_set_reg(input_set); - i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0), - (uint32_t)(inset_reg & UINT32_MAX)); - i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1), - (uint32_t)((inset_reg >> - I40E_32_BIT_WIDTH) & UINT32_MAX)); - } else { - PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter); - return -EINVAL; - } + i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0), + (uint32_t)(inset_reg & UINT32_MAX)); + i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1), + (uint32_t)((inset_reg >> + I40E_32_BIT_WIDTH) & UINT32_MAX)); + + for (i = 0; i < num; i++) + i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype), + mask_reg[i]); + /*clear unused mask registers of the pctype */ + for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) + i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype), + 0); I40E_WRITE_FLUSH(hw); + pf->fdir.input_set[pctype] = input_set; return 0; } @@ -7298,9 +7258,8 @@ i40e_hash_filter_set(struct i40e_hw *hw, struct rte_eth_hash_filter_info *info) &(info->info.global_conf)); break; case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT: - ret = i40e_filter_inset_select(hw, - &(info->info.input_set_conf), - RTE_ETH_FILTER_HASH); + ret = i40e_hash_filter_inset_select(hw, + &(info->info.input_set_conf)); break; default: diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index 1c75672..1d49835 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -367,6 +367,8 @@ struct i40e_fdir_info { struct i40e_rx_queue *rxq; void *prg_pkt; /* memory for fdir program packet */ uint64_t dma_addr; /* physic address of packet memory*/ + /* input set bits for each pctype */ + uint64_t input_set[I40E_FILTER_PCTYPE_MAX]; /* * the rule how bytes stream is extracted as flexible payload * for each payload layer, the setting can up to three elements @@ -433,6 +435,8 @@ struct i40e_pf { uint16_t fdir_qp_offset; uint16_t hash_lut_size; /* The size of hash lookup table */ + /* input set bits for each pctype */ + uint64_t hash_input_set[I40E_FILTER_PCTYPE_MAX]; /* store VXLAN UDP ports */ uint16_t vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; uint16_t vxlan_bitmap; /* Vxlan bit mask */ @@ -576,9 +580,10 @@ int i40e_fdir_ctrl_func(struct rte_eth_dev *dev, int i40e_select_filter_input_set(struct i40e_hw *hw, struct rte_eth_input_set_conf *conf, enum rte_filter_type filter); -int i40e_filter_inset_select(struct i40e_hw *hw, - struct rte_eth_input_set_conf *conf, - enum rte_filter_type filter); +int i40e_hash_filter_inset_select(struct i40e_hw *hw, + struct rte_eth_input_set_conf *conf); +int i40e_fdir_filter_inset_select(struct i40e_pf *pf, + struct rte_eth_input_set_conf *conf); void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, struct rte_eth_rxq_info *qinfo); diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c index 14c51ce..f8055e7 100644 --- a/drivers/net/i40e/i40e_fdir.c +++ b/drivers/net/i40e/i40e_fdir.c @@ -1362,7 +1362,6 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev, struct rte_eth_fdir_filter_info *info) { struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); - struct i40e_hw *hw = I40E_PF_TO_HW(pf); int ret = 0; if (!info) { @@ -1372,8 +1371,8 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev, switch (info->info_type) { case RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT: - ret = i40e_filter_inset_select(hw, - &(info->info.input_set_conf), RTE_ETH_FILTER_FDIR); + ret = i40e_fdir_filter_inset_select(pf, + &(info->info.input_set_conf)); break; default: PMD_DRV_LOG(ERR, "FD filter info type (%d) not supported",