1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2021 Intel Corporation
5 #include <rte_bus_pci.h>
6 #include <rte_dmadev_pmd.h>
7 #include <rte_malloc.h>
9 #include "ioat_internal.h"
11 static struct rte_pci_driver ioat_pmd_drv;
13 RTE_LOG_REGISTER_DEFAULT(ioat_pmd_logtype, INFO);
15 #define IOAT_PMD_NAME dmadev_ioat
16 #define IOAT_PMD_NAME_STR RTE_STR(IOAT_PMD_NAME)
18 /* Create a DMA device. */
20 ioat_dmadev_create(const char *name, struct rte_pci_device *dev)
22 static const struct rte_dma_dev_ops ioat_dmadev_ops = { };
24 struct rte_dma_dev *dmadev = NULL;
25 struct ioat_dmadev *ioat = NULL;
29 IOAT_PMD_ERR("Invalid name of the device!");
33 /* Allocate device structure. */
34 dmadev = rte_dma_pmd_allocate(name, dev->device.numa_node, sizeof(struct ioat_dmadev));
36 IOAT_PMD_ERR("Unable to allocate dma device");
40 dmadev->device = &dev->device;
42 dmadev->fp_obj->dev_private = dmadev->data->dev_private;
44 dmadev->dev_ops = &ioat_dmadev_ops;
46 ioat = dmadev->data->dev_private;
47 ioat->dmadev = dmadev;
48 ioat->regs = dev->mem_resource[0].addr;
49 ioat->doorbell = &ioat->regs->dmacount;
50 ioat->qcfg.nb_desc = 0;
51 ioat->desc_ring = NULL;
52 ioat->version = ioat->regs->cbver;
54 /* Do device initialization - reset and set error behaviour. */
55 if (ioat->regs->chancnt != 1)
56 IOAT_PMD_WARN("%s: Channel count == %d\n", __func__,
59 /* Locked by someone else. */
60 if (ioat->regs->chanctrl & IOAT_CHANCTRL_CHANNEL_IN_USE) {
61 IOAT_PMD_WARN("%s: Channel appears locked\n", __func__);
62 ioat->regs->chanctrl = 0;
65 /* clear any previous errors */
66 if (ioat->regs->chanerr != 0) {
67 uint32_t val = ioat->regs->chanerr;
68 ioat->regs->chanerr = val;
71 ioat->regs->chancmd = IOAT_CHANCMD_SUSPEND;
73 ioat->regs->chancmd = IOAT_CHANCMD_RESET;
75 while (ioat->regs->chancmd & IOAT_CHANCMD_RESET) {
76 ioat->regs->chainaddr = 0;
79 IOAT_PMD_ERR("%s: cannot reset device. CHANCMD=%#"PRIx8
80 ", CHANSTS=%#"PRIx64", CHANERR=%#"PRIx32"\n",
85 rte_dma_pmd_release(name);
89 ioat->regs->chanctrl = IOAT_CHANCTRL_ANY_ERR_ABORT_EN |
90 IOAT_CHANCTRL_ERR_COMPLETION_EN;
92 dmadev->fp_obj->dev_private = ioat;
94 dmadev->state = RTE_DMA_DEV_READY;
100 /* Destroy a DMA device. */
102 ioat_dmadev_destroy(const char *name)
107 IOAT_PMD_ERR("Invalid device name");
111 ret = rte_dma_pmd_release(name);
113 IOAT_PMD_DEBUG("Device cleanup failed");
118 /* Probe DMA device. */
120 ioat_dmadev_probe(struct rte_pci_driver *drv, struct rte_pci_device *dev)
124 rte_pci_device_name(&dev->addr, name, sizeof(name));
125 IOAT_PMD_INFO("Init %s on NUMA node %d", name, dev->device.numa_node);
127 dev->device.driver = &drv->driver;
128 return ioat_dmadev_create(name, dev);
131 /* Remove DMA device. */
133 ioat_dmadev_remove(struct rte_pci_device *dev)
137 rte_pci_device_name(&dev->addr, name, sizeof(name));
139 IOAT_PMD_INFO("Closing %s on NUMA node %d",
140 name, dev->device.numa_node);
142 return ioat_dmadev_destroy(name);
145 static const struct rte_pci_id pci_id_ioat_map[] = {
146 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_SKX) },
147 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX0) },
148 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX1) },
149 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX2) },
150 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX3) },
151 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX4) },
152 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX5) },
153 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX6) },
154 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX7) },
155 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDXE) },
156 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDXF) },
157 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_ICX) },
158 { .vendor_id = 0, /* sentinel */ },
161 static struct rte_pci_driver ioat_pmd_drv = {
162 .id_table = pci_id_ioat_map,
163 .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
164 .probe = ioat_dmadev_probe,
165 .remove = ioat_dmadev_remove,
168 RTE_PMD_REGISTER_PCI(IOAT_PMD_NAME, ioat_pmd_drv);
169 RTE_PMD_REGISTER_PCI_TABLE(IOAT_PMD_NAME, pci_id_ioat_map);
170 RTE_PMD_REGISTER_KMOD_DEP(IOAT_PMD_NAME, "* igb_uio | uio_pci_generic | vfio-pci");