224c5e5c38ed2255f58a1bb1e83069404faa6162
[dpdk.git] / drivers / raw / octeontx2_dma / otx2_dpi_rawdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <string.h>
6 #include <unistd.h>
7
8 #include <rte_bus.h>
9 #include <rte_bus_pci.h>
10 #include <rte_common.h>
11 #include <rte_eal.h>
12 #include <rte_lcore.h>
13 #include <rte_mempool.h>
14 #include <rte_pci.h>
15 #include <rte_rawdev.h>
16 #include <rte_rawdev_pmd.h>
17
18 #include <otx2_common.h>
19
20 #include "otx2_dpi_rawdev.h"
21
22 static const struct rte_pci_id pci_dma_map[] = {
23         {
24                 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
25                                PCI_DEVID_OCTEONTX2_DPI_VF)
26         },
27         {
28                 .vendor_id = 0,
29         },
30 };
31
32 /* Enable/Disable DMA queue */
33 static inline int
34 dma_engine_enb_dis(struct dpi_vf_s *dpivf, const bool enb)
35 {
36         if (enb)
37                 otx2_write64(0x1, dpivf->vf_bar0 + DPI_VDMA_EN);
38         else
39                 otx2_write64(0x0, dpivf->vf_bar0 + DPI_VDMA_EN);
40
41         return DPI_DMA_QUEUE_SUCCESS;
42 }
43
44 static int
45 otx2_dpi_rawdev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config)
46 {
47         struct dpi_rawdev_conf_s *conf = config;
48         struct dpi_vf_s *dpivf = NULL;
49         void *buf = NULL;
50         uintptr_t pool;
51         uint32_t gaura;
52
53         if (conf == NULL) {
54                 otx2_dpi_dbg("NULL configuration");
55                 return -EINVAL;
56         }
57         dpivf = (struct dpi_vf_s *)dev->dev_private;
58         dpivf->chunk_pool = conf->chunk_pool;
59         if (rte_mempool_get(conf->chunk_pool, &buf) || (buf == NULL)) {
60                 otx2_err("Unable allocate buffer");
61                 return -ENODEV;
62         }
63         dpivf->base_ptr = buf;
64         otx2_write64(0x0, dpivf->vf_bar0 + DPI_VDMA_EN);
65         dpivf->pool_size_m1 = (DPI_CHUNK_SIZE >> 3) - 2;
66         pool = (uintptr_t)((struct rte_mempool *)conf->chunk_pool)->pool_id;
67         gaura = npa_lf_aura_handle_to_aura(pool);
68         otx2_write64(0, dpivf->vf_bar0 + DPI_VDMA_REQQ_CTL);
69         otx2_write64(((uint64_t)buf >> 7) << 7,
70                      dpivf->vf_bar0 + DPI_VDMA_SADDR);
71         if (otx2_dpi_queue_open(dpivf->vf_id, DPI_CHUNK_SIZE, gaura) < 0) {
72                 otx2_err("Unable to open DPI VF %d", dpivf->vf_id);
73                 rte_mempool_put(conf->chunk_pool, buf);
74                 return -EACCES;
75         }
76         dma_engine_enb_dis(dpivf, true);
77
78         return DPI_DMA_QUEUE_SUCCESS;
79 }
80
81 static const struct rte_rawdev_ops dpi_rawdev_ops = {
82         .dev_configure = otx2_dpi_rawdev_configure,
83 };
84
85 static int
86 otx2_dpi_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
87                       struct rte_pci_device *pci_dev)
88 {
89         char name[RTE_RAWDEV_NAME_MAX_LEN];
90         struct dpi_vf_s *dpivf = NULL;
91         struct rte_rawdev *rawdev;
92         uint16_t vf_id;
93
94         /* For secondary processes, the primary has done all the work */
95         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
96                 return DPI_DMA_QUEUE_SUCCESS;
97
98         if (pci_dev->mem_resource[0].addr == NULL) {
99                 otx2_dpi_dbg("Empty bars %p %p", pci_dev->mem_resource[0].addr,
100                              pci_dev->mem_resource[2].addr);
101                 return -ENODEV;
102         }
103
104         memset(name, 0, sizeof(name));
105         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "DPI:%x:%02x.%x",
106                  pci_dev->addr.bus, pci_dev->addr.devid,
107                  pci_dev->addr.function);
108
109         /* Allocate device structure */
110         rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct dpi_vf_s),
111                                          rte_socket_id());
112         if (rawdev == NULL) {
113                 otx2_err("Rawdev allocation failed");
114                 return -EINVAL;
115         }
116
117         rawdev->dev_ops = &dpi_rawdev_ops;
118         rawdev->device = &pci_dev->device;
119         rawdev->driver_name = pci_dev->driver->driver.name;
120
121         dpivf = rawdev->dev_private;
122         if (dpivf->state != DPI_QUEUE_STOP) {
123                 otx2_dpi_dbg("Device already started!!!");
124                 return -ENODEV;
125         }
126
127         vf_id = ((pci_dev->addr.devid & 0x1F) << 3) |
128                  (pci_dev->addr.function & 0x7);
129         vf_id -= 1;
130         dpivf->state = DPI_QUEUE_START;
131         dpivf->vf_id = vf_id;
132         dpivf->vf_bar0 = (uintptr_t)pci_dev->mem_resource[0].addr;
133         dpivf->vf_bar2 = (uintptr_t)pci_dev->mem_resource[2].addr;
134
135         return DPI_DMA_QUEUE_SUCCESS;
136 }
137
138 static int
139 otx2_dpi_rawdev_remove(struct rte_pci_device *pci_dev)
140 {
141         char name[RTE_RAWDEV_NAME_MAX_LEN];
142         struct rte_rawdev *rawdev;
143
144         if (pci_dev == NULL) {
145                 otx2_dpi_dbg("Invalid pci_dev of the device!");
146                 return -EINVAL;
147         }
148
149         memset(name, 0, sizeof(name));
150         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "DPI:%x:%02x.%x",
151                  pci_dev->addr.bus, pci_dev->addr.devid,
152                  pci_dev->addr.function);
153
154         rawdev = rte_rawdev_pmd_get_named_dev(name);
155         if (rawdev == NULL) {
156                 otx2_dpi_dbg("Invalid device name (%s)", name);
157                 return -EINVAL;
158         }
159
160         /* rte_rawdev_close is called by pmd_release */
161         return rte_rawdev_pmd_release(rawdev);
162 }
163
164 static struct rte_pci_driver rte_dpi_rawdev_pmd = {
165         .id_table  = pci_dma_map,
166         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
167         .probe     = otx2_dpi_rawdev_probe,
168         .remove    = otx2_dpi_rawdev_remove,
169 };
170
171 RTE_PMD_REGISTER_PCI(dpi_rawdev_pci_driver, rte_dpi_rawdev_pmd);
172 RTE_PMD_REGISTER_PCI_TABLE(dpi_rawdev_pci_driver, pci_dma_map);
173 RTE_PMD_REGISTER_KMOD_DEP(dpi_rawdev_pci_driver, "vfio-pci");