[dpdk-dev,v2,1/4] net/i40e: implement dynamic mapping of sw flow types to hw pctypes

Message ID 1504278166-32769-2-git-send-email-kirill.rybalchenko@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Rybalchenko, Kirill Sept. 1, 2017, 3:02 p.m. UTC
  Implement dynamic mapping of software flow types to hardware pctypes.
This allows to add new flow types and pctypes for DDP without changing
API of the driver. The mapping table is located in private
data area for particular network adapter and can be individually
modified with set of appropriate functions.

Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
v2
Re-arrange patchset to avoid compillation errors.
Remove usage of statically defined flow types and pctypes.
---
 drivers/net/i40e/i40e_ethdev.c    | 347 ++++++++++----------------------------
 drivers/net/i40e/i40e_ethdev.h    |  16 +-
 drivers/net/i40e/i40e_ethdev_vf.c |  36 ++--
 drivers/net/i40e/i40e_fdir.c      |  51 +++---
 drivers/net/i40e/i40e_flow.c      |   2 +-
 drivers/net/i40e/i40e_rxtx.c      |  57 +++++++
 drivers/net/i40e/i40e_rxtx.h      |   1 +
 7 files changed, 190 insertions(+), 320 deletions(-)
  

Comments

Ananyev, Konstantin Sept. 4, 2017, 4:49 p.m. UTC | #1
Hi Kirill,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Kirill Rybalchenko
> Sent: Friday, September 1, 2017 4:03 PM
> To: dev@dpdk.org
> Cc: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>; Chilikin, Andrey <andrey.chilikin@intel.com>; Xing, Beilei <beilei.xing@intel.com>;
> Wu, Jingjing <jingjing.wu@intel.com>
> Subject: [dpdk-dev] [PATCH v2 1/4] net/i40e: implement dynamic mapping of sw flow types to hw pctypes
> 
> Implement dynamic mapping of software flow types to hardware pctypes.
> This allows to add new flow types and pctypes for DDP without changing
> API of the driver. The mapping table is located in private
> data area for particular network adapter and can be individually
> modified with set of appropriate functions.
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> ---
> v2
> Re-arrange patchset to avoid compillation errors.
> Remove usage of statically defined flow types and pctypes.
> ---
>  drivers/net/i40e/i40e_ethdev.c    | 347 ++++++++++----------------------------
>  drivers/net/i40e/i40e_ethdev.h    |  16 +-
>  drivers/net/i40e/i40e_ethdev_vf.c |  36 ++--
>  drivers/net/i40e/i40e_fdir.c      |  51 +++---
>  drivers/net/i40e/i40e_flow.c      |   2 +-
>  drivers/net/i40e/i40e_rxtx.c      |  57 +++++++
>  drivers/net/i40e/i40e_rxtx.h      |   1 +
>  7 files changed, 190 insertions(+), 320 deletions(-)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 8e0580c..56a96f5 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -1062,6 +1062,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
>  		return 0;
>  	}
>  	i40e_set_default_ptype_table(dev);
> +	i40e_set_default_pctype_table(dev);
>  	pci_dev = RTE_ETH_DEV_TO_PCI(dev);
>  	intr_handle = &pci_dev->intr_handle;
> 
> @@ -2971,7 +2972,7 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>  	dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
>  						sizeof(uint32_t);
>  	dev_info->reta_size = pf->hash_lut_size;
> -	dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
> +	dev_info->flow_type_rss_offloads = pf->adapter->flow_types_msk;
> 
>  	dev_info->default_rxconf = (struct rte_eth_rxconf) {
>  		.rx_thresh = {
> @@ -6562,104 +6563,36 @@ i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
> 
>  /* Configure hash enable flags for RSS */
>  uint64_t
> -i40e_config_hena(uint64_t flags, enum i40e_mac_type type)
> +i40e_config_hena(uint64_t flags, struct i40e_adapter *adapter)
>  {

As a nit here and in few other functions below, to keep more conventional order of parameters:
i40e_config_hena(struct i40e_adapter *adapter, ....)

probably even better: 'const struct i40e_adapter *adapter' whenever possible.

>  	uint64_t hena = 0;
> +	int i;
> 
>  	if (!flags)
>  		return hena;
> 
> -	if (flags & ETH_RSS_FRAG_IPV4)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4;
> -	if (flags & ETH_RSS_NONFRAG_IPV4_TCP) {
> -		if (type == I40E_MAC_X722) {
> -			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP) |
> -			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
> -		} else
> -			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
> -	}
> -	if (flags & ETH_RSS_NONFRAG_IPV4_UDP) {
> -		if (type == I40E_MAC_X722) {
> -			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
> -			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
> -			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
> -		} else
> -			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
> -	}
> -	if (flags & ETH_RSS_NONFRAG_IPV4_SCTP)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP;
> -	if (flags & ETH_RSS_NONFRAG_IPV4_OTHER)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER;
> -	if (flags & ETH_RSS_FRAG_IPV6)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6;
> -	if (flags & ETH_RSS_NONFRAG_IPV6_TCP) {
> -		if (type == I40E_MAC_X722) {
> -			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP) |
> -			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
> -		} else
> -			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
> +	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
> +		if (flags & (1ULL << i))
> +			hena |= adapter->pcypes_tbl[i];
>  	}
> -	if (flags & ETH_RSS_NONFRAG_IPV6_UDP) {
> -		if (type == I40E_MAC_X722) {
> -			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
> -			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
> -			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
> -		} else
> -			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
> -	}
> -	if (flags & ETH_RSS_NONFRAG_IPV6_SCTP)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP;
> -	if (flags & ETH_RSS_NONFRAG_IPV6_OTHER)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER;
> -	if (flags & ETH_RSS_L2_PAYLOAD)
> -		hena |= 1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD;
> 
>  	return hena;
>  }
> 

...

