> -----Original Message----- > From: Yang, Qiming > Sent: Monday, September 23, 2019 11:26 > To: Rong, Leyi <leyi.r...@intel.com>; Wang, Haiyue <haiyue.w...@intel.com>; > Lu, Wenzhuo > <wenzhuo...@intel.com>; Zhang, Qi Z <qi.z.zh...@intel.com>; Ye, Xiaolong > <xiaolong...@intel.com> > Cc: dev@dpdk.org > Subject: RE: [dpdk-dev] [PATCH v4 3/6] net/ice: add protocol extraction > support for per Rx queue > > > > > -----Original Message----- > > From: dev [mailto:dev-boun...@dpdk.org] On Behalf Of Leyi Rong > > Sent: Thursday, September 19, 2019 2:26 PM > > To: Wang, Haiyue <haiyue.w...@intel.com>; Lu, Wenzhuo > > <wenzhuo...@intel.com>; Zhang, Qi Z <qi.z.zh...@intel.com>; Ye, Xiaolong > > <xiaolong...@intel.com> > > Cc: dev@dpdk.org > > Subject: [dpdk-dev] [PATCH v4 3/6] net/ice: add protocol extraction support > > for per Rx queue > > > > From: Haiyue Wang <haiyue.w...@intel.com> > > > > The ice has the feature to extract protocol fields into flex descriptor by > > programming per queue. Currently, the ice PMD will put the protocol fields > > into rte_mbuf::udata64 with different type format. Application can access > > the protocol fields quickly. > > > > Signed-off-by: Haiyue Wang <haiyue.w...@intel.com> > > --- > > 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, features > > 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 checking > > the > > TCP SYN packets quickly. > > + > > + The argument format is:: > > + > > + -w 18:00.0,proto_xtr=<queues:protocol>[<queues:protocol>...] > > + -w 18:00.0,proto_xtr=<protocol> > > + > > + 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='[(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 extraction. > > + > > + .. code-block:: console > > + > > + testpmd -w > > 18:00.0,proto_xtr=vlan,proto_xtr='[(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 | > > + +======+===+=================+======+===+=================+ > > + | 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 | > > + +======+=======+=============+==============+=============+ > > + | 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 | > > + +=====+=============+========+=============+==============+ > > + | 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 | > > + +=====+=============+========+============================+ > > + | 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 | > > + +============================+======+======+==============+ > > + | 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 to > > + 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) += ice_generic_flow.c > > > > +# install this header file > > +SYMLINK-$(CONFIG_RTE_LIBRTE_ICE_PMD)-include := 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[] = { > > 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 = 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[] = { > > + { "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 = 0; i < RTE_DIM(xtr_type_map); i++) { > > + if (strcmp(xtr_name, xtr_type_map[i].name) == 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 = input; > > + char *end = NULL; > > + uint32_t min, max; > > + uint32_t idx; > > + > > + while (isblank(*str)) > > + str++; > > + > > + if (!isdigit(*str) && *str != '(') > > + return -1; > > + > > + /* process single number or single range of number */ > > + if (*str != '(') { > > + errno = 0; > > + idx = strtoul(str, &end, 10); > > + if (errno || end == NULL || idx >= ICE_MAX_QUEUE_NUM) > > + return -1; > > + > > + while (isblank(*end)) > > + end++; > > + > > + min = idx; > > + max = idx; > > + > > + /* process single <number>-<number> */ > > + if (*end == '-') { > > + end++; > > + while (isblank(*end)) > > + end++; > > + if (!isdigit(*end)) > > + return -1; > > + > > + errno = 0; > > + idx = strtoul(end, &end, 10); > > + if (errno || end == NULL || idx >= > > ICE_MAX_QUEUE_NUM) > > + return -1; > > + > > + max = idx; > > + while (isblank(*end)) > > + end++; > > + } > > + > > + if (*end != ':') > > + return -1; > > + > > + for (idx = RTE_MIN(min, max); > > + idx <= RTE_MAX(min, max); idx++) > > + devargs->proto_xtr[idx] = xtr_type; > > + > > + return 0; > > + } > > + > > + /* process set within bracket */ > > + str++; > > + while (isblank(*str)) > > + str++; > > + if (*str == '\0') > > + return -1; > > + > > + min = 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 = 0; > > + idx = strtoul(str, &end, 10); > > + if (errno || end == NULL || idx >= ICE_MAX_QUEUE_NUM) > > + return -1; > > + > > + /* go ahead to separator '-',',' and ')' */ > > + while (isblank(*end)) > > + end++; > > + if (*end == '-') { > > + if (min == ICE_MAX_QUEUE_NUM) > > + min = idx; > > + else /* avoid continuous '-' */ > > + return -1; > > + } else if (*end == ',' || *end == ')') { > > + max = idx; > > + if (min == ICE_MAX_QUEUE_NUM) > > + min = idx; > > + > > + for (idx = RTE_MIN(min, max); > > + idx <= RTE_MAX(min, max); idx++) > > + devargs->proto_xtr[idx] = xtr_type; > > + > > + min = ICE_MAX_QUEUE_NUM; > > + } else { > > + return -1; > > + } > > + > > + str = end + 1; > > + } while (*end != ')' && *end != '\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 != '[') { > > + xtr_type = 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 == '\0') > > + return -1; > > + > > + queue_start = queues; > > + > > + /* go across a complete bracket */ > > + if (*queue_start == '(') { > > + queues += strcspn(queues, ")"); > > + if (*queues != ')') > > + return -1; > > + } > > + > > + /* scan the separator ':' */ > > + queues += strcspn(queues, ":"); > > + if (*queues++ != ':') > > + return -1; > > + while (isblank(*queues)) > > + queues++; > > + > > + for (idx = 0; ; idx++) { > > + if (isblank(queues[idx]) || > > + queues[idx] == ',' || > > + queues[idx] == ']' || > > + queues[idx] == '\0') > > + break; > > + > > + if (idx > sizeof(xtr_name) - 2) > > + return -1; > > + > > + xtr_name[idx] = queues[idx]; > > + } > > + xtr_name[idx] = '\0'; > > + xtr_type = lookup_proto_xtr_type(xtr_name); > > + if (xtr_type < 0) > > + return -1; > > + > > + queues += idx; > > + > > + while (isblank(*queues) || *queues == ',' || *queues == ']') > > + queues++; > > + > > + if (parse_queue_set(queue_start, xtr_type, devargs) < 0) > > + return -1; > > + } while (*queues != '\0'); > > + > > + return 0; > > +} > > + > > +static int > > +handle_proto_xtr_arg(__rte_unused const char *key, const char *value, > > + void *extra_args) > > +{ > > + struct ice_devargs *devargs = extra_args; > > + > > + if (value == NULL || extra_args == 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[] = { > > + { 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 = 0; i < RTE_DIM(xtr_sets); i++) { > > + uint32_t rxdid = xtr_sets[i].rxdid; > > + uint32_t v; > > + > > + if (xtr_sets[i].protid_0 != ICE_PROT_ID_INVAL) { > > + v = ICE_READ_REG(hw, > > GLFLXP_RXDID_FLX_WRD_4(rxdid)); > > + > > + if (FLX_REG(v, PROT_MDID, 4) != xtr_sets[i].protid_0 > > || > > + FLX_REG(v, RXDID_OPCODE, 4) != > > ICE_RX_OPC_EXTRACT) > > + return false; > > + } > > + > > + if (xtr_sets[i].protid_1 != ICE_PROT_ID_INVAL) { > > + v = ICE_READ_REG(hw, > > GLFLXP_RXDID_FLX_WRD_5(rxdid)); > > + > > + if (FLX_REG(v, PROT_MDID, 5) != xtr_sets[i].protid_1 > > || > > + FLX_REG(v, RXDID_OPCODE, 5) != > > 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 = > > + ICE_DEV_PRIVATE_TO_ADAPTER(dev->data- > > >dev_private); > > struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private); > > struct ice_hw *hw = ICE_PF_TO_HW(pf); > > > > @@ -1088,6 +1366,16 @@ ice_pf_sw_init(struct rte_eth_dev *dev) > > > > pf->lan_nb_qps = pf->lan_nb_qp_max; > > > > + if (ice_proto_xtr_support(hw)) > > + pf->proto_xtr = rte_zmalloc(NULL, pf->lan_nb_qps, 0); > > + > > + if (pf->proto_xtr != 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 = rte_kvargs_process(kvlist, ICE_PROTO_XTR_ARG, > > + &handle_proto_xtr_arg, &ad->devargs); > > + if (ret) > > + goto bail; > > + > > Why is bail? >
free & ret, since 'ret' is used, 'bail' name from kernel. :) > > ret = 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 = NULL; > > ice_shutdown_all_ctrlq(hw); > > + rte_free(pf->proto_xtr); > > + pf->proto_xtr = 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 > > "=[queue:]<vlan|ipv4|ipv6|ipv6_flow|tcp>" > > ICE_SAFE_MODE_SUPPORT_ARG "=<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 index > > 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[] = { > > + [ICE_RXDID_COMMS_AUX_VLAN] = PROTO_XTR_VLAN, > > + [ICE_RXDID_COMMS_AUX_IPV4] = PROTO_XTR_IPV4, > > + [ICE_RXDID_COMMS_AUX_IPV6] = PROTO_XTR_IPV6, > > + [ICE_RXDID_COMMS_AUX_IPV6_FLOW] = > > PROTO_XTR_IPV6_FLOW, > > + [ICE_RXDID_COMMS_AUX_TCP] = 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[] = { > > + [PROTO_XTR_VLAN] = ICE_RXDID_COMMS_AUX_VLAN, > > + [PROTO_XTR_IPV4] = ICE_RXDID_COMMS_AUX_IPV4, > > + [PROTO_XTR_IPV6] = ICE_RXDID_COMMS_AUX_IPV6, > > + [PROTO_XTR_IPV6_FLOW] = > > ICE_RXDID_COMMS_AUX_IPV6_FLOW, > > + [PROTO_XTR_TCP] = ICE_RXDID_COMMS_AUX_TCP, > > + }; > > + uint8_t rxdid; > > + > > + rxdid = xtr_tpye < RTE_DIM(rxdid_map) ? rxdid_map[xtr_tpye] : 0; > > + > > + return rxdid != 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 = 0; > > rx_ctx.crcstrip = (rxq->crc_len == 0) ? 1 : 0; > > > > + rxdid = 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 = rx_conf->rx_drop_en; > > rxq->vsi = vsi; > > rxq->rx_deferred_start = rx_conf->rx_deferred_start; > > + rxq->proto_xtr = pf->proto_xtr != NULL ? > > + pf->proto_xtr[queue_idx] : PROTO_XTR_NONE; > > > > /* Allocate the maximun number of RX ring hardware descriptor. */ > > len = ICE_MAX_RING_DESC; > > @@ -1062,6 +1099,10 @@ ice_rxd_to_vlan_tci(struct rte_mbuf *mb, volatile > > 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 |= PKT_RX_RSS_HASH; > > mb->hash.rss = rte_le_to_cpu_32(desc->rss_hash); > > } > > + > > +#ifndef RTE_LIBRTE_ICE_16BYTE_RX_DESC > > + init_proto_xtr_flds(mb); > > + > > + stat_err = rte_le_to_cpu_16(desc->status_error1); > > + if (stat_err & ICE_RX_PROTO_XTR_VALID) { > > + struct proto_xtr_flds *xtr = get_proto_xtr_flds(mb); > > + > > + if (stat_err & (1 << > > ICE_RX_FLEX_DESC_STATUS1_XTRMD4_VALID_S)) > > + xtr->u.raw.data0 = > > + 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 = > > + rte_le_to_cpu_16(desc->flex_ts.flex.aux1); > > + > > + xtr->type = ice_rxdid_to_proto_xtr_type(desc->rxdid); > > + xtr->magic = 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 index > > 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 != 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 == 'x86' > > objs += 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_ice.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 <stdio.h> > > +#include <rte_mbuf.h> > > +#include <rte_ethdev.h> > > + > > +#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 = 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 = get_proto_xtr_flds(mb); > > + > > + if (xtr->magic != PROTO_XTR_MAGIC_ID || xtr->type == > > PROTO_XTR_NONE) > > + return; > > + > > + printf(" - Protocol Extraction:[0x%04x:0x%04x],", > > + xtr->u.raw.data0, xtr->u.raw.data1); > > + > > + if (xtr->type == PROTO_XTR_VLAN) > > + printf("vlan,stag=%u:%u:%u,ctag=%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 == PROTO_XTR_IPV4) > > + printf("ipv4,ver=%u,hdrlen=%u,tos=%u,ttl=%u,proto=%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 == PROTO_XTR_IPV6) > > + > > printf("ipv6,ver=%u,tc=%u,flow_hi4=0x%x,nexthdr=%u,hoplimit=%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 == PROTO_XTR_IPV6_FLOW) > > + printf("ipv6_flow,ver=%u,tc=%u,flow=0x%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 == PROTO_XTR_TCP) > > + printf("tcp,doff=%u,flags=%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