From: Jingjing Wu Date: Wed, 23 Mar 2016 13:07:05 +0000 (+0800) Subject: i40e: split function for hash and flow director input X-Git-Tag: spdx-start~7187 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=f2b2e2354bbd;p=dpdk.git i40e: split function for hash and flow director input For the input set selection, Hash filter and Flow director shared the same function, i.e. i40e_filter_inset_select. For code readability, this patch replaces i40e_filter_inset_select with two new functions: i40e_hash_filter_inset_select and i40e_fdir_filter_inset_select for Hash filter and Flow director respectively. Signed-off-by: Jingjing Wu Acked-by: Helin Zhang --- diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index e91e9660a9..45f35dcd58 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 b641882e4f..ce945fef61 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 */ @@ -578,9 +582,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 14c51ce196..f8055e75a2 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",