> 
> -enum i40e_filter_pctype
> -i40e_flowtype_to_pctype(uint16_t flow_type)
> -{
> -	static const enum i40e_filter_pctype pctype_table[] = {
> -		[RTE_ETH_FLOW_FRAG_IPV4] = I40E_FILTER_PCTYPE_FRAG_IPV4,
> -		[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] =
> -			I40E_FILTER_PCTYPE_NONF_IPV4_UDP,
> -		[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] =
> -			I40E_FILTER_PCTYPE_NONF_IPV4_TCP,
> -		[RTE_ETH_FLOW_NONFRAG_IPV4_SCTP] =
> -			I40E_FILTER_PCTYPE_NONF_IPV4_SCTP,
> -		[RTE_ETH_FLOW_NONFRAG_IPV4_OTHER] =
> -			I40E_FILTER_PCTYPE_NONF_IPV4_OTHER,
> -		[RTE_ETH_FLOW_FRAG_IPV6] = I40E_FILTER_PCTYPE_FRAG_IPV6,
> -		[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] =
> -			I40E_FILTER_PCTYPE_NONF_IPV6_UDP,
> -		[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] =
> -			I40E_FILTER_PCTYPE_NONF_IPV6_TCP,
> -		[RTE_ETH_FLOW_NONFRAG_IPV6_SCTP] =
> -			I40E_FILTER_PCTYPE_NONF_IPV6_SCTP,
> -		[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] =
> -			I40E_FILTER_PCTYPE_NONF_IPV6_OTHER,
> -		[RTE_ETH_FLOW_L2_PAYLOAD] = I40E_FILTER_PCTYPE_L2_PAYLOAD,
> -	};
> +uint16_t
> +i40e_flowtype_to_pctype(uint16_t flow_type, struct i40e_adapter *adapter)
> +{
> +	int i;
> +	uint64_t pctype_mask;
> 
> -	return pctype_table[flow_type];
> +	if (flow_type < I40E_FLOW_TYPE_MAX) {
> +		pctype_mask = adapter->pcypes_tbl[flow_type];
> +		for (i = I40E_PCTYPE_MAX - 1; i >= 0; i--) {
> +			if (pctype_mask & (1ULL << i))
> +				return (uint16_t)i;

So, each pcypes_tbl[] would always have only one bit set?
If so, wouldn't it  be more convenient to store only bit index?


> +		}
> +	}
> +	return 0;

As I can see, that function would return 0 for both
adapter->pcypes_tbl[flow_type] == 0 and adapter->pcypes_tbl[flow_type] == 1
Is that intended?
Konstantin

>  }
>
  
Ferruh Yigit Sept. 8, 2017, 4:58 p.m. UTC | #2
On 9/1/2017 4:02 PM, Kirill Rybalchenko wrote:
> Implement dynamic mapping of software flow types to hardware pctypes.
> This allows to add new flow types and pctypes for DDP without changing
> API of the driver. The mapping table is located in private
> data area for particular network adapter and can be individually
> modified with set of appropriate functions.
> 
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> ---
> v2
> Re-arrange patchset to avoid compillation errors.
> Remove usage of statically defined flow types and pctypes.
<...>

> +	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
> +		if (flags & (1ULL << i))
> +			hena |= adapter->pcypes_tbl[i];

s/pcypes_tbl/pctypes_tbl/ ?

<...>

> @@ -6668,16 +6601,9 @@ static void
>  i40e_pf_disable_rss(struct i40e_pf *pf)
>  {
>  	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> -	uint64_t hena;
>  
> -	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
> -	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
> -	if (hw->mac.type == I40E_MAC_X722)
> -		hena &= ~I40E_RSS_HENA_ALL_X722;
> -	else
> -		hena &= ~I40E_RSS_HENA_ALL;
> -	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
> -	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));

Above logic keeps intact bits of I40E_PFQF_HENA register that are not
supported RSS has filter. But below new code just sets all to zero.

I don't know why above prefer this logic, but would you mind separating
this decision into own its patch? I mean in this patch keep this as it
is, and make new patch to switch new register values.

> +	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0);
> +	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0);
>  	I40E_WRITE_FLUSH(hw);
>  }
>  
> @@ -6749,23 +6675,14 @@ static int
>  i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
>  {
>  	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> -	uint64_t rss_hf;
>  	uint64_t hena;
>  	int ret;
>  
> -	ret = i40e_set_rss_key(pf->main_vsi, rss_conf->rss_key,
> -			       rss_conf->rss_key_len);
> +	ret = i40e_set_rss_key(pf->main_vsi, rss_conf->rss_key, rss_conf->rss_key_len);

I think there is no change here, and original code is correct as syntax,
please keep it unchanged.

>  	if (ret)
>  		return ret;
>  
> -	rss_hf = rss_conf->rss_hf;
> -	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
> -	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
> -	if (hw->mac.type == I40E_MAC_X722)
> -		hena &= ~I40E_RSS_HENA_ALL_X722;
> -	else
> -		hena &= ~I40E_RSS_HENA_ALL;
> -	hena |= i40e_config_hena(rss_hf, hw->mac.type);

Same register comment as above one.

> +	hena = i40e_config_hena(rss_conf->rss_hf, pf->adapter);
>  	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
>  	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
>  	I40E_WRITE_FLUSH(hw);

<...>

> @@ -7820,29 +7736,31 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
>  	PMD_DRV_LOG(DEBUG, "Hash function is %s",
>  		(reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR");
>  
> -	for (i = 0; mask && i < RTE_ETH_FLOW_MAX; i++) {
> -		if (!(mask & (1UL << i)))
> -			continue;
> -		mask &= ~(1UL << i);
> -		/* Bit set indicats the coresponding flow type is supported */
> -		g_cfg->valid_bit_mask[0] |= (1UL << i);
> -		/* if flowtype is invalid, continue */
> -		if (!I40E_VALID_FLOW(i))
> -			continue;
> -		pctype = i40e_flowtype_to_pctype(i);
> -		reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(pctype));
> -		if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK)
> -			g_cfg->sym_hash_enable_mask[0] |= (1UL << i);
> +	g_cfg->valid_bit_mask[0] = (uint32_t)adapter->flow_types_msk;

Loosing data here by casting to 32bit, intentional?

> +
> +	for (i = 0; i < UINT32_BIT; i++) {

Why use UINT32_BIT? not I40E_FLOW_TYPE_MAX? Is it because
sym_hash_enable_mask is 32bits? Why not increase its stroge if we need
64 flow type / pctype ?

> +		if (adapter->pcypes_tbl[i]) {
> +			for (j = 0; j < I40E_PCTYPE_MAX; j++) {
> +				if (adapter->pcypes_tbl[i] & (1ULL << j)) {
> +					reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(j));
> +					if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK) {
> +						g_cfg->sym_hash_enable_mask[0] |=
> +									(1UL << i);
> +					}
> +				}
> +			}
> +		}
>  	}
>  
>  	return 0;
>  }

