From patchwork Fri Sep 3 11:17:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Conor Walsh X-Patchwork-Id: 97904 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: 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]) by inbox.dpdk.org (Postfix) with ESMTP id 7A8C8A0C54; Fri, 3 Sep 2021 13:18:06 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CD49D4113E; Fri, 3 Sep 2021 13:17:48 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mails.dpdk.org (Postfix) with ESMTP id 03E1C41123 for ; Fri, 3 Sep 2021 13:17:46 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10095"; a="217533955" X-IronPort-AV: E=Sophos;i="5.85,265,1624345200"; d="scan'208";a="217533955" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Sep 2021 04:17:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.85,265,1624345200"; d="scan'208";a="500322823" Received: from silpixa00401160.ir.intel.com ([10.55.128.248]) by fmsmga008.fm.intel.com with ESMTP; 03 Sep 2021 04:17:44 -0700 From: Conor Walsh To: bruce.richardson@intel.com, fengchengwen@huawei.com, jerinj@marvell.com, kevin.laatz@intel.com Cc: dev@dpdk.org, Conor Walsh Date: Fri, 3 Sep 2021 11:17:28 +0000 Message-Id: <20210903111734.2734545-5-conor.walsh@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210903111734.2734545-1-conor.walsh@intel.com> References: <20210827172550.1522362-1-conor.walsh@intel.com> <20210903111734.2734545-1-conor.walsh@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 04/10] dma/ioat: add configuration functions X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add functions for device configuration. The info_get and close functions are included here also. info_get can be useful for checking successful configuration and close is used by the dmadev api when releasing a configured device. Signed-off-by: Conor Walsh Reviewed-by: Kevin Laatz --- doc/guides/dmadevs/ioat.rst | 24 ++++++++++ drivers/dma/ioat/ioat_dmadev.c | 88 ++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/doc/guides/dmadevs/ioat.rst b/doc/guides/dmadevs/ioat.rst index 45a2e65d70..b6d88fe966 100644 --- a/doc/guides/dmadevs/ioat.rst +++ b/doc/guides/dmadevs/ioat.rst @@ -62,3 +62,27 @@ For example:: Once probed successfully, the device will appear as a ``dmadev``, that is a "DMA device type" inside DPDK, and can be accessed using APIs from the ``rte_dmadev`` library. + +Device Configuration +~~~~~~~~~~~~~~~~~~~~~ + +Configuring an IOAT dmadev device is done using the ``rte_dmadev_configure()`` +and ``rte_dmadev_vchan_setup()`` APIs. ``rte_dmadev_configure()`` uses the structure +``rte_dmadev_conf`` to configure an IOAT device, within this struct the number +of virtual DMA channels for the device is set and silent mode can be enabled. +Each IOAT device can only use 1 virtual DMA channel and silent mode is not +supported so these will always be set to ``1`` and ``false``. +``rte_dmadev_vchan_setup()`` uses the structure ``rte_dmadev_vchan_conf`` to setup +a virtual DMA channel within this struct the transfer direction and ring size +are set. Generally for an onboard Intel\ |reg| IOAT device the transfer direction +will be set to ``RTE_DMA_DIR_MEM_TO_MEM`` to copy from memory to memory (more info +available in the dmadev API guide). The ring size must be a power of two, between +64 and 4096. + +The following code shows how the device is configured in ``test_dmadev.c``: + +.. literalinclude:: ../../../app/test/test_dmadev.c + :language: c + :start-after: Setup of the dmadev device. 8< + :end-before: >8 End of setup of the dmadev device. + :dedent: 1 diff --git a/drivers/dma/ioat/ioat_dmadev.c b/drivers/dma/ioat/ioat_dmadev.c index d65881d852..94f9139e0d 100644 --- a/drivers/dma/ioat/ioat_dmadev.c +++ b/drivers/dma/ioat/ioat_dmadev.c @@ -12,9 +12,93 @@ static struct rte_pci_driver ioat_pmd_drv; RTE_LOG_REGISTER_DEFAULT(ioat_pmd_logtype, INFO); +#define DESC_SZ sizeof(struct ioat_dma_hw_desc) + #define IOAT_PMD_NAME dmadev_ioat #define IOAT_PMD_NAME_STR RTE_STR(IOAT_PMD_NAME) +/* Configure a device. */ +static int +ioat_dev_configure(struct rte_dmadev *dev __rte_unused, const struct rte_dmadev_conf *dev_conf) +{ + if (dev_conf->nb_vchans != 1) + return -EINVAL; + return 0; +} + +/* Setup a virtual channel for IOAT, only 1 vchan is supported. */ +static int +ioat_vchan_setup(struct rte_dmadev *dev, uint16_t vchan __rte_unused, + const struct rte_dmadev_vchan_conf *qconf) +{ + struct ioat_dmadev *ioat = dev->dev_private; + uint16_t max_desc = qconf->nb_desc; + int i; + + ioat->qcfg = *qconf; + + if (!rte_is_power_of_2(max_desc)) { + max_desc = rte_align32pow2(max_desc); + IOAT_PMD_DEBUG("DMA dev %u using %u descriptors", dev->data->dev_id, max_desc); + ioat->qcfg.nb_desc = max_desc; + } + + /* In case we are reconfiguring a device, free any existing memory. */ + rte_free(ioat->desc_ring); + + ioat->desc_ring = rte_zmalloc(NULL, sizeof(*ioat->desc_ring) * max_desc, 0); + if (ioat->desc_ring == NULL) + return -ENOMEM; + + ioat->ring_addr = rte_mem_virt2iova(ioat->desc_ring); + + ioat->status_addr = rte_mem_virt2iova(ioat) + offsetof(struct ioat_dmadev, status); + + /* Ensure all counters are reset, if reconfiguring/restarting device. */ + ioat->next_read = 0; + ioat->next_write = 0; + ioat->last_write = 0; + ioat->offset = 0; + ioat->failure = 0; + + /* Reset Stats. */ + memset(&ioat->stats, 0, sizeof(ioat->stats)); + + /* Configure descriptor ring - each one points to next. */ + for (i = 0; i < ioat->qcfg.nb_desc; i++) { + ioat->desc_ring[i].next = ioat->ring_addr + + (((i + 1) % ioat->qcfg.nb_desc) * DESC_SZ); + } + + return 0; +} + +/* Get device information of a device. */ +static int +ioat_dev_info_get(const struct rte_dmadev *dev, struct rte_dmadev_info *info, uint32_t size) +{ + struct ioat_dmadev *ioat = dev->dev_private; + + if (size < sizeof(*info)) + return -EINVAL; + info->device = dev->device; + info->dev_capa = RTE_DMADEV_CAPA_MEM_TO_MEM | + RTE_DMADEV_CAPA_OPS_COPY | RTE_DMADEV_CAPA_OPS_FILL, + info->max_vchans = 1; + info->min_desc = 32; + info->max_desc = 4096; + info->nb_vchans = (ioat->desc_ring == NULL); + return 0; +} + +/* Close a configured device. */ +static int +ioat_dev_close(struct rte_dmadev *dev) +{ + RTE_SET_USED(dev); + return 0; +} + /* Dump DMA device info. */ static int ioat_dev_dump(const struct rte_dmadev *dev, FILE *f) @@ -77,7 +161,11 @@ static int ioat_dmadev_create(const char *name, struct rte_pci_device *dev) { static const struct rte_dmadev_ops ioat_dmadev_ops = { + .dev_close = ioat_dev_close, + .dev_configure = ioat_dev_configure, .dev_dump = ioat_dev_dump, + .dev_info_get = ioat_dev_info_get, + .vchan_setup = ioat_vchan_setup, }; struct rte_dmadev *dmadev = NULL;