From patchwork Tue Nov 2 12:37:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: fengchengwen X-Patchwork-Id: 103480 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 B8AC7A0C4E; Tue, 2 Nov 2021 13:42:29 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id EE1894069F; Tue, 2 Nov 2021 13:42:24 +0100 (CET) Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by mails.dpdk.org (Postfix) with ESMTP id 573FA4068F for ; Tue, 2 Nov 2021 13:42:22 +0100 (CET) Received: from dggemv711-chm.china.huawei.com (unknown [172.30.72.54]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4Hk8cv03nfzZcgP; Tue, 2 Nov 2021 20:40:15 +0800 (CST) Received: from dggpeml500024.china.huawei.com (7.185.36.10) by dggemv711-chm.china.huawei.com (10.1.198.66) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Tue, 2 Nov 2021 20:42:18 +0800 Received: from localhost.localdomain (10.67.165.24) by dggpeml500024.china.huawei.com (7.185.36.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Tue, 2 Nov 2021 20:42:18 +0800 From: Chengwen Feng To: CC: Date: Tue, 2 Nov 2021 20:37:38 +0800 Message-ID: <20211102123743.13497-2-fengchengwen@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211102123743.13497-1-fengchengwen@huawei.com> References: <20211030103619.29924-1-fengchengwen@huawei.com> <20211102123743.13497-1-fengchengwen@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.165.24] X-ClientProxiedBy: dggems702-chm.china.huawei.com (10.3.19.179) To dggpeml500024.china.huawei.com (7.185.36.10) X-CFilter-Loop: Reflected Subject: [dpdk-dev] [PATCH v2 1/6] dma/hisilicon: add device probe and remove 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 the basic device probe and remove functions and initial documentation for new hisilicon DMA drivers. Maintainers update is also included in this patch. Signed-off-by: Chengwen Feng --- MAINTAINERS | 5 ++ doc/guides/dmadevs/hisilicon.rst | 21 +++++ doc/guides/dmadevs/index.rst | 1 + doc/guides/rel_notes/release_21_11.rst | 4 + drivers/dma/hisilicon/hisi_dmadev.c | 119 +++++++++++++++++++++++++ drivers/dma/hisilicon/hisi_dmadev.h | 24 +++++ drivers/dma/hisilicon/meson.build | 19 ++++ drivers/dma/hisilicon/version.map | 3 + drivers/dma/meson.build | 1 + 9 files changed, 197 insertions(+) create mode 100644 doc/guides/dmadevs/hisilicon.rst create mode 100644 drivers/dma/hisilicon/hisi_dmadev.c create mode 100644 drivers/dma/hisilicon/hisi_dmadev.h create mode 100644 drivers/dma/hisilicon/meson.build create mode 100644 drivers/dma/hisilicon/version.map diff --git a/MAINTAINERS b/MAINTAINERS index 0e5951f8f1..1567f7b695 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1206,6 +1206,11 @@ M: Conor Walsh F: drivers/dma/ioat/ F: doc/guides/dmadevs/ioat.rst +Hisilicon DMA +M: Chengwen Feng +F: drivers/dma/hisilicon +F: doc/guides/dmadevs/hisilicon.rst + RegEx Drivers ------------- diff --git a/doc/guides/dmadevs/hisilicon.rst b/doc/guides/dmadevs/hisilicon.rst new file mode 100644 index 0000000000..4cbaac4204 --- /dev/null +++ b/doc/guides/dmadevs/hisilicon.rst @@ -0,0 +1,21 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright(c) 2021 HiSilicon Limited. + +HISILICON Kunpeng DMA Driver +============================ + +Kunpeng SoC has an internal DMA unit which can be used by application to +accelerate data copies. The DMA PF function supports multiple DMA channels. + + +Supported Kunpeng SoCs +---------------------- + +* Kunpeng 920 + + +Device Setup +------------- + +Kunpeng DMA devices will need to be bound to a suitable DPDK-supported +user-space IO driver such as ``vfio-pci`` in order to be used by DPDK. diff --git a/doc/guides/dmadevs/index.rst b/doc/guides/dmadevs/index.rst index 20476039a5..6b04276524 100644 --- a/doc/guides/dmadevs/index.rst +++ b/doc/guides/dmadevs/index.rst @@ -13,3 +13,4 @@ an application through DMA API. idxd ioat + hisilicon diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst index 502cc5ceb2..00a45475be 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -86,6 +86,10 @@ New Features driver for Intel IOAT devices such as Crystal Beach DMA (CBDMA) on Ice Lake, Skylake and Broadwell. This device driver can be used through the generic dmadev API. +* **Added hisilicon dmadev driver implementation.** + The hisilicon dmadev driver provide device drivers for the Kunpeng's DMA devices. + This device driver can be used through the generic dmadev API. + * **Added support to get all MAC addresses of a device.** Added ``rte_eth_macaddrs_get`` to allow user to retrieve all Ethernet diff --git a/drivers/dma/hisilicon/hisi_dmadev.c b/drivers/dma/hisilicon/hisi_dmadev.c new file mode 100644 index 0000000000..e6fb8a0fc8 --- /dev/null +++ b/drivers/dma/hisilicon/hisi_dmadev.c @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 HiSilicon Limited + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "hisi_dmadev.h" + +RTE_LOG_REGISTER_DEFAULT(hisi_dma_logtype, INFO); +#define HISI_DMA_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, hisi_dma_logtype, \ + "%s(): " fmt "\n", __func__, ##args) +#define HISI_DMA_LOG_RAW(hw, level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, hisi_dma_logtype, \ + "%s %s(): " fmt "\n", (hw)->data->dev_name, \ + __func__, ##args) +#define HISI_DMA_DEBUG(hw, fmt, args...) \ + HISI_DMA_LOG_RAW(hw, DEBUG, fmt, ## args) +#define HISI_DMA_INFO(hw, fmt, args...) \ + HISI_DMA_LOG_RAW(hw, INFO, fmt, ## args) +#define HISI_DMA_WARN(hw, fmt, args...) \ + HISI_DMA_LOG_RAW(hw, WARNING, fmt, ## args) +#define HISI_DMA_ERR(hw, fmt, args...) \ + HISI_DMA_LOG_RAW(hw, ERR, fmt, ## args) + +static uint8_t +hisi_dma_reg_layout(uint8_t revision) +{ + if (revision == HISI_DMA_REVISION_HIP08B) + return HISI_DMA_REG_LAYOUT_HIP08; + else + return HISI_DMA_REG_LAYOUT_INVALID; +} + +static void +hisi_dma_gen_pci_device_name(const struct rte_pci_device *pci_dev, + char *name, size_t size) +{ + memset(name, 0, size); + (void)snprintf(name, size, "%x:%x.%x", + pci_dev->addr.bus, pci_dev->addr.devid, + pci_dev->addr.function); +} + +static int +hisi_dma_check_revision(struct rte_pci_device *pci_dev, const char *name, + uint8_t *out_revision) +{ + uint8_t revision; + int ret; + + ret = rte_pci_read_config(pci_dev, &revision, 1, + HISI_DMA_PCI_REVISION_ID_REG); + if (ret != 1) { + HISI_DMA_LOG(ERR, "%s read PCI revision failed!", name); + return -EINVAL; + } + if (hisi_dma_reg_layout(revision) == HISI_DMA_REG_LAYOUT_INVALID) { + HISI_DMA_LOG(ERR, "%s revision: 0x%x not supported!", + name, revision); + return -EINVAL; + } + + *out_revision = revision; + return 0; +} + +static int +hisi_dma_probe(struct rte_pci_driver *pci_drv __rte_unused, + struct rte_pci_device *pci_dev) +{ + char name[RTE_DEV_NAME_MAX_LEN] = { 0 }; + uint8_t revision; + int ret; + + hisi_dma_gen_pci_device_name(pci_dev, name, sizeof(name)); + + if (pci_dev->mem_resource[2].addr == NULL) { + HISI_DMA_LOG(ERR, "%s BAR2 is NULL!\n", name); + return -ENODEV; + } + + ret = hisi_dma_check_revision(pci_dev, name, &revision); + if (ret) + return ret; + HISI_DMA_LOG(DEBUG, "%s read PCI revision: 0x%x", name, revision); + + return ret; +} + +static int +hisi_dma_remove(struct rte_pci_device *pci_dev) +{ + RTE_SET_USED(pci_dev); + return 0; +} + +static const struct rte_pci_id pci_id_hisi_dma_map[] = { + { RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HISI_DMA_DEVICE_ID) }, + { .vendor_id = 0, }, /* sentinel */ +}; + +static struct rte_pci_driver hisi_dma_pmd_drv = { + .id_table = pci_id_hisi_dma_map, + .drv_flags = RTE_PCI_DRV_NEED_MAPPING, + .probe = hisi_dma_probe, + .remove = hisi_dma_remove, +}; + +RTE_PMD_REGISTER_PCI(dma_hisilicon, hisi_dma_pmd_drv); +RTE_PMD_REGISTER_PCI_TABLE(dma_hisilicon, pci_id_hisi_dma_map); +RTE_PMD_REGISTER_KMOD_DEP(dma_hisilicon, "vfio-pci"); diff --git a/drivers/dma/hisilicon/hisi_dmadev.h b/drivers/dma/hisilicon/hisi_dmadev.h new file mode 100644 index 0000000000..114b9dcb5b --- /dev/null +++ b/drivers/dma/hisilicon/hisi_dmadev.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 HiSilicon Limited + */ + +#ifndef HISI_DMADEV_H +#define HISI_DMADEV_H + +#define PCI_VENDOR_ID_HUAWEI 0x19e5 +#define HISI_DMA_DEVICE_ID 0xA122 +#define HISI_DMA_PCI_REVISION_ID_REG 0x08 +#define HISI_DMA_REVISION_HIP08B 0x21 + +/** + * The HIP08B(HiSilicon IP08) and later Chip(e.g. HiSilicon IP09) are DMA iEPs, + * they have the same pci device id but with different pci revision. + * Unfortunately, they have different register layouts, so the layout + * enumerations are defined. + */ +enum { + HISI_DMA_REG_LAYOUT_INVALID = 0, + HISI_DMA_REG_LAYOUT_HIP08 +}; + +#endif /* HISI_DMADEV_H */ diff --git a/drivers/dma/hisilicon/meson.build b/drivers/dma/hisilicon/meson.build new file mode 100644 index 0000000000..0786772442 --- /dev/null +++ b/drivers/dma/hisilicon/meson.build @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2021 HiSilicon Limited + +if not is_linux + build = false + reason = 'only supported on Linux' + subdir_done() +endif + +if (arch_subdir != 'x86' and arch_subdir != 'arm') or (not dpdk_conf.get('RTE_ARCH_64')) + build = false + reason = 'only supported on x86_64 and aarch64' + subdir_done() +endif + +deps += ['bus_pci', 'dmadev'] +sources = files( + 'hisi_dmadev.c', +) diff --git a/drivers/dma/hisilicon/version.map b/drivers/dma/hisilicon/version.map new file mode 100644 index 0000000000..c2e0723b4c --- /dev/null +++ b/drivers/dma/hisilicon/version.map @@ -0,0 +1,3 @@ +DPDK_22 { + local: *; +}; diff --git a/drivers/dma/meson.build b/drivers/dma/meson.build index a69418ce9b..6d6c054f51 100644 --- a/drivers/dma/meson.build +++ b/drivers/dma/meson.build @@ -4,6 +4,7 @@ drivers = [ 'idxd', 'ioat', + 'hisilicon', 'skeleton', ] std_deps = ['dmadev'] From patchwork Tue Nov 2 12:37:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: fengchengwen X-Patchwork-Id: 103484 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 03062A0C4E; Tue, 2 Nov 2021 13:42:58 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5554E41165; Tue, 2 Nov 2021 13:42:30 +0100 (CET) Received: from szxga08-in.huawei.com (szxga08-in.huawei.com [45.249.212.255]) by mails.dpdk.org (Postfix) with ESMTP id 9844E4069F for ; Tue, 2 Nov 2021 13:42:23 +0100 (CET) Received: from dggemv704-chm.china.huawei.com (unknown [172.30.72.55]) by szxga08-in.huawei.com (SkyGuard) with ESMTP id 4Hk8cy0qhBz1DHxc; Tue, 2 Nov 2021 20:40:18 +0800 (CST) Received: from dggpeml500024.china.huawei.com (7.185.36.10) by dggemv704-chm.china.huawei.com (10.3.19.47) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Tue, 2 Nov 2021 20:42:18 +0800 Received: from localhost.localdomain (10.67.165.24) by dggpeml500024.china.huawei.com (7.185.36.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Tue, 2 Nov 2021 20:42:18 +0800 From: Chengwen Feng To: CC: Date: Tue, 2 Nov 2021 20:37:39 +0800 Message-ID: <20211102123743.13497-3-fengchengwen@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211102123743.13497-1-fengchengwen@huawei.com> References: <20211030103619.29924-1-fengchengwen@huawei.com> <20211102123743.13497-1-fengchengwen@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.165.24] X-ClientProxiedBy: dggems702-chm.china.huawei.com (10.3.19.179) To dggpeml500024.china.huawei.com (7.185.36.10) X-CFilter-Loop: Reflected Subject: [dpdk-dev] [PATCH v2 2/6] dma/hisilicon: add dmadev instances create and destroy 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" This patch add dmadev instances create during the PCI probe, and destroy them during the PCI remove. Internal structures and HW definitions was also included. Signed-off-by: Chengwen Feng --- doc/guides/dmadevs/hisilicon.rst | 10 ++ drivers/dma/hisilicon/hisi_dmadev.c | 212 +++++++++++++++++++++++++++- drivers/dma/hisilicon/hisi_dmadev.h | 97 +++++++++++++ 3 files changed, 318 insertions(+), 1 deletion(-) diff --git a/doc/guides/dmadevs/hisilicon.rst b/doc/guides/dmadevs/hisilicon.rst index 4cbaac4204..65138a8365 100644 --- a/doc/guides/dmadevs/hisilicon.rst +++ b/doc/guides/dmadevs/hisilicon.rst @@ -19,3 +19,13 @@ Device Setup Kunpeng DMA devices will need to be bound to a suitable DPDK-supported user-space IO driver such as ``vfio-pci`` in order to be used by DPDK. + +Device Probing and Initialization +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once probed successfully, the device will appear as four ``dmadev`` which can be +accessed using API from the ``rte_dmadev`` library. + +The name of the ``dmadev`` created is like "B:D.F-chX", e.g. DMA 0000:7b:00.0 +will create four ``dmadev``, the 1st ``dmadev`` name is "7b:00.0-ch0", and the +2nd ``dmadev`` name is "7b:00.0-ch1". diff --git a/drivers/dma/hisilicon/hisi_dmadev.c b/drivers/dma/hisilicon/hisi_dmadev.c index e6fb8a0fc8..b8369e7e71 100644 --- a/drivers/dma/hisilicon/hisi_dmadev.c +++ b/drivers/dma/hisilicon/hisi_dmadev.c @@ -6,7 +6,9 @@ #include #include +#include #include +#include #include #include #include @@ -30,6 +32,141 @@ RTE_LOG_REGISTER_DEFAULT(hisi_dma_logtype, INFO); #define HISI_DMA_ERR(hw, fmt, args...) \ HISI_DMA_LOG_RAW(hw, ERR, fmt, ## args) +static uint32_t +hisi_dma_queue_base(struct hisi_dma_dev *hw) +{ + if (hw->reg_layout == HISI_DMA_REG_LAYOUT_HIP08) + return HISI_DMA_HIP08_QUEUE_BASE; + else + return 0; +} + +static void +hisi_dma_write_reg(void *base, uint32_t off, uint32_t val) +{ + rte_write32(rte_cpu_to_le_32(val), + (volatile void *)((char *)base + off)); +} + +static void +hisi_dma_write_dev(struct hisi_dma_dev *hw, uint32_t off, uint32_t val) +{ + hisi_dma_write_reg(hw->io_base, off, val); +} + +static void +hisi_dma_write_queue(struct hisi_dma_dev *hw, uint32_t qoff, uint32_t val) +{ + uint32_t off = hisi_dma_queue_base(hw) + + hw->queue_id * HISI_DMA_QUEUE_REGION_SIZE + qoff; + hisi_dma_write_dev(hw, off, val); +} + +static uint32_t +hisi_dma_read_reg(void *base, uint32_t off) +{ + uint32_t val = rte_read32((volatile void *)((char *)base + off)); + return rte_le_to_cpu_32(val); +} + +static uint32_t +hisi_dma_read_dev(struct hisi_dma_dev *hw, uint32_t off) +{ + return hisi_dma_read_reg(hw->io_base, off); +} + +static uint32_t +hisi_dma_read_queue(struct hisi_dma_dev *hw, uint32_t qoff) +{ + uint32_t off = hisi_dma_queue_base(hw) + + hw->queue_id * HISI_DMA_QUEUE_REGION_SIZE + qoff; + return hisi_dma_read_dev(hw, off); +} + +static void +hisi_dma_update_bit(struct hisi_dma_dev *hw, uint32_t off, uint32_t pos, + bool set) +{ + uint32_t tmp = hisi_dma_read_dev(hw, off); + uint32_t mask = 1u << pos; + tmp = set ? tmp | mask : tmp & ~mask; + hisi_dma_write_dev(hw, off, tmp); +} + +static void +hisi_dma_update_queue_bit(struct hisi_dma_dev *hw, uint32_t qoff, uint32_t pos, + bool set) +{ + uint32_t tmp = hisi_dma_read_queue(hw, qoff); + uint32_t mask = 1u << pos; + tmp = set ? tmp | mask : tmp & ~mask; + hisi_dma_write_queue(hw, qoff, tmp); +} + +#define hisi_dma_poll_hw_state(hw, val, cond, sleep_us, timeout_us) ({ \ + uint32_t timeout = 0; \ + while (timeout++ <= (timeout_us)) { \ + (val) = hisi_dma_read_queue(hw, HISI_DMA_QUEUE_FSM_REG); \ + if (cond) \ + break; \ + rte_delay_us(sleep_us); \ + } \ + (cond) ? 0 : -ETIME; \ +}) + +static int +hisi_dma_reset_hw(struct hisi_dma_dev *hw) +{ +#define POLL_SLEEP_US 100 +#define POLL_TIMEOUT_US 10000 + + uint32_t tmp; + int ret; + + hisi_dma_update_queue_bit(hw, HISI_DMA_QUEUE_CTRL0_REG, + HISI_DMA_QUEUE_CTRL0_PAUSE_B, true); + hisi_dma_update_queue_bit(hw, HISI_DMA_QUEUE_CTRL0_REG, + HISI_DMA_QUEUE_CTRL0_EN_B, false); + + ret = hisi_dma_poll_hw_state(hw, tmp, + FIELD_GET(HISI_DMA_QUEUE_FSM_STS_M, tmp) != HISI_DMA_STATE_RUN, + POLL_SLEEP_US, POLL_TIMEOUT_US); + if (ret) { + HISI_DMA_ERR(hw, "disable dma timeout!"); + return ret; + } + + hisi_dma_update_queue_bit(hw, HISI_DMA_QUEUE_CTRL1_REG, + HISI_DMA_QUEUE_CTRL1_RESET_B, true); + hisi_dma_write_queue(hw, HISI_DMA_QUEUE_SQ_TAIL_REG, 0); + hisi_dma_write_queue(hw, HISI_DMA_QUEUE_CQ_HEAD_REG, 0); + hisi_dma_update_queue_bit(hw, HISI_DMA_QUEUE_CTRL0_REG, + HISI_DMA_QUEUE_CTRL0_PAUSE_B, false); + + ret = hisi_dma_poll_hw_state(hw, tmp, + FIELD_GET(HISI_DMA_QUEUE_FSM_STS_M, tmp) == HISI_DMA_STATE_IDLE, + POLL_SLEEP_US, POLL_TIMEOUT_US); + if (ret) { + HISI_DMA_ERR(hw, "reset dma timeout!"); + return ret; + } + + return 0; +} + +static void +hisi_dma_init_gbl(void *pci_bar, uint8_t revision) +{ + struct hisi_dma_dev hw; + + memset(&hw, 0, sizeof(hw)); + hw.io_base = pci_bar; + + if (revision == HISI_DMA_REVISION_HIP08B) + hisi_dma_update_bit(&hw, HISI_DMA_HIP08_MODE_REG, + HISI_DMA_HIP08_MODE_SEL_B, true); +} + static uint8_t hisi_dma_reg_layout(uint8_t revision) { @@ -49,6 +186,57 @@ hisi_dma_gen_pci_device_name(const struct rte_pci_device *pci_dev, pci_dev->addr.function); } +static void +hisi_dma_gen_dev_name(const struct rte_pci_device *pci_dev, + uint8_t queue_id, char *name, size_t size) +{ + memset(name, 0, size); + (void)snprintf(name, size, "%x:%x.%x-ch%u", + pci_dev->addr.bus, pci_dev->addr.devid, + pci_dev->addr.function, queue_id); +} + +static int +hisi_dma_create(struct rte_pci_device *pci_dev, uint8_t queue_id, + uint8_t revision) +{ +#define REG_PCI_BAR_INDEX 2 + + char name[RTE_DEV_NAME_MAX_LEN]; + struct rte_dma_dev *dev; + struct hisi_dma_dev *hw; + int ret; + + hisi_dma_gen_dev_name(pci_dev, queue_id, name, sizeof(name)); + dev = rte_dma_pmd_allocate(name, pci_dev->device.numa_node, + sizeof(*hw)); + if (dev == NULL) { + HISI_DMA_LOG(ERR, "%s allocate dmadev fail!", name); + return -EINVAL; + } + + dev->device = &pci_dev->device; + + hw = dev->data->dev_private; + hw->data = dev->data; + hw->revision = revision; + hw->reg_layout = hisi_dma_reg_layout(revision); + hw->io_base = pci_dev->mem_resource[REG_PCI_BAR_INDEX].addr; + hw->queue_id = queue_id; + + ret = hisi_dma_reset_hw(hw); + if (ret) { + HISI_DMA_LOG(ERR, "%s init device fail!", name); + (void)rte_dma_pmd_release(name); + return -EIO; + } + + dev->state = RTE_DMA_DEV_READY; + HISI_DMA_LOG(DEBUG, "%s create dmadev success!", name); + + return 0; +} + static int hisi_dma_check_revision(struct rte_pci_device *pci_dev, const char *name, uint8_t *out_revision) @@ -78,6 +266,7 @@ hisi_dma_probe(struct rte_pci_driver *pci_drv __rte_unused, { char name[RTE_DEV_NAME_MAX_LEN] = { 0 }; uint8_t revision; + uint8_t i; int ret; hisi_dma_gen_pci_device_name(pci_dev, name, sizeof(name)); @@ -92,13 +281,34 @@ hisi_dma_probe(struct rte_pci_driver *pci_drv __rte_unused, return ret; HISI_DMA_LOG(DEBUG, "%s read PCI revision: 0x%x", name, revision); + hisi_dma_init_gbl(pci_dev->mem_resource[2].addr, revision); + + for (i = 0; i < HISI_DMA_MAX_HW_QUEUES; i++) { + ret = hisi_dma_create(pci_dev, i, revision); + if (ret) { + HISI_DMA_LOG(ERR, "%s create dmadev %u failed!", + name, i); + break; + } + } + return ret; } static int hisi_dma_remove(struct rte_pci_device *pci_dev) { - RTE_SET_USED(pci_dev); + char name[RTE_DEV_NAME_MAX_LEN]; + uint8_t i; + int ret; + + for (i = 0; i < HISI_DMA_MAX_HW_QUEUES; i++) { + hisi_dma_gen_dev_name(pci_dev, i, name, sizeof(name)); + ret = rte_dma_pmd_release(name); + if (ret) + return ret; + } + return 0; } diff --git a/drivers/dma/hisilicon/hisi_dmadev.h b/drivers/dma/hisilicon/hisi_dmadev.h index 114b9dcb5b..50aaa38b72 100644 --- a/drivers/dma/hisilicon/hisi_dmadev.h +++ b/drivers/dma/hisilicon/hisi_dmadev.h @@ -5,11 +5,24 @@ #ifndef HISI_DMADEV_H #define HISI_DMADEV_H +#include +#include + +#define BIT(x) (1ul << (x)) +#define BITS_PER_LONG (__SIZEOF_LONG__ * 8) +#define GENMASK(h, l) \ + (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) +#define BF_SHF(x) (__builtin_ffsll(x) - 1) +#define FIELD_GET(mask, reg) \ + ((typeof(mask))(((reg) & (mask)) >> BF_SHF(mask))) + #define PCI_VENDOR_ID_HUAWEI 0x19e5 #define HISI_DMA_DEVICE_ID 0xA122 #define HISI_DMA_PCI_REVISION_ID_REG 0x08 #define HISI_DMA_REVISION_HIP08B 0x21 +#define HISI_DMA_MAX_HW_QUEUES 4 + /** * The HIP08B(HiSilicon IP08) and later Chip(e.g. HiSilicon IP09) are DMA iEPs, * they have the same pci device id but with different pci revision. @@ -21,4 +34,88 @@ enum { HISI_DMA_REG_LAYOUT_HIP08 }; +/** + * Hardware PCI bar register MAP: + * + * -------------- + * | Misc-reg-0 | + * | | + * -------------- -> Queue base + * | | + * | Queue-0 | + * | | + * -------------- --- + * | | ^ + * | Queue-1 | Queue region + * | | v + * -------------- --- + * | ... | + * | Queue-x | + * | ... | + * -------------- + * | Misc-reg-1 | + * -------------- + * + * As described above, a single queue register is continuous and occupies the + * length of queue-region. The global offset for a single queue register is + * calculated by: + * offset = queue-base + (queue-id * queue-region) + reg-offset-in-region. + * + * The first part of queue region is basically the same for HIP08 and later chip + * register layouts, therefore, HISI_QUEUE_* registers are defined for it. + */ +#define HISI_DMA_QUEUE_SQ_BASE_L_REG 0x0 +#define HISI_DMA_QUEUE_SQ_BASE_H_REG 0x4 +#define HISI_DMA_QUEUE_SQ_DEPTH_REG 0x8 +#define HISI_DMA_QUEUE_SQ_TAIL_REG 0xC +#define HISI_DMA_QUEUE_CQ_BASE_L_REG 0x10 +#define HISI_DMA_QUEUE_CQ_BASE_H_REG 0x14 +#define HISI_DMA_QUEUE_CQ_DEPTH_REG 0x18 +#define HISI_DMA_QUEUE_CQ_HEAD_REG 0x1C +#define HISI_DMA_QUEUE_CTRL0_REG 0x20 +#define HISI_DMA_QUEUE_CTRL0_EN_B 0 +#define HISI_DMA_QUEUE_CTRL0_PAUSE_B 4 +#define HISI_DMA_QUEUE_CTRL1_REG 0x24 +#define HISI_DMA_QUEUE_CTRL1_RESET_B 0 +#define HISI_DMA_QUEUE_FSM_REG 0x30 +#define HISI_DMA_QUEUE_FSM_STS_M GENMASK(3, 0) +#define HISI_DMA_QUEUE_INT_STATUS_REG 0x40 +#define HISI_DMA_QUEUE_ERR_INT_NUM0_REG 0x84 +#define HISI_DMA_QUEUE_ERR_INT_NUM1_REG 0x88 +#define HISI_DMA_QUEUE_ERR_INT_NUM2_REG 0x8C +#define HISI_DMA_QUEUE_REGION_SIZE 0x100 + +/** + * HiSilicon IP08 DMA register and field define: + */ +#define HISI_DMA_HIP08_QUEUE_BASE 0x0 +#define HISI_DMA_HIP08_QUEUE_CTRL0_ERR_ABORT_B 2 +#define HISI_DMA_HIP08_QUEUE_INT_MASK_REG 0x44 +#define HISI_DMA_HIP08_QUEUE_INT_MASK_M GENMASK(14, 0) +#define HISI_DMA_HIP08_QUEUE_ERR_INT_NUM3_REG 0x90 +#define HISI_DMA_HIP08_QUEUE_ERR_INT_NUM4_REG 0x94 +#define HISI_DMA_HIP08_QUEUE_ERR_INT_NUM5_REG 0x98 +#define HISI_DMA_HIP08_QUEUE_ERR_INT_NUM6_REG 0x48 +#define HISI_DMA_HIP08_MODE_REG 0x217C +#define HISI_DMA_HIP08_MODE_SEL_B 0 +#define HISI_DMA_HIP08_DUMP_START_REG 0x2000 +#define HISI_DMA_HIP08_DUMP_END_REG 0x2280 + +/** + * In fact, there are multiple states, but it need to pay attention to + * the following two states for the driver: + */ +enum { + HISI_DMA_STATE_IDLE = 0, + HISI_DMA_STATE_RUN, +}; + +struct hisi_dma_dev { + struct rte_dma_dev_data *data; + uint8_t revision; /**< PCI revision. */ + uint8_t reg_layout; /**< hardware register layout. */ + void *io_base; + uint8_t queue_id; /**< hardware DMA queue index. */ +}; + #endif /* HISI_DMADEV_H */ From patchwork Tue Nov 2 12:37:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: fengchengwen X-Patchwork-Id: 103482 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 B7E70A0C4E; Tue, 2 Nov 2021 13:42:43 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E337E41144; Tue, 2 Nov 2021 13:42:27 +0100 (CET) Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by mails.dpdk.org (Postfix) with ESMTP id 50DE340689 for ; Tue, 2 Nov 2021 13:42:23 +0100 (CET) Received: from dggemv704-chm.china.huawei.com (unknown [172.30.72.55]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4Hk8g93JlBz90gX; Tue, 2 Nov 2021 20:42:13 +0800 (CST) Received: from dggpeml500024.china.huawei.com (7.185.36.10) by dggemv704-chm.china.huawei.com (10.3.19.47) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Tue, 2 Nov 2021 20:42:21 +0800 Received: from localhost.localdomain (10.67.165.24) by dggpeml500024.china.huawei.com (7.185.36.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Tue, 2 Nov 2021 20:42:18 +0800 From: Chengwen Feng To: CC: Date: Tue, 2 Nov 2021 20:37:40 +0800 Message-ID: <20211102123743.13497-4-fengchengwen@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211102123743.13497-1-fengchengwen@huawei.com> References: <20211030103619.29924-1-fengchengwen@huawei.com> <20211102123743.13497-1-fengchengwen@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.165.24] X-ClientProxiedBy: dggems702-chm.china.huawei.com (10.3.19.179) To dggpeml500024.china.huawei.com (7.185.36.10) X-CFilter-Loop: Reflected Subject: [dpdk-dev] [PATCH v2 3/6] dma/hisilicon: add control path 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" This patch add control path functions for Kunpeng DMA devices. Signed-off-by: Chengwen Feng --- doc/guides/dmadevs/hisilicon.rst | 10 + drivers/dma/hisilicon/hisi_dmadev.c | 385 ++++++++++++++++++++++++++++ drivers/dma/hisilicon/hisi_dmadev.h | 99 +++++++ 3 files changed, 494 insertions(+) diff --git a/doc/guides/dmadevs/hisilicon.rst b/doc/guides/dmadevs/hisilicon.rst index 65138a8365..24bae86bdc 100644 --- a/doc/guides/dmadevs/hisilicon.rst +++ b/doc/guides/dmadevs/hisilicon.rst @@ -29,3 +29,13 @@ accessed using API from the ``rte_dmadev`` library. The name of the ``dmadev`` created is like "B:D.F-chX", e.g. DMA 0000:7b:00.0 will create four ``dmadev``, the 1st ``dmadev`` name is "7b:00.0-ch0", and the 2nd ``dmadev`` name is "7b:00.0-ch1". + +Device Configuration +~~~~~~~~~~~~~~~~~~~~~ + +Kunpeng DMA configuration requirements: + +* ``ring_size`` must be a power of two, between 32 and 8192. +* Only one ``vchan`` is supported per ``dmadev``. +* Silent mode is not supported. +* The transfer direction must be set to ``RTE_DMA_DIR_MEM_TO_MEM``. diff --git a/drivers/dma/hisilicon/hisi_dmadev.c b/drivers/dma/hisilicon/hisi_dmadev.c index b8369e7e71..bcdcf4de4b 100644 --- a/drivers/dma/hisilicon/hisi_dmadev.c +++ b/drivers/dma/hisilicon/hisi_dmadev.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include @@ -41,6 +43,14 @@ hisi_dma_queue_base(struct hisi_dma_dev *hw) return 0; } +static volatile void * +hisi_dma_queue_regaddr(struct hisi_dma_dev *hw, uint32_t qoff) +{ + uint32_t off = hisi_dma_queue_base(hw) + + hw->queue_id * HISI_DMA_QUEUE_REGION_SIZE + qoff; + return (volatile void *)((char *)hw->io_base + off); +} + static void hisi_dma_write_reg(void *base, uint32_t off, uint32_t val) { @@ -103,6 +113,15 @@ hisi_dma_update_queue_bit(struct hisi_dma_dev *hw, uint32_t qoff, uint32_t pos, hisi_dma_write_queue(hw, qoff, tmp); } +static void +hisi_dma_update_queue_mbit(struct hisi_dma_dev *hw, uint32_t qoff, + uint32_t mask, bool set) +{ + uint32_t tmp = hisi_dma_read_queue(hw, qoff); + tmp = set ? tmp | mask : tmp & ~mask; + hisi_dma_write_queue(hw, qoff, tmp); +} + #define hisi_dma_poll_hw_state(hw, val, cond, sleep_us, timeout_us) ({ \ uint32_t timeout = 0; \ while (timeout++ <= (timeout_us)) { \ @@ -154,6 +173,45 @@ hisi_dma_reset_hw(struct hisi_dma_dev *hw) return 0; } +static void +hisi_dma_init_hw(struct hisi_dma_dev *hw) +{ + hisi_dma_write_queue(hw, HISI_DMA_QUEUE_SQ_BASE_L_REG, + lower_32_bits(hw->sqe_iova)); + hisi_dma_write_queue(hw, HISI_DMA_QUEUE_SQ_BASE_H_REG, + upper_32_bits(hw->sqe_iova)); + hisi_dma_write_queue(hw, HISI_DMA_QUEUE_CQ_BASE_L_REG, + lower_32_bits(hw->cqe_iova)); + hisi_dma_write_queue(hw, HISI_DMA_QUEUE_CQ_BASE_H_REG, + upper_32_bits(hw->cqe_iova)); + hisi_dma_write_queue(hw, HISI_DMA_QUEUE_SQ_DEPTH_REG, + hw->sq_depth_mask); + hisi_dma_write_queue(hw, HISI_DMA_QUEUE_CQ_DEPTH_REG, hw->cq_depth - 1); + hisi_dma_write_queue(hw, HISI_DMA_QUEUE_SQ_TAIL_REG, 0); + hisi_dma_write_queue(hw, HISI_DMA_QUEUE_CQ_HEAD_REG, 0); + hisi_dma_write_queue(hw, HISI_DMA_QUEUE_ERR_INT_NUM0_REG, 0); + hisi_dma_write_queue(hw, HISI_DMA_QUEUE_ERR_INT_NUM1_REG, 0); + hisi_dma_write_queue(hw, HISI_DMA_QUEUE_ERR_INT_NUM2_REG, 0); + + if (hw->reg_layout == HISI_DMA_REG_LAYOUT_HIP08) { + hisi_dma_write_queue(hw, HISI_DMA_HIP08_QUEUE_ERR_INT_NUM3_REG, + 0); + hisi_dma_write_queue(hw, HISI_DMA_HIP08_QUEUE_ERR_INT_NUM4_REG, + 0); + hisi_dma_write_queue(hw, HISI_DMA_HIP08_QUEUE_ERR_INT_NUM5_REG, + 0); + hisi_dma_write_queue(hw, HISI_DMA_HIP08_QUEUE_ERR_INT_NUM6_REG, + 0); + hisi_dma_update_queue_bit(hw, HISI_DMA_QUEUE_CTRL0_REG, + HISI_DMA_HIP08_QUEUE_CTRL0_ERR_ABORT_B, false); + hisi_dma_update_queue_mbit(hw, HISI_DMA_QUEUE_INT_STATUS_REG, + HISI_DMA_HIP08_QUEUE_INT_MASK_M, true); + hisi_dma_update_queue_mbit(hw, + HISI_DMA_HIP08_QUEUE_INT_MASK_REG, + HISI_DMA_HIP08_QUEUE_INT_MASK_M, true); + } +} + static void hisi_dma_init_gbl(void *pci_bar, uint8_t revision) { @@ -176,6 +234,301 @@ hisi_dma_reg_layout(uint8_t revision) return HISI_DMA_REG_LAYOUT_INVALID; } +static void +hisi_dma_zero_iomem(struct hisi_dma_dev *hw) +{ + memset(hw->iomz->addr, 0, hw->iomz_sz); +} + +static int +hisi_dma_alloc_iomem(struct hisi_dma_dev *hw, uint16_t ring_size, + const char *dev_name) +{ + uint32_t sq_size = sizeof(struct hisi_dma_sqe) * ring_size; + uint32_t cq_size = sizeof(struct hisi_dma_cqe) * + (ring_size + HISI_DMA_CQ_RESERVED); + uint32_t status_size = sizeof(uint16_t) * ring_size; + char mz_name[RTE_MEMZONE_NAMESIZE]; + const struct rte_memzone *iomz; + uint32_t total_size; + + sq_size = RTE_CACHE_LINE_ROUNDUP(sq_size); + cq_size = RTE_CACHE_LINE_ROUNDUP(cq_size); + status_size = RTE_CACHE_LINE_ROUNDUP(status_size); + total_size = sq_size + cq_size + status_size; + + (void)snprintf(mz_name, sizeof(mz_name), "hisi_dma:%s", dev_name); + iomz = rte_memzone_reserve(mz_name, total_size, hw->data->numa_node, + RTE_MEMZONE_IOVA_CONTIG); + if (iomz == NULL) { + HISI_DMA_ERR(hw, "malloc %s iomem fail!", mz_name); + return -ENOMEM; + } + + hw->iomz = iomz; + hw->iomz_sz = total_size; + hw->sqe = iomz->addr; + hw->cqe = (void *)((char *)iomz->addr + sq_size); + hw->status = (void *)((char *)iomz->addr + sq_size + cq_size); + hw->sqe_iova = iomz->iova; + hw->cqe_iova = iomz->iova + sq_size; + hw->sq_depth_mask = ring_size - 1; + hw->cq_depth = ring_size + HISI_DMA_CQ_RESERVED; + hisi_dma_zero_iomem(hw); + + return 0; +} + +static void +hisi_dma_free_iomem(struct hisi_dma_dev *hw) +{ + if (hw->iomz != NULL) + rte_memzone_free(hw->iomz); + + hw->iomz = NULL; + hw->sqe = NULL; + hw->cqe = NULL; + hw->status = NULL; + hw->sqe_iova = 0; + hw->cqe_iova = 0; + hw->sq_depth_mask = 0; + hw->cq_depth = 0; +} + +static int +hisi_dma_info_get(const struct rte_dma_dev *dev, + struct rte_dma_info *dev_info, + uint32_t info_sz) +{ + RTE_SET_USED(dev); + RTE_SET_USED(info_sz); + + dev_info->dev_capa = RTE_DMA_CAPA_MEM_TO_MEM | + RTE_DMA_CAPA_OPS_COPY; + dev_info->max_vchans = 1; + dev_info->max_desc = HISI_DMA_MAX_DESC_NUM; + dev_info->min_desc = HISI_DMA_MIN_DESC_NUM; + + return 0; +} + +static int +hisi_dma_configure(struct rte_dma_dev *dev, + const struct rte_dma_conf *conf, + uint32_t conf_sz) +{ + RTE_SET_USED(dev); + RTE_SET_USED(conf); + RTE_SET_USED(conf_sz); + return 0; +} + +static int +hisi_dma_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan, + const struct rte_dma_vchan_conf *conf, + uint32_t conf_sz) +{ + struct hisi_dma_dev *hw = dev->data->dev_private; + int ret; + + RTE_SET_USED(vchan); + RTE_SET_USED(conf_sz); + + if (!rte_is_power_of_2(conf->nb_desc)) { + HISI_DMA_ERR(hw, "Number of desc must be power of 2!"); + return -EINVAL; + } + + hisi_dma_free_iomem(hw); + ret = hisi_dma_alloc_iomem(hw, conf->nb_desc, dev->data->dev_name); + if (ret) + return ret; + + return 0; +} + +static int +hisi_dma_start(struct rte_dma_dev *dev) +{ + struct hisi_dma_dev *hw = dev->data->dev_private; + + if (hw->iomz == NULL) { + HISI_DMA_ERR(hw, "Vchan was not setup, start fail!\n"); + return -EINVAL; + } + + /* Reset the dmadev to a known state, include: + * 1) zero iomem, also include status fields. + * 2) init hardware register. + * 3) init index values to zero. + * 4) init running statistics. + */ + hisi_dma_zero_iomem(hw); + hisi_dma_init_hw(hw); + hw->ridx = 0; + hw->cridx = 0; + hw->sq_head = 0; + hw->sq_tail = 0; + hw->cq_sq_head = 0; + hw->cq_head = 0; + hw->cqs_completed = 0; + hw->cqe_vld = 1; + hw->submitted = 0; + hw->completed = 0; + hw->errors = 0; + + hisi_dma_update_queue_bit(hw, HISI_DMA_QUEUE_CTRL0_REG, + HISI_DMA_QUEUE_CTRL0_EN_B, true); + + return 0; +} + +static int +hisi_dma_stop(struct rte_dma_dev *dev) +{ + return hisi_dma_reset_hw(dev->data->dev_private); +} + +static int +hisi_dma_close(struct rte_dma_dev *dev) +{ + /* The dmadev already stopped */ + hisi_dma_free_iomem(dev->data->dev_private); + return 0; +} + +static int +hisi_dma_stats_get(const struct rte_dma_dev *dev, uint16_t vchan, + struct rte_dma_stats *stats, + uint32_t stats_sz) +{ + struct hisi_dma_dev *hw = dev->data->dev_private; + + RTE_SET_USED(vchan); + RTE_SET_USED(stats_sz); + stats->submitted = hw->submitted; + stats->completed = hw->completed; + stats->errors = hw->errors; + + return 0; +} + +static int +hisi_dma_stats_reset(struct rte_dma_dev *dev, uint16_t vchan) +{ + struct hisi_dma_dev *hw = dev->data->dev_private; + + RTE_SET_USED(vchan); + hw->submitted = 0; + hw->completed = 0; + hw->errors = 0; + + return 0; +} + +static void +hisi_dma_get_dump_range(struct hisi_dma_dev *hw, uint32_t *start, uint32_t *end) +{ + if (hw->reg_layout == HISI_DMA_REG_LAYOUT_HIP08) { + *start = HISI_DMA_HIP08_DUMP_START_REG; + *end = HISI_DMA_HIP08_DUMP_END_REG; + } else { + *start = 0; + *end = 0; + } +} + +static void +hisi_dma_dump_common(struct hisi_dma_dev *hw, FILE *f) +{ +#define DUMP_REGNUM_PER_LINE 4 + + uint32_t start, end; + uint32_t cnt, i; + + hisi_dma_get_dump_range(hw, &start, &end); + + (void)fprintf(f, " common-register:\n"); + + cnt = 0; + for (i = start; i <= end; i += sizeof(uint32_t)) { + if (cnt % DUMP_REGNUM_PER_LINE == 0) + (void)fprintf(f, " [%4x]:", i); + (void)fprintf(f, " 0x%08x", hisi_dma_read_dev(hw, i)); + cnt++; + if (cnt % DUMP_REGNUM_PER_LINE == 0) + (void)fprintf(f, "\n"); + } + if (cnt % DUMP_REGNUM_PER_LINE) + (void)fprintf(f, "\n"); +} + +static void +hisi_dma_dump_read_queue(struct hisi_dma_dev *hw, uint32_t qoff, + char *buffer, int max_sz) +{ + memset(buffer, 0, max_sz); + + /* Address-related registers are not printed for security reasons. */ + if (qoff == HISI_DMA_QUEUE_SQ_BASE_L_REG || + qoff == HISI_DMA_QUEUE_SQ_BASE_H_REG || + qoff == HISI_DMA_QUEUE_CQ_BASE_L_REG || + qoff == HISI_DMA_QUEUE_CQ_BASE_H_REG) { + (void)snprintf(buffer, max_sz, "**********"); + return; + } + + (void)snprintf(buffer, max_sz, "0x%08x", hisi_dma_read_queue(hw, qoff)); +} + +static void +hisi_dma_dump_queue(struct hisi_dma_dev *hw, FILE *f) +{ +#define REG_FMT_LEN 32 + char buf[REG_FMT_LEN] = { 0 }; + uint32_t i; + + (void)fprintf(f, " queue-register:\n"); + for (i = 0; i < HISI_DMA_QUEUE_REGION_SIZE; ) { + hisi_dma_dump_read_queue(hw, i, buf, sizeof(buf)); + (void)fprintf(f, " [%2x]: %s", i, buf); + i += sizeof(uint32_t); + hisi_dma_dump_read_queue(hw, i, buf, sizeof(buf)); + (void)fprintf(f, " %s", buf); + i += sizeof(uint32_t); + hisi_dma_dump_read_queue(hw, i, buf, sizeof(buf)); + (void)fprintf(f, " %s", buf); + i += sizeof(uint32_t); + hisi_dma_dump_read_queue(hw, i, buf, sizeof(buf)); + (void)fprintf(f, " %s\n", buf); + i += sizeof(uint32_t); + } +} + +static int +hisi_dma_dump(const struct rte_dma_dev *dev, FILE *f) +{ + struct hisi_dma_dev *hw = dev->data->dev_private; + + (void)fprintf(f, + " revision: 0x%x queue_id: %u ring_size: %u\n" + " ridx: %u cridx: %u\n" + " sq_head: %u sq_tail: %u cq_sq_head: %u\n" + " cq_head: %u cqs_completed: %u cqe_vld: %u\n" + " submitted: %" PRIu64 " completed: %" PRIu64 " errors %" + PRIu64"\n", + hw->revision, hw->queue_id, + hw->sq_depth_mask > 0 ? hw->sq_depth_mask + 1 : 0, + hw->ridx, hw->cridx, + hw->sq_head, hw->sq_tail, hw->cq_sq_head, + hw->cq_head, hw->cqs_completed, hw->cqe_vld, + hw->submitted, hw->completed, hw->errors); + hisi_dma_dump_queue(hw, f); + hisi_dma_dump_common(hw, f); + + return 0; +} + static void hisi_dma_gen_pci_device_name(const struct rte_pci_device *pci_dev, char *name, size_t size) @@ -196,6 +549,33 @@ hisi_dma_gen_dev_name(const struct rte_pci_device *pci_dev, pci_dev->addr.function, queue_id); } +/** + * Hardware queue state machine: + * + * ----------- dmadev_create ------------------ + * | Unknown | ---------------> | IDLE | + * ----------- ------------------ + * ^ | + * | |dev_start + * dev_stop| | + * | v + * ------------------ + * | RUN | + * ------------------ + * + */ +static const struct rte_dma_dev_ops hisi_dmadev_ops = { + .dev_info_get = hisi_dma_info_get, + .dev_configure = hisi_dma_configure, + .dev_start = hisi_dma_start, + .dev_stop = hisi_dma_stop, + .dev_close = hisi_dma_close, + .vchan_setup = hisi_dma_vchan_setup, + .stats_get = hisi_dma_stats_get, + .stats_reset = hisi_dma_stats_reset, + .dev_dump = hisi_dma_dump, +}; + static int hisi_dma_create(struct rte_pci_device *pci_dev, uint8_t queue_id, uint8_t revision) @@ -216,6 +596,7 @@ hisi_dma_create(struct rte_pci_device *pci_dev, uint8_t queue_id, } dev->device = &pci_dev->device; + dev->dev_ops = &hisi_dmadev_ops; hw = dev->data->dev_private; hw->data = dev->data; @@ -223,6 +604,10 @@ hisi_dma_create(struct rte_pci_device *pci_dev, uint8_t queue_id, hw->reg_layout = hisi_dma_reg_layout(revision); hw->io_base = pci_dev->mem_resource[REG_PCI_BAR_INDEX].addr; hw->queue_id = queue_id; + hw->sq_tail_reg = hisi_dma_queue_regaddr(hw, + HISI_DMA_QUEUE_SQ_TAIL_REG); + hw->cq_head_reg = hisi_dma_queue_regaddr(hw, + HISI_DMA_QUEUE_CQ_HEAD_REG); ret = hisi_dma_reset_hw(hw); if (ret) { diff --git a/drivers/dma/hisilicon/hisi_dmadev.h b/drivers/dma/hisilicon/hisi_dmadev.h index 50aaa38b72..dd0315cd31 100644 --- a/drivers/dma/hisilicon/hisi_dmadev.h +++ b/drivers/dma/hisilicon/hisi_dmadev.h @@ -16,12 +16,17 @@ #define FIELD_GET(mask, reg) \ ((typeof(mask))(((reg) & (mask)) >> BF_SHF(mask))) +#define lower_32_bits(x) ((uint32_t)(x)) +#define upper_32_bits(x) ((uint32_t)(((x) >> 16) >> 16)) + #define PCI_VENDOR_ID_HUAWEI 0x19e5 #define HISI_DMA_DEVICE_ID 0xA122 #define HISI_DMA_PCI_REVISION_ID_REG 0x08 #define HISI_DMA_REVISION_HIP08B 0x21 #define HISI_DMA_MAX_HW_QUEUES 4 +#define HISI_DMA_MAX_DESC_NUM 8192 +#define HISI_DMA_MIN_DESC_NUM 32 /** * The HIP08B(HiSilicon IP08) and later Chip(e.g. HiSilicon IP09) are DMA iEPs, @@ -110,12 +115,106 @@ enum { HISI_DMA_STATE_RUN, }; +/** + * After scanning the CQ array, the CQ head register needs to be updated. + * Updating the register involves write memory barrier operations. + * Here use the following method to reduce WMB operations: + * a) malloc more CQEs, which correspond to the macro HISI_DMA_CQ_RESERVED. + * b) update the CQ head register after accumulated number of completed CQs + * is greater than or equal to HISI_DMA_CQ_RESERVED. + */ +#define HISI_DMA_CQ_RESERVED 64 + +struct hisi_dma_sqe { + uint32_t dw0; +#define SQE_FENCE_FLAG BIT(10) +#define SQE_OPCODE_M2M 0x4 + uint32_t dw1; + uint32_t dw2; + uint32_t length; + uint64_t src_addr; + uint64_t dst_addr; +}; + +struct hisi_dma_cqe { + uint64_t rsv; + uint64_t misc; +#define CQE_SQ_HEAD_MASK GENMASK(15, 0) +#define CQE_VALID_B BIT(48) +#define CQE_STATUS_MASK GENMASK(63, 49) +}; + struct hisi_dma_dev { + struct hisi_dma_sqe *sqe; + volatile struct hisi_dma_cqe *cqe; + uint16_t *status; /* the completion status array of SQEs. */ + + volatile void *sq_tail_reg; /**< register address for doorbell. */ + volatile void *cq_head_reg; /**< register address for answer CQ. */ + + uint16_t sq_depth_mask; /**< SQ depth - 1, the SQ depth is power of 2 */ + uint16_t cq_depth; /* CQ depth */ + + uint16_t ridx; /**< ring index which will assign to the next request. */ + /** ring index which returned by hisi_dmadev_completed APIs. */ + uint16_t cridx; + + /** + * SQE array management fields: + * + * ----------------------------------------------------- + * | SQE0 | SQE1 | SQE2 | ... | SQEx | ... | SQEn-1 | + * ----------------------------------------------------- + * ^ ^ ^ + * | | | + * sq_head cq_sq_head sq_tail + * + * sq_head: index to the oldest completed request, this filed was + * updated by hisi_dmadev_completed* APIs. + * sq_tail: index of the next new request, this field was updated by + * hisi_dmadev_copy API. + * cq_sq_head: next index of index that has been completed by hardware, + * this filed was updated by hisi_dmadev_completed* APIs. + * + * [sq_head, cq_sq_head): the SQEs that hardware already completed. + * [cq_sq_head, sq_tail): the SQEs that hardware processing. + */ + uint16_t sq_head; + uint16_t sq_tail; + uint16_t cq_sq_head; + /** + * The driver scans the CQE array, if the valid bit changes, the CQE is + * considered valid. + * Note: One CQE is corresponding to one or several SQEs, e.g. app + * submits two copy requests, the hardware processes the two SQEs, + * but it may write back only one CQE and the CQE's sq_head field + * indicates the index of the second copy request in the SQE + * array. + */ + uint16_t cq_head; /**< CQ index for next scans. */ + /** accumulated number of completed CQs + * @see HISI_DMA_CQ_RESERVED + */ + uint16_t cqs_completed; + uint8_t cqe_vld; /**< valid bit for CQE, will change for every round. */ + + uint64_t submitted; + uint64_t completed; + uint64_t errors; + + /** + * The following fields are not accessed in the I/O path, so they are + * placed at the end. + */ struct rte_dma_dev_data *data; uint8_t revision; /**< PCI revision. */ uint8_t reg_layout; /**< hardware register layout. */ void *io_base; uint8_t queue_id; /**< hardware DMA queue index. */ + const struct rte_memzone *iomz; + uint32_t iomz_sz; + rte_iova_t sqe_iova; + rte_iova_t cqe_iova; }; #endif /* HISI_DMADEV_H */ From patchwork Tue Nov 2 12:37:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: fengchengwen X-Patchwork-Id: 103483 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 0085DA0C4E; Tue, 2 Nov 2021 13:42:50 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id EB49D41157; Tue, 2 Nov 2021 13:42:28 +0100 (CET) Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by mails.dpdk.org (Postfix) with ESMTP id A7CDB40A4B for ; Tue, 2 Nov 2021 13:42:23 +0100 (CET) Received: from dggemv704-chm.china.huawei.com (unknown [172.30.72.57]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4Hk8cy0qF3zZcYd; Tue, 2 Nov 2021 20:40:18 +0800 (CST) Received: from dggpeml500024.china.huawei.com (7.185.36.10) by dggemv704-chm.china.huawei.com (10.3.19.47) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Tue, 2 Nov 2021 20:42:21 +0800 Received: from localhost.localdomain (10.67.165.24) by dggpeml500024.china.huawei.com (7.185.36.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Tue, 2 Nov 2021 20:42:19 +0800 From: Chengwen Feng To: CC: Date: Tue, 2 Nov 2021 20:37:41 +0800 Message-ID: <20211102123743.13497-5-fengchengwen@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211102123743.13497-1-fengchengwen@huawei.com> References: <20211030103619.29924-1-fengchengwen@huawei.com> <20211102123743.13497-1-fengchengwen@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.165.24] X-ClientProxiedBy: dggems702-chm.china.huawei.com (10.3.19.179) To dggpeml500024.china.huawei.com (7.185.36.10) X-CFilter-Loop: Reflected Subject: [dpdk-dev] [PATCH v2 4/6] dma/hisilicon: add data path 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" This patch add data path functions for Kunpeng DMA devices. Signed-off-by: Chengwen Feng --- drivers/dma/hisilicon/hisi_dmadev.c | 206 ++++++++++++++++++++++++++++ drivers/dma/hisilicon/hisi_dmadev.h | 16 +++ 2 files changed, 222 insertions(+) diff --git a/drivers/dma/hisilicon/hisi_dmadev.c b/drivers/dma/hisilicon/hisi_dmadev.c index bcdcf4de4b..d03967cae3 100644 --- a/drivers/dma/hisilicon/hisi_dmadev.c +++ b/drivers/dma/hisilicon/hisi_dmadev.c @@ -529,6 +529,206 @@ hisi_dma_dump(const struct rte_dma_dev *dev, FILE *f) return 0; } +static int +hisi_dma_copy(void *dev_private, uint16_t vchan, + rte_iova_t src, rte_iova_t dst, + uint32_t length, uint64_t flags) +{ + struct hisi_dma_dev *hw = dev_private; + struct hisi_dma_sqe *sqe = &hw->sqe[hw->sq_tail]; + + RTE_SET_USED(vchan); + + if (((hw->sq_tail + 1) & hw->sq_depth_mask) == hw->sq_head) + return -ENOSPC; + + sqe->dw0 = rte_cpu_to_le_32(SQE_OPCODE_M2M); + sqe->dw1 = 0; + sqe->dw2 = 0; + sqe->length = rte_cpu_to_le_32(length); + sqe->src_addr = rte_cpu_to_le_64(src); + sqe->dst_addr = rte_cpu_to_le_64(dst); + hw->sq_tail = (hw->sq_tail + 1) & hw->sq_depth_mask; + hw->submitted++; + + if (flags & RTE_DMA_OP_FLAG_FENCE) + sqe->dw0 |= rte_cpu_to_le_32(SQE_FENCE_FLAG); + if (flags & RTE_DMA_OP_FLAG_SUBMIT) + rte_write32(rte_cpu_to_le_32(hw->sq_tail), hw->sq_tail_reg); + + return hw->ridx++; +} + +static int +hisi_dma_submit(void *dev_private, uint16_t vchan) +{ + struct hisi_dma_dev *hw = dev_private; + + RTE_SET_USED(vchan); + rte_write32(rte_cpu_to_le_32(hw->sq_tail), hw->sq_tail_reg); + + return 0; +} + +static inline void +hisi_dma_scan_cq(struct hisi_dma_dev *hw) +{ + volatile struct hisi_dma_cqe *cqe; + uint16_t csq_head = hw->cq_sq_head; + uint16_t cq_head = hw->cq_head; + uint16_t count = 0; + uint64_t misc; + + while (true) { + cqe = &hw->cqe[cq_head]; + misc = cqe->misc; + misc = rte_le_to_cpu_64(misc); + if (FIELD_GET(CQE_VALID_B, misc) != hw->cqe_vld) + break; + + csq_head = FIELD_GET(CQE_SQ_HEAD_MASK, misc); + if (unlikely(misc & CQE_STATUS_MASK)) + hw->status[csq_head] = FIELD_GET(CQE_STATUS_MASK, + misc); + + count++; + cq_head++; + if (cq_head == hw->cq_depth) { + hw->cqe_vld = !hw->cqe_vld; + cq_head = 0; + } + } + + if (count == 0) + return; + + hw->cq_head = cq_head; + hw->cq_sq_head = (csq_head + 1) & hw->sq_depth_mask; + hw->cqs_completed += count; + if (hw->cqs_completed >= HISI_DMA_CQ_RESERVED) { + rte_write32(rte_cpu_to_le_32(cq_head), hw->cq_head_reg); + hw->cqs_completed = 0; + } +} + +static inline uint16_t +hisi_dma_calc_cpls(struct hisi_dma_dev *hw, const uint16_t nb_cpls) +{ + uint16_t cpl_num; + + if (hw->cq_sq_head >= hw->sq_head) + cpl_num = hw->cq_sq_head - hw->sq_head; + else + cpl_num = hw->sq_depth_mask + 1 - hw->sq_head + hw->cq_sq_head; + + if (cpl_num > nb_cpls) + cpl_num = nb_cpls; + + return cpl_num; +} + +static uint16_t +hisi_dma_completed(void *dev_private, + uint16_t vchan, const uint16_t nb_cpls, + uint16_t *last_idx, bool *has_error) +{ + struct hisi_dma_dev *hw = dev_private; + uint16_t sq_head = hw->sq_head; + uint16_t cpl_num, i; + + RTE_SET_USED(vchan); + hisi_dma_scan_cq(hw); + + cpl_num = hisi_dma_calc_cpls(hw, nb_cpls); + for (i = 0; i < cpl_num; i++) { + if (hw->status[sq_head]) { + *has_error = true; + break; + } + sq_head = (sq_head + 1) & hw->sq_depth_mask; + } + if (i > 0) { + hw->cridx += i; + *last_idx = hw->cridx - 1; + hw->sq_head = sq_head; + } + hw->completed += i; + + return i; +} + +static enum rte_dma_status_code +hisi_dma_convert_status(uint16_t status) +{ + switch (status) { + case HISI_DMA_STATUS_SUCCESS: + return RTE_DMA_STATUS_SUCCESSFUL; + case HISI_DMA_STATUS_INVALID_OPCODE: + return RTE_DMA_STATUS_INVALID_OPCODE; + case HISI_DMA_STATUS_INVALID_LENGTH: + return RTE_DMA_STATUS_INVALID_LENGTH; + case HISI_DMA_STATUS_USER_ABORT: + return RTE_DMA_STATUS_USER_ABORT; + case HISI_DMA_STATUS_REMOTE_READ_ERROR: + case HISI_DMA_STATUS_AXI_READ_ERROR: + return RTE_DMA_STATUS_BUS_READ_ERROR; + case HISI_DMA_STATUS_AXI_WRITE_ERROR: + return RTE_DMA_STATUS_BUS_WRITE_ERROR; + case HISI_DMA_STATUS_DATA_POISON: + case HISI_DMA_STATUS_REMOTE_DATA_POISION: + return RTE_DMA_STATUS_DATA_POISION; + case HISI_DMA_STATUS_SQE_READ_ERROR: + case HISI_DMA_STATUS_SQE_READ_POISION: + return RTE_DMA_STATUS_DESCRIPTOR_READ_ERROR; + case HISI_DMA_STATUS_LINK_DOWN_ERROR: + return RTE_DMA_STATUS_DEV_LINK_ERROR; + default: + return RTE_DMA_STATUS_ERROR_UNKNOWN; + } +} + +static uint16_t +hisi_dma_completed_status(void *dev_private, + uint16_t vchan, const uint16_t nb_cpls, + uint16_t *last_idx, enum rte_dma_status_code *status) +{ + struct hisi_dma_dev *hw = dev_private; + uint16_t sq_head = hw->sq_head; + uint16_t cpl_num, i; + + RTE_SET_USED(vchan); + hisi_dma_scan_cq(hw); + + cpl_num = hisi_dma_calc_cpls(hw, nb_cpls); + for (i = 0; i < cpl_num; i++) { + status[i] = hisi_dma_convert_status(hw->status[sq_head]); + hw->errors += !!status[i]; + hw->status[sq_head] = HISI_DMA_STATUS_SUCCESS; + sq_head = (sq_head + 1) & hw->sq_depth_mask; + } + if (likely(cpl_num > 0)) { + hw->cridx += cpl_num; + *last_idx = hw->cridx - 1; + hw->sq_head = sq_head; + } + hw->completed += cpl_num; + + return cpl_num; +} + +static uint16_t +hisi_dma_burst_capacity(const void *dev_private, uint16_t vchan) +{ + const struct hisi_dma_dev *hw = dev_private; + uint16_t sq_head = hw->sq_head; + uint16_t sq_tail = hw->sq_tail; + + RTE_SET_USED(vchan); + + return (sq_tail >= sq_head) ? hw->sq_depth_mask - sq_tail + sq_head : + sq_head - 1 - sq_tail; +} + static void hisi_dma_gen_pci_device_name(const struct rte_pci_device *pci_dev, char *name, size_t size) @@ -597,6 +797,12 @@ hisi_dma_create(struct rte_pci_device *pci_dev, uint8_t queue_id, dev->device = &pci_dev->device; dev->dev_ops = &hisi_dmadev_ops; + dev->fp_obj->dev_private = dev->data->dev_private; + dev->fp_obj->copy = hisi_dma_copy; + dev->fp_obj->submit = hisi_dma_submit; + dev->fp_obj->completed = hisi_dma_completed; + dev->fp_obj->completed_status = hisi_dma_completed_status; + dev->fp_obj->burst_capacity = hisi_dma_burst_capacity; hw = dev->data->dev_private; hw->data = dev->data; diff --git a/drivers/dma/hisilicon/hisi_dmadev.h b/drivers/dma/hisilicon/hisi_dmadev.h index dd0315cd31..12e209c86e 100644 --- a/drivers/dma/hisilicon/hisi_dmadev.h +++ b/drivers/dma/hisilicon/hisi_dmadev.h @@ -115,6 +115,22 @@ enum { HISI_DMA_STATE_RUN, }; +/** + * Hardware complete status define: + */ +#define HISI_DMA_STATUS_SUCCESS 0x0 +#define HISI_DMA_STATUS_INVALID_OPCODE 0x1 +#define HISI_DMA_STATUS_INVALID_LENGTH 0x2 +#define HISI_DMA_STATUS_USER_ABORT 0x4 +#define HISI_DMA_STATUS_REMOTE_READ_ERROR 0x10 +#define HISI_DMA_STATUS_AXI_READ_ERROR 0x20 +#define HISI_DMA_STATUS_AXI_WRITE_ERROR 0x40 +#define HISI_DMA_STATUS_DATA_POISON 0x80 +#define HISI_DMA_STATUS_SQE_READ_ERROR 0x100 +#define HISI_DMA_STATUS_SQE_READ_POISION 0x200 +#define HISI_DMA_STATUS_REMOTE_DATA_POISION 0x400 +#define HISI_DMA_STATUS_LINK_DOWN_ERROR 0x800 + /** * After scanning the CQ array, the CQ head register needs to be updated. * Updating the register involves write memory barrier operations. From patchwork Tue Nov 2 12:37:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: fengchengwen X-Patchwork-Id: 103481 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 BF8DFA0C4E; Tue, 2 Nov 2021 13:42:37 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D06A24114A; Tue, 2 Nov 2021 13:42:26 +0100 (CET) Received: from szxga03-in.huawei.com (szxga03-in.huawei.com [45.249.212.189]) by mails.dpdk.org (Postfix) with ESMTP id 8AB694068F for ; Tue, 2 Nov 2021 13:42:23 +0100 (CET) Received: from dggemv704-chm.china.huawei.com (unknown [172.30.72.56]) by szxga03-in.huawei.com (SkyGuard) with ESMTP id 4Hk8dd6yqJzSh4b; Tue, 2 Nov 2021 20:40:53 +0800 (CST) Received: from dggpeml500024.china.huawei.com (7.185.36.10) by dggemv704-chm.china.huawei.com (10.3.19.47) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Tue, 2 Nov 2021 20:42:22 +0800 Received: from localhost.localdomain (10.67.165.24) by dggpeml500024.china.huawei.com (7.185.36.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Tue, 2 Nov 2021 20:42:19 +0800 From: Chengwen Feng To: CC: Date: Tue, 2 Nov 2021 20:37:42 +0800 Message-ID: <20211102123743.13497-6-fengchengwen@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211102123743.13497-1-fengchengwen@huawei.com> References: <20211030103619.29924-1-fengchengwen@huawei.com> <20211102123743.13497-1-fengchengwen@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.165.24] X-ClientProxiedBy: dggems702-chm.china.huawei.com (10.3.19.179) To dggpeml500024.china.huawei.com (7.185.36.10) X-CFilter-Loop: Reflected Subject: [dpdk-dev] [PATCH v2 5/6] dma/hisilicon: support multi-process 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" This patch add multi-process support for Kunpeng DMA devices. Signed-off-by: Chengwen Feng --- drivers/dma/hisilicon/hisi_dmadev.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/dma/hisilicon/hisi_dmadev.c b/drivers/dma/hisilicon/hisi_dmadev.c index d03967cae3..05066b4d0e 100644 --- a/drivers/dma/hisilicon/hisi_dmadev.c +++ b/drivers/dma/hisilicon/hisi_dmadev.c @@ -392,8 +392,10 @@ hisi_dma_stop(struct rte_dma_dev *dev) static int hisi_dma_close(struct rte_dma_dev *dev) { - /* The dmadev already stopped */ - hisi_dma_free_iomem(dev->data->dev_private); + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + /* The dmadev already stopped */ + hisi_dma_free_iomem(dev->data->dev_private); + } return 0; } @@ -815,11 +817,13 @@ hisi_dma_create(struct rte_pci_device *pci_dev, uint8_t queue_id, hw->cq_head_reg = hisi_dma_queue_regaddr(hw, HISI_DMA_QUEUE_CQ_HEAD_REG); - ret = hisi_dma_reset_hw(hw); - if (ret) { - HISI_DMA_LOG(ERR, "%s init device fail!", name); - (void)rte_dma_pmd_release(name); - return -EIO; + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + ret = hisi_dma_reset_hw(hw); + if (ret) { + HISI_DMA_LOG(ERR, "%s init device fail!", name); + (void)rte_dma_pmd_release(name); + return -EIO; + } } dev->state = RTE_DMA_DEV_READY; @@ -872,7 +876,8 @@ hisi_dma_probe(struct rte_pci_driver *pci_drv __rte_unused, return ret; HISI_DMA_LOG(DEBUG, "%s read PCI revision: 0x%x", name, revision); - hisi_dma_init_gbl(pci_dev->mem_resource[2].addr, revision); + if (rte_eal_process_type() == RTE_PROC_PRIMARY) + hisi_dma_init_gbl(pci_dev->mem_resource[2].addr, revision); for (i = 0; i < HISI_DMA_MAX_HW_QUEUES; i++) { ret = hisi_dma_create(pci_dev, i, revision); From patchwork Tue Nov 2 12:37:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: fengchengwen X-Patchwork-Id: 103485 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 42554A0C4E; Tue, 2 Nov 2021 13:43:04 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5B0014116A; Tue, 2 Nov 2021 13:42:31 +0100 (CET) Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by mails.dpdk.org (Postfix) with ESMTP id 84A2841140 for ; Tue, 2 Nov 2021 13:42:23 +0100 (CET) Received: from dggemv704-chm.china.huawei.com (unknown [172.30.72.57]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4Hk8cy2bXvzZcff; Tue, 2 Nov 2021 20:40:18 +0800 (CST) Received: from dggpeml500024.china.huawei.com (7.185.36.10) by dggemv704-chm.china.huawei.com (10.3.19.47) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Tue, 2 Nov 2021 20:42:22 +0800 Received: from localhost.localdomain (10.67.165.24) by dggpeml500024.china.huawei.com (7.185.36.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Tue, 2 Nov 2021 20:42:19 +0800 From: Chengwen Feng To: CC: Date: Tue, 2 Nov 2021 20:37:43 +0800 Message-ID: <20211102123743.13497-7-fengchengwen@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211102123743.13497-1-fengchengwen@huawei.com> References: <20211030103619.29924-1-fengchengwen@huawei.com> <20211102123743.13497-1-fengchengwen@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.165.24] X-ClientProxiedBy: dggems702-chm.china.huawei.com (10.3.19.179) To dggpeml500024.china.huawei.com (7.185.36.10) X-CFilter-Loop: Reflected Subject: [dpdk-dev] [PATCH v2 6/6] devbind: add Kunpeng DMA to dmadev category 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 Kunpeng DMA device ID to dmadev category. Signed-off-by: Chengwen Feng --- usertools/dpdk-devbind.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py index bb00f43702..a74a68ed82 100755 --- a/usertools/dpdk-devbind.py +++ b/usertools/dpdk-devbind.py @@ -68,10 +68,14 @@ intel_ntb_icx = {'Class': '06', 'Vendor': '8086', 'Device': '347e', 'SVendor': None, 'SDevice': None} +hisilicon_dma = {'Class': '08', 'Vendor': '19e5', 'Device': 'a122', + 'SVendor': None, 'SDevice': None} + network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class] baseband_devices = [acceleration_class] crypto_devices = [encryption_class, intel_processor_class] -dma_devices = [intel_idxd_spr, intel_ioat_bdw, intel_ioat_icx, intel_ioat_skx] +dma_devices = [intel_idxd_spr, intel_ioat_bdw, intel_ioat_icx, intel_ioat_skx, + hisilicon_dma] eventdev_devices = [cavium_sso, cavium_tim, intel_dlb, octeontx2_sso] mempool_devices = [cavium_fpa, octeontx2_npa] compress_devices = [cavium_zip]