<...>

> @@ -7885,64 +7803,26 @@ static int
>  i40e_set_hash_filter_global_config(struct i40e_hw *hw,
>  				   struct rte_eth_hash_global_conf *g_cfg)
>  {
> +	struct i40e_adapter *adapter = (struct i40e_adapter *)hw->back;
>  	int ret;
> -	uint16_t i;
> +	uint16_t i, j;
>  	uint32_t reg;
> -	uint32_t mask0 = g_cfg->valid_bit_mask[0];
> -	enum i40e_filter_pctype pctype;
> +	uint32_t mask0 = g_cfg->valid_bit_mask[0] & (uint32_t)adapter->flow_types_msk;

Loosing data here by casting to 32bit, intentional?


<...>

> @@ -8636,7 +8513,8 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
>  		return -EINVAL;
>  	}
>  
> -	if (!I40E_VALID_FLOW(conf->flow_type)) {
> +	pctype = i40e_flowtype_to_pctype(conf->flow_type, pf->adapter);
> +	if (!pctype) {

pctype 0 is not defined in enum, which technically possible to be
defined in the future and break this logic, it could be good to define
it now to something UNKNOWN, RESERVED etc.. to be sure it won't be used.

>  		PMD_DRV_LOG(ERR, "invalid flow_type input.");
>  		return -EINVAL;
>  	}

<...>

> @@ -8655,11 +8531,7 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
>  		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;
> -	}

Why removing this validation?

> +
>  	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));
> @@ -8713,24 +8585,19 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
>  		return -EINVAL;
>  	}
>  
> -	if (!I40E_VALID_FLOW(conf->flow_type)) {
> +	pctype = i40e_flowtype_to_pctype(conf->flow_type, pf->adapter);
> +
> +	if (!pctype) {
>  		PMD_DRV_LOG(ERR, "invalid flow_type input.");
>  		return -EINVAL;
>  	}
>  
> -	pctype = i40e_flowtype_to_pctype(conf->flow_type);
> -
>  	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_FDIR,
> -				    input_set) != 0) {
> -		PMD_DRV_LOG(ERR, "Invalid input set");
> -		return -EINVAL;
> -	}

And why removing this part?

>  
>  	/* get inset value in register */
>  	inset_reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
> @@ -9169,72 +9036,34 @@ i40e_hw_init(struct rte_eth_dev *dev)
>  	i40e_set_symmetric_hash_enable_per_port(hw, 0);
>  }
>  
> -enum i40e_filter_pctype
> -i40e_flowtype_to_pctype(uint16_t flow_type)
<...>
> +uint16_t

Why changed return type from "enum i40e_filter_pctype" to "uint16_t",
this function should be returning pctype?

> +i40e_flowtype_to_pctype(uint16_t flow_type, struct i40e_adapter *adapter)
> +{
> +	int i;
> +	uint64_t pctype_mask;
>  
> -	return pctype_table[flow_type];
> +	if (flow_type < I40E_FLOW_TYPE_MAX) {
> +		pctype_mask = adapter->pcypes_tbl[flow_type];
> +		for (i = I40E_PCTYPE_MAX - 1; i >= 0; i--) {
> +			if (pctype_mask & (1ULL << i))

pctype_mask can be having multiple pctype, why returning at first one,
this may be breaking some I40E_MAC_X722 code.

> +				return (uint16_t)i;

if you intend to cast "i" to uint16_t why not define it uint16_t at
first place.

If return type is changed to uint16_t to OR pctype values, that logic is
missing here and caller of the function should take this into account,
and function should be commented to clarify this. If this functions
intented to return single pctype as original code, it should return
"enum i40e_filter_pctype" I think.

> +		}
> +	}
> +	return 0;
>  }
>  

<...>

> +	uint16_t flowtype = RTE_ETH_FLOW_UNKNOWN;
> +	uint64_t pctype_mask = 1ULL << pctype;
> +
> +	for (; flowtype < I40E_FLOW_TYPE_MAX; flowtype++) {
> +		if (adapter->pcypes_tbl[flowtype] & pctype_mask)
> +			return flowtype;
> +	}
>  
> -	return flowtype_table[pctype];
> +	return flowtype;

If pctype is not in the table, this will return I40E_FLOW_TYPE_MAX,
which is wrong.


<...>

> @@ -881,6 +883,10 @@ struct i40e_adapter {
>  
>  	/* ptype mapping table */
>  	uint32_t ptype_tbl[I40E_MAX_PKT_TYPE] __rte_cache_min_aligned;
> +	/* flow type to pctype mapping table */

It can be good to note, not sure where, this is 1:N mapping, one flow
table can has multiple pctypes, bitmasked into pctype variable in the table.

> +	uint64_t pcypes_tbl[I40E_FLOW_TYPE_MAX] __rte_cache_min_aligned;

I guess there is a typo in variable name, is intention "pctypes_tbl" ?

> +	uint64_t flow_types_msk> +	uint64_t pctypes_msk;

abbrevation is only gaining one letter, "a", I would convert this to
"flow_types_mask" and "pctypes_mask".

>  };
>  
>  extern const struct rte_flow_ops i40e_flow_ops;
> @@ -925,8 +931,8 @@ int i40e_vsi_vlan_pvid_set(struct i40e_vsi *vsi,
>  			   struct i40e_vsi_vlan_pvid_info *info);
>  int i40e_vsi_config_vlan_stripping(struct i40e_vsi *vsi, bool on);
>  int i40e_vsi_config_vlan_filter(struct i40e_vsi *vsi, bool on);
> -uint64_t i40e_config_hena(uint64_t flags, enum i40e_mac_type type);
> -uint64_t i40e_parse_hena(uint64_t flags);
> +uint64_t i40e_config_hena(uint64_t flags, struct i40e_adapter *adapter);
> +uint64_t i40e_parse_hena(uint64_t flags, struct i40e_adapter *adapter);
>  enum i40e_status_code i40e_fdir_setup_tx_resources(struct i40e_pf *pf);
>  enum i40e_status_code i40e_fdir_setup_rx_resources(struct i40e_pf *pf);
>  int i40e_fdir_setup(struct i40e_pf *pf);
> @@ -935,8 +941,8 @@ const struct rte_memzone *i40e_memzone_reserve(const char *name,
>  					int socket_id);
>  int i40e_fdir_configure(struct rte_eth_dev *dev);
>  void i40e_fdir_teardown(struct i40e_pf *pf);
> -enum i40e_filter_pctype i40e_flowtype_to_pctype(uint16_t flow_type);
> -uint16_t i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype);
> +uint16_t i40e_flowtype_to_pctype(uint16_t flow_type, struct i40e_adapter *adapter);
> +uint16_t i40e_pctype_to_flowtype(uint16_t pctype, struct i40e_adapter *adapter);
>  int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
>  			  enum rte_filter_op filter_op,
>  			  void *arg);
> diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c

