From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 8EC9CA09E4; Fri, 29 Jan 2021 04:54:10 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 426084067B; Fri, 29 Jan 2021 04:54:10 +0100 (CET) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mails.dpdk.org (Postfix) with ESMTP id 7B61240395 for ; Fri, 29 Jan 2021 04:54:08 +0100 (CET) IronPort-SDR: YB2dGRzpyN4UnzLce3YnDXqmBIbDyoDSPD/940vQpl4Z2e8IJtycEvSPoBLim2H7oiBstRymEG JSiecgjzew3Q== X-IronPort-AV: E=McAfee;i="6000,8403,9878"; a="177796360" X-IronPort-AV: E=Sophos;i="5.79,384,1602572400"; d="scan'208";a="177796360" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jan 2021 19:54:07 -0800 IronPort-SDR: UYnvl7dF34v71NjJ7iB4PyQfwslwQXhcD62Ary7vgf8LKtmnRMQm2Ks5GYQyDWlH1JmubAOKL5 8cBq64OtOHuQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,384,1602572400"; d="scan'208";a="370136555" Received: from fmsmsx603.amr.corp.intel.com ([10.18.126.83]) by orsmga002.jf.intel.com with ESMTP; 28 Jan 2021 19:54:06 -0800 Received: from shsmsx601.ccr.corp.intel.com (10.109.6.141) by fmsmsx603.amr.corp.intel.com (10.18.126.83) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2; Thu, 28 Jan 2021 19:54:06 -0800 Received: from shsmsx606.ccr.corp.intel.com (10.109.6.216) by SHSMSX601.ccr.corp.intel.com (10.109.6.141) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Fri, 29 Jan 2021 11:54:04 +0800 Received: from shsmsx606.ccr.corp.intel.com ([10.109.6.216]) by SHSMSX606.ccr.corp.intel.com ([10.109.6.216]) with mapi id 15.01.1713.004; Fri, 29 Jan 2021 11:54:03 +0800 From: "Zhou, JunX W" To: "Zhang, AlvinX" , "Guo, Jia" , "Xing, Beilei" , "Zhang, Qi Z" CC: "dev@dpdk.org" Thread-Topic: [dpdk-dev] [PATCH] net/i40e: fix X722 FDIR field mask Thread-Index: AQHW9ePTxyQUsmYBZkKaBxh7Jy3+DKo9+M3g Date: Fri, 29 Jan 2021 03:54:03 +0000 Message-ID: References: <20210129020921.25104-1-alvinx.zhang@intel.com> In-Reply-To: <20210129020921.25104-1-alvinx.zhang@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.36] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH] net/i40e: fix X722 FDIR field mask X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Tested-by: Zhou, Jun -----Original Message----- From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Zhang,Alvin Sent: Friday, January 29, 2021 10:09 AM To: Guo, Jia ; Xing, Beilei ; Zha= ng, Qi Z Cc: dev@dpdk.org Subject: [dpdk-dev] [PATCH] net/i40e: fix X722 FDIR field mask From: Alvin Zhang The absolute field offsets of IPv4 or IPv6 header are related to hardware c= onfiguration. The X710 and X722 have different hardware configurations, and= users can even modify the hardware configuration. Therefore, The default values cannot be used when calculating mask offset. commands and packets as below: flow create 0 ingress pattern eth / ipv4 proto is 255 / end actions queue index 2 / end pkt =3D Ether()/IP(ttl=3D63, proto=3D255)/Raw('X'*40) flow create 0 ingress pattern eth / ipv4 tos is 50 / udp / end actions queue index 2 / end pkt =3D Ether()/IP(tos=3D50)/UDP()/Raw('X'*40) flow create 0 ingress pattern eth / ipv6 tc is 12 / udp / end actions queue index 3 / end pkt =3D Ether()/IPv6(tc=3D12,hlim=3D34,fl=3D0x98765)/UDP()/Raw('X'*40) flow create 0 ingress pattern eth / ipv6 hop is 34 / end actions queue index 3 / end pkt =3D Ether()/IPv6(tc=3D12,hlim=3D34,fl=3D0x98765)/Raw('X'*40) This patch read the field offsets from the NIC and return the mask register= value. Fixes: 98f055707685 ("i40e: configure input fields for RSS or flow director= ") Fixes: 92cf7f8ec082 ("i40e: allow filtering on more IP header fields") Cc: stable@dpdk.org Signed-off-by: Alvin Zhang --- drivers/net/i40e/i40e_ethdev.c | 158 +++++++++++++++++++++++++++++++------= ---- drivers/net/i40e/i40e_ethdev.h | 4 +- drivers/net/i40e/i40e_flow.c | 2 +- 3 files changed, 125 insertions(+), 39 deletions(-) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.= c index 946994b..e21c125 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -202,12 +202,12 @@ #define I40E_TRANSLATE_INSET 0 #define I40E_TRANSLATE_REG 1 =20 -#define I40E_INSET_IPV4_TOS_MASK 0x0009FF00UL -#define I40E_INSET_IPv4_TTL_MASK 0x000D00FFUL -#define I40E_INSET_IPV4_PROTO_MASK 0x000DFF00UL -#define I40E_INSET_IPV6_TC_MASK 0x0009F00FUL -#define I40E_INSET_IPV6_HOP_LIMIT_MASK 0x000CFF00UL -#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL +#define I40E_INSET_IPV4_TOS_MASK 0x0000FF00UL +#define I40E_INSET_IPV4_TTL_MASK 0x000000FFUL +#define I40E_INSET_IPV4_PROTO_MASK 0x0000FF00UL +#define I40E_INSET_IPV6_TC_MASK 0x0000F00FUL +#define I40E_INSET_IPV6_HOP_LIMIT_MASK 0x0000FF00UL +#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000000FFUL =20 /* PCI offset for querying capability */ #define PCI_DEV_CAP_REG 0xA4 @@ -220,6 +220,25 @@ /* Bit mask of Extended Tag enable/disable */ #define PCI_DEV_CTRL_EXT_TA= G_MASK (1 << PCI_DEV_CTRL_EXT_TAG_SHIFT) =20 +#define I40E_GLQF_PIT_IPV4_START 2 +#define I40E_GLQF_PIT_IPV4_COUNT 2 +#define I40E_GLQF_PIT_IPV6_START 4 +#define I40E_GLQF_PIT_IPV6_COUNT 2 + +#define I40E_GLQF_PIT_SOURCE_OFF_GET(a) \ + (((a) & I40E_GLQF_PIT_SOURCE_OFF_MASK) >> \ + I40E_GLQF_PIT_SOURCE_OFF_SHIFT) + +#define I40E_GLQF_PIT_DEST_OFF_GET(a) \ + (((a) & I40E_GLQF_PIT_DEST_OFF_MASK) >> \ + I40E_GLQF_PIT_DEST_OFF_SHIFT) + +#define I40E_GLQF_PIT_FSIZE_GET(a) (((a) & I40E_GLQF_PIT_FSIZE_MASK) >> \ + I40E_GLQF_PIT_FSIZE_SHIFT) + +#define I40E_GLQF_PIT_BUILD(off, mask) (((off) << 16) | (mask)) +#define I40E_FDIR_FIELD_OFFSET(a) ((a) >> 1) + static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev, void *init_param= s); static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev); static i= nt i40e_dev_configure(struct rte_eth_dev *dev); @@ -9417,49 +9436,116 @@ i4= 0e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf) return val; } =20 +static int +i40e_fd_get_field_offset(struct i40e_hw *hw, uint32_t pit_reg_start, + uint32_t pit_reg_count, uint32_t hdr_off) { + const uint32_t pit_reg_end =3D pit_reg_start + pit_reg_count; + uint32_t field_off =3D I40E_FDIR_FIELD_OFFSET(hdr_off); + uint32_t i, reg_val, src_off, count; + + for (i =3D pit_reg_start; i < pit_reg_end; i++) { + reg_val =3D i40e_read_rx_ctl(hw, I40E_GLQF_PIT(i)); + + src_off =3D I40E_GLQF_PIT_SOURCE_OFF_GET(reg_val); + count =3D I40E_GLQF_PIT_FSIZE_GET(reg_val); + + if (src_off <=3D field_off && (src_off + count) > field_off) + break; + } + + if (i >=3D pit_reg_end) { + PMD_DRV_LOG(ERR, + "Hardware GLQF_PIT configuration does not support this field mask")= ; + return -1; + } + + return I40E_GLQF_PIT_DEST_OFF_GET(reg_val) + field_off - src_off; } + int -i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_el= em) +i40e_generate_inset_mask_reg(struct i40e_hw *hw, uint64_t inset, + uint32_t *mask, uint8_t nb_elem) { - uint8_t i, idx =3D 0; - uint64_t inset_need_mask =3D inset; + static const uint64_t mask_inset[] =3D { + I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, + I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT }; =20 static const struct { uint64_t inset; uint32_t mask; - } inset_mask_map[] =3D { - {I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK}, - {I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, 0}, - {I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK}, - {I40E_INSET_IPV4_TTL, I40E_INSET_IPv4_TTL_MASK}, - {I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK}, - {I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT, 0}, - {I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK}, - {I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK}, + uint32_t offset; + } inset_mask_offset_map[] =3D { + { I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK, + offsetof(struct rte_ipv4_hdr, type_of_service) }, + + { I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK, + offsetof(struct rte_ipv4_hdr, next_proto_id) }, + + { I40E_INSET_IPV4_TTL, I40E_INSET_IPV4_TTL_MASK, + offsetof(struct rte_ipv4_hdr, time_to_live) }, + + { I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK, + offsetof(struct rte_ipv6_hdr, vtc_flow) }, + + { I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK, + offsetof(struct rte_ipv6_hdr, proto) }, + + { I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK, + offsetof(struct rte_ipv6_hdr, hop_limits) }, }; =20 - if (!inset || !mask || !nb_elem) + uint32_t i; + int idx =3D 0; + + assert(mask); + if (!inset) return 0; =20 - for (i =3D 0, idx =3D 0; i < RTE_DIM(inset_mask_map); i++) { + for (i =3D 0; i < RTE_DIM(mask_inset); i++) { /* Clear the inset bit, if no MASK is required, * for example proto + ttl */ - if ((inset & inset_mask_map[i].inset) =3D=3D - inset_mask_map[i].inset && inset_mask_map[i].mask =3D=3D 0) - inset_need_mask &=3D ~inset_mask_map[i].inset; - if (!inset_need_mask) - return 0; + if ((mask_inset[i] & inset) =3D=3D mask_inset[i]) { + inset &=3D ~mask_inset[i]; + if (!inset) + return 0; + } } - for (i =3D 0, idx =3D 0; i < RTE_DIM(inset_mask_map); i++) { - if ((inset_need_mask & 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++; + + for (i =3D 0; i < RTE_DIM(inset_mask_offset_map); i++) { + int offset, pit_start, pit_count; + + if (!(inset_mask_offset_map[i].inset & inset)) + continue; + + if (inset_mask_offset_map[i].inset & + (I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL)) { + pit_start =3D I40E_GLQF_PIT_IPV4_START; + pit_count =3D I40E_GLQF_PIT_IPV4_COUNT; + } else { + pit_start =3D I40E_GLQF_PIT_IPV6_START; + pit_count =3D I40E_GLQF_PIT_IPV6_COUNT; + } + + offset =3D inset_mask_offset_map[i].offset; + offset =3D i40e_fd_get_field_offset(hw, pit_start, pit_count, + offset); + + if (offset < 0) + return -EINVAL; + + if (idx >=3D nb_elem) { + PMD_DRV_LOG(ERR, + "FD_MASK configuration out of range %u", + nb_elem); + return -ERANGE; } + + mask[idx] =3D I40E_GLQF_PIT_BUILD(offset, + inset_mask_offset_map[i].mask); + idx++; } =20 return idx; @@ -9513,7 +9599,7 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct= i40e_pf *pf) =20 input_set =3D i40e_get_default_input_set(pctype); =20 - num =3D i40e_generate_inset_mask_reg(input_set, mask_reg, + num =3D i40e_generate_inset_mask_reg(hw, input_set, mask_reg, I40E_INSET_MASK_NUM_REG); if (num < 0) return; @@ -9593,7 +9679,7 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct= i40e_pf *pf) inset_reg |=3D i40e_read_rx_ctl(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, + num =3D i40e_generate_inset_mask_reg(hw, input_set, mask_reg, I40E_INSET_MASK_NUM_REG); if (num < 0) return -EINVAL; diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.= h index 1e8f5d3..faf6896 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -1458,8 +1458,8 @@ void i40e_set_symmetric_hash_enable_per_port(struct i= 40e_hw *hw, uint8_t enable); int i40e_validate_input_set(enum i40e_filter_pctype pctype, enum rte_filter_type filter, uint64_t inset); -int i40e_generate_in= set_mask_reg(uint64_t inset, uint32_t *mask, - uint8_t nb_elem); +int i40e_generate_inset_mask_reg(struct i40e_hw *hw, uint64_t inset, + uint32_t *mask, uint8_t nb_elem); uint64_t i40e_translate_input_set_reg(enum i40e_mac_type type, uint64_t in= put); void i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_= t val); void i40e_check_write_global_reg(struct i40e_hw *hw, diff --git a/= drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c index 7fe760d..= ac77cc3 100644 --- a/drivers/net/i40e/i40e_flow.c +++ b/drivers/net/i40e/i40e_flow.c @@ -2269,7 +2269,7 @@ static int i40e_flow_parse_l4_cloud_filter(struct rte= _eth_dev *dev, !memcmp(&pf->fdir.input_set[pctype], &input_set, sizeof(uint64_t))) return 0; =20 - num =3D i40e_generate_inset_mask_reg(input_set, mask_reg, + num =3D i40e_generate_inset_mask_reg(hw, input_set, mask_reg, I40E_INSET_MASK_NUM_REG); if (num < 0) return -EINVAL; -- 1.8.3.1