get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 23224,
    "url": "http://patches.dpdk.org/api/patches/23224/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1491335458-25355-1-git-send-email-ed.czeck@atomicrules.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": "<1491335458-25355-1-git-send-email-ed.czeck@atomicrules.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1491335458-25355-1-git-send-email-ed.czeck@atomicrules.com",
    "date": "2017-04-04T19:50:58",
    "name": "[dpdk-dev,v8,4/7] net/ark: provide API for hardware modules pktchkr and pktgen",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "c3df0bde0c4510408719053427529b87c4a8198e",
    "submitter": {
        "id": 699,
        "url": "http://patches.dpdk.org/api/people/699/?format=api",
        "name": "Ed Czeck",
        "email": "ed.czeck@atomicrules.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1491335458-25355-1-git-send-email-ed.czeck@atomicrules.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/23224/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/23224/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 [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id B2C2B37B3;\n\tTue,  4 Apr 2017 21:51:06 +0200 (CEST)",
            "from mail-qk0-f196.google.com (mail-qk0-f196.google.com\n\t[209.85.220.196]) by dpdk.org (Postfix) with ESMTP id 418DA37B3\n\tfor <dev@dpdk.org>; Tue,  4 Apr 2017 21:51:05 +0200 (CEST)",
            "by mail-qk0-f196.google.com with SMTP id k139so13793300qke.2\n\tfor <dev@dpdk.org>; Tue, 04 Apr 2017 12:51:05 -0700 (PDT)",
            "from z170.home (pool-173-48-118-253.bstnma.fios.verizon.net.\n\t[173.48.118.253]) by smtp.gmail.com with ESMTPSA id\n\tu5sm12526362qkd.46.2017.04.04.12.51.03\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tTue, 04 Apr 2017 12:51:03 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=atomicrules-com.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=SS0eh/2f7RzLzdcAGH7Y5HPwRvjeRZ+14/eVbeS0WzE=;\n\tb=dWMt/kHw3XmmoW1DtmGBM/lJoaZ7RZT4xZf6KV3A3E3jyNT0AVNCIGwWCDXiTGx1Xa\n\tpj1MZ2JHrPzQ0Ap53ngZ/0o+rF/o/Dx0xQnS1OxK6Dp61ytNEp+WdCTWE9vD9eKAUUPl\n\tH2DB9D2zfqxAN4o2D7skRw7V73Y3Ihtdt+PDREPy3wX4Zs0XtzektwFgCLgbPiimeSnd\n\twHzh8QQI6HECabi7UL2YPATen/2retSWUnN+0/29xW9msnev8hcidm6R9AhjeL9gCote\n\tISJTpfsIliox+tUic+4HTlxCVnjYDxk8INDmE/fCtcffX+0eFt1jT0VSWMLZKLWwuWEn\n\tmsig==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=SS0eh/2f7RzLzdcAGH7Y5HPwRvjeRZ+14/eVbeS0WzE=;\n\tb=S5bplrbmHtHbbwfS3B8E7jVq0pw90Hkmax4RiVL0GsO6vAKC4uWTGKhkMRtujWYlKQ\n\tQC8ZSSQnCkrIs+PeW6VYt7IKg88l8PBG2Oixj5ETBB+3IBjLCF7FnRTclQMqtsn4CpJL\n\trs76iCkT80vYSnvbxSSIuzSSMty4nPC/pmZroXNSsr5tbUacduZh/uVQOGSk0R7KBqp7\n\t4Bny7uLQSSH74Z0EraHP/i+sWluedYNsT0mddrgcd+lcKzVzaif53vwbOvmeyjzVieWW\n\tI/dAUpn5GM12eNn4rWe+C6ml7O50kMF18KD8WTZ3vGHEEkIKwOMGDhxjaEsY13dcGwGK\n\tJ/Zg==",
        "X-Gm-Message-State": "AFeK/H1GUKS1Tp8fVnSnlblVyJaNfw/YjDEKhb/kAL9iG+EUBpI9ccKtLDetu4+fHiN78A==",
        "X-Received": "by 10.55.71.11 with SMTP id u11mr26052314qka.78.1491335464154;\n\tTue, 04 Apr 2017 12:51:04 -0700 (PDT)",
        "From": "Ed Czeck <ed.czeck@atomicrules.com>",
        "To": "dev@dpdk.org",
        "Cc": "john.miller@atomicrules.com, shepard.siegel@atomicrules.com,\n\tferruh.yigit@intel.com, stephen@networkplumber.org,\n\tEd Czeck <ed.czeck@atomicrules.com>",
        "Date": "Tue,  4 Apr 2017 15:50:58 -0400",
        "Message-Id": "<1491335458-25355-1-git-send-email-ed.czeck@atomicrules.com>",
        "X-Mailer": "git-send-email 1.9.1",
        "In-Reply-To": "<1490823244-13221-1-git-send-email-ed.czeck@atomicrules.com>",
        "References": "<1490823244-13221-1-git-send-email-ed.czeck@atomicrules.com>",
        "Subject": "[dpdk-dev] [PATCH v8 4/7] net/ark: provide API for hardware modules\n\tpktchkr and pktgen",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Provide C-level interface for Arkville's internal HW resources\npktchkr and pktgen\n\nv6:\n* bug fix handing empty dev arguments.\n* Unify messaging and logging\n* Improve comments\n\nSigned-off-by: Ed Czeck <ed.czeck@atomicrules.com>\n---\n drivers/net/ark/Makefile      |   2 +\n drivers/net/ark/ark_pktchkr.c | 474 ++++++++++++++++++++++++++++++++++++++++\n drivers/net/ark/ark_pktchkr.h | 117 ++++++++++\n drivers/net/ark/ark_pktgen.c  | 496 ++++++++++++++++++++++++++++++++++++++++++\n drivers/net/ark/ark_pktgen.h  | 108 +++++++++\n 5 files changed, 1197 insertions(+)\n create mode 100644 drivers/net/ark/ark_pktchkr.c\n create mode 100644 drivers/net/ark/ark_pktchkr.h\n create mode 100644 drivers/net/ark/ark_pktgen.c\n create mode 100644 drivers/net/ark/ark_pktgen.h",
    "diff": "diff --git a/drivers/net/ark/Makefile b/drivers/net/ark/Makefile\nindex 06b2451..a086162 100644\n--- a/drivers/net/ark/Makefile\n+++ b/drivers/net/ark/Makefile\n@@ -49,7 +49,9 @@ LIBABIVER := 1\n SRCS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark_ddm.c\n SRCS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark_ethdev.c\n SRCS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark_mpu.c\n+SRCS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark_pktchkr.c\n SRCS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark_pktdir.c\n+SRCS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark_pktgen.c\n SRCS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark_rqp.c\n SRCS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark_udm.c\n \ndiff --git a/drivers/net/ark/ark_pktchkr.c b/drivers/net/ark/ark_pktchkr.c\nnew file mode 100644\nindex 0000000..62b3673\n--- /dev/null\n+++ b/drivers/net/ark/ark_pktchkr.c\n@@ -0,0 +1,474 @@\n+/*-\n+ * BSD LICENSE\n+ *\n+ * Copyright (c) 2015-2017 Atomic Rules LLC\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions\n+ * are met:\n+ *\n+ * * Redistributions of source code must retain the above copyright\n+ * notice, this list of conditions and the following disclaimer.\n+ * * Redistributions in binary form must reproduce the above copyright\n+ * notice, this list of conditions and the following disclaimer in\n+ * the documentation and/or other materials provided with the\n+ * distribution.\n+ * * Neither the name of copyright holder nor the names of its\n+ * contributors may be used to endorse or promote products derived\n+ * from this software without specific prior written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <getopt.h>\n+#include <sys/time.h>\n+#include <locale.h>\n+#include <unistd.h>\n+\n+#include <rte_ethdev.h>\n+#include <rte_malloc.h>\n+\n+#include \"ark_pktchkr.h\"\n+#include \"ark_logs.h\"\n+\n+static int set_arg(char *arg, char *val);\n+static int ark_pktchkr_is_gen_forever(ark_pkt_chkr_t handle);\n+\n+#define ARK_MAX_STR_LEN 64\n+union OPTV {\n+\tint INT;\n+\tint BOOL;\n+\tuint64_t LONG;\n+\tchar STR[ARK_MAX_STR_LEN];\n+};\n+\n+enum OPTYPE {\n+\tOTINT,\n+\tOTLONG,\n+\tOTBOOL,\n+\tOTSTRING\n+};\n+\n+struct OPTIONS {\n+\tchar opt[ARK_MAX_STR_LEN];\n+\tenum OPTYPE t;\n+\tunion OPTV v;\n+};\n+\n+static struct OPTIONS toptions[] = {\n+\t{{\"configure\"}, OTBOOL, {1} },\n+\t{{\"port\"}, OTINT, {0} },\n+\t{{\"mac-dump\"}, OTBOOL, {0} },\n+\t{{\"dg-mode\"}, OTBOOL, {1} },\n+\t{{\"run\"}, OTBOOL, {0} },\n+\t{{\"stop\"}, OTBOOL, {0} },\n+\t{{\"dump\"}, OTBOOL, {0} },\n+\t{{\"en_resync\"}, OTBOOL, {0} },\n+\t{{\"tuser_err_val\"}, OTINT, {1} },\n+\t{{\"gen_forever\"}, OTBOOL, {0} },\n+\t{{\"en_slaved_start\"}, OTBOOL, {0} },\n+\t{{\"vary_length\"}, OTBOOL, {0} },\n+\t{{\"incr_payload\"}, OTINT, {0} },\n+\t{{\"incr_first_byte\"}, OTBOOL, {0} },\n+\t{{\"ins_seq_num\"}, OTBOOL, {0} },\n+\t{{\"ins_time_stamp\"}, OTBOOL, {1} },\n+\t{{\"ins_udp_hdr\"}, OTBOOL, {0} },\n+\t{{\"num_pkts\"}, OTLONG, .v.LONG = 10000000000000L},\n+\t{{\"payload_byte\"}, OTINT, {0x55} },\n+\t{{\"pkt_spacing\"}, OTINT, {60} },\n+\t{{\"pkt_size_min\"}, OTINT, {2005} },\n+\t{{\"pkt_size_max\"}, OTINT, {1514} },\n+\t{{\"pkt_size_incr\"}, OTINT, {1} },\n+\t{{\"eth_type\"}, OTINT, {0x0800} },\n+\t{{\"src_mac_addr\"}, OTLONG, .v.LONG = 0xdC3cF6425060L},\n+\t{{\"dst_mac_addr\"}, OTLONG, .v.LONG = 0x112233445566L},\n+\t{{\"hdr_dW0\"}, OTINT, {0x0016e319} },\n+\t{{\"hdr_dW1\"}, OTINT, {0x27150004} },\n+\t{{\"hdr_dW2\"}, OTINT, {0x76967bda} },\n+\t{{\"hdr_dW3\"}, OTINT, {0x08004500} },\n+\t{{\"hdr_dW4\"}, OTINT, {0x005276ed} },\n+\t{{\"hdr_dW5\"}, OTINT, {0x40004006} },\n+\t{{\"hdr_dW6\"}, OTINT, {0x56cfc0a8} },\n+\t{{\"start_offset\"}, OTINT, {0} },\n+\t{{\"dst_ip\"}, OTSTRING, .v.STR = \"169.254.10.240\"},\n+\t{{\"dst_port\"}, OTINT, {65536} },\n+\t{{\"src_port\"}, OTINT, {65536} },\n+};\n+\n+ark_pkt_chkr_t\n+ark_pktchkr_init(void *addr, int ord, int l2_mode)\n+{\n+\tstruct ark_pkt_chkr_inst *inst =\n+\t\trte_malloc(\"ark_pkt_chkr_inst\",\n+\t\t\t   sizeof(struct ark_pkt_chkr_inst), 0);\n+\tinst->sregs = (struct ark_pkt_chkr_stat_regs *)addr;\n+\tinst->cregs =\n+\t\t(struct ark_pkt_chkr_ctl_regs *)(((uint8_t *)addr) + 0x100);\n+\tinst->ordinal = ord;\n+\tinst->l2_mode = l2_mode;\n+\treturn inst;\n+}\n+\n+void\n+ark_pktchkr_uninit(ark_pkt_chkr_t handle)\n+{\n+\trte_free(handle);\n+}\n+\n+void\n+ark_pktchkr_run(ark_pkt_chkr_t handle)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\n+\tinst->sregs->pkt_start_stop = 0;\n+\tinst->sregs->pkt_start_stop = 0x1;\n+}\n+\n+int\n+ark_pktchkr_stopped(ark_pkt_chkr_t handle)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\tuint32_t r = inst->sregs->pkt_start_stop;\n+\n+\treturn (((r >> 16) & 1) == 1);\n+}\n+\n+void\n+ark_pktchkr_stop(ark_pkt_chkr_t handle)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\tint wait_cycle = 10;\n+\n+\tinst->sregs->pkt_start_stop = 0;\n+\twhile (!ark_pktchkr_stopped(handle) && (wait_cycle > 0)) {\n+\t\tusleep(1000);\n+\t\twait_cycle--;\n+\t\tPMD_DEBUG_LOG(DEBUG, \"Waiting for pktchk %d to stop...\\n\",\n+\t\t\t      inst->ordinal);\n+\t}\n+\tPMD_DEBUG_LOG(DEBUG, \"Pktchk %d stopped.\\n\", inst->ordinal);\n+}\n+\n+int\n+ark_pktchkr_is_running(ark_pkt_chkr_t handle)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\tuint32_t r = inst->sregs->pkt_start_stop;\n+\n+\treturn ((r & 1) == 1);\n+}\n+\n+static void\n+ark_pktchkr_set_pkt_ctrl(ark_pkt_chkr_t handle,\n+\t\t\t uint32_t gen_forever,\n+\t\t\t uint32_t vary_length,\n+\t\t\t uint32_t incr_payload,\n+\t\t\t uint32_t incr_first_byte,\n+\t\t\t uint32_t ins_seq_num,\n+\t\t\t uint32_t ins_udp_hdr,\n+\t\t\t uint32_t en_resync,\n+\t\t\t uint32_t tuser_err_val,\n+\t\t\t uint32_t ins_time_stamp)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\tuint32_t r = (tuser_err_val << 16) | (en_resync << 0);\n+\n+\tinst->sregs->pkt_ctrl = r;\n+\tif (!inst->l2_mode)\n+\t\tins_udp_hdr = 0;\n+\tr = ((gen_forever << 24) |\n+\t     (vary_length << 16) |\n+\t     (incr_payload << 12) |\n+\t     (incr_first_byte << 8) |\n+\t     (ins_time_stamp << 5) |\n+\t     (ins_seq_num << 4) |\n+\t     ins_udp_hdr);\n+\tinst->cregs->pkt_ctrl = r;\n+}\n+\n+static\n+int\n+ark_pktchkr_is_gen_forever(ark_pkt_chkr_t handle)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\tuint32_t r = inst->cregs->pkt_ctrl;\n+\n+\treturn (((r >> 24) & 1) == 1);\n+}\n+\n+int\n+ark_pktchkr_wait_done(ark_pkt_chkr_t handle)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\n+\tif (ark_pktchkr_is_gen_forever(handle)) {\n+\t\tPMD_DEBUG_LOG(ERR, \"Pktchk wait_done will not terminate\"\n+\t\t\t      \" because gen_forever=1\\n\");\n+\t\treturn -1;\n+\t}\n+\tint wait_cycle = 10;\n+\n+\twhile (!ark_pktchkr_stopped(handle) && (wait_cycle > 0)) {\n+\t\tusleep(1000);\n+\t\twait_cycle--;\n+\t\tPMD_DEBUG_LOG(DEBUG, \"Waiting for packet checker %d's\"\n+\t\t\t      \" internal pktgen to finish sending...\\n\",\n+\t\t\t      inst->ordinal);\n+\t\tPMD_DEBUG_LOG(DEBUG, \"Pktchk %d's pktgen done.\\n\",\n+\t\t\t      inst->ordinal);\n+\t}\n+\treturn 0;\n+}\n+\n+int\n+ark_pktchkr_get_pkts_sent(ark_pkt_chkr_t handle)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\n+\treturn inst->cregs->pkts_sent;\n+}\n+\n+void\n+ark_pktchkr_set_payload_byte(ark_pkt_chkr_t handle, uint32_t b)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\n+\tinst->cregs->pkt_payload = b;\n+}\n+\n+void\n+ark_pktchkr_set_pkt_size_min(ark_pkt_chkr_t handle, uint32_t x)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\n+\tinst->cregs->pkt_size_min = x;\n+}\n+\n+void\n+ark_pktchkr_set_pkt_size_max(ark_pkt_chkr_t handle, uint32_t x)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\n+\tinst->cregs->pkt_size_max = x;\n+}\n+\n+void\n+ark_pktchkr_set_pkt_size_incr(ark_pkt_chkr_t handle, uint32_t x)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\n+\tinst->cregs->pkt_size_incr = x;\n+}\n+\n+void\n+ark_pktchkr_set_num_pkts(ark_pkt_chkr_t handle, uint32_t x)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\n+\tinst->cregs->num_pkts = x;\n+}\n+\n+void\n+ark_pktchkr_set_src_mac_addr(ark_pkt_chkr_t handle, uint64_t mac_addr)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\n+\tinst->cregs->src_mac_addr_h = (mac_addr >> 32) & 0xffff;\n+\tinst->cregs->src_mac_addr_l = mac_addr & 0xffffffff;\n+}\n+\n+void\n+ark_pktchkr_set_dst_mac_addr(ark_pkt_chkr_t handle, uint64_t mac_addr)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\n+\tinst->cregs->dst_mac_addr_h = (mac_addr >> 32) & 0xffff;\n+\tinst->cregs->dst_mac_addr_l = mac_addr & 0xffffffff;\n+}\n+\n+void\n+ark_pktchkr_set_eth_type(ark_pkt_chkr_t handle, uint32_t x)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\n+\tinst->cregs->eth_type = x;\n+}\n+\n+void\n+ark_pktchkr_set_hdr_dW(ark_pkt_chkr_t handle, uint32_t *hdr)\n+{\n+\tuint32_t i;\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\n+\tfor (i = 0; i < 7; i++)\n+\t\tinst->cregs->hdr_dw[i] = hdr[i];\n+}\n+\n+void\n+ark_pktchkr_dump_stats(ark_pkt_chkr_t handle)\n+{\n+\tstruct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;\n+\n+\tPMD_STATS_LOG(INFO, \"pkts_rcvd      = (%'u)\\n\",\n+\t\t      inst->sregs->pkts_rcvd);\n+\tPMD_STATS_LOG(INFO, \"bytes_rcvd     = (%'\" PRIU64 \")\\n\",\n+\t\t      inst->sregs->bytes_rcvd);\n+\tPMD_STATS_LOG(INFO, \"pkts_ok        = (%'u)\\n\",\n+\t\t      inst->sregs->pkts_ok);\n+\tPMD_STATS_LOG(INFO, \"pkts_mismatch  = (%'u)\\n\",\n+\t\t      inst->sregs->pkts_mismatch);\n+\tPMD_STATS_LOG(INFO, \"pkts_err       = (%'u)\\n\",\n+\t\t      inst->sregs->pkts_err);\n+\tPMD_STATS_LOG(INFO, \"first_mismatch = (%'u)\\n\",\n+\t\t      inst->sregs->first_mismatch);\n+\tPMD_STATS_LOG(INFO, \"resync_events  = (%'u)\\n\",\n+\t\t      inst->sregs->resync_events);\n+\tPMD_STATS_LOG(INFO, \"pkts_missing   = (%'u)\\n\",\n+\t\t      inst->sregs->pkts_missing);\n+\tPMD_STATS_LOG(INFO, \"min_latency    = (%'u)\\n\",\n+\t\t      inst->sregs->min_latency);\n+\tPMD_STATS_LOG(INFO, \"max_latency    = (%'u)\\n\",\n+\t\t      inst->sregs->max_latency);\n+}\n+\n+static struct OPTIONS *\n+options(const char *id)\n+{\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < sizeof(toptions) / sizeof(struct OPTIONS); i++) {\n+\t\tif (strcmp(id, toptions[i].opt) == 0)\n+\t\t\treturn &toptions[i];\n+\t}\n+\tPMD_DRV_LOG(ERR,\n+\t\t    \"pktchkr: Could not find requested option!, option = %s\\n\",\n+\t\t    id);\n+\treturn NULL;\n+}\n+\n+static int\n+set_arg(char *arg, char *val)\n+{\n+\tstruct OPTIONS *o = options(arg);\n+\n+\tif (o) {\n+\t\tswitch (o->t) {\n+\t\tcase OTINT:\n+\t\tcase OTBOOL:\n+\t\t\to->v.INT = atoi(val);\n+\t\t\tbreak;\n+\t\tcase OTLONG:\n+\t\t\to->v.INT = atoll(val);\n+\t\t\tbreak;\n+\t\tcase OTSTRING:\n+\t\t\tstrncpy(o->v.STR, val, ARK_MAX_STR_LEN);\n+\t\t\tbreak;\n+\t\t}\n+\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\n+\n+/******\n+ * Arg format = \"opt0=v,opt_n=v ...\"\n+ ******/\n+void\n+ark_pktchkr_parse(char *args)\n+{\n+\tchar *argv, *v;\n+\tconst char toks[] = \"=\\n\\t\\v\\f \\r\";\n+\targv = strtok(args, toks);\n+\tv = strtok(NULL, toks);\n+\twhile (argv && v) {\n+\t\tset_arg(argv, v);\n+\t\targv = strtok(NULL, toks);\n+\t\tv = strtok(NULL, toks);\n+\t}\n+}\n+\n+static int32_t parse_ipv4_string(char const *ip_address);\n+static int32_t\n+parse_ipv4_string(char const *ip_address)\n+{\n+\tunsigned int ip[4];\n+\n+\tif (sscanf(ip_address, \"%u.%u.%u.%u\",\n+\t\t   &ip[0], &ip[1], &ip[2], &ip[3]) != 4)\n+\t\treturn 0;\n+\treturn ip[3] + ip[2] * 0x100 + ip[1] * 0x10000ul + ip[0] * 0x1000000ul;\n+}\n+\n+void\n+ark_pktchkr_setup(ark_pkt_chkr_t handle)\n+{\n+\tuint32_t hdr[7];\n+\tint32_t dst_ip = parse_ipv4_string(options(\"dst_ip\")->v.STR);\n+\n+\tif (!options(\"stop\")->v.BOOL && options(\"configure\")->v.BOOL) {\n+\t\tark_pktchkr_set_payload_byte(handle,\n+\t\t\t\t\t     options(\"payload_byte\")->v.INT);\n+\t\tark_pktchkr_set_src_mac_addr(handle,\n+\t\t\t\t\t     options(\"src_mac_addr\")->v.INT);\n+\t\tark_pktchkr_set_dst_mac_addr(handle,\n+\t\t\t\t\t     options(\"dst_mac_addr\")->v.LONG);\n+\n+\t\tark_pktchkr_set_eth_type(handle,\n+\t\t\t\t\t options(\"eth_type\")->v.INT);\n+\t\tif (options(\"dg-mode\")->v.BOOL) {\n+\t\t\thdr[0] = options(\"hdr_dW0\")->v.INT;\n+\t\t\thdr[1] = options(\"hdr_dW1\")->v.INT;\n+\t\t\thdr[2] = options(\"hdr_dW2\")->v.INT;\n+\t\t\thdr[3] = options(\"hdr_dW3\")->v.INT;\n+\t\t\thdr[4] = options(\"hdr_dW4\")->v.INT;\n+\t\t\thdr[5] = options(\"hdr_dW5\")->v.INT;\n+\t\t\thdr[6] = options(\"hdr_dW6\")->v.INT;\n+\t\t} else {\n+\t\t\thdr[0] = dst_ip;\n+\t\t\thdr[1] = options(\"dst_port\")->v.INT;\n+\t\t\thdr[2] = options(\"src_port\")->v.INT;\n+\t\t\thdr[3] = 0;\n+\t\t\thdr[4] = 0;\n+\t\t\thdr[5] = 0;\n+\t\t\thdr[6] = 0;\n+\t\t}\n+\t\tark_pktchkr_set_hdr_dW(handle, hdr);\n+\t\tark_pktchkr_set_num_pkts(handle,\n+\t\t\t\t\t options(\"num_pkts\")->v.INT);\n+\t\tark_pktchkr_set_pkt_size_min(handle,\n+\t\t\t\t\t     options(\"pkt_size_min\")->v.INT);\n+\t\tark_pktchkr_set_pkt_size_max(handle,\n+\t\t\t\t\t     options(\"pkt_size_max\")->v.INT);\n+\t\tark_pktchkr_set_pkt_size_incr(handle,\n+\t\t\t\t\t      options(\"pkt_size_incr\")->v.INT);\n+\t\tark_pktchkr_set_pkt_ctrl(handle,\n+\t\t\t\t\t options(\"gen_forever\")->v.BOOL,\n+\t\t\t\t\t options(\"vary_length\")->v.BOOL,\n+\t\t\t\t\t options(\"incr_payload\")->v.BOOL,\n+\t\t\t\t\t options(\"incr_first_byte\")->v.BOOL,\n+\t\t\t\t\t options(\"ins_seq_num\")->v.INT,\n+\t\t\t\t\t options(\"ins_udp_hdr\")->v.BOOL,\n+\t\t\t\t\t options(\"en_resync\")->v.BOOL,\n+\t\t\t\t\t options(\"tuser_err_val\")->v.INT,\n+\t\t\t\t\t options(\"ins_time_stamp\")->v.INT);\n+\t}\n+\n+\tif (options(\"stop\")->v.BOOL)\n+\t\tark_pktchkr_stop(handle);\n+\n+\tif (options(\"run\")->v.BOOL) {\n+\t\tPMD_DEBUG_LOG(DEBUG, \"Starting packet checker on port %d\\n\",\n+\t\t\t      options(\"port\")->v.INT);\n+\t\tark_pktchkr_run(handle);\n+\t}\n+}\ndiff --git a/drivers/net/ark/ark_pktchkr.h b/drivers/net/ark/ark_pktchkr.h\nnew file mode 100644\nindex 0000000..f4025dd\n--- /dev/null\n+++ b/drivers/net/ark/ark_pktchkr.h\n@@ -0,0 +1,117 @@\n+/*-\n+ * BSD LICENSE\n+ *\n+ * Copyright (c) 2015-2017 Atomic Rules LLC\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions\n+ * are met:\n+ *\n+ * * Redistributions of source code must retain the above copyright\n+ * notice, this list of conditions and the following disclaimer.\n+ * * Redistributions in binary form must reproduce the above copyright\n+ * notice, this list of conditions and the following disclaimer in\n+ * the documentation and/or other materials provided with the\n+ * distribution.\n+ * * Neither the name of copyright holder nor the names of its\n+ * contributors may be used to endorse or promote products derived\n+ * from this software without specific prior written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef _ARK_PKTCHKR_H_\n+#define _ARK_PKTCHKR_H_\n+\n+#include <stdint.h>\n+#include <inttypes.h>\n+\n+#define ARK_PKTCHKR_BASE_ADR  0x90000\n+\n+typedef void *ark_pkt_chkr_t;\n+\n+/* The packet checker is an internal Arkville hardware module, which\n+ * verifies packet streams generated from the corresponding packet\n+ * generator.  This module is used for Arkville testing.\n+ * This module is *not* intended for end-user manipulation, hence\n+ * there is minimal documentation.\n+ */\n+\n+/*\n+ * This are overlay structures to a memory mapped FPGA device.  These\n+ * structs will never be instantiated in ram memory\n+ */\n+struct ark_pkt_chkr_stat_regs {\n+\tuint32_t r0;\n+\tuint32_t pkt_start_stop;\n+\tuint32_t pkt_ctrl;\n+\tuint32_t pkts_rcvd;\n+\tuint64_t bytes_rcvd;\n+\tuint32_t pkts_ok;\n+\tuint32_t pkts_mismatch;\n+\tuint32_t pkts_err;\n+\tuint32_t first_mismatch;\n+\tuint32_t resync_events;\n+\tuint32_t pkts_missing;\n+\tuint32_t min_latency;\n+\tuint32_t max_latency;\n+} __attribute__ ((packed));\n+\n+struct ark_pkt_chkr_ctl_regs {\n+\tuint32_t pkt_ctrl;\n+\tuint32_t pkt_payload;\n+\tuint32_t pkt_size_min;\n+\tuint32_t pkt_size_max;\n+\tuint32_t pkt_size_incr;\n+\tuint32_t num_pkts;\n+\tuint32_t pkts_sent;\n+\tuint32_t src_mac_addr_l;\n+\tuint32_t src_mac_addr_h;\n+\tuint32_t dst_mac_addr_l;\n+\tuint32_t dst_mac_addr_h;\n+\tuint32_t eth_type;\n+\tuint32_t hdr_dw[7];\n+} __attribute__ ((packed));\n+\n+struct ark_pkt_chkr_inst {\n+\tstruct rte_eth_dev_info *dev_info;\n+\tvolatile struct ark_pkt_chkr_stat_regs *sregs;\n+\tvolatile struct ark_pkt_chkr_ctl_regs *cregs;\n+\tint l2_mode;\n+\tint ordinal;\n+};\n+\n+/*  packet checker functions */\n+ark_pkt_chkr_t ark_pktchkr_init(void *addr, int ord, int l2_mode);\n+void ark_pktchkr_uninit(ark_pkt_chkr_t handle);\n+void ark_pktchkr_run(ark_pkt_chkr_t handle);\n+int ark_pktchkr_stopped(ark_pkt_chkr_t handle);\n+void ark_pktchkr_stop(ark_pkt_chkr_t handle);\n+int ark_pktchkr_is_running(ark_pkt_chkr_t handle);\n+int ark_pktchkr_get_pkts_sent(ark_pkt_chkr_t handle);\n+void ark_pktchkr_set_payload_byte(ark_pkt_chkr_t handle, uint32_t b);\n+void ark_pktchkr_set_pkt_size_min(ark_pkt_chkr_t handle, uint32_t x);\n+void ark_pktchkr_set_pkt_size_max(ark_pkt_chkr_t handle, uint32_t x);\n+void ark_pktchkr_set_pkt_size_incr(ark_pkt_chkr_t handle, uint32_t x);\n+void ark_pktchkr_set_num_pkts(ark_pkt_chkr_t handle, uint32_t x);\n+void ark_pktchkr_set_src_mac_addr(ark_pkt_chkr_t handle, uint64_t mac_addr);\n+void ark_pktchkr_set_dst_mac_addr(ark_pkt_chkr_t handle, uint64_t mac_addr);\n+void ark_pktchkr_set_eth_type(ark_pkt_chkr_t handle, uint32_t x);\n+void ark_pktchkr_set_hdr_dW(ark_pkt_chkr_t handle, uint32_t *hdr);\n+void ark_pktchkr_parse(char *args);\n+void ark_pktchkr_setup(ark_pkt_chkr_t handle);\n+void ark_pktchkr_dump_stats(ark_pkt_chkr_t handle);\n+int ark_pktchkr_wait_done(ark_pkt_chkr_t handle);\n+\n+#endif\ndiff --git a/drivers/net/ark/ark_pktgen.c b/drivers/net/ark/ark_pktgen.c\nnew file mode 100644\nindex 0000000..bdac054\n--- /dev/null\n+++ b/drivers/net/ark/ark_pktgen.c\n@@ -0,0 +1,496 @@\n+/*\n+ * BSD LICENSE\n+ *\n+ * Copyright (c) 2015-2017 Atomic Rules LLC\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions\n+ * are met:\n+ *\n+ * * Redistributions of source code must retain the above copyright\n+ * notice, this list of conditions and the following disclaimer.\n+ * * Redistributions in binary form must reproduce the above copyright\n+ * notice, this list of conditions and the following disclaimer in\n+ * the documentation and/or other materials provided with the\n+ * distribution.\n+ * * Neither the name of copyright holder nor the names of its\n+ * contributors may be used to endorse or promote products derived\n+ * from this software without specific prior written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <getopt.h>\n+#include <sys/time.h>\n+#include <locale.h>\n+#include <unistd.h>\n+\n+#include <rte_eal.h>\n+\n+#include <rte_ethdev.h>\n+#include <rte_malloc.h>\n+\n+#include \"ark_pktgen.h\"\n+#include \"ark_logs.h\"\n+\n+#define ARK_MAX_STR_LEN 64\n+union OPTV {\n+\tint INT;\n+\tint BOOL;\n+\tuint64_t LONG;\n+\tchar STR[ARK_MAX_STR_LEN];\n+};\n+\n+enum OPTYPE {\n+\tOTINT,\n+\tOTLONG,\n+\tOTBOOL,\n+\tOTSTRING\n+};\n+\n+struct OPTIONS {\n+\tchar opt[ARK_MAX_STR_LEN];\n+\tenum OPTYPE t;\n+\tunion OPTV v;\n+};\n+\n+static struct OPTIONS toptions[] = {\n+\t{{\"configure\"}, OTBOOL, {1} },\n+\t{{\"dg-mode\"}, OTBOOL, {1} },\n+\t{{\"run\"}, OTBOOL, {0} },\n+\t{{\"pause\"}, OTBOOL, {0} },\n+\t{{\"reset\"}, OTBOOL, {0} },\n+\t{{\"dump\"}, OTBOOL, {0} },\n+\t{{\"gen_forever\"}, OTBOOL, {0} },\n+\t{{\"en_slaved_start\"}, OTBOOL, {0} },\n+\t{{\"vary_length\"}, OTBOOL, {0} },\n+\t{{\"incr_payload\"}, OTBOOL, {0} },\n+\t{{\"incr_first_byte\"}, OTBOOL, {0} },\n+\t{{\"ins_seq_num\"}, OTBOOL, {0} },\n+\t{{\"ins_time_stamp\"}, OTBOOL, {1} },\n+\t{{\"ins_udp_hdr\"}, OTBOOL, {0} },\n+\t{{\"num_pkts\"}, OTLONG, .v.LONG = 100000000},\n+\t{{\"payload_byte\"}, OTINT, {0x55} },\n+\t{{\"pkt_spacing\"}, OTINT, {130} },\n+\t{{\"pkt_size_min\"}, OTINT, {2006} },\n+\t{{\"pkt_size_max\"}, OTINT, {1514} },\n+\t{{\"pkt_size_incr\"}, OTINT, {1} },\n+\t{{\"eth_type\"}, OTINT, {0x0800} },\n+\t{{\"src_mac_addr\"}, OTLONG, .v.LONG = 0xdC3cF6425060L},\n+\t{{\"dst_mac_addr\"}, OTLONG, .v.LONG = 0x112233445566L},\n+\t{{\"hdr_dW0\"}, OTINT, {0x0016e319} },\n+\t{{\"hdr_dW1\"}, OTINT, {0x27150004} },\n+\t{{\"hdr_dW2\"}, OTINT, {0x76967bda} },\n+\t{{\"hdr_dW3\"}, OTINT, {0x08004500} },\n+\t{{\"hdr_dW4\"}, OTINT, {0x005276ed} },\n+\t{{\"hdr_dW5\"}, OTINT, {0x40004006} },\n+\t{{\"hdr_dW6\"}, OTINT, {0x56cfc0a8} },\n+\t{{\"start_offset\"}, OTINT, {0} },\n+\t{{\"bytes_per_cycle\"}, OTINT, {10} },\n+\t{{\"shaping\"}, OTBOOL, {0} },\n+\t{{\"dst_ip\"}, OTSTRING, .v.STR = \"169.254.10.240\"},\n+\t{{\"dst_port\"}, OTINT, {65536} },\n+\t{{\"src_port\"}, OTINT, {65536} },\n+};\n+\n+ark_pkt_gen_t\n+ark_pktgen_init(void *adr, int ord, int l2_mode)\n+{\n+\tstruct ark_pkt_gen_inst *inst =\n+\t\trte_malloc(\"ark_pkt_gen_inst_pmd\",\n+\t\t\t   sizeof(struct ark_pkt_gen_inst), 0);\n+\tinst->regs = (struct ark_pkt_gen_regs *)adr;\n+\tinst->ordinal = ord;\n+\tinst->l2_mode = l2_mode;\n+\treturn inst;\n+}\n+\n+void\n+ark_pktgen_uninit(ark_pkt_gen_t handle)\n+{\n+\trte_free(handle);\n+}\n+\n+void\n+ark_pktgen_run(ark_pkt_gen_t handle)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\n+\tinst->regs->pkt_start_stop = 1;\n+}\n+\n+uint32_t\n+ark_pktgen_paused(ark_pkt_gen_t handle)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tuint32_t r = inst->regs->pkt_start_stop;\n+\n+\treturn (((r >> 16) & 1) == 1);\n+}\n+\n+void\n+ark_pktgen_pause(ark_pkt_gen_t handle)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tint cnt = 0;\n+\n+\tinst->regs->pkt_start_stop = 0;\n+\n+\twhile (!ark_pktgen_paused(handle)) {\n+\t\tusleep(1000);\n+\t\tif (cnt++ > 100) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Pktgen %d failed to pause.\\n\",\n+\t\t\t\t    inst->ordinal);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tPMD_DEBUG_LOG(DEBUG, \"Pktgen %d paused.\\n\", inst->ordinal);\n+}\n+\n+void\n+ark_pktgen_reset(ark_pkt_gen_t handle)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\n+\tif (!ark_pktgen_is_running(handle) &&\n+\t    !ark_pktgen_paused(handle)) {\n+\t\tPMD_DEBUG_LOG(DEBUG, \"Pktgen %d is not running\"\n+\t\t\t      \" and is not paused. No need to reset.\\n\",\n+\t\t\t      inst->ordinal);\n+\t\treturn;\n+\t}\n+\n+\tif (ark_pktgen_is_running(handle) &&\n+\t    !ark_pktgen_paused(handle)) {\n+\t\tPMD_DEBUG_LOG(DEBUG,\n+\t\t\t      \"Pktgen %d is not paused. Pausing first.\\n\",\n+\t\t\t      inst->ordinal);\n+\t\tark_pktgen_pause(handle);\n+\t}\n+\n+\tPMD_DEBUG_LOG(DEBUG, \"Resetting pktgen %d.\\n\", inst->ordinal);\n+\tinst->regs->pkt_start_stop = (1 << 8);\n+}\n+\n+uint32_t\n+ark_pktgen_tx_done(ark_pkt_gen_t handle)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tuint32_t r = inst->regs->pkt_start_stop;\n+\n+\treturn (((r >> 24) & 1) == 1);\n+}\n+\n+uint32_t\n+ark_pktgen_is_running(ark_pkt_gen_t handle)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tuint32_t r = inst->regs->pkt_start_stop;\n+\n+\treturn ((r & 1) == 1);\n+}\n+\n+uint32_t\n+ark_pktgen_is_gen_forever(ark_pkt_gen_t handle)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tuint32_t r = inst->regs->pkt_ctrl;\n+\n+\treturn (((r >> 24) & 1) == 1);\n+}\n+\n+void\n+ark_pktgen_wait_done(ark_pkt_gen_t handle)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tint wait_cycle = 10;\n+\n+\tif (ark_pktgen_is_gen_forever(handle))\n+\t\tPMD_DRV_LOG(ERR, \"Pktgen wait_done will not terminate\"\n+\t\t\t    \" because gen_forever=1\\n\");\n+\n+\twhile (!ark_pktgen_tx_done(handle) && (wait_cycle > 0)) {\n+\t\tusleep(1000);\n+\t\twait_cycle--;\n+\t\tPMD_DEBUG_LOG(DEBUG,\n+\t\t\t      \"Waiting for pktgen %d to finish sending...\\n\",\n+\t\t\t      inst->ordinal);\n+\t}\n+\tPMD_DEBUG_LOG(DEBUG, \"Pktgen %d done.\\n\", inst->ordinal);\n+}\n+\n+uint32_t\n+ark_pktgen_get_pkts_sent(ark_pkt_gen_t handle)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\treturn inst->regs->pkts_sent;\n+}\n+\n+void\n+ark_pktgen_set_payload_byte(ark_pkt_gen_t handle, uint32_t b)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tinst->regs->pkt_payload = b;\n+}\n+\n+void\n+ark_pktgen_set_pkt_spacing(ark_pkt_gen_t handle, uint32_t x)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tinst->regs->pkt_spacing = x;\n+}\n+\n+void\n+ark_pktgen_set_pkt_size_min(ark_pkt_gen_t handle, uint32_t x)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tinst->regs->pkt_size_min = x;\n+}\n+\n+void\n+ark_pktgen_set_pkt_size_max(ark_pkt_gen_t handle, uint32_t x)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tinst->regs->pkt_size_max = x;\n+}\n+\n+void\n+ark_pktgen_set_pkt_size_incr(ark_pkt_gen_t handle, uint32_t x)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tinst->regs->pkt_size_incr = x;\n+}\n+\n+void\n+ark_pktgen_set_num_pkts(ark_pkt_gen_t handle, uint32_t x)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tinst->regs->num_pkts = x;\n+}\n+\n+void\n+ark_pktgen_set_src_mac_addr(ark_pkt_gen_t handle, uint64_t mac_addr)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tinst->regs->src_mac_addr_h = (mac_addr >> 32) & 0xffff;\n+\tinst->regs->src_mac_addr_l = mac_addr & 0xffffffff;\n+}\n+\n+void\n+ark_pktgen_set_dst_mac_addr(ark_pkt_gen_t handle, uint64_t mac_addr)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tinst->regs->dst_mac_addr_h = (mac_addr >> 32) & 0xffff;\n+\tinst->regs->dst_mac_addr_l = mac_addr & 0xffffffff;\n+}\n+\n+void\n+ark_pktgen_set_eth_type(ark_pkt_gen_t handle, uint32_t x)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\tinst->regs->eth_type = x;\n+}\n+\n+void\n+ark_pktgen_set_hdr_dW(ark_pkt_gen_t handle, uint32_t *hdr)\n+{\n+\tuint32_t i;\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\n+\tfor (i = 0; i < 7; i++)\n+\t\tinst->regs->hdr_dw[i] = hdr[i];\n+}\n+\n+void\n+ark_pktgen_set_start_offset(ark_pkt_gen_t handle, uint32_t x)\n+{\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\n+\tinst->regs->start_offset = x;\n+}\n+\n+static struct OPTIONS *\n+options(const char *id)\n+{\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < sizeof(toptions) / sizeof(struct OPTIONS); i++) {\n+\t\tif (strcmp(id, toptions[i].opt) == 0)\n+\t\t\treturn &toptions[i];\n+\t}\n+\n+\tPMD_DRV_LOG(ERR,\n+\t\t    \"Pktgen: Could not find requested option!, \"\n+\t\t    \"option = %s\\n\",\n+\t\t    id\n+\t\t    );\n+\treturn NULL;\n+}\n+\n+static int pmd_set_arg(char *arg, char *val);\n+static int\n+pmd_set_arg(char *arg, char *val)\n+{\n+\tstruct OPTIONS *o = options(arg);\n+\n+\tif (o) {\n+\t\tswitch (o->t) {\n+\t\tcase OTINT:\n+\t\tcase OTBOOL:\n+\t\t\to->v.INT = atoi(val);\n+\t\t\tbreak;\n+\t\tcase OTLONG:\n+\t\t\to->v.INT = atoll(val);\n+\t\t\tbreak;\n+\t\tcase OTSTRING:\n+\t\t\tstrncpy(o->v.STR, val, ARK_MAX_STR_LEN);\n+\t\t\tbreak;\n+\t\t}\n+\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\n+\n+/******\n+ * Arg format = \"opt0=v,opt_n=v ...\"\n+ ******/\n+void\n+ark_pktgen_parse(char *args)\n+{\n+\tchar *argv, *v;\n+\tconst char toks[] = \" =\\n\\t\\v\\f \\r\";\n+\targv = strtok(args, toks);\n+\tv = strtok(NULL, toks);\n+\twhile (argv && v) {\n+\t\tpmd_set_arg(argv, v);\n+\t\targv = strtok(NULL, toks);\n+\t\tv = strtok(NULL, toks);\n+\t}\n+}\n+\n+static int32_t parse_ipv4_string(char const *ip_address);\n+static int32_t\n+parse_ipv4_string(char const *ip_address)\n+{\n+\tunsigned int ip[4];\n+\n+\tif (sscanf(ip_address, \"%u.%u.%u.%u\",\n+\t\t   &ip[0], &ip[1], &ip[2], &ip[3]) != 4)\n+\t\treturn 0;\n+\treturn ip[3] + ip[2] * 0x100 + ip[1] * 0x10000ul + ip[0] * 0x1000000ul;\n+}\n+\n+static void\n+ark_pktgen_set_pkt_ctrl(ark_pkt_gen_t handle,\n+\t\t\tuint32_t gen_forever,\n+\t\t\tuint32_t en_slaved_start,\n+\t\t\tuint32_t vary_length,\n+\t\t\tuint32_t incr_payload,\n+\t\t\tuint32_t incr_first_byte,\n+\t\t\tuint32_t ins_seq_num,\n+\t\t\tuint32_t ins_udp_hdr,\n+\t\t\tuint32_t ins_time_stamp)\n+{\n+\tuint32_t r;\n+\tstruct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)handle;\n+\n+\tif (!inst->l2_mode)\n+\t\tins_udp_hdr = 0;\n+\n+\tr = ((gen_forever << 24) |\n+\t     (en_slaved_start << 20) |\n+\t     (vary_length << 16) |\n+\t     (incr_payload << 12) |\n+\t     (incr_first_byte << 8) |\n+\t     (ins_time_stamp << 5) |\n+\t     (ins_seq_num << 4) |\n+\t     ins_udp_hdr);\n+\n+\tinst->regs->bytes_per_cycle = options(\"bytes_per_cycle\")->v.INT;\n+\tif (options(\"shaping\")->v.BOOL)\n+\t\tr = r | (1 << 28);\t/* enable shaping */\n+\n+\tinst->regs->pkt_ctrl = r;\n+}\n+\n+void\n+ark_pktgen_setup(ark_pkt_gen_t handle)\n+{\n+\tuint32_t hdr[7];\n+\tint32_t dst_ip = parse_ipv4_string(options(\"dst_ip\")->v.STR);\n+\n+\tif (!options(\"pause\")->v.BOOL &&\n+\t    (!options(\"reset\")->v.BOOL &&\n+\t     (options(\"configure\")->v.BOOL))) {\n+\t\tark_pktgen_set_payload_byte(handle,\n+\t\t\t\t\t    options(\"payload_byte\")->v.INT);\n+\t\tark_pktgen_set_src_mac_addr(handle,\n+\t\t\t\t\t    options(\"src_mac_addr\")->v.INT);\n+\t\tark_pktgen_set_dst_mac_addr(handle,\n+\t\t\t\t\t    options(\"dst_mac_addr\")->v.LONG);\n+\t\tark_pktgen_set_eth_type(handle,\n+\t\t\t\t\toptions(\"eth_type\")->v.INT);\n+\n+\t\tif (options(\"dg-mode\")->v.BOOL) {\n+\t\t\thdr[0] = options(\"hdr_dW0\")->v.INT;\n+\t\t\thdr[1] = options(\"hdr_dW1\")->v.INT;\n+\t\t\thdr[2] = options(\"hdr_dW2\")->v.INT;\n+\t\t\thdr[3] = options(\"hdr_dW3\")->v.INT;\n+\t\t\thdr[4] = options(\"hdr_dW4\")->v.INT;\n+\t\t\thdr[5] = options(\"hdr_dW5\")->v.INT;\n+\t\t\thdr[6] = options(\"hdr_dW6\")->v.INT;\n+\t\t} else {\n+\t\t\thdr[0] = dst_ip;\n+\t\t\thdr[1] = options(\"dst_port\")->v.INT;\n+\t\t\thdr[2] = options(\"src_port\")->v.INT;\n+\t\t\thdr[3] = 0;\n+\t\t\thdr[4] = 0;\n+\t\t\thdr[5] = 0;\n+\t\t\thdr[6] = 0;\n+\t\t}\n+\t\tark_pktgen_set_hdr_dW(handle, hdr);\n+\t\tark_pktgen_set_num_pkts(handle,\n+\t\t\t\t\toptions(\"num_pkts\")->v.INT);\n+\t\tark_pktgen_set_pkt_size_min(handle,\n+\t\t\t\t\t    options(\"pkt_size_min\")->v.INT);\n+\t\tark_pktgen_set_pkt_size_max(handle,\n+\t\t\t\t\t    options(\"pkt_size_max\")->v.INT);\n+\t\tark_pktgen_set_pkt_size_incr(handle,\n+\t\t\t\t\t     options(\"pkt_size_incr\")->v.INT);\n+\t\tark_pktgen_set_pkt_spacing(handle,\n+\t\t\t\t\t   options(\"pkt_spacing\")->v.INT);\n+\t\tark_pktgen_set_start_offset(handle,\n+\t\t\t\t\t    options(\"start_offset\")->v.INT);\n+\t\tark_pktgen_set_pkt_ctrl(handle,\n+\t\t\t\t\toptions(\"gen_forever\")->v.BOOL,\n+\t\t\t\t\toptions(\"en_slaved_start\")->v.BOOL,\n+\t\t\t\t\toptions(\"vary_length\")->v.BOOL,\n+\t\t\t\t\toptions(\"incr_payload\")->v.BOOL,\n+\t\t\t\t\toptions(\"incr_first_byte\")->v.BOOL,\n+\t\t\t\t\toptions(\"ins_seq_num\")->v.INT,\n+\t\t\t\t\toptions(\"ins_udp_hdr\")->v.BOOL,\n+\t\t\t\t\toptions(\"ins_time_stamp\")->v.INT);\n+\t}\n+\n+\tif (options(\"pause\")->v.BOOL)\n+\t\tark_pktgen_pause(handle);\n+\n+\tif (options(\"reset\")->v.BOOL)\n+\t\tark_pktgen_reset(handle);\n+\tif (options(\"run\")->v.BOOL) {\n+\t\tPMD_DEBUG_LOG(DEBUG, \"Starting packet generator on port %d\\n\",\n+\t\t\t\toptions(\"port\")->v.INT);\n+\t\tark_pktgen_run(handle);\n+\t}\n+}\ndiff --git a/drivers/net/ark/ark_pktgen.h b/drivers/net/ark/ark_pktgen.h\nnew file mode 100644\nindex 0000000..bf5a241\n--- /dev/null\n+++ b/drivers/net/ark/ark_pktgen.h\n@@ -0,0 +1,108 @@\n+/*-\n+ * BSD LICENSE\n+ *\n+ * Copyright (c) 2015-2017 Atomic Rules LLC\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions\n+ * are met:\n+ *\n+ * * Redistributions of source code must retain the above copyright\n+ * notice, this list of conditions and the following disclaimer.\n+ * * Redistributions in binary form must reproduce the above copyright\n+ * notice, this list of conditions and the following disclaimer in\n+ * the documentation and/or other materials provided with the\n+ * distribution.\n+ * * Neither the name of copyright holder nor the names of its\n+ * contributors may be used to endorse or promote products derived\n+ * from this software without specific prior written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef _ARK_PKTGEN_H_\n+#define _ARK_PKTGEN_H_\n+\n+#include <stdint.h>\n+#include <inttypes.h>\n+\n+#define ARK_PKTGEN_BASE_ADR  0x10000\n+\n+typedef void *ark_pkt_gen_t;\n+\n+/* The packet generator is an internal Arkville hardware module, which\n+ * generates known packets for use in integrity and line-rate testing.\n+ * This module is *not* intended for end-user manipulation, hence\n+ * there is minimal documentation.\n+ */\n+\n+/*\n+ * This is an overlay structure to a memory mapped FPGA device.  These\n+ * structs will never be instantiated in ram memory\n+ */\n+struct ark_pkt_gen_regs {\n+\tuint32_t r0;\n+\tvolatile uint32_t pkt_start_stop;\n+\tvolatile uint32_t pkt_ctrl;\n+\tuint32_t pkt_payload;\n+\tuint32_t pkt_spacing;\n+\tuint32_t pkt_size_min;\n+\tuint32_t pkt_size_max;\n+\tuint32_t pkt_size_incr;\n+\tvolatile uint32_t num_pkts;\n+\tvolatile uint32_t pkts_sent;\n+\tuint32_t src_mac_addr_l;\n+\tuint32_t src_mac_addr_h;\n+\tuint32_t dst_mac_addr_l;\n+\tuint32_t dst_mac_addr_h;\n+\tuint32_t eth_type;\n+\tuint32_t hdr_dw[7];\n+\tuint32_t start_offset;\n+\tuint32_t bytes_per_cycle;\n+} __attribute__ ((packed));\n+\n+struct ark_pkt_gen_inst {\n+\tstruct rte_eth_dev_info *dev_info;\n+\tstruct ark_pkt_gen_regs *regs;\n+\tint l2_mode;\n+\tint ordinal;\n+};\n+\n+/*  packet generator functions */\n+ark_pkt_gen_t ark_pktgen_init(void *arg, int ord, int l2_mode);\n+void ark_pktgen_uninit(ark_pkt_gen_t handle);\n+void ark_pktgen_run(ark_pkt_gen_t handle);\n+void ark_pktgen_pause(ark_pkt_gen_t handle);\n+uint32_t ark_pktgen_paused(ark_pkt_gen_t handle);\n+uint32_t ark_pktgen_is_gen_forever(ark_pkt_gen_t handle);\n+uint32_t ark_pktgen_is_running(ark_pkt_gen_t handle);\n+uint32_t ark_pktgen_tx_done(ark_pkt_gen_t handle);\n+void ark_pktgen_reset(ark_pkt_gen_t handle);\n+void ark_pktgen_wait_done(ark_pkt_gen_t handle);\n+uint32_t ark_pktgen_get_pkts_sent(ark_pkt_gen_t handle);\n+void ark_pktgen_set_payload_byte(ark_pkt_gen_t handle, uint32_t b);\n+void ark_pktgen_set_pkt_spacing(ark_pkt_gen_t handle, uint32_t x);\n+void ark_pktgen_set_pkt_size_min(ark_pkt_gen_t handle, uint32_t x);\n+void ark_pktgen_set_pkt_size_max(ark_pkt_gen_t handle, uint32_t x);\n+void ark_pktgen_set_pkt_size_incr(ark_pkt_gen_t handle, uint32_t x);\n+void ark_pktgen_set_num_pkts(ark_pkt_gen_t handle, uint32_t x);\n+void ark_pktgen_set_src_mac_addr(ark_pkt_gen_t handle, uint64_t mac_addr);\n+void ark_pktgen_set_dst_mac_addr(ark_pkt_gen_t handle, uint64_t mac_addr);\n+void ark_pktgen_set_eth_type(ark_pkt_gen_t handle, uint32_t x);\n+void ark_pktgen_set_hdr_dW(ark_pkt_gen_t handle, uint32_t *hdr);\n+void ark_pktgen_set_start_offset(ark_pkt_gen_t handle, uint32_t x);\n+void ark_pktgen_parse(char *argv);\n+void ark_pktgen_setup(ark_pkt_gen_t handle);\n+\n+#endif\n",
    "prefixes": [
        "dpdk-dev",
        "v8",
        "4/7"
    ]
}