Same above comments for VF code.

<...>
  

Patch

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 8e0580c..56a96f5 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1062,6 +1062,7 @@  eth_i40e_dev_init(struct rte_eth_dev *dev)
 		return 0;
 	}
 	i40e_set_default_ptype_table(dev);
+	i40e_set_default_pctype_table(dev);
 	pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	intr_handle = &pci_dev->intr_handle;
 
@@ -2971,7 +2972,7 @@  i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
 						sizeof(uint32_t);
 	dev_info->reta_size = pf->hash_lut_size;
-	dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
+	dev_info->flow_type_rss_offloads = pf->adapter->flow_types_msk;
 
 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
 		.rx_thresh = {
@@ -6562,104 +6563,36 @@  i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
 
 /* Configure hash enable flags for RSS */
 uint64_t
-i40e_config_hena(uint64_t flags, enum i40e_mac_type type)
+i40e_config_hena(uint64_t flags, struct i40e_adapter *adapter)
 {
 	uint64_t hena = 0;
+	int i;
 
 	if (!flags)
 		return hena;
 
-	if (flags & ETH_RSS_FRAG_IPV4)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4;
-	if (flags & ETH_RSS_NONFRAG_IPV4_TCP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV4_UDP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV4_SCTP)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP;
-	if (flags & ETH_RSS_NONFRAG_IPV4_OTHER)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER;
-	if (flags & ETH_RSS_FRAG_IPV6)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6;
-	if (flags & ETH_RSS_NONFRAG_IPV6_TCP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (flags & (1ULL << i))
+			hena |= adapter->pcypes_tbl[i];
 	}
-	if (flags & ETH_RSS_NONFRAG_IPV6_UDP) {
-		if (type == I40E_MAC_X722) {
-			hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
-			 (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
-		} else
-			hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
-	}
-	if (flags & ETH_RSS_NONFRAG_IPV6_SCTP)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP;
-	if (flags & ETH_RSS_NONFRAG_IPV6_OTHER)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER;
-	if (flags & ETH_RSS_L2_PAYLOAD)
-		hena |= 1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD;
 
 	return hena;
 }
 
 /* Parse the hash enable flags */
 uint64_t
-i40e_parse_hena(uint64_t flags)
+i40e_parse_hena(uint64_t flags, struct i40e_adapter *adapter)
 {
 	uint64_t rss_hf = 0;
 
 	if (!flags)
 		return rss_hf;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4))
-		rss_hf |= ETH_RSS_FRAG_IPV4;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_SCTP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER))
-		rss_hf |= ETH_RSS_NONFRAG_IPV4_OTHER;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6))
-		rss_hf |= ETH_RSS_FRAG_IPV6;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_SCTP;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER))
-		rss_hf |= ETH_RSS_NONFRAG_IPV6_OTHER;
-	if (flags & (1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD))
-		rss_hf |= ETH_RSS_L2_PAYLOAD;
+	int i;
 
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (flags & adapter->pcypes_tbl[i])
+			rss_hf |= (1ULL << i);
+	}
 	return rss_hf;
 }
 
@@ -6668,16 +6601,9 @@  static void
 i40e_pf_disable_rss(struct i40e_pf *pf)
 {
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
-	uint64_t hena;
 
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
-	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0);
+	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0);
 	I40E_WRITE_FLUSH(hw);
 }
 
