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