From a339694621359f4f4e5832cf6d7e7764172b7705 Mon Sep 17 00:00:00 2001 From: Bruce Richardson Date: Wed, 28 Oct 2020 12:45:34 +0000 Subject: [PATCH] raw/ioat: fix work-queue config size According to latest DSA spec[1], the work-queue config register size should be based off a value read from the WQ capabilities register. Update driver to read this value and base the start of each WQ config off that value. [1] https://software.intel.com/content/www/us/en/develop/download/intel-data-streaming-accelerator-preliminary-architecture-specification.html Fixes: ff06fa2cf3ba ("raw/ioat: probe idxd PCI") Signed-off-by: Bruce Richardson Tested-by: Kevin Laatz --- drivers/raw/ioat/idxd_pci.c | 19 +++++++++++++------ drivers/raw/ioat/ioat_private.h | 4 +++- drivers/raw/ioat/ioat_spec.h | 5 +---- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/raw/ioat/idxd_pci.c b/drivers/raw/ioat/idxd_pci.c index d4d87b199d..99ecfbbb48 100644 --- a/drivers/raw/ioat/idxd_pci.c +++ b/drivers/raw/ioat/idxd_pci.c @@ -44,10 +44,16 @@ idxd_pci_dev_command(struct idxd_rawdev *idxd, enum rte_idxd_cmds command) return err_code & CMDSTATUS_ERR_MASK; } +static uint32_t * +idxd_get_wq_cfg(struct idxd_pci_common *pci, uint8_t wq_idx) +{ + return RTE_PTR_ADD(pci->wq_regs_base, wq_idx << (5 + pci->wq_cfg_sz)); +} + static int idxd_is_wq_enabled(struct idxd_rawdev *idxd) { - uint32_t state = idxd->u.pci->wq_regs[idxd->qid].wqcfg[WQ_STATE_IDX]; + uint32_t state = idxd_get_wq_cfg(idxd->u.pci, idxd->qid)[WQ_STATE_IDX]; return ((state >> WQ_STATE_SHIFT) & WQ_STATE_MASK) == 0x1; } @@ -137,8 +143,9 @@ init_pci_device(struct rte_pci_device *dev, struct idxd_rawdev *idxd) grp_offset = (uint16_t)pci->regs->offsets[0]; pci->grp_regs = RTE_PTR_ADD(pci->regs, grp_offset * 0x100); wq_offset = (uint16_t)(pci->regs->offsets[0] >> 16); - pci->wq_regs = RTE_PTR_ADD(pci->regs, wq_offset * 0x100); + pci->wq_regs_base = RTE_PTR_ADD(pci->regs, wq_offset * 0x100); pci->portals = dev->mem_resource[2].addr; + pci->wq_cfg_sz = (pci->regs->wqcap >> 24) & 0x0F; /* sanity check device status */ if (pci->regs->gensts & GENSTS_DEV_STATE_MASK) { @@ -169,7 +176,7 @@ init_pci_device(struct rte_pci_device *dev, struct idxd_rawdev *idxd) pci->grp_regs[i].grpwqcfg[0] = 0; } for (i = 0; i < nb_wqs; i++) - pci->wq_regs[i].wqcfg[0] = 0; + idxd_get_wq_cfg(pci, i)[0] = 0; /* put each engine into a separate group to avoid reordering */ if (nb_groups > nb_engines) @@ -194,10 +201,10 @@ init_pci_device(struct rte_pci_device *dev, struct idxd_rawdev *idxd) i, i % nb_groups); pci->grp_regs[i % nb_groups].grpwqcfg[0] |= (1ULL << i); /* now configure it, in terms of size, max batch, mode */ - pci->wq_regs[i].wqcfg[WQ_SIZE_IDX] = wq_size; - pci->wq_regs[i].wqcfg[WQ_MODE_IDX] = (1 << WQ_PRIORITY_SHIFT) | + idxd_get_wq_cfg(pci, i)[WQ_SIZE_IDX] = wq_size; + idxd_get_wq_cfg(pci, i)[WQ_MODE_IDX] = (1 << WQ_PRIORITY_SHIFT) | WQ_MODE_DEDICATED; - pci->wq_regs[i].wqcfg[WQ_SIZES_IDX] = lg2_max_copy_size | + idxd_get_wq_cfg(pci, i)[WQ_SIZES_IDX] = lg2_max_copy_size | (lg2_max_batch << WQ_BATCH_SZ_SHIFT); } diff --git a/drivers/raw/ioat/ioat_private.h b/drivers/raw/ioat/ioat_private.h index a74bc0422f..6c423811ec 100644 --- a/drivers/raw/ioat/ioat_private.h +++ b/drivers/raw/ioat/ioat_private.h @@ -30,8 +30,10 @@ extern int ioat_pmd_logtype; struct idxd_pci_common { rte_spinlock_t lk; + + uint8_t wq_cfg_sz; volatile struct rte_idxd_bar0 *regs; - volatile struct rte_idxd_wqcfg *wq_regs; + volatile uint32_t *wq_regs_base; volatile struct rte_idxd_grpcfg *grp_regs; volatile void *portals; }; diff --git a/drivers/raw/ioat/ioat_spec.h b/drivers/raw/ioat/ioat_spec.h index 1aa768b9ae..6aa467e4cb 100644 --- a/drivers/raw/ioat/ioat_spec.h +++ b/drivers/raw/ioat/ioat_spec.h @@ -302,10 +302,7 @@ struct rte_idxd_bar0 { uint64_t __rte_aligned(0x20) swerror[4]; /* offset 0xC0 */ }; -struct rte_idxd_wqcfg { - uint32_t wqcfg[8] __rte_aligned(32); /* 32-byte register */ -}; - +/* workqueue config is provided by array of uint32_t. */ #define WQ_SIZE_IDX 0 /* size is in first 32-bit value */ #define WQ_THRESHOLD_IDX 1 /* WQ threshold second 32-bits */ #define WQ_MODE_IDX 2 /* WQ mode and other flags */ -- 2.20.1