@@ -6749,23 +6675,14 @@  static int
 i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
 {
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
-	uint64_t rss_hf;
 	uint64_t hena;
 	int ret;
 
-	ret = i40e_set_rss_key(pf->main_vsi, rss_conf->rss_key,
-			       rss_conf->rss_key_len);
+	ret = i40e_set_rss_key(pf->main_vsi, rss_conf->rss_key, rss_conf->rss_key_len);
 	if (ret)
 		return ret;
 
-	rss_hf = rss_conf->rss_hf;
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	hena |= i40e_config_hena(rss_hf, hw->mac.type);
+	hena = i40e_config_hena(rss_conf->rss_hf, pf->adapter);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40E_WRITE_FLUSH(hw);
@@ -6779,14 +6696,13 @@  i40e_dev_rss_hash_update(struct rte_eth_dev *dev,
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint64_t rss_hf = rss_conf->rss_hf & I40E_RSS_OFFLOAD_ALL;
+	uint64_t rss_hf = rss_conf->rss_hf & pf->adapter->flow_types_msk;
 	uint64_t hena;
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	if (!(hena & ((hw->mac.type == I40E_MAC_X722)
-		 ? I40E_RSS_HENA_ALL_X722
-		 : I40E_RSS_HENA_ALL))) { /* RSS disabled */
+
+	if (!(hena & pf->adapter->pctypes_msk)) { /* RSS disabled */
 		if (rss_hf != 0) /* Enable RSS */
 			return -EINVAL;
 		return 0; /* Nothing to do */
@@ -6811,7 +6727,7 @@  i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
-	rss_conf->rss_hf = i40e_parse_hena(hena);
+	rss_conf->rss_hf = i40e_parse_hena(hena, pf->adapter);
 
 	return 0;
 }
@@ -7586,7 +7502,7 @@  i40e_pf_config_rss(struct i40e_pf *pf)
 	}
 
 	rss_conf = pf->dev_data->dev_conf.rx_adv_conf.rss_conf;
-	if ((rss_conf.rss_hf & I40E_RSS_OFFLOAD_ALL) == 0) {
+	if ((rss_conf.rss_hf & pf->adapter->flow_types_msk) == 0) {
 		i40e_pf_disable_rss(pf);
 		return 0;
 	}
@@ -7807,9 +7723,9 @@  static int
 i40e_get_hash_filter_global_config(struct i40e_hw *hw,
 				   struct rte_eth_hash_global_conf *g_cfg)
 {
-	uint32_t reg, mask = I40E_FLOW_TYPES;
-	uint16_t i;
-	enum i40e_filter_pctype pctype;
+	struct i40e_adapter *adapter = (struct i40e_adapter *)hw->back;
+	uint32_t reg;
+	uint16_t i, j;
 
 	memset(g_cfg, 0, sizeof(*g_cfg));
 	reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL);
@@ -7820,29 +7736,31 @@  i40e_get_hash_filter_global_config(struct i40e_hw *hw,
 	PMD_DRV_LOG(DEBUG, "Hash function is %s",
 		(reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR");
 
-	for (i = 0; mask && i < RTE_ETH_FLOW_MAX; i++) {
-		if (!(mask & (1UL << i)))
-			continue;
-		mask &= ~(1UL << i);
-		/* Bit set indicats the coresponding flow type is supported */
-		g_cfg->valid_bit_mask[0] |= (1UL << i);
-		/* if flowtype is invalid, continue */
-		if (!I40E_VALID_FLOW(i))
-			continue;
-		pctype = i40e_flowtype_to_pctype(i);
-		reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(pctype));
-		if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK)
-			g_cfg->sym_hash_enable_mask[0] |= (1UL << i);
+	g_cfg->valid_bit_mask[0] = (uint32_t)adapter->flow_types_msk;
+
+	for (i = 0; i < UINT32_BIT; i++) {
+		if (adapter->pcypes_tbl[i]) {
+			for (j = 0; j < I40E_PCTYPE_MAX; j++) {
+				if (adapter->pcypes_tbl[i] & (1ULL << j)) {
+					reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(j));
+					if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK) {
+						g_cfg->sym_hash_enable_mask[0] |=
+									(1UL << i);
+					}
+				}
+			}
+		}
 	}
 
 	return 0;
 }
 
 static int
-i40e_hash_global_config_check(struct rte_eth_hash_global_conf *g_cfg)
+i40e_hash_global_config_check(struct rte_eth_hash_global_conf *g_cfg,
+			      struct i40e_adapter *adapter)
 {
 	uint32_t i;
-	uint32_t mask0, i40e_mask = I40E_FLOW_TYPES;
+	uint32_t mask0, i40e_mask = adapter->flow_types_msk;
 
 	if (g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
 		g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR &&
@@ -7885,64 +7803,26 @@  static int
 i40e_set_hash_filter_global_config(struct i40e_hw *hw,
 				   struct rte_eth_hash_global_conf *g_cfg)
 {
+	struct i40e_adapter *adapter = (struct i40e_adapter *)hw->back;
 	int ret;
-	uint16_t i;
+	uint16_t i, j;
 	uint32_t reg;
-	uint32_t mask0 = g_cfg->valid_bit_mask[0];
-	enum i40e_filter_pctype pctype;
+	uint32_t mask0 = g_cfg->valid_bit_mask[0] & (uint32_t)adapter->flow_types_msk;
 
 	/* Check the input parameters */
-	ret = i40e_hash_global_config_check(g_cfg);
+	ret = i40e_hash_global_config_check(g_cfg, adapter);
 	if (ret < 0)
 		return ret;
 
-	for (i = 0; mask0 && i < UINT32_BIT; i++) {
-		if (!(mask0 & (1UL << i)))
-			continue;
-		mask0 &= ~(1UL << i);
-		/* if flowtype is invalid, continue */
-		if (!I40E_VALID_FLOW(i))
-			continue;
-		pctype = i40e_flowtype_to_pctype(i);
-		reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
-				I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_UDP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP),
-				  reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_TCP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_TCP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_UDP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP),
-				  reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP),
-				  reg);
-			} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP) {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_TCP), reg);
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(
-				  I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK),
-				  reg);
-			} else {
-				i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(pctype),
-				  reg);
+	for (i = 0; i < UINT32_BIT; i++) {
+		if (mask0 & (1UL << i)) {
+			reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
+					I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
+
+			for (j = 0; j < I40E_PCTYPE_MAX; j++) {
+				if (adapter->pcypes_tbl[i] & (1ULL << j))
+					i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(j), reg);
 			}
-		} else {
-			i40e_write_rx_ctl(hw, I40E_GLQF_HSYM(pctype), reg);
 		}
 	}
 
@@ -8567,13 +8447,10 @@  i40e_filter_input_set_init(struct i40e_pf *pf)
 
 	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
 	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722(pctype))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE(pctype))
-				continue;
-		}
+		uint16_t flow_type = i40e_pctype_to_flowtype(pctype, pf->adapter);
+
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
 
 		input_set = i40e_get_default_input_set(pctype);
 
@@ -8636,7 +8513,8 @@  i40e_hash_filter_inset_select(struct i40e_hw *hw,
 		return -EINVAL;
 	}
 
-	if (!I40E_VALID_FLOW(conf->flow_type)) {
+	pctype = i40e_flowtype_to_pctype(conf->flow_type, pf->adapter);
+	if (!pctype) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
@@ -8644,10 +8522,8 @@  i40e_hash_filter_inset_select(struct i40e_hw *hw,
 	if (hw->mac.type == I40E_MAC_X722) {
 		/* get translated pctype value in fd pctype register */
 		pctype = (enum i40e_filter_pctype)i40e_read_rx_ctl(hw,
-			I40E_GLQF_FD_PCTYPES((int)i40e_flowtype_to_pctype(
-			conf->flow_type)));
-	} else
-		pctype = i40e_flowtype_to_pctype(conf->flow_type);
+			I40E_GLQF_FD_PCTYPES((int)pctype));
+	}
 
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
@@ -8655,11 +8531,7 @@  i40e_hash_filter_inset_select(struct i40e_hw *hw,
 		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));
