Show a patch.

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

{
    "id": 74549,
    "url": "https://patches.dpdk.org/api/patches/74549/",
    "web_url": "https://patches.dpdk.org/patch/74549/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/",
        "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"
    },
    "msgid": "<20200721095140.719297-11-bruce.richardson@intel.com>",
    "date": "2020-07-21T09:51:30",
    "name": "[20.11,10/20] raw/ioat: create rawdev instances on idxd PCI probe",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "6e8b0f1130cd3a15ae705ff7cc3bc6ff934f6f9a",
    "submitter": {
        "id": 20,
        "url": "https://patches.dpdk.org/api/people/20/",
        "name": "Bruce Richardson",
        "email": "bruce.richardson@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/patch/74549/mbox/",
    "series": [
        {
            "id": 11200,
            "url": "https://patches.dpdk.org/api/series/11200/",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=11200",
            "date": "2020-07-21T09:51:20",
            "name": "raw/ioat: enhancements and new hardware support",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/11200/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/74549/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/74549/checks/",
    "tags": {},
    "headers": {
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9688\"; a=\"138191433\"",
            "E=Sophos;i=\"5.75,378,1589266800\"; d=\"scan'208\";a=\"138191433\"",
            "E=Sophos;i=\"5.75,378,1589266800\"; d=\"scan'208\";a=\"488024418\""
        ],
        "IronPort-SDR": [
            "\n HyjjM6CFnWr+hbGA8MoK5mBGU1iPpxMHQK/D080f4sjgrNhDxRqoUtZ+P40FfYa2qCE5J9eBOn\n uEySGq0ux2yg==",
            "\n IdakRBhEXu6LccmYX/9GdluEdcP92f2MnDB3YnJ39NBs5GEpPa0ai2cn+uEwtF4nZZ7mGsAMK/\n oo5H5bcXz+Yw=="
        ],
        "X-Amp-File-Uploaded": "False",
        "Precedence": "list",
        "X-Mailman-Version": "2.1.15",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "List-Post": "<mailto:dev@dpdk.org>",
        "MIME-Version": "1.0",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "X-BeenThere": "dev@dpdk.org",
        "References": "<20200721095140.719297-1-bruce.richardson@intel.com>",
        "Subject": "[dpdk-dev] [PATCH 20.11 10/20] raw/ioat: create rawdev instances on\n\tidxd PCI probe",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 4FE88A0526;\n\tTue, 21 Jul 2020 11:56:06 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 365731BFFE;\n\tTue, 21 Jul 2020 11:56:06 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n by dpdk.org (Postfix) with ESMTP id B8B881BFF9\n for <dev@dpdk.org>; Tue, 21 Jul 2020 11:56:04 +0200 (CEST)",
            "from fmsmga005.fm.intel.com ([10.253.24.32])\n by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 21 Jul 2020 02:56:03 -0700",
            "from silpixa00399126.ir.intel.com ([10.237.222.36])\n by fmsmga005.fm.intel.com with ESMTP; 21 Jul 2020 02:56:02 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "X-Mailer": "git-send-email 2.25.1",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "X-ExtLoop1": "1",
        "Date": "Tue, 21 Jul 2020 10:51:30 +0100",
        "Content-Transfer-Encoding": "8bit",
        "To": "dev@dpdk.org",
        "From": "Bruce Richardson <bruce.richardson@intel.com>",
        "In-Reply-To": "<20200721095140.719297-1-bruce.richardson@intel.com>",
        "Cc": "cheng1.jiang@intel.com, patrick.fu@intel.com, kevin.laatz@intel.com,\n Bruce Richardson <bruce.richardson@intel.com>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Message-Id": "<20200721095140.719297-11-bruce.richardson@intel.com>",
        "Return-Path": "<dev-bounces@dpdk.org>"
    },
    "content": "When a matching device is found via PCI probe create a rawdev instance for\neach queue on the hardware. Use empty self-test function for these devices\nso that the overall rawdev_autotest does not report failures.\n\nSigned-off-by: Bruce Richardson <bruce.richardson@intel.com>\n---\n drivers/raw/ioat/idxd_pci.c            | 235 ++++++++++++++++++++++++-\n drivers/raw/ioat/ioat_common.c         |  62 +++++++\n drivers/raw/ioat/ioat_private.h        |  37 ++++\n drivers/raw/ioat/ioat_rawdev_test.c    |   7 +\n drivers/raw/ioat/ioat_spec.h           |  52 ++++++\n drivers/raw/ioat/meson.build           |   1 +\n drivers/raw/ioat/rte_ioat_rawdev_fns.h |  35 +++-\n 7 files changed, 426 insertions(+), 3 deletions(-)\n create mode 100644 drivers/raw/ioat/ioat_common.c",
    "diff": "diff --git a/drivers/raw/ioat/idxd_pci.c b/drivers/raw/ioat/idxd_pci.c\nindex f6af9d33a..11c07efaa 100644\n--- a/drivers/raw/ioat/idxd_pci.c\n+++ b/drivers/raw/ioat/idxd_pci.c\n@@ -3,8 +3,10 @@\n  */\n \n #include <rte_bus_pci.h>\n+#include <rte_memzone.h>\n \n #include \"ioat_private.h\"\n+#include \"ioat_spec.h\"\n \n #define IDXD_VENDOR_ID\t\t0x8086\n #define IDXD_DEVICE_ID_SPR\t0x0B25\n@@ -16,17 +18,244 @@ const struct rte_pci_id pci_id_idxd_map[] = {\n \t{ .vendor_id = 0, /* sentinel */ },\n };\n \n+static inline int\n+idxd_pci_dev_command(struct idxd_rawdev *idxd, enum rte_idxd_cmds command)\n+{\n+\tuint8_t err_code;\n+\tuint16_t qid = idxd->qid;\n+\tint i = 0;\n+\n+\tif (command >= idxd_disable_wq && command <= idxd_reset_wq)\n+\t\tqid = (1 << qid);\n+\trte_spinlock_lock(&idxd->u.pci->lk);\n+\tidxd->u.pci->regs->cmd = (command << IDXD_CMD_SHIFT) | qid;\n+\n+\tdo {\n+\t\trte_pause();\n+\t\terr_code = idxd->u.pci->regs->cmdstatus;\n+\t\tif (++i >= 1000) {\n+\t\t\tIOAT_PMD_ERR(\"Timeout waiting for command response from HW\");\n+\t\t\trte_spinlock_unlock(&idxd->u.pci->lk);\n+\t\t\treturn err_code;\n+\t\t}\n+\t} while (idxd->u.pci->regs->cmdstatus & CMDSTATUS_ACTIVE_MASK);\n+\trte_spinlock_unlock(&idxd->u.pci->lk);\n+\n+\treturn err_code & CMDSTATUS_ERR_MASK;\n+}\n+\n+static int\n+idxd_is_wq_enabled(struct idxd_rawdev *idxd)\n+{\n+\tuint32_t state = (idxd->u.pci->wq_regs[idxd->qid].wqcfg[WQ_STATE_IDX] >> WQ_STATE_SHIFT);\n+\treturn (state & WQ_STATE_MASK) == 0x1;\n+}\n+\n+static const struct rte_rawdev_ops idxd_pci_ops = {\n+\t\t.dev_selftest = idxd_rawdev_test\n+};\n+\n+/* each portal uses 4 x 4k pages */\n+#define IDXD_PORTAL_SIZE (4096 * 4)\n+\n+static int\n+init_pci_device(struct rte_pci_device *dev, struct idxd_rawdev *idxd)\n+{\n+\tstruct idxd_pci_common *pci;\n+\tuint8_t nb_groups, nb_engines, nb_wqs;\n+\tuint16_t grp_offset, wq_offset; /* how far into bar0 the regs are */\n+\tuint16_t wq_size, total_wq_size;\n+\tuint8_t lg2_max_batch, lg2_max_copy_size;\n+\tunsigned int i, err_code;\n+\n+\tpci = malloc(sizeof(*pci));\n+\tif (pci == NULL) {\n+\t\tIOAT_PMD_ERR(\"%s: Can't allocate memory\", __func__);\n+\t\tgoto err;\n+\t}\n+\trte_spinlock_init(&pci->lk);\n+\n+\t/* assign the bar registers, and then configure device */\n+\tpci->regs = dev->mem_resource[0].addr;\n+\tgrp_offset = (uint16_t)pci->regs->offsets[0];\n+\tpci->grp_regs = RTE_PTR_ADD(pci->regs, grp_offset * 0x100);\n+\twq_offset = (uint16_t)(pci->regs->offsets[0] >> 16);\n+\tpci->wq_regs = RTE_PTR_ADD(pci->regs, wq_offset * 0x100);\n+\tpci->portals = dev->mem_resource[2].addr;\n+\n+\t/* sanity check device status */\n+\tif (pci->regs->gensts & GENSTS_DEV_STATE_MASK) {\n+\t\t/* need function-level-reset (FLR) or is enabled */\n+\t\tIOAT_PMD_ERR(\"Device status is not disabled, cannot init\");\n+\t\tgoto err;\n+\t}\n+\tif (pci->regs->cmdstatus & CMDSTATUS_ACTIVE_MASK) {\n+\t\t/* command in progress */\n+\t\tIOAT_PMD_ERR(\"Device has a command in progress, cannot init\");\n+\t\tgoto err;\n+\t}\n+\n+\t/* read basic info about the hardware for use when configuring */\n+\tnb_groups = (uint8_t)pci->regs->grpcap;\n+\tnb_engines = (uint8_t)pci->regs->engcap;\n+\tnb_wqs = (uint8_t)(pci->regs->wqcap >> 16);\n+\ttotal_wq_size = (uint16_t)pci->regs->wqcap;\n+\tlg2_max_copy_size = (uint8_t)(pci->regs->gencap >> 16) & 0x1F;\n+\tlg2_max_batch = (uint8_t)(pci->regs->gencap >> 21) & 0x0F;\n+\n+\tIOAT_PMD_DEBUG(\"nb_groups = %u, nb_engines = %u, nb_wqs = %u\",\n+\t\t\tnb_groups, nb_engines, nb_wqs);\n+\n+\t/* zero out any old config */\n+\tfor (i = 0; i < nb_groups; i++) {\n+\t\tpci->grp_regs[i].grpengcfg = 0;\n+\t\tpci->grp_regs[i].grpwqcfg[0] = 0;\n+\t}\n+\tfor (i = 0; i < nb_wqs; i++)\n+\t\tpci->wq_regs[i].wqcfg[0] = 0;\n+\n+\t/* put each engine into a separate group to avoid reordering */\n+\tif (nb_groups > nb_engines)\n+\t\tnb_groups = nb_engines;\n+\tif (nb_groups < nb_engines)\n+\t\tnb_engines = nb_groups;\n+\n+\t/* assign engines to groups, round-robin style */\n+\tfor (i = 0; i < nb_engines; i++) {\n+\t\tIOAT_PMD_DEBUG(\"Assigning engine %u to group %u\",\n+\t\t\t\ti, i % nb_groups);\n+\t\tpci->grp_regs[i % nb_groups].grpengcfg |= (1ULL << i);\n+\t}\n+\n+\t/* now do the same for queues and give work slots to each queue */\n+\twq_size = total_wq_size / nb_wqs;\n+\tIOAT_PMD_DEBUG(\"Work queue size = %u, max batch = 2^%u, max copy = 2^%u\",\n+\t\t\twq_size, lg2_max_batch, lg2_max_copy_size);\n+\tfor (i = 0; i < nb_wqs; i++) {\n+\t\t/* add engine \"i\" to a group */\n+\t\tIOAT_PMD_DEBUG(\"Assigning work queue %u to group %u\",\n+\t\t\t\ti, i % nb_groups);\n+\t\tpci->grp_regs[i % nb_groups].grpwqcfg[0] |= (1ULL << i);\n+\t\t/* now configure it, in terms of size, max batch, mode */\n+\t\tpci->wq_regs[i].wqcfg[0] = wq_size;\n+\t\tpci->wq_regs[i].wqcfg[2] = 0x11; /* TODO: use defines - dedicated mode, priority 1 */\n+\t\tpci->wq_regs[i].wqcfg[3] = (lg2_max_batch << 5) |\n+\t\t\t\tlg2_max_copy_size;\n+\t}\n+\n+\t/* dump the group configuration to output */\n+\tfor (i = 0; i < nb_groups; i++) {\n+\t\tIOAT_PMD_DEBUG(\"## Group %d\", i);\n+\t\tIOAT_PMD_DEBUG(\"    GRPWQCFG: %\"PRIx64, pci->grp_regs[i].grpwqcfg[0]);\n+\t\tIOAT_PMD_DEBUG(\"    GRPENGCFG: %\"PRIx64, pci->grp_regs[i].grpengcfg);\n+\t\tIOAT_PMD_DEBUG(\"    GRPFLAGS: %\"PRIx32, pci->grp_regs[i].grpflags);\n+\t}\n+\n+\tidxd->u.pci = pci;\n+\tidxd->max_batches = wq_size;\n+\n+\t/* enable the device itself */\n+\terr_code = idxd_pci_dev_command(idxd, idxd_enable_dev);\n+\tif (err_code) {\n+\t\tIOAT_PMD_ERR(\"Error enabling device: code %#x\", err_code);\n+\t\treturn err_code;\n+\t}\n+\tIOAT_PMD_DEBUG(\"IDXD Device enabled OK\");\n+\n+\treturn nb_wqs;\n+\n+err:\n+\tfree(pci);\n+\treturn -1;\n+}\n+\n static int\n idxd_rawdev_probe_pci(struct rte_pci_driver *drv, struct rte_pci_device *dev)\n {\n-\tint ret = 0;\n+\tstruct idxd_rawdev idxd = {0};\n+\tuint8_t nb_wqs;\n+\tint qid, ret = 0;\n \tchar name[32];\n \n \trte_pci_device_name(&dev->addr, name, sizeof(name));\n \tIOAT_PMD_INFO(\"Init %s on NUMA node %d\", name, dev->device.numa_node);\n \tdev->device.driver = &drv->driver;\n \n-\treturn ret;\n+\tret = init_pci_device(dev, &idxd);\n+\tif (ret < 0) {\n+\t\tIOAT_PMD_ERR(\"Error initializing PCI hardware\");\n+\t\treturn ret;\n+\t}\n+\tnb_wqs = (uint8_t)ret;\n+\n+\t/* set up one device for each queue */\n+\tfor (qid = 0; qid < nb_wqs; qid++) {\n+\t\tchar qname[32];\n+\n+\t\t/* add the queue number to each device name */\n+\t\tsnprintf(qname, sizeof(qname), \"%s-q%d\", name, qid);\n+\t\tidxd.qid = qid;\n+\t\tidxd.public.portal = RTE_PTR_ADD(idxd.u.pci->portals,\n+\t\t\t\tqid * IDXD_PORTAL_SIZE);\n+\t\tif (idxd_is_wq_enabled(&idxd))\n+\t\t\tIOAT_PMD_ERR(\"Error, WQ %u seems enabled\", qid);\n+\t\tret = idxd_rawdev_create(qname, &dev->device,\n+\t\t\t\t&idxd, &idxd_pci_ops);\n+\t\tif (ret != 0){\n+\t\t\tIOAT_PMD_ERR(\"Failed to create rawdev %s\", name);\n+\t\t\tif (qid == 0) /* if no devices using this, free pci */\n+\t\t\t\tfree(idxd.u.pci);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+idxd_rawdev_destroy(const char *name)\n+{\n+\tint ret;\n+\tuint8_t err_code;\n+\tstruct rte_rawdev *rdev;\n+\tstruct idxd_rawdev *idxd;\n+\n+\tif (!name) {\n+\t\tIOAT_PMD_ERR(\"Invalid device name\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\trdev = rte_rawdev_pmd_get_named_dev(name);\n+\tif (!rdev) {\n+\t\tIOAT_PMD_ERR(\"Invalid device name (%s)\", name);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tidxd = rdev->dev_private;\n+\n+\t/* disable the device */\n+\terr_code = idxd_pci_dev_command(idxd, idxd_disable_dev);\n+\tif (err_code) {\n+\t\tIOAT_PMD_ERR(\"Error disabling device: code %#x\", err_code);\n+\t\treturn err_code;\n+\t}\n+\tIOAT_PMD_DEBUG(\"IDXD Device disabled OK\");\n+\n+\t/* free device memory */\n+\tif (rdev->dev_private != NULL) {\n+\t\tIOAT_PMD_DEBUG(\"Freeing device driver memory\");\n+\t\trdev->dev_private = NULL;\n+\t\trte_free(idxd->public.batch_ring);\n+\t\trte_free(idxd->public.hdl_ring);\n+\t\trte_memzone_free(idxd->mz);\n+\t}\n+\n+\t/* rte_rawdev_close is called by pmd_release */\n+\tret = rte_rawdev_pmd_release(rdev);\n+\tif (ret)\n+\t\tIOAT_PMD_DEBUG(\"Device cleanup failed\");\n+\n+\treturn 0;\n }\n \n static int\n@@ -39,6 +268,8 @@ idxd_rawdev_remove_pci(struct rte_pci_device *dev)\n \n \tIOAT_PMD_INFO(\"Closing %s on NUMA node %d\", name, dev->device.numa_node);\n \n+\tret = idxd_rawdev_destroy(name);\n+\n \treturn ret;\n }\n \ndiff --git a/drivers/raw/ioat/ioat_common.c b/drivers/raw/ioat/ioat_common.c\nnew file mode 100644\nindex 000000000..4397be886\n--- /dev/null\n+++ b/drivers/raw/ioat/ioat_common.c\n@@ -0,0 +1,62 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+\n+#include <rte_rawdev_pmd.h>\n+#include <rte_memzone.h>\n+\n+#include \"ioat_private.h\"\n+\n+int\n+idxd_rawdev_create(const char *name, struct rte_device *dev,\n+\t\t   const struct idxd_rawdev *base_idxd,\n+\t\t   const struct rte_rawdev_ops *ops)\n+{\n+\tstruct idxd_rawdev *idxd;\n+\tstruct rte_rawdev *rawdev = NULL;\n+\tconst struct rte_memzone *mz = NULL;\n+\tchar mz_name[RTE_MEMZONE_NAMESIZE];\n+\tint ret = 0;\n+\n+\tif (!name) {\n+\t\tIOAT_PMD_ERR(\"Invalid name of the device!\");\n+\t\tret = -EINVAL;\n+\t\tgoto cleanup;\n+\t}\n+\n+\t/* Allocate device structure */\n+\trawdev = rte_rawdev_pmd_allocate(name, sizeof(struct idxd_rawdev),\n+\t\t\t\t\t dev->numa_node);\n+\tif (rawdev == NULL) {\n+\t\tIOAT_PMD_ERR(\"Unable to allocate raw device\");\n+\t\tret = -ENOMEM;\n+\t\tgoto cleanup;\n+\t}\n+\n+\tsnprintf(mz_name, sizeof(mz_name), \"rawdev%u_private\", rawdev->dev_id);\n+\tmz = rte_memzone_reserve(mz_name, sizeof(struct idxd_rawdev),\n+\t\t\tdev->numa_node, RTE_MEMZONE_IOVA_CONTIG);\n+\tif (mz == NULL) {\n+\t\tIOAT_PMD_ERR(\"Unable to reserve memzone for private data\\n\");\n+\t\tret = -ENOMEM;\n+\t\tgoto cleanup;\n+\t}\n+\trawdev->dev_private = mz->addr;\n+\trawdev->dev_ops = ops;\n+\trawdev->device = dev;\n+\trawdev->driver_name = RTE_STR(IOAT_PMD_RAWDEV_NAME);\n+\n+\tidxd = rawdev->dev_private;\n+\t*idxd = *base_idxd; /* copy over the main fields already passed in */\n+\tidxd->rawdev = rawdev;\n+\tidxd->mz = mz;\n+\n+\treturn 0;\n+\n+cleanup:\n+\tif (rawdev)\n+\t\trte_rawdev_pmd_release(rawdev);\n+\n+\treturn ret;\n+}\n+\ndiff --git a/drivers/raw/ioat/ioat_private.h b/drivers/raw/ioat/ioat_private.h\nindex d87d4d055..2ddaddc37 100644\n--- a/drivers/raw/ioat/ioat_private.h\n+++ b/drivers/raw/ioat/ioat_private.h\n@@ -14,6 +14,10 @@\n  * @b EXPERIMENTAL: these structures and APIs may change without prior notice\n  */\n \n+#include <rte_spinlock.h>\n+#include <rte_rawdev_pmd.h>\n+#include \"rte_ioat_rawdev.h\"\n+\n extern int ioat_pmd_logtype;\n \n #define IOAT_PMD_LOG(level, fmt, args...) rte_log(RTE_LOG_ ## level, \\\n@@ -24,4 +28,37 @@ extern int ioat_pmd_logtype;\n #define IOAT_PMD_ERR(fmt, args...)    IOAT_PMD_LOG(ERR, fmt, ## args)\n #define IOAT_PMD_WARN(fmt, args...)   IOAT_PMD_LOG(WARNING, fmt, ## args)\n \n+struct idxd_pci_common {\n+\trte_spinlock_t lk;\n+\tvolatile struct rte_idxd_bar0 *regs;\n+\tvolatile struct rte_idxd_wqcfg *wq_regs;\n+\tvolatile struct rte_idxd_grpcfg *grp_regs;\n+\tvolatile void *portals;\n+};\n+\n+struct idxd_rawdev {\n+\tstruct rte_idxd_rawdev public; /* the public members, must be first */\n+\n+\tstruct rte_rawdev *rawdev;\n+\tconst struct rte_memzone *mz;\n+\tuint8_t qid;\n+\tuint16_t max_batches;\n+\n+\tunion {\n+\t\tstruct {\n+\t\t\tstruct accfg_ctx *ctx;\n+\t\t\tstruct accfg_device *device;\n+\t\t\tstruct accfg_wq *wq;\n+\t\t} vdev;\n+\n+\t\tstruct idxd_pci_common *pci;\n+\t} u;\n+};\n+\n+extern int idxd_rawdev_create(const char *name, struct rte_device *dev,\n+\t\t       const struct idxd_rawdev *idxd,\n+\t\t       const struct rte_rawdev_ops *ops);\n+\n+extern int idxd_rawdev_test(uint16_t dev_id);\n+\n #endif /* _IOAT_PRIVATE_H_ */\ndiff --git a/drivers/raw/ioat/ioat_rawdev_test.c b/drivers/raw/ioat/ioat_rawdev_test.c\nindex e5b50ae9f..b208b8c19 100644\n--- a/drivers/raw/ioat/ioat_rawdev_test.c\n+++ b/drivers/raw/ioat/ioat_rawdev_test.c\n@@ -7,6 +7,7 @@\n #include <rte_mbuf.h>\n #include \"rte_rawdev.h\"\n #include \"rte_ioat_rawdev.h\"\n+#include \"ioat_private.h\"\n \n #define MAX_SUPPORTED_RAWDEVS 64\n #define TEST_SKIPPED 77\n@@ -252,3 +253,9 @@ ioat_rawdev_test(uint16_t dev_id)\n \tfree(ids);\n \treturn -1;\n }\n+\n+int\n+idxd_rawdev_test(uint16_t dev_id __rte_unused)\n+{\n+\treturn 0;\n+}\ndiff --git a/drivers/raw/ioat/ioat_spec.h b/drivers/raw/ioat/ioat_spec.h\nindex 9645e16d4..b865fc0ec 100644\n--- a/drivers/raw/ioat/ioat_spec.h\n+++ b/drivers/raw/ioat/ioat_spec.h\n@@ -268,6 +268,58 @@ union rte_ioat_hw_desc {\n \tstruct rte_ioat_pq_update_hw_desc pq_update;\n };\n \n+/*** Definitions for Intel(R) Data Streaming Accelerator Follow ***/\n+\n+#define IDXD_CMD_SHIFT 20\n+enum rte_idxd_cmds {\n+\tidxd_enable_dev = 1,\n+\tidxd_disable_dev,\n+\tidxd_drain_all,\n+\tidxd_abort_all,\n+\tidxd_reset_device,\n+\tidxd_enable_wq,\n+\tidxd_disable_wq,\n+\tidxd_drain_wq,\n+\tidxd_abort_wq,\n+\tidxd_reset_wq,\n+};\n+\n+/* General bar0 registers */\n+struct rte_idxd_bar0 {\n+\tuint32_t version    __rte_cache_aligned; /* offset 0x00 */\n+\tuint64_t gencap     __rte_aligned(0x10); /* offset 0x10 */\n+\tuint64_t wqcap      __rte_aligned(0x10); /* offset 0x20 */\n+\tuint64_t grpcap     __rte_aligned(0x10); /* offset 0x30 */\n+\tuint64_t engcap     __rte_aligned(0x08); /* offset 0x38 */\n+\tuint64_t opcap      __rte_aligned(0x10); /* offset 0x40 */\n+\tuint64_t offsets[2] __rte_aligned(0x20); /* offset 0x60 */\n+\tuint32_t gencfg     __rte_aligned(0x20); /* offset 0x80 */\n+\tuint32_t genctrl    __rte_aligned(0x08); /* offset 0x88 */\n+\tuint32_t gensts     __rte_aligned(0x10); /* offset 0x90 */\n+\tuint32_t intcause   __rte_aligned(0x08); /* offset 0x98 */\n+\tuint32_t cmd        __rte_aligned(0x10); /* offset 0xA0 */\n+\tuint32_t cmdstatus  __rte_aligned(0x08); /* offset 0xA8 */\n+\tuint64_t swerror[4] __rte_aligned(0x20); /* offset 0xC0 */\n+};\n+\n+struct rte_idxd_wqcfg {\n+\tuint32_t wqcfg[8] __rte_aligned(32); /* 32-byte register */\n+};\n+#define WQ_STATE_IDX    6 /* 7th 32-bit value in array */\n+#define WQ_STATE_SHIFT 30\n+#define WQ_STATE_MASK 0x3\n+\n+struct rte_idxd_grpcfg {\n+\tuint64_t grpwqcfg[4]  __rte_cache_aligned; /* 64-byte register set */\n+\tuint64_t grpengcfg;  /* offset 32 */\n+\tuint32_t grpflags;   /* offset 40 */\n+};\n+\n+#define GENSTS_DEV_STATE_MASK 0x03\n+#define CMDSTATUS_ACTIVE_SHIFT 31\n+#define CMDSTATUS_ACTIVE_MASK (1 << 31)\n+#define CMDSTATUS_ERR_MASK 0xFF\n+\n #ifdef __cplusplus\n }\n #endif\ndiff --git a/drivers/raw/ioat/meson.build b/drivers/raw/ioat/meson.build\nindex b343b7367..5eff76a1a 100644\n--- a/drivers/raw/ioat/meson.build\n+++ b/drivers/raw/ioat/meson.build\n@@ -6,6 +6,7 @@ reason = 'only supported on x86'\n sources = files(\n \t'idxd_pci.c',\n \t'idxd_vdev.c',\n+\t'ioat_common.c',\n \t'ioat_rawdev.c',\n \t'ioat_rawdev_test.c')\n deps += ['bus_pci',\ndiff --git a/drivers/raw/ioat/rte_ioat_rawdev_fns.h b/drivers/raw/ioat/rte_ioat_rawdev_fns.h\nindex 0cee6b1b0..aca91dd4f 100644\n--- a/drivers/raw/ioat/rte_ioat_rawdev_fns.h\n+++ b/drivers/raw/ioat/rte_ioat_rawdev_fns.h\n@@ -39,9 +39,20 @@ struct rte_ioat_generic_hw_desc {\n \n /**\n  * @internal\n- * Structure representing a device instance\n+ * Identify the data path to use.\n+ * Must be first field of rte_ioat_rawdev and rte_idxd_rawdev structs\n+ */\n+enum rte_ioat_dev_type {\n+\tRTE_IOAT_DEV,\n+\tRTE_IDXD_DEV,\n+};\n+\n+/**\n+ * @internal\n+ * Structure representing an IOAT device instance  * Structure representing a device instance\n  */\n struct rte_ioat_rawdev {\n+\tenum rte_ioat_dev_type type;\n \tstruct rte_rawdev *rawdev;\n \tconst struct rte_memzone *mz;\n \tconst struct rte_memzone *desc_mz;\n@@ -77,6 +88,28 @@ struct rte_ioat_rawdev {\n #define RTE_IOAT_CHANSTS_HALTED\t\t0x3\n #define RTE_IOAT_CHANSTS_ARMED\t\t\t0x4\n \n+/**\n+ * @internal\n+ * Structure representing an IDXD device instance\n+ */\n+struct rte_idxd_rawdev {\n+\tenum rte_ioat_dev_type type;\n+\tvoid *portal; /* address to write the batch descriptor */\n+\n+\t/* counters to track the batches and the individual op handles */\n+\tuint16_t batch_ring_sz;  /* size of batch ring */\n+\tuint16_t hdl_ring_sz;    /* size of the user hdl ring */\n+\n+\tuint16_t next_batch;     /* where we write descriptor ops */\n+\tuint16_t next_completed; /* batch where we read completions */\n+\tuint16_t next_ret_hdl;   /* the next user hdl to return */\n+\tuint16_t last_completed_hdl; /* the last user hdl that has completed */\n+\tuint16_t next_free_hdl;  /* where the handle for next op will go */\n+\n+\tstruct rte_idxd_user_hdl *hdl_ring;\n+\tstruct rte_idxd_desc_batch *batch_ring;\n+};\n+\n /**\n  * Enqueue a copy operation onto the ioat device\n  */\n",
    "prefixes": [
        "20.11",
        "10/20"
    ]
}