get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 17133,
    "url": "http://patches.dpdk.org/api/patches/17133/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1479740470-6723-39-git-send-email-arybchenko@solarflare.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": "<1479740470-6723-39-git-send-email-arybchenko@solarflare.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1479740470-6723-39-git-send-email-arybchenko@solarflare.com",
    "date": "2016-11-21T15:00:52",
    "name": "[dpdk-dev,38/56] net/sfc: implement event queue support",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "6ea679c446fdf94bd6be69de527e5a8f70d4b7c3",
    "submitter": {
        "id": 607,
        "url": "http://patches.dpdk.org/api/people/607/?format=api",
        "name": "Andrew Rybchenko",
        "email": "arybchenko@solarflare.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/1479740470-6723-39-git-send-email-arybchenko@solarflare.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/17133/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/17133/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 5BAA2D57E;\n\tMon, 21 Nov 2016 16:03:21 +0100 (CET)",
            "from nbfkord-smmo02.seg.att.com (nbfkord-smmo02.seg.att.com\n\t[209.65.160.78]) by dpdk.org (Postfix) with ESMTP id 154D6532C\n\tfor <dev@dpdk.org>; Mon, 21 Nov 2016 16:01:36 +0100 (CET)",
            "from unknown [12.187.104.26]\n\tby nbfkord-smmo02.seg.att.com(mxl_mta-7.2.4-7) with SMTP id\n\t05c03385.0.1541294.00-2325.3424223.nbfkord-smmo02.seg.att.com\n\t(envelope-from <arybchenko@solarflare.com>); \n\tMon, 21 Nov 2016 15:01:37 +0000 (UTC)",
            "from ocex03.SolarFlarecom.com (10.20.40.36) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id 15.0.1044.25; Mon, 21 Nov 2016 07:01:22 -0800",
            "from opal.uk.solarflarecom.com (10.17.10.1) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id\n\t15.0.1044.25 via Frontend Transport; Mon, 21 Nov 2016 07:01:21 -0800",
            "from uklogin.uk.solarflarecom.com (uklogin.uk.solarflarecom.com\n\t[10.17.10.10])\n\tby opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id\n\tuALF1Ka0007210 for <dev@dpdk.org>; Mon, 21 Nov 2016 15:01:20 GMT",
            "from uklogin.uk.solarflarecom.com (localhost.localdomain\n\t[127.0.0.1])\n\tby uklogin.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id\n\tuALF1J3T006765 for <dev@dpdk.org>; Mon, 21 Nov 2016 15:01:20 GMT"
        ],
        "X-MXL-Hash": "58330c5179f10421-1f3c2eeee661f85e8ec4c18b5f683fbb0509c9e3",
        "From": "Andrew Rybchenko <arybchenko@solarflare.com>",
        "To": "<dev@dpdk.org>",
        "Date": "Mon, 21 Nov 2016 15:00:52 +0000",
        "Message-ID": "<1479740470-6723-39-git-send-email-arybchenko@solarflare.com>",
        "X-Mailer": "git-send-email 1.8.2.3",
        "In-Reply-To": "<1479740470-6723-1-git-send-email-arybchenko@solarflare.com>",
        "References": "<1479740470-6723-1-git-send-email-arybchenko@solarflare.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-AnalysisOut": [
            "[v=2.1 cv=UI/baXry c=1 sm=1 tr=0 a=8BlWFWvVlq5taO8ncb8nKg==]",
            "[:17 a=L24OOQBejmoA:10 a=zRKbQ67AAAAA:8 a=m46YgpYouJgSWnsLt]",
            "[cMA:9 a=OOzZkUnBOZBx3BnS:21 a=NLEWjvBr6eF-72LM:21 a=PA03WX]",
            "[8tBzeizutn5_OT:22]"
        ],
        "X-Spam": "[F=0.3658846512; CM=0.500; S=0.365(2015072901)]",
        "X-MAIL-FROM": "<arybchenko@solarflare.com>",
        "X-SOURCE-IP": "[12.187.104.26]",
        "Subject": "[dpdk-dev] [PATCH 38/56] net/sfc: implement event queue support",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <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": "Reviewed-by: Andy Moreton <amoreton@solarflare.com>\nSigned-off-by: Andrew Rybchenko <arybchenko@solarflare.com>\n---\n drivers/net/sfc/efx/Makefile |   1 +\n drivers/net/sfc/efx/sfc.c    |  17 ++\n drivers/net/sfc/efx/sfc.h    |   7 +\n drivers/net/sfc/efx/sfc_ev.c | 484 +++++++++++++++++++++++++++++++++++++++++++\n drivers/net/sfc/efx/sfc_ev.h | 138 ++++++++++++\n 5 files changed, 647 insertions(+)\n create mode 100644 drivers/net/sfc/efx/sfc_ev.c\n create mode 100644 drivers/net/sfc/efx/sfc_ev.h",
    "diff": "diff --git a/drivers/net/sfc/efx/Makefile b/drivers/net/sfc/efx/Makefile\nindex 2d2f9b8..a0b388f 100644\n--- a/drivers/net/sfc/efx/Makefile\n+++ b/drivers/net/sfc/efx/Makefile\n@@ -85,6 +85,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_kvargs.c\n SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc.c\n SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_mcdi.c\n SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_intr.c\n+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_ev.c\n \n VPATH += $(SRCDIR)/base\n \ndiff --git a/drivers/net/sfc/efx/sfc.c b/drivers/net/sfc/efx/sfc.c\nindex d66ea4a..6870efe 100644\n--- a/drivers/net/sfc/efx/sfc.c\n+++ b/drivers/net/sfc/efx/sfc.c\n@@ -36,6 +36,7 @@\n \n #include \"sfc.h\"\n #include \"sfc_log.h\"\n+#include \"sfc_ev.h\"\n \n \n int\n@@ -261,10 +262,17 @@ sfc_start(struct sfc_adapter *sa)\n \tif (rc != 0)\n \t\tgoto fail_intr_start;\n \n+\trc = sfc_ev_start(sa);\n+\tif (rc != 0)\n+\t\tgoto fail_ev_start;\n+\n \tsa->state = SFC_ADAPTER_STARTED;\n \tsfc_log_init(sa, \"done\");\n \treturn 0;\n \n+fail_ev_start:\n+\tsfc_intr_stop(sa);\n+\n fail_intr_start:\n \tefx_nic_fini(sa->nic);\n \n@@ -297,6 +305,7 @@ sfc_stop(struct sfc_adapter *sa)\n \n \tsa->state = SFC_ADAPTER_STOPPING;\n \n+\tsfc_ev_stop(sa);\n \tsfc_intr_stop(sa);\n \tefx_nic_fini(sa->nic);\n \n@@ -324,10 +333,17 @@ sfc_configure(struct sfc_adapter *sa)\n \tif (rc != 0)\n \t\tgoto fail_intr_init;\n \n+\trc = sfc_ev_init(sa);\n+\tif (rc != 0)\n+\t\tgoto fail_ev_init;\n+\n \tsa->state = SFC_ADAPTER_CONFIGURED;\n \tsfc_log_init(sa, \"done\");\n \treturn 0;\n \n+fail_ev_init:\n+\tsfc_intr_fini(sa);\n+\n fail_intr_init:\n fail_check_conf:\n \tsa->state = SFC_ADAPTER_INITIALIZED;\n@@ -345,6 +361,7 @@ sfc_close(struct sfc_adapter *sa)\n \tSFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED);\n \tsa->state = SFC_ADAPTER_CLOSING;\n \n+\tsfc_ev_fini(sa);\n \tsfc_intr_fini(sa);\n \n \tsa->state = SFC_ADAPTER_INITIALIZED;\ndiff --git a/drivers/net/sfc/efx/sfc.h b/drivers/net/sfc/efx/sfc.h\nindex 2b1c784..eb8c071 100644\n--- a/drivers/net/sfc/efx/sfc.h\n+++ b/drivers/net/sfc/efx/sfc.h\n@@ -113,6 +113,8 @@ struct sfc_intr {\n \tefx_intr_type_t\t\t\ttype;\n };\n \n+struct sfc_evq_info;\n+\n /* Adapter private data */\n struct sfc_adapter {\n \t/*\n@@ -137,6 +139,11 @@ struct sfc_adapter {\n \n \tunsigned int\t\t\trxq_max;\n \tunsigned int\t\t\ttxq_max;\n+\n+\tunsigned int\t\t\tevq_count;\n+\tstruct sfc_evq_info\t\t*evq_info;\n+\n+\tunsigned int\t\t\tmgmt_evq_index;\n };\n \n /*\ndiff --git a/drivers/net/sfc/efx/sfc_ev.c b/drivers/net/sfc/efx/sfc_ev.c\nnew file mode 100644\nindex 0000000..852051c\n--- /dev/null\n+++ b/drivers/net/sfc/efx/sfc_ev.c\n@@ -0,0 +1,484 @@\n+/*-\n+ * Copyright (c) 2016 Solarflare Communications Inc.\n+ * All rights reserved.\n+ *\n+ * This software was jointly developed between OKTET Labs (under contract\n+ * for Solarflare) and Solarflare Communications, Inc.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ *\n+ * 1. Redistributions of source code must retain the above copyright notice,\n+ *    this list of conditions and the following disclaimer.\n+ * 2. Redistributions in binary form must reproduce the above copyright notice,\n+ *    this list of conditions and the following disclaimer in the documentation\n+ *    and/or other materials provided with the distribution.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <rte_debug.h>\n+#include <rte_cycles.h>\n+\n+#include \"efx.h\"\n+\n+#include \"sfc.h\"\n+#include \"sfc_debug.h\"\n+#include \"sfc_log.h\"\n+#include \"sfc_ev.h\"\n+\n+\n+/* Initial delay when waiting for event queue init complete event */\n+#define\tSFC_EVQ_INIT_BACKOFF_START_US\t(1)\n+/* Maximum delay between event queue polling attempts */\n+#define\tSFC_EVQ_INIT_BACKOFF_MAX_US\t(10 * 1000)\n+/* Event queue init approx timeout */\n+#define\tSFC_EVQ_INIT_TIMEOUT_US\t\t(2 * US_PER_S)\n+\n+\n+static boolean_t\n+sfc_ev_initialized(void *arg)\n+{\n+\tstruct sfc_evq *evq = arg;\n+\n+\t/* Init done events may be duplicated on SFN7xxx (SFC bug 31631) */\n+\tSFC_ASSERT(evq->init_state == SFC_EVQ_STARTING ||\n+\t\t   evq->init_state == SFC_EVQ_STARTED);\n+\n+\tevq->init_state = SFC_EVQ_STARTED;\n+\n+\treturn B_FALSE;\n+}\n+\n+static boolean_t\n+sfc_ev_rx(void *arg, uint32_t label, uint32_t id, uint32_t size, uint16_t flags)\n+{\n+\tstruct sfc_evq *evq = arg;\n+\n+\tsfc_err(evq->sa, \"EVQ %u unexpected Rx event\", evq->evq_index);\n+\treturn B_TRUE;\n+}\n+\n+static boolean_t\n+sfc_ev_tx(void *arg, uint32_t label, uint32_t id)\n+{\n+\tstruct sfc_evq *evq = arg;\n+\n+\tsfc_err(evq->sa, \"EVQ %u unexpected Tx event\", evq->evq_index);\n+\treturn B_TRUE;\n+}\n+\n+static boolean_t\n+sfc_ev_exception(void *arg, uint32_t code, uint32_t data)\n+{\n+\tstruct sfc_evq *evq = arg;\n+\n+\tsfc_err(evq->sa, \"EVQ %u unexpected exception event\",\n+\t\tevq->evq_index);\n+\treturn B_TRUE;\n+}\n+\n+static boolean_t\n+sfc_ev_rxq_flush_done(void *arg, uint32_t rxq_hw_index)\n+{\n+\tstruct sfc_evq *evq = arg;\n+\n+\tsfc_err(evq->sa, \"EVQ %u unexpected Rx flush done event\",\n+\t\tevq->evq_index);\n+\treturn B_TRUE;\n+}\n+\n+static boolean_t\n+sfc_ev_rxq_flush_failed(void *arg, uint32_t rxq_hw_index)\n+{\n+\tstruct sfc_evq *evq = arg;\n+\n+\tsfc_err(evq->sa, \"EVQ %u unexpected Rx flush failed event\",\n+\t\tevq->evq_index);\n+\treturn B_TRUE;\n+}\n+\n+static boolean_t\n+sfc_ev_txq_flush_done(void *arg, uint32_t txq_hw_index)\n+{\n+\tstruct sfc_evq *evq = arg;\n+\n+\tsfc_err(evq->sa, \"EVQ %u unexpected Tx flush done event\",\n+\t\tevq->evq_index);\n+\treturn B_TRUE;\n+}\n+\n+static boolean_t\n+sfc_ev_software(void *arg, uint16_t magic)\n+{\n+\tstruct sfc_evq *evq = arg;\n+\n+\tsfc_err(evq->sa, \"EVQ %u unexpected software event magic=%#.4x\",\n+\t\tevq->evq_index, magic);\n+\treturn B_TRUE;\n+}\n+\n+static boolean_t\n+sfc_ev_sram(void *arg, uint32_t code)\n+{\n+\tstruct sfc_evq *evq = arg;\n+\n+\tsfc_err(evq->sa, \"EVQ %u unexpected SRAM event code=%u\",\n+\t\tevq->evq_index, code);\n+\treturn B_TRUE;\n+}\n+\n+static boolean_t\n+sfc_ev_wake_up(void *arg, uint32_t index)\n+{\n+\tstruct sfc_evq *evq = arg;\n+\n+\tsfc_err(evq->sa, \"EVQ %u unexpected wake up event index=%u\",\n+\t\tevq->evq_index, index);\n+\treturn B_TRUE;\n+}\n+\n+static boolean_t\n+sfc_ev_timer(void *arg, uint32_t index)\n+{\n+\tstruct sfc_evq *evq = arg;\n+\n+\tsfc_err(evq->sa, \"EVQ %u unexpected timer event index=%u\",\n+\t\tevq->evq_index, index);\n+\treturn B_TRUE;\n+}\n+\n+static boolean_t\n+sfc_ev_link_change(void *arg, efx_link_mode_t link_mode)\n+{\n+\tstruct sfc_evq *evq = arg;\n+\n+\tsfc_err(evq->sa, \"EVQ %u unexpected link change\",\n+\t\tevq->evq_index);\n+\treturn B_TRUE;\n+}\n+\n+static const efx_ev_callbacks_t sfc_ev_callbacks = {\n+\t.eec_initialized\t= sfc_ev_initialized,\n+\t.eec_rx\t\t\t= sfc_ev_rx,\n+\t.eec_tx\t\t\t= sfc_ev_tx,\n+\t.eec_exception\t\t= sfc_ev_exception,\n+\t.eec_rxq_flush_done\t= sfc_ev_rxq_flush_done,\n+\t.eec_rxq_flush_failed\t= sfc_ev_rxq_flush_failed,\n+\t.eec_txq_flush_done\t= sfc_ev_txq_flush_done,\n+\t.eec_software\t\t= sfc_ev_software,\n+\t.eec_sram\t\t= sfc_ev_sram,\n+\t.eec_wake_up\t\t= sfc_ev_wake_up,\n+\t.eec_timer\t\t= sfc_ev_timer,\n+\t.eec_link_change\t= sfc_ev_link_change,\n+};\n+\n+\n+void\n+sfc_ev_qpoll(struct sfc_evq *evq)\n+{\n+\tSFC_ASSERT(evq->init_state == SFC_EVQ_STARTED ||\n+\t\t   evq->init_state == SFC_EVQ_STARTING);\n+\n+\t/* Synchronize the DMA memory for reading not required */\n+\n+\tefx_ev_qpoll(evq->common, &evq->read_ptr, &sfc_ev_callbacks, evq);\n+\n+\t/* Poll-mode driver does not re-prime the event queue for interrupts */\n+}\n+\n+int\n+sfc_ev_qprime(struct sfc_evq *evq)\n+{\n+\tSFC_ASSERT(evq->init_state == SFC_EVQ_STARTED);\n+\treturn efx_ev_qprime(evq->common, evq->read_ptr);\n+}\n+\n+int\n+sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index)\n+{\n+\tconst struct sfc_evq_info *evq_info;\n+\tstruct sfc_evq *evq;\n+\tefsys_mem_t *esmp;\n+\tunsigned int total_delay_us;\n+\tunsigned int delay_us;\n+\tint rc;\n+\n+\tsfc_log_init(sa, \"sw_index=%u\", sw_index);\n+\n+\tevq_info = &sa->evq_info[sw_index];\n+\tevq = evq_info->evq;\n+\tesmp = &evq->mem;\n+\n+\t/* Clear all events */\n+\t(void)memset((void *)esmp->esm_base, 0xff,\n+\t\t     EFX_EVQ_SIZE(evq_info->entries));\n+\n+\t/* Create the common code event queue */\n+\trc = efx_ev_qcreate(sa->nic, sw_index, esmp, evq_info->entries,\n+\t\t\t    0 /* unused on EF10 */, 0,\n+\t\t\t    EFX_EVQ_FLAGS_TYPE_THROUGHPUT |\n+\t\t\t    EFX_EVQ_FLAGS_NOTIFY_DISABLED,\n+\t\t\t    &evq->common);\n+\tif (rc != 0)\n+\t\tgoto fail_ev_qcreate;\n+\n+\tevq->init_state = SFC_EVQ_STARTING;\n+\n+\t/* Wait for the initialization event */\n+\ttotal_delay_us = 0;\n+\tdelay_us = SFC_EVQ_INIT_BACKOFF_START_US;\n+\tdo {\n+\t\t(void)sfc_ev_qpoll(evq);\n+\n+\t\t/* Check to see if the initialization complete indication\n+\t\t * posted by the hardware.\n+\t\t */\n+\t\tif (evq->init_state == SFC_EVQ_STARTED)\n+\t\t\tgoto done;\n+\n+\t\t/* Give event queue some time to init */\n+\t\trte_delay_us(delay_us);\n+\n+\t\ttotal_delay_us += delay_us;\n+\n+\t\t/* Exponential backoff */\n+\t\tdelay_us *= 2;\n+\t\tif (delay_us > SFC_EVQ_INIT_BACKOFF_MAX_US)\n+\t\t\tdelay_us = SFC_EVQ_INIT_BACKOFF_MAX_US;\n+\n+\t} while (total_delay_us < SFC_EVQ_INIT_TIMEOUT_US);\n+\n+\trc = ETIMEDOUT;\n+\tgoto fail_timedout;\n+\n+done:\n+\treturn 0;\n+\n+fail_timedout:\n+\tevq->init_state = SFC_EVQ_INITIALIZED;\n+\tefx_ev_qdestroy(evq->common);\n+\n+fail_ev_qcreate:\n+\tsfc_log_init(sa, \"failed %d\", rc);\n+\treturn rc;\n+}\n+\n+void\n+sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index)\n+{\n+\tconst struct sfc_evq_info *evq_info;\n+\tstruct sfc_evq *evq;\n+\n+\tsfc_log_init(sa, \"sw_index=%u\", sw_index);\n+\n+\tSFC_ASSERT(sw_index < sa->evq_count);\n+\n+\tevq_info = &sa->evq_info[sw_index];\n+\tevq = evq_info->evq;\n+\n+\tif (evq == NULL || evq->init_state != SFC_EVQ_STARTED)\n+\t\treturn;\n+\n+\tevq->init_state = SFC_EVQ_INITIALIZED;\n+\tevq->read_ptr = 0;\n+\tevq->exception = B_FALSE;\n+\n+\tefx_ev_qdestroy(evq->common);\n+}\n+\n+int\n+sfc_ev_start(struct sfc_adapter *sa)\n+{\n+\tint rc;\n+\n+\tsfc_log_init(sa, \"entry\");\n+\n+\trc = efx_ev_init(sa->nic);\n+\tif (rc != 0)\n+\t\tgoto fail_ev_init;\n+\n+\t/*\n+\t * Rx/Tx event queues are started/stopped when corresponding queue\n+\t * is started/stopped.\n+\t */\n+\n+\treturn 0;\n+\n+fail_ev_init:\n+\tsfc_log_init(sa, \"failed %d\", rc);\n+\treturn rc;\n+}\n+\n+void\n+sfc_ev_stop(struct sfc_adapter *sa)\n+{\n+\tint sw_index;\n+\n+\tsfc_log_init(sa, \"entry\");\n+\n+\t/* Make sure that all event queues are stopped */\n+\tsw_index = sa->evq_count;\n+\twhile (--sw_index >= 0)\n+\t\tsfc_ev_qstop(sa, sw_index);\n+\n+\tefx_ev_fini(sa->nic);\n+}\n+\n+int\n+sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,\n+\t     unsigned int entries, int socket_id)\n+{\n+\tstruct sfc_evq_info *evq_info;\n+\tstruct sfc_evq *evq;\n+\tint rc;\n+\n+\tsfc_log_init(sa, \"sw_index=%u\", sw_index);\n+\n+\tevq_info = &sa->evq_info[sw_index];\n+\n+\tSFC_ASSERT(rte_is_power_of_2(entries));\n+\tSFC_ASSERT(entries <= evq_info->max_entries);\n+\tevq_info->entries = entries;\n+\n+\tevq = rte_zmalloc_socket(\"sfc-evq\", sizeof(*evq), RTE_CACHE_LINE_SIZE,\n+\t\t\t\t socket_id);\n+\tif (evq == NULL)\n+\t\treturn ENOMEM;\n+\n+\tevq->sa = sa;\n+\tevq->evq_index = sw_index;\n+\n+\t/* Allocate DMA space */\n+\trc = sfc_dma_alloc(sa, \"evq\", sw_index, EFX_EVQ_SIZE(evq_info->entries),\n+\t\t\t   socket_id, &evq->mem);\n+\tif (rc != 0)\n+\t\treturn rc;\n+\n+\tevq->init_state = SFC_EVQ_INITIALIZED;\n+\n+\tevq_info->evq = evq;\n+\n+\treturn 0;\n+}\n+\n+void\n+sfc_ev_qfini(struct sfc_adapter *sa, unsigned int sw_index)\n+{\n+\tstruct sfc_evq *evq;\n+\n+\tsfc_log_init(sa, \"sw_index=%u\", sw_index);\n+\n+\tevq = sa->evq_info[sw_index].evq;\n+\n+\tSFC_ASSERT(evq->init_state == SFC_EVQ_INITIALIZED);\n+\n+\tsa->evq_info[sw_index].evq = NULL;\n+\n+\tsfc_dma_free(sa, &evq->mem);\n+\n+\trte_free(evq);\n+}\n+\n+static int\n+sfc_ev_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)\n+{\n+\tstruct sfc_evq_info *evq_info = &sa->evq_info[sw_index];\n+\tunsigned int max_entries;\n+\tint rc;\n+\n+\tsfc_log_init(sa, \"sw_index=%u\", sw_index);\n+\n+\tmax_entries = sfc_evq_max_entries(sa, sw_index);\n+\tSFC_ASSERT(rte_is_power_of_2(max_entries));\n+\n+\tevq_info->max_entries = max_entries;\n+\n+\treturn 0;\n+}\n+\n+static void\n+sfc_ev_qfini_info(struct sfc_adapter *sa, unsigned int sw_index)\n+{\n+\tstruct sfc_evq_info *evq_info = &sa->evq_info[sw_index];\n+\tint rc;\n+\n+\tsfc_log_init(sa, \"sw_index=%u\", sw_index);\n+\n+\t/* Nothing to cleanup */\n+}\n+\n+int\n+sfc_ev_init(struct sfc_adapter *sa)\n+{\n+\tint sw_index;\n+\tint rc;\n+\n+\tsfc_log_init(sa, \"entry\");\n+\n+\tsa->evq_count = sfc_ev_qcount(sa);\n+\tsa->mgmt_evq_index = 0;\n+\n+\t/* Allocate EVQ info array */\n+\trc = ENOMEM;\n+\tsa->evq_info = rte_calloc_socket(\"sfc-evqs\", sa->evq_count,\n+\t\t\t\t\t sizeof(struct sfc_evq_info), 0,\n+\t\t\t\t\t sa->socket_id);\n+\tif (sa->evq_info == NULL)\n+\t\tgoto fail_evqs_alloc;\n+\n+\tfor (sw_index = 0; sw_index < sa->evq_count; ++sw_index) {\n+\t\trc = sfc_ev_qinit_info(sa, sw_index);\n+\t\tif (rc != 0)\n+\t\t\tgoto fail_ev_qinit_info;\n+\t}\n+\n+\t/*\n+\t * Rx/Tx event queues are created/destroyed when corresponding\n+\t * Rx/Tx queue is created/destroyed.\n+\t */\n+\n+\treturn 0;\n+\n+fail_ev_qinit_info:\n+\twhile (sw_index-- > 0)\n+\t\tsfc_ev_qfini_info(sa, sw_index);\n+\n+\trte_free(sa->evq_info);\n+\tsa->evq_info = NULL;\n+\n+fail_evqs_alloc:\n+\tsa->evq_count = 0;\n+\tsfc_log_init(sa, \"failed %d\", rc);\n+\treturn rc;\n+}\n+\n+void\n+sfc_ev_fini(struct sfc_adapter *sa)\n+{\n+\tint sw_index;\n+\n+\tsfc_log_init(sa, \"entry\");\n+\n+\t/* Cleanup all event queues */\n+\tsw_index = sa->evq_count;\n+\twhile (--sw_index >= 0) {\n+\t\tif (sa->evq_info[sw_index].evq != NULL)\n+\t\t\tsfc_ev_qfini(sa, sw_index);\n+\t\tsfc_ev_qfini_info(sa, sw_index);\n+\t}\n+\n+\trte_free(sa->evq_info);\n+\tsa->evq_info = NULL;\n+\tsa->evq_count = 0;\n+}\ndiff --git a/drivers/net/sfc/efx/sfc_ev.h b/drivers/net/sfc/efx/sfc_ev.h\nnew file mode 100644\nindex 0000000..140a436\n--- /dev/null\n+++ b/drivers/net/sfc/efx/sfc_ev.h\n@@ -0,0 +1,138 @@\n+/*-\n+ * Copyright (c) 2016 Solarflare Communications Inc.\n+ * All rights reserved.\n+ *\n+ * This software was jointly developed between OKTET Labs (under contract\n+ * for Solarflare) and Solarflare Communications, Inc.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ *\n+ * 1. Redistributions of source code must retain the above copyright notice,\n+ *    this list of conditions and the following disclaimer.\n+ * 2. Redistributions in binary form must reproduce the above copyright notice,\n+ *    this list of conditions and the following disclaimer in the documentation\n+ *    and/or other materials provided with the distribution.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef _SFC_EV_H_\n+#define\t_SFC_EV_H_\n+\n+#include \"efx.h\"\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+/* Number of entries in the management event queue */\n+#define\tSFC_MGMT_EVQ_ENTRIES\t(EFX_EVQ_MINNEVS)\n+\n+struct sfc_adapter;\n+\n+enum sfc_evq_state {\n+\tSFC_EVQ_UNINITIALIZED = 0,\n+\tSFC_EVQ_INITIALIZED,\n+\tSFC_EVQ_STARTING,\n+\tSFC_EVQ_STARTED,\n+\n+\tSFC_EVQ_NSTATES\n+};\n+\n+struct sfc_evq {\n+\t/* Used on datapath */\n+\tefx_evq_t\t\t*common;\n+\tunsigned int\t\tread_ptr;\n+\tboolean_t\t\texception;\n+\tefsys_mem_t\t\tmem;\n+\n+\t/* Not used on datapath */\n+\tstruct sfc_adapter\t*sa;\n+\tunsigned int\t\tevq_index;\n+\tenum sfc_evq_state\tinit_state;\n+};\n+\n+struct sfc_evq_info {\n+\t/* Maximum number of EVQ entries taken into account when buffer\n+\t * table space is allocated.\n+\t */\n+\tunsigned int\t\tmax_entries;\n+\t/* Real number of EVQ entries, less or equal to max_entries */\n+\tunsigned int\t\tentries;\n+\t/* NUMA-aware EVQ data structure used on datapath */\n+\tstruct sfc_evq\t\t*evq;\n+};\n+\n+/*\n+ * Functions below define event queue to transmit/receive queue and vice\n+ * versa mapping.\n+ */\n+\n+static inline unsigned int\n+sfc_ev_qcount(struct sfc_adapter *sa)\n+{\n+\tconst struct rte_eth_dev_data *dev_data = sa->eth_dev->data;\n+\n+\t/*\n+\t * One management EVQ for global events.\n+\t * Own EVQ for each Tx and Rx queue.\n+\t */\n+\treturn 1 + dev_data->nb_rx_queues + dev_data->nb_tx_queues;\n+}\n+\n+static inline unsigned int\n+sfc_evq_max_entries(struct sfc_adapter *sa, unsigned int sw_index)\n+{\n+\tunsigned int max_entries;\n+\n+\tif (sw_index == sa->mgmt_evq_index)\n+\t\tmax_entries = SFC_MGMT_EVQ_ENTRIES;\n+\telse if (sw_index <= sa->eth_dev->data->nb_rx_queues)\n+\t\tmax_entries = EFX_RXQ_MAXNDESCS;\n+\telse\n+\t\tmax_entries = efx_nic_cfg_get(sa->nic)->enc_txq_max_ndescs;\n+\n+\treturn max_entries;\n+}\n+\n+static inline unsigned int\n+sfc_evq_index_by_rxq_sw_index(struct sfc_adapter *sa, unsigned int rxq_sw_index)\n+{\n+\treturn 1 + rxq_sw_index;\n+}\n+\n+static inline unsigned int\n+sfc_evq_index_by_txq_sw_index(struct sfc_adapter *sa, unsigned int txq_sw_index)\n+{\n+\treturn 1 + sa->eth_dev->data->nb_rx_queues + txq_sw_index;\n+}\n+\n+int sfc_ev_init(struct sfc_adapter *sa);\n+void sfc_ev_fini(struct sfc_adapter *sa);\n+int sfc_ev_start(struct sfc_adapter *sa);\n+void sfc_ev_stop(struct sfc_adapter *sa);\n+\n+int sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,\n+\t\t unsigned int entries, int socket_id);\n+void sfc_ev_qfini(struct sfc_adapter *sa, unsigned int sw_index);\n+int sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index);\n+void sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index);\n+\n+int sfc_ev_qprime(struct sfc_evq *evq);\n+void sfc_ev_qpoll(struct sfc_evq *evq);\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+#endif /* _SFC_EV_H_ */\n",
    "prefixes": [
        "dpdk-dev",
        "38/56"
    ]
}