get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 131043,
    "url": "https://patches.dpdk.org/api/patches/131043/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20230901032842.223547-6-wanry@3snic.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20230901032842.223547-6-wanry@3snic.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230901032842.223547-6-wanry@3snic.com",
    "date": "2023-09-01T03:28:15",
    "name": "[v3,05/32] net/sssnic: add event queue",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "2bafd69b40f0cac36f41caa99660fa256ad12a22",
    "submitter": {
        "id": 3119,
        "url": "https://patches.dpdk.org/api/people/3119/?format=api",
        "name": "Renyong Wan",
        "email": "wanry@3snic.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20230901032842.223547-6-wanry@3snic.com/mbox/",
    "series": [
        {
            "id": 29399,
            "url": "https://patches.dpdk.org/api/series/29399/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=29399",
            "date": "2023-09-01T03:28:13",
            "name": "Introduce sssnic PMD for 3SNIC's 9x0 serials Ethernet adapters",
            "version": 3,
            "mbox": "https://patches.dpdk.org/series/29399/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/131043/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/131043/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id DE16642219;\n\tFri,  1 Sep 2023 05:32:49 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id BCF8C402B6;\n\tFri,  1 Sep 2023 05:31:31 +0200 (CEST)",
            "from VLXDG1SPAM1.ramaxel.com (email.ramaxel.com [221.4.138.186])\n by mails.dpdk.org (Postfix) with ESMTP id 2A3BB4029C\n for <dev@dpdk.org>; Fri,  1 Sep 2023 05:31:28 +0200 (CEST)",
            "from V12DG1MBS03.ramaxel.local ([172.26.18.33])\n by VLXDG1SPAM1.ramaxel.com with ESMTP id 3813SnVh033287;\n Fri, 1 Sep 2023 11:28:51 +0800 (GMT-8)\n (envelope-from wanry@3snic.com)",
            "from localhost.localdomain (10.64.136.151) by\n V12DG1MBS03.ramaxel.local (172.26.18.33) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id\n 15.1.2375.17; Fri, 1 Sep 2023 11:28:50 +0800"
        ],
        "From": "<wanry@3snic.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<ferruh.yigit@amd.com>, Renyong Wan <wanry@3snic.com>, Steven Song\n <steven.song@3snic.com>",
        "Subject": "[PATCH v3 05/32] net/sssnic: add event queue",
        "Date": "Fri, 1 Sep 2023 11:28:15 +0800",
        "Message-ID": "<20230901032842.223547-6-wanry@3snic.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20230901032842.223547-1-wanry@3snic.com>",
        "References": "<20230901032842.223547-1-wanry@3snic.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "7bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.64.136.151]",
        "X-ClientProxiedBy": "V12DG1MBS03.ramaxel.local (172.26.18.33) To\n V12DG1MBS03.ramaxel.local (172.26.18.33)",
        "X-DNSRBL": "",
        "X-SPAM-SOURCE-CHECK": "pass",
        "X-MAIL": "VLXDG1SPAM1.ramaxel.com 3813SnVh033287",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "From: Renyong Wan <wanry@3snic.com>\n\nEvent queue is intended for receiving event from hardware as well\nas mailbox response message.\n\nSigned-off-by: Steven Song <steven.song@3snic.com>\nSigned-off-by: Renyong Wan <wanry@3snic.com>\n---\n drivers/net/sssnic/base/meson.build     |   1 +\n drivers/net/sssnic/base/sssnic_eventq.c | 426 ++++++++++++++++++++++++\n drivers/net/sssnic/base/sssnic_eventq.h |  84 +++++\n drivers/net/sssnic/base/sssnic_hw.c     |   9 +-\n drivers/net/sssnic/base/sssnic_hw.h     |   5 +\n drivers/net/sssnic/base/sssnic_reg.h    |  51 +++\n drivers/net/sssnic/sssnic_ethdev.c      |   1 +\n 7 files changed, 576 insertions(+), 1 deletion(-)\n create mode 100644 drivers/net/sssnic/base/sssnic_eventq.c\n create mode 100644 drivers/net/sssnic/base/sssnic_eventq.h",
    "diff": "diff --git a/drivers/net/sssnic/base/meson.build b/drivers/net/sssnic/base/meson.build\nindex 3e64112c72..7758faa482 100644\n--- a/drivers/net/sssnic/base/meson.build\n+++ b/drivers/net/sssnic/base/meson.build\n@@ -3,6 +3,7 @@\n \n sources = [\n         'sssnic_hw.c',\n+        'sssnic_eventq.c'\n ]\n \n c_args = cflags\ndiff --git a/drivers/net/sssnic/base/sssnic_eventq.c b/drivers/net/sssnic/base/sssnic_eventq.c\nnew file mode 100644\nindex 0000000000..a479bdff35\n--- /dev/null\n+++ b/drivers/net/sssnic/base/sssnic_eventq.c\n@@ -0,0 +1,426 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#include <rte_byteorder.h>\n+#include <rte_common.h>\n+#include <rte_cycles.h>\n+#include <rte_bus_pci.h>\n+#include <rte_malloc.h>\n+#include <rte_memzone.h>\n+#include <ethdev_pci.h>\n+#include <ethdev_driver.h>\n+\n+#include \"../sssnic_log.h\"\n+#include \"sssnic_hw.h\"\n+#include \"sssnic_reg.h\"\n+#include \"sssnic_eventq.h\"\n+\n+#define SSSNIC_EVENTQ_DEF_DEPTH 64\n+#define SSSNIC_EVENTQ_NUM_PAGES 4\n+#define SSSNIC_EVENTQ_MAX_PAGE_SZ 0x400000\n+#define SSSNIC_EVENTQ_MIN_PAGE_SZ 0x1000\n+\n+#define SSSNIC_EVENT_ADDR(base_addr, event_sz, idx)                            \\\n+\t(struct sssnic_event *)(((uint8_t *)(base_addr)) + ((idx) * (event_sz)))\n+\n+static inline struct sssnic_event *\n+sssnic_eventq_peek(struct sssnic_eventq *eq)\n+{\n+\tuint16_t page = eq->ci / eq->page_len;\n+\tuint16_t idx = eq->ci % eq->page_len;\n+\n+\treturn SSSNIC_EVENT_ADDR(eq->pages[page]->addr, eq->entry_size, idx);\n+}\n+\n+static inline void\n+sssnic_eventq_reg_write(struct sssnic_eventq *eq, uint32_t reg, uint32_t val)\n+{\n+\tsssnic_cfg_reg_write(eq->hw, reg, val);\n+}\n+\n+static inline uint32_t\n+sssnic_eventq_reg_read(struct sssnic_eventq *eq, uint32_t reg)\n+{\n+\treturn sssnic_cfg_reg_read(eq->hw, reg);\n+}\n+\n+static inline void\n+sssnic_eventq_reg_write64(struct sssnic_eventq *eq, uint32_t reg, uint64_t val)\n+{\n+\tsssnic_cfg_reg_write(eq->hw, reg, (uint32_t)((val >> 16) >> 16));\n+\tsssnic_cfg_reg_write(eq->hw, reg + sizeof(uint32_t), (uint32_t)val);\n+}\n+\n+/* all eventq registers that to be access must be selected first */\n+static inline void\n+sssnic_eventq_reg_select(struct sssnic_eventq *eq)\n+{\n+\tsssnic_eventq_reg_write(eq, SSSNIC_EVENTQ_IDX_SEL_REG, eq->qid);\n+}\n+\n+static const struct rte_memzone *\n+sssnic_eventq_page_alloc(struct sssnic_eventq *eq, int page_idx)\n+{\n+\tconst struct rte_memzone *mz = NULL;\n+\tchar mz_name[RTE_MEMZONE_NAMESIZE];\n+\n+\tsnprintf(mz_name, sizeof(mz_name), \"sssnic%u_eq%d_page%d\",\n+\t\tSSSNIC_ETH_PORT_ID(eq->hw), eq->qid, page_idx);\n+\tmz = rte_memzone_reserve_aligned(mz_name, eq->page_size, SOCKET_ID_ANY,\n+\t\tRTE_MEMZONE_IOVA_CONTIG, eq->page_size);\n+\treturn mz;\n+}\n+\n+static uint32_t\n+sssnic_eventq_page_size_calc(uint32_t depth, uint32_t entry_size)\n+{\n+\tuint32_t pages = SSSNIC_EVENTQ_NUM_PAGES;\n+\tuint32_t size;\n+\n+\tsize = RTE_ALIGN(depth * entry_size, SSSNIC_EVENTQ_MIN_PAGE_SZ);\n+\tif (size <= pages * SSSNIC_EVENTQ_MIN_PAGE_SZ) {\n+\t\t/* use minimum page size */\n+\t\treturn SSSNIC_EVENTQ_MIN_PAGE_SZ;\n+\t}\n+\n+\t/* Calculate how many pages of minimum size page the big size page covers */\n+\tsize = RTE_ALIGN(size / pages, SSSNIC_EVENTQ_MIN_PAGE_SZ);\n+\tpages = rte_fls_u32(size / SSSNIC_EVENTQ_MIN_PAGE_SZ);\n+\n+\treturn SSSNIC_EVENTQ_MIN_PAGE_SZ * pages;\n+}\n+\n+static int\n+sssnic_eventq_pages_setup(struct sssnic_eventq *eq)\n+{\n+\tconst struct rte_memzone *mz;\n+\tstruct sssnic_event *ev;\n+\tint i, j;\n+\n+\teq->pages = rte_zmalloc(NULL,\n+\t\teq->num_pages * sizeof(struct rte_memzone *), 1);\n+\tif (eq->pages == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Could not alloc memory for pages\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (i = 0; i < eq->num_pages; i++) {\n+\t\tmz = sssnic_eventq_page_alloc(eq, i);\n+\t\tif (mz == NULL) {\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t\"Could not alloc DMA memory for eventq page %d\",\n+\t\t\t\ti);\n+\t\t\tgoto alloc_dma_fail;\n+\t\t}\n+\t\t/* init eventq entries */\n+\t\tfor (j = 0; j < eq->page_len; j++) {\n+\t\t\tev = SSSNIC_EVENT_ADDR(mz->addr, eq->entry_size, j);\n+\t\t\tev->desc.u32 = 0;\n+\t\t}\n+\t\teq->pages[i] = mz;\n+\t\tsssnic_eventq_reg_write64(eq,\n+\t\t\tSSSNIC_EVENTQ_PAGE_ADDR_REG + i * sizeof(uint64_t),\n+\t\t\tmz->iova);\n+\t}\n+\n+\treturn 0;\n+\n+alloc_dma_fail:\n+\twhile (i--)\n+\t\trte_memzone_free(eq->pages[i]);\n+\trte_free(eq->pages);\n+\treturn -ENOMEM;\n+}\n+\n+static void\n+sssnic_eventq_pages_cleanup(struct sssnic_eventq *eq)\n+{\n+\tint i;\n+\n+\tif (eq->pages == NULL)\n+\t\treturn;\n+\tfor (i = 0; i < eq->num_pages; i++)\n+\t\trte_memzone_free(eq->pages[i]);\n+\trte_free(eq->pages);\n+\teq->pages = NULL;\n+}\n+\n+static void\n+sssnic_eventq_ctrl_setup(struct sssnic_eventq *eq)\n+{\n+\tstruct sssnic_hw *hw = eq->hw;\n+\tstruct sssnic_eventq_ctrl0_reg ctrl_0;\n+\tstruct sssnic_eventq_ctrl1_reg ctrl_1;\n+\n+\tctrl_0.u32 = sssnic_eventq_reg_read(eq, SSSNIC_EVENTQ_CTRL0_REG);\n+\tctrl_0.intr_idx = eq->msix_entry;\n+\tctrl_0.dma_attr = SSSNIC_REG_EVENTQ_DEF_DMA_ATTR;\n+\tctrl_0.pci_idx = hw->attr.pci_idx;\n+\tctrl_0.intr_mode = SSSNIC_REG_EVENTQ_INTR_MODE_0;\n+\tsssnic_eventq_reg_write(eq, SSSNIC_EVENTQ_CTRL0_REG, ctrl_0.u32);\n+\n+\tctrl_1.page_size = rte_log2_u32(eq->page_size >> 12);\n+\tctrl_1.depth = eq->depth;\n+\tctrl_1.entry_size = rte_log2_u32(eq->entry_size >> 5);\n+\tsssnic_eventq_reg_write(eq, SSSNIC_EVENTQ_CTRL1_REG, ctrl_1.u32);\n+}\n+\n+/* synchronize current software CI to hardware.\n+ * @ informed: indate event will be informed by interrupt.\n+ *             0: not to be informed\n+ *             1: informed by interrupt\n+ */\n+static void\n+sssnic_eventq_ci_update(struct sssnic_eventq *eq, int informed)\n+{\n+\tstruct sssnic_eventq_ci_ctrl_reg reg;\n+\n+\treg.u32 = 0;\n+\tif (eq->qid == 0)\n+\t\treg.informed = !!informed;\n+\treg.qid = eq->qid;\n+\treg.ci = eq->ci_wrapped;\n+\tsssnic_eventq_reg_write(eq, SSSNIC_EVENTQ_CI_CTRL_REG, reg.u32);\n+}\n+\n+static int\n+sssnic_eventq_init(struct sssnic_hw *hw, struct sssnic_eventq *eq, uint16_t qid)\n+{\n+\tint ret;\n+\n+\tif (hw == NULL || eq == NULL) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad parameter for event queue initialization.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\teq->hw = hw;\n+\teq->msix_entry = 0; /* eventq uses msix 0 in PMD driver */\n+\teq->qid = qid;\n+\teq->depth = SSSNIC_EVENTQ_DEF_DEPTH;\n+\teq->entry_size = SSSNIC_EVENT_SIZE;\n+\teq->page_size = sssnic_eventq_page_size_calc(eq->depth, eq->entry_size);\n+\teq->page_len = eq->page_size / eq->entry_size;\n+\tif (eq->page_len & (eq->page_len - 1)) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid page length: %d, must be power of 2\",\n+\t\t\teq->page_len);\n+\t\treturn -EINVAL;\n+\t}\n+\teq->num_pages = RTE_ALIGN((eq->depth * eq->entry_size), eq->page_size) /\n+\t\t\teq->page_size;\n+\tif (eq->num_pages > SSSNIC_EVENTQ_NUM_PAGES) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Invalid number of pages: %d, can't be more than %d pages.\",\n+\t\t\teq->num_pages, SSSNIC_EVENTQ_NUM_PAGES);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* select the eq which registers to be acesss */\n+\tsssnic_eventq_reg_select(eq);\n+\trte_wmb();\n+\t/* clear entries in eventq */\n+\tsssnic_eventq_reg_write(eq, SSSNIC_EVENTQ_CTRL1_REG, 0);\n+\trte_wmb();\n+\t/* reset pi to 0 */\n+\tsssnic_eventq_reg_write(eq, SSSNIC_EVENTQ_PROD_IDX_REG, 0);\n+\n+\tret = sssnic_eventq_pages_setup(eq);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to setup eventq pages!\");\n+\t\treturn ret;\n+\t}\n+\tsssnic_eventq_ctrl_setup(eq);\n+\tsssnic_eventq_ci_update(eq, 1);\n+\tif (qid == 0)\n+\t\tsssnic_msix_state_set(eq->hw, 0, SSSNIC_MSIX_ENABLE);\n+\n+\tPMD_DRV_LOG(DEBUG,\n+\t\t\"eventq %u: q_depth=%u, entry_size=%u, num_pages=%u, page_size=%u, page_len=%u\",\n+\t\tqid, eq->depth, eq->entry_size, eq->num_pages, eq->page_size,\n+\t\teq->page_len);\n+\n+\treturn 0;\n+}\n+\n+static void\n+sssnic_eventq_shutdown(struct sssnic_eventq *eq)\n+{\n+\tif (eq->qid == 0)\n+\t\tsssnic_msix_state_set(eq->hw, 0, SSSNIC_MSIX_DISABLE);\n+\n+\tsssnic_eventq_reg_select(eq);\n+\trte_wmb();\n+\n+\tsssnic_eventq_reg_write(eq, SSSNIC_EVENTQ_CTRL1_REG, 0);\n+\teq->ci = sssnic_eventq_reg_read(eq, SSSNIC_EVENTQ_PROD_IDX_REG);\n+\tsssnic_eventq_ci_update(eq, 0);\n+\tsssnic_eventq_pages_cleanup(eq);\n+}\n+\n+static void\n+sssnic_event_be_to_cpu_32(struct sssnic_event *in, struct sssnic_event *out)\n+{\n+\tuint32_t i;\n+\n+\tfor (i = 0; i < SSSNIC_EVENT_SIZE; i += 4)\n+\t\t*((uint32_t *)(out->data + i)) =\n+\t\t\trte_be_to_cpu_32(*((uint32_t *)(in->data + i)));\n+}\n+\n+static int\n+sssinc_event_handle(struct sssnic_eventq *eq, struct sssnic_event *event)\n+{\n+\tstruct sssnic_event ev;\n+\tsssnic_event_handler_func_t *func;\n+\tvoid *data;\n+\n+\tsssnic_event_be_to_cpu_32(event, &ev);\n+\tif (ev.desc.code < SSSNIC_EVENT_CODE_MIN ||\n+\t\tev.desc.code > SSSNIC_EVENT_CODE_MAX) {\n+\t\tPMD_DRV_LOG(ERR, \"Event code %d is not supported\",\n+\t\t\tev.desc.code);\n+\t\treturn -1;\n+\t}\n+\n+\tfunc = eq->handlers[ev.desc.code].func;\n+\tdata = eq->handlers[ev.desc.code].data;\n+\tif (func == NULL) {\n+\t\tPMD_DRV_LOG(NOTICE,\n+\t\t\t\"Could not find handler for event qid:%u code:%d\",\n+\t\t\teq->qid, ev.desc.code);\n+\t\treturn -1;\n+\t}\n+\n+\treturn func(eq, &ev, data);\n+}\n+\n+/* Poll one valid event in timeout_ms */\n+static struct sssnic_event *\n+sssnic_eventq_poll(struct sssnic_eventq *eq, uint32_t timeout_ms)\n+{\n+\tstruct sssnic_event *event;\n+\tstruct sssnic_eventd desc;\n+\tuint64_t end;\n+\n+\tif (timeout_ms > 0)\n+\t\tend = rte_get_timer_cycles() +\n+\t\t      rte_get_timer_hz() * timeout_ms / 1000;\n+\n+\tdo {\n+\t\tevent = sssnic_eventq_peek(eq);\n+\t\tdesc.u32 = rte_be_to_cpu_32(event->desc.u32);\n+\t\tif (desc.wrapped != eq->wrapped)\n+\t\t\treturn event;\n+\n+\t\tif (timeout_ms > 0)\n+\t\t\trte_delay_us_sleep(1000);\n+\t} while ((timeout_ms > 0) &&\n+\t\t (((long)(rte_get_timer_cycles() - end)) < 0));\n+\n+\treturn NULL;\n+}\n+\n+/*  Take one or more events to handle. */\n+int\n+sssnic_eventq_flush(struct sssnic_hw *hw, uint16_t qid, uint32_t timeout_ms)\n+{\n+\tint found = 0;\n+\tuint32_t i = 0;\n+\tint done = 0;\n+\tstruct sssnic_event *event;\n+\tstruct sssnic_eventq *eq;\n+\n+\tif (qid >= hw->num_eventqs) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\"Bad parameter, event queue id must be less than %u\",\n+\t\t\thw->num_eventqs);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\teq = &hw->eventqs[qid];\n+\tfor (i = 0; i < eq->depth; i++) {\n+\t\tevent = sssnic_eventq_poll(eq, timeout_ms);\n+\t\tif (event == NULL)\n+\t\t\tbreak;\n+\t\tdone = sssinc_event_handle(eq, event);\n+\t\teq->ci++;\n+\t\tif (eq->ci == eq->depth) {\n+\t\t\teq->ci = 0;\n+\t\t\teq->wrapped = !eq->wrapped;\n+\t\t}\n+\n+\t\tfound++;\n+\t\tif (done == SSSNIC_EVENT_DONE)\n+\t\t\tbreak;\n+\t}\n+\n+\tSSSNIC_DEBUG(\"found:%d, done:%d, ci:%u, depth:%u, wrapped:%u\", found,\n+\t\tdone, eq->ci, eq->depth, eq->wrapped);\n+\n+\tif (!found)\n+\t\treturn -ETIME;\n+\n+\tsssnic_eventq_ci_update(eq, 1);\n+\n+\tif (event == NULL || done != SSSNIC_EVENT_DONE)\n+\t\treturn -ETIME;\n+\n+\treturn 0;\n+}\n+\n+int\n+sssnic_eventq_all_init(struct sssnic_hw *hw)\n+{\n+\tstruct sssnic_eventq *eventqs;\n+\tint num_eventqs;\n+\tint i = 0;\n+\tint ret;\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\tnum_eventqs = hw->attr.num_aeq;\n+\teventqs = rte_zmalloc(NULL, sizeof(struct sssnic_eventq) * num_eventqs,\n+\t\t1);\n+\tif (eventqs == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Could not alloc memory for event queue\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tfor (i = 0; i < num_eventqs; i++) {\n+\t\tret = sssnic_eventq_init(hw, &eventqs[i], i);\n+\t\tif (ret != 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Failed to initialize event queue: %d\",\n+\t\t\t\ti);\n+\t\t\tgoto init_eventq_fail;\n+\t\t}\n+\t}\n+\thw->eventqs = eventqs;\n+\thw->num_eventqs = num_eventqs;\n+\n+\tPMD_DRV_LOG(INFO, \"Initialized %d event queues\", num_eventqs);\n+\n+\treturn 0;\n+\n+init_eventq_fail:\n+\twhile (i--)\n+\t\tsssnic_eventq_shutdown(&eventqs[i]);\n+\trte_free(eventqs);\n+\treturn ret;\n+}\n+\n+void\n+sssnic_eventq_all_shutdown(struct sssnic_hw *hw)\n+{\n+\tint i;\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\tif (hw->eventqs == NULL)\n+\t\treturn;\n+\n+\tfor (i = 0; i < hw->num_eventqs; i++)\n+\t\tsssnic_eventq_shutdown(&hw->eventqs[i]);\n+\trte_free(hw->eventqs);\n+\thw->eventqs = NULL;\n+}\ndiff --git a/drivers/net/sssnic/base/sssnic_eventq.h b/drivers/net/sssnic/base/sssnic_eventq.h\nnew file mode 100644\nindex 0000000000..a196c10f48\n--- /dev/null\n+++ b/drivers/net/sssnic/base/sssnic_eventq.h\n@@ -0,0 +1,84 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.\n+ */\n+\n+#ifndef _SSSNIC_EVENTQ_H_\n+#define _SSSNIC_EVENTQ_H_\n+\n+#define SSSNIC_MAX_NUM_EVENTQ 4\n+#define SSSNIC_MIN_NUM_EVENTQ 2\n+\n+#define SSSNIC_EVENT_DESC_SIZE sizeof(uint32_t)\n+#define SSSNIC_EVENT_SIZE 64\n+#define SSSNIC_EVENT_DATA_SIZE (SSSNIC_EVENT_SIZE - SSSNIC_EVENT_DESC_SIZE)\n+\n+enum sssnic_event_code {\n+\tSSSNIC_EVENT_CODE_RESVD = 0,\n+\tSSSNIC_EVENT_FROM_FUNC = 1, /* event from PF and VF */\n+\tSSSNIC_EVENT_FROM_MPU = 2, /* event form management processor unit*/\n+};\n+#define SSSNIC_EVENT_CODE_MIN SSSNIC_EVENT_FROM_FUNC\n+#define SSSNIC_EVENT_CODE_MAX SSSNIC_EVENT_FROM_MPU\n+\n+struct sssnic_eventq;\n+struct sssnic_event;\n+\n+/* Indicate that sssnic event has been finished to handle */\n+#define SSSNIC_EVENT_DONE 1\n+\n+typedef int sssnic_event_handler_func_t(struct sssnic_eventq *eq,\n+\tstruct sssnic_event *ev, void *data);\n+\n+struct sssnic_event_handler {\n+\tsssnic_event_handler_func_t *func;\n+\tvoid *data;\n+};\n+\n+struct sssnic_eventq {\n+\tstruct sssnic_hw *hw;\n+\tuint16_t qid;\n+\tuint16_t entry_size;\n+\tuint32_t depth; /* max number of entries in eventq */\n+\tuint16_t page_len; /* number of entries in a page */\n+\tuint16_t num_pages; /* number pages to store event entries */\n+\tuint32_t page_size;\n+\tconst struct rte_memzone **pages;\n+\tunion {\n+\t\tuint32_t ci_wrapped;\n+\t\tstruct {\n+\t\t\tuint32_t ci : 19;\n+\t\t\tuint32_t wrapped : 1;\n+\t\t\tuint32_t resvd : 12;\n+\t\t};\n+\t};\n+\tuint16_t msix_entry;\n+\tstruct sssnic_event_handler handlers[SSSNIC_EVENT_CODE_MAX + 1];\n+};\n+\n+/* event descriptor */\n+struct sssnic_eventd {\n+\tunion {\n+\t\tuint32_t u32;\n+\t\tstruct {\n+\t\t\tuint32_t code : 7;\n+\t\t\tuint32_t src : 1;\n+\t\t\tuint32_t size : 8;\n+\t\t\tuint32_t resvd : 15;\n+\t\t\tuint32_t wrapped : 1;\n+\t\t};\n+\t};\n+};\n+\n+/* event entry */\n+struct sssnic_event {\n+\tuint8_t data[SSSNIC_EVENT_DATA_SIZE];\n+\tstruct sssnic_eventd desc;\n+};\n+\n+int sssnic_eventq_flush(struct sssnic_hw *hw, uint16_t qid,\n+\tuint32_t timeout_ms);\n+\n+int sssnic_eventq_all_init(struct sssnic_hw *hw);\n+void sssnic_eventq_all_shutdown(struct sssnic_hw *hw);\n+\n+#endif /* _SSSNIC_EVENTQ_H_ */\ndiff --git a/drivers/net/sssnic/base/sssnic_hw.c b/drivers/net/sssnic/base/sssnic_hw.c\nindex 8b7bba7644..44e04486a5 100644\n--- a/drivers/net/sssnic/base/sssnic_hw.c\n+++ b/drivers/net/sssnic/base/sssnic_hw.c\n@@ -9,6 +9,7 @@\n #include \"../sssnic_log.h\"\n #include \"sssnic_hw.h\"\n #include \"sssnic_reg.h\"\n+#include \"sssnic_eventq.h\"\n \n static int\n wait_for_sssnic_hw_ready(struct sssnic_hw *hw)\n@@ -196,12 +197,18 @@ sssnic_hw_init(struct sssnic_hw *hw)\n \t\treturn ret;\n \t}\n \n+\tret = sssnic_eventq_all_init(hw);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to initialize event queues\");\n+\t\treturn ret;\n+\t}\n+\n \treturn -EINVAL;\n }\n \n void\n sssnic_hw_shutdown(struct sssnic_hw *hw)\n {\n-\tRTE_SET_USED(hw);\n \tPMD_INIT_FUNC_TRACE();\n+\tsssnic_eventq_all_shutdown(hw);\n }\ndiff --git a/drivers/net/sssnic/base/sssnic_hw.h b/drivers/net/sssnic/base/sssnic_hw.h\nindex 65d4d562b4..6caf3a6d66 100644\n--- a/drivers/net/sssnic/base/sssnic_hw.h\n+++ b/drivers/net/sssnic/base/sssnic_hw.h\n@@ -51,8 +51,13 @@ struct sssnic_hw {\n \tuint8_t *db_base_addr;\n \tuint8_t *db_mem_len;\n \tstruct sssnic_hw_attr attr;\n+\tstruct sssnic_eventq *eventqs;\n+\tuint8_t num_eventqs;\n+\tuint16_t eth_port_id;\n };\n \n+#define SSSNIC_ETH_PORT_ID(hw) ((hw)->eth_port_id)\n+\n int sssnic_hw_init(struct sssnic_hw *hw);\n void sssnic_hw_shutdown(struct sssnic_hw *hw);\n void sssnic_msix_state_set(struct sssnic_hw *hw, uint16_t msix_id, int state);\ndiff --git a/drivers/net/sssnic/base/sssnic_reg.h b/drivers/net/sssnic/base/sssnic_reg.h\nindex 77d83292eb..e38d39a691 100644\n--- a/drivers/net/sssnic/base/sssnic_reg.h\n+++ b/drivers/net/sssnic/base/sssnic_reg.h\n@@ -18,6 +18,14 @@\n \n #define SSSNIC_MSIX_CTRL_REG 0x58\n \n+#define SSSNIC_EVENTQ_CI_CTRL_REG 0x50\n+#define SSSNIC_EVENTQ_IDX_SEL_REG 0x210\n+#define SSSNIC_EVENTQ_CTRL0_REG 0x200\n+#define SSSNIC_EVENTQ_CTRL1_REG 0x204\n+#define SSSNIC_EVENTQ_CONS_IDX_REG 0x208\n+#define SSSNIC_EVENTQ_PROD_IDX_REG 0x20c\n+#define SSSNIC_EVENTQ_PAGE_ADDR_REG 0x240\n+\n /* registers of mgmt */\n #define SSSNIC_AF_ELECTION_REG 0x6000\n #define SSSNIC_MF_ELECTION_REG 0x6020\n@@ -142,6 +150,49 @@ struct sssnic_msix_ctrl_reg {\n \t};\n };\n \n+#define SSSNIC_REG_EVENTQ_INTR_MODE_0 0 /* armed mode */\n+#define SSSNIC_REG_EVENTQ_INTR_MODE_1 1 /* allway mode */\n+#define SSSNIC_REG_EVENTQ_DEF_DMA_ATTR 0\n+struct sssnic_eventq_ctrl0_reg {\n+\tunion {\n+\t\tuint32_t u32;\n+\t\tstruct {\n+\t\t\tuint32_t intr_idx : 10;\n+\t\t\tuint32_t resvd_0 : 2;\n+\t\t\tuint32_t dma_attr : 6;\n+\t\t\tuint32_t resvd_1 : 2;\n+\t\t\tuint32_t pci_idx : 1;\n+\t\t\tuint32_t resvd_2 : 8;\n+\t\t\tuint32_t intr_mode : 1;\n+\t\t};\n+\t};\n+};\n+\n+struct sssnic_eventq_ctrl1_reg {\n+\tunion {\n+\t\tuint32_t u32;\n+\t\tstruct {\n+\t\t\tuint32_t depth : 21;\n+\t\t\tuint32_t resvd_0 : 3;\n+\t\t\tuint32_t entry_size : 2;\n+\t\t\tuint32_t resvd_1 : 2;\n+\t\t\tuint32_t page_size : 4;\n+\t\t};\n+\t};\n+};\n+\n+struct sssnic_eventq_ci_ctrl_reg {\n+\tunion {\n+\t\tuint32_t u32;\n+\t\tstruct {\n+\t\t\tuint32_t ci : 21;\n+\t\t\tuint32_t informed : 1;\n+\t\t\tuint32_t resvd_0 : 8;\n+\t\t\tuint32_t qid : 2;\n+\t\t};\n+\t};\n+};\n+\n static inline uint32_t\n sssnic_cfg_reg_read(struct sssnic_hw *hw, uint32_t reg)\n {\ndiff --git a/drivers/net/sssnic/sssnic_ethdev.c b/drivers/net/sssnic/sssnic_ethdev.c\nindex e198b1e1d0..460ff604aa 100644\n--- a/drivers/net/sssnic/sssnic_ethdev.c\n+++ b/drivers/net/sssnic/sssnic_ethdev.c\n@@ -40,6 +40,7 @@ sssnic_ethdev_init(struct rte_eth_dev *ethdev)\n \t}\n \tnetdev->hw = hw;\n \thw->pci_dev = pci_dev;\n+\thw->eth_port_id = ethdev->data->port_id;\n \tret = sssnic_hw_init(hw);\n \tif (ret != 0) {\n \t\trte_free(hw);\n",
    "prefixes": [
        "v3",
        "05/32"
    ]
}