From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <helin.zhang@intel.com>
Received: from mga11.intel.com (mga11.intel.com [192.55.52.93])
 by dpdk.org (Postfix) with ESMTP id DD6B158E6
 for <dev@dpdk.org>; Tue, 14 Oct 2014 02:35:12 +0200 (CEST)
Received: from fmsmga003.fm.intel.com ([10.253.24.29])
 by fmsmga102.fm.intel.com with ESMTP; 13 Oct 2014 17:42:53 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="4.97,862,1389772800"; d="scan'208";a="399713957"
Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203])
 by FMSMGA003.fm.intel.com with ESMTP; 13 Oct 2014 17:35:45 -0700
Received: from fmsmsx115.amr.corp.intel.com (10.18.116.19) by
 FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS)
 id 14.3.195.1; Mon, 13 Oct 2014 17:42:53 -0700
Received: from shsmsx102.ccr.corp.intel.com (10.239.4.154) by
 fmsmsx115.amr.corp.intel.com (10.18.116.19) with Microsoft SMTP Server (TLS)
 id 14.3.195.1; Mon, 13 Oct 2014 17:42:52 -0700
Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.230]) by
 shsmsx102.ccr.corp.intel.com ([169.254.2.192]) with mapi id 14.03.0195.001;
 Tue, 14 Oct 2014 08:42:51 +0800
From: "Zhang, Helin" <helin.zhang@intel.com>
To: "Chilikin, Andrey" <andrey.chilikin@intel.com>, "dev@dpdk.org"
 <dev@dpdk.org>
Thread-Topic: [dpdk-dev] [PATCH v4 4/7] i40e: add hash filter control
 implementation
Thread-Index: AQHP5qzu1udpDUr+skq3cycj50ibe5wtzlyggADzHmA=
Date: Tue, 14 Oct 2014 00:42:50 +0000
Message-ID: <F35DEAC7BCE34641BA9FAC6BCA4A12E70A79BC7D@SHSMSX104.ccr.corp.intel.com>
References: <1412058028-10971-2-git-send-email-helin.zhang@intel.com>
 <1413180766-12211-1-git-send-email-helin.zhang@intel.com>
 <1413180766-12211-5-git-send-email-helin.zhang@intel.com>
 <AAC06825A3B29643AF5372F5E0DDF05334FFD7C5@IRSMSX106.ger.corp.intel.com>
In-Reply-To: <AAC06825A3B29643AF5372F5E0DDF05334FFD7C5@IRSMSX106.ger.corp.intel.com>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
x-originating-ip: [10.239.127.40]
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
Subject: Re: [dpdk-dev] [PATCH v4 4/7] i40e: add hash filter
	control	implementation
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: Tue, 14 Oct 2014 00:35:14 -0000

Hi Andrey

Yes, you are right. Actually I tried to rename those macros to more readabl=
e. For now, I'd like to put those renaming into another patches after all c=
urrent feature patches merged. Thank you very much!

Regards,
Helin

