get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 56086,
    "url": "http://patches.dpdk.org/api/patches/56086/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20190704122959.18919-4-thomas@monjalon.net/",
    "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": "<20190704122959.18919-4-thomas@monjalon.net>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20190704122959.18919-4-thomas@monjalon.net",
    "date": "2019-07-04T12:29:58",
    "name": "[v11,3/4] raw/ntb: add handshake process",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "ad935c969ae9949c63291ccffc2481b9f2d3e174",
    "submitter": {
        "id": 685,
        "url": "http://patches.dpdk.org/api/people/685/?format=api",
        "name": "Thomas Monjalon",
        "email": "thomas@monjalon.net"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20190704122959.18919-4-thomas@monjalon.net/mbox/",
    "series": [
        {
            "id": 5339,
            "url": "http://patches.dpdk.org/api/series/5339/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=5339",
            "date": "2019-07-04T12:29:55",
            "name": "rawdev driver for ntb",
            "version": 11,
            "mbox": "http://patches.dpdk.org/series/5339/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/56086/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/56086/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id BF2791BE3F;\n\tThu,  4 Jul 2019 14:30:56 +0200 (CEST)",
            "from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com\n\t[66.111.4.25]) by dpdk.org (Postfix) with ESMTP id A6B8A1BE32\n\tfor <dev@dpdk.org>; Thu,  4 Jul 2019 14:30:54 +0200 (CEST)",
            "from compute1.internal (compute1.nyi.internal [10.202.2.41])\n\tby mailout.nyi.internal (Postfix) with ESMTP id 2045F21FC3;\n\tThu,  4 Jul 2019 08:30:54 -0400 (EDT)",
            "from mailfrontend2 ([10.202.2.163])\n\tby compute1.internal (MEProxy); Thu, 04 Jul 2019 08:30:54 -0400",
            "from xps.monjalon.net (184.203.134.77.rev.sfr.net [77.134.203.184])\n\tby mail.messagingengine.com (Postfix) with ESMTPA id 0043B38008C;\n\tThu,  4 Jul 2019 08:30:52 -0400 (EDT)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/relaxed; d=monjalon.net; h=\n\tfrom:to:cc:subject:date:message-id:in-reply-to:references\n\t:mime-version:content-transfer-encoding; s=mesmtp; bh=6mN1Zfe1sM\n\tH+pAJiKJhZ88NIHpQZiM6w3VmhoBNaQ6w=; b=OnqwNiIZAMbb4GIP8MLXpucX4q\n\t6ia7lENs01uMFvHyvVBF3KSUNr8WLNtWUb1AIbSSni/eLe9sCqm1wjOhmUWbGPE5\n\tbPoNWEPQraPApHRbzbZEkiXRYKoZVxh/uagdXCBmgmqsJ/PthoycDRrO8vhChNG1\n\ttdLDkvwCq2PWZsjBY=",
            "v=1; a=rsa-sha256; c=relaxed/relaxed; d=\n\tmessagingengine.com; h=cc:content-transfer-encoding:date:from\n\t:in-reply-to:message-id:mime-version:references:subject:to\n\t:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=\n\tfm3; bh=6mN1Zfe1sMH+pAJiKJhZ88NIHpQZiM6w3VmhoBNaQ6w=; b=SEaWL7vj\n\tdL3r5D8mXlXPnTmNs1KX1dHKtSrUa8g1sXxtgFHqyDJ3mu2vjgrwK+cAiue3JmuL\n\tw3wEQ+55WJfpj7L2Jzq+jpgkLIYpT5YWKz00pI6TBThQ7m5KRZ+g7moouwVW1PHa\n\tBIzGRHw6Sd8CpvYIiChL29OpxJFH90mRDYgrBwjpihIXBNWKZmEnUo7h1HMJ4+vc\n\tuvqP2uybz9WQ99OEiVe+sucAhGCVWblPJODxoP9Wglu/+fRck4q+BxOJqAXMBSxp\n\tpSGnK+xbpuauRtfZpg10OFWdOUE388JzZrPDw0memyx5wIH28IjHQoCrk6GjaH1S\n\tpgIKpaZgoh7FMg=="
        ],
        "X-ME-Sender": "<xms:ffEdXdlhx3EppIjEoyHVZGuLXoWh2_bDmHXZznkWr3Vwt-SCbMksnQ>",
        "X-ME-Proxy-Cause": "gggruggvucftvghtrhhoucdtuddrgeduvddrfedvgdehiecutefuodetggdotefrodftvf\n\tcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu\n\tuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc\n\tfjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepvfhhohhmrghs\n\tucfoohhnjhgrlhhonhcuoehthhhomhgrshesmhhonhhjrghlohhnrdhnvghtqeenucfkph\n\tepjeejrddufeegrddvtdefrddukeegnecurfgrrhgrmhepmhgrihhlfhhrohhmpehthhho\n\tmhgrshesmhhonhhjrghlohhnrdhnvghtnecuvehluhhsthgvrhfuihiivgeptd",
        "X-ME-Proxy": "<xmx:ffEdXdGU_pbfV-ZFsXSH477aBzZkXiMVx2QEBNpbfiDBuW56ktUlaQ>\n\t<xmx:ffEdXeoPcDRtsBFCJjx1U-dXP_gSLxsIfUieIzgzP9Xuoy8BjMBWaQ>\n\t<xmx:ffEdXR4MuqiKQ6pxRV4KM_IgTfjRAIF0TmgKouUf_xUGGXvKqyx4FA>\n\t<xmx:fvEdXb2-MjGB0P6gartdAZwey-5A0YiG5xvWLnJOpIFNadvZn-ihsg>",
        "From": "Thomas Monjalon <thomas@monjalon.net>",
        "To": "dev@dpdk.org, Xiaoyun Li <xiaoyun.li@intel.com>,\n\tJingjing Wu <jingjing.wu@intel.com>,\n\tJohn McNamara <john.mcnamara@intel.com>,\n\tMarko Kovacevic <marko.kovacevic@intel.com>",
        "Cc": "Xiaolong Ye <xiaolong.ye@intel.com>",
        "Date": "Thu,  4 Jul 2019 14:29:58 +0200",
        "Message-Id": "<20190704122959.18919-4-thomas@monjalon.net>",
        "X-Mailer": "git-send-email 2.21.0",
        "In-Reply-To": "<20190704122959.18919-1-thomas@monjalon.net>",
        "References": "<20190628025346.31312-1-xiaoyun.li@intel.com>\n\t<20190704122959.18919-1-thomas@monjalon.net>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v11 3/4] raw/ntb: add handshake process",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Xiaoyun Li <xiaoyun.li@intel.com>\n\nAdd handshake process using doorbell so that two hosts can\ncommunicate to start and stop.\n\nSigned-off-by: Xiaoyun Li <xiaoyun.li@intel.com>\nAcked-by: Jingjing Wu <jingjing.wu@intel.com>\nReviewed-by: Xiaolong Ye <xiaolong.ye@intel.com>\n---\n doc/guides/rawdevs/ntb.rst |   5 +\n drivers/raw/ntb/ntb.c      | 336 ++++++++++++++++++++++++++++++++++++-\n 2 files changed, 340 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/doc/guides/rawdevs/ntb.rst b/doc/guides/rawdevs/ntb.rst\nindex ff0795b47..0a61ec03d 100644\n--- a/doc/guides/rawdevs/ntb.rst\n+++ b/doc/guides/rawdevs/ntb.rst\n@@ -9,6 +9,11 @@ separate hosts so that they can communicate with each other. Thus, many\n user cases can benefit from this, such as fault tolerance and visual\n acceleration.\n \n+This PMD allows two hosts to handshake for device start and stop, memory\n+allocation for the peer to access and read/write allocated memory from peer.\n+Also, the PMD allows to use doorbell registers to notify the peer and share\n+some information by using scratchpad registers.\n+\n BIOS setting on Intel Skylake\n -----------------------------\n \ndiff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c\nindex 5fde704b7..c83b8d964 100644\n--- a/drivers/raw/ntb/ntb.c\n+++ b/drivers/raw/ntb/ntb.c\n@@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {\n \t{ .vendor_id = 0, /* sentinel */ },\n };\n \n+static int\n+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)\n+{\n+\tstruct ntb_hw *hw = dev->dev_private;\n+\tchar mw_name[RTE_MEMZONE_NAMESIZE];\n+\tconst struct rte_memzone *mz;\n+\tint ret = 0;\n+\n+\tif (hw->ntb_ops->mw_set_trans == NULL) {\n+\t\tNTB_LOG(ERR, \"Not supported to set mw.\");\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\tsnprintf(mw_name, sizeof(mw_name), \"ntb_%d_mw_%d\",\n+\t\t dev->dev_id, mw_idx);\n+\n+\tmz = rte_memzone_lookup(mw_name);\n+\tif (mz)\n+\t\treturn 0;\n+\n+\t/**\n+\t * Hardware requires that mapped memory base address should be\n+\t * aligned with EMBARSZ and needs continuous memzone.\n+\t */\n+\tmz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,\n+\t\t\t\tRTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);\n+\tif (!mz) {\n+\t\tNTB_LOG(ERR, \"Cannot allocate aligned memzone.\");\n+\t\treturn -EIO;\n+\t}\n+\thw->mz[mw_idx] = mz;\n+\n+\tret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);\n+\tif (ret) {\n+\t\tNTB_LOG(ERR, \"Cannot set mw translation.\");\n+\t\treturn ret;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static void\n+ntb_link_cleanup(struct rte_rawdev *dev)\n+{\n+\tstruct ntb_hw *hw = dev->dev_private;\n+\tint status, i;\n+\n+\tif (hw->ntb_ops->spad_write == NULL ||\n+\t    hw->ntb_ops->mw_set_trans == NULL) {\n+\t\tNTB_LOG(ERR, \"Not supported to clean up link.\");\n+\t\treturn;\n+\t}\n+\n+\t/* Clean spad registers. */\n+\tfor (i = 0; i < hw->spad_cnt; i++) {\n+\t\tstatus = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);\n+\t\tif (status)\n+\t\t\tNTB_LOG(ERR, \"Failed to clean local spad.\");\n+\t}\n+\n+\t/* Clear mw so that peer cannot access local memory.*/\n+\tfor (i = 0; i < hw->mw_cnt; i++) {\n+\t\tstatus = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);\n+\t\tif (status)\n+\t\t\tNTB_LOG(ERR, \"Failed to clean mw.\");\n+\t}\n+}\n+\n+static void\n+ntb_dev_intr_handler(void *param)\n+{\n+\tstruct rte_rawdev *dev = (struct rte_rawdev *)param;\n+\tstruct ntb_hw *hw = dev->dev_private;\n+\tuint32_t mw_size_h, mw_size_l;\n+\tuint64_t db_bits = 0;\n+\tint i = 0;\n+\n+\tif (hw->ntb_ops->db_read == NULL ||\n+\t    hw->ntb_ops->db_clear == NULL ||\n+\t    hw->ntb_ops->peer_db_set == NULL) {\n+\t\tNTB_LOG(ERR, \"Doorbell is not supported.\");\n+\t\treturn;\n+\t}\n+\n+\tdb_bits = (*hw->ntb_ops->db_read)(dev);\n+\tif (!db_bits)\n+\t\tNTB_LOG(ERR, \"No doorbells\");\n+\n+\t/* Doorbell 0 is for peer device ready. */\n+\tif (db_bits & 1) {\n+\t\tNTB_LOG(DEBUG, \"DB0: Peer device is up.\");\n+\t\t/* Clear received doorbell. */\n+\t\t(*hw->ntb_ops->db_clear)(dev, 1);\n+\n+\t\t/**\n+\t\t * Peer dev is already up. All mw settings are already done.\n+\t\t * Skip them.\n+\t\t */\n+\t\tif (hw->peer_dev_up)\n+\t\t\treturn;\n+\n+\t\tif (hw->ntb_ops->spad_read == NULL ||\n+\t\t    hw->ntb_ops->spad_write == NULL) {\n+\t\t\tNTB_LOG(ERR, \"Scratchpad is not supported.\");\n+\t\t\treturn;\n+\t\t}\n+\n+\t\thw->peer_mw_cnt = (*hw->ntb_ops->spad_read)\n+\t\t\t\t  (dev, SPAD_NUM_MWS, 0);\n+\t\thw->peer_mw_size = rte_zmalloc(\"uint64_t\",\n+\t\t\t\t   hw->peer_mw_cnt * sizeof(uint64_t), 0);\n+\t\tfor (i = 0; i < hw->mw_cnt; i++) {\n+\t\t\tmw_size_h = (*hw->ntb_ops->spad_read)\n+\t\t\t\t    (dev, SPAD_MW0_SZ_H + 2 * i, 0);\n+\t\t\tmw_size_l = (*hw->ntb_ops->spad_read)\n+\t\t\t\t    (dev, SPAD_MW0_SZ_L + 2 * i, 0);\n+\t\t\thw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |\n+\t\t\t\t\t      mw_size_l;\n+\t\t\tNTB_LOG(DEBUG, \"Peer %u mw size: 0x%\"PRIx64\"\", i,\n+\t\t\t\t\thw->peer_mw_size[i]);\n+\t\t}\n+\n+\t\thw->peer_dev_up = 1;\n+\n+\t\t/**\n+\t\t * Handshake with peer. Spad_write only works when both\n+\t\t * devices are up. So write spad again when db is received.\n+\t\t * And set db again for the later device who may miss\n+\t\t * the 1st db.\n+\t\t */\n+\t\tfor (i = 0; i < hw->mw_cnt; i++) {\n+\t\t\t(*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,\n+\t\t\t\t\t\t   1, hw->mw_cnt);\n+\t\t\tmw_size_h = hw->mw_size[i] >> 32;\n+\t\t\t(*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,\n+\t\t\t\t\t\t   1, mw_size_h);\n+\n+\t\t\tmw_size_l = hw->mw_size[i];\n+\t\t\t(*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,\n+\t\t\t\t\t\t   1, mw_size_l);\n+\t\t}\n+\t\t(*hw->ntb_ops->peer_db_set)(dev, 0);\n+\n+\t\t/* To get the link info. */\n+\t\tif (hw->ntb_ops->get_link_status == NULL) {\n+\t\t\tNTB_LOG(ERR, \"Not supported to get link status.\");\n+\t\t\treturn;\n+\t\t}\n+\t\t(*hw->ntb_ops->get_link_status)(dev);\n+\t\tNTB_LOG(INFO, \"Link is up. Link speed: %u. Link width: %u\",\n+\t\t\thw->link_speed, hw->link_width);\n+\t\treturn;\n+\t}\n+\n+\tif (db_bits & (1 << 1)) {\n+\t\tNTB_LOG(DEBUG, \"DB1: Peer device is down.\");\n+\t\t/* Clear received doorbell. */\n+\t\t(*hw->ntb_ops->db_clear)(dev, 2);\n+\n+\t\t/* Peer device will be down, So clean local side too. */\n+\t\tntb_link_cleanup(dev);\n+\n+\t\thw->peer_dev_up = 0;\n+\t\t/* Response peer's dev_stop request. */\n+\t\t(*hw->ntb_ops->peer_db_set)(dev, 2);\n+\t\treturn;\n+\t}\n+\n+\tif (db_bits & (1 << 2)) {\n+\t\tNTB_LOG(DEBUG, \"DB2: Peer device agrees dev to be down.\");\n+\t\t/* Clear received doorbell. */\n+\t\t(*hw->ntb_ops->db_clear)(dev, (1 << 2));\n+\t\thw->peer_dev_up = 0;\n+\t\treturn;\n+\t}\n+}\n+\n static void\n ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,\n \t\t   uint16_t queue_id __rte_unused,\n@@ -147,7 +324,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,\n static int\n ntb_dev_start(struct rte_rawdev *dev)\n {\n+\tstruct ntb_hw *hw = dev->dev_private;\n+\tint ret, i;\n+\n \t/* TODO: init queues and start queues. */\n+\n+\t/* Map memory of bar_size to remote. */\n+\thw->mz = rte_zmalloc(\"struct rte_memzone *\",\n+\t\t\t     hw->mw_cnt * sizeof(struct rte_memzone *), 0);\n+\tfor (i = 0; i < hw->mw_cnt; i++) {\n+\t\tret = ntb_set_mw(dev, i, hw->mw_size[i]);\n+\t\tif (ret) {\n+\t\t\tNTB_LOG(ERR, \"Fail to set mw.\");\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n \tdev->started = 1;\n \n \treturn 0;\n@@ -156,13 +348,59 @@ ntb_dev_start(struct rte_rawdev *dev)\n static void\n ntb_dev_stop(struct rte_rawdev *dev)\n {\n+\tstruct ntb_hw *hw = dev->dev_private;\n+\tuint32_t time_out;\n+\tint status;\n+\n \t/* TODO: stop rx/tx queues. */\n+\n+\tif (!hw->peer_dev_up)\n+\t\tgoto clean;\n+\n+\tntb_link_cleanup(dev);\n+\n+\t/* Notify the peer that device will be down. */\n+\tif (hw->ntb_ops->peer_db_set == NULL) {\n+\t\tNTB_LOG(ERR, \"Peer doorbell setting is not supported.\");\n+\t\treturn;\n+\t}\n+\tstatus = (*hw->ntb_ops->peer_db_set)(dev, 1);\n+\tif (status) {\n+\t\tNTB_LOG(ERR, \"Failed to tell peer device is down.\");\n+\t\treturn;\n+\t}\n+\n+\t/*\n+\t * Set time out as 1s in case that the peer is stopped accidently\n+\t * without any notification.\n+\t */\n+\ttime_out = 1000000;\n+\n+\t/* Wait for cleanup work down before db mask clear. */\n+\twhile (hw->peer_dev_up && time_out) {\n+\t\ttime_out -= 10;\n+\t\trte_delay_us(10);\n+\t}\n+\n+clean:\n+\t/* Clear doorbells mask. */\n+\tif (hw->ntb_ops->db_set_mask == NULL) {\n+\t\tNTB_LOG(ERR, \"Doorbell mask setting is not supported.\");\n+\t\treturn;\n+\t}\n+\tstatus = (*hw->ntb_ops->db_set_mask)(dev,\n+\t\t\t\t(((uint64_t)1 << hw->db_cnt) - 1));\n+\tif (status)\n+\t\tNTB_LOG(ERR, \"Failed to clear doorbells.\");\n+\n \tdev->started = 0;\n }\n \n static int\n ntb_dev_close(struct rte_rawdev *dev)\n {\n+\tstruct ntb_hw *hw = dev->dev_private;\n+\tstruct rte_intr_handle *intr_handle;\n \tint ret = 0;\n \n \tif (dev->started)\n@@ -170,6 +408,20 @@ ntb_dev_close(struct rte_rawdev *dev)\n \n \t/* TODO: free queues. */\n \n+\tintr_handle = &hw->pci_dev->intr_handle;\n+\t/* Clean datapath event and vec mapping */\n+\trte_intr_efd_disable(intr_handle);\n+\tif (intr_handle->intr_vec) {\n+\t\trte_free(intr_handle->intr_vec);\n+\t\tintr_handle->intr_vec = NULL;\n+\t}\n+\t/* Disable uio intr before callback unregister */\n+\trte_intr_disable(intr_handle);\n+\n+\t/* Unregister callback func to eal lib */\n+\trte_intr_callback_unregister(intr_handle,\n+\t\t\t\t     ntb_dev_intr_handler, dev);\n+\n \treturn ret;\n }\n \n@@ -346,7 +598,9 @@ static int\n ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)\n {\n \tstruct ntb_hw *hw = dev->dev_private;\n-\tint ret;\n+\tstruct rte_intr_handle *intr_handle;\n+\tuint32_t val;\n+\tint ret, i;\n \n \thw->pci_dev = pci_dev;\n \thw->peer_dev_up = 0;\n@@ -377,6 +631,86 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)\n \tif (ret)\n \t\treturn ret;\n \n+\t/* Init doorbell. */\n+\thw->db_valid_mask = RTE_LEN2MASK(hw->db_cnt, uint64_t);\n+\n+\tintr_handle = &pci_dev->intr_handle;\n+\t/* Register callback func to eal lib */\n+\trte_intr_callback_register(intr_handle,\n+\t\t\t\t   ntb_dev_intr_handler, dev);\n+\n+\tret = rte_intr_efd_enable(intr_handle, hw->db_cnt);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* To clarify, the interrupt for each doorbell is already mapped\n+\t * by default for intel gen3. They are mapped to msix vec 1-32,\n+\t * and hardware intr is mapped to 0. Map all to 0 for uio.\n+\t */\n+\tif (!rte_intr_cap_multiple(intr_handle)) {\n+\t\tfor (i = 0; i < hw->db_cnt; i++) {\n+\t\t\tif (hw->ntb_ops->vector_bind == NULL)\n+\t\t\t\treturn -ENOTSUP;\n+\t\t\tret = (*hw->ntb_ops->vector_bind)(dev, i, 0);\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\tif (hw->ntb_ops->db_set_mask == NULL ||\n+\t    hw->ntb_ops->peer_db_set == NULL) {\n+\t\tNTB_LOG(ERR, \"Doorbell is not supported.\");\n+\t\treturn -ENOTSUP;\n+\t}\n+\thw->db_mask = 0;\n+\tret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);\n+\tif (ret) {\n+\t\tNTB_LOG(ERR, \"Unable to enable intr for all dbs.\");\n+\t\treturn ret;\n+\t}\n+\n+\t/* enable uio intr after callback register */\n+\trte_intr_enable(intr_handle);\n+\n+\tif (hw->ntb_ops->spad_write == NULL) {\n+\t\tNTB_LOG(ERR, \"Scratchpad is not supported.\");\n+\t\treturn -ENOTSUP;\n+\t}\n+\t/* Tell peer the mw_cnt of local side. */\n+\tret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);\n+\tif (ret) {\n+\t\tNTB_LOG(ERR, \"Failed to tell peer mw count.\");\n+\t\treturn ret;\n+\t}\n+\n+\t/* Tell peer each mw size on local side. */\n+\tfor (i = 0; i < hw->mw_cnt; i++) {\n+\t\tNTB_LOG(DEBUG, \"Local %u mw size: 0x%\"PRIx64\"\", i,\n+\t\t\t\thw->mw_size[i]);\n+\t\tval = hw->mw_size[i] >> 32;\n+\t\tret = (*hw->ntb_ops->spad_write)\n+\t\t\t\t(dev, SPAD_MW0_SZ_H + 2 * i, 1, val);\n+\t\tif (ret) {\n+\t\t\tNTB_LOG(ERR, \"Failed to tell peer mw size.\");\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tval = hw->mw_size[i];\n+\t\tret = (*hw->ntb_ops->spad_write)\n+\t\t\t\t(dev, SPAD_MW0_SZ_L + 2 * i, 1, val);\n+\t\tif (ret) {\n+\t\t\tNTB_LOG(ERR, \"Failed to tell peer mw size.\");\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\t/* Ring doorbell 0 to tell peer the device is ready. */\n+\tret = (*hw->ntb_ops->peer_db_set)(dev, 0);\n+\tif (ret) {\n+\t\tNTB_LOG(ERR, \"Failed to tell peer device is probed.\");\n+\t\treturn ret;\n+\t}\n+\n \treturn ret;\n }\n \n",
    "prefixes": [
        "v11",
        "3/4"
    ]
}