raw/octeontx2_ep: add enqueue operation
[dpdk.git] / drivers / raw / octeontx2_ep / otx2_ep_rawdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4 #include <string.h>
5 #include <unistd.h>
6
7 #include <rte_bus.h>
8 #include <rte_bus_pci.h>
9 #include <rte_eal.h>
10 #include <rte_lcore.h>
11 #include <rte_mempool.h>
12 #include <rte_pci.h>
13
14 #include <rte_common.h>
15 #include <rte_rawdev.h>
16 #include <rte_rawdev_pmd.h>
17
18 #include "otx2_common.h"
19 #include "otx2_ep_rawdev.h"
20 #include "otx2_ep_vf.h"
21
22 static const struct rte_pci_id pci_sdp_vf_map[] = {
23         {
24                 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
25                                PCI_DEVID_OCTEONTX2_EP_VF)
26         },
27         {
28                 .vendor_id = 0,
29         },
30 };
31
32 /* SDP_VF default configuration */
33 const struct sdp_config default_sdp_conf = {
34         /* IQ attributes */
35         .iq                        = {
36                 .max_iqs           = SDP_VF_CFG_IO_QUEUES,
37                 .instr_type        = SDP_VF_64BYTE_INSTR,
38                 .pending_list_size = (SDP_VF_MAX_IQ_DESCRIPTORS *
39                                       SDP_VF_CFG_IO_QUEUES),
40         },
41
42         /* OQ attributes */
43         .oq                        = {
44                 .max_oqs           = SDP_VF_CFG_IO_QUEUES,
45                 .info_ptr          = SDP_VF_OQ_INFOPTR_MODE,
46                 .refill_threshold  = SDP_VF_OQ_REFIL_THRESHOLD,
47         },
48
49         .num_iqdef_descs           = SDP_VF_MAX_IQ_DESCRIPTORS,
50         .num_oqdef_descs           = SDP_VF_MAX_OQ_DESCRIPTORS,
51         .oqdef_buf_size            = SDP_VF_OQ_BUF_SIZE,
52
53 };
54
55 const struct sdp_config*
56 sdp_get_defconf(struct sdp_device *sdp_dev __rte_unused)
57 {
58         const struct sdp_config *default_conf = NULL;
59
60         default_conf = &default_sdp_conf;
61
62         return default_conf;
63 }
64
65 static int
66 sdp_vfdev_exit(struct rte_rawdev *rawdev)
67 {
68         struct sdp_device *sdpvf;
69         uint32_t rawdev_queues, q;
70
71         otx2_info("%s:", __func__);
72
73         sdpvf = (struct sdp_device *)rawdev->dev_private;
74
75         sdpvf->fn_list.disable_io_queues(sdpvf);
76
77         rawdev_queues = sdpvf->num_oqs;
78         for (q = 0; q < rawdev_queues; q++) {
79                 if (sdp_delete_oqs(sdpvf, q)) {
80                         otx2_err("Failed to delete OQ:%d", q);
81                         return -ENOMEM;
82                 }
83         }
84         otx2_info("Num OQs:%d freed", sdpvf->num_oqs);
85
86         /* Free the oqbuf_pool */
87         rte_mempool_free(sdpvf->enqdeq_mpool);
88         sdpvf->enqdeq_mpool = NULL;
89
90         otx2_info("Enqdeq_mpool free done");
91
92         rawdev_queues = sdpvf->num_iqs;
93         for (q = 0; q < rawdev_queues; q++) {
94                 if (sdp_delete_iqs(sdpvf, q)) {
95                         otx2_err("Failed to delete IQ:%d", q);
96                         return -ENOMEM;
97                 }
98         }
99         otx2_sdp_dbg("Num IQs:%d freed", sdpvf->num_iqs);
100
101         return 0;
102 }
103
104 static int
105 sdp_chip_specific_setup(struct sdp_device *sdpvf)
106 {
107         struct rte_pci_device *pdev = sdpvf->pci_dev;
108         uint32_t dev_id = pdev->id.device_id;
109         int ret;
110
111         switch (dev_id) {
112         case PCI_DEVID_OCTEONTX2_EP_VF:
113                 sdpvf->chip_id = PCI_DEVID_OCTEONTX2_EP_VF;
114                 ret = sdp_vf_setup_device(sdpvf);
115
116                 break;
117         default:
118                 otx2_err("Unsupported device");
119                 ret = -EINVAL;
120         }
121
122         if (!ret)
123                 otx2_info("SDP dev_id[%d]", dev_id);
124
125         return ret;
126 }
127
128 /* SDP VF device initialization */
129 static int
130 sdp_vfdev_init(struct sdp_device *sdpvf)
131 {
132         uint32_t rawdev_queues, q;
133
134         if (sdp_chip_specific_setup(sdpvf)) {
135                 otx2_err("Chip specific setup failed");
136                 goto setup_fail;
137         }
138
139         if (sdpvf->fn_list.setup_device_regs(sdpvf)) {
140                 otx2_err("Failed to configure device registers");
141                 goto setup_fail;
142         }
143
144         rawdev_queues = (uint32_t)(sdpvf->sriov_info.rings_per_vf);
145
146         /* Rawdev queues setup for enqueue/dequeue */
147         for (q = 0; q < rawdev_queues; q++) {
148                 if (sdp_setup_iqs(sdpvf, q)) {
149                         otx2_err("Failed to setup IQs");
150                         goto iq_fail;
151                 }
152         }
153         otx2_info("Total[%d] IQs setup", sdpvf->num_iqs);
154
155         for (q = 0; q < rawdev_queues; q++) {
156                 if (sdp_setup_oqs(sdpvf, q)) {
157                         otx2_err("Failed to setup OQs");
158                         goto oq_fail;
159                 }
160         }
161         otx2_info("Total [%d] OQs setup", sdpvf->num_oqs);
162
163         /* Enable IQ/OQ for this device */
164         sdpvf->fn_list.enable_io_queues(sdpvf);
165
166         /* Send OQ desc credits for OQs, credits are always
167          * sent after the OQs are enabled.
168          */
169         for (q = 0; q < rawdev_queues; q++) {
170                 rte_write32(sdpvf->droq[q]->nb_desc,
171                             sdpvf->droq[q]->pkts_credit_reg);
172
173                 rte_io_mb();
174                 otx2_info("OQ[%d] dbells [%d]", q,
175                 rte_read32(sdpvf->droq[q]->pkts_credit_reg));
176         }
177
178         rte_wmb();
179
180         otx2_info("SDP Device is Ready");
181
182         return 0;
183
184 /* Error handling  */
185 oq_fail:
186         /* Free the allocated OQs */
187         for (q = 0; q < sdpvf->num_oqs; q++)
188                 sdp_delete_oqs(sdpvf, q);
189
190 iq_fail:
191         /* Free the allocated IQs */
192         for (q = 0; q < sdpvf->num_iqs; q++)
193                 sdp_delete_iqs(sdpvf, q);
194
195 setup_fail:
196         return -ENOMEM;
197 }
198
199 static int
200 sdp_rawdev_start(struct rte_rawdev *dev)
201 {
202         dev->started = 1;
203
204         return 0;
205 }
206
207 static void
208 sdp_rawdev_stop(struct rte_rawdev *dev)
209 {
210         dev->started = 0;
211 }
212
213 static int
214 sdp_rawdev_close(struct rte_rawdev *dev)
215 {
216         int ret;
217         ret = sdp_vfdev_exit(dev);
218         if (ret) {
219                 otx2_err(" SDP_EP rawdev exit error");
220                 return ret;
221         }
222
223         return 0;
224 }
225
226 static int
227 sdp_rawdev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config)
228 {
229         struct sdp_rawdev_info *app_info = (struct sdp_rawdev_info *)config;
230         struct sdp_device *sdpvf;
231
232         if (app_info == NULL) {
233                 otx2_err("Application config info [NULL]");
234                 return -EINVAL;
235         }
236
237         sdpvf = (struct sdp_device *)dev->dev_private;
238
239         sdpvf->conf = app_info->app_conf;
240         sdpvf->enqdeq_mpool = app_info->enqdeq_mpool;
241
242         sdp_vfdev_init(sdpvf);
243
244         return 0;
245
246 }
247
248 /* SDP VF endpoint rawdev ops */
249 static const struct rte_rawdev_ops sdp_rawdev_ops = {
250         .dev_configure  = sdp_rawdev_configure,
251         .dev_start      = sdp_rawdev_start,
252         .dev_stop       = sdp_rawdev_stop,
253         .dev_close      = sdp_rawdev_close,
254         .enqueue_bufs   = sdp_rawdev_enqueue,
255 };
256
257 static int
258 otx2_sdp_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
259                       struct rte_pci_device *pci_dev)
260 {
261         char name[RTE_RAWDEV_NAME_MAX_LEN];
262         struct sdp_device *sdpvf = NULL;
263         struct rte_rawdev *sdp_rawdev;
264         uint16_t vf_id;
265
266         /* Single process support */
267         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
268                 return 0;
269
270         if (pci_dev->mem_resource[0].addr)
271                 otx2_info("SDP_EP BAR0 is mapped:");
272         else {
273                 otx2_err("SDP_EP: Failed to map device BARs");
274                 otx2_err("BAR0 %p\n BAR2 %p",
275                         pci_dev->mem_resource[0].addr,
276                         pci_dev->mem_resource[2].addr);
277                 return -ENODEV;
278         }
279
280         memset(name, 0, sizeof(name));
281         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
282                  pci_dev->addr.bus, pci_dev->addr.devid,
283                  pci_dev->addr.function);
284
285         /* Allocate rawdev pmd */
286         sdp_rawdev = rte_rawdev_pmd_allocate(name,
287                                              sizeof(struct sdp_device),
288                                              rte_socket_id());
289
290         if (sdp_rawdev == NULL) {
291                 otx2_err("SDP_EP VF rawdev allocation failed");
292                 return -ENOMEM;
293         }
294
295         sdp_rawdev->dev_ops = &sdp_rawdev_ops;
296         sdp_rawdev->device = &pci_dev->device;
297         sdp_rawdev->driver_name = pci_dev->driver->driver.name;
298
299         sdpvf = (struct sdp_device *)sdp_rawdev->dev_private;
300         sdpvf->hw_addr = pci_dev->mem_resource[0].addr;
301         sdpvf->pci_dev = pci_dev;
302
303         /* Discover the VF number being probed */
304         vf_id = ((pci_dev->addr.devid & 0x1F) << 3) |
305                  (pci_dev->addr.function & 0x7);
306
307         vf_id -= 1;
308         sdpvf->vf_num = vf_id;
309
310         otx2_info("SDP_EP VF[%d] probe done", vf_id);
311
312         return 0;
313 }
314
315 static int
316 otx2_sdp_rawdev_remove(struct rte_pci_device *pci_dev)
317 {
318         char name[RTE_RAWDEV_NAME_MAX_LEN];
319         struct rte_rawdev *rawdev;
320         struct sdp_device *sdpvf;
321
322         /* Single process support */
323         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
324                 return 0;
325
326         if (pci_dev == NULL) {
327                 otx2_err("SDP_EP:invalid pci_dev!");
328                 return -EINVAL;
329         }
330
331
332         memset(name, 0, sizeof(name));
333         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
334                  pci_dev->addr.bus, pci_dev->addr.devid,
335                  pci_dev->addr.function);
336
337         rawdev = rte_rawdev_pmd_get_named_dev(name);
338         if (rawdev == NULL) {
339                 otx2_err("SDP_EP: invalid device name (%s)", name);
340                 return -EINVAL;
341         }
342
343         sdpvf = (struct sdp_device *)rawdev->dev_private;
344         otx2_info("Removing SDP_EP VF[%d] ", sdpvf->vf_num);
345
346         /* rte_rawdev_close is called by pmd_release */
347         return rte_rawdev_pmd_release(rawdev);
348 }
349
350 static struct rte_pci_driver rte_sdp_rawdev_pmd = {
351         .id_table  = pci_sdp_vf_map,
352         .drv_flags = (RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA),
353         .probe     = otx2_sdp_rawdev_probe,
354         .remove    = otx2_sdp_rawdev_remove,
355 };
356
357 RTE_PMD_REGISTER_PCI(sdp_rawdev_pci_driver, rte_sdp_rawdev_pmd);
358 RTE_PMD_REGISTER_PCI_TABLE(sdp_rawdev_pci_driver, pci_sdp_vf_map);
359 RTE_PMD_REGISTER_KMOD_DEP(sdp_rawdev_pci_driver, "vfio-pci");