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