get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/80817/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 80817,
    "url": "https://patches.dpdk.org/api/patches/80817/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20201015034130.72551-1-jia.guo@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20201015034130.72551-1-jia.guo@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20201015034130.72551-1-jia.guo@intel.com",
    "date": "2020-10-15T03:41:30",
    "name": "[v9] net/iavf: support flex desc metadata extraction",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "0423177cf6b1591b79ee0d74d1e7453acc795f95",
    "submitter": {
        "id": 507,
        "url": "https://patches.dpdk.org/api/people/507/?format=api",
        "name": "Guo, Jia",
        "email": "jia.guo@intel.com"
    },
    "delegate": {
        "id": 1540,
        "url": "https://patches.dpdk.org/api/users/1540/?format=api",
        "username": "qzhan15",
        "first_name": "Qi",
        "last_name": "Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20201015034130.72551-1-jia.guo@intel.com/mbox/",
    "series": [
        {
            "id": 12982,
            "url": "https://patches.dpdk.org/api/series/12982/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=12982",
            "date": "2020-10-15T03:41:30",
            "name": "[v9] net/iavf: support flex desc metadata extraction",
            "version": 9,
            "mbox": "https://patches.dpdk.org/series/12982/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/80817/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/80817/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id D3BB6A04DB;\n\tThu, 15 Oct 2020 05:48:01 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 446171DBCC;\n\tThu, 15 Oct 2020 05:48:00 +0200 (CEST)",
            "from mga04.intel.com (mga04.intel.com [192.55.52.120])\n by dpdk.org (Postfix) with ESMTP id 5CEFC1D557\n for <dev@dpdk.org>; Thu, 15 Oct 2020 05:47:58 +0200 (CEST)",
            "from fmsmga001.fm.intel.com ([10.253.24.23])\n by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 14 Oct 2020 20:47:56 -0700",
            "from npg-dpdk-cvl-jeffguo-01.sh.intel.com ([10.67.111.128])\n by fmsmga001.fm.intel.com with ESMTP; 14 Oct 2020 20:47:53 -0700"
        ],
        "IronPort-SDR": [
            "\n QGq7V+biWrNzmreeA7sy0jnrX+IVvnymnD5/Vgx+ZIJu3y6dDZTBQcKEEzgKBFVWLHJF4Nwzx6\n UcrUkenBA4+g==",
            "\n clh9cTvSGrFmV7JJJjQr+U1GiDAa4YbGVX5g3nvRx+KTbbMSJnmcqMnWqWe3FzZZoXyLTwxify\n QWdqmMTbgW/g=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9774\"; a=\"163619696\"",
            "E=Sophos;i=\"5.77,377,1596524400\"; d=\"scan'208\";a=\"163619696\"",
            "E=Sophos;i=\"5.77,377,1596524400\"; d=\"scan'208\";a=\"421041948\""
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "From": "Jeff Guo <jia.guo@intel.com>",
        "To": "jingjing.wu@intel.com, qi.z.zhang@intel.com, beilei.xing@intel.com,\n ferruh.yigit@intel.com",
        "Cc": "dev@dpdk.org, haiyue.wang@intel.com, bruce.richardson@intel.com,\n jia.guo@intel.com",
        "Date": "Thu, 15 Oct 2020 11:41:30 +0800",
        "Message-Id": "<20201015034130.72551-1-jia.guo@intel.com>",
        "X-Mailer": "git-send-email 2.20.1",
        "In-Reply-To": "<20200909025415.6185-1-jia.guo@intel.com>",
        "References": "<20200909025415.6185-1-jia.guo@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v9] net/iavf: support flex desc metadata\n\textraction",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Enable metadata extraction for flexible descriptors in AVF, that would\nallow network function directly get metadata without additional parsing\nwhich would reduce the CPU cost for VFs. The enabling metadata\nextractions involve the metadata of VLAN/IPv4/IPv6/IPv6-FLOW/TCP/MPLS\nflexible descriptors, and the VF could negotiate the capability of\nthe flexible descriptor with PF and correspondingly configure the\nspecific offload at receiving queues.\n\nSigned-off-by: Jeff Guo <jia.guo@intel.com>\nAcked-by: Haiyue Wang <haiyue.wang@intel.com>\n---\nv9:\nchange the undef config\n\nv8:\nrebase patch for apply issue\n\nv7:\nclean some useless and add doc\n\nv6:\nrebase patch\n\nv5:\nremove ovs configure since ovs is not protocol extraction\n\nv4:\nadd flex desc type in rx queue for handling vector path\nhandle ovs flex type\n\nv3:\nexport these global symbols into .map\n\nv2:\nremove makefile change and modify the rxdid handling\n---\n config/rte_config.h                       |   3 +\n doc/guides/nics/intel_vf.rst              |  16 +\n doc/guides/rel_notes/release_20_11.rst    |   6 +\n drivers/net/iavf/iavf.h                   |  24 +-\n drivers/net/iavf/iavf_ethdev.c            | 394 ++++++++++++++++++++++\n drivers/net/iavf/iavf_rxtx.c              | 252 ++++++++++++--\n drivers/net/iavf/iavf_rxtx.h              | 168 +++++----\n drivers/net/iavf/iavf_rxtx_vec_common.h   |   3 +\n drivers/net/iavf/iavf_vchnl.c             |  22 +-\n drivers/net/iavf/meson.build              |   2 +\n drivers/net/iavf/rte_pmd_iavf.h           | 250 ++++++++++++++\n drivers/net/iavf/rte_pmd_iavf_version.map |  13 +\n 12 files changed, 1039 insertions(+), 114 deletions(-)\n create mode 100644 drivers/net/iavf/rte_pmd_iavf.h",
    "diff": "diff --git a/config/rte_config.h b/config/rte_config.h\nindex 03d90d78bc..67a7ad66df 100644\n--- a/config/rte_config.h\n+++ b/config/rte_config.h\n@@ -127,6 +127,9 @@\n #define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF 4\n #define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM 4\n \n+/* iavf defines */\n+// RTE_LIBRTE_IAVF_16BYTE_RX_DESC is not set\n+\n /* Ring net PMD settings */\n #define RTE_PMD_RING_MAX_RX_RINGS 16\n #define RTE_PMD_RING_MAX_TX_RINGS 16\ndiff --git a/doc/guides/nics/intel_vf.rst b/doc/guides/nics/intel_vf.rst\nindex ade5152595..207f456143 100644\n--- a/doc/guides/nics/intel_vf.rst\n+++ b/doc/guides/nics/intel_vf.rst\n@@ -615,3 +615,19 @@ which belongs to the destination VF on the VM.\n .. figure:: img/inter_vm_comms.*\n \n    Inter-VM Communication\n+\n+\n+Pre-Installation Configuration\n+------------------------------\n+\n+Config File Options\n+~~~~~~~~~~~~~~~~~~~\n+\n+The following options can be modified in the ``config`` file.\n+Please note that enabling debugging options may affect system performance.\n+\n+- ``CONFIG_RTE_LIBRTE_IAVF_16BYTE_RX_DESC`` (default ``n``)\n+\n+  Toggle to use a 16-byte RX descriptor, by default the RX descriptor is 32 byte.\n+  Configure to 16-byte Rx descriptor may cause a negotiation failure during VF driver initialization\n+  if the PF driver doesn't support.\ndiff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst\nindex 30db8f27e9..e8ae4d4912 100644\n--- a/doc/guides/rel_notes/release_20_11.rst\n+++ b/doc/guides/rel_notes/release_20_11.rst\n@@ -183,6 +183,12 @@ New Features\n   packets with specified ratio, and apply with own set of actions with a fate\n   action. When the ratio is set to 1 then the packets will be 100% mirrored.\n \n+* **Updated Intel iavf driver.**\n+\n+  Updated iavf PMD with new features and improvements, including:\n+\n+  * Added support for flexible descriptor metadata extraction.\n+\n \n Removed Items\n -------------\ndiff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h\nindex 3198d85b3a..d566116086 100644\n--- a/drivers/net/iavf/iavf.h\n+++ b/drivers/net/iavf/iavf.h\n@@ -119,7 +119,7 @@ struct iavf_info {\n \tstruct virtchnl_vf_resource *vf_res; /* VF resource */\n \tstruct virtchnl_vsi_resource *vsi_res; /* LAN VSI */\n \tuint64_t supported_rxdid;\n-\n+\tuint8_t *proto_xtr; /* proto xtr type for all queues */\n \tvolatile enum virtchnl_ops pend_cmd; /* pending command not finished */\n \tuint32_t cmd_retval; /* return value of the cmd response from PF */\n \tuint8_t *aq_resp; /* buffer to store the adminq response from PF */\n@@ -153,6 +153,27 @@ struct iavf_info {\n \n #define IAVF_MAX_PKT_TYPE 1024\n \n+#define IAVF_MAX_QUEUE_NUM  2048\n+\n+enum iavf_proto_xtr_type {\n+\tIAVF_PROTO_XTR_NONE,\n+\tIAVF_PROTO_XTR_VLAN,\n+\tIAVF_PROTO_XTR_IPV4,\n+\tIAVF_PROTO_XTR_IPV6,\n+\tIAVF_PROTO_XTR_IPV6_FLOW,\n+\tIAVF_PROTO_XTR_TCP,\n+\tIAVF_PROTO_XTR_IP_OFFSET,\n+\tIAVF_PROTO_XTR_MAX,\n+};\n+\n+/**\n+ * Cache devargs parse result.\n+ */\n+struct iavf_devargs {\n+\tuint8_t proto_xtr_dflt;\n+\tuint8_t proto_xtr[IAVF_MAX_QUEUE_NUM];\n+};\n+\n /* Structure to store private data for each VF instance. */\n struct iavf_adapter {\n \tstruct iavf_hw hw;\n@@ -166,6 +187,7 @@ struct iavf_adapter {\n \tconst uint32_t *ptype_tbl;\n \tbool stopped;\n \tuint16_t fdir_ref_cnt;\n+\tstruct iavf_devargs devargs;\n };\n \n /* IAVF_DEV_PRIVATE_TO */\ndiff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c\nindex f5e6e852ae..93e26c768c 100644\n--- a/drivers/net/iavf/iavf_ethdev.c\n+++ b/drivers/net/iavf/iavf_ethdev.c\n@@ -28,6 +28,49 @@\n #include \"iavf.h\"\n #include \"iavf_rxtx.h\"\n #include \"iavf_generic_flow.h\"\n+#include \"rte_pmd_iavf.h\"\n+\n+/* devargs */\n+#define IAVF_PROTO_XTR_ARG         \"proto_xtr\"\n+\n+static const char * const iavf_valid_args[] = {\n+\tIAVF_PROTO_XTR_ARG,\n+\tNULL\n+};\n+\n+static const struct rte_mbuf_dynfield iavf_proto_xtr_metadata_param = {\n+\t.name = \"iavf_dynfield_proto_xtr_metadata\",\n+\t.size = sizeof(uint32_t),\n+\t.align = __alignof__(uint32_t),\n+\t.flags = 0,\n+};\n+\n+struct iavf_proto_xtr_ol {\n+\tconst struct rte_mbuf_dynflag param;\n+\tuint64_t *ol_flag;\n+\tbool required;\n+};\n+\n+static struct iavf_proto_xtr_ol iavf_proto_xtr_params[] = {\n+\t[IAVF_PROTO_XTR_VLAN] = {\n+\t\t.param = { .name = \"iavf_dynflag_proto_xtr_vlan\" },\n+\t\t.ol_flag = &rte_net_iavf_dynflag_proto_xtr_vlan_mask },\n+\t[IAVF_PROTO_XTR_IPV4] = {\n+\t\t.param = { .name = \"iavf_dynflag_proto_xtr_ipv4\" },\n+\t\t.ol_flag = &rte_net_iavf_dynflag_proto_xtr_ipv4_mask },\n+\t[IAVF_PROTO_XTR_IPV6] = {\n+\t\t.param = { .name = \"iavf_dynflag_proto_xtr_ipv6\" },\n+\t\t.ol_flag = &rte_net_iavf_dynflag_proto_xtr_ipv6_mask },\n+\t[IAVF_PROTO_XTR_IPV6_FLOW] = {\n+\t\t.param = { .name = \"iavf_dynflag_proto_xtr_ipv6_flow\" },\n+\t\t.ol_flag = &rte_net_iavf_dynflag_proto_xtr_ipv6_flow_mask },\n+\t[IAVF_PROTO_XTR_TCP] = {\n+\t\t.param = { .name = \"iavf_dynflag_proto_xtr_tcp\" },\n+\t\t.ol_flag = &rte_net_iavf_dynflag_proto_xtr_tcp_mask },\n+\t[IAVF_PROTO_XTR_IP_OFFSET] = {\n+\t\t.param = { .name = \"ice_dynflag_proto_xtr_ip_offset\" },\n+\t\t.ol_flag = &rte_net_iavf_dynflag_proto_xtr_ip_offset_mask },\n+};\n \n static int iavf_dev_configure(struct rte_eth_dev *dev);\n static int iavf_dev_start(struct rte_eth_dev *dev);\n@@ -1247,6 +1290,349 @@ iavf_check_vf_reset_done(struct iavf_hw *hw)\n \treturn 0;\n }\n \n+static int\n+iavf_lookup_proto_xtr_type(const char *flex_name)\n+{\n+\tstatic struct {\n+\t\tconst char *name;\n+\t\tenum iavf_proto_xtr_type type;\n+\t} xtr_type_map[] = {\n+\t\t{ \"vlan\",      IAVF_PROTO_XTR_VLAN      },\n+\t\t{ \"ipv4\",      IAVF_PROTO_XTR_IPV4      },\n+\t\t{ \"ipv6\",      IAVF_PROTO_XTR_IPV6      },\n+\t\t{ \"ipv6_flow\", IAVF_PROTO_XTR_IPV6_FLOW },\n+\t\t{ \"tcp\",       IAVF_PROTO_XTR_TCP       },\n+\t\t{ \"ip_offset\", IAVF_PROTO_XTR_IP_OFFSET },\n+\t};\n+\tuint32_t i;\n+\n+\tfor (i = 0; i < RTE_DIM(xtr_type_map); i++) {\n+\t\tif (strcmp(flex_name, xtr_type_map[i].name) == 0)\n+\t\t\treturn xtr_type_map[i].type;\n+\t}\n+\n+\tPMD_DRV_LOG(ERR, \"wrong proto_xtr type, \"\n+\t\t    \"it should be: vlan|ipv4|ipv6|ipv6_flow|tcp|ip_offset\");\n+\n+\treturn -1;\n+}\n+\n+/**\n+ * Parse elem, the elem could be single number/range or '(' ')' group\n+ * 1) A single number elem, it's just a simple digit. e.g. 9\n+ * 2) A single range elem, two digits with a '-' between. e.g. 2-6\n+ * 3) A group elem, combines multiple 1) or 2) with '( )'. e.g (0,2-4,6)\n+ *    Within group elem, '-' used for a range separator;\n+ *                       ',' used for a single number.\n+ */\n+static int\n+iavf_parse_queue_set(const char *input, int xtr_type,\n+\t\t     struct iavf_devargs *devargs)\n+{\n+\tconst char *str = input;\n+\tchar *end = NULL;\n+\tuint32_t min, max;\n+\tuint32_t idx;\n+\n+\twhile (isblank(*str))\n+\t\tstr++;\n+\n+\tif (!isdigit(*str) && *str != '(')\n+\t\treturn -1;\n+\n+\t/* process single number or single range of number */\n+\tif (*str != '(') {\n+\t\terrno = 0;\n+\t\tidx = strtoul(str, &end, 10);\n+\t\tif (errno || !end || idx >= IAVF_MAX_QUEUE_NUM)\n+\t\t\treturn -1;\n+\n+\t\twhile (isblank(*end))\n+\t\t\tend++;\n+\n+\t\tmin = idx;\n+\t\tmax = idx;\n+\n+\t\t/* process single <number>-<number> */\n+\t\tif (*end == '-') {\n+\t\t\tend++;\n+\t\t\twhile (isblank(*end))\n+\t\t\t\tend++;\n+\t\t\tif (!isdigit(*end))\n+\t\t\t\treturn -1;\n+\n+\t\t\terrno = 0;\n+\t\t\tidx = strtoul(end, &end, 10);\n+\t\t\tif (errno || !end || idx >= IAVF_MAX_QUEUE_NUM)\n+\t\t\t\treturn -1;\n+\n+\t\t\tmax = idx;\n+\t\t\twhile (isblank(*end))\n+\t\t\t\tend++;\n+\t\t}\n+\n+\t\tif (*end != ':')\n+\t\t\treturn -1;\n+\n+\t\tfor (idx = RTE_MIN(min, max);\n+\t\t     idx <= RTE_MAX(min, max); idx++)\n+\t\t\tdevargs->proto_xtr[idx] = xtr_type;\n+\n+\t\treturn 0;\n+\t}\n+\n+\t/* process set within bracket */\n+\tstr++;\n+\twhile (isblank(*str))\n+\t\tstr++;\n+\tif (*str == '\\0')\n+\t\treturn -1;\n+\n+\tmin = IAVF_MAX_QUEUE_NUM;\n+\tdo {\n+\t\t/* go ahead to the first digit */\n+\t\twhile (isblank(*str))\n+\t\t\tstr++;\n+\t\tif (!isdigit(*str))\n+\t\t\treturn -1;\n+\n+\t\t/* get the digit value */\n+\t\terrno = 0;\n+\t\tidx = strtoul(str, &end, 10);\n+\t\tif (errno || !end || idx >= IAVF_MAX_QUEUE_NUM)\n+\t\t\treturn -1;\n+\n+\t\t/* go ahead to separator '-',',' and ')' */\n+\t\twhile (isblank(*end))\n+\t\t\tend++;\n+\t\tif (*end == '-') {\n+\t\t\tif (min == IAVF_MAX_QUEUE_NUM)\n+\t\t\t\tmin = idx;\n+\t\t\telse /* avoid continuous '-' */\n+\t\t\t\treturn -1;\n+\t\t} else if (*end == ',' || *end == ')') {\n+\t\t\tmax = idx;\n+\t\t\tif (min == IAVF_MAX_QUEUE_NUM)\n+\t\t\t\tmin = idx;\n+\n+\t\t\tfor (idx = RTE_MIN(min, max);\n+\t\t\t     idx <= RTE_MAX(min, max); idx++)\n+\t\t\t\tdevargs->proto_xtr[idx] = xtr_type;\n+\n+\t\t\tmin = IAVF_MAX_QUEUE_NUM;\n+\t\t} else {\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tstr = end + 1;\n+\t} while (*end != ')' && *end != '\\0');\n+\n+\treturn 0;\n+}\n+\n+static int\n+iavf_parse_queue_proto_xtr(const char *queues, struct iavf_devargs *devargs)\n+{\n+\tconst char *queue_start;\n+\tuint32_t idx;\n+\tint xtr_type;\n+\tchar flex_name[32];\n+\n+\twhile (isblank(*queues))\n+\t\tqueues++;\n+\n+\tif (*queues != '[') {\n+\t\txtr_type = iavf_lookup_proto_xtr_type(queues);\n+\t\tif (xtr_type < 0)\n+\t\t\treturn -1;\n+\n+\t\tdevargs->proto_xtr_dflt = xtr_type;\n+\n+\t\treturn 0;\n+\t}\n+\n+\tqueues++;\n+\tdo {\n+\t\twhile (isblank(*queues))\n+\t\t\tqueues++;\n+\t\tif (*queues == '\\0')\n+\t\t\treturn -1;\n+\n+\t\tqueue_start = queues;\n+\n+\t\t/* go across a complete bracket */\n+\t\tif (*queue_start == '(') {\n+\t\t\tqueues += strcspn(queues, \")\");\n+\t\t\tif (*queues != ')')\n+\t\t\t\treturn -1;\n+\t\t}\n+\n+\t\t/* scan the separator ':' */\n+\t\tqueues += strcspn(queues, \":\");\n+\t\tif (*queues++ != ':')\n+\t\t\treturn -1;\n+\t\twhile (isblank(*queues))\n+\t\t\tqueues++;\n+\n+\t\tfor (idx = 0; ; idx++) {\n+\t\t\tif (isblank(queues[idx]) ||\n+\t\t\t    queues[idx] == ',' ||\n+\t\t\t    queues[idx] == ']' ||\n+\t\t\t    queues[idx] == '\\0')\n+\t\t\t\tbreak;\n+\n+\t\t\tif (idx > sizeof(flex_name) - 2)\n+\t\t\t\treturn -1;\n+\n+\t\t\tflex_name[idx] = queues[idx];\n+\t\t}\n+\t\tflex_name[idx] = '\\0';\n+\t\txtr_type = iavf_lookup_proto_xtr_type(flex_name);\n+\t\tif (xtr_type < 0)\n+\t\t\treturn -1;\n+\n+\t\tqueues += idx;\n+\n+\t\twhile (isblank(*queues) || *queues == ',' || *queues == ']')\n+\t\t\tqueues++;\n+\n+\t\tif (iavf_parse_queue_set(queue_start, xtr_type, devargs) < 0)\n+\t\t\treturn -1;\n+\t} while (*queues != '\\0');\n+\n+\treturn 0;\n+}\n+\n+static int\n+iavf_handle_proto_xtr_arg(__rte_unused const char *key, const char *value,\n+\t\t\t  void *extra_args)\n+{\n+\tstruct iavf_devargs *devargs = extra_args;\n+\n+\tif (!value || !extra_args)\n+\t\treturn -EINVAL;\n+\n+\tif (iavf_parse_queue_proto_xtr(value, devargs) < 0) {\n+\t\tPMD_DRV_LOG(ERR, \"the proto_xtr's parameter is wrong : '%s'\",\n+\t\t\t    value);\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int iavf_parse_devargs(struct rte_eth_dev *dev)\n+{\n+\tstruct iavf_adapter *ad =\n+\t\tIAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n+\tstruct rte_devargs *devargs = dev->device->devargs;\n+\tstruct rte_kvargs *kvlist;\n+\tint ret;\n+\n+\tif (!devargs)\n+\t\treturn 0;\n+\n+\tkvlist = rte_kvargs_parse(devargs->args, iavf_valid_args);\n+\tif (!kvlist) {\n+\t\tPMD_INIT_LOG(ERR, \"invalid kvargs key\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tad->devargs.proto_xtr_dflt = IAVF_PROTO_XTR_NONE;\n+\tmemset(ad->devargs.proto_xtr, IAVF_PROTO_XTR_NONE,\n+\t       sizeof(ad->devargs.proto_xtr));\n+\n+\tret = rte_kvargs_process(kvlist, IAVF_PROTO_XTR_ARG,\n+\t\t\t\t &iavf_handle_proto_xtr_arg, &ad->devargs);\n+\tif (ret)\n+\t\tgoto bail;\n+\n+bail:\n+\trte_kvargs_free(kvlist);\n+\treturn ret;\n+}\n+\n+static void\n+iavf_init_proto_xtr(struct rte_eth_dev *dev)\n+{\n+\tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);\n+\tstruct iavf_adapter *ad =\n+\t\t\tIAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n+\tconst struct iavf_proto_xtr_ol *xtr_ol;\n+\tbool proto_xtr_enable = false;\n+\tint offset;\n+\tuint16_t i;\n+\n+\tvf->proto_xtr = rte_zmalloc(\"vf proto xtr\",\n+\t\t\t\t    vf->vsi_res->num_queue_pairs, 0);\n+\tif (unlikely(!(vf->proto_xtr))) {\n+\t\tPMD_DRV_LOG(ERR, \"no memory for setting up proto_xtr's table\");\n+\t\treturn;\n+\t}\n+\n+\tfor (i = 0; i < vf->vsi_res->num_queue_pairs; i++) {\n+\t\tvf->proto_xtr[i] = ad->devargs.proto_xtr[i] !=\n+\t\t\t\t\tIAVF_PROTO_XTR_NONE ?\n+\t\t\t\t\tad->devargs.proto_xtr[i] :\n+\t\t\t\t\tad->devargs.proto_xtr_dflt;\n+\n+\t\tif (vf->proto_xtr[i] != IAVF_PROTO_XTR_NONE) {\n+\t\t\tuint8_t type = vf->proto_xtr[i];\n+\n+\t\t\tiavf_proto_xtr_params[type].required = true;\n+\t\t\tproto_xtr_enable = true;\n+\t\t}\n+\t}\n+\n+\tif (likely(!proto_xtr_enable))\n+\t\treturn;\n+\n+\toffset = rte_mbuf_dynfield_register(&iavf_proto_xtr_metadata_param);\n+\tif (unlikely(offset == -1)) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"failed to extract protocol metadata, error %d\",\n+\t\t\t    -rte_errno);\n+\t\treturn;\n+\t}\n+\n+\tPMD_DRV_LOG(DEBUG,\n+\t\t    \"proto_xtr metadata offset in mbuf is : %d\",\n+\t\t    offset);\n+\trte_net_iavf_dynfield_proto_xtr_metadata_offs = offset;\n+\n+\tfor (i = 0; i < RTE_DIM(iavf_proto_xtr_params); i++) {\n+\t\txtr_ol = &iavf_proto_xtr_params[i];\n+\n+\t\tuint8_t rxdid = iavf_proto_xtr_type_to_rxdid((uint8_t)i);\n+\n+\t\tif (!xtr_ol->required)\n+\t\t\tcontinue;\n+\n+\t\tif (!(vf->supported_rxdid & BIT(rxdid))) {\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t    \"rxdid[%u] is not supported in hardware\",\n+\t\t\t\t    rxdid);\n+\t\t\trte_net_iavf_dynfield_proto_xtr_metadata_offs = -1;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\toffset = rte_mbuf_dynflag_register(&xtr_ol->param);\n+\t\tif (unlikely(offset == -1)) {\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t    \"failed to register proto_xtr offload '%s', error %d\",\n+\t\t\t\t    xtr_ol->param.name, -rte_errno);\n+\n+\t\t\trte_net_iavf_dynfield_proto_xtr_metadata_offs = -1;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tPMD_DRV_LOG(DEBUG,\n+\t\t\t    \"proto_xtr offload '%s' offset in mbuf is : %d\",\n+\t\t\t    xtr_ol->param.name, offset);\n+\t\t*xtr_ol->ol_flag = 1ULL << offset;\n+\t}\n+}\n+\n static int\n iavf_init_vf(struct rte_eth_dev *dev)\n {\n@@ -1256,6 +1642,12 @@ iavf_init_vf(struct rte_eth_dev *dev)\n \tstruct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);\n \n+\terr = iavf_parse_devargs(dev);\n+\tif (err) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to parse devargs\");\n+\t\tgoto err;\n+\t}\n+\n \terr = iavf_set_mac_type(hw);\n \tif (err) {\n \t\tPMD_INIT_LOG(ERR, \"set_mac_type failed: %d\", err);\n@@ -1319,6 +1711,8 @@ iavf_init_vf(struct rte_eth_dev *dev)\n \t\t}\n \t}\n \n+\tiavf_init_proto_xtr(dev);\n+\n \treturn 0;\n err_rss:\n \trte_free(vf->rss_key);\ndiff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c\nindex 1b0efe0433..7e6e425ac8 100644\n--- a/drivers/net/iavf/iavf_rxtx.c\n+++ b/drivers/net/iavf/iavf_rxtx.c\n@@ -26,6 +26,35 @@\n \n #include \"iavf.h\"\n #include \"iavf_rxtx.h\"\n+#include \"rte_pmd_iavf.h\"\n+\n+/* Offset of mbuf dynamic field for protocol extraction's metadata */\n+int rte_net_iavf_dynfield_proto_xtr_metadata_offs = -1;\n+\n+/* Mask of mbuf dynamic flags for protocol extraction's type */\n+uint64_t rte_net_iavf_dynflag_proto_xtr_vlan_mask;\n+uint64_t rte_net_iavf_dynflag_proto_xtr_ipv4_mask;\n+uint64_t rte_net_iavf_dynflag_proto_xtr_ipv6_mask;\n+uint64_t rte_net_iavf_dynflag_proto_xtr_ipv6_flow_mask;\n+uint64_t rte_net_iavf_dynflag_proto_xtr_tcp_mask;\n+uint64_t rte_net_iavf_dynflag_proto_xtr_ip_offset_mask;\n+\n+uint8_t\n+iavf_proto_xtr_type_to_rxdid(uint8_t flex_type)\n+{\n+\tstatic uint8_t rxdid_map[] = {\n+\t\t[IAVF_PROTO_XTR_NONE]      = IAVF_RXDID_COMMS_OVS_1,\n+\t\t[IAVF_PROTO_XTR_VLAN]      = IAVF_RXDID_COMMS_AUX_VLAN,\n+\t\t[IAVF_PROTO_XTR_IPV4]      = IAVF_RXDID_COMMS_AUX_IPV4,\n+\t\t[IAVF_PROTO_XTR_IPV6]      = IAVF_RXDID_COMMS_AUX_IPV6,\n+\t\t[IAVF_PROTO_XTR_IPV6_FLOW] = IAVF_RXDID_COMMS_AUX_IPV6_FLOW,\n+\t\t[IAVF_PROTO_XTR_TCP]       = IAVF_RXDID_COMMS_AUX_TCP,\n+\t\t[IAVF_PROTO_XTR_IP_OFFSET] = IAVF_RXDID_COMMS_AUX_IP_OFFSET,\n+\t};\n+\n+\treturn flex_type < RTE_DIM(rxdid_map) ?\n+\t\t\t\trxdid_map[flex_type] : IAVF_RXDID_COMMS_OVS_1;\n+}\n \n static inline int\n check_rx_thresh(uint16_t nb_desc, uint16_t thresh)\n@@ -294,6 +323,160 @@ static const struct iavf_txq_ops def_txq_ops = {\n \t.release_mbufs = release_txq_mbufs,\n };\n \n+static inline void\n+iavf_rxd_to_pkt_fields_by_comms_ovs(__rte_unused struct iavf_rx_queue *rxq,\n+\t\t\t\t    struct rte_mbuf *mb,\n+\t\t\t\t    volatile union iavf_rx_flex_desc *rxdp)\n+{\n+\tvolatile struct iavf_32b_rx_flex_desc_comms_ovs *desc =\n+\t\t\t(volatile struct iavf_32b_rx_flex_desc_comms_ovs *)rxdp;\n+#ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC\n+\tuint16_t stat_err;\n+#endif\n+\n+\tif (desc->flow_id != 0xFFFFFFFF) {\n+\t\tmb->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;\n+\t\tmb->hash.fdir.hi = rte_le_to_cpu_32(desc->flow_id);\n+\t}\n+\n+#ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC\n+\tstat_err = rte_le_to_cpu_16(desc->status_error0);\n+\tif (likely(stat_err & (1 << IAVF_RX_FLEX_DESC_STATUS0_RSS_VALID_S))) {\n+\t\tmb->ol_flags |= PKT_RX_RSS_HASH;\n+\t\tmb->hash.rss = rte_le_to_cpu_32(desc->rss_hash);\n+\t}\n+#endif\n+}\n+\n+static inline void\n+iavf_rxd_to_pkt_fields_by_comms_aux_v1(struct iavf_rx_queue *rxq,\n+\t\t\t\t       struct rte_mbuf *mb,\n+\t\t\t\t       volatile union iavf_rx_flex_desc *rxdp)\n+{\n+\tvolatile struct iavf_32b_rx_flex_desc_comms *desc =\n+\t\t\t(volatile struct iavf_32b_rx_flex_desc_comms *)rxdp;\n+\tuint16_t stat_err;\n+\n+\tstat_err = rte_le_to_cpu_16(desc->status_error0);\n+\tif (likely(stat_err & (1 << IAVF_RX_FLEX_DESC_STATUS0_RSS_VALID_S))) {\n+\t\tmb->ol_flags |= PKT_RX_RSS_HASH;\n+\t\tmb->hash.rss = rte_le_to_cpu_32(desc->rss_hash);\n+\t}\n+\n+#ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC\n+\tif (desc->flow_id != 0xFFFFFFFF) {\n+\t\tmb->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;\n+\t\tmb->hash.fdir.hi = rte_le_to_cpu_32(desc->flow_id);\n+\t}\n+\n+\tif (rxq->xtr_ol_flag) {\n+\t\tuint32_t metadata = 0;\n+\n+\t\tstat_err = rte_le_to_cpu_16(desc->status_error1);\n+\n+\t\tif (stat_err & (1 << IAVF_RX_FLEX_DESC_STATUS1_XTRMD4_VALID_S))\n+\t\t\tmetadata = rte_le_to_cpu_16(desc->flex_ts.flex.aux0);\n+\n+\t\tif (stat_err & (1 << IAVF_RX_FLEX_DESC_STATUS1_XTRMD5_VALID_S))\n+\t\t\tmetadata |=\n+\t\t\t\trte_le_to_cpu_16(desc->flex_ts.flex.aux1) << 16;\n+\n+\t\tif (metadata) {\n+\t\t\tmb->ol_flags |= rxq->xtr_ol_flag;\n+\n+\t\t\t*RTE_NET_IAVF_DYNF_PROTO_XTR_METADATA(mb) = metadata;\n+\t\t}\n+\t}\n+#endif\n+}\n+\n+static inline void\n+iavf_rxd_to_pkt_fields_by_comms_aux_v2(struct iavf_rx_queue *rxq,\n+\t\t\t\t       struct rte_mbuf *mb,\n+\t\t\t\t       volatile union iavf_rx_flex_desc *rxdp)\n+{\n+\tvolatile struct iavf_32b_rx_flex_desc_comms *desc =\n+\t\t\t(volatile struct iavf_32b_rx_flex_desc_comms *)rxdp;\n+\tuint16_t stat_err;\n+\n+\tstat_err = rte_le_to_cpu_16(desc->status_error0);\n+\tif (likely(stat_err & (1 << IAVF_RX_FLEX_DESC_STATUS0_RSS_VALID_S))) {\n+\t\tmb->ol_flags |= PKT_RX_RSS_HASH;\n+\t\tmb->hash.rss = rte_le_to_cpu_32(desc->rss_hash);\n+\t}\n+\n+#ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC\n+\tif (desc->flow_id != 0xFFFFFFFF) {\n+\t\tmb->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;\n+\t\tmb->hash.fdir.hi = rte_le_to_cpu_32(desc->flow_id);\n+\t}\n+\n+\tif (rxq->xtr_ol_flag) {\n+\t\tuint32_t metadata = 0;\n+\n+\t\tif (desc->flex_ts.flex.aux0 != 0xFFFF)\n+\t\t\tmetadata = rte_le_to_cpu_16(desc->flex_ts.flex.aux0);\n+\t\telse if (desc->flex_ts.flex.aux1 != 0xFFFF)\n+\t\t\tmetadata = rte_le_to_cpu_16(desc->flex_ts.flex.aux1);\n+\n+\t\tif (metadata) {\n+\t\t\tmb->ol_flags |= rxq->xtr_ol_flag;\n+\n+\t\t\t*RTE_NET_IAVF_DYNF_PROTO_XTR_METADATA(mb) = metadata;\n+\t\t}\n+\t}\n+#endif\n+}\n+\n+static void\n+iavf_select_rxd_to_pkt_fields_handler(struct iavf_rx_queue *rxq, uint32_t rxdid)\n+{\n+\tswitch (rxdid) {\n+\tcase IAVF_RXDID_COMMS_AUX_VLAN:\n+\t\trxq->xtr_ol_flag = rte_net_iavf_dynflag_proto_xtr_vlan_mask;\n+\t\trxq->rxd_to_pkt_fields =\n+\t\t\tiavf_rxd_to_pkt_fields_by_comms_aux_v1;\n+\t\tbreak;\n+\tcase IAVF_RXDID_COMMS_AUX_IPV4:\n+\t\trxq->xtr_ol_flag = rte_net_iavf_dynflag_proto_xtr_ipv4_mask;\n+\t\trxq->rxd_to_pkt_fields =\n+\t\t\tiavf_rxd_to_pkt_fields_by_comms_aux_v1;\n+\t\tbreak;\n+\tcase IAVF_RXDID_COMMS_AUX_IPV6:\n+\t\trxq->xtr_ol_flag = rte_net_iavf_dynflag_proto_xtr_ipv6_mask;\n+\t\trxq->rxd_to_pkt_fields =\n+\t\t\tiavf_rxd_to_pkt_fields_by_comms_aux_v1;\n+\t\tbreak;\n+\tcase IAVF_RXDID_COMMS_AUX_IPV6_FLOW:\n+\t\trxq->xtr_ol_flag =\n+\t\t\trte_net_iavf_dynflag_proto_xtr_ipv6_flow_mask;\n+\t\trxq->rxd_to_pkt_fields =\n+\t\t\tiavf_rxd_to_pkt_fields_by_comms_aux_v1;\n+\t\tbreak;\n+\tcase IAVF_RXDID_COMMS_AUX_TCP:\n+\t\trxq->xtr_ol_flag = rte_net_iavf_dynflag_proto_xtr_tcp_mask;\n+\t\trxq->rxd_to_pkt_fields =\n+\t\t\tiavf_rxd_to_pkt_fields_by_comms_aux_v1;\n+\t\tbreak;\n+\tcase IAVF_RXDID_COMMS_AUX_IP_OFFSET:\n+\t\trxq->xtr_ol_flag =\n+\t\t\trte_net_iavf_dynflag_proto_xtr_ip_offset_mask;\n+\t\trxq->rxd_to_pkt_fields =\n+\t\t\tiavf_rxd_to_pkt_fields_by_comms_aux_v2;\n+\t\tbreak;\n+\tcase IAVF_RXDID_COMMS_OVS_1:\n+\t\trxq->rxd_to_pkt_fields = iavf_rxd_to_pkt_fields_by_comms_ovs;\n+\t\tbreak;\n+\tdefault:\n+\t\t/* update this according to the RXDID for FLEX_DESC_NONE */\n+\t\trxq->rxd_to_pkt_fields = iavf_rxd_to_pkt_fields_by_comms_ovs;\n+\t\tbreak;\n+\t}\n+\n+\tif (!rte_net_iavf_dynf_proto_xtr_metadata_avail())\n+\t\trxq->xtr_ol_flag = 0;\n+}\n+\n int\n iavf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,\n \t\t       uint16_t nb_desc, unsigned int socket_id,\n@@ -309,6 +492,7 @@ iavf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,\n \tstruct iavf_rx_queue *rxq;\n \tconst struct rte_memzone *mz;\n \tuint32_t ring_size;\n+\tuint8_t proto_xtr;\n \tuint16_t len;\n \tuint16_t rx_free_thresh;\n \n@@ -346,14 +530,18 @@ iavf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,\n \t\treturn -ENOMEM;\n \t}\n \n-\tif (vf->vf_res->vf_cap_flags &\n-\t    VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC &&\n-\t    vf->supported_rxdid & BIT(IAVF_RXDID_COMMS_OVS_1)) {\n-\t\trxq->rxdid = IAVF_RXDID_COMMS_OVS_1;\n+\tif (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC) {\n+\t\tproto_xtr = vf->proto_xtr ? vf->proto_xtr[queue_idx] :\n+\t\t\t\tIAVF_PROTO_XTR_NONE;\n+\t\trxq->rxdid = iavf_proto_xtr_type_to_rxdid(proto_xtr);\n+\t\trxq->proto_xtr = proto_xtr;\n \t} else {\n \t\trxq->rxdid = IAVF_RXDID_LEGACY_1;\n+\t\trxq->proto_xtr = IAVF_PROTO_XTR_NONE;\n \t}\n \n+\tiavf_select_rxd_to_pkt_fields_handler(rxq, rxq->rxdid);\n+\n \trxq->mp = mp;\n \trxq->nb_rx_desc = nb_desc;\n \trxq->rx_free_thresh = rx_free_thresh;\n@@ -715,6 +903,14 @@ iavf_stop_queues(struct rte_eth_dev *dev)\n \t}\n }\n \n+#define IAVF_RX_FLEX_ERR0_BITS\t\\\n+\t((1 << IAVF_RX_FLEX_DESC_STATUS0_HBO_S) |\t\\\n+\t (1 << IAVF_RX_FLEX_DESC_STATUS0_XSUM_IPE_S) |\t\\\n+\t (1 << IAVF_RX_FLEX_DESC_STATUS0_XSUM_L4E_S) |\t\\\n+\t (1 << IAVF_RX_FLEX_DESC_STATUS0_XSUM_EIPE_S) |\t\\\n+\t (1 << IAVF_RX_FLEX_DESC_STATUS0_XSUM_EUDPE_S) |\t\\\n+\t (1 << IAVF_RX_FLEX_DESC_STATUS0_RXE_S))\n+\n static inline void\n iavf_rxd_to_vlan_tci(struct rte_mbuf *mb, volatile union iavf_rx_desc *rxdp)\n {\n@@ -740,6 +936,21 @@ iavf_flex_rxd_to_vlan_tci(struct rte_mbuf *mb,\n \t} else {\n \t\tmb->vlan_tci = 0;\n \t}\n+\n+#ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC\n+\tif (rte_le_to_cpu_16(rxdp->wb.status_error1) &\n+\t    (1 << IAVF_RX_FLEX_DESC_STATUS1_L2TAG2P_S)) {\n+\t\tmb->ol_flags |= PKT_RX_QINQ_STRIPPED | PKT_RX_QINQ |\n+\t\t\t\tPKT_RX_VLAN_STRIPPED | PKT_RX_VLAN;\n+\t\tmb->vlan_tci_outer = mb->vlan_tci;\n+\t\tmb->vlan_tci = rte_le_to_cpu_16(rxdp->wb.l2tag2_2nd);\n+\t\tPMD_RX_LOG(DEBUG, \"Descriptor l2tag2_1: %u, l2tag2_2: %u\",\n+\t\t\t   rte_le_to_cpu_16(rxdp->wb.l2tag2_1st),\n+\t\t\t   rte_le_to_cpu_16(rxdp->wb.l2tag2_2nd));\n+\t} else {\n+\t\tmb->vlan_tci_outer = 0;\n+\t}\n+#endif\n }\n \n /* Translate the rx descriptor status and error fields to pkt flags */\n@@ -804,30 +1015,6 @@ iavf_rxd_build_fdir(volatile union iavf_rx_desc *rxdp, struct rte_mbuf *mb)\n \treturn flags;\n }\n \n-\n-/* Translate the rx flex descriptor status to pkt flags */\n-static inline void\n-iavf_rxd_to_pkt_fields(struct rte_mbuf *mb,\n-\t\t       volatile union iavf_rx_flex_desc *rxdp)\n-{\n-\tvolatile struct iavf_32b_rx_flex_desc_comms_ovs *desc =\n-\t\t\t(volatile struct iavf_32b_rx_flex_desc_comms_ovs *)rxdp;\n-#ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC\n-\tuint16_t stat_err;\n-\n-\tstat_err = rte_le_to_cpu_16(desc->status_error0);\n-\tif (likely(stat_err & (1 << IAVF_RX_FLEX_DESC_STATUS0_RSS_VALID_S))) {\n-\t\tmb->ol_flags |= PKT_RX_RSS_HASH;\n-\t\tmb->hash.rss = rte_le_to_cpu_32(desc->rss_hash);\n-\t}\n-#endif\n-\n-\tif (desc->flow_id != 0xFFFFFFFF) {\n-\t\tmb->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;\n-\t\tmb->hash.fdir.hi = rte_le_to_cpu_32(desc->flow_id);\n-\t}\n-}\n-\n #define IAVF_RX_FLEX_ERR0_BITS\t\\\n \t((1 << IAVF_RX_FLEX_DESC_STATUS0_HBO_S) |\t\\\n \t (1 << IAVF_RX_FLEX_DESC_STATUS0_XSUM_IPE_S) |\t\\\n@@ -1082,7 +1269,7 @@ iavf_recv_pkts_flex_rxd(void *rx_queue,\n \t\trxm->packet_type = ptype_tbl[IAVF_RX_FLEX_DESC_PTYPE_M &\n \t\t\trte_le_to_cpu_16(rxd.wb.ptype_flex_flags0)];\n \t\tiavf_flex_rxd_to_vlan_tci(rxm, &rxd);\n-\t\tiavf_rxd_to_pkt_fields(rxm, &rxd);\n+\t\trxq->rxd_to_pkt_fields(rxq, rxm, &rxd);\n \t\tpkt_flags = iavf_flex_rxd_error_to_pkt_flags(rx_stat_err0);\n \t\trxm->ol_flags |= pkt_flags;\n \n@@ -1223,7 +1410,7 @@ iavf_recv_scattered_pkts_flex_rxd(void *rx_queue, struct rte_mbuf **rx_pkts,\n \t\tfirst_seg->packet_type = ptype_tbl[IAVF_RX_FLEX_DESC_PTYPE_M &\n \t\t\trte_le_to_cpu_16(rxd.wb.ptype_flex_flags0)];\n \t\tiavf_flex_rxd_to_vlan_tci(first_seg, &rxd);\n-\t\tiavf_rxd_to_pkt_fields(first_seg, &rxd);\n+\t\trxq->rxd_to_pkt_fields(rxq, first_seg, &rxd);\n \t\tpkt_flags = iavf_flex_rxd_error_to_pkt_flags(rx_stat_err0);\n \n \t\tfirst_seg->ol_flags |= pkt_flags;\n@@ -1460,7 +1647,7 @@ iavf_rx_scan_hw_ring_flex_rxd(struct iavf_rx_queue *rxq)\n \t\t\tmb->packet_type = ptype_tbl[IAVF_RX_FLEX_DESC_PTYPE_M &\n \t\t\t\trte_le_to_cpu_16(rxdp[j].wb.ptype_flex_flags0)];\n \t\t\tiavf_flex_rxd_to_vlan_tci(mb, &rxdp[j]);\n-\t\t\tiavf_rxd_to_pkt_fields(mb, &rxdp[j]);\n+\t\t\trxq->rxd_to_pkt_fields(rxq, mb, &rxdp[j]);\n \t\t\tstat_err0 = rte_le_to_cpu_16(rxdp[j].wb.status_error0);\n \t\t\tpkt_flags = iavf_flex_rxd_error_to_pkt_flags(stat_err0);\n \n@@ -1652,7 +1839,7 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)\n \tif (rxq->rx_nb_avail)\n \t\treturn iavf_rx_fill_from_stage(rxq, rx_pkts, nb_pkts);\n \n-\tif (rxq->rxdid == IAVF_RXDID_COMMS_OVS_1)\n+\tif (rxq->rxdid >= IAVF_RXDID_FLEX_NIC && rxq->rxdid <= IAVF_RXDID_LAST)\n \t\tnb_rx = (uint16_t)iavf_rx_scan_hw_ring_flex_rxd(rxq);\n \telse\n \t\tnb_rx = (uint16_t)iavf_rx_scan_hw_ring(rxq);\n@@ -2099,6 +2286,7 @@ iavf_set_rx_function(struct rte_eth_dev *dev)\n \tstruct iavf_adapter *adapter =\n \t\tIAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n \tstruct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);\n+\n #ifdef RTE_ARCH_X86\n \tstruct iavf_rx_queue *rxq;\n \tint i;\ndiff --git a/drivers/net/iavf/iavf_rxtx.h b/drivers/net/iavf/iavf_rxtx.h\nindex 3d02c6589d..39b31aaa8e 100644\n--- a/drivers/net/iavf/iavf_rxtx.h\n+++ b/drivers/net/iavf/iavf_rxtx.h\n@@ -57,6 +57,77 @@\n #define IAVF_TX_OFFLOAD_NOTSUP_MASK \\\n \t\t(PKT_TX_OFFLOAD_MASK ^ IAVF_TX_OFFLOAD_MASK)\n \n+/* Rx Flex Descriptors\n+ * These descriptors are used instead of the legacy version descriptors\n+ */\n+union iavf_16b_rx_flex_desc {\n+\tstruct {\n+\t\t__le64 pkt_addr; /* Packet buffer address */\n+\t\t__le64 hdr_addr; /* Header buffer address */\n+\t\t\t\t /* bit 0 of hdr_addr is DD bit */\n+\t} read;\n+\tstruct {\n+\t\t/* Qword 0 */\n+\t\tu8 rxdid; /* descriptor builder profile ID */\n+\t\tu8 mir_id_umb_cast; /* mirror=[5:0], umb=[7:6] */\n+\t\t__le16 ptype_flex_flags0; /* ptype=[9:0], ff0=[15:10] */\n+\t\t__le16 pkt_len; /* [15:14] are reserved */\n+\t\t__le16 hdr_len_sph_flex_flags1; /* header=[10:0] */\n+\t\t\t\t\t\t/* sph=[11:11] */\n+\t\t\t\t\t\t/* ff1/ext=[15:12] */\n+\n+\t\t/* Qword 1 */\n+\t\t__le16 status_error0;\n+\t\t__le16 l2tag1;\n+\t\t__le16 flex_meta0;\n+\t\t__le16 flex_meta1;\n+\t} wb; /* writeback */\n+};\n+\n+union iavf_32b_rx_flex_desc {\n+\tstruct {\n+\t\t__le64 pkt_addr; /* Packet buffer address */\n+\t\t__le64 hdr_addr; /* Header buffer address */\n+\t\t\t\t /* bit 0 of hdr_addr is DD bit */\n+\t\t__le64 rsvd1;\n+\t\t__le64 rsvd2;\n+\t} read;\n+\tstruct {\n+\t\t/* Qword 0 */\n+\t\tu8 rxdid; /* descriptor builder profile ID */\n+\t\tu8 mir_id_umb_cast; /* mirror=[5:0], umb=[7:6] */\n+\t\t__le16 ptype_flex_flags0; /* ptype=[9:0], ff0=[15:10] */\n+\t\t__le16 pkt_len; /* [15:14] are reserved */\n+\t\t__le16 hdr_len_sph_flex_flags1; /* header=[10:0] */\n+\t\t\t\t\t\t/* sph=[11:11] */\n+\t\t\t\t\t\t/* ff1/ext=[15:12] */\n+\n+\t\t/* Qword 1 */\n+\t\t__le16 status_error0;\n+\t\t__le16 l2tag1;\n+\t\t__le16 flex_meta0;\n+\t\t__le16 flex_meta1;\n+\n+\t\t/* Qword 2 */\n+\t\t__le16 status_error1;\n+\t\tu8 flex_flags2;\n+\t\tu8 time_stamp_low;\n+\t\t__le16 l2tag2_1st;\n+\t\t__le16 l2tag2_2nd;\n+\n+\t\t/* Qword 3 */\n+\t\t__le16 flex_meta2;\n+\t\t__le16 flex_meta3;\n+\t\tunion {\n+\t\t\tstruct {\n+\t\t\t\t__le16 flex_meta4;\n+\t\t\t\t__le16 flex_meta5;\n+\t\t\t} flex;\n+\t\t\t__le32 ts_high;\n+\t\t} flex_ts;\n+\t} wb; /* writeback */\n+};\n+\n /* HW desc structure, both 16-byte and 32-byte types are supported */\n #ifdef RTE_LIBRTE_IAVF_16BYTE_RX_DESC\n #define iavf_rx_desc iavf_16byte_rx_desc\n@@ -66,6 +137,10 @@\n #define iavf_rx_flex_desc iavf_32b_rx_flex_desc\n #endif\n \n+typedef void (*iavf_rxd_to_pkt_fields_t)(struct iavf_rx_queue *rxq,\n+\t\t\t\tstruct rte_mbuf *mb,\n+\t\t\t\tvolatile union iavf_rx_flex_desc *rxdp);\n+\n struct iavf_rxq_ops {\n \tvoid (*release_mbufs)(struct iavf_rx_queue *rxq);\n };\n@@ -114,6 +189,11 @@ struct iavf_rx_queue {\n \tbool q_set;             /* if rx queue has been configured */\n \tbool rx_deferred_start; /* don't start this queue in dev start */\n \tconst struct iavf_rxq_ops *ops;\n+\tuint8_t proto_xtr; /* protocol extraction type */\n+\tuint64_t xtr_ol_flag;\n+\t\t/* flexible descriptor metadata extraction offload flag */\n+\tiavf_rxd_to_pkt_fields_t rxd_to_pkt_fields;\n+\t\t\t\t/* handle flexible descriptor by RXDID */\n };\n \n struct iavf_tx_entry {\n@@ -161,77 +241,6 @@ union iavf_tx_offload {\n \t};\n };\n \n-/* Rx Flex Descriptors\n- * These descriptors are used instead of the legacy version descriptors\n- */\n-union iavf_16b_rx_flex_desc {\n-\tstruct {\n-\t\t__le64 pkt_addr; /* Packet buffer address */\n-\t\t__le64 hdr_addr; /* Header buffer address */\n-\t\t\t\t /* bit 0 of hdr_addr is DD bit */\n-\t} read;\n-\tstruct {\n-\t\t/* Qword 0 */\n-\t\tu8 rxdid; /* descriptor builder profile ID */\n-\t\tu8 mir_id_umb_cast; /* mirror=[5:0], umb=[7:6] */\n-\t\t__le16 ptype_flex_flags0; /* ptype=[9:0], ff0=[15:10] */\n-\t\t__le16 pkt_len; /* [15:14] are reserved */\n-\t\t__le16 hdr_len_sph_flex_flags1; /* header=[10:0] */\n-\t\t\t\t\t\t/* sph=[11:11] */\n-\t\t\t\t\t\t/* ff1/ext=[15:12] */\n-\n-\t\t/* Qword 1 */\n-\t\t__le16 status_error0;\n-\t\t__le16 l2tag1;\n-\t\t__le16 flex_meta0;\n-\t\t__le16 flex_meta1;\n-\t} wb; /* writeback */\n-};\n-\n-union iavf_32b_rx_flex_desc {\n-\tstruct {\n-\t\t__le64 pkt_addr; /* Packet buffer address */\n-\t\t__le64 hdr_addr; /* Header buffer address */\n-\t\t\t\t /* bit 0 of hdr_addr is DD bit */\n-\t\t__le64 rsvd1;\n-\t\t__le64 rsvd2;\n-\t} read;\n-\tstruct {\n-\t\t/* Qword 0 */\n-\t\tu8 rxdid; /* descriptor builder profile ID */\n-\t\tu8 mir_id_umb_cast; /* mirror=[5:0], umb=[7:6] */\n-\t\t__le16 ptype_flex_flags0; /* ptype=[9:0], ff0=[15:10] */\n-\t\t__le16 pkt_len; /* [15:14] are reserved */\n-\t\t__le16 hdr_len_sph_flex_flags1; /* header=[10:0] */\n-\t\t\t\t\t\t/* sph=[11:11] */\n-\t\t\t\t\t\t/* ff1/ext=[15:12] */\n-\n-\t\t/* Qword 1 */\n-\t\t__le16 status_error0;\n-\t\t__le16 l2tag1;\n-\t\t__le16 flex_meta0;\n-\t\t__le16 flex_meta1;\n-\n-\t\t/* Qword 2 */\n-\t\t__le16 status_error1;\n-\t\tu8 flex_flags2;\n-\t\tu8 time_stamp_low;\n-\t\t__le16 l2tag2_1st;\n-\t\t__le16 l2tag2_2nd;\n-\n-\t\t/* Qword 3 */\n-\t\t__le16 flex_meta2;\n-\t\t__le16 flex_meta3;\n-\t\tunion {\n-\t\t\tstruct {\n-\t\t\t\t__le16 flex_meta4;\n-\t\t\t\t__le16 flex_meta5;\n-\t\t\t} flex;\n-\t\t\t__le32 ts_high;\n-\t\t} flex_ts;\n-\t} wb; /* writeback */\n-};\n-\n /* Rx Flex Descriptor\n  * RxDID Profile ID 16-21\n  * Flex-field 0: RSS hash lower 16-bits\n@@ -331,6 +340,7 @@ enum iavf_rxdid {\n \tIAVF_RXDID_COMMS_AUX_TCP\t= 21,\n \tIAVF_RXDID_COMMS_OVS_1\t\t= 22,\n \tIAVF_RXDID_COMMS_OVS_2\t\t= 23,\n+\tIAVF_RXDID_COMMS_AUX_IP_OFFSET\t= 25,\n \tIAVF_RXDID_LAST\t\t\t= 63,\n };\n \n@@ -355,6 +365,20 @@ enum iavf_rx_flex_desc_status_error_0_bits {\n \tIAVF_RX_FLEX_DESC_STATUS0_LAST /* this entry must be last!!! */\n };\n \n+enum iavf_rx_flex_desc_status_error_1_bits {\n+\t/* Note: These are predefined bit offsets */\n+\tIAVF_RX_FLEX_DESC_STATUS1_CPM_S = 0, /* 4 bits */\n+\tIAVF_RX_FLEX_DESC_STATUS1_NAT_S = 4,\n+\tIAVF_RX_FLEX_DESC_STATUS1_CRYPTO_S = 5,\n+\t/* [10:6] reserved */\n+\tIAVF_RX_FLEX_DESC_STATUS1_L2TAG2P_S = 11,\n+\tIAVF_RX_FLEX_DESC_STATUS1_XTRMD2_VALID_S = 12,\n+\tIAVF_RX_FLEX_DESC_STATUS1_XTRMD3_VALID_S = 13,\n+\tIAVF_RX_FLEX_DESC_STATUS1_XTRMD4_VALID_S = 14,\n+\tIAVF_RX_FLEX_DESC_STATUS1_XTRMD5_VALID_S = 15,\n+\tIAVF_RX_FLEX_DESC_STATUS1_LAST /* this entry must be last!!! */\n+};\n+\n /* for iavf_32b_rx_flex_desc.ptype_flex_flags0 member */\n #define IAVF_RX_FLEX_DESC_PTYPE_M\t(0x3FF) /* 10-bits */\n \n@@ -439,6 +463,8 @@ int iavf_tx_vec_dev_check(struct rte_eth_dev *dev);\n int iavf_rxq_vec_setup(struct iavf_rx_queue *rxq);\n int iavf_txq_vec_setup(struct iavf_tx_queue *txq);\n \n+uint8_t iavf_proto_xtr_type_to_rxdid(uint8_t xtr_type);\n+\n const uint32_t *iavf_get_default_ptype_table(void);\n \n static inline\ndiff --git a/drivers/net/iavf/iavf_rxtx_vec_common.h b/drivers/net/iavf/iavf_rxtx_vec_common.h\nindex 25bb502de2..7ad1e0f68a 100644\n--- a/drivers/net/iavf/iavf_rxtx_vec_common.h\n+++ b/drivers/net/iavf/iavf_rxtx_vec_common.h\n@@ -224,6 +224,9 @@ iavf_rx_vec_queue_default(struct iavf_rx_queue *rxq)\n \tif (rxq->nb_rx_desc % rxq->rx_free_thresh)\n \t\treturn -1;\n \n+\tif (rxq->proto_xtr != IAVF_PROTO_XTR_NONE)\n+\t\treturn -1;\n+\n \treturn 0;\n }\n \ndiff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c\nindex db0b768765..5e7142893b 100644\n--- a/drivers/net/iavf/iavf_vchnl.c\n+++ b/drivers/net/iavf/iavf_vchnl.c\n@@ -648,25 +648,27 @@ iavf_configure_queues(struct iavf_adapter *adapter)\n \n #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC\n \t\tif (vf->vf_res->vf_cap_flags &\n-\t\t\tVIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC &&\n-\t\t\tvf->supported_rxdid & BIT(IAVF_RXDID_COMMS_OVS_1)) {\n-\t\t\tvc_qp->rxq.rxdid = IAVF_RXDID_COMMS_OVS_1;\n-\t\t\tPMD_DRV_LOG(NOTICE, \"request RXDID == %d in \"\n-\t\t\t\t\t\"Queue[%d]\", vc_qp->rxq.rxdid, i);\n+\t\t    VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC &&\n+\t\t    vf->supported_rxdid & BIT(rxq[i]->rxdid)) {\n+\t\t\tvc_qp->rxq.rxdid = rxq[i]->rxdid;\n+\t\t\tPMD_DRV_LOG(NOTICE, \"request RXDID[%d] in Queue[%d]\",\n+\t\t\t\t    vc_qp->rxq.rxdid, i);\n \t\t} else {\n+\t\t\tPMD_DRV_LOG(NOTICE, \"RXDID[%d] is not supported, \"\n+\t\t\t\t    \"request default RXDID[%d] in Queue[%d]\",\n+\t\t\t\t    rxq[i]->rxdid, IAVF_RXDID_LEGACY_1, i);\n \t\t\tvc_qp->rxq.rxdid = IAVF_RXDID_LEGACY_1;\n-\t\t\tPMD_DRV_LOG(NOTICE, \"request RXDID == %d in \"\n-\t\t\t\t\t\"Queue[%d]\", vc_qp->rxq.rxdid, i);\n \t\t}\n #else\n \t\tif (vf->vf_res->vf_cap_flags &\n \t\t\tVIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC &&\n \t\t\tvf->supported_rxdid & BIT(IAVF_RXDID_LEGACY_0)) {\n \t\t\tvc_qp->rxq.rxdid = IAVF_RXDID_LEGACY_0;\n-\t\t\tPMD_DRV_LOG(NOTICE, \"request RXDID == %d in \"\n-\t\t\t\t\t\"Queue[%d]\", vc_qp->rxq.rxdid, i);\n+\t\t\tPMD_DRV_LOG(NOTICE, \"request RXDID[%d] in Queue[%d]\",\n+\t\t\t\t    vc_qp->rxq.rxdid, i);\n \t\t} else {\n-\t\t\tPMD_DRV_LOG(ERR, \"RXDID == 0 is not supported\");\n+\t\t\tPMD_DRV_LOG(ERR, \"RXDID[%d] is not supported\",\n+\t\t\t\t    IAVF_RXDID_LEGACY_0);\n \t\t\treturn -1;\n \t\t}\n #endif\ndiff --git a/drivers/net/iavf/meson.build b/drivers/net/iavf/meson.build\nindex 33407c5032..c1c74571a1 100644\n--- a/drivers/net/iavf/meson.build\n+++ b/drivers/net/iavf/meson.build\n@@ -35,3 +35,5 @@ if arch_subdir == 'x86'\n \t\tobjs += iavf_avx2_lib.extract_objects('iavf_rxtx_vec_avx2.c')\n \tendif\n endif\n+\n+install_headers('rte_pmd_iavf.h')\ndiff --git a/drivers/net/iavf/rte_pmd_iavf.h b/drivers/net/iavf/rte_pmd_iavf.h\nnew file mode 100644\nindex 0000000000..5e41568c32\n--- /dev/null\n+++ b/drivers/net/iavf/rte_pmd_iavf.h\n@@ -0,0 +1,250 @@\n+/* SPDX-Liavfnse-Identifier: BSD-3-Clause\n+ * Copyright(c) 2019 Intel Corporation\n+ */\n+\n+#ifndef _RTE_PMD_IAVF_H_\n+#define _RTE_PMD_IAVF_H_\n+\n+/**\n+ * @file rte_pmd_iavf.h\n+ *\n+ * iavf PMD specific functions.\n+ *\n+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notiavf\n+ *\n+ */\n+\n+#include <stdio.h>\n+#include <rte_mbuf.h>\n+#include <rte_mbuf_dyn.h>\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+/**\n+ * The supported network flexible descriptor's extraction metadata format.\n+ */\n+union rte_net_iavf_proto_xtr_metadata {\n+\tuint32_t metadata;\n+\n+\tstruct {\n+\t\tuint16_t data0;\n+\t\tuint16_t data1;\n+\t} raw;\n+\n+\tstruct {\n+\t\tuint16_t stag_vid:12,\n+\t\t\t stag_dei:1,\n+\t\t\t stag_pcp:3;\n+\t\tuint16_t ctag_vid:12,\n+\t\t\t ctag_dei:1,\n+\t\t\t ctag_pcp:3;\n+\t} vlan;\n+\n+\tstruct {\n+\t\tuint16_t protocol:8,\n+\t\t\t ttl:8;\n+\t\tuint16_t tos:8,\n+\t\t\t ihl:4,\n+\t\t\t version:4;\n+\t} ipv4;\n+\n+\tstruct {\n+\t\tuint16_t hoplimit:8,\n+\t\t\t nexthdr:8;\n+\t\tuint16_t flowhi4:4,\n+\t\t\t tc:8,\n+\t\t\t version:4;\n+\t} ipv6;\n+\n+\tstruct {\n+\t\tuint16_t flowlo16;\n+\t\tuint16_t flowhi4:4,\n+\t\t\t tc:8,\n+\t\t\t version:4;\n+\t} ipv6_flow;\n+\n+\tstruct {\n+\t\tuint16_t fin:1,\n+\t\t\t syn:1,\n+\t\t\t rst:1,\n+\t\t\t psh:1,\n+\t\t\t ack:1,\n+\t\t\t urg:1,\n+\t\t\t ece:1,\n+\t\t\t cwr:1,\n+\t\t\t res1:4,\n+\t\t\t doff:4;\n+\t\tuint16_t rsvd;\n+\t} tcp;\n+\n+\tuint32_t ip_ofs;\n+};\n+\n+/* Offset of mbuf dynamic field for flexible descriptor's extraction data */\n+extern int rte_net_iavf_dynfield_proto_xtr_metadata_offs;\n+\n+/* Mask of mbuf dynamic flags for flexible descriptor's extraction type */\n+extern uint64_t rte_net_iavf_dynflag_proto_xtr_vlan_mask;\n+extern uint64_t rte_net_iavf_dynflag_proto_xtr_ipv4_mask;\n+extern uint64_t rte_net_iavf_dynflag_proto_xtr_ipv6_mask;\n+extern uint64_t rte_net_iavf_dynflag_proto_xtr_ipv6_flow_mask;\n+extern uint64_t rte_net_iavf_dynflag_proto_xtr_tcp_mask;\n+extern uint64_t rte_net_iavf_dynflag_proto_xtr_ip_offset_mask;\n+\n+/**\n+ * The mbuf dynamic field pointer for flexible descriptor's extraction metadata.\n+ */\n+#define RTE_NET_IAVF_DYNF_PROTO_XTR_METADATA(m) \\\n+\tRTE_MBUF_DYNFIELD((m), \\\n+\t\t\t  rte_net_iavf_dynfield_proto_xtr_metadata_offs, \\\n+\t\t\t  uint32_t *)\n+\n+/**\n+ * The mbuf dynamic flag for VLAN protocol extraction metadata, it is valid\n+ * when dev_args 'proto_xtr' has 'vlan' specified.\n+ */\n+#define RTE_IAVF_PKT_RX_DYNF_PROTO_XTR_VLAN \\\n+\t(rte_net_iavf_dynflag_proto_xtr_vlan_mask)\n+\n+/**\n+ * The mbuf dynamic flag for IPv4 protocol extraction metadata, it is valid\n+ * when dev_args 'proto_xtr' has 'ipv4' specified.\n+ */\n+#define RTE_IAVF_PKT_RX_DYNF_PROTO_XTR_IPV4 \\\n+\t(rte_net_iavf_dynflag_proto_xtr_ipv4_mask)\n+\n+/**\n+ * The mbuf dynamic flag for IPv6 protocol extraction metadata, it is valid\n+ * when dev_args 'proto_xtr' has 'ipv6' specified.\n+ */\n+#define RTE_IAVF_PKT_RX_DYNF_PROTO_XTR_IPV6 \\\n+\t(rte_net_iavf_dynflag_proto_xtr_ipv6_mask)\n+\n+/**\n+ * The mbuf dynamic flag for IPv6 with flow protocol extraction metadata, it is\n+ * valid when dev_args 'proto_xtr' has 'ipv6_flow' specified.\n+ */\n+#define RTE_IAVF_PKT_RX_DYNF_PROTO_XTR_IPV6_FLOW \\\n+\t(rte_net_iavf_dynflag_proto_xtr_ipv6_flow_mask)\n+\n+/**\n+ * The mbuf dynamic flag for TCP protocol extraction metadata, it is valid\n+ * when dev_args 'proto_xtr' has 'tcp' specified.\n+ */\n+#define RTE_IAVF_PKT_RX_DYNF_PROTO_XTR_TCP \\\n+\t(rte_net_iavf_dynflag_proto_xtr_tcp_mask)\n+\n+/**\n+ * The mbuf dynamic flag for IP_OFFSET extraction metadata, it is valid\n+ * when dev_args 'proto_xtr' has 'ip_offset' specified.\n+ */\n+#define RTE_IAVF_PKT_RX_DYNF_PROTO_XTR_IP_OFFSET \\\n+\t(rte_net_iavf_dynflag_proto_xtr_ip_offset_mask)\n+\n+/**\n+ * Check if mbuf dynamic field for flexible descriptor's extraction metadata\n+ * is registered.\n+ *\n+ * @return\n+ *   True if registered, false otherwise.\n+ */\n+__rte_experimental\n+static __rte_always_inline int\n+rte_net_iavf_dynf_proto_xtr_metadata_avail(void)\n+{\n+\treturn rte_net_iavf_dynfield_proto_xtr_metadata_offs != -1;\n+}\n+\n+/**\n+ * Get the mbuf dynamic field for flexible descriptor's extraction metadata.\n+ *\n+ * @param m\n+ *    The pointer to the mbuf.\n+ * @return\n+ *   The saved protocol extraction metadata.\n+ */\n+__rte_experimental\n+static __rte_always_inline uint32_t\n+rte_net_iavf_dynf_proto_xtr_metadata_get(struct rte_mbuf *m)\n+{\n+\treturn *RTE_NET_IAVF_DYNF_PROTO_XTR_METADATA(m);\n+}\n+\n+/**\n+ * Dump the mbuf dynamic field for flexible descriptor's extraction metadata.\n+ *\n+ * @param m\n+ *    The pointer to the mbuf.\n+ */\n+__rte_experimental\n+static inline void\n+rte_net_iavf_dump_proto_xtr_metadata(struct rte_mbuf *m)\n+{\n+\tunion rte_net_iavf_proto_xtr_metadata data;\n+\n+\tif (!rte_net_iavf_dynf_proto_xtr_metadata_avail())\n+\t\treturn;\n+\n+\tdata.metadata = rte_net_iavf_dynf_proto_xtr_metadata_get(m);\n+\n+\tif (m->ol_flags & RTE_IAVF_PKT_RX_DYNF_PROTO_XTR_VLAN)\n+\t\tprintf(\" - Flexible descriptor's Metadata: [0x%04x:0x%04x],\"\n+\t\t       \"vlan,stag=%u:%u:%u,ctag=%u:%u:%u\",\n+\t\t       data.raw.data0, data.raw.data1,\n+\t\t       data.vlan.stag_pcp,\n+\t\t       data.vlan.stag_dei,\n+\t\t       data.vlan.stag_vid,\n+\t\t       data.vlan.ctag_pcp,\n+\t\t       data.vlan.ctag_dei,\n+\t\t       data.vlan.ctag_vid);\n+\telse if (m->ol_flags & RTE_IAVF_PKT_RX_DYNF_PROTO_XTR_IPV4)\n+\t\tprintf(\" - Flexible descriptor's Metadata: [0x%04x:0x%04x],\"\n+\t\t       \"ipv4,ver=%u,hdrlen=%u,tos=%u,ttl=%u,proto=%u\",\n+\t\t       data.raw.data0, data.raw.data1,\n+\t\t       data.ipv4.version,\n+\t\t       data.ipv4.ihl,\n+\t\t       data.ipv4.tos,\n+\t\t       data.ipv4.ttl,\n+\t\t       data.ipv4.protocol);\n+\telse if (m->ol_flags & RTE_IAVF_PKT_RX_DYNF_PROTO_XTR_IPV6)\n+\t\tprintf(\" - Flexible descriptor's Metadata: [0x%04x:0x%04x],\"\n+\t\t       \"ipv6,ver=%u,tc=%u,flow_hi4=0x%x,nexthdr=%u,hoplimit=%u\",\n+\t\t       data.raw.data0, data.raw.data1,\n+\t\t       data.ipv6.version,\n+\t\t       data.ipv6.tc,\n+\t\t       data.ipv6.flowhi4,\n+\t\t       data.ipv6.nexthdr,\n+\t\t       data.ipv6.hoplimit);\n+\telse if (m->ol_flags & RTE_IAVF_PKT_RX_DYNF_PROTO_XTR_IPV6_FLOW)\n+\t\tprintf(\" - Flexible descriptor's Metadata: [0x%04x:0x%04x],\"\n+\t\t       \"ipv6_flow,ver=%u,tc=%u,flow=0x%x%04x\",\n+\t\t       data.raw.data0, data.raw.data1,\n+\t\t       data.ipv6_flow.version,\n+\t\t       data.ipv6_flow.tc,\n+\t\t       data.ipv6_flow.flowhi4,\n+\t\t       data.ipv6_flow.flowlo16);\n+\telse if (m->ol_flags & RTE_IAVF_PKT_RX_DYNF_PROTO_XTR_TCP)\n+\t\tprintf(\" - Flexible descriptor's Metadata: [0x%04x:0x%04x],\"\n+\t\t       \"tcp,doff=%u,flags=%s%s%s%s%s%s%s%s\",\n+\t\t       data.raw.data0, data.raw.data1,\n+\t\t       data.tcp.doff,\n+\t\t       data.tcp.cwr ? \"C\" : \"\",\n+\t\t       data.tcp.ece ? \"E\" : \"\",\n+\t\t       data.tcp.urg ? \"U\" : \"\",\n+\t\t       data.tcp.ack ? \"A\" : \"\",\n+\t\t       data.tcp.psh ? \"P\" : \"\",\n+\t\t       data.tcp.rst ? \"R\" : \"\",\n+\t\t       data.tcp.syn ? \"S\" : \"\",\n+\t\t       data.tcp.fin ? \"F\" : \"\");\n+\telse if (m->ol_flags & RTE_IAVF_PKT_RX_DYNF_PROTO_XTR_IP_OFFSET)\n+\t\tprintf(\" - Flexible descriptor's Extraction: ip_offset=%u\",\n+\t\t       data.ip_ofs);\n+}\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* _RTE_PMD_IAVF_H_ */\ndiff --git a/drivers/net/iavf/rte_pmd_iavf_version.map b/drivers/net/iavf/rte_pmd_iavf_version.map\nindex 4a76d1d52d..d7afd31d14 100644\n--- a/drivers/net/iavf/rte_pmd_iavf_version.map\n+++ b/drivers/net/iavf/rte_pmd_iavf_version.map\n@@ -1,3 +1,16 @@\n DPDK_21 {\n \tlocal: *;\n };\n+\n+EXPERIMENTAL {\n+        global:\n+\n+        # added in 20.11\n+        rte_net_iavf_dynfield_proto_xtr_metadata_offs;\n+        rte_net_iavf_dynflag_proto_xtr_vlan_mask;\n+        rte_net_iavf_dynflag_proto_xtr_ipv4_mask;\n+        rte_net_iavf_dynflag_proto_xtr_ipv6_mask;\n+        rte_net_iavf_dynflag_proto_xtr_ipv6_flow_mask;\n+        rte_net_iavf_dynflag_proto_xtr_tcp_mask;\n+        rte_net_iavf_dynflag_proto_xtr_ip_offset_mask;\n+};\n",
    "prefixes": [
        "v9"
    ]
}