dma/ioat: add statistics
[dpdk.git] / drivers / dma / ioat / ioat_dmadev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2021 Intel Corporation
3  */
4
5 #include <rte_bus_pci.h>
6 #include <rte_dmadev_pmd.h>
7 #include <rte_malloc.h>
8 #include <rte_prefetch.h>
9 #include <rte_errno.h>
10
11 #include "ioat_internal.h"
12
13 static struct rte_pci_driver ioat_pmd_drv;
14
15 RTE_LOG_REGISTER_DEFAULT(ioat_pmd_logtype, INFO);
16
17 #define DESC_SZ sizeof(struct ioat_dma_hw_desc)
18
19 #define IOAT_PMD_NAME dmadev_ioat
20 #define IOAT_PMD_NAME_STR RTE_STR(IOAT_PMD_NAME)
21
22 /* IOAT operations. */
23 enum rte_ioat_ops {
24         ioat_op_copy = 0,       /* Standard DMA Operation */
25         ioat_op_fill            /* Block Fill */
26 };
27
28 /* Configure a device. */
29 static int
30 ioat_dev_configure(struct rte_dma_dev *dev __rte_unused, const struct rte_dma_conf *dev_conf,
31                 uint32_t conf_sz)
32 {
33         if (sizeof(struct rte_dma_conf) != conf_sz)
34                 return -EINVAL;
35
36         if (dev_conf->nb_vchans != 1)
37                 return -EINVAL;
38
39         return 0;
40 }
41
42 /* Setup a virtual channel for IOAT, only 1 vchan is supported. */
43 static int
44 ioat_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan __rte_unused,
45                 const struct rte_dma_vchan_conf *qconf, uint32_t qconf_sz)
46 {
47         struct ioat_dmadev *ioat = dev->fp_obj->dev_private;
48         uint16_t max_desc = qconf->nb_desc;
49         int i;
50
51         if (sizeof(struct rte_dma_vchan_conf) != qconf_sz)
52                 return -EINVAL;
53
54         ioat->qcfg = *qconf;
55
56         if (!rte_is_power_of_2(max_desc)) {
57                 max_desc = rte_align32pow2(max_desc);
58                 IOAT_PMD_DEBUG("DMA dev %u using %u descriptors", dev->data->dev_id, max_desc);
59                 ioat->qcfg.nb_desc = max_desc;
60         }
61
62         /* In case we are reconfiguring a device, free any existing memory. */
63         rte_free(ioat->desc_ring);
64
65         ioat->desc_ring = rte_zmalloc(NULL, sizeof(*ioat->desc_ring) * max_desc, 0);
66         if (ioat->desc_ring == NULL)
67                 return -ENOMEM;
68
69         ioat->ring_addr = rte_mem_virt2iova(ioat->desc_ring);
70
71         ioat->status_addr = rte_mem_virt2iova(ioat) + offsetof(struct ioat_dmadev, status);
72
73         /* Ensure all counters are reset, if reconfiguring/restarting device. */
74         ioat->next_read = 0;
75         ioat->next_write = 0;
76         ioat->last_write = 0;
77         ioat->offset = 0;
78         ioat->failure = 0;
79
80         /* Reset Stats. */
81         ioat->stats = (struct rte_dma_stats){0};
82
83         /* Configure descriptor ring - each one points to next. */
84         for (i = 0; i < ioat->qcfg.nb_desc; i++) {
85                 ioat->desc_ring[i].next = ioat->ring_addr +
86                                 (((i + 1) % ioat->qcfg.nb_desc) * DESC_SZ);
87         }
88
89         return 0;
90 }
91
92 /* Recover IOAT device. */
93 static inline int
94 __ioat_recover(struct ioat_dmadev *ioat)
95 {
96         uint32_t chanerr, retry = 0;
97         uint16_t mask = ioat->qcfg.nb_desc - 1;
98
99         /* Clear any channel errors. Reading and writing to chanerr does this. */
100         chanerr = ioat->regs->chanerr;
101         ioat->regs->chanerr = chanerr;
102
103         /* Reset Channel. */
104         ioat->regs->chancmd = IOAT_CHANCMD_RESET;
105
106         /* Write new chain address to trigger state change. */
107         ioat->regs->chainaddr = ioat->desc_ring[(ioat->next_read - 1) & mask].next;
108         /* Ensure channel control and status addr are correct. */
109         ioat->regs->chanctrl = IOAT_CHANCTRL_ANY_ERR_ABORT_EN |
110                         IOAT_CHANCTRL_ERR_COMPLETION_EN;
111         ioat->regs->chancmp = ioat->status_addr;
112
113         /* Allow HW time to move to the ARMED state. */
114         do {
115                 rte_pause();
116                 retry++;
117         } while (ioat->regs->chansts != IOAT_CHANSTS_ARMED && retry < 200);
118
119         /* Exit as failure if device is still HALTED. */
120         if (ioat->regs->chansts != IOAT_CHANSTS_ARMED)
121                 return -1;
122
123         /* Store next write as offset as recover will move HW and SW ring out of sync. */
124         ioat->offset = ioat->next_read;
125
126         /* Prime status register with previous address. */
127         ioat->status = ioat->desc_ring[(ioat->next_read - 2) & mask].next;
128
129         return 0;
130 }
131
132 /* Start a configured device. */
133 static int
134 ioat_dev_start(struct rte_dma_dev *dev)
135 {
136         struct ioat_dmadev *ioat = dev->fp_obj->dev_private;
137
138         if (ioat->qcfg.nb_desc == 0 || ioat->desc_ring == NULL)
139                 return -EBUSY;
140
141         /* Inform hardware of where the descriptor ring is. */
142         ioat->regs->chainaddr = ioat->ring_addr;
143         /* Inform hardware of where to write the status/completions. */
144         ioat->regs->chancmp = ioat->status_addr;
145
146         /* Prime the status register to be set to the last element. */
147         ioat->status = ioat->ring_addr + ((ioat->qcfg.nb_desc - 1) * DESC_SZ);
148
149         printf("IOAT.status: %s [0x%"PRIx64"]\n",
150                         chansts_readable[ioat->status & IOAT_CHANSTS_STATUS],
151                         ioat->status);
152
153         if ((ioat->regs->chansts & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_HALTED) {
154                 IOAT_PMD_WARN("Device HALTED on start, attempting to recover\n");
155                 if (__ioat_recover(ioat) != 0) {
156                         IOAT_PMD_ERR("Device couldn't be recovered");
157                         return -1;
158                 }
159         }
160
161         return 0;
162 }
163
164 /* Stop a configured device. */
165 static int
166 ioat_dev_stop(struct rte_dma_dev *dev)
167 {
168         struct ioat_dmadev *ioat = dev->fp_obj->dev_private;
169         uint32_t retry = 0;
170
171         ioat->regs->chancmd = IOAT_CHANCMD_SUSPEND;
172
173         do {
174                 rte_pause();
175                 retry++;
176         } while ((ioat->regs->chansts & IOAT_CHANSTS_STATUS) != IOAT_CHANSTS_SUSPENDED
177                         && retry < 200);
178
179         return ((ioat->regs->chansts & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_SUSPENDED) ? 0 : -1;
180 }
181
182 /* Get device information of a device. */
183 static int
184 ioat_dev_info_get(const struct rte_dma_dev *dev, struct rte_dma_info *info, uint32_t size)
185 {
186         struct ioat_dmadev *ioat = dev->fp_obj->dev_private;
187         if (size < sizeof(*info))
188                 return -EINVAL;
189         info->dev_capa = RTE_DMA_CAPA_MEM_TO_MEM |
190                         RTE_DMA_CAPA_OPS_COPY |
191                         RTE_DMA_CAPA_OPS_FILL;
192         if (ioat->version >= IOAT_VER_3_4)
193                 info->dev_capa |= RTE_DMA_CAPA_HANDLES_ERRORS;
194         info->max_vchans = 1;
195         info->min_desc = 32;
196         info->max_desc = 4096;
197         return 0;
198 }
199
200 /* Close a configured device. */
201 static int
202 ioat_dev_close(struct rte_dma_dev *dev)
203 {
204         struct ioat_dmadev *ioat;
205
206         if (!dev) {
207                 IOAT_PMD_ERR("Invalid device");
208                 return -EINVAL;
209         }
210
211         ioat = dev->fp_obj->dev_private;
212         if (!ioat) {
213                 IOAT_PMD_ERR("Error getting dev_private");
214                 return -EINVAL;
215         }
216
217         rte_free(ioat->desc_ring);
218
219         return 0;
220 }
221
222 /* Trigger hardware to begin performing enqueued operations. */
223 static inline void
224 __submit(struct ioat_dmadev *ioat)
225 {
226         *ioat->doorbell = ioat->next_write - ioat->offset;
227
228         ioat->stats.submitted += (uint16_t)(ioat->next_write - ioat->last_write);
229
230         ioat->last_write = ioat->next_write;
231 }
232
233 /* External submit function wrapper. */
234 static int
235 ioat_submit(void *dev_private, uint16_t qid __rte_unused)
236 {
237         struct ioat_dmadev *ioat = dev_private;
238
239         __submit(ioat);
240
241         return 0;
242 }
243
244 /* Write descriptor for enqueue. */
245 static inline int
246 __write_desc(void *dev_private, uint32_t op, uint64_t src, phys_addr_t dst,
247                 unsigned int length, uint64_t flags)
248 {
249         struct ioat_dmadev *ioat = dev_private;
250         uint16_t ret;
251         const unsigned short mask = ioat->qcfg.nb_desc - 1;
252         const unsigned short read = ioat->next_read;
253         unsigned short write = ioat->next_write;
254         const unsigned short space = mask + read - write;
255         struct ioat_dma_hw_desc *desc;
256
257         if (space == 0)
258                 return -ENOSPC;
259
260         ioat->next_write = write + 1;
261         write &= mask;
262
263         desc = &ioat->desc_ring[write];
264         desc->size = length;
265         desc->u.control_raw = (uint32_t)((op << IOAT_CMD_OP_SHIFT) |
266                         (1 << IOAT_COMP_UPDATE_SHIFT));
267
268         /* In IOAT the fence ensures that all operations including the current one
269          * are completed before moving on, DMAdev assumes that the fence ensures
270          * all operations before the current one are completed before starting
271          * the current one, so in IOAT we set the fence for the previous descriptor.
272          */
273         if (flags & RTE_DMA_OP_FLAG_FENCE)
274                 ioat->desc_ring[(write - 1) & mask].u.control.fence = 1;
275
276         desc->src_addr = src;
277         desc->dest_addr = dst;
278
279         rte_prefetch0(&ioat->desc_ring[ioat->next_write & mask]);
280
281         ret = (uint16_t)(ioat->next_write - 1);
282
283         if (flags & RTE_DMA_OP_FLAG_SUBMIT)
284                 __submit(ioat);
285
286         return ret;
287 }
288
289 /* Enqueue a fill operation onto the ioat device. */
290 static int
291 ioat_enqueue_fill(void *dev_private, uint16_t qid __rte_unused, uint64_t pattern,
292                 rte_iova_t dst, unsigned int length, uint64_t flags)
293 {
294         return __write_desc(dev_private, ioat_op_fill, pattern, dst, length, flags);
295 }
296
297 /* Enqueue a copy operation onto the ioat device. */
298 static int
299 ioat_enqueue_copy(void *dev_private, uint16_t qid __rte_unused, rte_iova_t src,
300                 rte_iova_t dst, unsigned int length, uint64_t flags)
301 {
302         return __write_desc(dev_private, ioat_op_copy, src, dst, length, flags);
303 }
304
305 /* Dump DMA device info. */
306 static int
307 __dev_dump(void *dev_private, FILE *f)
308 {
309         struct ioat_dmadev *ioat = dev_private;
310         uint64_t chansts_masked = ioat->regs->chansts & IOAT_CHANSTS_STATUS;
311         uint32_t chanerr = ioat->regs->chanerr;
312         uint64_t mask = (ioat->qcfg.nb_desc - 1);
313         char ver = ioat->version;
314         fprintf(f, "========= IOAT =========\n");
315         fprintf(f, "  IOAT version: %d.%d\n", ver >> 4, ver & 0xF);
316         fprintf(f, "  Channel status: %s [0x%"PRIx64"]\n",
317                         chansts_readable[chansts_masked], chansts_masked);
318         fprintf(f, "  ChainADDR: 0x%"PRIu64"\n", ioat->regs->chainaddr);
319         if (chanerr == 0) {
320                 fprintf(f, "  No Channel Errors\n");
321         } else {
322                 fprintf(f, "  ChanERR: 0x%"PRIu32"\n", chanerr);
323                 if (chanerr & IOAT_CHANERR_INVALID_SRC_ADDR_MASK)
324                         fprintf(f, "    Invalid Source Address\n");
325                 if (chanerr & IOAT_CHANERR_INVALID_DST_ADDR_MASK)
326                         fprintf(f, "    Invalid Destination Address\n");
327                 if (chanerr & IOAT_CHANERR_INVALID_LENGTH_MASK)
328                         fprintf(f, "    Invalid Descriptor Length\n");
329                 if (chanerr & IOAT_CHANERR_DESCRIPTOR_READ_ERROR_MASK)
330                         fprintf(f, "    Descriptor Read Error\n");
331                 if ((chanerr & ~(IOAT_CHANERR_INVALID_SRC_ADDR_MASK |
332                                 IOAT_CHANERR_INVALID_DST_ADDR_MASK |
333                                 IOAT_CHANERR_INVALID_LENGTH_MASK |
334                                 IOAT_CHANERR_DESCRIPTOR_READ_ERROR_MASK)) != 0)
335                         fprintf(f, "    Unknown Error(s)\n");
336         }
337         fprintf(f, "== Private Data ==\n");
338         fprintf(f, "  Config: { ring_size: %u }\n", ioat->qcfg.nb_desc);
339         fprintf(f, "  Status: 0x%"PRIx64"\n", ioat->status);
340         fprintf(f, "  Status IOVA: 0x%"PRIx64"\n", ioat->status_addr);
341         fprintf(f, "  Status ADDR: %p\n", &ioat->status);
342         fprintf(f, "  Ring IOVA: 0x%"PRIx64"\n", ioat->ring_addr);
343         fprintf(f, "  Ring ADDR: 0x%"PRIx64"\n", ioat->desc_ring[0].next-64);
344         fprintf(f, "  Next write: %"PRIu16"\n", ioat->next_write);
345         fprintf(f, "  Next read: %"PRIu16"\n", ioat->next_read);
346         struct ioat_dma_hw_desc *desc_ring = &ioat->desc_ring[(ioat->next_write - 1) & mask];
347         fprintf(f, "  Last Descriptor Written {\n");
348         fprintf(f, "    Size: %"PRIu32"\n", desc_ring->size);
349         fprintf(f, "    Control: 0x%"PRIx32"\n", desc_ring->u.control_raw);
350         fprintf(f, "    Src: 0x%"PRIx64"\n", desc_ring->src_addr);
351         fprintf(f, "    Dest: 0x%"PRIx64"\n", desc_ring->dest_addr);
352         fprintf(f, "    Next: 0x%"PRIx64"\n", desc_ring->next);
353         fprintf(f, "  }\n");
354         fprintf(f, "  Next Descriptor {\n");
355         fprintf(f, "    Size: %"PRIu32"\n", ioat->desc_ring[ioat->next_read & mask].size);
356         fprintf(f, "    Src: 0x%"PRIx64"\n", ioat->desc_ring[ioat->next_read & mask].src_addr);
357         fprintf(f, "    Dest: 0x%"PRIx64"\n", ioat->desc_ring[ioat->next_read & mask].dest_addr);
358         fprintf(f, "    Next: 0x%"PRIx64"\n", ioat->desc_ring[ioat->next_read & mask].next);
359         fprintf(f, "  }\n");
360         fprintf(f, "  Key Stats { submitted: %"PRIu64", comp: %"PRIu64", failed: %"PRIu64" }\n",
361                         ioat->stats.submitted,
362                         ioat->stats.completed,
363                         ioat->stats.errors);
364
365         return 0;
366 }
367
368 /* Public wrapper for dump. */
369 static int
370 ioat_dev_dump(const struct rte_dma_dev *dev, FILE *f)
371 {
372         return __dev_dump(dev->fp_obj->dev_private, f);
373 }
374
375 /* Returns the index of the last completed operation. */
376 static inline uint16_t
377 __get_last_completed(const struct ioat_dmadev *ioat, int *state)
378 {
379         /* Status register contains the address of the completed operation */
380         uint64_t status = ioat->status;
381
382         /* lower 3 bits indicate "transfer status" : active, idle, halted.
383          * We can ignore bit 0.
384          */
385         *state = status & IOAT_CHANSTS_STATUS;
386
387         /* If we are just after recovering from an error the address returned by
388          * status will be 0, in this case we return the offset - 1 as the last
389          * completed. If not return the status value minus the chainaddr which
390          * gives us an offset into the ring. Right shifting by 6 (divide by 64)
391          * gives the index of the completion from the HW point of view and adding
392          * the offset translates the ring index from HW to SW point of view.
393          */
394         if ((status & ~IOAT_CHANSTS_STATUS) == 0)
395                 return ioat->offset - 1;
396
397         return (status - ioat->ring_addr) >> 6;
398 }
399
400 /* Translates IOAT ChanERRs to DMA error codes. */
401 static inline enum rte_dma_status_code
402 __translate_status_ioat_to_dma(uint32_t chanerr)
403 {
404         if (chanerr & IOAT_CHANERR_INVALID_SRC_ADDR_MASK)
405                 return RTE_DMA_STATUS_INVALID_SRC_ADDR;
406         else if (chanerr & IOAT_CHANERR_INVALID_DST_ADDR_MASK)
407                 return RTE_DMA_STATUS_INVALID_DST_ADDR;
408         else if (chanerr & IOAT_CHANERR_INVALID_LENGTH_MASK)
409                 return RTE_DMA_STATUS_INVALID_LENGTH;
410         else if (chanerr & IOAT_CHANERR_DESCRIPTOR_READ_ERROR_MASK)
411                 return RTE_DMA_STATUS_DESCRIPTOR_READ_ERROR;
412         else
413                 return RTE_DMA_STATUS_ERROR_UNKNOWN;
414 }
415
416 /* Returns details of operations that have been completed. */
417 static uint16_t
418 ioat_completed(void *dev_private, uint16_t qid __rte_unused, const uint16_t max_ops,
419                 uint16_t *last_idx, bool *has_error)
420 {
421         struct ioat_dmadev *ioat = dev_private;
422
423         const unsigned short mask = (ioat->qcfg.nb_desc - 1);
424         const unsigned short read = ioat->next_read;
425         unsigned short last_completed, count;
426         int state, fails = 0;
427
428         /* Do not do any work if there is an uncleared error. */
429         if (ioat->failure != 0) {
430                 *has_error = true;
431                 *last_idx = ioat->next_read - 2;
432                 return 0;
433         }
434
435         last_completed = __get_last_completed(ioat, &state);
436         count = (last_completed + 1 - read) & mask;
437
438         /* Cap count at max_ops or set as last run in batch. */
439         if (count > max_ops)
440                 count = max_ops;
441
442         if (count == max_ops || state != IOAT_CHANSTS_HALTED) {
443                 ioat->next_read = read + count;
444                 *last_idx = ioat->next_read - 1;
445         } else {
446                 *has_error = true;
447                 rte_errno = EIO;
448                 ioat->failure = ioat->regs->chanerr;
449                 ioat->next_read = read + count + 1;
450                 if (__ioat_recover(ioat) != 0) {
451                         IOAT_PMD_ERR("Device HALTED and could not be recovered\n");
452                         __dev_dump(dev_private, stdout);
453                         return 0;
454                 }
455                 __submit(ioat);
456                 fails++;
457                 *last_idx = ioat->next_read - 2;
458         }
459
460         ioat->stats.completed += count;
461         ioat->stats.errors += fails;
462
463         return count;
464 }
465
466 /* Returns detailed status information about operations that have been completed. */
467 static uint16_t
468 ioat_completed_status(void *dev_private, uint16_t qid __rte_unused,
469                 uint16_t max_ops, uint16_t *last_idx, enum rte_dma_status_code *status)
470 {
471         struct ioat_dmadev *ioat = dev_private;
472
473         const unsigned short mask = (ioat->qcfg.nb_desc - 1);
474         const unsigned short read = ioat->next_read;
475         unsigned short count, last_completed;
476         uint64_t fails = 0;
477         int state, i;
478
479         last_completed = __get_last_completed(ioat, &state);
480         count = (last_completed + 1 - read) & mask;
481
482         for (i = 0; i < RTE_MIN(count + 1, max_ops); i++)
483                 status[i] = RTE_DMA_STATUS_SUCCESSFUL;
484
485         /* Cap count at max_ops or set as last run in batch. */
486         if (count > max_ops)
487                 count = max_ops;
488
489         if (count == max_ops || state != IOAT_CHANSTS_HALTED)
490                 ioat->next_read = read + count;
491         else {
492                 rte_errno = EIO;
493                 status[count] = __translate_status_ioat_to_dma(ioat->regs->chanerr);
494                 count++;
495                 ioat->next_read = read + count;
496                 if (__ioat_recover(ioat) != 0) {
497                         IOAT_PMD_ERR("Device HALTED and could not be recovered\n");
498                         __dev_dump(dev_private, stdout);
499                         return 0;
500                 }
501                 __submit(ioat);
502                 fails++;
503         }
504
505         if (ioat->failure > 0) {
506                 status[0] = __translate_status_ioat_to_dma(ioat->failure);
507                 count = RTE_MIN(count + 1, max_ops);
508                 ioat->failure = 0;
509         }
510
511         *last_idx = ioat->next_read - 1;
512
513         ioat->stats.completed += count;
514         ioat->stats.errors += fails;
515
516         return count;
517 }
518
519 /* Retrieve the generic stats of a DMA device. */
520 static int
521 ioat_stats_get(const struct rte_dma_dev *dev, uint16_t vchan __rte_unused,
522                 struct rte_dma_stats *rte_stats, uint32_t size)
523 {
524         struct rte_dma_stats *stats = (&((struct ioat_dmadev *)dev->fp_obj->dev_private)->stats);
525
526         if (size < sizeof(rte_stats))
527                 return -EINVAL;
528         if (rte_stats == NULL)
529                 return -EINVAL;
530
531         *rte_stats = *stats;
532         return 0;
533 }
534
535 /* Reset the generic stat counters for the DMA device. */
536 static int
537 ioat_stats_reset(struct rte_dma_dev *dev, uint16_t vchan __rte_unused)
538 {
539         struct ioat_dmadev *ioat = dev->fp_obj->dev_private;
540
541         ioat->stats = (struct rte_dma_stats){0};
542         return 0;
543 }
544
545 /* Create a DMA device. */
546 static int
547 ioat_dmadev_create(const char *name, struct rte_pci_device *dev)
548 {
549         static const struct rte_dma_dev_ops ioat_dmadev_ops = {
550                 .dev_close = ioat_dev_close,
551                 .dev_configure = ioat_dev_configure,
552                 .dev_dump = ioat_dev_dump,
553                 .dev_info_get = ioat_dev_info_get,
554                 .dev_start = ioat_dev_start,
555                 .dev_stop = ioat_dev_stop,
556                 .stats_get = ioat_stats_get,
557                 .stats_reset = ioat_stats_reset,
558                 .vchan_setup = ioat_vchan_setup,
559         };
560
561         struct rte_dma_dev *dmadev = NULL;
562         struct ioat_dmadev *ioat = NULL;
563         int retry = 0;
564
565         if (!name) {
566                 IOAT_PMD_ERR("Invalid name of the device!");
567                 return -EINVAL;
568         }
569
570         /* Allocate device structure. */
571         dmadev = rte_dma_pmd_allocate(name, dev->device.numa_node, sizeof(struct ioat_dmadev));
572         if (dmadev == NULL) {
573                 IOAT_PMD_ERR("Unable to allocate dma device");
574                 return -ENOMEM;
575         }
576
577         dmadev->device = &dev->device;
578
579         dmadev->fp_obj->dev_private = dmadev->data->dev_private;
580
581         dmadev->dev_ops = &ioat_dmadev_ops;
582
583         dmadev->fp_obj->completed = ioat_completed;
584         dmadev->fp_obj->completed_status = ioat_completed_status;
585         dmadev->fp_obj->copy = ioat_enqueue_copy;
586         dmadev->fp_obj->fill = ioat_enqueue_fill;
587         dmadev->fp_obj->submit = ioat_submit;
588
589         ioat = dmadev->data->dev_private;
590         ioat->dmadev = dmadev;
591         ioat->regs = dev->mem_resource[0].addr;
592         ioat->doorbell = &ioat->regs->dmacount;
593         ioat->qcfg.nb_desc = 0;
594         ioat->desc_ring = NULL;
595         ioat->version = ioat->regs->cbver;
596
597         /* Do device initialization - reset and set error behaviour. */
598         if (ioat->regs->chancnt != 1)
599                 IOAT_PMD_WARN("%s: Channel count == %d\n", __func__,
600                                 ioat->regs->chancnt);
601
602         /* Locked by someone else. */
603         if (ioat->regs->chanctrl & IOAT_CHANCTRL_CHANNEL_IN_USE) {
604                 IOAT_PMD_WARN("%s: Channel appears locked\n", __func__);
605                 ioat->regs->chanctrl = 0;
606         }
607
608         /* clear any previous errors */
609         if (ioat->regs->chanerr != 0) {
610                 uint32_t val = ioat->regs->chanerr;
611                 ioat->regs->chanerr = val;
612         }
613
614         ioat->regs->chancmd = IOAT_CHANCMD_SUSPEND;
615         rte_delay_ms(1);
616         ioat->regs->chancmd = IOAT_CHANCMD_RESET;
617         rte_delay_ms(1);
618         while (ioat->regs->chancmd & IOAT_CHANCMD_RESET) {
619                 ioat->regs->chainaddr = 0;
620                 rte_delay_ms(1);
621                 if (++retry >= 200) {
622                         IOAT_PMD_ERR("%s: cannot reset device. CHANCMD=%#"PRIx8
623                                         ", CHANSTS=%#"PRIx64", CHANERR=%#"PRIx32"\n",
624                                         __func__,
625                                         ioat->regs->chancmd,
626                                         ioat->regs->chansts,
627                                         ioat->regs->chanerr);
628                         rte_dma_pmd_release(name);
629                         return -EIO;
630                 }
631         }
632         ioat->regs->chanctrl = IOAT_CHANCTRL_ANY_ERR_ABORT_EN |
633                         IOAT_CHANCTRL_ERR_COMPLETION_EN;
634
635         dmadev->fp_obj->dev_private = ioat;
636
637         dmadev->state = RTE_DMA_DEV_READY;
638
639         return 0;
640
641 }
642
643 /* Destroy a DMA device. */
644 static int
645 ioat_dmadev_destroy(const char *name)
646 {
647         int ret;
648
649         if (!name) {
650                 IOAT_PMD_ERR("Invalid device name");
651                 return -EINVAL;
652         }
653
654         ret = rte_dma_pmd_release(name);
655         if (ret)
656                 IOAT_PMD_DEBUG("Device cleanup failed");
657
658         return 0;
659 }
660
661 /* Probe DMA device. */
662 static int
663 ioat_dmadev_probe(struct rte_pci_driver *drv, struct rte_pci_device *dev)
664 {
665         char name[32];
666
667         rte_pci_device_name(&dev->addr, name, sizeof(name));
668         IOAT_PMD_INFO("Init %s on NUMA node %d", name, dev->device.numa_node);
669
670         dev->device.driver = &drv->driver;
671         return ioat_dmadev_create(name, dev);
672 }
673
674 /* Remove DMA device. */
675 static int
676 ioat_dmadev_remove(struct rte_pci_device *dev)
677 {
678         char name[32];
679
680         rte_pci_device_name(&dev->addr, name, sizeof(name));
681
682         IOAT_PMD_INFO("Closing %s on NUMA node %d",
683                         name, dev->device.numa_node);
684
685         return ioat_dmadev_destroy(name);
686 }
687
688 static const struct rte_pci_id pci_id_ioat_map[] = {
689         { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_SKX) },
690         { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX0) },
691         { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX1) },
692         { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX2) },
693         { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX3) },
694         { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX4) },
695         { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX5) },
696         { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX6) },
697         { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDX7) },
698         { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDXE) },
699         { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_BDXF) },
700         { RTE_PCI_DEVICE(IOAT_VENDOR_ID, IOAT_DEVICE_ID_ICX) },
701         { .vendor_id = 0, /* sentinel */ },
702 };
703
704 static struct rte_pci_driver ioat_pmd_drv = {
705         .id_table = pci_id_ioat_map,
706         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
707         .probe = ioat_dmadev_probe,
708         .remove = ioat_dmadev_remove,
709 };
710
711 RTE_PMD_REGISTER_PCI(IOAT_PMD_NAME, ioat_pmd_drv);
712 RTE_PMD_REGISTER_PCI_TABLE(IOAT_PMD_NAME, pci_id_ioat_map);
713 RTE_PMD_REGISTER_KMOD_DEP(IOAT_PMD_NAME, "* igb_uio | uio_pci_generic | vfio-pci");