get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 22110,
    "url": "http://patches.dpdk.org/api/patches/22110/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1490231015-31748-6-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": "<1490231015-31748-6-git-send-email-ed.czeck@atomicrules.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1490231015-31748-6-git-send-email-ed.czeck@atomicrules.com",
    "date": "2017-03-23T01:03:34",
    "name": "[dpdk-dev,v4,6/7] net/ark: Packet RX support initial version",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "23981d9aef34c4368312bc65c6197a8880dd60c4",
    "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/1490231015-31748-6-git-send-email-ed.czeck@atomicrules.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/22110/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/22110/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 849D1CFA4;\n\tThu, 23 Mar 2017 02:05:03 +0100 (CET)",
            "from mail-qt0-f195.google.com (mail-qt0-f195.google.com\n\t[209.85.216.195]) by dpdk.org (Postfix) with ESMTP id BCE913777\n\tfor <dev@dpdk.org>; Thu, 23 Mar 2017 02:04:05 +0100 (CET)",
            "by mail-qt0-f195.google.com with SMTP id x35so27510805qtc.1\n\tfor <dev@dpdk.org>; Wed, 22 Mar 2017 18:04: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\tu63sm2187363qkh.45.2017.03.22.18.04.03\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tWed, 22 Mar 2017 18:04:04 -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=qG1KPq/UrgDFI5s8HQHklQ9MpVDuCxdujv6pFuO3XB0=;\n\tb=1RBIjDYfl7smEZuwhF0zvtJQMTeETVzDPpPraAE6OTXDwE89PonsL5lxbvlVBhvzRC\n\tcOknPZa0pRgTgJ30rVBQQNpuCZntdkIZjQXFJisuazPRMLiagTlgZBsDiMSdPTPQlQpl\n\tBHQx0w4+OhcYWKvKuvZZ2LAShymR3ldxDDerqYp7mJ7gdbi8/yZUverVf/O+8mFQwIVZ\n\tGyZrzZrLcFtWjt5ZkdbMrYGH6VhEBLzTugFzjm5sun+stsfzA2ZPxIjGIeYhj7DE/roW\n\t5RmcaJrkkxER7yz4w6nmgkMSCRZkF6dMCScrQtSc1ZOPg3u3VNEiVHi+BYpMWrxtLuAO\n\tmdPA==",
        "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=qG1KPq/UrgDFI5s8HQHklQ9MpVDuCxdujv6pFuO3XB0=;\n\tb=VP3FF8ltkkLI685R4Tg6Kjvk7e9JXZLg4lCIBl9gf/MXeyl91ofa7atg7iaXhBZ1xj\n\tuI6VcRCKe8hBb1P2CARDyp3q8l9/qy3PtGsmHXIfCMYM61ik4T8BxOslsN8L92zlFHMr\n\tfSzzvcgOEf8MArsTAZ21kkJAukxHuJvUn24bHzrk6EP2lHS1XRtQK6w7kAcB8EsWhi7M\n\tKeunlPJqxt/oKSWk9jIEDG2GWXyQJtYmtl1Bfi8N/lN6U+86vK6jaXOV1dh5ukligjZa\n\tb3RUcX0hRQddiTa6vAHrXxd22d9OIOnERj+9e6hFXO0Ynurr0jgfLJ2AZSk9RhLivQDQ\n\tKdnA==",
        "X-Gm-Message-State": "AFeK/H3+aQXMBSSp0FVed5RZkWycg0xGngwB4LReD1fxRiUW7/JZp0ulObMFMVQQyuAkcg==",
        "X-Received": "by 10.200.4.171 with SMTP id s43mr42777718qtg.150.1490231044431; \n\tWed, 22 Mar 2017 18:04:04 -0700 (PDT)",
        "From": "Ed Czeck <ed.czeck@atomicrules.com>",
        "To": "dev@dpdk.org",
        "Cc": "Ed Czeck <ed.czeck@atomicrules.com>",
        "Date": "Wed, 22 Mar 2017 21:03:34 -0400",
        "Message-Id": "<1490231015-31748-6-git-send-email-ed.czeck@atomicrules.com>",
        "X-Mailer": "git-send-email 1.9.1",
        "In-Reply-To": "<1490231015-31748-1-git-send-email-ed.czeck@atomicrules.com>",
        "References": "<1490231015-31748-1-git-send-email-ed.czeck@atomicrules.com>",
        "Subject": "[dpdk-dev] [PATCH v4 6/7] net/ark: Packet RX support initial version",
        "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": "* Core RX packet moving functions\n\nSigned-off-by: Ed Czeck <ed.czeck@atomicrules.com>\n---\n drivers/net/ark/Makefile        |   1 +\n drivers/net/ark/ark_ethdev_rx.c | 681 ++++++++++++++++++++++++++++++++++++++++\n drivers/net/ark/ark_ethdev_rx.h |  67 ++++\n 3 files changed, 749 insertions(+)\n create mode 100644 drivers/net/ark/ark_ethdev_rx.c\n create mode 100644 drivers/net/ark/ark_ethdev_rx.h",
    "diff": "diff --git a/drivers/net/ark/Makefile b/drivers/net/ark/Makefile\nindex a79584e..e6490b6 100644\n--- a/drivers/net/ark/Makefile\n+++ b/drivers/net/ark/Makefile\n@@ -47,6 +47,7 @@ LIBABIVER := 1\n # all source are stored in SRCS-y\n #\n SRCS-y += ark_ethdev.c\n+SRCS-y += ark_ethdev_rx.c\n SRCS-y += ark_ethdev_tx.c\n SRCS-y += ark_pktgen.c\n SRCS-y += ark_pktchkr.c\ndiff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c\nnew file mode 100644\nindex 0000000..106bf7e\n--- /dev/null\n+++ b/drivers/net/ark/ark_ethdev_rx.c\n@@ -0,0 +1,681 @@\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 <unistd.h>\n+\n+#include \"ark_ethdev_rx.h\"\n+#include \"ark_global.h\"\n+#include \"ark_debug.h\"\n+#include \"ark_ethdev.h\"\n+#include \"ark_mpu.h\"\n+#include \"ark_udm.h\"\n+\n+#define ARK_RX_META_SIZE 32\n+#define ARK_RX_META_OFFSET (RTE_PKTMBUF_HEADROOM - ARK_RX_META_SIZE)\n+#define ARK_RX_MAX_NOCHAIN (RTE_MBUF_DEFAULT_DATAROOM)\n+\n+#ifdef RTE_LIBRTE_ARK_DEBUG_RX\n+#define ARK_RX_DEBUG 1\n+#define ARK_FULL_DEBUG 1\n+#else\n+#define ARK_RX_DEBUG 0\n+#define ARK_FULL_DEBUG 0\n+#endif\n+\n+/* Forward declarations */\n+struct ark_rx_queue;\n+struct ark_rx_meta;\n+\n+static void dump_mbuf_data(struct rte_mbuf *mbuf, uint16_t lo, uint16_t hi);\n+static void ark_ethdev_rx_dump(const char *name, struct ark_rx_queue *queue);\n+static uint32_t eth_ark_rx_jumbo(struct ark_rx_queue *queue,\n+\t\t\t\t struct ark_rx_meta *meta,\n+\t\t\t\t struct rte_mbuf *mbuf0,\n+\t\t\t\t uint32_t cons_index);\n+static inline int eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue);\n+\n+/* ************************************************************************* */\n+struct ark_rx_queue {\n+\t/* array of mbufs to populate */\n+\tstruct rte_mbuf **reserve_q;\n+\t/* array of physical addrresses of the mbuf data pointer */\n+\t/* This point is a virtual address */\n+\tphys_addr_t *paddress_q;\n+\tstruct rte_mempool *mb_pool;\n+\n+\tstruct ark_udm_t *udm;\n+\tstruct ark_mpu_t *mpu;\n+\n+\tuint32_t queue_size;\n+\tuint32_t queue_mask;\n+\n+\tuint32_t seed_index;\t\t/* 1 set with an empty mbuf */\n+\tuint32_t cons_index;\t\t/* 3 consumed by the driver */\n+\n+\t/* The queue Id is used to identify the HW Q */\n+\tuint16_t phys_qid;\n+\n+\t/* The queue Index is used within the dpdk device structures */\n+\tuint16_t queue_index;\n+\n+\tuint32_t pad1;\n+\n+\t/* separate cache line */\n+\t/* second cache line - fields only used in slow path */\n+\tMARKER cacheline1 __rte_cache_min_aligned;\n+\n+\tvolatile uint32_t prod_index;\t/* 2 filled by the HW */\n+} __rte_cache_aligned;\n+\n+/* ************************************************************************* */\n+\n+/* MATCHES struct in UDMDefines.bsv */\n+\n+/* ************************************************************************* */\n+\n+/* TODO  pick a better function name */\n+static int\n+eth_ark_rx_hw_setup(struct rte_eth_dev *dev,\n+\t\t    struct ark_rx_queue *queue,\n+\t\t    uint16_t rx_queue_id __rte_unused, uint16_t rx_queue_idx)\n+{\n+\tphys_addr_t queue_base;\n+\tphys_addr_t phys_addr_q_base;\n+\tphys_addr_t phys_addr_prod_index;\n+\n+\tqueue_base = rte_malloc_virt2phy(queue);\n+\tphys_addr_prod_index = queue_base +\n+\t\toffsetof(struct ark_rx_queue, prod_index);\n+\n+\tphys_addr_q_base = rte_malloc_virt2phy(queue->paddress_q);\n+\n+\t/* Verify HW */\n+\tif (ark_mpu_verify(queue->mpu, sizeof(phys_addr_t))) {\n+\t\tPMD_DRV_LOG(ERR, \"ARKP: Illegal configuration rx queue\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\t/* Stop and Reset and configure MPU */\n+\tark_mpu_configure(queue->mpu, phys_addr_q_base, queue->queue_size, 0);\n+\n+\tark_udm_write_addr(queue->udm, phys_addr_prod_index);\n+\n+\t/* advance the valid pointer, but don't start until the queue starts */\n+\tark_mpu_reset_stats(queue->mpu);\n+\n+\t/* The seed is the producer index for the HW */\n+\tark_mpu_set_producer(queue->mpu, queue->seed_index);\n+\tdev->data->rx_queue_state[rx_queue_idx] = RTE_ETH_QUEUE_STATE_STOPPED;\n+\n+\treturn 0;\n+}\n+\n+static inline void\n+eth_ark_rx_update_cons_index(struct ark_rx_queue *queue, uint32_t cons_index)\n+{\n+\tqueue->cons_index = cons_index;\n+\teth_ark_rx_seed_mbufs(queue);\n+\tark_mpu_set_producer(queue->mpu, queue->seed_index);\n+}\n+\n+/* ************************************************************************* */\n+int\n+eth_ark_dev_rx_queue_setup(struct rte_eth_dev *dev,\n+\t\t\t   uint16_t queue_idx,\n+\t\t\t   uint16_t nb_desc,\n+\t\t\t   unsigned int socket_id,\n+\t\t\t   const struct rte_eth_rxconf *rx_conf,\n+\t\t\t   struct rte_mempool *mb_pool)\n+{\n+\tstruct ark_adapter *ark = (struct ark_adapter *)dev->data->dev_private;\n+\tstatic int warning1;\t\t/* = 0 */\n+\n+\tstruct ark_rx_queue *queue;\n+\tuint32_t i;\n+\tint status;\n+\n+\tint port = ark_get_port_id(dev, ark);\n+\tint qidx = port + queue_idx;\t/* TODO FIXME */\n+\n+\t// TODO: We may already be setup, check here if there is nothing to do\n+\t/* Free memory prior to re-allocation if needed */\n+\tif (dev->data->rx_queues[queue_idx] != NULL) {\n+\t\t// TODO: release any allocated queues\n+\t\tdev->data->rx_queues[queue_idx] = NULL;\n+\t}\n+\n+\tif (rx_conf != NULL && warning1 == 0) {\n+\t\twarning1 = 1;\n+\t\tPMD_DRV_LOG(INFO,\n+\t\t\t    \"ARKP: Arkville PMD ignores  rte_eth_rxconf argument.\\n\");\n+\t}\n+\n+\tif (RTE_PKTMBUF_HEADROOM < ARK_RX_META_SIZE) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Error: DPDK Arkville requires head room > %d bytes (%s)\\n\",\n+\t\t\t    ARK_RX_META_SIZE, __func__);\n+\t\treturn -1;\t\t/* ERROR CODE */\n+\t}\n+\n+\tif (!rte_is_power_of_2(nb_desc)) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"DPDK Arkville configuration queue size must be power of two %u (%s)\\n\",\n+\t\t\t    nb_desc, __func__);\n+\t\treturn -1;\t\t/* ERROR CODE */\n+\t}\n+\n+\t/* Allocate queue struct */\n+\tqueue = rte_zmalloc_socket(\"Ark_rXQueue\",\n+\t\t\t\t   sizeof(struct ark_rx_queue),\n+\t\t\t\t   64,\n+\t\t\t\t   socket_id);\n+\tif (queue == 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to allocate memory in %s\\n\", __func__);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\t/* NOTE zmalloc is used, no need to 0 indexes, etc. */\n+\tqueue->mb_pool = mb_pool;\n+\tqueue->phys_qid = qidx;\n+\tqueue->queue_index = queue_idx;\n+\tqueue->queue_size = nb_desc;\n+\tqueue->queue_mask = nb_desc - 1;\n+\n+\tqueue->reserve_q =\n+\t\trte_zmalloc_socket(\"Ark_rx_queue mbuf\",\n+\t\t\t\t   nb_desc * sizeof(struct rte_mbuf *),\n+\t\t\t\t   64,\n+\t\t\t\t   socket_id);\n+\tqueue->paddress_q =\n+\t\trte_zmalloc_socket(\"Ark_rx_queue paddr\",\n+\t\t\t\t   nb_desc * sizeof(phys_addr_t),\n+\t\t\t\t   64,\n+\t\t\t\t   socket_id);\n+\n+\tif (queue->reserve_q == 0 || queue->paddress_q == 0) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Failed to allocate queue memory in %s\\n\",\n+\t\t\t    __func__);\n+\t\trte_free(queue->reserve_q);\n+\t\trte_free(queue->paddress_q);\n+\t\trte_free(queue);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tdev->data->rx_queues[queue_idx] = queue;\n+\tqueue->udm = RTE_PTR_ADD(ark->udm.v, qidx * ARK_UDM_QOFFSET);\n+\tqueue->mpu = RTE_PTR_ADD(ark->mpurx.v, qidx * ARK_MPU_QOFFSET);\n+\n+\t/* populate mbuf reserve */\n+\tstatus = eth_ark_rx_seed_mbufs(queue);\n+\n+\t/* MPU Setup */\n+\tif (status == 0)\n+\t\tstatus = eth_ark_rx_hw_setup(dev, queue, qidx, queue_idx);\n+\n+\tif (unlikely(status != 0)) {\n+\t\tstruct rte_mbuf *mbuf;\n+\n+\t\tPMD_DRV_LOG(ERR, \"ARKP Failed to initialize RX queue %d %s\\n\",\n+\t\t\t    qidx,\n+\t\t\t    __func__);\n+\t\t/* Free the mbufs allocated */\n+\t\tfor (i = 0, mbuf = queue->reserve_q[0];\n+\t\t     i < nb_desc; ++i, mbuf++) {\n+\t\t\trte_pktmbuf_free(mbuf);\n+\t\t}\n+\t\trte_free(queue->reserve_q);\n+\t\trte_free(queue->paddress_q);\n+\t\trte_free(queue);\n+\t\treturn -1;\t\t/* ERROR CODE */\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* ************************************************************************* */\n+uint16_t\n+eth_ark_recv_pkts_noop(void *rx_queue __rte_unused,\n+\t\t       struct rte_mbuf **rx_pkts __rte_unused,\n+\t\t       uint16_t nb_pkts __rte_unused)\n+{\n+\treturn 0;\n+}\n+\n+/* ************************************************************************* */\n+uint16_t\n+eth_ark_recv_pkts(void *rx_queue,\n+\t\t  struct rte_mbuf **rx_pkts,\n+\t\t  uint16_t nb_pkts)\n+{\n+\tstruct ark_rx_queue *queue;\n+\tregister uint32_t cons_index, prod_index;\n+\tuint16_t nb;\n+\tstruct rte_mbuf *mbuf;\n+\tstruct ark_rx_meta *meta;\n+\n+\tqueue = (struct ark_rx_queue *)rx_queue;\n+\tif (unlikely(queue == 0))\n+\t\treturn 0;\n+\tif (unlikely(nb_pkts == 0))\n+\t\treturn 0;\n+\tprod_index = queue->prod_index;\n+\tcons_index = queue->cons_index;\n+\tnb = 0;\n+\n+\twhile (prod_index != cons_index) {\n+\t\tmbuf = queue->reserve_q[cons_index & queue->queue_mask];\n+\t\t/* prefetch mbuf ? */\n+\t\trte_mbuf_prefetch_part1(mbuf);\n+\t\trte_mbuf_prefetch_part2(mbuf);\n+\n+\t\t/* META DATA burried in buffer */\n+\t\tmeta = RTE_PTR_ADD(mbuf->buf_addr, ARK_RX_META_OFFSET);\n+\n+\t\tmbuf->port = meta->port;\n+\t\tmbuf->pkt_len = meta->pkt_len;\n+\t\tmbuf->data_len = meta->pkt_len;\n+\t\tmbuf->data_off = RTE_PKTMBUF_HEADROOM;\n+\t\tmbuf->udata64 = meta->user_data;\n+\t\tif (ARK_RX_DEBUG) {\t/* debug use */\n+\t\t\tif ((meta->pkt_len > (1024 * 16)) ||\n+\t\t\t    (meta->pkt_len == 0)) {\n+\t\t\t\tPMD_DRV_LOG(INFO,\n+\t\t\t\t\t    \"ARKP RX: Bad Meta Q: %u\"\n+\t\t\t\t\t    \" cons: %u prod: %u\\n\",\n+\t\t\t\t\t    queue->phys_qid,\n+\t\t\t\t\t    cons_index,\n+\t\t\t\t\t    queue->prod_index);\n+\n+\t\t\t\tPMD_DRV_LOG(INFO,\n+\t\t\t\t\t    \"       :  cons: %u prod: %u\"\n+\t\t\t\t\t    \" seed_index %u\\n\",\n+\t\t\t\t\t    cons_index,\n+\t\t\t\t\t    queue->prod_index,\n+\t\t\t\t\t    queue->seed_index);\n+\n+\t\t\t\tPMD_DRV_LOG(INFO, \"       :  UDM prod: %u\"\n+\t\t\t\t\t    \"  len: %u\\n\",\n+\t\t\t\t\t    queue->udm->rt_cfg.prod_idx,\n+\t\t\t\t\t    meta->pkt_len);\n+\t\t\t\tark_mpu_dump(queue->mpu,\n+\t\t\t\t\t     \"    \",\n+\t\t\t\t\t     queue->phys_qid);\n+\n+\t\t\t\tdump_mbuf_data(mbuf, 0, 256);\n+\t\t\t\t/* its FUBAR so fix it */\n+\t\t\t\tmbuf->pkt_len = 63;\n+\t\t\t\tmeta->pkt_len = 63;\n+\t\t\t}\n+\t\t\tmbuf->seqn = cons_index;\n+\t\t}\n+\n+\t\tif (unlikely(meta->pkt_len > ARK_RX_MAX_NOCHAIN))\n+\t\t\tcons_index = eth_ark_rx_jumbo\n+\t\t\t\t(queue, meta, mbuf, cons_index + 1);\n+\t\telse\n+\t\t\tcons_index += 1;\n+\n+\t\trx_pkts[nb] = mbuf;\n+\t\tnb++;\n+\t\tif (nb >= nb_pkts)\n+\t\t\tbreak;\n+\t}\n+\n+\tif (unlikely(nb != 0))\n+\t\t/* report next free to FPGA */\n+\t\teth_ark_rx_update_cons_index(queue, cons_index);\n+\n+\treturn nb;\n+}\n+\n+/* ************************************************************************* */\n+static uint32_t\n+eth_ark_rx_jumbo(struct ark_rx_queue *queue,\n+\t\t struct ark_rx_meta *meta,\n+\t\t struct rte_mbuf *mbuf0,\n+\t\t uint32_t cons_index)\n+{\n+\tstruct rte_mbuf *mbuf_prev;\n+\tstruct rte_mbuf *mbuf;\n+\n+\tuint16_t remaining;\n+\tuint16_t data_len;\n+\tuint8_t segments;\n+\n+\t/* first buf populated by called */\n+\tmbuf_prev = mbuf0;\n+\tsegments = 1;\n+\tdata_len = RTE_MIN(meta->pkt_len, RTE_MBUF_DEFAULT_DATAROOM);\n+\tremaining = meta->pkt_len - data_len;\n+\tmbuf0->data_len = data_len;\n+\n+\t/* TODO check that the data does not exceed prod_index! */\n+\twhile (remaining != 0) {\n+\t\tdata_len = RTE_MIN(remaining,\n+\t\t\t\t   RTE_MBUF_DEFAULT_DATAROOM +\n+\t\t\t\t   RTE_PKTMBUF_HEADROOM);\n+\n+\t\tremaining -= data_len;\n+\t\tsegments += 1;\n+\n+\t\tmbuf = queue->reserve_q[cons_index & queue->queue_mask];\n+\t\tmbuf_prev->next = mbuf;\n+\t\tmbuf_prev = mbuf;\n+\t\tmbuf->data_len = data_len;\n+\t\tmbuf->data_off = 0;\n+\t\tif (ARK_RX_DEBUG)\n+\t\t\tmbuf->seqn = cons_index;\t/* for debug only */\n+\n+\t\tcons_index += 1;\n+\t}\n+\n+\tmbuf0->nb_segs = segments;\n+\treturn cons_index;\n+}\n+\n+/* Drain the internal queue allowing hw to clear out. */\n+static void\n+eth_ark_rx_queue_drain(struct ark_rx_queue *queue)\n+{\n+\tregister uint32_t cons_index;\n+\tstruct rte_mbuf *mbuf;\n+\n+\tcons_index = queue->cons_index;\n+\n+\t/* NOT performance optimized, since this is a one-shot call */\n+\twhile ((cons_index ^ queue->prod_index) & queue->queue_mask) {\n+\t\tmbuf = queue->reserve_q[cons_index & queue->queue_mask];\n+\t\trte_pktmbuf_free(mbuf);\n+\t\tcons_index++;\n+\t\teth_ark_rx_update_cons_index(queue, cons_index);\n+\t}\n+}\n+\n+uint32_t\n+eth_ark_dev_rx_queue_count(struct rte_eth_dev *dev, uint16_t queue_id)\n+{\n+\tstruct ark_rx_queue *queue;\n+\n+\tqueue = dev->data->rx_queues[queue_id];\n+\treturn (queue->prod_index - queue->cons_index);\t/* mod arith */\n+}\n+\n+/* ************************************************************************* */\n+int\n+eth_ark_rx_start_queue(struct rte_eth_dev *dev, uint16_t queue_id)\n+{\n+\tstruct ark_rx_queue *queue;\n+\n+\tqueue = dev->data->rx_queues[queue_id];\n+\tif (queue == 0)\n+\t\treturn -1;\n+\n+\tdev->data->rx_queue_state[queue_id] = RTE_ETH_QUEUE_STATE_STARTED;\n+\n+\tark_mpu_set_producer(queue->mpu, queue->seed_index);\n+\tark_mpu_start(queue->mpu);\n+\n+\tark_udm_queue_enable(queue->udm, 1);\n+\n+\treturn 0;\n+}\n+\n+/* ************************************************************************* */\n+\n+/* Queue can be restarted.   data remains\n+ */\n+int\n+eth_ark_rx_stop_queue(struct rte_eth_dev *dev, uint16_t queue_id)\n+{\n+\tstruct ark_rx_queue *queue;\n+\n+\tqueue = dev->data->rx_queues[queue_id];\n+\tif (queue == 0)\n+\t\treturn -1;\n+\n+\tark_udm_queue_enable(queue->udm, 0);\n+\n+\tdev->data->rx_queue_state[queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;\n+\n+\treturn 0;\n+}\n+\n+/* ************************************************************************* */\n+static inline int\n+eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)\n+{\n+\tuint32_t limit = queue->cons_index + queue->queue_size;\n+\tuint32_t seed_index = queue->seed_index;\n+\n+\tuint32_t count = 0;\n+\tuint32_t seed_m = queue->seed_index & queue->queue_mask;\n+\n+\tuint32_t nb = limit - seed_index;\n+\n+\t/* Handle wrap around -- remainder is filled on the next call */\n+\tif (unlikely(seed_m + nb > queue->queue_size))\n+\t\tnb = queue->queue_size - seed_m;\n+\n+\tstruct rte_mbuf **mbufs = &queue->reserve_q[seed_m];\n+\tint status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, nb);\n+\n+\tif (unlikely(status != 0))\n+\t\treturn -1;\n+\n+\tif (ARK_RX_DEBUG) {\t\t/* DEBUG */\n+\t\twhile (count != nb) {\n+\t\t\tstruct rte_mbuf *mbuf_init =\n+\t\t\t\tqueue->reserve_q[seed_m + count];\n+\n+\t\t\tmemset(mbuf_init->buf_addr, -1, 512);\n+\t\t\t*((uint32_t *)mbuf_init->buf_addr) =\n+\t\t\t\tseed_index + count;\n+\t\t\t*(uint16_t *)RTE_PTR_ADD(mbuf_init->buf_addr, 4) =\n+\t\t\t\tqueue->phys_qid;\n+\t\t\tcount++;\n+\t\t}\n+\t\tcount = 0;\n+\t} /* DEBUG */\n+\tqueue->seed_index += nb;\n+\n+\t/* Duff's device https://en.wikipedia.org/wiki/Duff's_device */\n+\tswitch (nb % 4) {\n+\tcase 0:\n+\t\twhile (count != nb) {\n+\t\t\tqueue->paddress_q[seed_m++] =\n+\t\t\t\t(*mbufs++)->buf_physaddr;\n+\t\t\tcount++;\n+\t\t/* FALLTHROUGH */\n+\tcase 3:\n+\t\tqueue->paddress_q[seed_m++] =\n+\t\t\t(*mbufs++)->buf_physaddr;\n+\t\tcount++;\n+\t\t/* FALLTHROUGH */\n+\tcase 2:\n+\t\tqueue->paddress_q[seed_m++] =\n+\t\t\t(*mbufs++)->buf_physaddr;\n+\t\tcount++;\n+\t\t/* FALLTHROUGH */\n+\tcase 1:\n+\t\tqueue->paddress_q[seed_m++] =\n+\t\t\t(*mbufs++)->buf_physaddr;\n+\t\tcount++;\n+\t\t/* FALLTHROUGH */\n+\n+\t\t} /* while (count != nb) */\n+\t} /* switch */\n+\n+\treturn 0;\n+}\n+\n+void\n+eth_ark_rx_dump_queue(struct rte_eth_dev *dev, uint16_t queue_id,\n+\t\t      const char *msg)\n+{\n+\tstruct ark_rx_queue *queue;\n+\n+\tqueue = dev->data->rx_queues[queue_id];\n+\n+\tark_ethdev_rx_dump(msg, queue);\n+}\n+\n+/* ************************************************************************* */\n+/* Call on device closed no user API, queue is stopped */\n+void\n+eth_ark_dev_rx_queue_release(void *vqueue)\n+{\n+\tstruct ark_rx_queue *queue;\n+\tuint32_t i;\n+\n+\tqueue = (struct ark_rx_queue *)vqueue;\n+\tif (queue == 0)\n+\t\treturn;\n+\n+\tark_udm_queue_enable(queue->udm, 0);\n+\t/* Stop the MPU since pointer are going away */\n+\tark_mpu_stop(queue->mpu);\n+\n+\t/* Need to clear out mbufs here, dropping packets along the way */\n+\teth_ark_rx_queue_drain(queue);\n+\n+\tfor (i = 0; i < queue->queue_size; ++i)\n+\t\trte_pktmbuf_free(queue->reserve_q[i]);\n+\n+\trte_free(queue->reserve_q);\n+\trte_free(queue->paddress_q);\n+\trte_free(queue);\n+}\n+\n+void\n+eth_rx_queue_stats_get(void *vqueue, struct rte_eth_stats *stats)\n+{\n+\tstruct ark_rx_queue *queue;\n+\tstruct ark_udm_t *udm;\n+\n+\tqueue = vqueue;\n+\tif (queue == 0)\n+\t\treturn;\n+\tudm = queue->udm;\n+\n+\tuint64_t ibytes = ark_udm_bytes(udm);\n+\tuint64_t ipackets = ark_udm_packets(udm);\n+\tuint64_t idropped = ark_udm_dropped(queue->udm);\n+\n+\tstats->q_ipackets[queue->queue_index] = ipackets;\n+\tstats->q_ibytes[queue->queue_index] = ibytes;\n+\tstats->q_errors[queue->queue_index] = idropped;\n+\tstats->ipackets += ipackets;\n+\tstats->ibytes += ibytes;\n+\tstats->imissed += idropped;\n+}\n+\n+void\n+eth_rx_queue_stats_reset(void *vqueue)\n+{\n+\tstruct ark_rx_queue *queue;\n+\n+\tqueue = vqueue;\n+\tif (queue == 0)\n+\t\treturn;\n+\n+\tark_mpu_reset_stats(queue->mpu);\n+\tark_udm_queue_stats_reset(queue->udm);\n+}\n+\n+void\n+eth_ark_udm_force_close(struct rte_eth_dev *dev)\n+{\n+\tstruct ark_adapter *ark = (struct ark_adapter *)dev->data->dev_private;\n+\tstruct ark_rx_queue *queue;\n+\tuint32_t index;\n+\tuint16_t i;\n+\n+\tif (!ark_udm_is_flushed(ark->udm.v)) {\n+\t\t/* restart the MPUs */\n+\t\tPMD_DRV_LOG(ERR, \"ARK: %s UDM not flushed\\n\", __func__);\n+\t\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\t\tqueue = (struct ark_rx_queue *)dev->data->rx_queues[i];\n+\t\t\tif (queue == 0)\n+\t\t\t\tcontinue;\n+\n+\t\t\tark_mpu_start(queue->mpu);\n+\t\t\t/* Add some buffers */\n+\t\t\tindex = 100000 + queue->seed_index;\n+\t\t\tark_mpu_set_producer(queue->mpu, index);\n+\t\t}\n+\t\t/* Wait to allow data to pass */\n+\t\tusleep(100);\n+\n+\t\tARK_DEBUG_TRACE(\"UDM forced flush attempt, stopped = %d\\n\",\n+\t\t\t\tark_udm_is_flushed(ark->udm.v));\n+\t}\n+\tark_udm_reset(ark->udm.v);\n+}\n+\n+static void\n+ark_ethdev_rx_dump(const char *name, struct ark_rx_queue *queue)\n+{\n+\tif (queue == NULL)\n+\t\treturn;\n+\tARK_DEBUG_TRACE(\"RX QUEUE %d -- %s\", queue->phys_qid, name);\n+\tARK_DEBUG_TRACE(ARK_SU32 ARK_SU32 ARK_SU32 ARK_SU32 \"\\n\",\n+\t\t\t\"queue_size\", queue->queue_size,\n+\t\t\t\"seed_index\", queue->seed_index,\n+\t\t\t\"prod_index\", queue->prod_index,\n+\t\t\t\"cons_index\", queue->cons_index);\n+\n+\tark_mpu_dump(queue->mpu, name, queue->phys_qid);\n+\tark_mpu_dump_setup(queue->mpu, queue->phys_qid);\n+\tark_udm_dump(queue->udm, name);\n+\tark_udm_dump_setup(queue->udm, queue->phys_qid);\n+}\n+\n+/* Only used in debug */\n+static void\n+dump_mbuf_data(struct rte_mbuf *mbuf, uint16_t lo, uint16_t hi)\n+{\n+\tuint16_t i, j;\n+\n+\tPMD_DRV_LOG(ERR, \" MBUF: %p len %d, off: %d, seq: %u\\n\", mbuf,\n+\t\tmbuf->pkt_len, mbuf->data_off, mbuf->seqn);\n+\tfor (i = lo; i < hi; i += 16) {\n+\t\tuint8_t *dp = RTE_PTR_ADD(mbuf->buf_addr, i);\n+\n+\t\tPMD_DRV_LOG(ERR, \"  %6d:  \", i);\n+\t\tfor (j = 0; j < 16; j++)\n+\t\t\tPMD_DRV_LOG(ERR, \" %02x\", dp[j]);\n+\n+\t\tPMD_DRV_LOG(ERR, \"\\n\");\n+\t}\n+}\ndiff --git a/drivers/net/ark/ark_ethdev_rx.h b/drivers/net/ark/ark_ethdev_rx.h\nnew file mode 100644\nindex 0000000..e6c9fa2\n--- /dev/null\n+++ b/drivers/net/ark/ark_ethdev_rx.h\n@@ -0,0 +1,67 @@\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_ETHDEV_RX_H_\n+#define _ARK_ETHDEV_RX_H_\n+\n+#include <stdint.h>\n+\n+/* Forward declarations */\n+struct rte_mbuf;\n+struct rte_mempool;\n+struct rte_eth_dev;\n+struct rte_eth_stats;\n+struct rte_eth_rxconf;\n+\n+int eth_ark_dev_rx_queue_setup(struct rte_eth_dev *dev,\n+\t\t\t       uint16_t queue_idx,\n+\t\t\t       uint16_t nb_desc,\n+\t\t\t       unsigned int socket_id,\n+\t\t\t       const struct rte_eth_rxconf *rx_conf,\n+\t\t\t       struct rte_mempool *mp);\n+uint32_t eth_ark_dev_rx_queue_count(struct rte_eth_dev *dev,\n+\t\t\t\t    uint16_t rx_queue_id);\n+int eth_ark_rx_stop_queue(struct rte_eth_dev *dev, uint16_t queue_id);\n+int eth_ark_rx_start_queue(struct rte_eth_dev *dev, uint16_t queue_id);\n+uint16_t eth_ark_recv_pkts_noop(void *rx_queue, struct rte_mbuf **rx_pkts,\n+\t\t\t\tuint16_t nb_pkts);\n+uint16_t eth_ark_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,\n+\t\t\t   uint16_t nb_pkts);\n+void eth_ark_dev_rx_queue_release(void *rx_queue);\n+void eth_rx_queue_stats_get(void *vqueue, struct rte_eth_stats *stats);\n+void eth_rx_queue_stats_reset(void *vqueue);\n+void eth_ark_rx_dump_queue(struct rte_eth_dev *dev, uint16_t queue_id,\n+\t\t\t   const char *msg);\n+void eth_ark_udm_force_close(struct rte_eth_dev *dev);\n+\n+#endif\n",
    "prefixes": [
        "dpdk-dev",
        "v4",
        "6/7"
    ]
}