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*
sdp_get_defconf(struct sdp_device * sdp_dev __rte_unused)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
sdp_vfdev_exit(struct rte_rawdev * rawdev)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
sdp_chip_specific_setup(struct sdp_device * sdpvf)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
sdp_vfdev_init(struct sdp_device * sdpvf)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
sdp_rawdev_start(struct rte_rawdev * dev)200 sdp_rawdev_start(struct rte_rawdev *dev)
201 {
202 dev->started = 1;
203
204 return 0;
205 }
206
207 static void
sdp_rawdev_stop(struct rte_rawdev * dev)208 sdp_rawdev_stop(struct rte_rawdev *dev)
209 {
210 dev->started = 0;
211 }
212
213 static int
sdp_rawdev_close(struct rte_rawdev * dev)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
sdp_rawdev_configure(const struct rte_rawdev * dev,rte_rawdev_obj_t config,size_t config_size)227 sdp_rawdev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config,
228 size_t config_size)
229 {
230 struct sdp_rawdev_info *app_info = (struct sdp_rawdev_info *)config;
231 struct sdp_device *sdpvf;
232
233 if (app_info == NULL || config_size != sizeof(*app_info)) {
234 otx2_err("Application config info [NULL] or incorrect size");
235 return -EINVAL;
236 }
237
238 sdpvf = (struct sdp_device *)dev->dev_private;
239
240 sdpvf->conf = app_info->app_conf;
241 sdpvf->enqdeq_mpool = app_info->enqdeq_mpool;
242
243 sdp_vfdev_init(sdpvf);
244
245 return 0;
246
247 }
248
249 /* SDP VF endpoint rawdev ops */
250 static const struct rte_rawdev_ops sdp_rawdev_ops = {
251 .dev_configure = sdp_rawdev_configure,
252 .dev_start = sdp_rawdev_start,
253 .dev_stop = sdp_rawdev_stop,
254 .dev_close = sdp_rawdev_close,
255 .enqueue_bufs = sdp_rawdev_enqueue,
256 .dequeue_bufs = sdp_rawdev_dequeue,
257 .dev_selftest = sdp_rawdev_selftest,
258 };
259
260 static int
otx2_sdp_rawdev_probe(struct rte_pci_driver * pci_drv __rte_unused,struct rte_pci_device * pci_dev)261 otx2_sdp_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
262 struct rte_pci_device *pci_dev)
263 {
264 char name[RTE_RAWDEV_NAME_MAX_LEN];
265 struct sdp_device *sdpvf = NULL;
266 struct rte_rawdev *sdp_rawdev;
267 uint16_t vf_id;
268
269 /* Single process support */
270 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
271 return 0;
272
273 if (pci_dev->mem_resource[0].addr)
274 otx2_info("SDP_EP BAR0 is mapped:");
275 else {
276 otx2_err("SDP_EP: Failed to map device BARs");
277 otx2_err("BAR0 %p\n BAR2 %p",
278 pci_dev->mem_resource[0].addr,
279 pci_dev->mem_resource[2].addr);
280 return -ENODEV;
281 }
282
283 memset(name, 0, sizeof(name));
284 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
285 pci_dev->addr.bus, pci_dev->addr.devid,
286 pci_dev->addr.function);
287
288 /* Allocate rawdev pmd */
289 sdp_rawdev = rte_rawdev_pmd_allocate(name,
290 sizeof(struct sdp_device),
291 rte_socket_id());
292
293 if (sdp_rawdev == NULL) {
294 otx2_err("SDP_EP VF rawdev allocation failed");
295 return -ENOMEM;
296 }
297
298 sdp_rawdev->dev_ops = &sdp_rawdev_ops;
299 sdp_rawdev->device = &pci_dev->device;
300 sdp_rawdev->driver_name = pci_dev->driver->driver.name;
301
302 sdpvf = (struct sdp_device *)sdp_rawdev->dev_private;
303 sdpvf->hw_addr = pci_dev->mem_resource[0].addr;
304 sdpvf->pci_dev = pci_dev;
305
306 /* Discover the VF number being probed */
307 vf_id = ((pci_dev->addr.devid & 0x1F) << 3) |
308 (pci_dev->addr.function & 0x7);
309
310 vf_id -= 1;
311 sdpvf->vf_num = vf_id;
312
313 otx2_info("SDP_EP VF[%d] probe done", vf_id);
314
315 return 0;
316 }
317
318 static int
otx2_sdp_rawdev_remove(struct rte_pci_device * pci_dev)319 otx2_sdp_rawdev_remove(struct rte_pci_device *pci_dev)
320 {
321 char name[RTE_RAWDEV_NAME_MAX_LEN];
322 struct rte_rawdev *rawdev;
323 struct sdp_device *sdpvf;
324
325 /* Single process support */
326 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
327 return 0;
328
329 if (pci_dev == NULL) {
330 otx2_err("SDP_EP:invalid pci_dev!");
331 return -EINVAL;
332 }
333
334
335 memset(name, 0, sizeof(name));
336 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
337 pci_dev->addr.bus, pci_dev->addr.devid,
338 pci_dev->addr.function);
339
340 rawdev = rte_rawdev_pmd_get_named_dev(name);
341 if (rawdev == NULL) {
342 otx2_err("SDP_EP: invalid device name (%s)", name);
343 return -EINVAL;
344 }
345
346 sdpvf = (struct sdp_device *)rawdev->dev_private;
347 otx2_info("Removing SDP_EP VF[%d] ", sdpvf->vf_num);
348
349 /* rte_rawdev_close is called by pmd_release */
350 return rte_rawdev_pmd_release(rawdev);
351 }
352
353 static struct rte_pci_driver rte_sdp_rawdev_pmd = {
354 .id_table = pci_sdp_vf_map,
355 .drv_flags = (RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA),
356 .probe = otx2_sdp_rawdev_probe,
357 .remove = otx2_sdp_rawdev_remove,
358 };
359
360 RTE_PMD_REGISTER_PCI(sdp_rawdev_pci_driver, rte_sdp_rawdev_pmd);
361 RTE_PMD_REGISTER_PCI_TABLE(sdp_rawdev_pci_driver, pci_sdp_vf_map);
362 RTE_PMD_REGISTER_KMOD_DEP(sdp_rawdev_pci_driver, "vfio-pci");
363