Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2016 Cavium, Inc
3 : : */
4 : :
5 : : #include <assert.h>
6 : : #include <stdio.h>
7 : : #include <stdbool.h>
8 : : #include <errno.h>
9 : : #include <stdint.h>
10 : : #include <string.h>
11 : :
12 : : #include <rte_byteorder.h>
13 : : #include <rte_common.h>
14 : : #include <rte_debug.h>
15 : : #include <dev_driver.h>
16 : : #include <rte_eal.h>
17 : : #include <rte_log.h>
18 : : #include <rte_malloc.h>
19 : : #include <rte_memory.h>
20 : : #include <rte_lcore.h>
21 : : #include <bus_vdev_driver.h>
22 : :
23 : : #include "skeleton_eventdev.h"
24 : :
25 : : #define EVENTDEV_NAME_SKELETON_PMD event_skeleton
26 : : /**< Skeleton event device PMD name */
27 : :
28 : : static uint16_t
29 : 0 : skeleton_eventdev_enqueue(void *port, const struct rte_event *ev)
30 : : {
31 : : struct skeleton_port *sp = port;
32 : :
33 : : RTE_SET_USED(sp);
34 : : RTE_SET_USED(ev);
35 : : RTE_SET_USED(port);
36 : :
37 : 0 : return 0;
38 : : }
39 : :
40 : : static uint16_t
41 : 0 : skeleton_eventdev_enqueue_burst(void *port, const struct rte_event ev[],
42 : : uint16_t nb_events)
43 : : {
44 : : struct skeleton_port *sp = port;
45 : :
46 : : RTE_SET_USED(sp);
47 : : RTE_SET_USED(ev);
48 : : RTE_SET_USED(port);
49 : : RTE_SET_USED(nb_events);
50 : :
51 : 0 : return 0;
52 : : }
53 : :
54 : : static uint16_t
55 : 0 : skeleton_eventdev_dequeue(void *port, struct rte_event *ev,
56 : : uint64_t timeout_ticks)
57 : : {
58 : : struct skeleton_port *sp = port;
59 : :
60 : : RTE_SET_USED(sp);
61 : : RTE_SET_USED(ev);
62 : : RTE_SET_USED(timeout_ticks);
63 : :
64 : 0 : return 0;
65 : : }
66 : :
67 : : static uint16_t
68 : 0 : skeleton_eventdev_dequeue_burst(void *port, struct rte_event ev[],
69 : : uint16_t nb_events, uint64_t timeout_ticks)
70 : : {
71 : : struct skeleton_port *sp = port;
72 : :
73 : : RTE_SET_USED(sp);
74 : : RTE_SET_USED(ev);
75 : : RTE_SET_USED(nb_events);
76 : : RTE_SET_USED(timeout_ticks);
77 : :
78 : 0 : return 0;
79 : : }
80 : :
81 : : static void
82 : 286 : skeleton_eventdev_info_get(struct rte_eventdev *dev,
83 : : struct rte_event_dev_info *dev_info)
84 : : {
85 : : struct skeleton_eventdev *skel = skeleton_pmd_priv(dev);
86 : :
87 : : PMD_DRV_FUNC_TRACE();
88 : :
89 : : RTE_SET_USED(skel);
90 : :
91 : 286 : dev_info->min_dequeue_timeout_ns = 1;
92 : 286 : dev_info->max_dequeue_timeout_ns = 10000;
93 : 286 : dev_info->dequeue_timeout_ns = 25;
94 : 286 : dev_info->max_event_queues = 64;
95 : 286 : dev_info->max_event_queue_flows = (1ULL << 20);
96 : 286 : dev_info->max_event_queue_priority_levels = 8;
97 : 286 : dev_info->max_event_priority_levels = 8;
98 : 286 : dev_info->max_event_ports = 32;
99 : 286 : dev_info->max_event_port_dequeue_depth = 16;
100 : 286 : dev_info->max_event_port_enqueue_depth = 16;
101 : 286 : dev_info->max_num_events = (1ULL << 20);
102 : 286 : dev_info->event_dev_cap = RTE_EVENT_DEV_CAP_QUEUE_QOS |
103 : : RTE_EVENT_DEV_CAP_BURST_MODE |
104 : : RTE_EVENT_DEV_CAP_EVENT_QOS |
105 : : RTE_EVENT_DEV_CAP_CARRY_FLOW_ID |
106 : : RTE_EVENT_DEV_CAP_MAINTENANCE_FREE;
107 : 286 : dev_info->max_profiles_per_port = 1;
108 : 286 : }
109 : :
110 : : static int
111 : 26 : skeleton_eventdev_configure(const struct rte_eventdev *dev)
112 : : {
113 : : struct rte_eventdev_data *data = dev->data;
114 : : struct rte_event_dev_config *conf = &data->dev_conf;
115 : : struct skeleton_eventdev *skel = skeleton_pmd_priv(dev);
116 : :
117 : : PMD_DRV_FUNC_TRACE();
118 : :
119 : : RTE_SET_USED(conf);
120 : : RTE_SET_USED(skel);
121 : :
122 : : PMD_DRV_LOG(DEBUG, "Configured eventdev devid=%d", dev->data->dev_id);
123 : 26 : return 0;
124 : : }
125 : :
126 : : static int
127 : 5 : skeleton_eventdev_start(struct rte_eventdev *dev)
128 : : {
129 : : struct skeleton_eventdev *skel = skeleton_pmd_priv(dev);
130 : :
131 : : PMD_DRV_FUNC_TRACE();
132 : :
133 : : RTE_SET_USED(skel);
134 : :
135 : 5 : return 0;
136 : : }
137 : :
138 : : static void
139 : 5 : skeleton_eventdev_stop(struct rte_eventdev *dev)
140 : : {
141 : : struct skeleton_eventdev *skel = skeleton_pmd_priv(dev);
142 : :
143 : : PMD_DRV_FUNC_TRACE();
144 : :
145 : : RTE_SET_USED(skel);
146 : 5 : }
147 : :
148 : : static int
149 : 3 : skeleton_eventdev_close(struct rte_eventdev *dev)
150 : : {
151 : : struct skeleton_eventdev *skel = skeleton_pmd_priv(dev);
152 : :
153 : : PMD_DRV_FUNC_TRACE();
154 : :
155 : : RTE_SET_USED(skel);
156 : :
157 : 3 : return 0;
158 : : }
159 : :
160 : : static void
161 : 516 : skeleton_eventdev_queue_def_conf(struct rte_eventdev *dev, uint8_t queue_id,
162 : : struct rte_event_queue_conf *queue_conf)
163 : : {
164 : : struct skeleton_eventdev *skel = skeleton_pmd_priv(dev);
165 : :
166 : : PMD_DRV_FUNC_TRACE();
167 : :
168 : : RTE_SET_USED(skel);
169 : : RTE_SET_USED(queue_id);
170 : :
171 : 516 : queue_conf->nb_atomic_flows = (1ULL << 20);
172 : 516 : queue_conf->nb_atomic_order_sequences = (1ULL << 20);
173 : 516 : queue_conf->event_queue_cfg = RTE_EVENT_QUEUE_CFG_ALL_TYPES;
174 : 516 : queue_conf->priority = RTE_EVENT_DEV_PRIORITY_NORMAL;
175 : 516 : }
176 : :
177 : : static void
178 : 32 : skeleton_eventdev_queue_release(struct rte_eventdev *dev, uint8_t queue_id)
179 : : {
180 : : PMD_DRV_FUNC_TRACE();
181 : :
182 : : RTE_SET_USED(dev);
183 : : RTE_SET_USED(queue_id);
184 : 32 : }
185 : :
186 : : static int
187 : 640 : skeleton_eventdev_queue_setup(struct rte_eventdev *dev, uint8_t queue_id,
188 : : const struct rte_event_queue_conf *queue_conf)
189 : : {
190 : : struct skeleton_eventdev *skel = skeleton_pmd_priv(dev);
191 : :
192 : : PMD_DRV_FUNC_TRACE();
193 : :
194 : : RTE_SET_USED(skel);
195 : : RTE_SET_USED(queue_conf);
196 : : RTE_SET_USED(queue_id);
197 : :
198 : 640 : return 0;
199 : : }
200 : :
201 : : static void
202 : 228 : skeleton_eventdev_port_def_conf(struct rte_eventdev *dev, uint8_t port_id,
203 : : struct rte_event_port_conf *port_conf)
204 : : {
205 : : struct skeleton_eventdev *skel = skeleton_pmd_priv(dev);
206 : :
207 : : PMD_DRV_FUNC_TRACE();
208 : :
209 : : RTE_SET_USED(skel);
210 : : RTE_SET_USED(port_id);
211 : :
212 : 228 : port_conf->new_event_threshold = 32 * 1024;
213 : 228 : port_conf->dequeue_depth = 16;
214 : 228 : port_conf->enqueue_depth = 16;
215 : 228 : port_conf->event_port_cfg = 0;
216 : 228 : }
217 : :
218 : : static void
219 : 16 : skeleton_eventdev_port_release(void *port)
220 : : {
221 : : struct skeleton_port *sp = port;
222 : : PMD_DRV_FUNC_TRACE();
223 : :
224 : 179 : rte_free(sp);
225 : 16 : }
226 : :
227 : : static int
228 [ + + ]: 195 : skeleton_eventdev_port_setup(struct rte_eventdev *dev, uint8_t port_id,
229 : : const struct rte_event_port_conf *port_conf)
230 : : {
231 : : struct skeleton_port *sp;
232 : : struct skeleton_eventdev *skel = skeleton_pmd_priv(dev);
233 : :
234 : : PMD_DRV_FUNC_TRACE();
235 : :
236 : : RTE_SET_USED(skel);
237 : : RTE_SET_USED(port_conf);
238 : :
239 : : /* Free memory prior to re-allocation if needed */
240 [ + + ]: 195 : if (dev->data->ports[port_id] != NULL) {
241 : : PMD_DRV_LOG(DEBUG, "Freeing memory prior to re-allocation %d",
242 : : port_id);
243 : : skeleton_eventdev_port_release(dev->data->ports[port_id]);
244 : 163 : dev->data->ports[port_id] = NULL;
245 : : }
246 : :
247 : : /* Allocate event port memory */
248 : 195 : sp = rte_zmalloc_socket("eventdev port",
249 : : sizeof(struct skeleton_port), RTE_CACHE_LINE_SIZE,
250 : 195 : dev->data->socket_id);
251 [ - + ]: 195 : if (sp == NULL) {
252 : 0 : PMD_DRV_ERR("Failed to allocate sp port_id=%d", port_id);
253 : 0 : return -ENOMEM;
254 : : }
255 : :
256 : 195 : sp->port_id = port_id;
257 : :
258 : : PMD_DRV_LOG(DEBUG, "[%d] sp=%p", port_id, sp);
259 : :
260 : 195 : dev->data->ports[port_id] = sp;
261 : 195 : return 0;
262 : : }
263 : :
264 : : static int
265 : 12 : skeleton_eventdev_port_link(struct rte_eventdev *dev, void *port,
266 : : const uint8_t queues[], const uint8_t priorities[],
267 : : uint16_t nb_links)
268 : : {
269 : : struct skeleton_port *sp = port;
270 : : PMD_DRV_FUNC_TRACE();
271 : :
272 : : RTE_SET_USED(dev);
273 : : RTE_SET_USED(sp);
274 : : RTE_SET_USED(queues);
275 : : RTE_SET_USED(priorities);
276 : :
277 : : /* Linked all the queues */
278 : 12 : return (int)nb_links;
279 : : }
280 : :
281 : : static int
282 : 201 : skeleton_eventdev_port_unlink(struct rte_eventdev *dev, void *port,
283 : : uint8_t queues[], uint16_t nb_unlinks)
284 : : {
285 : : struct skeleton_port *sp = port;
286 : : PMD_DRV_FUNC_TRACE();
287 : :
288 : : RTE_SET_USED(dev);
289 : : RTE_SET_USED(sp);
290 : : RTE_SET_USED(queues);
291 : :
292 : : /* Unlinked all the queues */
293 : 201 : return (int)nb_unlinks;
294 : :
295 : : }
296 : :
297 : : static int
298 : 1 : skeleton_eventdev_timeout_ticks(struct rte_eventdev *dev, uint64_t ns,
299 : : uint64_t *timeout_ticks)
300 : : {
301 : : struct skeleton_eventdev *skel = skeleton_pmd_priv(dev);
302 : : uint32_t scale = 1;
303 : :
304 : : PMD_DRV_FUNC_TRACE();
305 : :
306 : : RTE_SET_USED(skel);
307 : 1 : *timeout_ticks = ns * scale;
308 : :
309 : 1 : return 0;
310 : : }
311 : :
312 : : static void
313 : 0 : skeleton_eventdev_dump(struct rte_eventdev *dev, FILE *f)
314 : : {
315 : : struct skeleton_eventdev *skel = skeleton_pmd_priv(dev);
316 : :
317 : : PMD_DRV_FUNC_TRACE();
318 : :
319 : : RTE_SET_USED(skel);
320 : : RTE_SET_USED(f);
321 : 0 : }
322 : :
323 : :
324 : : /* Initialize and register event driver with DPDK Application */
325 : : static struct eventdev_ops skeleton_eventdev_ops = {
326 : : .dev_infos_get = skeleton_eventdev_info_get,
327 : : .dev_configure = skeleton_eventdev_configure,
328 : : .dev_start = skeleton_eventdev_start,
329 : : .dev_stop = skeleton_eventdev_stop,
330 : : .dev_close = skeleton_eventdev_close,
331 : : .queue_def_conf = skeleton_eventdev_queue_def_conf,
332 : : .queue_setup = skeleton_eventdev_queue_setup,
333 : : .queue_release = skeleton_eventdev_queue_release,
334 : : .port_def_conf = skeleton_eventdev_port_def_conf,
335 : : .port_setup = skeleton_eventdev_port_setup,
336 : : .port_release = skeleton_eventdev_port_release,
337 : : .port_link = skeleton_eventdev_port_link,
338 : : .port_unlink = skeleton_eventdev_port_unlink,
339 : : .timeout_ticks = skeleton_eventdev_timeout_ticks,
340 : : .dump = skeleton_eventdev_dump
341 : : };
342 : :
343 : : static int
344 : 0 : skeleton_eventdev_init(struct rte_eventdev *eventdev)
345 : : {
346 : : struct rte_pci_device *pci_dev;
347 : : struct skeleton_eventdev *skel = skeleton_pmd_priv(eventdev);
348 : : int ret = 0;
349 : :
350 : : PMD_DRV_FUNC_TRACE();
351 : :
352 : 0 : eventdev->dev_ops = &skeleton_eventdev_ops;
353 : 0 : eventdev->enqueue = skeleton_eventdev_enqueue;
354 : 0 : eventdev->enqueue_burst = skeleton_eventdev_enqueue_burst;
355 : 0 : eventdev->dequeue = skeleton_eventdev_dequeue;
356 : 0 : eventdev->dequeue_burst = skeleton_eventdev_dequeue_burst;
357 : :
358 : : /* For secondary processes, the primary has done all the work */
359 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
360 : : return 0;
361 : :
362 : 0 : pci_dev = RTE_DEV_TO_PCI(eventdev->dev);
363 : :
364 : 0 : skel->reg_base = (uintptr_t)pci_dev->mem_resource[0].addr;
365 [ # # ]: 0 : if (!skel->reg_base) {
366 : 0 : PMD_DRV_ERR("Failed to map BAR0");
367 : : ret = -ENODEV;
368 : 0 : goto fail;
369 : : }
370 : :
371 : 0 : skel->device_id = pci_dev->id.device_id;
372 : 0 : skel->vendor_id = pci_dev->id.vendor_id;
373 : 0 : skel->subsystem_device_id = pci_dev->id.subsystem_device_id;
374 : 0 : skel->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
375 : :
376 : : PMD_DRV_LOG(DEBUG, "PCI device (%x:%x) " PCI_PRI_FMT,
377 : : pci_dev->id.vendor_id, pci_dev->id.device_id,
378 : : pci_dev->addr.domain, pci_dev->addr.bus,
379 : : pci_dev->addr.devid, pci_dev->addr.function);
380 : :
381 : : PMD_DRV_LOG(INFO, "dev_id=%d socket_id=%d (%x:%x)",
382 : : eventdev->data->dev_id, eventdev->data->socket_id,
383 : : skel->vendor_id, skel->device_id);
384 : :
385 : : fail:
386 : : return ret;
387 : : }
388 : :
389 : : /* PCI based event device */
390 : :
391 : : #define EVENTDEV_SKEL_VENDOR_ID 0x177d
392 : : #define EVENTDEV_SKEL_PRODUCT_ID 0x0001
393 : :
394 : : static const struct rte_pci_id pci_id_skeleton_map[] = {
395 : : {
396 : : RTE_PCI_DEVICE(EVENTDEV_SKEL_VENDOR_ID,
397 : : EVENTDEV_SKEL_PRODUCT_ID)
398 : : },
399 : : {
400 : : .vendor_id = 0,
401 : : },
402 : : };
403 : :
404 : : static int
405 : 0 : event_skeleton_pci_probe(struct rte_pci_driver *pci_drv,
406 : : struct rte_pci_device *pci_dev)
407 : : {
408 : 0 : return rte_event_pmd_pci_probe(pci_drv, pci_dev,
409 : : sizeof(struct skeleton_eventdev), skeleton_eventdev_init);
410 : : }
411 : :
412 : : static int
413 : 0 : event_skeleton_pci_remove(struct rte_pci_device *pci_dev)
414 : : {
415 : 0 : return rte_event_pmd_pci_remove(pci_dev, NULL);
416 : : }
417 : :
418 : : static struct rte_pci_driver pci_eventdev_skeleton_pmd = {
419 : : .id_table = pci_id_skeleton_map,
420 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
421 : : .probe = event_skeleton_pci_probe,
422 : : .remove = event_skeleton_pci_remove,
423 : : };
424 : :
425 : 238 : RTE_PMD_REGISTER_PCI(event_skeleton_pci, pci_eventdev_skeleton_pmd);
426 : : RTE_PMD_REGISTER_PCI_TABLE(event_skeleton_pci, pci_id_skeleton_map);
427 : :
428 : : /* VDEV based event device */
429 : :
430 : : static int
431 : 2 : skeleton_eventdev_create(const char *name, int socket_id, struct rte_vdev_device *vdev)
432 : : {
433 : : struct rte_eventdev *eventdev;
434 : :
435 : 2 : eventdev = rte_event_pmd_vdev_init(name,
436 : : sizeof(struct skeleton_eventdev), socket_id, vdev);
437 [ - + ]: 2 : if (eventdev == NULL) {
438 : 0 : PMD_DRV_ERR("Failed to create eventdev vdev %s", name);
439 : 0 : goto fail;
440 : : }
441 : :
442 : 2 : eventdev->dev_ops = &skeleton_eventdev_ops;
443 : 2 : eventdev->enqueue = skeleton_eventdev_enqueue;
444 : 2 : eventdev->enqueue_burst = skeleton_eventdev_enqueue_burst;
445 : 2 : eventdev->dequeue = skeleton_eventdev_dequeue;
446 : 2 : eventdev->dequeue_burst = skeleton_eventdev_dequeue_burst;
447 : :
448 : 2 : event_dev_probing_finish(eventdev);
449 : 2 : return 0;
450 : : fail:
451 : 0 : return -EFAULT;
452 : : }
453 : :
454 : : static int
455 [ + - ]: 2 : skeleton_eventdev_probe(struct rte_vdev_device *vdev)
456 : : {
457 : : const char *name;
458 : :
459 : : name = rte_vdev_device_name(vdev);
460 : : PMD_DRV_LOG(INFO, "Initializing %s on NUMA node %d", name, rte_socket_id());
461 : 2 : return skeleton_eventdev_create(name, rte_socket_id(), vdev);
462 : : }
463 : :
464 : : static int
465 [ + - ]: 2 : skeleton_eventdev_remove(struct rte_vdev_device *vdev)
466 : : {
467 : : const char *name;
468 : :
469 : : name = rte_vdev_device_name(vdev);
470 : : PMD_DRV_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
471 : :
472 : 2 : return rte_event_pmd_vdev_uninit(name);
473 : : }
474 : :
475 : : static struct rte_vdev_driver vdev_eventdev_skeleton_pmd = {
476 : : .probe = skeleton_eventdev_probe,
477 : : .remove = skeleton_eventdev_remove
478 : : };
479 : :
480 : 238 : RTE_PMD_REGISTER_VDEV(EVENTDEV_NAME_SKELETON_PMD, vdev_eventdev_skeleton_pmd);
481 [ - + ]: 238 : RTE_LOG_REGISTER_DEFAULT(skeleton_eventdev_logtype, INFO);
|