> -----Original Message-----
> From: Chilikin, Andrey
> Sent: Monday, October 13, 2014 6:23 PM
> To: Zhang, Helin; dev@dpdk.org
> Subject: RE: [dpdk-dev] [PATCH v4 4/7] i40e: add hash filter control
> implementation
>=20
> Hi Helin,
>=20
> Should we define packet classification types separately and do not reuse =
bit
> shifts for RSS register as pctypes?
> Packet classification is a global index table which used by RSS Hash Enab=
le
> registers, not vice versa.
> For example, there is no Packet classification named
> "ETH_RSS_NONF_IPV4_UDP_SHIFT" in Table 7-15 of XL710 Datasheet,  it is
> "PCTYPE_NONF_IPV4_UDP", so
>=20
> switch (info->pctype) {
> 	case PCTYPE_NONF_IPV4_UDP:
> 	case PCTYPE_NONF_IPV4_TCP:
> 	...
> Is more clean and readable for me than
>=20
> switch (info->pctype) {
> 	case ETH_RSS_NONF_IPV4_UDP_SHIFT:
> 	case ETH_RSS_NONF_IPV4_TCP_SHIFT:
>=20
> We can rerefine ETH_RSS_* using PCTYPE_* though:
>=20
> #define ETH_RSS_NONF_IPV4_UDP_SHIFT PCTYPE_NONF_IPV4_UDP and so
> one
>=20
> Regards,
> Andrey
>=20
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Helin Zhang
> Sent: Monday, October 13, 2014 7:13 AM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v4 4/7] i40e: add hash filter control implemen=
tation
>=20
> Hash filter control has been implemented for i40e. It includes getting/se=
tting
> - hash function type
> - symmetric hash enable per pctype (packet classification type)
> - symmetric hash enable per port
> - filter swap configuration
>=20
> Signed-off-by: Helin Zhang <helin.zhang@intel.com>
> ---
>  lib/librte_pmd_i40e/i40e_ethdev.c | 402
> ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 402 insertions(+)
>=20
> diff --git a/lib/librte_pmd_i40e/i40e_ethdev.c
> b/lib/librte_pmd_i40e/i40e_ethdev.c
> index 46c43a7..60b619b 100644
> --- a/lib/librte_pmd_i40e/i40e_ethdev.c
> +++ b/lib/librte_pmd_i40e/i40e_ethdev.c
> @@ -216,6 +216,10 @@ static int i40e_dev_rss_hash_update(struct
> rte_eth_dev *dev,
>  				    struct rte_eth_rss_conf *rss_conf);  static int
> i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
>  				      struct rte_eth_rss_conf *rss_conf);
> +static int i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
> +				enum rte_filter_type filter_type,
> +				enum rte_filter_op filter_op,
> +				void *arg);
>=20
>  /* Default hash key buffer for RSS */
>  static uint32_t rss_key_default[I40E_PFQF_HKEY_MAX_INDEX + 1]; @@
> -267,6 +271,7 @@ static struct eth_dev_ops i40e_eth_dev_ops =3D {
>  	.reta_query                   =3D i40e_dev_rss_reta_query,
>  	.rss_hash_update              =3D i40e_dev_rss_hash_update,
>  	.rss_hash_conf_get            =3D i40e_dev_rss_hash_conf_get,
> +	.filter_ctrl                  =3D i40e_dev_filter_ctrl,
>  };
>=20
>  static struct eth_driver rte_i40e_pmd =3D { @@ -4162,3 +4167,400 @@
> i40e_pf_config_mq_rx(struct i40e_pf *pf)
>=20
>  	return 0;
>  }
> +
> +/* Get the symmetric hash enable configurations per PCTYPE */ static
> +int i40e_get_symmetric_hash_enable_per_pctype(struct i40e_hw *hw,
> +			struct rte_eth_sym_hash_ena_info *info) {
> +	uint32_t reg;
> +
> +	switch (info->pctype) {
> +	case ETH_RSS_NONF_IPV4_UDP_SHIFT:
> +	case ETH_RSS_NONF_IPV4_TCP_SHIFT:
> +	case ETH_RSS_NONF_IPV4_SCTP_SHIFT:
> +	case ETH_RSS_NONF_IPV4_OTHER_SHIFT:
> +	case ETH_RSS_FRAG_IPV4_SHIFT:
> +	case ETH_RSS_NONF_IPV6_UDP_SHIFT:
> +	case ETH_RSS_NONF_IPV6_TCP_SHIFT:
> +	case ETH_RSS_NONF_IPV6_SCTP_SHIFT:
> +	case ETH_RSS_NONF_IPV6_OTHER_SHIFT:
> +	case ETH_RSS_FRAG_IPV6_SHIFT:
> +	case ETH_RSS_L2_PAYLOAD_SHIFT:
> +		reg =3D I40E_READ_REG(hw, I40E_GLQF_HSYM(info->pctype));
> +		info->enable =3D reg & I40E_GLQF_HSYM_SYMH_ENA_MASK ? 1 : 0;
> +		break;
> +	default:
> +		PMD_DRV_LOG(ERR, "PCTYPE[%u] not supported", info->pctype);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +/* Set the symmetric hash enable configurations per PCTYPE */ static
> +int i40e_set_symmetric_hash_enable_per_pctype(struct i40e_hw *hw,
> +		const struct rte_eth_sym_hash_ena_info *info) {
> +	uint32_t reg;
> +
> +	switch (info->pctype) {
> +	case ETH_RSS_NONF_IPV4_UDP_SHIFT:
> +	case ETH_RSS_NONF_IPV4_TCP_SHIFT:
> +	case ETH_RSS_NONF_IPV4_SCTP_SHIFT:
> +	case ETH_RSS_NONF_IPV4_OTHER_SHIFT:
> +	case ETH_RSS_FRAG_IPV4_SHIFT:
> +	case ETH_RSS_NONF_IPV6_UDP_SHIFT:
> +	case ETH_RSS_NONF_IPV6_TCP_SHIFT:
> +	case ETH_RSS_NONF_IPV6_SCTP_SHIFT:
> +	case ETH_RSS_NONF_IPV6_OTHER_SHIFT:
> +	case ETH_RSS_FRAG_IPV6_SHIFT:
> +	case ETH_RSS_L2_PAYLOAD_SHIFT:
> +		reg =3D info->enable ? I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
> +		I40E_WRITE_REG(hw, I40E_GLQF_HSYM(info->pctype), reg);
> +		I40E_WRITE_FLUSH(hw);
> +		break;
> +	default:
> +		PMD_DRV_LOG(ERR, "PCTYPE[%u] not supported", info->pctype);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +/* Get the symmetric hash enable configurations per port */ static void
> +i40e_get_symmetric_hash_enable_per_port(struct i40e_hw *hw, uint8_t
> +*enable) {
> +	uint32_t reg =3D I40E_READ_REG(hw, I40E_PRTQF_CTL_0);
> +
> +	*enable =3D reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK ? 1 : 0; }
> +
> +/* Set the symmetric hash enable configurations per port */ static void
> +i40e_set_symmetric_hash_enable_per_port(struct i40e_hw *hw, uint8_t
> +enable) {
> +	uint32_t reg =3D I40E_READ_REG(hw, I40E_PRTQF_CTL_0);
> +
> +	if (enable > 0) {
> +		if (reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK) {
> +			PMD_DRV_LOG(INFO, "Symmetric hash has already "
> +							"been enabled");
> +			return;
> +		}
> +		reg |=3D I40E_PRTQF_CTL_0_HSYM_ENA_MASK;
> +	} else {
> +		if (!(reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK)) {
> +			PMD_DRV_LOG(INFO, "Symmetric hash has already "
> +							"been disabled");
> +			return;
> +		}
> +		reg &=3D ~I40E_PRTQF_CTL_0_HSYM_ENA_MASK;
> +	}
> +	I40E_WRITE_REG(hw, I40E_PRTQF_CTL_0, reg);
> +	I40E_WRITE_FLUSH(hw);
> +}
> +
> +/* Get filter swap configurations */
> +static int
> +i40e_get_filter_swap(struct i40e_hw *hw, struct
> +rte_eth_filter_swap_info *info) {
> +	uint32_t reg;
> +
> +	switch (info->pctype) {
> +	case ETH_RSS_NONF_IPV4_UDP_SHIFT:
> +	case ETH_RSS_NONF_IPV4_TCP_SHIFT:
> +	case ETH_RSS_NONF_IPV4_SCTP_SHIFT:
> +	case ETH_RSS_NONF_IPV4_OTHER_SHIFT:
> +	case ETH_RSS_FRAG_IPV4_SHIFT:
> +	case ETH_RSS_NONF_IPV6_UDP_SHIFT:
> +	case ETH_RSS_NONF_IPV6_TCP_SHIFT:
> +	case ETH_RSS_NONF_IPV6_SCTP_SHIFT:
> +	case ETH_RSS_NONF_IPV6_OTHER_SHIFT:
> +	case ETH_RSS_FRAG_IPV6_SHIFT:
> +	case ETH_RSS_L2_PAYLOAD_SHIFT:
> +		reg =3D I40E_READ_REG(hw, I40E_GLQF_SWAP(0, info->pctype));
> +		PMD_DRV_LOG(DEBUG, "Value read from I40E_GLQF_SWAP[0,%d]: "
> +						"0x%x", info->pctype, reg);
> +
> +		/**
> +		 * The offset and length read from register in word unit,
> +		 * which need to be converted in byte unit before being saved.
> +		 */
> +		info->off0_src0 =3D
> +			(uint8_t)((reg & I40E_GLQF_SWAP_OFF0_SRC0_MASK) >>
> +					I40E_GLQF_SWAP_OFF0_SRC0_SHIFT) << 1;
> +		info->off0_src1 =3D
> +			(uint8_t)((reg & I40E_GLQF_SWAP_OFF0_SRC1_MASK) >>
> +					I40E_GLQF_SWAP_OFF0_SRC1_SHIFT) << 1;
> +		info->len0 =3D (uint8_t)((reg & I40E_GLQF_SWAP_FLEN0_MASK) >>
> +					I40E_GLQF_SWAP_FLEN0_SHIFT) << 1;
> +		info->off1_src0 =3D
> +			(uint8_t)((reg & I40E_GLQF_SWAP_OFF1_SRC0_MASK) >>
> +					I40E_GLQF_SWAP_OFF1_SRC0_SHIFT) << 1;
> +		info->off1_src1 =3D
> +			(uint8_t)((reg & I40E_GLQF_SWAP_OFF1_SRC1_MASK) >>
> +					I40E_GLQF_SWAP_OFF1_SRC1_SHIFT) << 1;
> +		info->len1 =3D (uint8_t)((reg & I40E_GLQF_SWAP_FLEN1_MASK) >>
> +					I40E_GLQF_SWAP_FLEN1_SHIFT) << 1;
> +		break;
> +	default:
> +		PMD_DRV_LOG(ERR, "PCTYPE[%u] not supported", info->pctype);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +/* Set filter swap configurations */
> +static int
> +i40e_set_filter_swap(struct i40e_hw *hw,
> +		     const struct rte_eth_filter_swap_info *info) { #define
> +I40E_FIELD_LEN_MAX 0x1f #define I40E_FIELD_OFFSET_MAX 0x7f
> +	uint32_t reg;
> +
> +	switch (info->pctype) {
> +	case ETH_RSS_NONF_IPV4_UDP_SHIFT:
> +	case ETH_RSS_NONF_IPV4_TCP_SHIFT:
> +	case ETH_RSS_NONF_IPV4_SCTP_SHIFT:
> +	case ETH_RSS_NONF_IPV4_OTHER_SHIFT:
> +	case ETH_RSS_FRAG_IPV4_SHIFT:
> +	case ETH_RSS_NONF_IPV6_UDP_SHIFT:
> +	case ETH_RSS_NONF_IPV6_TCP_SHIFT:
> +	case ETH_RSS_NONF_IPV6_SCTP_SHIFT:
> +	case ETH_RSS_NONF_IPV6_OTHER_SHIFT:
> +	case ETH_RSS_FRAG_IPV6_SHIFT:
> +	case ETH_RSS_L2_PAYLOAD_SHIFT:
> +		if (info->off0_src0 > I40E_FIELD_OFFSET_MAX) {
> +			PMD_DRV_LOG(ERR, "off0_src0 (0x%x) exceeds the "
> +				"maximum of 0x%x", info->off0_src0,
> +						I40E_FIELD_OFFSET_MAX);
> +			return I40E_ERR_PARAM;
> +		} else if (info->off0_src1 > I40E_FIELD_OFFSET_MAX) {
> +			PMD_DRV_LOG(ERR, "off0_src1 (0x%x) exceeds the "
> +				"maximum of 0x%x", info->off0_src1,
> +						I40E_FIELD_OFFSET_MAX);
> +			return I40E_ERR_PARAM;
> +		} else if (info->len0 > I40E_FIELD_LEN_MAX) {
> +			PMD_DRV_LOG(ERR, "len0 (0x%x) exceeds the maximum "
> +				"of 0x%x", info->len0, I40E_FIELD_LEN_MAX);
> +			return I40E_ERR_PARAM;
> +		} else if (info->off1_src0 > I40E_FIELD_OFFSET_MAX) {
> +			PMD_DRV_LOG(ERR, "off1_src0 (0x%x) exceeds the "
> +				"maximum of 0x%x", info->off1_src0,
> +						I40E_FIELD_OFFSET_MAX);
> +			return I40E_ERR_PARAM;
> +		} else if (info->off1_src1 > I40E_FIELD_OFFSET_MAX) {
> +			PMD_DRV_LOG(ERR, "off1_src1 (0x%x) exceeds the "
> +				"maximum of 0x%x", info->off1_src1,
> +						I40E_FIELD_OFFSET_MAX);
> +			return I40E_ERR_PARAM;
> +		} else if (info->len1 > I40E_FIELD_LEN_MAX) {
> +			PMD_DRV_LOG(ERR, "len1 (0x%x) exceeds the maximum "
> +				"of 0x%x", info->len1, I40E_FIELD_LEN_MAX);
> +			return I40E_ERR_PARAM;
> +		}
> +
> +		/**
> +		 * The offset and length given in byte unit, which need to be
> +		 * converted in word unit before being written to the register,
> +		 * as hardware requires it in word unit.
> +		 */
> +		reg =3D (info->off0_src0 >> 1) << I40E_GLQF_SWAP_OFF0_SRC0_SHIFT;
> +		reg |=3D (info->off0_src1 >> 1) <<
> +			I40E_GLQF_SWAP_OFF0_SRC1_SHIFT;
> +		reg |=3D (info->len0 >> 1) << I40E_GLQF_SWAP_FLEN0_SHIFT;
> +		reg |=3D (info->off1_src0 >> 1) <<
> +			I40E_GLQF_SWAP_OFF1_SRC0_SHIFT;
> +		reg |=3D (info->off1_src1 >> 1) <<
> +			I40E_GLQF_SWAP_OFF1_SRC1_SHIFT;
> +		reg |=3D (info->len1 >> 1) << I40E_GLQF_SWAP_FLEN1_SHIFT;
> +
> +		PMD_DRV_LOG(DEBUG, "Value to be written to "
> +			"I40E_GLQF_SWAP[0,%d]: 0x%x", info->pctype, reg);
> +		I40E_WRITE_REG(hw, I40E_GLQF_SWAP(0, info->pctype), reg);
> +		I40E_WRITE_FLUSH(hw);
> +		break;
> +	default:
> +		PMD_DRV_LOG(ERR, "PCTYPE[%u] not supported", info->pctype);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +/* Get hash function type */
> +static void
> +i40e_get_hash_function(struct i40e_hw *hw, enum rte_eth_hash_function
> +*hf) {
> +	uint32_t reg =3D I40E_READ_REG(hw, I40E_GLQF_CTL);
> +
> +	if (reg & I40E_GLQF_CTL_HTOEP_MASK)
> +		*hf =3D RTE_ETH_HASH_FUNCTION_TOEPLITZ;
> +	else
> +		*hf =3D RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
> +
> +	PMD_DRV_LOG(INFO, "Hash function is %s",
> +		(reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR"); }
> +
> +/* Set hash function type */
> +static int
> +i40e_set_hash_function(struct i40e_hw *hw, enum rte_eth_hash_function
> +hf) {
> +	uint32_t reg =3D I40E_READ_REG(hw, I40E_GLQF_CTL);
> +
> +	if (hf =3D=3D RTE_ETH_HASH_FUNCTION_TOEPLITZ) {
> +		if (reg & I40E_GLQF_CTL_HTOEP_MASK) {
> +			PMD_DRV_LOG(DEBUG, "Hash function already set to "
> +								"Toeplitz");
> +			return 0;
> +		}
> +		reg |=3D I40E_GLQF_CTL_HTOEP_MASK;
> +	} else if (hf =3D=3D RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
> +		if (!(reg & I40E_GLQF_CTL_HTOEP_MASK)) {
> +			PMD_DRV_LOG(DEBUG, "Hash function already set to "
> +							"Simple XOR");
> +			return 0;
> +		}
> +		reg &=3D ~I40E_GLQF_CTL_HTOEP_MASK;
> +	} else {
> +		PMD_DRV_LOG(ERR, "Unknown hash function type");
> +		return -EINVAL;
> +	}
> +
> +	PMD_DRV_LOG(INFO, "Hash function set to %s",
> +		(reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR");
> +	I40E_WRITE_REG(hw, I40E_GLQF_CTL, reg);
> +	I40E_WRITE_FLUSH(hw);
> +
> +	return 0;
> +}
> +
> +static int
> +i40e_hash_filter_get(struct i40e_hw *hw, struct
> +rte_eth_hash_filter_info *info) {
> +	int ret =3D 0;
> +
> +	if (!hw || !info) {
> +		PMD_DRV_LOG(ERR, "Invalid pointer");
> +		return -EFAULT;
> +	}
> +
> +	switch (info->info_type) {
> +	case RTE_ETH_HASH_FILTER_INFO_TYPE_SYM_HASH_ENA_PER_PCTYPE:
> +		ret =3D i40e_get_symmetric_hash_enable_per_pctype(hw,
> +					&(info->info.sym_hash_ena));
> +		break;
> +	case RTE_ETH_HASH_FILTER_INFO_TYPE_SYM_HASH_ENA_PER_PORT:
> +		i40e_get_symmetric_hash_enable_per_port(hw,
> +					&(info->info.enable));
> +		break;
> +	case RTE_ETH_HASH_FILTER_INFO_TYPE_FILTER_SWAP:
> +		ret =3D i40e_get_filter_swap(hw, &(info->info.filter_swap));
> +		break;
> +	case RTE_ETH_HASH_FILTER_INFO_TYPE_HASH_FUNCTION:
> +		i40e_get_hash_function(hw, &(info->info.hash_function));
> +		break;
> +	default:
> +		PMD_DRV_LOG(ERR, "Hash filter info type (%d) not supported",
> +							info->info_type);
> +		ret =3D -EINVAL;
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static int
> +i40e_hash_filter_set(struct i40e_hw *hw, struct
> +rte_eth_hash_filter_info *info) {
> +	int ret =3D 0;
> +
> +	if (!hw || !info) {
> +		PMD_DRV_LOG(ERR, "Invalid pointer");
> +		return -EFAULT;
> +	}
> +
> +	switch (info->info_type) {
> +	case RTE_ETH_HASH_FILTER_INFO_TYPE_SYM_HASH_ENA_PER_PCTYPE:
> +		ret =3D i40e_set_symmetric_hash_enable_per_pctype(hw,
> +					&(info->info.sym_hash_ena));
> +		break;
> +	case RTE_ETH_HASH_FILTER_INFO_TYPE_SYM_HASH_ENA_PER_PORT:
> +		i40e_set_symmetric_hash_enable_per_port(hw, info->info.enable);
> +		break;
> +	case RTE_ETH_HASH_FILTER_INFO_TYPE_FILTER_SWAP:
> +		ret =3D i40e_set_filter_swap(hw, &(info->info.filter_swap));
> +		break;
> +	case RTE_ETH_HASH_FILTER_INFO_TYPE_HASH_FUNCTION:
> +		ret =3D i40e_set_hash_function(hw, info->info.hash_function);
> +		break;
> +	default:
> +		PMD_DRV_LOG(ERR, "Hash filter info type (%d) not supported",
> +							info->info_type);
> +		ret =3D -EINVAL;
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +/* Operations for hash function */
> +static int
> +i40e_hash_filter_ctrl(struct rte_eth_dev *dev,
> +		      enum rte_filter_op filter_op,
> +		      void *arg)
> +{
> +	struct i40e_hw *hw =3D
> I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +	int ret =3D 0;
> +
> +	switch (filter_op) {
> +	case RTE_ETH_FILTER_OP_NONE:
> +		break;
> +	case RTE_ETH_FILTER_OP_GET:
> +		ret =3D i40e_hash_filter_get(hw,
> +			(struct rte_eth_hash_filter_info *)arg);
> +		break;
> +	case RTE_ETH_FILTER_OP_SET:
> +		ret =3D i40e_hash_filter_set(hw,
> +			(struct rte_eth_hash_filter_info *)arg);
> +		break;
> +	default:
> +		PMD_DRV_LOG(WARNING, "Filter operation (%d) not supported",
> +								filter_op);
> +		ret =3D -ENOTSUP;
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static int
> +i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
> +		     enum rte_filter_type filter_type,
> +		     enum rte_filter_op filter_op,
> +		     void *arg)
> +{
> +	int ret =3D -ENOTSUP;
> +
> +	switch (filter_type) {
> +	case RTE_ETH_FILTER_HASH:
> +		ret =3D i40e_hash_filter_ctrl(dev, filter_op, arg);
> +		break;
> +	case RTE_ETH_FILTER_FDIR:
> +		break;
> +	case RTE_ETH_FILTER_TUNNEL:
> +		break;
> +	default:
> +		PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
> +							filter_type);
> +		break;
> +	}
> +
> +	return ret;
> +}
> --
> 1.8.1.4