From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <andrey.chilikin@intel.com>
Received: from mga03.intel.com (mga03.intel.com [134.134.136.65])
 by dpdk.org (Postfix) with ESMTP id 958D25A9B
 for <dev@dpdk.org>; Wed, 20 Jan 2016 21:07:03 +0100 (CET)
Received: from fmsmga001.fm.intel.com ([10.253.24.23])
 by orsmga103.jf.intel.com with ESMTP; 20 Jan 2016 12:07:02 -0800
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.22,322,1449561600"; d="scan'208";a="885753856"
Received: from irsmsx101.ger.corp.intel.com ([163.33.3.153])
 by fmsmga001.fm.intel.com with ESMTP; 20 Jan 2016 12:06:53 -0800
Received: from irsmsx106.ger.corp.intel.com ([169.254.8.197]) by
 IRSMSX101.ger.corp.intel.com ([169.254.1.113]) with mapi id 14.03.0248.002;
 Wed, 20 Jan 2016 20:04:36 +0000
From: "Chilikin, Andrey" <andrey.chilikin@intel.com>
To: "Wu, Jingjing" <jingjing.wu@intel.com>, "dev@dpdk.org" <dev@dpdk.org>
Thread-Topic: [PATCH 2/4] i40e: split function for input set change of hash
 and fdir
Thread-Index: AQHRPu6F/dFGp1Zbck+kJ2qjwi2lj58E+nPg
Date: Wed, 20 Jan 2016 20:04:35 +0000
Message-ID: <AAC06825A3B29643AF5372F5E0DDF05364389E35@IRSMSX106.ger.corp.intel.com>
References: <1451032200-24973-1-git-send-email-jingjing.wu@intel.com>
 <1451032200-24973-3-git-send-email-jingjing.wu@intel.com>
In-Reply-To: <1451032200-24973-3-git-send-email-jingjing.wu@intel.com>
Accept-Language: en-GB, en-US
Content-Language: en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
x-originating-ip: [163.33.239.181]
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
Subject: Re: [dpdk-dev] [PATCH 2/4] i40e: split function for input set
 change of hash and fdir
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: patches and discussions about DPDK <dev.dpdk.org>
List-Unsubscribe: <http://dpdk.org/ml/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://dpdk.org/ml/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <http://dpdk.org/ml/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Wed, 20 Jan 2016 20:07:04 -0000

Hi Jingjing,

As I can see this patch not only splits fdir functionality from common fdir=
/hash code but also removes compatibility with DPDK 2.2 as it deletes I40E_=
INSET_FLEX_PAYLOAD from valid fdir input set values. Yes, flexible payload =
configuration can be set for fdir separately at the port initialization, bu=
t this is more legacy from the previous generations of NICs which did not s=
upport dynamic input set configuration. I believe it would better to have I=
40E_INSET_FLEX_PAYLOAD valid for fdir input set same as in DPDK 2.2. So in =
legacy mode, when application has to run on an old NIC and on a new one, on=
ly legacy configuration would be used, but for applications targeting new H=
W single point of configuration would be used instead of mix of two.

Regards,
Andrey

