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 /* Dump DMA device info. */
20 __dev_dump(void *dev_private, FILE *f)
22 struct ioat_dmadev *ioat = dev_private;
23 uint64_t chansts_masked = ioat->regs->chansts & IOAT_CHANSTS_STATUS;
24 uint32_t chanerr = ioat->regs->chanerr;
25 uint64_t mask = (ioat->qcfg.nb_desc - 1);
26 char ver = ioat->version;
27 fprintf(f, "========= IOAT =========\n");
28 fprintf(f, " IOAT version: %d.%d\n", ver >> 4, ver & 0xF);
29 fprintf(f, " Channel status: %s [0x%"PRIx64"]\n",
30 chansts_readable[chansts_masked], chansts_masked);
31 fprintf(f, " ChainADDR: 0x%"PRIu64"\n", ioat->regs->chainaddr);
33 fprintf(f, " No Channel Errors\n");
35 fprintf(f, " ChanERR: 0x%"PRIu32"\n", chanerr);
36 if (chanerr & IOAT_CHANERR_INVALID_SRC_ADDR_MASK)
37 fprintf(f, " Invalid Source Address\n");
38 if (chanerr & IOAT_CHANERR_INVALID_DST_ADDR_MASK)
39 fprintf(f, " Invalid Destination Address\n");
40 if (chanerr & IOAT_CHANERR_INVALID_LENGTH_MASK)
41 fprintf(f, " Invalid Descriptor Length\n");
42 if (chanerr & IOAT_CHANERR_DESCRIPTOR_READ_ERROR_MASK)
43 fprintf(f, " Descriptor Read Error\n");
44 if ((chanerr & ~(IOAT_CHANERR_INVALID_SRC_ADDR_MASK |
45 IOAT_CHANERR_INVALID_DST_ADDR_MASK |
46 IOAT_CHANERR_INVALID_LENGTH_MASK |
47 IOAT_CHANERR_DESCRIPTOR_READ_ERROR_MASK)) != 0)
48 fprintf(f, " Unknown Error(s)\n");
50 fprintf(f, "== Private Data ==\n");
51 fprintf(f, " Config: { ring_size: %u }\n", ioat->qcfg.nb_desc);
52 fprintf(f, " Status: 0x%"PRIx64"\n", ioat->status);
53 fprintf(f, " Status IOVA: 0x%"PRIx64"\n", ioat->status_addr);
54 fprintf(f, " Status ADDR: %p\n", &ioat->status);
55 fprintf(f, " Ring IOVA: 0x%"PRIx64"\n", ioat->ring_addr);
56 fprintf(f, " Ring ADDR: 0x%"PRIx64"\n", ioat->desc_ring[0].next-64);
57 fprintf(f, " Next write: %"PRIu16"\n", ioat->next_write);
58 fprintf(f, " Next read: %"PRIu16"\n", ioat->next_read);
59 struct ioat_dma_hw_desc *desc_ring = &ioat->desc_ring[(ioat->next_write - 1) & mask];
60 fprintf(f, " Last Descriptor Written {\n");
61 fprintf(f, " Size: %"PRIu32"\n", desc_ring->size);
62 fprintf(f, " Control: 0x%"PRIx32"\n", desc_ring->u.control_raw);
63 fprintf(f, " Src: 0x%"PRIx64"\n", desc_ring->src_addr);
64 fprintf(f, " Dest: 0x%"PRIx64"\n", desc_ring->dest_addr);
65 fprintf(f, " Next: 0x%"PRIx64"\n", desc_ring->next);
67 fprintf(f, " Next Descriptor {\n");
68 fprintf(f, " Size: %"PRIu32"\n", ioat->desc_ring[ioat->next_read & mask].size);
69 fprintf(f, " Src: 0x%"PRIx64"\n", ioat->desc_ring[ioat->next_read & mask].src_addr);
70 fprintf(f, " Dest: 0x%"PRIx64"\n", ioat->desc_ring[ioat->next_read & mask].dest_addr);
71 fprintf(f, " Next: 0x%"PRIx64"\n", ioat->desc_ring[ioat->next_read & mask].next);
77 /* Public wrapper for dump. */
79 ioat_dev_dump(const struct rte_dma_dev *dev, FILE *f)
81 return __dev_dump(dev->fp_obj->dev_private, f);
84 /* Create a DMA device. */
86 ioat_dmadev_create(const char *name, struct rte_pci_device *dev)
88 static const struct rte_dma_dev_ops ioat_dmadev_ops = {
89 .dev_dump = ioat_dev_dump,
92 struct rte_dma_dev *dmadev = NULL;
93 struct ioat_dmadev *ioat = NULL;
97 IOAT_PMD_ERR("Invalid name of the device!");
101 /* Allocate device structure. */
102 dmadev = rte_dma_pmd_allocate(name, dev->device.numa_node, sizeof(struct ioat_dmadev));
103 if (dmadev == NULL) {
104 IOAT_PMD_ERR("Unable to allocate dma device");
108 dmadev->device = &dev->device;
110 dmadev->fp_obj->dev_private = dmadev->data->dev_private;
112 dmadev->dev_ops = &ioat_dmadev_ops;
114 ioat = dmadev->data->dev_private;
115 ioat->dmadev = dmadev;
116 ioat->regs = dev->mem_resource[0].addr;
117 ioat->doorbell = &ioat->regs->dmacount;
118 ioat->qcfg.nb_desc = 0;
119 ioat->desc_ring = NULL;
120 ioat->version = ioat->regs->cbver;
122 /* Do device initialization - reset and set error behaviour. */
123 if (ioat->regs->chancnt != 1)
124 IOAT_PMD_WARN("%s: Channel count == %d\n", __func__,
125 ioat->regs->chancnt);
127 /* Locked by someone else. */
128 if (ioat->regs->chanctrl & IOAT_CHANCTRL_CHANNEL_IN_USE) {
129 IOAT_PMD_WARN("%s: Channel appears locked\n", __func__);
130 ioat->regs->chanctrl = 0;
133 /* clear any previous errors */
134 if (ioat->regs->chanerr != 0) {
135 uint32_t val = ioat->regs->chanerr;
136 ioat->regs->chanerr = val;
139 ioat->regs->chancmd = IOAT_CHANCMD_SUSPEND;
141 ioat->regs->chancmd = IOAT_CHANCMD_RESET;
143 while (ioat->regs->chancmd & IOAT_CHANCMD_RESET) {
144 ioat->regs->chainaddr = 0;
146 if (++retry >= 200) {
147 IOAT_PMD_ERR("%s: cannot reset device. CHANCMD=%#"PRIx8
148 ", CHANSTS=%#"PRIx64", CHANERR=%#"PRIx32"\n",
152 ioat->regs->chanerr);
153 rte_dma_pmd_release(name);
157 ioat->regs->chanctrl = IOAT_CHANCTRL_ANY_ERR_ABORT_EN |
158 IOAT_CHANCTRL_ERR_COMPLETION_EN;
160 dmadev->fp_obj->dev_private = ioat;
162 dmadev->state = RTE_DMA_DEV_READY;
168 /* Destroy a DMA device. */
170 ioat_dmadev_destroy(const char *name)
175 IOAT_PMD_ERR("Invalid device name");
179 ret = rte_dma_pmd_release(name);
181 IOAT_PMD_DEBUG("Device cleanup failed");
186 /* Probe DMA device. */
188 ioat_dmadev_probe(struct rte_pci_driver *drv, struct rte_pci_device *dev)
192 rte_pci_device_name(&dev->addr, name, sizeof(name));
193 IOAT_PMD_INFO("Init %s on NUMA node %d", name, dev->device.numa_node);
195 dev->device.driver = &drv->driver;
196 return ioat_dmadev_create(name, dev);
199 /* Remove DMA device. */
201 ioat_dmadev_remove(struct rte_pci_device *dev)
205 rte_pci_device_name(&dev->addr, name, sizeof(name));
207 IOAT_PMD_INFO("Closing %s on NUMA node %d",
208 name, dev->device.numa_node);
210 return ioat_dmadev_destroy(name);
213 static const struct rte_pci_id pci_id_ioat_map[] = {
214 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_SKX) },
215 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX0) },
216 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX1) },
217 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX2) },
218 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX3) },
219 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX4) },
220 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX5) },
221 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX6) },
222 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX7) },
223 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDXE) },
224 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDXF) },
225 { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_ICX) },
226 { .vendor_id = 0, /* sentinel */ },
229 static struct rte_pci_driver ioat_pmd_drv = {
230 .id_table = pci_id_ioat_map,
231 .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
232 .probe = ioat_dmadev_probe,
233 .remove = ioat_dmadev_remove,
236 RTE_PMD_REGISTER_PCI(IOAT_PMD_NAME, ioat_pmd_drv);
237 RTE_PMD_REGISTER_PCI_TABLE(IOAT_PMD_NAME, pci_id_ioat_map);
238 RTE_PMD_REGISTER_KMOD_DEP(IOAT_PMD_NAME, "* igb_uio | uio_pci_generic | vfio-pci");