From 4a072ad434426ebfb5a6120858a971b54e7d2204 Mon Sep 17 00:00:00 2001 From: Murphy Yang Date: Thu, 1 Apr 2021 03:23:32 +0000 Subject: [PATCH] net/i40e: fix flow director config after flow validate The configuration of FDIR input set should not be set during flow validate. It should be set when flow create. Fixes: fe5d0e85b713 ("net/i40e: fix flow director flex configuration") Fixes: 15018d79f0be ("net/i40e: add FDIR support for GTP-C and GTP-U") Cc: stable@dpdk.org Signed-off-by: Murphy Yang Acked-by: Beilei Xing --- drivers/net/i40e/i40e_ethdev.h | 1 + drivers/net/i40e/i40e_fdir.c | 88 +++++++++++++++++++++++++++++++ drivers/net/i40e/i40e_flow.c | 94 +++------------------------------- 3 files changed, 96 insertions(+), 87 deletions(-) diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index faf6896fbc..cdf1c2fe1f 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -631,6 +631,7 @@ struct i40e_fdir_flow_ext { uint8_t raw_id; uint8_t is_vf; /* 1 for VF, 0 for port dev */ uint16_t dst_id; /* VF ID, available when is_vf is 1*/ + uint64_t input_set; bool inner_ip; /* If there is inner ip */ enum i40e_fdir_ip_type iip_type; /* ip type for inner ip */ enum i40e_fdir_ip_type oip_type; /* ip type for outer ip */ diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c index c572d003cb..da089baa4d 100644 --- a/drivers/net/i40e/i40e_fdir.c +++ b/drivers/net/i40e/i40e_fdir.c @@ -1588,6 +1588,83 @@ i40e_flow_set_fdir_flex_msk(struct i40e_pf *pf, pf->fdir.flex_mask_flag[pctype] = 1; } +static int +i40e_flow_set_fdir_inset(struct i40e_pf *pf, + enum i40e_filter_pctype pctype, + uint64_t input_set) +{ + uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0}; + struct i40e_hw *hw = I40E_PF_TO_HW(pf); + uint64_t inset_reg = 0; + int i, num; + + /* Check if the input set is valid */ + if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR, + input_set) != 0) { + PMD_DRV_LOG(ERR, "Invalid input set"); + return -EINVAL; + } + + /* Check if the configuration is conflicted */ + if (pf->fdir.inset_flag[pctype] && + memcmp(&pf->fdir.input_set[pctype], &input_set, sizeof(uint64_t))) + return -1; + + if (pf->fdir.inset_flag[pctype] && + !memcmp(&pf->fdir.input_set[pctype], &input_set, sizeof(uint64_t))) + return 0; + + num = i40e_generate_inset_mask_reg(hw, input_set, mask_reg, + I40E_INSET_MASK_NUM_REG); + if (num < 0) + return -EINVAL; + + if (pf->support_multi_driver) { + for (i = 0; i < num; i++) + if (i40e_read_rx_ctl(hw, + I40E_GLQF_FD_MSK(i, pctype)) != + mask_reg[i]) { + PMD_DRV_LOG(ERR, "Input set setting is not" + " supported with" + " `support-multi-driver`" + " enabled!"); + return -EPERM; + } + for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) + if (i40e_read_rx_ctl(hw, + I40E_GLQF_FD_MSK(i, pctype)) != 0) { + PMD_DRV_LOG(ERR, "Input set setting is not" + " supported with" + " `support-multi-driver`" + " enabled!"); + return -EPERM; + } + + } else { + 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); + } + + inset_reg |= i40e_translate_input_set_reg(hw->mac.type, 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)); + + I40E_WRITE_FLUSH(hw); + + pf->fdir.input_set[pctype] = input_set; + pf->fdir.inset_flag[pctype] = 1; + return 0; +} + static inline unsigned char * i40e_find_available_buffer(struct rte_eth_dev *dev) { @@ -1686,6 +1763,17 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev, if (add) { if (filter->input.flow_ext.is_flex_flow) { + ret = i40e_flow_set_fdir_inset(pf, pctype, + filter->input.flow_ext.input_set); + if (ret == -1) { + PMD_DRV_LOG(ERR, "Conflict with the" + " first rule's input set."); + return -EINVAL; + } else if (ret == -EINVAL) { + PMD_DRV_LOG(ERR, "Invalid pattern mask."); + return -EINVAL; + } + for (i = 0; i < filter->input.flow_ext.raw_id; i++) { layer_idx = filter->input.flow_ext.layer_idx; field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i; diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c index 1ee8959e56..2cc9ad9ef7 100644 --- a/drivers/net/i40e/i40e_flow.c +++ b/drivers/net/i40e/i40e_flow.c @@ -2243,82 +2243,6 @@ i40e_flow_check_raw_item(const struct rte_flow_item *item, return 0; } -static int -i40e_flow_set_fdir_inset(struct i40e_pf *pf, - enum i40e_filter_pctype pctype, - uint64_t input_set) -{ - struct i40e_hw *hw = I40E_PF_TO_HW(pf); - uint64_t inset_reg = 0; - uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0}; - int i, num; - - /* Check if the input set is valid */ - if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR, - input_set) != 0) { - PMD_DRV_LOG(ERR, "Invalid input set"); - return -EINVAL; - } - - /* Check if the configuration is conflicted */ - if (pf->fdir.inset_flag[pctype] && - memcmp(&pf->fdir.input_set[pctype], &input_set, sizeof(uint64_t))) - return -1; - - if (pf->fdir.inset_flag[pctype] && - !memcmp(&pf->fdir.input_set[pctype], &input_set, sizeof(uint64_t))) - return 0; - - num = i40e_generate_inset_mask_reg(hw, input_set, mask_reg, - I40E_INSET_MASK_NUM_REG); - if (num < 0) - return -EINVAL; - - if (pf->support_multi_driver) { - for (i = 0; i < num; i++) - if (i40e_read_rx_ctl(hw, - I40E_GLQF_FD_MSK(i, pctype)) != - mask_reg[i]) { - PMD_DRV_LOG(ERR, "Input set setting is not" - " supported with" - " `support-multi-driver`" - " enabled!"); - return -EPERM; - } - for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) - if (i40e_read_rx_ctl(hw, - I40E_GLQF_FD_MSK(i, pctype)) != 0) { - PMD_DRV_LOG(ERR, "Input set setting is not" - " supported with" - " `support-multi-driver`" - " enabled!"); - return -EPERM; - } - - } else { - 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); - } - - inset_reg |= i40e_translate_input_set_reg(hw->mac.type, 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)); - - I40E_WRITE_FLUSH(hw); - - pf->fdir.input_set[pctype] = input_set; - pf->fdir.inset_flag[pctype] = 1; - return 0; -} static uint8_t i40e_flow_fdir_get_pctype_value(struct i40e_pf *pf, @@ -3212,18 +3136,14 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, /* If customized pctype is not used, set fdir configuration.*/ if (!filter->input.flow_ext.customized_pctype) { - ret = i40e_flow_set_fdir_inset(pf, pctype, input_set); - if (ret == -1) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Conflict with the first rule's input set."); - return -rte_errno; - } else if (ret == -EINVAL) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, - "Invalid pattern mask."); - return -rte_errno; + /* Check if the input set is valid */ + if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR, + input_set) != 0) { + PMD_DRV_LOG(ERR, "Invalid input set"); + return -EINVAL; } + + filter->input.flow_ext.input_set = input_set; } filter->input.pctype = pctype; -- 2.20.1