get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 60604,
    "url": "http://patches.dpdk.org/api/patches/60604/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20191007110809.62801-2-bruce.richardson@intel.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<20191007110809.62801-2-bruce.richardson@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20191007110809.62801-2-bruce.richardson@intel.com",
    "date": "2019-10-07T11:08:04",
    "name": "[v7,1/6] examples/ioat: new sample app for ioat driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "72935b6d8965e1f7768f75cf7827c31d778dee70",
    "submitter": {
        "id": 20,
        "url": "http://patches.dpdk.org/api/people/20/?format=api",
        "name": "Bruce Richardson",
        "email": "bruce.richardson@intel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20191007110809.62801-2-bruce.richardson@intel.com/mbox/",
    "series": [
        {
            "id": 6718,
            "url": "http://patches.dpdk.org/api/series/6718/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=6718",
            "date": "2019-10-07T11:08:03",
            "name": "examples/ioat: sample app for ioat driver",
            "version": 7,
            "mbox": "http://patches.dpdk.org/series/6718/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/60604/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/60604/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 6BED11C1F8;\n\tMon,  7 Oct 2019 13:08:28 +0200 (CEST)",
            "from mga01.intel.com (mga01.intel.com [192.55.52.88])\n\tby dpdk.org (Postfix) with ESMTP id 35BA71C1F8\n\tfor <dev@dpdk.org>; Mon,  7 Oct 2019 13:08:26 +0200 (CEST)",
            "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t07 Oct 2019 04:08:26 -0700",
            "from silpixa00399126.ir.intel.com (HELO\n\tsilpixa00399126.ger.corp.intel.com) ([10.237.223.2])\n\tby orsmga002.jf.intel.com with ESMTP; 07 Oct 2019 04:08:25 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.67,268,1566889200\"; d=\"scan'208\";a=\"205041005\"",
        "From": "Bruce Richardson <bruce.richardson@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Marcin Baran <marcinx.baran@intel.com>,\n\tPawel Modrak <pawelx.modrak@intel.com>,\n\tBruce Richardson <bruce.richardson@intel.com>",
        "Date": "Mon,  7 Oct 2019 12:08:04 +0100",
        "Message-Id": "<20191007110809.62801-2-bruce.richardson@intel.com>",
        "X-Mailer": "git-send-email 2.21.0",
        "In-Reply-To": "<20191007110809.62801-1-bruce.richardson@intel.com>",
        "References": "<20190920073714.1314-1-marcinx.baran@intel.com>\n\t<20191007110809.62801-1-bruce.richardson@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v7 1/6] examples/ioat: new sample app for ioat\n\tdriver",
        "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\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Pawel Modrak <pawelx.modrak@intel.com>\n\nA new sample app demonstrating use of driver for CBDMA.  The app receives\npackets, performs software or hardware copy, changes packets' MAC addresses\n(if enabled) and forwards them. The change covers ports initialization,\nclosing connection and argument parsing.\n\nSigned-off-by: Pawel Modrak <pawelx.modrak@intel.com>\nSigned-off-by: Marcin Baran <marcinx.baran@intel.com>\nAcked-by: Bruce Richardson <bruce.richardson@intel.com>\n\n---\nV6: add maintainers file entry for this new app\n---\n MAINTAINERS               |   1 +\n examples/Makefile         |   3 +\n examples/ioat/Makefile    |  54 +++++\n examples/ioat/ioatfwd.c   | 439 ++++++++++++++++++++++++++++++++++++++\n examples/ioat/meson.build |  15 ++\n examples/meson.build      |   1 +\n 6 files changed, 513 insertions(+)\n create mode 100644 examples/ioat/Makefile\n create mode 100644 examples/ioat/ioatfwd.c\n create mode 100644 examples/ioat/meson.build",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 37672b7f6..7e1e6948e 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -1107,6 +1107,7 @@ IOAT Rawdev\n M: Bruce Richardson <bruce.richardson@intel.com>\n F: drivers/raw/ioat/\n F: doc/guides/rawdevs/ioat.rst\n+F: examples/ioat/\n \n NXP DPAA2 QDMA\n M: Nipun Gupta <nipun.gupta@nxp.com>\ndiff --git a/examples/Makefile b/examples/Makefile\nindex de11dd487..3cb313d7d 100644\n--- a/examples/Makefile\n+++ b/examples/Makefile\n@@ -23,6 +23,9 @@ DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += fips_validation\n DIRS-$(CONFIG_RTE_LIBRTE_FLOW_CLASSIFY) += flow_classify\n DIRS-y += flow_filtering\n DIRS-y += helloworld\n+ifeq ($(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV),y)\n+DIRS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV) += ioat\n+endif\n DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += ip_pipeline\n ifeq ($(CONFIG_RTE_LIBRTE_LPM),y)\n DIRS-$(CONFIG_RTE_IP_FRAG) += ip_reassembly\ndiff --git a/examples/ioat/Makefile b/examples/ioat/Makefile\nnew file mode 100644\nindex 000000000..2a4d1da2d\n--- /dev/null\n+++ b/examples/ioat/Makefile\n@@ -0,0 +1,54 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2019 Intel Corporation\n+\n+# binary name\n+APP = ioatfwd\n+\n+# all source are stored in SRCS-y\n+SRCS-y := ioatfwd.c\n+\n+# Build using pkg-config variables if possible\n+ifeq ($(shell pkg-config --exists libdpdk && echo 0),0)\n+\n+all: shared\n+.PHONY: shared static\n+shared: build/$(APP)-shared\n+\tln -sf $(APP)-shared build/$(APP)\n+static: build/$(APP)-static\n+\tln -sf $(APP)-static build/$(APP)\n+\n+PC_FILE := $(shell pkg-config --path libdpdk)\n+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)\n+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)\n+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)\n+\n+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build\n+\t$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)\n+\n+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build\n+\t$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)\n+\n+build:\n+\t@mkdir -p $@\n+\n+.PHONY: clean\n+clean:\n+\trm -f build/$(APP) build/$(APP)-static build/$(APP)-shared\n+\ttest -d build && rmdir -p build || true\n+\n+else # Build using legacy build system\n+ifeq ($(RTE_SDK),)\n+$(error \"Please define RTE_SDK environment variable\")\n+endif\n+\n+# Default target, detect a build directory, by looking for a path with a .config\n+RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config)))))\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+\n+CFLAGS += -O3\n+CFLAGS += $(WERROR_FLAGS)\n+\n+include $(RTE_SDK)/mk/rte.extapp.mk\n+endif\ndiff --git a/examples/ioat/ioatfwd.c b/examples/ioat/ioatfwd.c\nnew file mode 100644\nindex 000000000..b33c1eeb4\n--- /dev/null\n+++ b/examples/ioat/ioatfwd.c\n@@ -0,0 +1,439 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2019 Intel Corporation\n+ */\n+\n+#include <stdint.h>\n+#include <getopt.h>\n+#include <signal.h>\n+#include <stdbool.h>\n+#include <unistd.h>\n+\n+#include <rte_malloc.h>\n+#include <rte_ethdev.h>\n+#include <rte_rawdev.h>\n+#include <rte_ioat_rawdev.h>\n+\n+/* size of ring used for software copying between rx and tx. */\n+#define RTE_LOGTYPE_IOAT RTE_LOGTYPE_USER1\n+#define MAX_PKT_BURST 32\n+#define MEMPOOL_CACHE_SIZE 512\n+#define MIN_POOL_SIZE 65536U\n+#define CMD_LINE_OPT_MAC_UPDATING \"mac-updating\"\n+#define CMD_LINE_OPT_NO_MAC_UPDATING \"no-mac-updating\"\n+#define CMD_LINE_OPT_PORTMASK \"portmask\"\n+#define CMD_LINE_OPT_NB_QUEUE \"nb-queue\"\n+#define CMD_LINE_OPT_COPY_TYPE \"copy-type\"\n+#define CMD_LINE_OPT_RING_SIZE \"ring-size\"\n+\n+/* configurable number of RX/TX ring descriptors */\n+#define RX_DEFAULT_RINGSIZE 1024\n+#define TX_DEFAULT_RINGSIZE 1024\n+\n+/* max number of RX queues per port */\n+#define MAX_RX_QUEUES_COUNT 8\n+\n+struct rxtx_port_config {\n+\t/* common config */\n+\tuint16_t rxtx_port;\n+\tuint16_t nb_queues;\n+\t/* for software copy mode */\n+\tstruct rte_ring *rx_to_tx_ring;\n+\t/* for IOAT rawdev copy mode */\n+\tuint16_t ioat_ids[MAX_RX_QUEUES_COUNT];\n+};\n+\n+struct rxtx_transmission_config {\n+\tstruct rxtx_port_config ports[RTE_MAX_ETHPORTS];\n+\tuint16_t nb_ports;\n+\tuint16_t nb_lcores;\n+};\n+\n+typedef enum copy_mode_t {\n+#define COPY_MODE_SW \"sw\"\n+\tCOPY_MODE_SW_NUM,\n+#define COPY_MODE_IOAT \"hw\"\n+\tCOPY_MODE_IOAT_NUM,\n+\tCOPY_MODE_INVALID_NUM,\n+\tCOPY_MODE_SIZE_NUM = COPY_MODE_INVALID_NUM\n+} copy_mode_t;\n+\n+/* mask of enabled ports */\n+static uint32_t ioat_enabled_port_mask;\n+\n+/* number of RX queues per port */\n+static uint16_t nb_queues = 1;\n+\n+/* MAC updating enabled by default. */\n+static int mac_updating = 1;\n+\n+/* hardare copy mode enabled by default. */\n+static copy_mode_t copy_mode = COPY_MODE_IOAT_NUM;\n+\n+/* size of IOAT rawdev ring for hardware copy mode or\n+ * rte_ring for software copy mode\n+ */\n+static unsigned short ring_size = 2048;\n+\n+/* global transmission config */\n+struct rxtx_transmission_config cfg;\n+\n+/* configurable number of RX/TX ring descriptors */\n+static uint16_t nb_rxd = RX_DEFAULT_RINGSIZE;\n+static uint16_t nb_txd = TX_DEFAULT_RINGSIZE;\n+\n+static volatile bool force_quit;\n+\n+/* ethernet addresses of ports */\n+static struct rte_ether_addr ioat_ports_eth_addr[RTE_MAX_ETHPORTS];\n+\n+static struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS];\n+struct rte_mempool *ioat_pktmbuf_pool;\n+\n+/* Display usage */\n+static void\n+ioat_usage(const char *prgname)\n+{\n+\tprintf(\"%s [EAL options] -- -p PORTMASK [-q NQ]\\n\"\n+\t\t\"  -p --portmask: hexadecimal bitmask of ports to configure\\n\"\n+\t\t\"  -q NQ: number of RX queues per port (default is 1)\\n\"\n+\t\t\"  --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)\\n\"\n+\t\t\"      When enabled:\\n\"\n+\t\t\"       - The source MAC address is replaced by the TX port MAC address\\n\"\n+\t\t\"       - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID\\n\"\n+\t\t\"  -c --copy-type CT: type of copy: sw|hw\\n\"\n+\t\t\"  -s --ring-size RS: size of IOAT rawdev ring for hardware copy mode or rte_ring for software copy mode\\n\",\n+\t\t\tprgname);\n+}\n+\n+static int\n+ioat_parse_portmask(const char *portmask)\n+{\n+\tchar *end = NULL;\n+\tunsigned long pm;\n+\n+\t/* Parse hexadecimal string */\n+\tpm = strtoul(portmask, &end, 16);\n+\tif ((portmask[0] == '\\0') || (end == NULL) || (*end != '\\0'))\n+\t\treturn -1;\n+\n+\treturn pm;\n+}\n+\n+static copy_mode_t\n+ioat_parse_copy_mode(const char *copy_mode)\n+{\n+\tif (strcmp(copy_mode, COPY_MODE_SW) == 0)\n+\t\treturn COPY_MODE_SW_NUM;\n+\telse if (strcmp(copy_mode, COPY_MODE_IOAT) == 0)\n+\t\treturn COPY_MODE_IOAT_NUM;\n+\n+\treturn COPY_MODE_INVALID_NUM;\n+}\n+\n+/* Parse the argument given in the command line of the application */\n+static int\n+ioat_parse_args(int argc, char **argv, unsigned int nb_ports)\n+{\n+\tstatic const char short_options[] =\n+\t\t\"p:\"  /* portmask */\n+\t\t\"q:\"  /* number of RX queues per port */\n+\t\t\"c:\"  /* copy type (sw|hw) */\n+\t\t\"s:\"  /* ring size */\n+\t\t;\n+\n+\tstatic const struct option lgopts[] = {\n+\t\t{CMD_LINE_OPT_MAC_UPDATING, no_argument, &mac_updating, 1},\n+\t\t{CMD_LINE_OPT_NO_MAC_UPDATING, no_argument, &mac_updating, 0},\n+\t\t{CMD_LINE_OPT_PORTMASK, required_argument, NULL, 'p'},\n+\t\t{CMD_LINE_OPT_NB_QUEUE, required_argument, NULL, 'q'},\n+\t\t{CMD_LINE_OPT_COPY_TYPE, required_argument, NULL, 'c'},\n+\t\t{CMD_LINE_OPT_RING_SIZE, required_argument, NULL, 's'},\n+\t\t{NULL, 0, 0, 0}\n+\t};\n+\n+\tconst unsigned int default_port_mask = (1 << nb_ports) - 1;\n+\tint opt, ret;\n+\tchar **argvopt;\n+\tint option_index;\n+\tchar *prgname = argv[0];\n+\n+\tioat_enabled_port_mask = default_port_mask;\n+\targvopt = argv;\n+\n+\twhile ((opt = getopt_long(argc, argvopt, short_options,\n+\t\t\tlgopts, &option_index)) != EOF) {\n+\n+\t\tswitch (opt) {\n+\t\t/* portmask */\n+\t\tcase 'p':\n+\t\t\tioat_enabled_port_mask = ioat_parse_portmask(optarg);\n+\t\t\tif (ioat_enabled_port_mask & ~default_port_mask ||\n+\t\t\t\t\tioat_enabled_port_mask <= 0) {\n+\t\t\t\tprintf(\"Invalid portmask, %s, suggest 0x%x\\n\",\n+\t\t\t\t\t\toptarg, default_port_mask);\n+\t\t\t\tioat_usage(prgname);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase 'q':\n+\t\t\tnb_queues = atoi(optarg);\n+\t\t\tif (nb_queues == 0 || nb_queues > MAX_RX_QUEUES_COUNT) {\n+\t\t\t\tprintf(\"Invalid RX queues number %s. Max %u\\n\",\n+\t\t\t\t\toptarg, MAX_RX_QUEUES_COUNT);\n+\t\t\t\tioat_usage(prgname);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase 'c':\n+\t\t\tcopy_mode = ioat_parse_copy_mode(optarg);\n+\t\t\tif (copy_mode == COPY_MODE_INVALID_NUM) {\n+\t\t\t\tprintf(\"Invalid copy type. Use: sw, hw\\n\");\n+\t\t\t\tioat_usage(prgname);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase 's':\n+\t\t\tring_size = atoi(optarg);\n+\t\t\tif (ring_size == 0) {\n+\t\t\t\tprintf(\"Invalid ring size, %s.\\n\", optarg);\n+\t\t\t\tioat_usage(prgname);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\t/* long options */\n+\t\tcase 0:\n+\t\t\tbreak;\n+\n+\t\tdefault:\n+\t\t\tioat_usage(prgname);\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\tprintf(\"MAC updating %s\\n\", mac_updating ? \"enabled\" : \"disabled\");\n+\tif (optind >= 0)\n+\t\targv[optind - 1] = prgname;\n+\n+\tret = optind - 1;\n+\toptind = 1; /* reset getopt lib */\n+\treturn ret;\n+}\n+\n+/* check link status, return true if at least one port is up */\n+static int\n+check_link_status(uint32_t port_mask)\n+{\n+\tuint16_t portid;\n+\tstruct rte_eth_link link;\n+\tint retval = 0;\n+\n+\tprintf(\"\\nChecking link status\\n\");\n+\tRTE_ETH_FOREACH_DEV(portid) {\n+\t\tif ((port_mask & (1 << portid)) == 0)\n+\t\t\tcontinue;\n+\n+\t\tmemset(&link, 0, sizeof(link));\n+\t\trte_eth_link_get(portid, &link);\n+\n+\t\t/* Print link status */\n+\t\tif (link.link_status) {\n+\t\t\tprintf(\n+\t\t\t\t\"Port %d Link Up. Speed %u Mbps - %s\\n\",\n+\t\t\t\tportid, link.link_speed,\n+\t\t\t\t(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?\n+\t\t\t\t(\"full-duplex\") : (\"half-duplex\\n\"));\n+\t\t\tretval = 1;\n+\t\t} else\n+\t\t\tprintf(\"Port %d Link Down\\n\", portid);\n+\t}\n+\treturn retval;\n+}\n+\n+/*\n+ * Initializes a given port using global settings and with the RX buffers\n+ * coming from the mbuf_pool passed as a parameter.\n+ */\n+static inline void\n+port_init(uint16_t portid, struct rte_mempool *mbuf_pool, uint16_t nb_queues)\n+{\n+\t/* configuring port to use RSS for multiple RX queues */\n+\tstatic const struct rte_eth_conf port_conf = {\n+\t\t.rxmode = {\n+\t\t\t.mq_mode = ETH_MQ_RX_RSS,\n+\t\t\t.max_rx_pkt_len = RTE_ETHER_MAX_LEN\n+\t\t},\n+\t\t.rx_adv_conf = {\n+\t\t\t.rss_conf = {\n+\t\t\t\t.rss_key = NULL,\n+\t\t\t\t.rss_hf = ETH_RSS_PROTO_MASK,\n+\t\t\t}\n+\t\t}\n+\t};\n+\n+\tstruct rte_eth_rxconf rxq_conf;\n+\tstruct rte_eth_txconf txq_conf;\n+\tstruct rte_eth_conf local_port_conf = port_conf;\n+\tstruct rte_eth_dev_info dev_info;\n+\tint ret, i;\n+\n+\t/* Skip ports that are not enabled */\n+\tif ((ioat_enabled_port_mask & (1 << portid)) == 0) {\n+\t\tprintf(\"Skipping disabled port %u\\n\", portid);\n+\t\treturn;\n+\t}\n+\n+\t/* Init port */\n+\tprintf(\"Initializing port %u... \", portid);\n+\tfflush(stdout);\n+\trte_eth_dev_info_get(portid, &dev_info);\n+\tlocal_port_conf.rx_adv_conf.rss_conf.rss_hf &=\n+\t\tdev_info.flow_type_rss_offloads;\n+\tif (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)\n+\t\tlocal_port_conf.txmode.offloads |=\n+\t\t\tDEV_TX_OFFLOAD_MBUF_FAST_FREE;\n+\tret = rte_eth_dev_configure(portid, nb_queues, 1, &local_port_conf);\n+\tif (ret < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Cannot configure device:\"\n+\t\t\t\" err=%d, port=%u\\n\", ret, portid);\n+\n+\tret = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd,\n+\t\t\t&nb_txd);\n+\tif (ret < 0)\n+\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\"Cannot adjust number of descriptors: err=%d, port=%u\\n\",\n+\t\t\tret, portid);\n+\n+\trte_eth_macaddr_get(portid, &ioat_ports_eth_addr[portid]);\n+\n+\t/* Init RX queues */\n+\trxq_conf = dev_info.default_rxconf;\n+\trxq_conf.offloads = local_port_conf.rxmode.offloads;\n+\tfor (i = 0; i < nb_queues; i++) {\n+\t\tret = rte_eth_rx_queue_setup(portid, i, nb_rxd,\n+\t\t\trte_eth_dev_socket_id(portid), &rxq_conf,\n+\t\t\tmbuf_pool);\n+\t\tif (ret < 0)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\"rte_eth_rx_queue_setup:err=%d,port=%u, queue_id=%u\\n\",\n+\t\t\t\tret, portid, i);\n+\t}\n+\n+\t/* Init one TX queue on each port */\n+\ttxq_conf = dev_info.default_txconf;\n+\ttxq_conf.offloads = local_port_conf.txmode.offloads;\n+\tret = rte_eth_tx_queue_setup(portid, 0, nb_txd,\n+\t\t\trte_eth_dev_socket_id(portid),\n+\t\t\t&txq_conf);\n+\tif (ret < 0)\n+\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\"rte_eth_tx_queue_setup:err=%d,port=%u\\n\",\n+\t\t\tret, portid);\n+\n+\t/* Initialize TX buffers */\n+\ttx_buffer[portid] = rte_zmalloc_socket(\"tx_buffer\",\n+\t\t\tRTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0,\n+\t\t\trte_eth_dev_socket_id(portid));\n+\tif (tx_buffer[portid] == NULL)\n+\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\"Cannot allocate buffer for tx on port %u\\n\",\n+\t\t\tportid);\n+\n+\trte_eth_tx_buffer_init(tx_buffer[portid], MAX_PKT_BURST);\n+\n+\t/* Start device */\n+\tret = rte_eth_dev_start(portid);\n+\tif (ret < 0)\n+\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\"rte_eth_dev_start:err=%d, port=%u\\n\",\n+\t\t\tret, portid);\n+\n+\trte_eth_promiscuous_enable(portid);\n+\n+\tprintf(\"Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\\n\\n\",\n+\t\t\tportid,\n+\t\t\tioat_ports_eth_addr[portid].addr_bytes[0],\n+\t\t\tioat_ports_eth_addr[portid].addr_bytes[1],\n+\t\t\tioat_ports_eth_addr[portid].addr_bytes[2],\n+\t\t\tioat_ports_eth_addr[portid].addr_bytes[3],\n+\t\t\tioat_ports_eth_addr[portid].addr_bytes[4],\n+\t\t\tioat_ports_eth_addr[portid].addr_bytes[5]);\n+\n+\tcfg.ports[cfg.nb_ports].rxtx_port = portid;\n+\tcfg.ports[cfg.nb_ports++].nb_queues = nb_queues;\n+}\n+\n+static void\n+signal_handler(int signum)\n+{\n+\tif (signum == SIGINT || signum == SIGTERM) {\n+\t\tprintf(\"\\n\\nSignal %d received, preparing to exit...\\n\",\n+\t\t\tsignum);\n+\t\tforce_quit = true;\n+\t}\n+}\n+\n+int\n+main(int argc, char **argv)\n+{\n+\tint ret;\n+\tuint16_t nb_ports, portid;\n+\tuint32_t i;\n+\tunsigned int nb_mbufs;\n+\n+\t/* Init EAL */\n+\tret = rte_eal_init(argc, argv);\n+\tif (ret < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Invalid EAL arguments\\n\");\n+\targc -= ret;\n+\targv += ret;\n+\n+\tforce_quit = false;\n+\tsignal(SIGINT, signal_handler);\n+\tsignal(SIGTERM, signal_handler);\n+\n+\tnb_ports = rte_eth_dev_count_avail();\n+\tif (nb_ports == 0)\n+\t\trte_exit(EXIT_FAILURE, \"No Ethernet ports - bye\\n\");\n+\n+\t/* Parse application arguments (after the EAL ones) */\n+\tret = ioat_parse_args(argc, argv, nb_ports);\n+\tif (ret < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Invalid IOAT arguments\\n\");\n+\n+\tnb_mbufs = RTE_MAX(nb_ports * (nb_queues * (nb_rxd + nb_txd +\n+\t\t4 * MAX_PKT_BURST) + rte_lcore_count() * MEMPOOL_CACHE_SIZE),\n+\t\tMIN_POOL_SIZE);\n+\n+\t/* Create the mbuf pool */\n+\tioat_pktmbuf_pool = rte_pktmbuf_pool_create(\"mbuf_pool\", nb_mbufs,\n+\t\tMEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE,\n+\t\trte_socket_id());\n+\tif (ioat_pktmbuf_pool == NULL)\n+\t\trte_exit(EXIT_FAILURE, \"Cannot init mbuf pool\\n\");\n+\n+\t/* Initialise each port */\n+\tcfg.nb_ports = 0;\n+\tRTE_ETH_FOREACH_DEV(portid)\n+\t\tport_init(portid, ioat_pktmbuf_pool, nb_queues);\n+\n+\twhile (!check_link_status(ioat_enabled_port_mask) && !force_quit)\n+\t\tsleep(1);\n+\n+\t/* Check if there is enough lcores for all ports. */\n+\tcfg.nb_lcores = rte_lcore_count() - 1;\n+\tif (cfg.nb_lcores < 1)\n+\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\"There should be at least one slave lcore.\\n\");\n+\tfor (i = 0; i < cfg.nb_ports; i++) {\n+\t\tprintf(\"Closing port %d\\n\", cfg.ports[i].rxtx_port);\n+\t\trte_eth_dev_stop(cfg.ports[i].rxtx_port);\n+\t\trte_eth_dev_close(cfg.ports[i].rxtx_port);\n+\t}\n+\n+\tprintf(\"Bye...\\n\");\n+\treturn 0;\n+}\ndiff --git a/examples/ioat/meson.build b/examples/ioat/meson.build\nnew file mode 100644\nindex 000000000..ed8328963\n--- /dev/null\n+++ b/examples/ioat/meson.build\n@@ -0,0 +1,15 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2019 Intel Corporation\n+\n+# meson file, for building this example as part of a main DPDK build.\n+#\n+# To build this example as a standalone application with an already-installed\n+# DPDK instance, use 'make'\n+\n+build = dpdk_conf.has('RTE_LIBRTE_PMD_IOAT_RAWDEV')\n+\n+deps += ['rawdev_ioat']\n+\n+sources = files(\n+\t'ioatfwd.c'\n+)\ndiff --git a/examples/meson.build b/examples/meson.build\nindex a046b74ad..c2e18b59b 100644\n--- a/examples/meson.build\n+++ b/examples/meson.build\n@@ -16,6 +16,7 @@ all_examples = [\n \t'eventdev_pipeline', 'exception_path',\n \t'fips_validation', 'flow_classify',\n \t'flow_filtering', 'helloworld',\n+\t'ioat',\n \t'ip_fragmentation', 'ip_pipeline',\n \t'ip_reassembly', 'ipsec-secgw',\n \t'ipv4_multicast', 'kni',\n",
    "prefixes": [
        "v7",
        "1/6"
    ]
}