raw/octeontx2_ep: add device uninitialization
[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 };
255
256 static int
257 otx2_sdp_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
258                       struct rte_pci_device *pci_dev)
259 {
260         char name[RTE_RAWDEV_NAME_MAX_LEN];
261         struct sdp_device *sdpvf = NULL;
262         struct rte_rawdev *sdp_rawdev;
263         uint16_t vf_id;
264
265         /* Single process support */
266         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
267                 return 0;
268
269         if (pci_dev->mem_resource[0].addr)
270                 otx2_info("SDP_EP BAR0 is mapped:");
271         else {
272                 otx2_err("SDP_EP: Failed to map device BARs");
273                 otx2_err("BAR0 %p\n BAR2 %p",
274                         pci_dev->mem_resource[0].addr,
275                         pci_dev->mem_resource[2].addr);
276                 return -ENODEV;
277         }
278
279         memset(name, 0, sizeof(name));
280         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
281                  pci_dev->addr.bus, pci_dev->addr.devid,
282                  pci_dev->addr.function);
283
284         /* Allocate rawdev pmd */
285         sdp_rawdev = rte_rawdev_pmd_allocate(name,
286                                              sizeof(struct sdp_device),
287                                              rte_socket_id());
288
289         if (sdp_rawdev == NULL) {
290                 otx2_err("SDP_EP VF rawdev allocation failed");
291                 return -ENOMEM;
292         }
293
294         sdp_rawdev->dev_ops = &sdp_rawdev_ops;
295         sdp_rawdev->device = &pci_dev->device;
296         sdp_rawdev->driver_name = pci_dev->driver->driver.name;
297
298         sdpvf = (struct sdp_device *)sdp_rawdev->dev_private;
299         sdpvf->hw_addr = pci_dev->mem_resource[0].addr;
300         sdpvf->pci_dev = pci_dev;
301
302         /* Discover the VF number being probed */
303         vf_id = ((pci_dev->addr.devid & 0x1F) << 3) |
304                  (pci_dev->addr.function & 0x7);
305
306         vf_id -= 1;
307         sdpvf->vf_num = vf_id;
308
309         otx2_info("SDP_EP VF[%d] probe done", vf_id);
310
311         return 0;
312 }
313
314 static int
315 otx2_sdp_rawdev_remove(struct rte_pci_device *pci_dev)
316 {
317         char name[RTE_RAWDEV_NAME_MAX_LEN];
318         struct rte_rawdev *rawdev;
319         struct sdp_device *sdpvf;
320
321         /* Single process support */
322         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
323                 return 0;
324
325         if (pci_dev == NULL) {
326                 otx2_err("SDP_EP:invalid pci_dev!");
327                 return -EINVAL;
328         }
329
330
331         memset(name, 0, sizeof(name));
332         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
333                  pci_dev->addr.bus, pci_dev->addr.devid,
334                  pci_dev->addr.function);
335
336         rawdev = rte_rawdev_pmd_get_named_dev(name);
337         if (rawdev == NULL) {
338                 otx2_err("SDP_EP: invalid device name (%s)", name);
339                 return -EINVAL;
340         }
341
342         sdpvf = (struct sdp_device *)rawdev->dev_private;
343         otx2_info("Removing SDP_EP VF[%d] ", sdpvf->vf_num);
344
345         /* rte_rawdev_close is called by pmd_release */
346         return rte_rawdev_pmd_release(rawdev);
347 }
348
349 static struct rte_pci_driver rte_sdp_rawdev_pmd = {
350         .id_table  = pci_sdp_vf_map,
351         .drv_flags = (RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA),
352         .probe     = otx2_sdp_rawdev_probe,
353         .remove    = otx2_sdp_rawdev_remove,
354 };
355
356 RTE_PMD_REGISTER_PCI(sdp_rawdev_pci_driver, rte_sdp_rawdev_pmd);
357 RTE_PMD_REGISTER_PCI_TABLE(sdp_rawdev_pci_driver, pci_sdp_vf_map);
358 RTE_PMD_REGISTER_KMOD_DEP(sdp_rawdev_pci_driver, "vfio-pci");