> -----Original Message-----
> From: Wu, Jingjing
> Sent: Friday, December 25, 2015 8:30 AM
> To: dev@dpdk.org
> Cc: Wu, Jingjing; Zhang, Helin; Chilikin, Andrey; Pei, Yulong
> Subject: [PATCH 2/4] i40e: split function for input set change of hash an=
d fdir
>=20
> This patch splited function for input set change of hash and fdir, and ad=
ded a
> new function to set the input set to default when initialization.
>=20
> Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> ---
>  drivers/net/i40e/i40e_ethdev.c | 330 +++++++++++++++++++++--------------=
------
>  drivers/net/i40e/i40e_ethdev.h |  11 +-
>  drivers/net/i40e/i40e_fdir.c   |   5 +-
>  3 files changed, 180 insertions(+), 166 deletions(-)
>=20
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethde=
v.c
> index bf6220d..b919aac 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -262,7 +262,8 @@
>  #define I40E_REG_INSET_FLEX_PAYLOAD_WORD7
> 0x0000000000000080ULL
>  /* 8th word of flex payload */
>  #define I40E_REG_INSET_FLEX_PAYLOAD_WORD8
> 0x0000000000000040ULL
> -
> +/* all 8 words flex payload */
> +#define I40E_REG_INSET_FLEX_PAYLOAD_WORDS
> 0x0000000000003FC0ULL
>  #define I40E_REG_INSET_MASK_DEFAULT              0x0000000000000000ULL
>=20
>  #define I40E_TRANSLATE_INSET 0
> @@ -373,6 +374,7 @@ static int i40e_dev_udp_tunnel_add(struct rte_eth_dev
> *dev,
>  				struct rte_eth_udp_tunnel *udp_tunnel);  static
> int i40e_dev_udp_tunnel_del(struct rte_eth_dev *dev,
>  				struct rte_eth_udp_tunnel *udp_tunnel);
> +static void i40e_filter_input_set_init(struct i40e_pf *pf);
>  static int i40e_ethertype_filter_set(struct i40e_pf *pf,
>  			struct rte_eth_ethertype_filter *filter,
>  			bool add);
> @@ -787,6 +789,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
>  	 * It should be removed once issues are fixed in NVM.
>  	 */
>  	i40e_flex_payload_reg_init(hw);
> +	/* Initialize the input set for filters (hash and fd) to default value =
*/
> +	i40e_filter_input_set_init(pf);
>=20
>  	/* Initialize the parameters for adminq */
>  	i40e_init_adminq_parameter(hw);
> @@ -6545,43 +6549,32 @@ i40e_get_valid_input_set(enum i40e_filter_pctype
> pctype,
>  	 */
>  	static const uint64_t valid_fdir_inset_table[] =3D {
>  		[I40E_FILTER_PCTYPE_FRAG_IPV4] =3D
> -		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
>  		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =3D
>  		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
> -		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
>  		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =3D
> -		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
> -		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
>  		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =3D
>  		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
>  		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
> -		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_SCTP_VT,
>  		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =3D
> -		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
>  		[I40E_FILTER_PCTYPE_FRAG_IPV6] =3D
> -		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
>  		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =3D
> -		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
> -		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
>  		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =3D
> -		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
> -		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
>  		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =3D
>  		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
>  		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
> -		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_SCTP_VT,
>  		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =3D
> -		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
>  		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =3D
> -		I40E_INSET_LAST_ETHER_TYPE | I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_LAST_ETHER_TYPE,
>  	};
>=20
>  	if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) @@ -6809,7 +6802,7
> @@ i40e_translate_input_set_reg(uint64_t input)
>  	return val;
>  }
>=20
> -static uint8_t
> +static int
>  i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t
> nb_elem)  {
>  	uint8_t i, idx =3D 0;
> @@ -6827,16 +6820,13 @@ i40e_generate_inset_mask_reg(uint64_t inset,
> uint32_t *mask, uint8_t nb_elem)
>  	if (!inset || !mask || !nb_elem)
>  		return 0;
>=20
> -	if (!inset && nb_elem >=3D I40E_INSET_MASK_NUM_REG) {
> -		for (i =3D 0; i < I40E_INSET_MASK_NUM_REG; i++)
> -			mask[i] =3D 0;
> -		return I40E_INSET_MASK_NUM_REG;
> -	}
>=20
>  	for (i =3D 0, idx =3D 0; i < RTE_DIM(inset_mask_map); i++) {
> -		if (idx >=3D nb_elem)
> -			break;
> -		if (inset & inset_mask_map[i].inset) {
> +		if ((inset & inset_mask_map[i].inset) =3D=3D
> inset_mask_map[i].inset) {
> +			if (idx >=3D nb_elem) {
> +				PMD_DRV_LOG(ERR, "exceed maximal
> number of bitmasks");
> +				return -EINVAL;
> +			}
>  			mask[idx] =3D inset_mask_map[i].mask;
>  			idx++;
>  		}
> @@ -6845,25 +6835,6 @@ i40e_generate_inset_mask_reg(uint64_t inset,
> uint32_t *mask, uint8_t nb_elem)
>  	return idx;
>  }
>=20
> -static uint64_t
> -i40e_get_reg_inset(struct i40e_hw *hw, enum rte_filter_type filter,
> -			    enum i40e_filter_pctype pctype)
> -{
> -	uint64_t reg =3D 0;
> -
> -	if (filter =3D=3D RTE_ETH_FILTER_HASH) {
> -		reg =3D I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(1,
> pctype));
> -		reg <<=3D I40E_32_BIT_WIDTH;
> -		reg |=3D I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(0,
> pctype));
> -	} else if (filter =3D=3D RTE_ETH_FILTER_FDIR) {
> -		reg =3D I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 1));
> -		reg <<=3D I40E_32_BIT_WIDTH;
> -		reg |=3D I40E_READ_REG(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)  {=
 @@
> -6876,103 +6847,149 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t
> addr, uint32_t val)
>  		    (uint32_t)I40E_READ_REG(hw, addr));  }
>=20
> -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)
> +static void
> +i40e_filter_input_set_init(struct i40e_pf *pf)
>  {
> -	uint32_t reg;
> -	uint8_t i;
> +	struct i40e_hw *hw =3D I40E_PF_TO_HW(pf);
> +	enum i40e_filter_pctype pctype;
> +	uint64_t input_set, inset_reg;
> +	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] =3D {0};
> +	int num, i;
>=20
> -	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
> -		return -EINVAL;
> +	for (pctype =3D I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
> +	     pctype <=3D I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
> +		if (!I40E_VALID_PCTYPE(pctype))
> +			continue;
> +		input_set =3D i40e_get_default_input_set(pctype);
>=20
> -	if (op =3D=3D RTE_ETH_INPUT_SET_SELECT) {
> -		for (i =3D 0; i < I40E_INSET_MASK_NUM_REG; i++) {
> -			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i,
> pctype),
> -					     0);
> -			if (i >=3D num)
> -				continue;
> +		num =3D i40e_generate_inset_mask_reg(input_set, mask_reg,
> +
> I40E_INSET_MASK_NUM_REG);
> +		if (num < 0)
> +			return;
> +		inset_reg =3D 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));
> +		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 =3D 0; i < num; i++) {
> +			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i,
> pctype),
> +					     mask_reg[i]);
>  			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i,
> pctype),
>  					     mask_reg[i]);
>  		}
> -	} else if (op =3D=3D RTE_ETH_INPUT_SET_ADD) {
> -		uint8_t j, count =3D 0;
> -
> -		for (i =3D 0; i < I40E_INSET_MASK_NUM_REG; i++) {
> -			reg =3D I40E_READ_REG(hw, I40E_GLQF_HASH_MSK(i,
> pctype));
> -			if (reg & I40E_GLQF_HASH_MSK_FIELD)
> -				count++;
> +		/*clear unused mask registers of the pctype */
> +		for (i =3D num; i < I40E_INSET_MASK_NUM_REG; i++) {
> +			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i,
> pctype),
> +					     0);
> +			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i,
> pctype),
> +					     0);
>  		}
> -		if (count + num > I40E_INSET_MASK_NUM_REG)
> -			return -EINVAL;
> +		I40E_WRITE_FLUSH(hw);
>=20
> -		for (i =3D count, j =3D 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
> -			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i,
> pctype),
> -					     mask_reg[j]);
> +		/* store the default input set */
> +		pf->hash_input_set[pctype] =3D input_set;
> +		pf->fdir.input_set[pctype] =3D input_set;
>  	}
> -
> -	return 0;
>  }
>=20
> -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)
> +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 =3D &((struct i40e_adapter *)hw->back)->pf;
> +	enum i40e_filter_pctype pctype;
> +	uint64_t input_set, inset_reg =3D 0;
> +	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] =3D {0};
> +	int ret, i, num;
>=20
> -	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
> +	if (!hw || !conf) {
> +		PMD_DRV_LOG(ERR, "Invalid pointer");
> +		return -EFAULT;
> +	}
> +	if (conf->op !=3D RTE_ETH_INPUT_SET_SELECT &&
> +	    conf->op !=3D RTE_ETH_INPUT_SET_ADD) {
> +		PMD_DRV_LOG(ERR, "Unsupported input set operation");
>  		return -EINVAL;
> +	}
>=20
> -	if (op =3D=3D RTE_ETH_INPUT_SET_SELECT) {
> -		for (i =3D 0; i < I40E_INSET_MASK_NUM_REG; i++) {
> -			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i,
> pctype),
> -					     0);
> -			if (i >=3D num)
> -				continue;
> -			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i,
> pctype),
> -					     mask_reg[i]);
> -		}
> -	} else if (op =3D=3D RTE_ETH_INPUT_SET_ADD) {
> -		uint8_t j, count =3D 0;
> -
> -		for (i =3D 0; i < I40E_INSET_MASK_NUM_REG; i++) {
> -			reg =3D I40E_READ_REG(hw, I40E_GLQF_FD_MSK(i,
> pctype));
> -			if (reg & I40E_GLQF_FD_MSK_FIELD)
> -				count++;
> -		}
> -		if (count + num > I40E_INSET_MASK_NUM_REG)
> -			return -EINVAL;
> +	pctype =3D i40e_flowtype_to_pctype(conf->flow_type);
> +	if (pctype =3D=3D 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
> +		PMD_DRV_LOG(ERR, "Not supported flow type (%u)",
> +			    conf->flow_type);
> +		return -EINVAL;
> +	}
>=20
> -		for (i =3D count, j =3D 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
> -			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i,
> pctype),
> -					     mask_reg[j]);
> +	ret =3D 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) !=3D 0) {
> +		PMD_DRV_LOG(ERR, "Invalid input set");
> +		return -EINVAL;
> +	}
> +	if (conf->op =3D=3D RTE_ETH_INPUT_SET_ADD) {
> +		/* get inset value in register */
> +		inset_reg =3D I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(1,
> pctype));
> +		inset_reg <<=3D I40E_32_BIT_WIDTH;
> +		inset_reg |=3D I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(0,
> pctype));
> +		input_set |=3D pf->hash_input_set[pctype];
> +	}
> +	num =3D i40e_generate_inset_mask_reg(input_set, mask_reg,
> +					   I40E_INSET_MASK_NUM_REG);
> +	if (num < 0)
> +		return -EINVAL;
> +
> +	inset_reg |=3D i40e_translate_input_set_reg(input_set);
>=20
> +	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 =3D 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 =3D 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] =3D input_set;
>  	return 0;
>  }
>=20
>  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 =3D I40E_PF_TO_HW(pf);
>  	enum i40e_filter_pctype pctype;
> -	uint64_t inset_reg =3D 0, input_set;
> -	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG];
> -	uint8_t num;
> -	int ret;
> +	uint64_t input_set, inset_reg =3D 0;
> +	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] =3D {0};
> +	int ret, i, num;
>=20
>  	if (!hw || !conf) {
>  		PMD_DRV_LOG(ERR, "Invalid pointer");
>  		return -EFAULT;
>  	}
> +	if (conf->op !=3D RTE_ETH_INPUT_SET_SELECT &&
> +	    conf->op !=3D RTE_ETH_INPUT_SET_ADD) {
> +		PMD_DRV_LOG(ERR, "Unsupported input set operation");
> +		return -EINVAL;
> +	}
>=20
>  	pctype =3D i40e_flowtype_to_pctype(conf->flow_type);
>  	if (pctype =3D=3D 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) { @@ -
> 6980,60 +6997,54 @@ i40e_filter_inset_select(struct i40e_hw *hw,
>  			    conf->flow_type);
>  		return -EINVAL;
>  	}
> -	if (filter !=3D RTE_ETH_FILTER_HASH && filter !=3D RTE_ETH_FILTER_FDIR)
> {
> -		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
> -		return -EINVAL;
> -	}
> -
>  	ret =3D 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) !=3D 0) {
> +	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
> +				    input_set) !=3D 0) {
>  		PMD_DRV_LOG(ERR, "Invalid input set");
>  		return -EINVAL;
>  	}
>=20
> -	if (conf->op =3D=3D RTE_ETH_INPUT_SET_ADD) {
> -		inset_reg |=3D i40e_get_reg_inset(hw, filter, pctype);
> -	} else if (conf->op !=3D RTE_ETH_INPUT_SET_SELECT) {
> -		PMD_DRV_LOG(ERR, "Unsupported input set operation");
> -		return -EINVAL;
> -	}
> +	/* get inset value in register */
> +	inset_reg =3D I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 1));
> +	inset_reg <<=3D I40E_32_BIT_WIDTH;
> +	inset_reg |=3D I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 0));
> +
> +	/*Can not change the inset reg for flex payload for fdir,
> +	 * it is done by writing I40E_PRTQF_FD_FLXINSET
> +	 * in i40e_set_flex_mask_on_pctype.
> +	 */
> +	if (conf->op =3D=3D RTE_ETH_INPUT_SET_SELECT)
> +		inset_reg &=3D I40E_REG_INSET_FLEX_PAYLOAD_WORDS;
> +	else
> +		input_set |=3D pf->fdir.input_set[pctype];
>  	num =3D i40e_generate_inset_mask_reg(input_set, mask_reg,
>  					   I40E_INSET_MASK_NUM_REG);
> -	inset_reg |=3D i40e_translate_input_set_reg(input_set);
> -
> -	if (filter =3D=3D RTE_ETH_FILTER_HASH) {
> -		ret =3D i40e_set_hash_inset_mask(hw, pctype, conf->op,
> mask_reg,
> -					       num);
> -		if (ret)
> -			return -EINVAL;
> +	if (num < 0)
> +		return -EINVAL;
>=20
> -		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 =3D=3D RTE_ETH_FILTER_FDIR) {
> -		ret =3D i40e_set_fd_inset_mask(hw, pctype, conf->op, mask_reg,
> -					     num);
> -		if (ret)
> -			return -EINVAL;
> +	inset_reg |=3D i40e_translate_input_set_reg(input_set);
>=20
> -		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 =3D 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 =3D num; i < I40E_INSET_MASK_NUM_REG; i++)
> +		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
> +				     0);
>  	I40E_WRITE_FLUSH(hw);
>=20
> +	pf->fdir.input_set[pctype] =3D input_set;
>  	return 0;
>  }
>=20
> @@ -7085,9 +7096,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 =3D i40e_filter_inset_select(hw,
> -					       &(info->info.input_set_conf),
> -					       RTE_ETH_FILTER_HASH);
> +		ret =3D i40e_hash_filter_inset_select(hw,
> +					       &(info->info.input_set_conf));
>  		break;
>=20
>  	default:
> diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethde=
v.h
> index 1f9792b..4dc7e1e 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -361,6 +361,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 @@ -
> 427,6 +429,8 @@ struct i40e_pf {
>  	uint16_t fdir_qp_offset;
>=20
>  	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 */ @@ -569,9 +573,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);
>=20
>  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
> 9ad6981..155a34a 100644
> --- a/drivers/net/i40e/i40e_fdir.c
> +++ b/drivers/net/i40e/i40e_fdir.c
> @@ -1361,7 +1361,6 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
>  		     struct rte_eth_fdir_filter_info *info)  {
>  	struct i40e_pf *pf =3D I40E_DEV_PRIVATE_TO_PF(dev->data-
> >dev_private);
> -	struct i40e_hw *hw =3D I40E_PF_TO_HW(pf);
>  	int ret =3D 0;
>=20
>  	if (!info) {
> @@ -1371,8 +1370,8 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
>=20
>  	switch (info->info_type) {
>  	case RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT:
> -		ret =3D i40e_filter_inset_select(hw,
> -			&(info->info.input_set_conf), RTE_ETH_FILTER_FDIR);
> +		ret =3D i40e_fdir_filter_inset_select(pf,
> +				&(info->info.input_set_conf));
>  		break;
>  	default:
>  		PMD_DRV_LOG(ERR, "FD filter info type (%d) not supported",
> --
> 2.4.0