From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7667DA0613 for ; Mon, 23 Sep 2019 05:34:11 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 49E365B32; Mon, 23 Sep 2019 05:34:10 +0200 (CEST) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by dpdk.org (Postfix) with ESMTP id 6C6E437A2 for ; Mon, 23 Sep 2019 05:34:08 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Sep 2019 20:34:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,538,1559545200"; d="scan'208";a="178991947" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by orsmga007.jf.intel.com with ESMTP; 22 Sep 2019 20:34:07 -0700 Received: from shsmsx153.ccr.corp.intel.com (10.239.6.53) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.439.0; Sun, 22 Sep 2019 20:34:06 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.113]) by SHSMSX153.ccr.corp.intel.com ([169.254.12.235]) with mapi id 14.03.0439.000; Mon, 23 Sep 2019 11:34:04 +0800 From: "Wang, Haiyue" To: "Yang, Qiming" , "Rong, Leyi" , "Lu, Wenzhuo" , "Zhang, Qi Z" , "Ye, Xiaolong" CC: "dev@dpdk.org" Thread-Topic: [dpdk-dev] [PATCH v4 3/6] net/ice: add protocol extraction support for per Rx queue Thread-Index: AQHVcb6TW0g01wRQPkO9g3nGAM+gsac4m5bA Date: Mon, 23 Sep 2019 03:34:04 +0000 Message-ID: References: <20190829023421.112551-1-leyi.rong@intel.com> <20190919062553.79257-1-leyi.rong@intel.com> <20190919062553.79257-4-leyi.rong@intel.com> In-Reply-To: Accept-Language: zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMTRiNzM2ZGEtN2Q0MC00NTE5LWEyMzAtNzUyODI5MjdhY2RkIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiZWtLNDg0SXQrNkl4M210SXM2bFRRaVwvZTdobVlKWVNnODBjY0pmOVI1Q1NiVHo1NE9VM1lCa052WHJjRlVkdXEifQ== x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action 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 3/6] net/ice: add protocol extraction support for per Rx queue X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" > -----Original Message----- > From: Yang, Qiming > Sent: Monday, September 23, 2019 11:26 > To: Rong, Leyi ; Wang, Haiyue ; Lu, Wenzhuo > ; Zhang, Qi Z ; Ye, Xiaolong = > Cc: dev@dpdk.org > Subject: RE: [dpdk-dev] [PATCH v4 3/6] net/ice: add protocol extraction s= upport for per Rx queue >=20 >=20 >=20 > > -----Original Message----- > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Leyi Rong > > Sent: Thursday, September 19, 2019 2:26 PM > > To: Wang, Haiyue ; Lu, Wenzhuo > > ; Zhang, Qi Z ; Ye, Xiaolon= g > > > > Cc: dev@dpdk.org > > Subject: [dpdk-dev] [PATCH v4 3/6] net/ice: add protocol extraction sup= port > > for per Rx queue > > > > From: Haiyue Wang > > > > The ice has the feature to extract protocol fields into flex descriptor= by > > programming per queue. Currently, the ice PMD will put the protocol fie= lds > > into rte_mbuf::udata64 with different type format. Application can acce= ss > > the protocol fields quickly. > > > > Signed-off-by: Haiyue Wang > > --- > > doc/guides/nics/ice.rst | 101 +++++++++ > > doc/guides/rel_notes/release_19_11.rst | 4 + > > drivers/net/ice/Makefile | 3 + > > drivers/net/ice/ice_ethdev.c | 301 +++++++++++++++++++++++++ > > drivers/net/ice/ice_ethdev.h | 4 + > > drivers/net/ice/ice_rxtx.c | 61 +++++ > > drivers/net/ice/ice_rxtx.h | 2 + > > drivers/net/ice/ice_rxtx_vec_common.h | 3 + > > drivers/net/ice/meson.build | 2 + > > drivers/net/ice/rte_pmd_ice.h | 152 +++++++++++++ > > 10 files changed, 633 insertions(+) > > create mode 100644 drivers/net/ice/rte_pmd_ice.h > > > > diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst index > > 03819d29f..8a6f60e71 100644 > > --- a/doc/guides/nics/ice.rst > > +++ b/doc/guides/nics/ice.rst > > @@ -61,6 +61,107 @@ Runtime Config Options > > NOTE: In Safe mode, only very limited features are available, featur= es like > > RSS, > > checksum, fdir, tunneling ... are all disabled. > > > > +- ``Protocol extraction for per queue`` > > + > > + Configure the RX queues to do protocol extraction into > > + ``rte_mbuf::udata64`` for protocol handling acceleration, like check= ing the > > TCP SYN packets quickly. > > + > > + The argument format is:: > > + > > + -w 18:00.0,proto_xtr=3D[...] > > + -w 18:00.0,proto_xtr=3D > > + > > + Queues are grouped by ``(`` and ``)`` within the group. The ``-`` > > + character is used as a range separator and ``,`` is used as a single= number > > separator. > > + The grouping ``()`` can be omitted for single element group. If no > > + queues are specified, PMD will use this protocol extraction type for= all > > queues. > > + > > + Protocol is : ``vlan, ipv4, ipv6, ipv6_flow, tcp``. > > + > > + .. code-block:: console > > + > > + testpmd -w 18:00.0,proto_xtr=3D'[(1,2-3,8-9):tcp,10-13:vlan]' > > + > > + This setting means queues 1, 2-3, 8-9 are TCP extraction, queues > > + 10-13 are VLAN extraction, other queues run with no protocol extract= ion. > > + > > + .. code-block:: console > > + > > + testpmd -w 18:00.0,proto_xtr=3Dvlan,proto_xtr=3D'[(1,2-3,8-9):tcp,= 10-23:ipv6]' > > + > > + This setting means queues 1, 2-3, 8-9 are TCP extraction, queues > > + 10-23 are > > + IPv6 extraction, other queues use the default VLAN extraction. > > + > > + The extraction will be copied into the lower 32 bit of > > ``rte_mbuf::udata64``. > > + > > + .. table:: Protocol extraction : ``vlan`` > > + > > + +----------------------------+----------------------------+ > > + | VLAN2 | VLAN1 | > > + +=3D=3D=3D=3D=3D=3D+=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D+=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ > > + | PCP | D | VID | PCP | D | VID | > > + +------+---+-----------------+------+---+-----------------+ > > + > > + VLAN1 - single or EVLAN (first for QinQ). > > + > > + VLAN2 - C-VLAN (second for QinQ). > > + > > + .. table:: Protocol extraction : ``ipv4`` > > + > > + +----------------------------+----------------------------+ > > + | IPHDR2 | IPHDR1 | > > + +=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D+ > > + | Ver |Hdr Len| ToS | TTL | Protocol | > > + +------+-------+-------------+--------------+-------------+ > > + > > + IPHDR1 - IPv4 header word 4, "TTL" and "Protocol" fields. > > + > > + IPHDR2 - IPv4 header word 0, "Ver", "Hdr Len" and "Type of Service" = fields. > > + > > + .. table:: Protocol extraction : ``ipv6`` > > + > > + +----------------------------+----------------------------+ > > + | IPHDR2 | IPHDR1 | > > + +=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D= =3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D+ > > + | Ver |Traffic class| Flow | Next Header | Hop Limit | > > + +-----+-------------+--------+-------------+--------------+ > > + > > + IPHDR1 - IPv6 header word 3, "Next Header" and "Hop Limit" fields. > > + > > + IPHDR2 - IPv6 header word 0, "Ver", "Traffic class" and high 4 bits > > + of "Flow Label" fields. > > + > > + .. table:: Protocol extraction : ``ipv6_flow`` > > + > > + +----------------------------+----------------------------+ > > + | IPHDR2 | IPHDR1 | > > + +=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D= =3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D+ > > + | Ver |Traffic class| Flow Label | > > + +-----+-------------+-------------------------------------+ > > + > > + IPHDR1 - IPv6 header word 1, 16 low bits of the "Flow Label" field. > > + > > + IPHDR2 - IPv6 header word 0, "Ver", "Traffic class" and high 4 bits > > + of "Flow Label" fields. > > + > > + .. table:: Protocol extraction : ``tcp`` > > + > > + +----------------------------+----------------------------+ > > + | TCPHDR2 | TCPHDR1 | > > + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D+ > > + | Reserved |Offset| RSV | Flags | > > + +----------------------------+------+------+--------------+ > > + > > + TCPHDR1 - TCP header word 6, "Data Offset" and "Flags" fields. > > + > > + TCPHDR2 - Reserved > > + > > + Use ``get_proto_xtr_flds(struct rte_mbuf *mb)`` to access the > > + protocol extraction, do not use ``rte_mbuf::udata64`` directly. > > + > > + The ``dump_proto_xtr_flds(struct rte_mbuf *mb)`` routine shows how t= o > > + access the protocol extraction result in ``struct rte_mbuf``. > > + > > Driver compilation and testing > > ------------------------------ > > > > diff --git a/doc/guides/rel_notes/release_19_11.rst > > b/doc/guides/rel_notes/release_19_11.rst > > index 8490d897c..382806229 100644 > > --- a/doc/guides/rel_notes/release_19_11.rst > > +++ b/doc/guides/rel_notes/release_19_11.rst > > @@ -21,6 +21,10 @@ DPDK Release 19.11 > > > > xdg-open build/doc/html/guides/rel_notes/release_19_11.html > > > > +* **Updated the ICE driver.** > > + > > + * Added support for handling Receive Flex Descriptor. > > + * Added support for protocol extraction on per Rx queue. > > > > New Features > > ------------ > > diff --git a/drivers/net/ice/Makefile b/drivers/net/ice/Makefile index > > ae53c2646..4a279f196 100644 > > --- a/drivers/net/ice/Makefile > > +++ b/drivers/net/ice/Makefile > > @@ -82,4 +82,7 @@ ifeq ($(CC_AVX2_SUPPORT), 1) endif > > SRCS-$(CONFIG_RTE_LIBRTE_ICE_PMD) +=3D ice_generic_flow.c > > > > +# install this header file > > +SYMLINK-$(CONFIG_RTE_LIBRTE_ICE_PMD)-include :=3D rte_pmd_ice.h > > + > > include $(RTE_SDK)/mk/rte.lib.mk > > diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.= c index > > 44a14cb8a..7c74b6169 100644 > > --- a/drivers/net/ice/ice_ethdev.c > > +++ b/drivers/net/ice/ice_ethdev.c > > @@ -19,9 +19,11 @@ > > > > /* devargs */ > > #define ICE_SAFE_MODE_SUPPORT_ARG "safe-mode-support" > > +#define ICE_PROTO_XTR_ARG "proto_xtr" > > > > static const char * const ice_valid_args[] =3D { > > ICE_SAFE_MODE_SUPPORT_ARG, > > + ICE_PROTO_XTR_ARG, > > NULL > > }; > > > > @@ -257,6 +259,280 @@ ice_init_controlq_parameter(struct ice_hw *hw) > > hw->mailboxq.sq_buf_size =3D ICE_MAILBOXQ_BUF_SZ; } > > > > +static int > > +lookup_proto_xtr_type(const char *xtr_name) { > > + static struct { > > + const char *name; > > + enum proto_xtr_type type; > > + } xtr_type_map[] =3D { > > + { "vlan", PROTO_XTR_VLAN }, > > + { "ipv4", PROTO_XTR_IPV4 }, > > + { "ipv6", PROTO_XTR_IPV6 }, > > + { "ipv6_flow", PROTO_XTR_IPV6_FLOW }, > > + { "tcp", PROTO_XTR_TCP }, > > + }; > > + uint32_t i; > > + > > + for (i =3D 0; i < RTE_DIM(xtr_type_map); i++) { > > + if (strcmp(xtr_name, xtr_type_map[i].name) =3D=3D 0) > > + return xtr_type_map[i].type; > > + } > > + > > + return -1; > > +} > > + > > +/* > > + * Parse elem, the elem could be single number/range or '(' ')' group > > + * 1) A single number elem, it's just a simple digit. e.g. 9 > > + * 2) A single range elem, two digits with a '-' between. e.g. 2-6 > > + * 3) A group elem, combines multiple 1) or 2) with '( )'. e.g (0,2-4,= 6) > > + * Within group elem, '-' used for a range separator; > > + * ',' used for a single number. > > + */ > > +static int > > +parse_queue_set(const char *input, int xtr_type, struct ice_devargs > > +*devargs) { > > + const char *str =3D input; > > + char *end =3D NULL; > > + uint32_t min, max; > > + uint32_t idx; > > + > > + while (isblank(*str)) > > + str++; > > + > > + if (!isdigit(*str) && *str !=3D '(') > > + return -1; > > + > > + /* process single number or single range of number */ > > + if (*str !=3D '(') { > > + errno =3D 0; > > + idx =3D strtoul(str, &end, 10); > > + if (errno || end =3D=3D NULL || idx >=3D ICE_MAX_QUEUE_NUM) > > + return -1; > > + > > + while (isblank(*end)) > > + end++; > > + > > + min =3D idx; > > + max =3D idx; > > + > > + /* process single - */ > > + if (*end =3D=3D '-') { > > + end++; > > + while (isblank(*end)) > > + end++; > > + if (!isdigit(*end)) > > + return -1; > > + > > + errno =3D 0; > > + idx =3D strtoul(end, &end, 10); > > + if (errno || end =3D=3D NULL || idx >=3D > > ICE_MAX_QUEUE_NUM) > > + return -1; > > + > > + max =3D idx; > > + while (isblank(*end)) > > + end++; > > + } > > + > > + if (*end !=3D ':') > > + return -1; > > + > > + for (idx =3D RTE_MIN(min, max); > > + idx <=3D RTE_MAX(min, max); idx++) > > + devargs->proto_xtr[idx] =3D xtr_type; > > + > > + return 0; > > + } > > + > > + /* process set within bracket */ > > + str++; > > + while (isblank(*str)) > > + str++; > > + if (*str =3D=3D '\0') > > + return -1; > > + > > + min =3D ICE_MAX_QUEUE_NUM; > > + do { > > + /* go ahead to the first digit */ > > + while (isblank(*str)) > > + str++; > > + if (!isdigit(*str)) > > + return -1; > > + > > + /* get the digit value */ > > + errno =3D 0; > > + idx =3D strtoul(str, &end, 10); > > + if (errno || end =3D=3D NULL || idx >=3D ICE_MAX_QUEUE_NUM) > > + return -1; > > + > > + /* go ahead to separator '-',',' and ')' */ > > + while (isblank(*end)) > > + end++; > > + if (*end =3D=3D '-') { > > + if (min =3D=3D ICE_MAX_QUEUE_NUM) > > + min =3D idx; > > + else /* avoid continuous '-' */ > > + return -1; > > + } else if (*end =3D=3D ',' || *end =3D=3D ')') { > > + max =3D idx; > > + if (min =3D=3D ICE_MAX_QUEUE_NUM) > > + min =3D idx; > > + > > + for (idx =3D RTE_MIN(min, max); > > + idx <=3D RTE_MAX(min, max); idx++) > > + devargs->proto_xtr[idx] =3D xtr_type; > > + > > + min =3D ICE_MAX_QUEUE_NUM; > > + } else { > > + return -1; > > + } > > + > > + str =3D end + 1; > > + } while (*end !=3D ')' && *end !=3D '\0'); > > + > > + return 0; > > +} > > + > > +static int > > +parse_queue_proto_xtr(const char *queues, struct ice_devargs *devargs) > > +{ > > + const char *queue_start; > > + uint32_t idx; > > + int xtr_type; > > + char xtr_name[32]; > > + > > + while (isblank(*queues)) > > + queues++; > > + > > + if (*queues !=3D '[') { > > + xtr_type =3D lookup_proto_xtr_type(queues); > > + if (xtr_type < 0) > > + return -1; > > + > > + memset(devargs->proto_xtr, xtr_type, > > + sizeof(devargs->proto_xtr)); > > + > > + return 0; > > + } > > + > > + queues++; > > + do { > > + while (isblank(*queues)) > > + queues++; > > + if (*queues =3D=3D '\0') > > + return -1; > > + > > + queue_start =3D queues; > > + > > + /* go across a complete bracket */ > > + if (*queue_start =3D=3D '(') { > > + queues +=3D strcspn(queues, ")"); > > + if (*queues !=3D ')') > > + return -1; > > + } > > + > > + /* scan the separator ':' */ > > + queues +=3D strcspn(queues, ":"); > > + if (*queues++ !=3D ':') > > + return -1; > > + while (isblank(*queues)) > > + queues++; > > + > > + for (idx =3D 0; ; idx++) { > > + if (isblank(queues[idx]) || > > + queues[idx] =3D=3D ',' || > > + queues[idx] =3D=3D ']' || > > + queues[idx] =3D=3D '\0') > > + break; > > + > > + if (idx > sizeof(xtr_name) - 2) > > + return -1; > > + > > + xtr_name[idx] =3D queues[idx]; > > + } > > + xtr_name[idx] =3D '\0'; > > + xtr_type =3D lookup_proto_xtr_type(xtr_name); > > + if (xtr_type < 0) > > + return -1; > > + > > + queues +=3D idx; > > + > > + while (isblank(*queues) || *queues =3D=3D ',' || *queues =3D=3D ']') > > + queues++; > > + > > + if (parse_queue_set(queue_start, xtr_type, devargs) < 0) > > + return -1; > > + } while (*queues !=3D '\0'); > > + > > + return 0; > > +} > > + > > +static int > > +handle_proto_xtr_arg(__rte_unused const char *key, const char *value, > > + void *extra_args) > > +{ > > + struct ice_devargs *devargs =3D extra_args; > > + > > + if (value =3D=3D NULL || extra_args =3D=3D NULL) > > + return -EINVAL; > > + > > + if (parse_queue_proto_xtr(value, devargs) < 0) { > > + PMD_DRV_LOG(ERR, > > + "The protocol extraction parameter is wrong : '%s'", > > + value); > > + return -1; > > + } > > + > > + return 0; > > +} > > + > > +static bool > > +ice_proto_xtr_support(struct ice_hw *hw) { #define FLX_REG(val, fld, > > +idx) \ > > + (((val) & GLFLXP_RXDID_FLX_WRD_##idx##_##fld##_M) >> \ > > + GLFLXP_RXDID_FLX_WRD_##idx##_##fld##_S) > > + static struct { > > + uint32_t rxdid; > > + uint16_t protid_0; > > + uint16_t protid_1; > > + } xtr_sets[] =3D { > > + { ICE_RXDID_COMMS_AUX_VLAN, ICE_PROT_EVLAN_O, > > ICE_PROT_VLAN_O }, > > + { ICE_RXDID_COMMS_AUX_IPV4, ICE_PROT_IPV4_OF_OR_S, > > + ICE_PROT_IPV4_OF_OR_S }, > > + { ICE_RXDID_COMMS_AUX_IPV6, ICE_PROT_IPV6_OF_OR_S, > > + ICE_PROT_IPV6_OF_OR_S }, > > + { ICE_RXDID_COMMS_AUX_IPV6_FLOW, > > ICE_PROT_IPV6_OF_OR_S, > > + ICE_PROT_IPV6_OF_OR_S }, > > + { ICE_RXDID_COMMS_AUX_TCP, ICE_PROT_TCP_IL, > > ICE_PROT_ID_INVAL }, > > + }; > > + uint32_t i; > > + > > + for (i =3D 0; i < RTE_DIM(xtr_sets); i++) { > > + uint32_t rxdid =3D xtr_sets[i].rxdid; > > + uint32_t v; > > + > > + if (xtr_sets[i].protid_0 !=3D ICE_PROT_ID_INVAL) { > > + v =3D ICE_READ_REG(hw, > > GLFLXP_RXDID_FLX_WRD_4(rxdid)); > > + > > + if (FLX_REG(v, PROT_MDID, 4) !=3D xtr_sets[i].protid_0 > > || > > + FLX_REG(v, RXDID_OPCODE, 4) !=3D > > ICE_RX_OPC_EXTRACT) > > + return false; > > + } > > + > > + if (xtr_sets[i].protid_1 !=3D ICE_PROT_ID_INVAL) { > > + v =3D ICE_READ_REG(hw, > > GLFLXP_RXDID_FLX_WRD_5(rxdid)); > > + > > + if (FLX_REG(v, PROT_MDID, 5) !=3D xtr_sets[i].protid_1 > > || > > + FLX_REG(v, RXDID_OPCODE, 5) !=3D > > ICE_RX_OPC_EXTRACT) > > + return false; > > + } > > + } > > + > > + return true; > > +} > > + > > static int > > ice_res_pool_init(struct ice_res_pool_info *pool, uint32_t base, > > uint32_t num) > > @@ -1079,6 +1355,8 @@ ice_interrupt_handler(void *param) static int > > ice_pf_sw_init(struct rte_eth_dev *dev) { > > + struct ice_adapter *ad =3D > > + ICE_DEV_PRIVATE_TO_ADAPTER(dev->data- > > >dev_private); > > struct ice_pf *pf =3D ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private); > > struct ice_hw *hw =3D ICE_PF_TO_HW(pf); > > > > @@ -1088,6 +1366,16 @@ ice_pf_sw_init(struct rte_eth_dev *dev) > > > > pf->lan_nb_qps =3D pf->lan_nb_qp_max; > > > > + if (ice_proto_xtr_support(hw)) > > + pf->proto_xtr =3D rte_zmalloc(NULL, pf->lan_nb_qps, 0); > > + > > + if (pf->proto_xtr !=3D NULL) > > + rte_memcpy(pf->proto_xtr, ad->devargs.proto_xtr, > > + RTE_MIN((size_t)pf->lan_nb_qps, > > + sizeof(ad->devargs.proto_xtr))); > > + else > > + PMD_DRV_LOG(NOTICE, "Protocol extraction is disabled"); > > + > > return 0; > > } > > > > @@ -1378,9 +1666,18 @@ static int ice_parse_devargs(struct rte_eth_dev > > *dev) > > return -EINVAL; > > } > > > > + memset(ad->devargs.proto_xtr, PROTO_XTR_NONE, > > + sizeof(ad->devargs.proto_xtr)); > > + > > + ret =3D rte_kvargs_process(kvlist, ICE_PROTO_XTR_ARG, > > + &handle_proto_xtr_arg, &ad->devargs); > > + if (ret) > > + goto bail; > > + >=20 > Why is bail? >=20 free & ret, since 'ret' is used, 'bail' name from kernel. :) > > ret =3D rte_kvargs_process(kvlist, ICE_SAFE_MODE_SUPPORT_ARG, > > &parse_bool, &ad- > > >devargs.safe_mode_support); > > > > +bail: > > rte_kvargs_free(kvlist); > > return ret; > > } > > @@ -1547,6 +1844,7 @@ ice_dev_init(struct rte_eth_dev *dev) > > ice_sched_cleanup_all(hw); > > rte_free(hw->port_info); > > ice_shutdown_all_ctrlq(hw); > > + rte_free(pf->proto_xtr); > > > > return ret; > > } > > @@ -1672,6 +1970,8 @@ ice_dev_close(struct rte_eth_dev *dev) > > rte_free(hw->port_info); > > hw->port_info =3D NULL; > > ice_shutdown_all_ctrlq(hw); > > + rte_free(pf->proto_xtr); > > + pf->proto_xtr =3D NULL; > > } > > > > static int > > @@ -3795,6 +4095,7 @@ RTE_PMD_REGISTER_PCI(net_ice, rte_ice_pmd); > > RTE_PMD_REGISTER_PCI_TABLE(net_ice, pci_id_ice_map); > > RTE_PMD_REGISTER_KMOD_DEP(net_ice, "* igb_uio | uio_pci_generic | vfio- > > pci"); RTE_PMD_REGISTER_PARAM_STRING(net_ice, > > + ICE_PROTO_XTR_ARG > > "=3D[queue:]" > > ICE_SAFE_MODE_SUPPORT_ARG "=3D<0|1>"); > > > > RTE_INIT(ice_init_log) > > diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.= h index > > f569da833..adbb66322 100644 > > --- a/drivers/net/ice/ice_ethdev.h > > +++ b/drivers/net/ice/ice_ethdev.h > > @@ -263,6 +263,7 @@ struct ice_pf { > > uint16_t lan_nb_qp_max; > > uint16_t lan_nb_qps; /* The number of queue pairs of LAN */ > > uint16_t base_queue; /* The base queue pairs index in the device > > */ > > + uint8_t *proto_xtr; /* Protocol extraction type for all queues */ > > struct ice_hw_port_stats stats_offset; > > struct ice_hw_port_stats stats; > > /* internal packet statistics, it should be excluded from the total *= / > > @@ -273,11 +274,14 @@ struct ice_pf { > > struct ice_flow_list flow_list; > > }; > > > > +#define ICE_MAX_QUEUE_NUM 2048 > > + > > /** > > * Cache devargs parse result. > > */ > > struct ice_devargs { > > int safe_mode_support; > > + uint8_t proto_xtr[ICE_MAX_QUEUE_NUM]; > > }; > > > > /** > > diff --git a/drivers/net/ice/ice_rxtx.c b/drivers/net/ice/ice_rxtx.c in= dex > > d2e36853f..e28310b96 100644 > > --- a/drivers/net/ice/ice_rxtx.c > > +++ b/drivers/net/ice/ice_rxtx.c > > @@ -13,6 +13,36 @@ > > PKT_TX_TCP_SEG | \ > > PKT_TX_OUTER_IP_CKSUM) > > > > +static inline uint8_t > > +ice_rxdid_to_proto_xtr_type(uint8_t rxdid) { > > + static uint8_t xtr_map[] =3D { > > + [ICE_RXDID_COMMS_AUX_VLAN] =3D PROTO_XTR_VLAN, > > + [ICE_RXDID_COMMS_AUX_IPV4] =3D PROTO_XTR_IPV4, > > + [ICE_RXDID_COMMS_AUX_IPV6] =3D PROTO_XTR_IPV6, > > + [ICE_RXDID_COMMS_AUX_IPV6_FLOW] =3D > > PROTO_XTR_IPV6_FLOW, > > + [ICE_RXDID_COMMS_AUX_TCP] =3D PROTO_XTR_TCP, > > + }; > > + > > + return rxdid < RTE_DIM(xtr_map) ? xtr_map[rxdid] : > > PROTO_XTR_NONE; } > > + > > +static inline uint8_t > > +ice_proto_xtr_type_to_rxdid(uint8_t xtr_tpye) { > > + static uint8_t rxdid_map[] =3D { > > + [PROTO_XTR_VLAN] =3D ICE_RXDID_COMMS_AUX_VLAN, > > + [PROTO_XTR_IPV4] =3D ICE_RXDID_COMMS_AUX_IPV4, > > + [PROTO_XTR_IPV6] =3D ICE_RXDID_COMMS_AUX_IPV6, > > + [PROTO_XTR_IPV6_FLOW] =3D > > ICE_RXDID_COMMS_AUX_IPV6_FLOW, > > + [PROTO_XTR_TCP] =3D ICE_RXDID_COMMS_AUX_TCP, > > + }; > > + uint8_t rxdid; > > + > > + rxdid =3D xtr_tpye < RTE_DIM(rxdid_map) ? rxdid_map[xtr_tpye] : 0; > > + > > + return rxdid !=3D 0 ? rxdid : ICE_RXDID_COMMS_GENERIC; } > > > > static enum ice_status > > ice_program_hw_rx_queue(struct ice_rx_queue *rxq) @@ -84,6 +114,11 > > @@ ice_program_hw_rx_queue(struct ice_rx_queue *rxq) > > rx_ctx.showiv =3D 0; > > rx_ctx.crcstrip =3D (rxq->crc_len =3D=3D 0) ? 1 : 0; > > > > + rxdid =3D ice_proto_xtr_type_to_rxdid(rxq->proto_xtr); > > + > > + PMD_DRV_LOG(DEBUG, "Port (%u) - Rx queue (%u) is set with > > RXDID : %u", > > + rxq->port_id, rxq->queue_id, rxdid); > > + > > /* Enable Flexible Descriptors in the queue context which > > * allows this driver to select a specific receive descriptor format > > */ > > @@ -641,6 +676,8 @@ ice_rx_queue_setup(struct rte_eth_dev *dev, > > rxq->drop_en =3D rx_conf->rx_drop_en; > > rxq->vsi =3D vsi; > > rxq->rx_deferred_start =3D rx_conf->rx_deferred_start; > > + rxq->proto_xtr =3D pf->proto_xtr !=3D NULL ? > > + pf->proto_xtr[queue_idx] : PROTO_XTR_NONE; > > > > /* Allocate the maximun number of RX ring hardware descriptor. */ > > len =3D ICE_MAX_RING_DESC; > > @@ -1062,6 +1099,10 @@ ice_rxd_to_vlan_tci(struct rte_mbuf *mb, volatil= e > > union ice_rx_flex_desc *rxdp) > > mb->vlan_tci, mb->vlan_tci_outer); } > > > > +#define ICE_RX_PROTO_XTR_VALID \ > > + ((1 << ICE_RX_FLEX_DESC_STATUS1_XTRMD4_VALID_S) | \ > > + (1 << ICE_RX_FLEX_DESC_STATUS1_XTRMD5_VALID_S)) > > + > > static inline void > > ice_rxd_to_pkt_fields(struct rte_mbuf *mb, > > volatile union ice_rx_flex_desc *rxdp) @@ -1075,6 > > +1116,26 @@ ice_rxd_to_pkt_fields(struct rte_mbuf *mb, > > mb->ol_flags |=3D PKT_RX_RSS_HASH; > > mb->hash.rss =3D rte_le_to_cpu_32(desc->rss_hash); > > } > > + > > +#ifndef RTE_LIBRTE_ICE_16BYTE_RX_DESC > > + init_proto_xtr_flds(mb); > > + > > + stat_err =3D rte_le_to_cpu_16(desc->status_error1); > > + if (stat_err & ICE_RX_PROTO_XTR_VALID) { > > + struct proto_xtr_flds *xtr =3D get_proto_xtr_flds(mb); > > + > > + if (stat_err & (1 << > > ICE_RX_FLEX_DESC_STATUS1_XTRMD4_VALID_S)) > > + xtr->u.raw.data0 =3D > > + rte_le_to_cpu_16(desc->flex_ts.flex.aux0); > > + > > + if (stat_err & (1 << > > ICE_RX_FLEX_DESC_STATUS1_XTRMD5_VALID_S)) > > + xtr->u.raw.data1 =3D > > + rte_le_to_cpu_16(desc->flex_ts.flex.aux1); > > + > > + xtr->type =3D ice_rxdid_to_proto_xtr_type(desc->rxdid); > > + xtr->magic =3D PROTO_XTR_MAGIC_ID; > > + } > > +#endif > > } > > > > #ifdef RTE_LIBRTE_ICE_RX_ALLOW_BULK_ALLOC > > diff --git a/drivers/net/ice/ice_rxtx.h b/drivers/net/ice/ice_rxtx.h in= dex > > 64e891875..de16637f3 100644 > > --- a/drivers/net/ice/ice_rxtx.h > > +++ b/drivers/net/ice/ice_rxtx.h > > @@ -5,6 +5,7 @@ > > #ifndef _ICE_RXTX_H_ > > #define _ICE_RXTX_H_ > > > > +#include "rte_pmd_ice.h" > > #include "ice_ethdev.h" > > > > #define ICE_ALIGN_RING_DESC 32 > > @@ -78,6 +79,7 @@ struct ice_rx_queue { > > uint16_t max_pkt_len; /* Maximum packet length */ > > bool q_set; /* indicate if rx queue has been configured */ > > bool rx_deferred_start; /* don't start this queue in dev start */ > > + uint8_t proto_xtr; /* Protocol extraction from flexible descriptor */ > > ice_rx_release_mbufs_t rx_rel_mbufs; > > }; > > > > diff --git a/drivers/net/ice/ice_rxtx_vec_common.h > > b/drivers/net/ice/ice_rxtx_vec_common.h > > index c5f0d564f..080ca4175 100644 > > --- a/drivers/net/ice/ice_rxtx_vec_common.h > > +++ b/drivers/net/ice/ice_rxtx_vec_common.h > > @@ -234,6 +234,9 @@ ice_rx_vec_queue_default(struct ice_rx_queue *rxq) > > if (rxq->nb_rx_desc % rxq->rx_free_thresh) > > return -1; > > > > + if (rxq->proto_xtr !=3D PROTO_XTR_NONE) > > + return -1; > > + > > return 0; > > } > > > > diff --git a/drivers/net/ice/meson.build b/drivers/net/ice/meson.build = index > > 36b4b3c85..6828170a9 100644 > > --- a/drivers/net/ice/meson.build > > +++ b/drivers/net/ice/meson.build > > @@ -34,3 +34,5 @@ if arch_subdir =3D=3D 'x86' > > objs +=3D ice_avx2_lib.extract_objects('ice_rxtx_vec_avx2.c') > > endif > > endif > > + > > +install_headers('rte_pmd_ice.h') > > diff --git a/drivers/net/ice/rte_pmd_ice.h b/drivers/net/ice/rte_pmd_ic= e.h > > new file mode 100644 index 000000000..719487e1e > > --- /dev/null > > +++ b/drivers/net/ice/rte_pmd_ice.h > > @@ -0,0 +1,152 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright(c) 2019 Intel Corporation > > + */ > > + > > +#ifndef _RTE_PMD_ICE_H_ > > +#define _RTE_PMD_ICE_H_ > > + > > +#include > > +#include > > +#include > > + > > +#ifdef __cplusplus > > +extern "C" { > > +#endif > > + > > +enum proto_xtr_type { > > + PROTO_XTR_NONE, > > + PROTO_XTR_VLAN, > > + PROTO_XTR_IPV4, > > + PROTO_XTR_IPV6, > > + PROTO_XTR_IPV6_FLOW, > > + PROTO_XTR_TCP, > > +}; > > + > > +struct proto_xtr_flds { > > + union { > > + struct { > > + uint16_t data0; > > + uint16_t data1; > > + } raw; > > + struct { > > + uint16_t stag_vid:12, > > + stag_dei:1, > > + stag_pcp:3; > > + uint16_t ctag_vid:12, > > + ctag_dei:1, > > + ctag_pcp:3; > > + } vlan; > > + struct { > > + uint16_t protocol:8, > > + ttl:8; > > + uint16_t tos:8, > > + ihl:4, > > + version:4; > > + } ipv4; > > + struct { > > + uint16_t hoplimit:8, > > + nexthdr:8; > > + uint16_t flowhi4:4, > > + tc:8, > > + version:4; > > + } ipv6; > > + struct { > > + uint16_t flowlo16; > > + uint16_t flowhi4:4, > > + tc:8, > > + version:4; > > + } ipv6_flow; > > + struct { > > + uint16_t fin:1, > > + syn:1, > > + rst:1, > > + psh:1, > > + ack:1, > > + urg:1, > > + ece:1, > > + cwr:1, > > + res1:4, > > + doff:4; > > + uint16_t rsvd; > > + } tcp; > > + } u; > > + > > + uint16_t rsvd; > > + > > + uint8_t type; > > + > > +#define PROTO_XTR_MAGIC_ID 0xCE > > + uint8_t magic; > > +}; > > + > > +static inline void > > +init_proto_xtr_flds(struct rte_mbuf *mb) { > > + mb->udata64 =3D 0; > > +} > > + > > +static inline struct proto_xtr_flds * > > +get_proto_xtr_flds(struct rte_mbuf *mb) { > > + RTE_BUILD_BUG_ON(sizeof(struct proto_xtr_flds) > sizeof(mb- > > >udata64)); > > + > > + return (struct proto_xtr_flds *)&mb->udata64; } > > + > > +static inline void > > +dump_proto_xtr_flds(struct rte_mbuf *mb) { > > + struct proto_xtr_flds *xtr =3D get_proto_xtr_flds(mb); > > + > > + if (xtr->magic !=3D PROTO_XTR_MAGIC_ID || xtr->type =3D=3D > > PROTO_XTR_NONE) > > + return; > > + > > + printf(" - Protocol Extraction:[0x%04x:0x%04x],", > > + xtr->u.raw.data0, xtr->u.raw.data1); > > + > > + if (xtr->type =3D=3D PROTO_XTR_VLAN) > > + printf("vlan,stag=3D%u:%u:%u,ctag=3D%u:%u:%u ", > > + xtr->u.vlan.stag_pcp, > > + xtr->u.vlan.stag_dei, > > + xtr->u.vlan.stag_vid, > > + xtr->u.vlan.ctag_pcp, > > + xtr->u.vlan.ctag_dei, > > + xtr->u.vlan.ctag_vid); > > + else if (xtr->type =3D=3D PROTO_XTR_IPV4) > > + printf("ipv4,ver=3D%u,hdrlen=3D%u,tos=3D%u,ttl=3D%u,proto=3D%u ", > > + xtr->u.ipv4.version, > > + xtr->u.ipv4.ihl, > > + xtr->u.ipv4.tos, > > + xtr->u.ipv4.ttl, > > + xtr->u.ipv4.protocol); > > + else if (xtr->type =3D=3D PROTO_XTR_IPV6) > > + > > printf("ipv6,ver=3D%u,tc=3D%u,flow_hi4=3D0x%x,nexthdr=3D%u,hoplimit=3D= %u ", > > + xtr->u.ipv6.version, > > + xtr->u.ipv6.tc, > > + xtr->u.ipv6.flowhi4, > > + xtr->u.ipv6.nexthdr, > > + xtr->u.ipv6.hoplimit); > > + else if (xtr->type =3D=3D PROTO_XTR_IPV6_FLOW) > > + printf("ipv6_flow,ver=3D%u,tc=3D%u,flow=3D0x%x%04x ", > > + xtr->u.ipv6_flow.version, > > + xtr->u.ipv6_flow.tc, > > + xtr->u.ipv6_flow.flowhi4, > > + xtr->u.ipv6_flow.flowlo16); > > + else if (xtr->type =3D=3D PROTO_XTR_TCP) > > + printf("tcp,doff=3D%u,flags=3D%s%s%s%s%s%s%s%s ", > > + xtr->u.tcp.doff, > > + xtr->u.tcp.cwr ? "C" : "", > > + xtr->u.tcp.ece ? "E" : "", > > + xtr->u.tcp.urg ? "U" : "", > > + xtr->u.tcp.ack ? "A" : "", > > + xtr->u.tcp.psh ? "P" : "", > > + xtr->u.tcp.rst ? "R" : "", > > + xtr->u.tcp.syn ? "S" : "", > > + xtr->u.tcp.fin ? "F" : ""); > > +} > > + > > +#ifdef __cplusplus > > +} > > +#endif > > + > > +#endif /* _RTE_PMD_ICE_H_ */ > > -- > > 2.17.1