[2/2] net/i40e: fix incorrect FDIR flex pit
Checks
Commit Message
The register of FDIR flex pit should not be set during flow validate.
It should be set when flow create.
Fixes: 6ced3dd72f5f ("net/i40e: support flexible payload parsing for FDIR")
Cc: stable@dpdk.org
Signed-off-by: Chenxu Di <chenxux.di@intel.com>
---
drivers/net/i40e/i40e_ethdev.h | 21 ++++---
drivers/net/i40e/i40e_fdir.c | 100 +++++++++++++++++++++++++++++++++
drivers/net/i40e/i40e_flow.c | 98 +++-----------------------------
3 files changed, 119 insertions(+), 100 deletions(-)
Comments
Hi, chenxu
> -----Original Message-----
> From: Chenxu Di <chenxux.di@intel.com>
> Sent: Wednesday, November 4, 2020 4:30 PM
> To: dev@dpdk.org
> Cc: Xing, Beilei <beilei.xing@intel.com>; Guo, Jia <jia.guo@intel.com>; Wang,
> Haiyue <haiyue.wang@intel.com>; Di, ChenxuX <chenxux.di@intel.com>;
> stable@dpdk.org
> Subject: [PATCH 2/2] net/i40e: fix incorrect FDIR flex pit
>
> The register of FDIR flex pit should not be set during flow validate.
> It should be set when flow create.
>
> Fixes: 6ced3dd72f5f ("net/i40e: support flexible payload parsing for FDIR")
> Cc: stable@dpdk.org
>
> Signed-off-by: Chenxu Di <chenxux.di@intel.com>
> ---
> drivers/net/i40e/i40e_ethdev.h | 21 ++++---
> drivers/net/i40e/i40e_fdir.c | 100
> +++++++++++++++++++++++++++++++++
> drivers/net/i40e/i40e_flow.c | 98 +++-----------------------------
> 3 files changed, 119 insertions(+), 100 deletions(-)
>
> diff --git a/drivers/net/i40e/i40e_ethdev.h
> b/drivers/net/i40e/i40e_ethdev.h index 6be929f65..e00133c88 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -599,12 +599,22 @@ enum i40e_fdir_ip_type {
> I40E_FDIR_IPTYPE_IPV6,
> };
>
> +/*
> + * Structure to store flex pit for flow diretor.
> + */
> +struct i40e_fdir_flex_pit {
> + uint8_t src_offset; /* offset in words from the beginning of payload
> */
> + uint8_t size; /* size in words */
> + uint8_t dst_offset; /* offset in words of flexible payload */ };
> +
> /* A structure used to contain extend input of flow */ struct
> i40e_fdir_flow_ext {
> uint16_t vlan_tci;
> uint8_t flexbytes[RTE_ETH_FDIR_MAX_FLEXLEN];
> /* It is filled by the flexible payload to match. */
> uint8_t flex_mask[I40E_FDIR_MAX_FLEX_LEN];
> + 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*/
> bool inner_ip; /* If there is inner ip */
> @@ -613,6 +623,8 @@ struct i40e_fdir_flow_ext {
> bool customized_pctype; /* If customized pctype is used */
> bool pkt_template; /* If raw packet template is used */
> bool is_udp; /* ipv4|ipv6 udp flow */
> + enum i40e_flxpld_layer_idx layer_idx;
> + struct i40e_fdir_flex_pit flex_pit[I40E_MAX_FLXPLD_LAYER *
> +I40E_MAX_FLXPLD_FIED];
> };
>
> /* A structure used to define the input for a flow director filter entry */ @@
> -664,15 +676,6 @@ struct i40e_fdir_filter_conf {
> struct i40e_fdir_action action; /* Action taken when match */ };
>
> -/*
> - * Structure to store flex pit for flow diretor.
> - */
> -struct i40e_fdir_flex_pit {
> - uint8_t src_offset; /* offset in words from the beginning of payload
> */
> - uint8_t size; /* size in words */
> - uint8_t dst_offset; /* offset in words of flexible payload */
> -};
> -
> struct i40e_fdir_flex_mask {
> uint8_t word_mask; /**< Bit i enables word i of flexible payload */
> uint8_t nb_bitmask;
> diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c index
> e31464eb7..e64cb2fd0 100644
> --- a/drivers/net/i40e/i40e_fdir.c
> +++ b/drivers/net/i40e/i40e_fdir.c
> @@ -1765,6 +1765,81 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
> return ret;
> }
>
> +static int
> +i40e_flow_store_flex_pit(struct i40e_pf *pf,
> + struct i40e_fdir_flex_pit *flex_pit,
> + enum i40e_flxpld_layer_idx layer_idx,
> + uint8_t raw_id)
> +{
> + uint8_t field_idx;
> +
> + field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + raw_id;
> + /* Check if the configuration is conflicted */
> + if (pf->fdir.flex_pit_flag[layer_idx] &&
> + (pf->fdir.flex_set[field_idx].src_offset != flex_pit->src_offset ||
> + pf->fdir.flex_set[field_idx].size != flex_pit->size ||
> + pf->fdir.flex_set[field_idx].dst_offset != flex_pit->dst_offset))
> + return -1;
> +
> + /* Check if the configuration exists. */
> + if (pf->fdir.flex_pit_flag[layer_idx] &&
> + (pf->fdir.flex_set[field_idx].src_offset == flex_pit->src_offset &&
> + pf->fdir.flex_set[field_idx].size == flex_pit->size &&
> + pf->fdir.flex_set[field_idx].dst_offset == flex_pit->dst_offset))
> + return 1;
> +
> + pf->fdir.flex_set[field_idx].src_offset =
> + flex_pit->src_offset;
> + pf->fdir.flex_set[field_idx].size =
> + flex_pit->size;
> + pf->fdir.flex_set[field_idx].dst_offset =
> + flex_pit->dst_offset;
> +
> + return 0;
> +}
> +
> +static void
> +i40e_flow_set_fdir_flex_pit(struct i40e_pf *pf,
> + enum i40e_flxpld_layer_idx layer_idx,
> + uint8_t raw_id)
> +{
> + struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> + uint32_t flx_pit, flx_ort;
> + uint8_t field_idx;
> + uint16_t min_next_off = 0; /* in words */
> + uint8_t i;
> +
> + if (raw_id) {
> + flx_ort = (1 << I40E_GLQF_ORT_FLX_PAYLOAD_SHIFT) |
> + (raw_id << I40E_GLQF_ORT_FIELD_CNT_SHIFT) |
> + (layer_idx * I40E_MAX_FLXPLD_FIED);
> + I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(33 + layer_idx),
> flx_ort);
> + }
> +
> + /* Set flex pit */
> + for (i = 0; i < raw_id; i++) {
> + field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i;
> + flx_pit = MK_FLX_PIT(pf->fdir.flex_set[field_idx].src_offset,
> + pf->fdir.flex_set[field_idx].size,
> + pf->fdir.flex_set[field_idx].dst_offset);
> +
> + I40E_WRITE_REG(hw, I40E_PRTQF_FLX_PIT(field_idx),
> flx_pit);
> + min_next_off = pf->fdir.flex_set[field_idx].src_offset +
> + pf->fdir.flex_set[field_idx].size;
> + }
> +
> + for (; i < I40E_MAX_FLXPLD_FIED; i++) {
> + /* set the non-used register obeying register's constrain */
> + field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i;
> + flx_pit = MK_FLX_PIT(min_next_off,
> NONUSE_FLX_PIT_FSIZE,
> + NONUSE_FLX_PIT_DEST_OFF);
> + I40E_WRITE_REG(hw, I40E_PRTQF_FLX_PIT(field_idx),
> flx_pit);
> + min_next_off++;
> + }
> +
> + pf->fdir.flex_pit_flag[layer_idx] = 1; }
> +
> static int
> i40e_flow_store_flex_mask(struct i40e_pf *pf,
> enum i40e_filter_pctype pctype,
> @@ -1889,13 +1964,17 @@ i40e_flow_add_del_fdir_filter(struct
> rte_eth_dev *dev, {
> struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data-
> >dev_private);
> + enum i40e_flxpld_layer_idx layer_idx = I40E_FLXPLD_L2_IDX;
> unsigned char *pkt = NULL;
> enum i40e_filter_pctype pctype;
> struct i40e_fdir_info *fdir_info = &pf->fdir;
> uint8_t flex_mask[I40E_FDIR_MAX_FLEX_LEN];
> struct i40e_fdir_filter *node;
> struct i40e_fdir_filter check_filter; /* Check if the filter exists */
> + struct i40e_fdir_flex_pit flex_pit;
> + bool cfg_flex_pit = true;
> bool wait_status = true;
> + uint8_t field_idx;
> int ret = 0;
> int i;
>
> @@ -1931,6 +2010,27 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev
> *dev,
>
> if (add) {
> if (!filter->input.flow_ext.customized_pctype) {
> + 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;
> + flex_pit = filter-
> >input.flow_ext.flex_pit[field_idx];
> +
> + /* Store flex pit to SW */
> + ret = i40e_flow_store_flex_pit(pf, &flex_pit,
> + layer_idx, i);
> + if (ret < 0) {
> + PMD_DRV_LOG(ERR, "Conflict with
> the"
> + " first flexible rule.");
> + return -EINVAL;
> + } else if (ret > 0) {
> + cfg_flex_pit = false;
> + }
> + }
> +
> + if (cfg_flex_pit)
> + i40e_flow_set_fdir_flex_pit(pf, layer_idx,
> + filter-
> >input.flow_ext.raw_id);
> +
> /* Store flex mask to SW */
> for (i = 0; i < I40E_FDIR_MAX_FLEX_LEN; i++)
> flex_mask[i] =
> diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
> index 4f916494e..098ae13ab 100644
> --- a/drivers/net/i40e/i40e_flow.c
> +++ b/drivers/net/i40e/i40e_flow.c
> @@ -2240,81 +2240,6 @@ i40e_flow_check_raw_item(const struct
> rte_flow_item *item,
> return 0;
> }
>
> -static int
> -i40e_flow_store_flex_pit(struct i40e_pf *pf,
> - struct i40e_fdir_flex_pit *flex_pit,
> - enum i40e_flxpld_layer_idx layer_idx,
> - uint8_t raw_id)
> -{
> - uint8_t field_idx;
> -
> - field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + raw_id;
> - /* Check if the configuration is conflicted */
> - if (pf->fdir.flex_pit_flag[layer_idx] &&
> - (pf->fdir.flex_set[field_idx].src_offset != flex_pit->src_offset ||
> - pf->fdir.flex_set[field_idx].size != flex_pit->size ||
> - pf->fdir.flex_set[field_idx].dst_offset != flex_pit->dst_offset))
> - return -1;
> -
> - /* Check if the configuration exists. */
> - if (pf->fdir.flex_pit_flag[layer_idx] &&
> - (pf->fdir.flex_set[field_idx].src_offset == flex_pit->src_offset &&
> - pf->fdir.flex_set[field_idx].size == flex_pit->size &&
> - pf->fdir.flex_set[field_idx].dst_offset == flex_pit->dst_offset))
> - return 1;
> -
> - pf->fdir.flex_set[field_idx].src_offset =
> - flex_pit->src_offset;
> - pf->fdir.flex_set[field_idx].size =
> - flex_pit->size;
> - pf->fdir.flex_set[field_idx].dst_offset =
> - flex_pit->dst_offset;
> -
> - return 0;
> -}
> -
> -static void
> -i40e_flow_set_fdir_flex_pit(struct i40e_pf *pf,
> - enum i40e_flxpld_layer_idx layer_idx,
> - uint8_t raw_id)
> -{
> - struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> - uint32_t flx_pit, flx_ort;
> - uint8_t field_idx;
> - uint16_t min_next_off = 0; /* in words */
> - uint8_t i;
> -
> - if (raw_id) {
> - flx_ort = (1 << I40E_GLQF_ORT_FLX_PAYLOAD_SHIFT) |
> - (raw_id << I40E_GLQF_ORT_FIELD_CNT_SHIFT) |
> - (layer_idx * I40E_MAX_FLXPLD_FIED);
> - I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(33 + layer_idx),
> flx_ort);
> - }
> -
> - /* Set flex pit */
> - for (i = 0; i < raw_id; i++) {
> - field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i;
> - flx_pit = MK_FLX_PIT(pf->fdir.flex_set[field_idx].src_offset,
> - pf->fdir.flex_set[field_idx].size,
> - pf->fdir.flex_set[field_idx].dst_offset);
> -
> - I40E_WRITE_REG(hw, I40E_PRTQF_FLX_PIT(field_idx),
> flx_pit);
> - min_next_off = pf->fdir.flex_set[field_idx].src_offset +
> - pf->fdir.flex_set[field_idx].size;
> - }
> -
> - for (; i < I40E_MAX_FLXPLD_FIED; i++) {
> - /* set the non-used register obeying register's constrain */
> - field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i;
> - flx_pit = MK_FLX_PIT(min_next_off,
> NONUSE_FLX_PIT_FSIZE,
> - NONUSE_FLX_PIT_DEST_OFF);
> - I40E_WRITE_REG(hw, I40E_PRTQF_FLX_PIT(field_idx),
> flx_pit);
> - min_next_off++;
> - }
> -
> - pf->fdir.flex_pit_flag[layer_idx] = 1;
> -}
> -
> static int
> i40e_flow_set_fdir_inset(struct i40e_pf *pf,
> enum i40e_filter_pctype pctype,
> @@ -2534,10 +2459,10 @@ i40e_flow_parse_fdir_pattern(struct
> rte_eth_dev *dev,
> struct i40e_fdir_flex_pit flex_pit;
> uint8_t next_dst_off = 0;
> uint16_t flex_size;
> - bool cfg_flex_pit = true;
> uint16_t ether_type;
> uint32_t vtc_flow_cpu;
> bool outer_ip = true;
> + uint8_t field_idx;
> int ret;
>
> memset(off_arr, 0, sizeof(off_arr));
> @@ -3089,6 +3014,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev
> *dev,
>
> flex_size = 0;
> memset(&flex_pit, 0, sizeof(struct
> i40e_fdir_flex_pit));
> + field_idx = layer_idx * I40E_MAX_FLXPLD_FIED +
> raw_id;
> flex_pit.size =
> raw_spec->length / sizeof(uint16_t);
> flex_pit.dst_offset =
> @@ -3115,18 +3041,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev
> *dev,
> return -rte_errno;
> }
>
> - /* Store flex pit to SW */
> - ret = i40e_flow_store_flex_pit(pf, &flex_pit,
> - layer_idx, raw_id);
> - if (ret < 0) {
> - rte_flow_error_set(error, EINVAL,
> - RTE_FLOW_ERROR_TYPE_ITEM,
> - item,
> - "Conflict with the first flexible rule.");
> - return -rte_errno;
> - } else if (ret > 0)
> - cfg_flex_pit = false;
> -
> for (i = 0; i < raw_spec->length; i++) {
> j = i + next_dst_off;
> filter->input.flow_ext.flexbytes[j] = @@ -
> 3137,6 +3051,11 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
>
> next_dst_off += raw_spec->length;
> raw_id++;
> +
> + memcpy(&filter->input.flow_ext.flex_pit[field_idx],
> + &flex_pit, sizeof(struct i40e_fdir_flex_pit));
> + filter->input.flow_ext.layer_idx = layer_idx;
> + filter->input.flow_ext.raw_id = raw_id;
> break;
> case RTE_FLOW_ITEM_TYPE_VF:
> vf_spec = item->spec;
> @@ -3222,9 +3141,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev
> *dev,
> "Invalid pattern mask.");
> return -rte_errno;
> }
> -
> - if (cfg_flex_pit)
> - i40e_flow_set_fdir_flex_pit(pf, layer_idx, raw_id);
Seems that multiple switch case set the layer_idx not only the place you delete, please double check if these case all need to handle.
> }
>
> filter->input.pctype = pctype;
> --
> 2.17.1
@@ -599,12 +599,22 @@ enum i40e_fdir_ip_type {
I40E_FDIR_IPTYPE_IPV6,
};
+/*
+ * Structure to store flex pit for flow diretor.
+ */
+struct i40e_fdir_flex_pit {
+ uint8_t src_offset; /* offset in words from the beginning of payload */
+ uint8_t size; /* size in words */
+ uint8_t dst_offset; /* offset in words of flexible payload */
+};
+
/* A structure used to contain extend input of flow */
struct i40e_fdir_flow_ext {
uint16_t vlan_tci;
uint8_t flexbytes[RTE_ETH_FDIR_MAX_FLEXLEN];
/* It is filled by the flexible payload to match. */
uint8_t flex_mask[I40E_FDIR_MAX_FLEX_LEN];
+ 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*/
bool inner_ip; /* If there is inner ip */
@@ -613,6 +623,8 @@ struct i40e_fdir_flow_ext {
bool customized_pctype; /* If customized pctype is used */
bool pkt_template; /* If raw packet template is used */
bool is_udp; /* ipv4|ipv6 udp flow */
+ enum i40e_flxpld_layer_idx layer_idx;
+ struct i40e_fdir_flex_pit flex_pit[I40E_MAX_FLXPLD_LAYER * I40E_MAX_FLXPLD_FIED];
};
/* A structure used to define the input for a flow director filter entry */
@@ -664,15 +676,6 @@ struct i40e_fdir_filter_conf {
struct i40e_fdir_action action; /* Action taken when match */
};
-/*
- * Structure to store flex pit for flow diretor.
- */
-struct i40e_fdir_flex_pit {
- uint8_t src_offset; /* offset in words from the beginning of payload */
- uint8_t size; /* size in words */
- uint8_t dst_offset; /* offset in words of flexible payload */
-};
-
struct i40e_fdir_flex_mask {
uint8_t word_mask; /**< Bit i enables word i of flexible payload */
uint8_t nb_bitmask;
@@ -1765,6 +1765,81 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
return ret;
}
+static int
+i40e_flow_store_flex_pit(struct i40e_pf *pf,
+ struct i40e_fdir_flex_pit *flex_pit,
+ enum i40e_flxpld_layer_idx layer_idx,
+ uint8_t raw_id)
+{
+ uint8_t field_idx;
+
+ field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + raw_id;
+ /* Check if the configuration is conflicted */
+ if (pf->fdir.flex_pit_flag[layer_idx] &&
+ (pf->fdir.flex_set[field_idx].src_offset != flex_pit->src_offset ||
+ pf->fdir.flex_set[field_idx].size != flex_pit->size ||
+ pf->fdir.flex_set[field_idx].dst_offset != flex_pit->dst_offset))
+ return -1;
+
+ /* Check if the configuration exists. */
+ if (pf->fdir.flex_pit_flag[layer_idx] &&
+ (pf->fdir.flex_set[field_idx].src_offset == flex_pit->src_offset &&
+ pf->fdir.flex_set[field_idx].size == flex_pit->size &&
+ pf->fdir.flex_set[field_idx].dst_offset == flex_pit->dst_offset))
+ return 1;
+
+ pf->fdir.flex_set[field_idx].src_offset =
+ flex_pit->src_offset;
+ pf->fdir.flex_set[field_idx].size =
+ flex_pit->size;
+ pf->fdir.flex_set[field_idx].dst_offset =
+ flex_pit->dst_offset;
+
+ return 0;
+}
+
+static void
+i40e_flow_set_fdir_flex_pit(struct i40e_pf *pf,
+ enum i40e_flxpld_layer_idx layer_idx,
+ uint8_t raw_id)
+{
+ struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+ uint32_t flx_pit, flx_ort;
+ uint8_t field_idx;
+ uint16_t min_next_off = 0; /* in words */
+ uint8_t i;
+
+ if (raw_id) {
+ flx_ort = (1 << I40E_GLQF_ORT_FLX_PAYLOAD_SHIFT) |
+ (raw_id << I40E_GLQF_ORT_FIELD_CNT_SHIFT) |
+ (layer_idx * I40E_MAX_FLXPLD_FIED);
+ I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(33 + layer_idx), flx_ort);
+ }
+
+ /* Set flex pit */
+ for (i = 0; i < raw_id; i++) {
+ field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i;
+ flx_pit = MK_FLX_PIT(pf->fdir.flex_set[field_idx].src_offset,
+ pf->fdir.flex_set[field_idx].size,
+ pf->fdir.flex_set[field_idx].dst_offset);
+
+ I40E_WRITE_REG(hw, I40E_PRTQF_FLX_PIT(field_idx), flx_pit);
+ min_next_off = pf->fdir.flex_set[field_idx].src_offset +
+ pf->fdir.flex_set[field_idx].size;
+ }
+
+ for (; i < I40E_MAX_FLXPLD_FIED; i++) {
+ /* set the non-used register obeying register's constrain */
+ field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i;
+ flx_pit = MK_FLX_PIT(min_next_off, NONUSE_FLX_PIT_FSIZE,
+ NONUSE_FLX_PIT_DEST_OFF);
+ I40E_WRITE_REG(hw, I40E_PRTQF_FLX_PIT(field_idx), flx_pit);
+ min_next_off++;
+ }
+
+ pf->fdir.flex_pit_flag[layer_idx] = 1;
+}
+
static int
i40e_flow_store_flex_mask(struct i40e_pf *pf,
enum i40e_filter_pctype pctype,
@@ -1889,13 +1964,17 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev,
{
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ enum i40e_flxpld_layer_idx layer_idx = I40E_FLXPLD_L2_IDX;
unsigned char *pkt = NULL;
enum i40e_filter_pctype pctype;
struct i40e_fdir_info *fdir_info = &pf->fdir;
uint8_t flex_mask[I40E_FDIR_MAX_FLEX_LEN];
struct i40e_fdir_filter *node;
struct i40e_fdir_filter check_filter; /* Check if the filter exists */
+ struct i40e_fdir_flex_pit flex_pit;
+ bool cfg_flex_pit = true;
bool wait_status = true;
+ uint8_t field_idx;
int ret = 0;
int i;
@@ -1931,6 +2010,27 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev,
if (add) {
if (!filter->input.flow_ext.customized_pctype) {
+ 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;
+ flex_pit = filter->input.flow_ext.flex_pit[field_idx];
+
+ /* Store flex pit to SW */
+ ret = i40e_flow_store_flex_pit(pf, &flex_pit,
+ layer_idx, i);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Conflict with the"
+ " first flexible rule.");
+ return -EINVAL;
+ } else if (ret > 0) {
+ cfg_flex_pit = false;
+ }
+ }
+
+ if (cfg_flex_pit)
+ i40e_flow_set_fdir_flex_pit(pf, layer_idx,
+ filter->input.flow_ext.raw_id);
+
/* Store flex mask to SW */
for (i = 0; i < I40E_FDIR_MAX_FLEX_LEN; i++)
flex_mask[i] =
@@ -2240,81 +2240,6 @@ i40e_flow_check_raw_item(const struct rte_flow_item *item,
return 0;
}
-static int
-i40e_flow_store_flex_pit(struct i40e_pf *pf,
- struct i40e_fdir_flex_pit *flex_pit,
- enum i40e_flxpld_layer_idx layer_idx,
- uint8_t raw_id)
-{
- uint8_t field_idx;
-
- field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + raw_id;
- /* Check if the configuration is conflicted */
- if (pf->fdir.flex_pit_flag[layer_idx] &&
- (pf->fdir.flex_set[field_idx].src_offset != flex_pit->src_offset ||
- pf->fdir.flex_set[field_idx].size != flex_pit->size ||
- pf->fdir.flex_set[field_idx].dst_offset != flex_pit->dst_offset))
- return -1;
-
- /* Check if the configuration exists. */
- if (pf->fdir.flex_pit_flag[layer_idx] &&
- (pf->fdir.flex_set[field_idx].src_offset == flex_pit->src_offset &&
- pf->fdir.flex_set[field_idx].size == flex_pit->size &&
- pf->fdir.flex_set[field_idx].dst_offset == flex_pit->dst_offset))
- return 1;
-
- pf->fdir.flex_set[field_idx].src_offset =
- flex_pit->src_offset;
- pf->fdir.flex_set[field_idx].size =
- flex_pit->size;
- pf->fdir.flex_set[field_idx].dst_offset =
- flex_pit->dst_offset;
-
- return 0;
-}
-
-static void
-i40e_flow_set_fdir_flex_pit(struct i40e_pf *pf,
- enum i40e_flxpld_layer_idx layer_idx,
- uint8_t raw_id)
-{
- struct i40e_hw *hw = I40E_PF_TO_HW(pf);
- uint32_t flx_pit, flx_ort;
- uint8_t field_idx;
- uint16_t min_next_off = 0; /* in words */
- uint8_t i;
-
- if (raw_id) {
- flx_ort = (1 << I40E_GLQF_ORT_FLX_PAYLOAD_SHIFT) |
- (raw_id << I40E_GLQF_ORT_FIELD_CNT_SHIFT) |
- (layer_idx * I40E_MAX_FLXPLD_FIED);
- I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(33 + layer_idx), flx_ort);
- }
-
- /* Set flex pit */
- for (i = 0; i < raw_id; i++) {
- field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i;
- flx_pit = MK_FLX_PIT(pf->fdir.flex_set[field_idx].src_offset,
- pf->fdir.flex_set[field_idx].size,
- pf->fdir.flex_set[field_idx].dst_offset);
-
- I40E_WRITE_REG(hw, I40E_PRTQF_FLX_PIT(field_idx), flx_pit);
- min_next_off = pf->fdir.flex_set[field_idx].src_offset +
- pf->fdir.flex_set[field_idx].size;
- }
-
- for (; i < I40E_MAX_FLXPLD_FIED; i++) {
- /* set the non-used register obeying register's constrain */
- field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i;
- flx_pit = MK_FLX_PIT(min_next_off, NONUSE_FLX_PIT_FSIZE,
- NONUSE_FLX_PIT_DEST_OFF);
- I40E_WRITE_REG(hw, I40E_PRTQF_FLX_PIT(field_idx), flx_pit);
- min_next_off++;
- }
-
- pf->fdir.flex_pit_flag[layer_idx] = 1;
-}
-
static int
i40e_flow_set_fdir_inset(struct i40e_pf *pf,
enum i40e_filter_pctype pctype,
@@ -2534,10 +2459,10 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
struct i40e_fdir_flex_pit flex_pit;
uint8_t next_dst_off = 0;
uint16_t flex_size;
- bool cfg_flex_pit = true;
uint16_t ether_type;
uint32_t vtc_flow_cpu;
bool outer_ip = true;
+ uint8_t field_idx;
int ret;
memset(off_arr, 0, sizeof(off_arr));
@@ -3089,6 +3014,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
flex_size = 0;
memset(&flex_pit, 0, sizeof(struct i40e_fdir_flex_pit));
+ field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + raw_id;
flex_pit.size =
raw_spec->length / sizeof(uint16_t);
flex_pit.dst_offset =
@@ -3115,18 +3041,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
return -rte_errno;
}
- /* Store flex pit to SW */
- ret = i40e_flow_store_flex_pit(pf, &flex_pit,
- layer_idx, raw_id);
- if (ret < 0) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- item,
- "Conflict with the first flexible rule.");
- return -rte_errno;
- } else if (ret > 0)
- cfg_flex_pit = false;
-
for (i = 0; i < raw_spec->length; i++) {
j = i + next_dst_off;
filter->input.flow_ext.flexbytes[j] =
@@ -3137,6 +3051,11 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
next_dst_off += raw_spec->length;
raw_id++;
+
+ memcpy(&filter->input.flow_ext.flex_pit[field_idx],
+ &flex_pit, sizeof(struct i40e_fdir_flex_pit));
+ filter->input.flow_ext.layer_idx = layer_idx;
+ filter->input.flow_ext.raw_id = raw_id;
break;
case RTE_FLOW_ITEM_TYPE_VF:
vf_spec = item->spec;
@@ -3222,9 +3141,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
"Invalid pattern mask.");
return -rte_errno;
}
-
- if (cfg_flex_pit)
- i40e_flow_set_fdir_flex_pit(pf, layer_idx, raw_id);
}
filter->input.pctype = pctype;