@@ -8713,24 +8585,19 @@  i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 		return -EINVAL;
 	}
 
-	if (!I40E_VALID_FLOW(conf->flow_type)) {
+	pctype = i40e_flowtype_to_pctype(conf->flow_type, pf->adapter);
+
+	if (!pctype) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
 
-	pctype = i40e_flowtype_to_pctype(conf->flow_type);
-
 	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_FDIR,
-				    input_set) != 0) {
-		PMD_DRV_LOG(ERR, "Invalid input set");
-		return -EINVAL;
-	}
 
 	/* get inset value in register */
 	inset_reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
@@ -9169,72 +9036,34 @@  i40e_hw_init(struct rte_eth_dev *dev)
 	i40e_set_symmetric_hash_enable_per_port(hw, 0);
 }
 
-enum i40e_filter_pctype
-i40e_flowtype_to_pctype(uint16_t flow_type)
-{
-	static const enum i40e_filter_pctype pctype_table[] = {
-		[RTE_ETH_FLOW_FRAG_IPV4] = I40E_FILTER_PCTYPE_FRAG_IPV4,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_UDP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_TCP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_SCTP] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_SCTP,
-		[RTE_ETH_FLOW_NONFRAG_IPV4_OTHER] =
-			I40E_FILTER_PCTYPE_NONF_IPV4_OTHER,
-		[RTE_ETH_FLOW_FRAG_IPV6] = I40E_FILTER_PCTYPE_FRAG_IPV6,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_UDP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_TCP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_SCTP] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_SCTP,
-		[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] =
-			I40E_FILTER_PCTYPE_NONF_IPV6_OTHER,
-		[RTE_ETH_FLOW_L2_PAYLOAD] = I40E_FILTER_PCTYPE_L2_PAYLOAD,
-	};
+uint16_t
+i40e_flowtype_to_pctype(uint16_t flow_type, struct i40e_adapter *adapter)
+{
+	int i;
+	uint64_t pctype_mask;
 
-	return pctype_table[flow_type];
+	if (flow_type < I40E_FLOW_TYPE_MAX) {
+		pctype_mask = adapter->pcypes_tbl[flow_type];
+		for (i = I40E_PCTYPE_MAX - 1; i >= 0; i--) {
+			if (pctype_mask & (1ULL << i))
+				return (uint16_t)i;
+		}
+	}
+	return 0;
 }
 
 uint16_t
-i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype)
+i40e_pctype_to_flowtype(uint16_t pctype, struct i40e_adapter *adapter)
 {
-	static const uint16_t flowtype_table[] = {
-		[I40E_FILTER_PCTYPE_FRAG_IPV4] = RTE_ETH_FLOW_FRAG_IPV4,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_SCTP,
-		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-			RTE_ETH_FLOW_NONFRAG_IPV4_OTHER,
-		[I40E_FILTER_PCTYPE_FRAG_IPV6] = RTE_ETH_FLOW_FRAG_IPV6,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_TCP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_SCTP,
-		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-			RTE_ETH_FLOW_NONFRAG_IPV6_OTHER,
-		[I40E_FILTER_PCTYPE_L2_PAYLOAD] = RTE_ETH_FLOW_L2_PAYLOAD,
-	};
+	uint16_t flowtype = RTE_ETH_FLOW_UNKNOWN;
+	uint64_t pctype_mask = 1ULL << pctype;
+
+	for (; flowtype < I40E_FLOW_TYPE_MAX; flowtype++) {
+		if (adapter->pcypes_tbl[flowtype] & pctype_mask)
+			return flowtype;
+	}
 
-	return flowtype_table[pctype];
+	return flowtype;
 }
 
 /*
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index ad80f0f..a8fdad3 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -852,7 +852,9 @@  struct i40e_vf {
 	uint64_t flags;
 };
 
-#define I40E_MAX_PKT_TYPE 256
+#define I40E_MAX_PKT_TYPE  256
+#define I40E_FLOW_TYPE_MAX 64
+#define I40E_PCTYPE_MAX    64
 
 /*
  * Structure to store private data for each PF/VF instance.
@@ -881,6 +883,10 @@  struct i40e_adapter {
 
 	/* ptype mapping table */
 	uint32_t ptype_tbl[I40E_MAX_PKT_TYPE] __rte_cache_min_aligned;
+	/* flow type to pctype mapping table */
+	uint64_t pcypes_tbl[I40E_FLOW_TYPE_MAX] __rte_cache_min_aligned;
+	uint64_t flow_types_msk;
+	uint64_t pctypes_msk;
 };
 
 extern const struct rte_flow_ops i40e_flow_ops;
@@ -925,8 +931,8 @@  int i40e_vsi_vlan_pvid_set(struct i40e_vsi *vsi,
 			   struct i40e_vsi_vlan_pvid_info *info);
 int i40e_vsi_config_vlan_stripping(struct i40e_vsi *vsi, bool on);
 int i40e_vsi_config_vlan_filter(struct i40e_vsi *vsi, bool on);
-uint64_t i40e_config_hena(uint64_t flags, enum i40e_mac_type type);
-uint64_t i40e_parse_hena(uint64_t flags);
+uint64_t i40e_config_hena(uint64_t flags, struct i40e_adapter *adapter);
+uint64_t i40e_parse_hena(uint64_t flags, struct i40e_adapter *adapter);
 enum i40e_status_code i40e_fdir_setup_tx_resources(struct i40e_pf *pf);
 enum i40e_status_code i40e_fdir_setup_rx_resources(struct i40e_pf *pf);
 int i40e_fdir_setup(struct i40e_pf *pf);
@@ -935,8 +941,8 @@  const struct rte_memzone *i40e_memzone_reserve(const char *name,
 					int socket_id);
 int i40e_fdir_configure(struct rte_eth_dev *dev);
 void i40e_fdir_teardown(struct i40e_pf *pf);
