b23d76666e80e6eb52c3a1cbe07bc7479ba0dbf2
[dpdk.git] / drivers / bbdev / null / bbdev_null.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Intel Corporation
3  */
4
5 #include <string.h>
6
7 #include <rte_common.h>
8 #include <rte_bus_vdev.h>
9 #include <rte_malloc.h>
10 #include <rte_ring.h>
11 #include <rte_kvargs.h>
12
13 #include <rte_bbdev.h>
14 #include <rte_bbdev_pmd.h>
15
16 #define DRIVER_NAME bbdev_null
17
18 /*  Initialisation params structure that can be used by null BBDEV driver */
19 struct bbdev_null_params {
20         int socket_id;  /*< Null BBDEV socket */
21         uint16_t queues_num;  /*< Null BBDEV queues number */
22 };
23
24 /* Accecptable params for null BBDEV devices */
25 #define BBDEV_NULL_MAX_NB_QUEUES_ARG  "max_nb_queues"
26 #define BBDEV_NULL_SOCKET_ID_ARG      "socket_id"
27
28 static const char * const bbdev_null_valid_params[] = {
29         BBDEV_NULL_MAX_NB_QUEUES_ARG,
30         BBDEV_NULL_SOCKET_ID_ARG
31 };
32
33 /* private data structure */
34 struct bbdev_private {
35         unsigned int max_nb_queues;  /**< Max number of queues */
36 };
37
38 /* queue */
39 struct bbdev_queue {
40         struct rte_ring *processed_pkts;  /* Ring for processed packets */
41 } __rte_cache_aligned;
42
43 /* Get device info */
44 static void
45 info_get(struct rte_bbdev *dev, struct rte_bbdev_driver_info *dev_info)
46 {
47         struct bbdev_private *internals = dev->data->dev_private;
48
49         static const struct rte_bbdev_op_cap bbdev_capabilities[] = {
50                 RTE_BBDEV_END_OF_CAPABILITIES_LIST(),
51         };
52
53         static struct rte_bbdev_queue_conf default_queue_conf = {
54                 .queue_size = RTE_BBDEV_QUEUE_SIZE_LIMIT,
55         };
56
57         default_queue_conf.socket = dev->data->socket_id;
58
59         dev_info->driver_name = RTE_STR(DRIVER_NAME);
60         dev_info->max_num_queues = internals->max_nb_queues;
61         dev_info->queue_size_lim = RTE_BBDEV_QUEUE_SIZE_LIMIT;
62         dev_info->hardware_accelerated = false;
63         dev_info->max_queue_priority = 0;
64         dev_info->default_queue_conf = default_queue_conf;
65         dev_info->capabilities = bbdev_capabilities;
66         dev_info->cpu_flag_reqs = NULL;
67         dev_info->min_alignment = 0;
68
69         rte_bbdev_log_debug("got device info from %u", dev->data->dev_id);
70 }
71
72 /* Release queue */
73 static int
74 q_release(struct rte_bbdev *dev, uint16_t q_id)
75 {
76         struct bbdev_queue *q = dev->data->queues[q_id].queue_private;
77
78         if (q != NULL) {
79                 rte_ring_free(q->processed_pkts);
80                 rte_free(q);
81                 dev->data->queues[q_id].queue_private = NULL;
82         }
83
84         rte_bbdev_log_debug("released device queue %u:%u",
85                         dev->data->dev_id, q_id);
86         return 0;
87 }
88
89 /* Setup a queue */
90 static int
91 q_setup(struct rte_bbdev *dev, uint16_t q_id,
92                 const struct rte_bbdev_queue_conf *queue_conf)
93 {
94         struct bbdev_queue *q;
95         char ring_name[RTE_RING_NAMESIZE];
96         snprintf(ring_name, RTE_RING_NAMESIZE, RTE_STR(DRIVER_NAME) "%u:%u",
97                                 dev->data->dev_id, q_id);
98
99         /* Allocate the queue data structure. */
100         q = rte_zmalloc_socket(RTE_STR(DRIVER_NAME), sizeof(*q),
101                         RTE_CACHE_LINE_SIZE, queue_conf->socket);
102         if (q == NULL) {
103                 rte_bbdev_log(ERR, "Failed to allocate queue memory");
104                 return -ENOMEM;
105         }
106
107         q->processed_pkts = rte_ring_create(ring_name, queue_conf->queue_size,
108                         queue_conf->socket, RING_F_SP_ENQ | RING_F_SC_DEQ);
109         if (q->processed_pkts == NULL) {
110                 rte_bbdev_log(ERR, "Failed to create ring");
111                 goto free_q;
112         }
113
114         dev->data->queues[q_id].queue_private = q;
115         rte_bbdev_log_debug("setup device queue %s", ring_name);
116         return 0;
117
118 free_q:
119         rte_free(q);
120         return -EFAULT;
121 }
122
123 static const struct rte_bbdev_ops pmd_ops = {
124         .info_get = info_get,
125         .queue_setup = q_setup,
126         .queue_release = q_release
127 };
128
129 /* Enqueue decode burst */
130 static uint16_t
131 enqueue_dec_ops(struct rte_bbdev_queue_data *q_data,
132                 struct rte_bbdev_dec_op **ops, uint16_t nb_ops)
133 {
134         struct bbdev_queue *q = q_data->queue_private;
135         uint16_t nb_enqueued = rte_ring_enqueue_burst(q->processed_pkts,
136                         (void **)ops, nb_ops, NULL);
137
138         q_data->queue_stats.enqueue_err_count += nb_ops - nb_enqueued;
139         q_data->queue_stats.enqueued_count += nb_enqueued;
140
141         return nb_enqueued;
142 }
143
144 /* Enqueue encode burst */
145 static uint16_t
146 enqueue_enc_ops(struct rte_bbdev_queue_data *q_data,
147                 struct rte_bbdev_enc_op **ops, uint16_t nb_ops)
148 {
149         struct bbdev_queue *q = q_data->queue_private;
150         uint16_t nb_enqueued = rte_ring_enqueue_burst(q->processed_pkts,
151                         (void **)ops, nb_ops, NULL);
152
153         q_data->queue_stats.enqueue_err_count += nb_ops - nb_enqueued;
154         q_data->queue_stats.enqueued_count += nb_enqueued;
155
156         return nb_enqueued;
157 }
158
159 /* Dequeue decode burst */
160 static uint16_t
161 dequeue_dec_ops(struct rte_bbdev_queue_data *q_data,
162                 struct rte_bbdev_dec_op **ops, uint16_t nb_ops)
163 {
164         struct bbdev_queue *q = q_data->queue_private;
165         uint16_t nb_dequeued = rte_ring_dequeue_burst(q->processed_pkts,
166                         (void **)ops, nb_ops, NULL);
167         q_data->queue_stats.dequeued_count += nb_dequeued;
168
169         return nb_dequeued;
170 }
171
172 /* Dequeue encode burst */
173 static uint16_t
174 dequeue_enc_ops(struct rte_bbdev_queue_data *q_data,
175                 struct rte_bbdev_enc_op **ops, uint16_t nb_ops)
176 {
177         struct bbdev_queue *q = q_data->queue_private;
178         uint16_t nb_dequeued = rte_ring_dequeue_burst(q->processed_pkts,
179                         (void **)ops, nb_ops, NULL);
180         q_data->queue_stats.dequeued_count += nb_dequeued;
181
182         return nb_dequeued;
183 }
184
185 /* Parse 16bit integer from string argument */
186 static inline int
187 parse_u16_arg(const char *key, const char *value, void *extra_args)
188 {
189         uint16_t *u16 = extra_args;
190         unsigned int long result;
191
192         if ((value == NULL) || (extra_args == NULL))
193                 return -EINVAL;
194         errno = 0;
195         result = strtoul(value, NULL, 0);
196         if ((result >= (1 << 16)) || (errno != 0)) {
197                 rte_bbdev_log(ERR, "Invalid value %lu for %s", result, key);
198                 return -ERANGE;
199         }
200         *u16 = (uint16_t)result;
201         return 0;
202 }
203
204 /* Parse parameters used to create device */
205 static int
206 parse_bbdev_null_params(struct bbdev_null_params *params,
207                 const char *input_args)
208 {
209         struct rte_kvargs *kvlist = NULL;
210         int ret = 0;
211
212         if (params == NULL)
213                 return -EINVAL;
214         if (input_args) {
215                 kvlist = rte_kvargs_parse(input_args, bbdev_null_valid_params);
216                 if (kvlist == NULL)
217                         return -EFAULT;
218
219                 ret = rte_kvargs_process(kvlist, bbdev_null_valid_params[0],
220                                         &parse_u16_arg, &params->queues_num);
221                 if (ret < 0)
222                         goto exit;
223
224                 ret = rte_kvargs_process(kvlist, bbdev_null_valid_params[1],
225                                         &parse_u16_arg, &params->socket_id);
226                 if (ret < 0)
227                         goto exit;
228
229                 if (params->socket_id >= RTE_MAX_NUMA_NODES) {
230                         rte_bbdev_log(ERR, "Invalid socket, must be < %u",
231                                         RTE_MAX_NUMA_NODES);
232                         goto exit;
233                 }
234         }
235
236 exit:
237         if (kvlist)
238                 rte_kvargs_free(kvlist);
239         return ret;
240 }
241
242 /* Create device */
243 static int
244 null_bbdev_create(struct rte_vdev_device *vdev,
245                 struct bbdev_null_params *init_params)
246 {
247         struct rte_bbdev *bbdev;
248         const char *name = rte_vdev_device_name(vdev);
249
250         bbdev = rte_bbdev_allocate(name);
251         if (bbdev == NULL)
252                 return -ENODEV;
253
254         bbdev->data->dev_private = rte_zmalloc_socket(name,
255                         sizeof(struct bbdev_private), RTE_CACHE_LINE_SIZE,
256                         init_params->socket_id);
257         if (bbdev->data->dev_private == NULL) {
258                 rte_bbdev_release(bbdev);
259                 return -ENOMEM;
260         }
261
262         bbdev->dev_ops = &pmd_ops;
263         bbdev->device = &vdev->device;
264         bbdev->data->socket_id = init_params->socket_id;
265         bbdev->intr_handle = NULL;
266
267         /* register rx/tx burst functions for data path */
268         bbdev->dequeue_enc_ops = dequeue_enc_ops;
269         bbdev->dequeue_dec_ops = dequeue_dec_ops;
270         bbdev->enqueue_enc_ops = enqueue_enc_ops;
271         bbdev->enqueue_dec_ops = enqueue_dec_ops;
272         ((struct bbdev_private *) bbdev->data->dev_private)->max_nb_queues =
273                         init_params->queues_num;
274
275         return 0;
276 }
277
278 /* Initialise device */
279 static int
280 null_bbdev_probe(struct rte_vdev_device *vdev)
281 {
282         struct bbdev_null_params init_params = {
283                 rte_socket_id(),
284                 RTE_BBDEV_DEFAULT_MAX_NB_QUEUES
285         };
286         const char *name;
287         const char *input_args;
288
289         if (vdev == NULL)
290                 return -EINVAL;
291
292         name = rte_vdev_device_name(vdev);
293         if (name == NULL)
294                 return -EINVAL;
295
296         input_args = rte_vdev_device_args(vdev);
297         parse_bbdev_null_params(&init_params, input_args);
298
299         rte_bbdev_log_debug("Init %s on NUMA node %d with max queues: %d",
300                         name, init_params.socket_id, init_params.queues_num);
301
302         return null_bbdev_create(vdev, &init_params);
303 }
304
305 /* Uninitialise device */
306 static int
307 null_bbdev_remove(struct rte_vdev_device *vdev)
308 {
309         struct rte_bbdev *bbdev;
310         const char *name;
311
312         if (vdev == NULL)
313                 return -EINVAL;
314
315         name = rte_vdev_device_name(vdev);
316         if (name == NULL)
317                 return -EINVAL;
318
319         bbdev = rte_bbdev_get_named_dev(name);
320         if (bbdev == NULL)
321                 return -EINVAL;
322
323         rte_free(bbdev->data->dev_private);
324
325         return rte_bbdev_release(bbdev);
326 }
327
328 static struct rte_vdev_driver bbdev_null_pmd_drv = {
329         .probe = null_bbdev_probe,
330         .remove = null_bbdev_remove
331 };
332
333 RTE_PMD_REGISTER_VDEV(DRIVER_NAME, bbdev_null_pmd_drv);
334 RTE_PMD_REGISTER_PARAM_STRING(DRIVER_NAME,
335         BBDEV_NULL_MAX_NB_QUEUES_ARG"=<int> "
336         BBDEV_NULL_SOCKET_ID_ARG"=<int>");
337
338 int bbdev_logtype;
339 RTE_INIT(null_bbdev_init_log);
340 static void
341 null_bbdev_init_log(void)
342 {
343         bbdev_logtype = rte_log_register("pmd.bbdev.null");
344         if (bbdev_logtype >= 0)
345                 rte_log_set_level(bbdev_logtype, RTE_LOG_NOTICE);
346 }