From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id DD6B158E6 for ; 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" To: "Chilikin, Andrey" , "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: 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> In-Reply-To: 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-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 > --- > 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