-enum i40e_filter_pctype i40e_flowtype_to_pctype(uint16_t flow_type);
-uint16_t i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype);
+uint16_t i40e_flowtype_to_pctype(uint16_t flow_type, struct i40e_adapter *adapter);
+uint16_t i40e_pctype_to_flowtype(uint16_t pctype, struct i40e_adapter *adapter);
 int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
 			  enum rte_filter_op filter_op,
 			  void *arg);
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 7c5c16b..9fc82b7 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1393,6 +1393,7 @@  i40evf_dev_init(struct rte_eth_dev *eth_dev)
 		return 0;
 	}
 	i40e_set_default_ptype_table(eth_dev);
+	i40e_set_default_pctype_table(eth_dev);
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
 
@@ -2128,7 +2129,7 @@  i40evf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
 	dev_info->hash_key_size = (I40E_VFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t);
 	dev_info->reta_size = ETH_RSS_RETA_SIZE_64;
-	dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
+	dev_info->flow_type_rss_offloads = vf->adapter->flow_types_msk;
 	dev_info->max_mac_addrs = I40E_NUM_MACADDR_MAX;
 	dev_info->rx_offload_capa =
 		DEV_RX_OFFLOAD_VLAN_STRIP |
@@ -2413,7 +2414,7 @@  static int
 i40evf_hw_rss_hash_set(struct i40e_vf *vf, struct rte_eth_rss_conf *rss_conf)
 {
 	struct i40e_hw *hw = I40E_VF_TO_HW(vf);
-	uint64_t rss_hf, hena;
+	uint64_t hena;
 	int ret;
 
 	ret = i40evf_set_rss_key(&vf->vsi, rss_conf->rss_key,
@@ -2421,14 +2422,7 @@  i40evf_hw_rss_hash_set(struct i40e_vf *vf, struct rte_eth_rss_conf *rss_conf)
 	if (ret)
 		return ret;
 
-	rss_hf = rss_conf->rss_hf;
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	hena |= i40e_config_hena(rss_hf, hw->mac.type);
+	hena = i40e_config_hena(rss_conf->rss_hf, vf->adapter);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), (uint32_t)hena);
 	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), (uint32_t)(hena >> 32));
 	I40EVF_WRITE_FLUSH(hw);
@@ -2440,16 +2434,9 @@  static void
 i40evf_disable_rss(struct i40e_vf *vf)
 {
 	struct i40e_hw *hw = I40E_VF_TO_HW(vf);
-	uint64_t hena;
 
-	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
-	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (hw->mac.type == I40E_MAC_X722)
-		hena &= ~I40E_RSS_HENA_ALL_X722;
-	else
-		hena &= ~I40E_RSS_HENA_ALL;
-	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), (uint32_t)hena);
-	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), (uint32_t)(hena >> 32));
+	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(0), 0);
+	i40e_write_rx_ctl(hw, I40E_VFQF_HENA(1), 0);
 	I40EVF_WRITE_FLUSH(hw);
 }
 
@@ -2478,7 +2465,7 @@  i40evf_config_rss(struct i40e_vf *vf)
 	}
 
 	rss_conf = vf->dev_data->dev_conf.rx_adv_conf.rss_conf;
-	if ((rss_conf.rss_hf & I40E_RSS_OFFLOAD_ALL) == 0) {
+	if ((rss_conf.rss_hf & vf->adapter->flow_types_msk) == 0) {
 		i40evf_disable_rss(vf);
 		PMD_DRV_LOG(DEBUG, "No hash flag is set");
 		return 0;
@@ -2503,14 +2490,13 @@  i40evf_dev_rss_hash_update(struct rte_eth_dev *dev,
 {
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint64_t rss_hf = rss_conf->rss_hf & I40E_RSS_OFFLOAD_ALL;
+	uint64_t rss_hf = rss_conf->rss_hf & vf->adapter->flow_types_msk;
 	uint64_t hena;
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	if (!(hena & ((hw->mac.type == I40E_MAC_X722)
-		 ? I40E_RSS_HENA_ALL_X722
-		 : I40E_RSS_HENA_ALL))) { /* RSS disabled */
+
+	if (!(hena & vf->adapter->pctypes_msk)) { /* RSS disabled */
 		if (rss_hf != 0) /* Enable RSS */
 			return -EINVAL;
 		return 0;
@@ -2536,7 +2522,7 @@  i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 
 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(0));
 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_VFQF_HENA(1))) << 32;
-	rss_conf->rss_hf = i40e_parse_hena(hena);
+	rss_conf->rss_hf = i40e_parse_hena(hena, vf->adapter);
 
 	return 0;
 }
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 8013add..fbee050 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -344,15 +344,10 @@  i40e_init_flx_pld(struct i40e_pf *pf)
 	/* initialize the masks */
 	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
 	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722(
-				 (enum i40e_filter_pctype)pctype))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE(
-				 (enum i40e_filter_pctype)pctype))
-				continue;
-		}
+		uint16_t flow_type = i40e_pctype_to_flowtype(pctype, pf->adapter);
+
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
 		pf->fdir.flex_mask[pctype].word_mask = 0;
 		i40e_write_rx_ctl(hw, I40E_PRTQF_FD_FLXINSET(pctype), 0);
 		for (i = 0; i < I40E_FDIR_BITMASK_NUM_WORD; i++) {
@@ -449,7 +444,8 @@  i40e_check_fdir_flex_payload(const struct rte_eth_flex_payload_cfg *flex_cfg)
  * arguments are valid
  */
 static int
-i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
+i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf,
+			  struct i40e_adapter *adapter)
 {
 	const struct rte_eth_flex_payload_cfg *flex_cfg;
 	const struct rte_eth_fdir_flex_mask *flex_mask;
@@ -486,8 +482,11 @@  i40e_check_fdir_flex_conf(const struct rte_eth_fdir_flex_conf *conf)
 		return -EINVAL;
 	}
 	for (i = 0; i < conf->nb_flexmasks; i++) {
+		enum i40e_filter_pctype pctype;
+
 		flex_mask = &conf->flex_mask[i];
-		if (!I40E_VALID_FLOW(flex_mask->flow_type)) {
+		pctype = i40e_flowtype_to_pctype(flex_mask->flow_type, adapter);
+		if (!pctype) {
 			PMD_DRV_LOG(WARNING, "invalid flow type.");
 			return -EINVAL;
 		}
@@ -650,7 +649,7 @@  i40e_fdir_configure(struct rte_eth_dev *dev)
 	i40e_init_flx_pld(pf); /* set flex config to default value */
 
 	conf = &dev->data->dev_conf.fdir_conf.flex_conf;
-	ret = i40e_check_fdir_flex_conf(conf);
+	ret = i40e_check_fdir_flex_conf(conf, pf->adapter);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, " invalid configuration arguments.");
 		return -EINVAL;
@@ -665,10 +664,10 @@  i40e_fdir_configure(struct rte_eth_dev *dev)
 			pctype = (enum i40e_filter_pctype)i40e_read_rx_ctl(
 				hw, I40E_GLQF_FD_PCTYPES(
 				(int)i40e_flowtype_to_pctype(
-				conf->flex_mask[i].flow_type)));
+				conf->flex_mask[i].flow_type, pf->adapter)));
 		} else
 			pctype = i40e_flowtype_to_pctype(
-				conf->flex_mask[i].flow_type);
+				conf->flex_mask[i].flow_type, pf->adapter);
 
 		i40e_set_flex_mask_on_pctype(pf, pctype, &conf->flex_mask[i]);
 	}
