1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2019 Marvell International Ltd.
9 #include <rte_bus_pci.h>
10 #include <rte_common.h>
12 #include <rte_lcore.h>
13 #include <rte_mempool.h>
15 #include <rte_rawdev.h>
16 #include <rte_rawdev_pmd.h>
18 #include <otx2_common.h>
20 #include "otx2_dpi_rawdev.h"
22 static const struct rte_pci_id pci_dma_map[] = {
24 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
25 PCI_DEVID_OCTEONTX2_DPI_VF)
32 /* Enable/Disable DMA queue */
34 dma_engine_enb_dis(struct dpi_vf_s *dpivf, const bool enb)
37 otx2_write64(0x1, dpivf->vf_bar0 + DPI_VDMA_EN);
39 otx2_write64(0x0, dpivf->vf_bar0 + DPI_VDMA_EN);
41 return DPI_DMA_QUEUE_SUCCESS;
44 /* Free DMA Queue instruction buffers, and send close notification to PF */
46 dma_queue_finish(struct dpi_vf_s *dpivf)
48 uint32_t timeout = 0, sleep = 1;
51 /* Wait for SADDR to become idle */
52 reg = otx2_read64(dpivf->vf_bar0 + DPI_VDMA_SADDR);
53 while (!(reg & BIT_ULL(DPI_VDMA_SADDR_REQ_IDLE))) {
56 if (timeout >= DPI_QFINISH_TIMEOUT) {
57 otx2_dpi_dbg("Timeout!!! Closing Forcibly");
60 reg = otx2_read64(dpivf->vf_bar0 + DPI_VDMA_SADDR);
63 if (otx2_dpi_queue_close(dpivf->vf_id) < 0)
66 rte_mempool_put(dpivf->chunk_pool, dpivf->base_ptr);
67 dpivf->vf_bar0 = (uintptr_t)NULL;
69 return DPI_DMA_QUEUE_SUCCESS;
73 otx2_dpi_rawdev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config)
75 struct dpi_rawdev_conf_s *conf = config;
76 struct dpi_vf_s *dpivf = NULL;
82 otx2_dpi_dbg("NULL configuration");
85 dpivf = (struct dpi_vf_s *)dev->dev_private;
86 dpivf->chunk_pool = conf->chunk_pool;
87 if (rte_mempool_get(conf->chunk_pool, &buf) || (buf == NULL)) {
88 otx2_err("Unable allocate buffer");
91 dpivf->base_ptr = buf;
92 otx2_write64(0x0, dpivf->vf_bar0 + DPI_VDMA_EN);
93 dpivf->pool_size_m1 = (DPI_CHUNK_SIZE >> 3) - 2;
94 pool = (uintptr_t)((struct rte_mempool *)conf->chunk_pool)->pool_id;
95 gaura = npa_lf_aura_handle_to_aura(pool);
96 otx2_write64(0, dpivf->vf_bar0 + DPI_VDMA_REQQ_CTL);
97 otx2_write64(((uint64_t)buf >> 7) << 7,
98 dpivf->vf_bar0 + DPI_VDMA_SADDR);
99 if (otx2_dpi_queue_open(dpivf->vf_id, DPI_CHUNK_SIZE, gaura) < 0) {
100 otx2_err("Unable to open DPI VF %d", dpivf->vf_id);
101 rte_mempool_put(conf->chunk_pool, buf);
104 dma_engine_enb_dis(dpivf, true);
106 return DPI_DMA_QUEUE_SUCCESS;
109 static const struct rte_rawdev_ops dpi_rawdev_ops = {
110 .dev_configure = otx2_dpi_rawdev_configure,
114 otx2_dpi_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
115 struct rte_pci_device *pci_dev)
117 char name[RTE_RAWDEV_NAME_MAX_LEN];
118 struct dpi_vf_s *dpivf = NULL;
119 struct rte_rawdev *rawdev;
122 /* For secondary processes, the primary has done all the work */
123 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
124 return DPI_DMA_QUEUE_SUCCESS;
126 if (pci_dev->mem_resource[0].addr == NULL) {
127 otx2_dpi_dbg("Empty bars %p %p", pci_dev->mem_resource[0].addr,
128 pci_dev->mem_resource[2].addr);
132 memset(name, 0, sizeof(name));
133 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "DPI:%x:%02x.%x",
134 pci_dev->addr.bus, pci_dev->addr.devid,
135 pci_dev->addr.function);
137 /* Allocate device structure */
138 rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct dpi_vf_s),
140 if (rawdev == NULL) {
141 otx2_err("Rawdev allocation failed");
145 rawdev->dev_ops = &dpi_rawdev_ops;
146 rawdev->device = &pci_dev->device;
147 rawdev->driver_name = pci_dev->driver->driver.name;
149 dpivf = rawdev->dev_private;
150 if (dpivf->state != DPI_QUEUE_STOP) {
151 otx2_dpi_dbg("Device already started!!!");
155 vf_id = ((pci_dev->addr.devid & 0x1F) << 3) |
156 (pci_dev->addr.function & 0x7);
158 dpivf->state = DPI_QUEUE_START;
159 dpivf->vf_id = vf_id;
160 dpivf->vf_bar0 = (uintptr_t)pci_dev->mem_resource[0].addr;
161 dpivf->vf_bar2 = (uintptr_t)pci_dev->mem_resource[2].addr;
163 return DPI_DMA_QUEUE_SUCCESS;
167 otx2_dpi_rawdev_remove(struct rte_pci_device *pci_dev)
169 char name[RTE_RAWDEV_NAME_MAX_LEN];
170 struct rte_rawdev *rawdev;
171 struct dpi_vf_s *dpivf;
173 if (pci_dev == NULL) {
174 otx2_dpi_dbg("Invalid pci_dev of the device!");
178 memset(name, 0, sizeof(name));
179 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "DPI:%x:%02x.%x",
180 pci_dev->addr.bus, pci_dev->addr.devid,
181 pci_dev->addr.function);
183 rawdev = rte_rawdev_pmd_get_named_dev(name);
184 if (rawdev == NULL) {
185 otx2_dpi_dbg("Invalid device name (%s)", name);
189 dpivf = (struct dpi_vf_s *)rawdev->dev_private;
190 dma_engine_enb_dis(dpivf, false);
191 dma_queue_finish(dpivf);
193 /* rte_rawdev_close is called by pmd_release */
194 return rte_rawdev_pmd_release(rawdev);
197 static struct rte_pci_driver rte_dpi_rawdev_pmd = {
198 .id_table = pci_dma_map,
199 .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
200 .probe = otx2_dpi_rawdev_probe,
201 .remove = otx2_dpi_rawdev_remove,
204 RTE_PMD_REGISTER_PCI(dpi_rawdev_pci_driver, rte_dpi_rawdev_pmd);
205 RTE_PMD_REGISTER_PCI_TABLE(dpi_rawdev_pci_driver, pci_dma_map);
206 RTE_PMD_REGISTER_KMOD_DEP(dpi_rawdev_pci_driver, "vfio-pci");