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 612FFA2EFC for ; Thu, 19 Sep 2019 01:33:03 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C63651D177; Thu, 19 Sep 2019 01:33:01 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 2BD5C1D149 for ; Thu, 19 Sep 2019 01:32:59 +0200 (CEST) X-Amp-Result: UNKNOWN X-Amp-Original-Verdict: FILE UNKNOWN X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Sep 2019 16:32:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,522,1559545200"; d="scan'208";a="189418594" Received: from yexl-server.sh.intel.com (HELO localhost) ([10.67.117.5]) by orsmga003.jf.intel.com with ESMTP; 18 Sep 2019 16:32:56 -0700 Date: Thu, 19 Sep 2019 07:30:17 +0800 From: Ye Xiaolong To: Leyi Rong Cc: haiyue.wang@intel.com, wenzhuo.lu@intel.com, qi.z.zhang@intel.com, dev@dpdk.org Message-ID: <20190918233017.GA77813@intel.com> References: <20190829023421.112551-1-leyi.rong@intel.com> <20190917085317.57598-1-leyi.rong@intel.com> <20190917085317.57598-4-leyi.rong@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190917085317.57598-4-leyi.rong@intel.com> User-Agent: Mutt/1.9.4 (2018-02-28) Subject: Re: [dpdk-dev] [PATCH v3 3/5] 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" On 09/17, Leyi Rong wrote: >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 >fields into rte_mbuf::udata64 with different type format. Application >can access the protocol fields quickly. > [snip] >+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 != '(') || (*str == '\0')) Minor nit, (*str == '\0') seems redundant here, no? >+ 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 - */ >+ 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; >+ >+ devargs->proto_xtr_dflt = xtr_type; If we memset(devargs->proto_xtr, xtr_type, ICE_MAX_QUEUE_NUM) here, seems we don't need proto_xtr_dflt. >+ 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 void >+ice_parse_proto_xtr_devarg(struct rte_kvargs *kvlist, >+ struct ice_devargs *devargs) >+{ >+ int i; >+ >+ devargs->proto_xtr_dflt = PROTO_XTR_NONE; >+ >+ for (i = 0; i < ICE_MAX_QUEUE_NUM; i++) >+ devargs->proto_xtr[i] = PROTO_XTR_NONE; memset(devargs->proto_xtr, PROTO_XTR_NONE, ICE_MAX_QUEUE_NUM) ? >+ >+ rte_kvargs_process(kvlist, ICE_PROTO_XTR_ARG, >+ handle_proto_xtr_arg, devargs); Do we need to check ret of rte_kvargs_process here and change ice_parse_proto_xtr_devarg to return int? >+} >+ >+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 +1368,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 +1379,21 @@ 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) { >+ uint16_t i; >+ >+ for (i = 0; i < pf->lan_nb_qps; i++) >+ pf->proto_xtr[i] = >+ ad->devargs.proto_xtr[i] != PROTO_XTR_NONE ? >+ ad->devargs.proto_xtr[i] : >+ ad->devargs.proto_xtr_dflt; >+ } else { >+ PMD_DRV_LOG(NOTICE, "Protocol extraction is disabled"); >+ } >+ > return 0; > } > >@@ -1378,6 +1684,8 @@ static int ice_parse_devargs(struct rte_eth_dev *dev) > return -EINVAL; > } > >+ ice_parse_proto_xtr_devarg(kvlist, &ad->devargs); >+ > ret = rte_kvargs_process(kvlist, ICE_SAFE_MODE_SUPPORT_ARG, > &parse_bool, &ad->devargs.safe_mode_support); > >@@ -1547,6 +1855,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 +1981,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 +4106,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:]" > 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..e58192104 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,15 @@ 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_dflt; >+ 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 >+#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 = 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 >