@@ -1100,7 +1099,8 @@  i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
 		return -ENOTSUP;
 	}
 
-	if (!I40E_VALID_FLOW(filter->input.flow_type)) {
+	pctype = i40e_flowtype_to_pctype(filter->input.flow_type, pf->adapter);
+	if (!pctype) {
 		PMD_DRV_LOG(ERR, "invalid flow_type input.");
 		return -EINVAL;
 	}
@@ -1141,12 +1141,8 @@  i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
 	if (hw->mac.type == I40E_MAC_X722) {
 		/* get translated pctype value in fd pctype register */
 		pctype = (enum i40e_filter_pctype)i40e_read_rx_ctl(
-			hw, I40E_GLQF_FD_PCTYPES(
-			(int)i40e_flowtype_to_pctype(
-			filter->input.flow_type)));
-	} else
-		pctype = i40e_flowtype_to_pctype(filter->input.flow_type);
-
+			hw, I40E_GLQF_FD_PCTYPES((int)pctype));
+	}
 	ret = i40e_fdir_filter_programming(pf, pctype, filter, add);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "fdir programming fails for PCTYPE(%u).",
@@ -1384,7 +1380,6 @@  i40e_fdir_info_get_flex_mask(struct i40e_pf *pf,
 {
 	struct i40e_fdir_flex_mask *mask;
 	struct rte_eth_fdir_flex_mask *ptr = flex_mask;
-	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	uint16_t flow_type;
 	uint8_t i, j;
 	uint16_t off_bytes, mask_tmp;
@@ -1393,14 +1388,10 @@  i40e_fdir_info_get_flex_mask(struct i40e_pf *pf,
 	     i <= I40E_FILTER_PCTYPE_L2_PAYLOAD;
 	     i++) {
 		mask =  &pf->fdir.flex_mask[i];
-		if (hw->mac.type == I40E_MAC_X722) {
-			if (!I40E_VALID_PCTYPE_X722((enum i40e_filter_pctype)i))
-				continue;
-		} else {
-			if (!I40E_VALID_PCTYPE((enum i40e_filter_pctype)i))
-				continue;
-		}
-		flow_type = i40e_pctype_to_flowtype((enum i40e_filter_pctype)i);
+		flow_type = i40e_pctype_to_flowtype(i, pf->adapter);
+		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
+			continue;
+
 		for (j = 0; j < I40E_FDIR_MAX_FLEXWORD_NUM; j++) {
 			if (mask->word_mask & I40E_FLEX_WORD_MASK(j)) {
 				ptr->mask[j * sizeof(uint16_t)] = UINT8_MAX;
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index b92719a..4db771c 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -2776,7 +2776,7 @@  i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 		}
 	}
 
-	pctype = i40e_flowtype_to_pctype(flow_type);
+	pctype = i40e_flowtype_to_pctype(flow_type, pf->adapter);
 	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
 		rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ITEM, item,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index d42c23c..5e75567 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -2941,6 +2941,63 @@  i40e_set_default_ptype_table(struct rte_eth_dev *dev)
 		ad->ptype_tbl[i] = i40e_get_default_pkt_type(i);
 }
 
+void __attribute__((cold))
+i40e_set_default_pctype_table(struct rte_eth_dev *dev)
+{
+	struct i40e_adapter *ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int i;
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++)
+		ad->pcypes_tbl[i] = 0ULL;
+	ad->flow_types_msk = 0ULL;
+	ad->pctypes_msk = 0ULL;
+
+	ad->pcypes_tbl[RTE_ETH_FLOW_FRAG_IPV4] =
+				(1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_SCTP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_OTHER] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
+	ad->pcypes_tbl[RTE_ETH_FLOW_FRAG_IPV6] =
+				(1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_SCTP] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP);
+	ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] =
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
+	ad->pcypes_tbl[RTE_ETH_FLOW_L2_PAYLOAD] =
+				(1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD);
+
+	if (hw->mac.type == I40E_MAC_X722) {
+		ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP);
+		ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
+		ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
+		ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP);
+		ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_UDP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
+		ad->pcypes_tbl[RTE_ETH_FLOW_NONFRAG_IPV6_TCP] |=
+				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
+	}
+
+	for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
+		if (ad->pcypes_tbl[i])
+			ad->flow_types_msk |= (1ULL << i);
+		ad->pctypes_msk |= ad->pcypes_tbl[i];
+	}
+}
+
 /* Stubs needed for linkage when CONFIG_RTE_I40E_INC_VECTOR is set to 'n' */
 int __attribute__((weak))
 i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev __rte_unused *dev)
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 20084d6..2a58ced 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -255,6 +255,7 @@  void i40e_set_tx_function_flag(struct rte_eth_dev *dev,
 			       struct i40e_tx_queue *txq);
 void i40e_set_tx_function(struct rte_eth_dev *dev);
 void i40e_set_default_ptype_table(struct rte_eth_dev *dev);
+void i40e_set_default_pctype_table(struct rte_eth_dev *dev);
 
 /* For each value it means, datasheet of hardware can tell more details
  *