Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2020-2021 NXP
3 : : */
4 : :
5 : : #include <stdlib.h>
6 : : #include <string.h>
7 : : #include <unistd.h>
8 : : #include <fcntl.h>
9 : : #include <sys/ioctl.h>
10 : : #include <sys/mman.h>
11 : : #include <dirent.h>
12 : :
13 : : #include <rte_common.h>
14 : : #include <bus_vdev_driver.h>
15 : : #include <rte_malloc.h>
16 : : #include <rte_ring.h>
17 : : #include <rte_kvargs.h>
18 : :
19 : : #include <rte_bbdev.h>
20 : : #include <rte_bbdev_pmd.h>
21 : :
22 : : #include <bbdev_la12xx_pmd_logs.h>
23 : : #include <bbdev_la12xx_ipc.h>
24 : : #include <bbdev_la12xx.h>
25 : :
26 : : #define DRIVER_NAME baseband_la12xx
27 : :
28 : : /* Initialisation params structure that can be used by LA12xx BBDEV driver */
29 : : struct bbdev_la12xx_params {
30 : : uint8_t queues_num; /*< LA12xx BBDEV queues number */
31 : : int8_t modem_id; /*< LA12xx modem instance id */
32 : : };
33 : :
34 : : #define LA12XX_MAX_NB_QUEUES_ARG "max_nb_queues"
35 : : #define LA12XX_VDEV_MODEM_ID_ARG "modem"
36 : : #define LA12XX_MAX_MODEM 4
37 : :
38 : : #define LA12XX_MAX_CORES 4
39 : : #define LA12XX_LDPC_ENC_CORE 0
40 : : #define LA12XX_LDPC_DEC_CORE 1
41 : :
42 : : #define LA12XX_MAX_LDPC_ENC_QUEUES 4
43 : : #define LA12XX_MAX_LDPC_DEC_QUEUES 4
44 : :
45 : : static const char * const bbdev_la12xx_valid_params[] = {
46 : : LA12XX_MAX_NB_QUEUES_ARG,
47 : : LA12XX_VDEV_MODEM_ID_ARG,
48 : : };
49 : :
50 : : static const struct rte_bbdev_op_cap bbdev_capabilities[] = {
51 : : {
52 : : .type = RTE_BBDEV_OP_LDPC_ENC,
53 : : .cap.ldpc_enc = {
54 : : .capability_flags =
55 : : RTE_BBDEV_LDPC_RATE_MATCH |
56 : : RTE_BBDEV_LDPC_CRC_24A_ATTACH |
57 : : RTE_BBDEV_LDPC_CRC_24B_ATTACH,
58 : : .num_buffers_src =
59 : : RTE_BBDEV_LDPC_MAX_CODE_BLOCKS,
60 : : .num_buffers_dst =
61 : : RTE_BBDEV_LDPC_MAX_CODE_BLOCKS,
62 : : }
63 : : },
64 : : {
65 : : .type = RTE_BBDEV_OP_LDPC_DEC,
66 : : .cap.ldpc_dec = {
67 : : .capability_flags =
68 : : RTE_BBDEV_LDPC_CRC_TYPE_24A_CHECK |
69 : : RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK |
70 : : RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP,
71 : : .num_buffers_src =
72 : : RTE_BBDEV_LDPC_MAX_CODE_BLOCKS,
73 : : .num_buffers_hard_out =
74 : : RTE_BBDEV_LDPC_MAX_CODE_BLOCKS,
75 : : .llr_size = 8,
76 : : .llr_decimals = 1,
77 : : }
78 : : },
79 : : RTE_BBDEV_END_OF_CAPABILITIES_LIST()
80 : : };
81 : :
82 : : static struct rte_bbdev_queue_conf default_queue_conf = {
83 : : .queue_size = MAX_CHANNEL_DEPTH,
84 : : };
85 : :
86 : : /* Get device info */
87 : : static void
88 : 0 : la12xx_info_get(struct rte_bbdev *dev __rte_unused,
89 : : struct rte_bbdev_driver_info *dev_info)
90 : : {
91 : : PMD_INIT_FUNC_TRACE();
92 : :
93 : 0 : dev_info->driver_name = RTE_STR(DRIVER_NAME);
94 : 0 : dev_info->max_num_queues = LA12XX_MAX_QUEUES;
95 : 0 : dev_info->queue_size_lim = MAX_CHANNEL_DEPTH;
96 : 0 : dev_info->hardware_accelerated = true;
97 : 0 : dev_info->max_dl_queue_priority = 0;
98 : 0 : dev_info->max_ul_queue_priority = 0;
99 : 0 : dev_info->data_endianness = RTE_BIG_ENDIAN;
100 : 0 : dev_info->default_queue_conf = default_queue_conf;
101 : 0 : dev_info->capabilities = bbdev_capabilities;
102 : 0 : dev_info->cpu_flag_reqs = NULL;
103 : 0 : dev_info->min_alignment = 64;
104 : 0 : dev_info->device_status = RTE_BBDEV_DEV_NOT_SUPPORTED;
105 : :
106 : 0 : dev_info->num_queues[RTE_BBDEV_OP_NONE] = 0;
107 : 0 : dev_info->num_queues[RTE_BBDEV_OP_TURBO_DEC] = 0;
108 : 0 : dev_info->num_queues[RTE_BBDEV_OP_TURBO_ENC] = 0;
109 : 0 : dev_info->num_queues[RTE_BBDEV_OP_LDPC_DEC] = LA12XX_MAX_QUEUES / 2;
110 : 0 : dev_info->num_queues[RTE_BBDEV_OP_LDPC_ENC] = LA12XX_MAX_QUEUES / 2;
111 : 0 : dev_info->num_queues[RTE_BBDEV_OP_FFT] = 0;
112 : 0 : dev_info->num_queues[RTE_BBDEV_OP_MLDTS] = 0;
113 : 0 : dev_info->queue_priority[RTE_BBDEV_OP_LDPC_DEC] = 1;
114 : 0 : dev_info->queue_priority[RTE_BBDEV_OP_LDPC_ENC] = 1;
115 : : rte_bbdev_log_debug("got device info from %u", dev->data->dev_id);
116 : 0 : }
117 : :
118 : : /* Release queue */
119 : : static int
120 : 0 : la12xx_queue_release(struct rte_bbdev *dev, uint16_t q_id)
121 : : {
122 : : RTE_SET_USED(dev);
123 : : RTE_SET_USED(q_id);
124 : :
125 : : PMD_INIT_FUNC_TRACE();
126 : :
127 : 0 : return 0;
128 : : }
129 : :
130 : : #define HUGEPG_OFFSET(A) \
131 : : ((uint64_t) ((unsigned long) (A) \
132 : : - ((uint64_t)ipc_priv->hugepg_start.host_vaddr)))
133 : :
134 : : #define MODEM_P2V(A) \
135 : : ((uint64_t) ((unsigned long) (A) \
136 : : + (unsigned long)(ipc_priv->peb_start.host_vaddr)))
137 : :
138 : : static int
139 : 0 : ipc_queue_configure(uint32_t channel_id,
140 : : ipc_t instance,
141 : : struct bbdev_la12xx_q_priv *q_priv)
142 : : {
143 : : ipc_userspace_t *ipc_priv = (ipc_userspace_t *)instance;
144 : 0 : ipc_instance_t *ipc_instance = ipc_priv->instance;
145 : : ipc_ch_t *ch;
146 : : void *vaddr;
147 : : uint32_t i = 0;
148 : : uint32_t msg_size = sizeof(struct bbdev_ipc_enqueue_op);
149 : :
150 : : PMD_INIT_FUNC_TRACE();
151 : :
152 : : rte_bbdev_log_debug("%x %p", ipc_instance->initialized,
153 : : ipc_priv->instance);
154 : : ch = &(ipc_instance->ch_list[channel_id]);
155 : :
156 : : rte_bbdev_log_debug("channel: %u, depth: %u, msg size: %u",
157 : : channel_id, q_priv->queue_size, msg_size);
158 : :
159 : : /* Start init of channel */
160 [ # # ]: 0 : ch->md.ring_size = rte_cpu_to_be_32(q_priv->queue_size);
161 : 0 : ch->md.pi = 0;
162 : 0 : ch->md.ci = 0;
163 : 0 : ch->md.msg_size = msg_size;
164 [ # # ]: 0 : for (i = 0; i < q_priv->queue_size; i++) {
165 : 0 : vaddr = rte_malloc(NULL, msg_size, RTE_CACHE_LINE_SIZE);
166 [ # # ]: 0 : if (!vaddr)
167 : : return IPC_HOST_BUF_ALLOC_FAIL;
168 : : /* Only offset now */
169 : 0 : ch->bd_h[i].modem_ptr =
170 [ # # ]: 0 : rte_cpu_to_be_32(HUGEPG_OFFSET(vaddr));
171 : 0 : ch->bd_h[i].host_virt_l = lower_32_bits(vaddr);
172 : 0 : ch->bd_h[i].host_virt_h = upper_32_bits(vaddr);
173 : 0 : q_priv->msg_ch_vaddr[i] = vaddr;
174 : : /* Not sure use of this len may be for CRC*/
175 : 0 : ch->bd_h[i].len = 0;
176 : : }
177 : 0 : ch->host_ipc_params =
178 [ # # ]: 0 : rte_cpu_to_be_32(HUGEPG_OFFSET(q_priv->host_params));
179 : :
180 : : rte_bbdev_log_debug("Channel configured");
181 : 0 : return IPC_SUCCESS;
182 : : }
183 : :
184 : : static int
185 : 0 : la12xx_e200_queue_setup(struct rte_bbdev *dev,
186 : : struct bbdev_la12xx_q_priv *q_priv)
187 : : {
188 : 0 : struct bbdev_la12xx_private *priv = dev->data->dev_private;
189 : 0 : ipc_userspace_t *ipc_priv = priv->ipc_priv;
190 : : struct gul_hif *mhif;
191 : : ipc_metadata_t *ipc_md;
192 : : ipc_ch_t *ch;
193 : : int instance_id = 0, i;
194 : : int ret;
195 : :
196 : : PMD_INIT_FUNC_TRACE();
197 : :
198 [ # # # ]: 0 : switch (q_priv->op_type) {
199 : 0 : case RTE_BBDEV_OP_LDPC_ENC:
200 : 0 : q_priv->la12xx_core_id = LA12XX_LDPC_ENC_CORE;
201 : 0 : break;
202 : 0 : case RTE_BBDEV_OP_LDPC_DEC:
203 : 0 : q_priv->la12xx_core_id = LA12XX_LDPC_DEC_CORE;
204 : 0 : break;
205 : 0 : default:
206 : 0 : rte_bbdev_log(ERR, "Unsupported op type");
207 : 0 : return -1;
208 : : }
209 : :
210 : 0 : mhif = (struct gul_hif *)ipc_priv->mhif_start.host_vaddr;
211 : : /* offset is from start of PEB */
212 : 0 : ipc_md = (ipc_metadata_t *)((uintptr_t)ipc_priv->peb_start.host_vaddr +
213 : 0 : mhif->ipc_regs.ipc_mdata_offset);
214 : 0 : ch = &ipc_md->instance_list[instance_id].ch_list[q_priv->q_id];
215 : :
216 [ # # ]: 0 : if (q_priv->q_id < priv->num_valid_queues) {
217 : : ipc_br_md_t *md = &(ch->md);
218 : :
219 [ # # ]: 0 : q_priv->feca_blk_id = rte_cpu_to_be_32(ch->feca_blk_id);
220 : 0 : q_priv->feca_blk_id_be32 = ch->feca_blk_id;
221 : 0 : q_priv->host_pi = rte_be_to_cpu_32(md->pi);
222 : 0 : q_priv->host_ci = rte_be_to_cpu_32(md->ci);
223 : 0 : q_priv->host_params = (host_ipc_params_t *)(uintptr_t)
224 [ # # ]: 0 : (rte_be_to_cpu_32(ch->host_ipc_params) +
225 : 0 : ((uint64_t)ipc_priv->hugepg_start.host_vaddr));
226 : :
227 [ # # ]: 0 : for (i = 0; i < q_priv->queue_size; i++) {
228 : : uint32_t h, l;
229 : :
230 : 0 : h = ch->bd_h[i].host_virt_h;
231 : 0 : l = ch->bd_h[i].host_virt_l;
232 : 0 : q_priv->msg_ch_vaddr[i] = (void *)join_32_bits(h, l);
233 : : }
234 : :
235 : 0 : rte_bbdev_log(WARNING,
236 : : "Queue [%d] already configured, not configuring again",
237 : : q_priv->q_id);
238 : 0 : return 0;
239 : : }
240 : :
241 : : rte_bbdev_log_debug("setting up queue %d", q_priv->q_id);
242 : :
243 : : /* Call ipc_configure_channel */
244 : 0 : ret = ipc_queue_configure(q_priv->q_id, ipc_priv, q_priv);
245 [ # # ]: 0 : if (ret) {
246 : 0 : rte_bbdev_log(ERR, "Unable to setup queue (%d) (err=%d)",
247 : : q_priv->q_id, ret);
248 : 0 : return ret;
249 : : }
250 : :
251 : : /* Set queue properties for LA12xx device */
252 [ # # # ]: 0 : switch (q_priv->op_type) {
253 : 0 : case RTE_BBDEV_OP_LDPC_ENC:
254 [ # # ]: 0 : if (priv->num_ldpc_enc_queues >= LA12XX_MAX_LDPC_ENC_QUEUES) {
255 : 0 : rte_bbdev_log(ERR,
256 : : "num_ldpc_enc_queues reached max value");
257 : 0 : return -1;
258 : : }
259 : 0 : ch->la12xx_core_id =
260 : : rte_cpu_to_be_32(LA12XX_LDPC_ENC_CORE);
261 : 0 : ch->feca_blk_id = rte_cpu_to_be_32(priv->num_ldpc_enc_queues++);
262 : 0 : break;
263 : 0 : case RTE_BBDEV_OP_LDPC_DEC:
264 [ # # ]: 0 : if (priv->num_ldpc_dec_queues >= LA12XX_MAX_LDPC_DEC_QUEUES) {
265 : 0 : rte_bbdev_log(ERR,
266 : : "num_ldpc_dec_queues reached max value");
267 : 0 : return -1;
268 : : }
269 : 0 : ch->la12xx_core_id =
270 : : rte_cpu_to_be_32(LA12XX_LDPC_DEC_CORE);
271 : 0 : ch->feca_blk_id = rte_cpu_to_be_32(priv->num_ldpc_dec_queues++);
272 : 0 : break;
273 : 0 : default:
274 : 0 : rte_bbdev_log(ERR, "Not supported op type");
275 : 0 : return -1;
276 : : }
277 [ # # ]: 0 : ch->op_type = rte_cpu_to_be_32(q_priv->op_type);
278 [ # # ]: 0 : ch->depth = rte_cpu_to_be_32(q_priv->queue_size);
279 : :
280 : : /* Store queue config here */
281 [ # # ]: 0 : q_priv->feca_blk_id = rte_cpu_to_be_32(ch->feca_blk_id);
282 : 0 : q_priv->feca_blk_id_be32 = ch->feca_blk_id;
283 : :
284 : 0 : return 0;
285 : : }
286 : :
287 : : /* Setup a queue */
288 : : static int
289 : 0 : la12xx_queue_setup(struct rte_bbdev *dev, uint16_t q_id,
290 : : const struct rte_bbdev_queue_conf *queue_conf)
291 : : {
292 : 0 : struct bbdev_la12xx_private *priv = dev->data->dev_private;
293 : : struct rte_bbdev_queue_data *q_data;
294 : : struct bbdev_la12xx_q_priv *q_priv;
295 : : int ret;
296 : :
297 : : PMD_INIT_FUNC_TRACE();
298 : :
299 : : /* Move to setup_queues callback */
300 : 0 : q_data = &dev->data->queues[q_id];
301 : 0 : q_data->queue_private = rte_zmalloc(NULL,
302 : : sizeof(struct bbdev_la12xx_q_priv), 0);
303 [ # # ]: 0 : if (!q_data->queue_private) {
304 : 0 : rte_bbdev_log(ERR, "Memory allocation failed for qpriv");
305 : 0 : return -ENOMEM;
306 : : }
307 : : q_priv = q_data->queue_private;
308 : 0 : q_priv->q_id = q_id;
309 : 0 : q_priv->bbdev_priv = dev->data->dev_private;
310 : 0 : q_priv->queue_size = queue_conf->queue_size;
311 : 0 : q_priv->op_type = queue_conf->op_type;
312 : :
313 : 0 : ret = la12xx_e200_queue_setup(dev, q_priv);
314 [ # # ]: 0 : if (ret) {
315 : 0 : rte_bbdev_log(ERR, "e200_queue_setup failed for qid: %d",
316 : : q_id);
317 : 0 : return ret;
318 : : }
319 : :
320 : : /* Store queue config here */
321 : 0 : priv->num_valid_queues++;
322 : :
323 : 0 : return 0;
324 : : }
325 : :
326 : : static int
327 : 0 : la12xx_start(struct rte_bbdev *dev)
328 : : {
329 : 0 : struct bbdev_la12xx_private *priv = dev->data->dev_private;
330 : 0 : ipc_userspace_t *ipc_priv = priv->ipc_priv;
331 : : int ready = 0;
332 : : struct gul_hif *hif_start;
333 : :
334 : : PMD_INIT_FUNC_TRACE();
335 : :
336 : 0 : hif_start = (struct gul_hif *)ipc_priv->mhif_start.host_vaddr;
337 : :
338 : : /* Set Host Read bit */
339 : 0 : SET_HIF_HOST_RDY(hif_start, HIF_HOST_READY_IPC_APP);
340 : :
341 : : /* Now wait for modem ready bit */
342 [ # # ]: 0 : while (!ready)
343 : 0 : ready = CHK_HIF_MOD_RDY(hif_start, HIF_MOD_READY_IPC_APP);
344 : :
345 : 0 : return 0;
346 : : }
347 : :
348 : : static const struct rte_bbdev_ops pmd_ops = {
349 : : .info_get = la12xx_info_get,
350 : : .queue_setup = la12xx_queue_setup,
351 : : .queue_release = la12xx_queue_release,
352 : : .start = la12xx_start
353 : : };
354 : :
355 : : static inline int
356 : : is_bd_ring_full(uint32_t ci, uint32_t ci_flag,
357 : : uint32_t pi, uint32_t pi_flag)
358 : : {
359 : 0 : if (pi == ci) {
360 [ # # ]: 0 : if (pi_flag != ci_flag)
361 : : return 1; /* Ring is Full */
362 : : }
363 : : return 0;
364 : : }
365 : :
366 : : static inline int
367 : 0 : prepare_ldpc_enc_op(struct rte_bbdev_enc_op *bbdev_enc_op,
368 : : struct bbdev_la12xx_q_priv *q_priv __rte_unused,
369 : : struct rte_bbdev_op_data *in_op_data __rte_unused,
370 : : struct rte_bbdev_op_data *out_op_data)
371 : : {
372 : : struct rte_bbdev_op_ldpc_enc *ldpc_enc = &bbdev_enc_op->ldpc_enc;
373 : : uint32_t total_out_bits;
374 : :
375 : 0 : total_out_bits = (ldpc_enc->tb_params.cab *
376 : 0 : ldpc_enc->tb_params.ea) + (ldpc_enc->tb_params.c -
377 : 0 : ldpc_enc->tb_params.cab) * ldpc_enc->tb_params.eb;
378 : :
379 : 0 : ldpc_enc->output.length = (total_out_bits + 7)/8;
380 : :
381 : 0 : rte_pktmbuf_append(out_op_data->data, ldpc_enc->output.length);
382 : :
383 : 0 : return 0;
384 : : }
385 : :
386 : : static inline int
387 : 0 : prepare_ldpc_dec_op(struct rte_bbdev_dec_op *bbdev_dec_op,
388 : : struct bbdev_ipc_dequeue_op *bbdev_ipc_op,
389 : : struct bbdev_la12xx_q_priv *q_priv __rte_unused,
390 : : struct rte_bbdev_op_data *out_op_data __rte_unused)
391 : : {
392 : : struct rte_bbdev_op_ldpc_dec *ldpc_dec = &bbdev_dec_op->ldpc_dec;
393 : : uint32_t total_out_bits;
394 : : uint32_t num_code_blocks = 0;
395 : : uint16_t sys_cols;
396 : :
397 [ # # ]: 0 : sys_cols = (ldpc_dec->basegraph == 1) ? 22 : 10;
398 [ # # ]: 0 : if (ldpc_dec->tb_params.c == 1) {
399 : 0 : total_out_bits = ((sys_cols * ldpc_dec->z_c) -
400 : 0 : ldpc_dec->n_filler);
401 : : /* 5G-NR protocol uses 16 bit CRC when output packet
402 : : * size <= 3824 (bits). Otherwise 24 bit CRC is used.
403 : : * Adjust the output bits accordingly
404 : : */
405 [ # # ]: 0 : if (total_out_bits - 16 <= 3824)
406 : : total_out_bits -= 16;
407 : : else
408 : 0 : total_out_bits -= 24;
409 : 0 : ldpc_dec->hard_output.length = (total_out_bits / 8);
410 : : } else {
411 : 0 : total_out_bits = (((sys_cols * ldpc_dec->z_c) -
412 : 0 : ldpc_dec->n_filler - 24) *
413 : 0 : ldpc_dec->tb_params.c);
414 : 0 : ldpc_dec->hard_output.length = (total_out_bits / 8) - 3;
415 : : }
416 : :
417 : 0 : num_code_blocks = ldpc_dec->tb_params.c;
418 : :
419 [ # # ]: 0 : bbdev_ipc_op->num_code_blocks = rte_cpu_to_be_32(num_code_blocks);
420 : :
421 : 0 : return 0;
422 : : }
423 : :
424 : : static int
425 : 0 : enqueue_single_op(struct bbdev_la12xx_q_priv *q_priv, void *bbdev_op)
426 : : {
427 : 0 : struct bbdev_la12xx_private *priv = q_priv->bbdev_priv;
428 : 0 : ipc_userspace_t *ipc_priv = priv->ipc_priv;
429 : 0 : ipc_instance_t *ipc_instance = ipc_priv->instance;
430 : : struct bbdev_ipc_dequeue_op *bbdev_ipc_op;
431 : : struct rte_bbdev_op_ldpc_enc *ldpc_enc;
432 : : struct rte_bbdev_op_ldpc_dec *ldpc_dec;
433 : 0 : uint32_t q_id = q_priv->q_id;
434 : : uint32_t ci, ci_flag, pi, pi_flag;
435 : : ipc_ch_t *ch = &(ipc_instance->ch_list[q_id]);
436 : : ipc_br_md_t *md = &(ch->md);
437 : : size_t virt;
438 : 0 : char *huge_start_addr =
439 : : (char *)q_priv->bbdev_priv->ipc_priv->hugepg_start.host_vaddr;
440 : : struct rte_bbdev_op_data *in_op_data, *out_op_data;
441 : : char *data_ptr;
442 : : uint32_t l1_pcie_addr;
443 : : int ret;
444 : :
445 : 0 : ci = IPC_GET_CI_INDEX(q_priv->host_ci);
446 : 0 : ci_flag = IPC_GET_CI_FLAG(q_priv->host_ci);
447 : :
448 : 0 : pi = IPC_GET_PI_INDEX(q_priv->host_pi);
449 [ # # ]: 0 : pi_flag = IPC_GET_PI_FLAG(q_priv->host_pi);
450 : :
451 : : rte_bbdev_dp_log(DEBUG, "before bd_ring_full: pi: %u, ci: %u,"
452 : : "pi_flag: %u, ci_flag: %u, ring size: %u",
453 : : pi, ci, pi_flag, ci_flag, q_priv->queue_size);
454 : :
455 : : if (is_bd_ring_full(ci, ci_flag, pi, pi_flag)) {
456 : : rte_bbdev_dp_log(DEBUG, "bd ring full for queue id: %d", q_id);
457 : : return IPC_CH_FULL;
458 : : }
459 : :
460 : 0 : virt = MODEM_P2V(q_priv->host_params->bd_m_modem_ptr[pi]);
461 : 0 : bbdev_ipc_op = (struct bbdev_ipc_dequeue_op *)virt;
462 : 0 : q_priv->bbdev_op[pi] = bbdev_op;
463 : :
464 [ # # # ]: 0 : switch (q_priv->op_type) {
465 : 0 : case RTE_BBDEV_OP_LDPC_ENC:
466 : : ldpc_enc = &(((struct rte_bbdev_enc_op *)bbdev_op)->ldpc_enc);
467 : 0 : in_op_data = &ldpc_enc->input;
468 : 0 : out_op_data = &ldpc_enc->output;
469 : :
470 : 0 : ret = prepare_ldpc_enc_op(bbdev_op, q_priv,
471 : : in_op_data, out_op_data);
472 [ # # ]: 0 : if (ret) {
473 : 0 : rte_bbdev_log(ERR, "process_ldpc_enc_op fail, ret: %d",
474 : : ret);
475 : 0 : return ret;
476 : : }
477 : : break;
478 : :
479 : 0 : case RTE_BBDEV_OP_LDPC_DEC:
480 : : ldpc_dec = &(((struct rte_bbdev_dec_op *)bbdev_op)->ldpc_dec);
481 : 0 : in_op_data = &ldpc_dec->input;
482 : :
483 : 0 : out_op_data = &ldpc_dec->hard_output;
484 : :
485 : 0 : ret = prepare_ldpc_dec_op(bbdev_op, bbdev_ipc_op,
486 : : q_priv, out_op_data);
487 [ # # ]: 0 : if (ret) {
488 : 0 : rte_bbdev_log(ERR, "process_ldpc_dec_op fail, ret: %d",
489 : : ret);
490 : 0 : return ret;
491 : : }
492 : : break;
493 : :
494 : 0 : default:
495 : 0 : rte_bbdev_log(ERR, "unsupported bbdev_ipc op type");
496 : 0 : return -1;
497 : : }
498 : :
499 [ # # ]: 0 : if (in_op_data->data) {
500 : 0 : data_ptr = rte_pktmbuf_mtod(in_op_data->data, char *);
501 : 0 : l1_pcie_addr = (uint32_t)GUL_USER_HUGE_PAGE_ADDR +
502 : 0 : data_ptr - huge_start_addr;
503 : 0 : bbdev_ipc_op->in_addr = l1_pcie_addr;
504 : 0 : bbdev_ipc_op->in_len = in_op_data->length;
505 : : }
506 : :
507 [ # # ]: 0 : if (out_op_data->data) {
508 : 0 : data_ptr = rte_pktmbuf_mtod(out_op_data->data, char *);
509 : 0 : l1_pcie_addr = (uint32_t)GUL_USER_HUGE_PAGE_ADDR +
510 : 0 : data_ptr - huge_start_addr;
511 [ # # ]: 0 : bbdev_ipc_op->out_addr = rte_cpu_to_be_32(l1_pcie_addr);
512 [ # # ]: 0 : bbdev_ipc_op->out_len = rte_cpu_to_be_32(out_op_data->length);
513 : : }
514 : :
515 : : /* Move Producer Index forward */
516 : 0 : pi++;
517 : : /* Flip the PI flag, if wrapping */
518 [ # # ]: 0 : if (unlikely(q_priv->queue_size == pi)) {
519 : : pi = 0;
520 : 0 : pi_flag = pi_flag ? 0 : 1;
521 : : }
522 : :
523 [ # # ]: 0 : if (pi_flag)
524 : 0 : IPC_SET_PI_FLAG(pi);
525 : : else
526 : 0 : IPC_RESET_PI_FLAG(pi);
527 : 0 : q_priv->host_pi = pi;
528 : :
529 : : /* Wait for Data Copy & pi_flag update to complete before updating pi */
530 : : rte_mb();
531 : : /* now update pi */
532 [ # # ]: 0 : md->pi = rte_cpu_to_be_32(pi);
533 : :
534 : : rte_bbdev_dp_log(DEBUG, "enter: pi: %u, ci: %u,"
535 : : "pi_flag: %u, ci_flag: %u, ring size: %u",
536 : : pi, ci, pi_flag, ci_flag, q_priv->queue_size);
537 : :
538 : 0 : return 0;
539 : : }
540 : :
541 : : /* Enqueue decode burst */
542 : : static uint16_t
543 : 0 : enqueue_dec_ops(struct rte_bbdev_queue_data *q_data,
544 : : struct rte_bbdev_dec_op **ops, uint16_t nb_ops)
545 : : {
546 : 0 : struct bbdev_la12xx_q_priv *q_priv = q_data->queue_private;
547 : : int nb_enqueued, ret;
548 : :
549 [ # # ]: 0 : for (nb_enqueued = 0; nb_enqueued < nb_ops; nb_enqueued++) {
550 : 0 : ret = enqueue_single_op(q_priv, ops[nb_enqueued]);
551 [ # # ]: 0 : if (ret)
552 : : break;
553 : : }
554 : :
555 : 0 : q_data->queue_stats.enqueue_err_count += nb_ops - nb_enqueued;
556 : 0 : q_data->queue_stats.enqueued_count += nb_enqueued;
557 : :
558 : 0 : return nb_enqueued;
559 : : }
560 : :
561 : : /* Enqueue encode burst */
562 : : static uint16_t
563 : 0 : enqueue_enc_ops(struct rte_bbdev_queue_data *q_data,
564 : : struct rte_bbdev_enc_op **ops, uint16_t nb_ops)
565 : : {
566 : 0 : struct bbdev_la12xx_q_priv *q_priv = q_data->queue_private;
567 : : int nb_enqueued, ret;
568 : :
569 [ # # ]: 0 : for (nb_enqueued = 0; nb_enqueued < nb_ops; nb_enqueued++) {
570 : 0 : ret = enqueue_single_op(q_priv, ops[nb_enqueued]);
571 [ # # ]: 0 : if (ret)
572 : : break;
573 : : }
574 : :
575 : 0 : q_data->queue_stats.enqueue_err_count += nb_ops - nb_enqueued;
576 : 0 : q_data->queue_stats.enqueued_count += nb_enqueued;
577 : :
578 : 0 : return nb_enqueued;
579 : : }
580 : :
581 : : /* Dequeue encode burst */
582 : : static void *
583 : 0 : dequeue_single_op(struct bbdev_la12xx_q_priv *q_priv, void *dst)
584 : : {
585 : : void *op;
586 : : uint32_t ci, ci_flag;
587 : : uint32_t temp_ci;
588 : :
589 : 0 : temp_ci = q_priv->host_params->ci;
590 [ # # ]: 0 : if (temp_ci == q_priv->host_ci)
591 : : return NULL;
592 : :
593 : 0 : ci = IPC_GET_CI_INDEX(q_priv->host_ci);
594 : 0 : ci_flag = IPC_GET_CI_FLAG(q_priv->host_ci);
595 : :
596 : : rte_bbdev_dp_log(DEBUG,
597 : : "ci: %u, ci_flag: %u, ring size: %u",
598 : : ci, ci_flag, q_priv->queue_size);
599 : :
600 : 0 : op = q_priv->bbdev_op[ci];
601 : :
602 [ # # ]: 0 : rte_memcpy(dst, q_priv->msg_ch_vaddr[ci],
603 : : sizeof(struct bbdev_ipc_enqueue_op));
604 : :
605 : : /* Move Consumer Index forward */
606 : 0 : ci++;
607 : : /* Flip the CI flag, if wrapping */
608 [ # # ]: 0 : if (q_priv->queue_size == ci) {
609 : : ci = 0;
610 : 0 : ci_flag = ci_flag ? 0 : 1;
611 : : }
612 [ # # ]: 0 : if (ci_flag)
613 : 0 : IPC_SET_CI_FLAG(ci);
614 : : else
615 : 0 : IPC_RESET_CI_FLAG(ci);
616 : :
617 : 0 : q_priv->host_ci = ci;
618 : :
619 : : rte_bbdev_dp_log(DEBUG,
620 : : "exit: ci: %u, ci_flag: %u, ring size: %u",
621 : : ci, ci_flag, q_priv->queue_size);
622 : :
623 : 0 : return op;
624 : : }
625 : :
626 : : /* Dequeue decode burst */
627 : : static uint16_t
628 : 0 : dequeue_dec_ops(struct rte_bbdev_queue_data *q_data,
629 : : struct rte_bbdev_dec_op **ops, uint16_t nb_ops)
630 : : {
631 : 0 : struct bbdev_la12xx_q_priv *q_priv = q_data->queue_private;
632 : : struct bbdev_ipc_enqueue_op bbdev_ipc_op;
633 : : int nb_dequeued;
634 : :
635 [ # # ]: 0 : for (nb_dequeued = 0; nb_dequeued < nb_ops; nb_dequeued++) {
636 : 0 : ops[nb_dequeued] = dequeue_single_op(q_priv, &bbdev_ipc_op);
637 [ # # ]: 0 : if (!ops[nb_dequeued])
638 : : break;
639 : 0 : ops[nb_dequeued]->status = bbdev_ipc_op.status;
640 : : }
641 : 0 : q_data->queue_stats.dequeued_count += nb_dequeued;
642 : :
643 : 0 : return nb_dequeued;
644 : : }
645 : :
646 : : /* Dequeue encode burst */
647 : : static uint16_t
648 : 0 : dequeue_enc_ops(struct rte_bbdev_queue_data *q_data,
649 : : struct rte_bbdev_enc_op **ops, uint16_t nb_ops)
650 : : {
651 : 0 : struct bbdev_la12xx_q_priv *q_priv = q_data->queue_private;
652 : : struct bbdev_ipc_enqueue_op bbdev_ipc_op;
653 : : int nb_enqueued;
654 : :
655 [ # # ]: 0 : for (nb_enqueued = 0; nb_enqueued < nb_ops; nb_enqueued++) {
656 : 0 : ops[nb_enqueued] = dequeue_single_op(q_priv, &bbdev_ipc_op);
657 [ # # ]: 0 : if (!ops[nb_enqueued])
658 : : break;
659 : 0 : ops[nb_enqueued]->status = bbdev_ipc_op.status;
660 : : }
661 : 0 : q_data->queue_stats.enqueued_count += nb_enqueued;
662 : :
663 : 0 : return nb_enqueued;
664 : : }
665 : :
666 : : static struct hugepage_info *
667 : 0 : get_hugepage_info(void)
668 : : {
669 : : struct hugepage_info *hp_info;
670 : : struct rte_memseg *mseg;
671 : :
672 : : PMD_INIT_FUNC_TRACE();
673 : :
674 : : /* TODO - find a better way */
675 : 0 : hp_info = rte_malloc(NULL, sizeof(struct hugepage_info), 0);
676 [ # # ]: 0 : if (!hp_info) {
677 : 0 : rte_bbdev_log(ERR, "Unable to allocate on local heap");
678 : 0 : return NULL;
679 : : }
680 : :
681 : 0 : mseg = rte_mem_virt2memseg(hp_info, NULL);
682 : 0 : hp_info->vaddr = mseg->addr;
683 : 0 : hp_info->paddr = rte_mem_virt2phy(mseg->addr);
684 : 0 : hp_info->len = mseg->len;
685 : :
686 : 0 : return hp_info;
687 : : }
688 : :
689 : : static int
690 : 0 : open_ipc_dev(int modem_id)
691 : : {
692 : : char dev_initials[16], dev_path[PATH_MAX];
693 : : struct dirent *entry;
694 : : int dev_ipc = 0;
695 : : DIR *dir;
696 : :
697 : 0 : dir = opendir("/dev/");
698 [ # # ]: 0 : if (!dir) {
699 : 0 : rte_bbdev_log(ERR, "Unable to open /dev/");
700 : 0 : return -1;
701 : : }
702 : :
703 : : sprintf(dev_initials, "gulipcgul%d", modem_id);
704 : :
705 [ # # ]: 0 : while ((entry = readdir(dir)) != NULL) {
706 [ # # ]: 0 : if (!strncmp(dev_initials, entry->d_name,
707 : : sizeof(dev_initials) - 1))
708 : : break;
709 : : }
710 : :
711 [ # # ]: 0 : if (!entry) {
712 : 0 : rte_bbdev_log(ERR, "Error: No gulipcgul%d device", modem_id);
713 : 0 : return -1;
714 : : }
715 : :
716 : 0 : sprintf(dev_path, "/dev/%s", entry->d_name);
717 : : dev_ipc = open(dev_path, O_RDWR);
718 [ # # ]: 0 : if (dev_ipc < 0) {
719 : 0 : rte_bbdev_log(ERR, "Error: Cannot open %s", dev_path);
720 : 0 : return -errno;
721 : : }
722 : :
723 : : return dev_ipc;
724 : : }
725 : :
726 : : static int
727 : 0 : setup_la12xx_dev(struct rte_bbdev *dev)
728 : : {
729 : 0 : struct bbdev_la12xx_private *priv = dev->data->dev_private;
730 : 0 : ipc_userspace_t *ipc_priv = priv->ipc_priv;
731 : : struct hugepage_info *hp = NULL;
732 : : ipc_channel_us_t *ipc_priv_ch = NULL;
733 : : int dev_ipc = 0, dev_mem = 0, i;
734 : : ipc_metadata_t *ipc_md;
735 : : struct gul_hif *mhif;
736 : : uint32_t phy_align = 0;
737 : : int ret;
738 : :
739 : : PMD_INIT_FUNC_TRACE();
740 : :
741 [ # # ]: 0 : if (!ipc_priv) {
742 : : /* TODO - get a better way */
743 : : /* Get the hugepage info against it */
744 : 0 : hp = get_hugepage_info();
745 [ # # ]: 0 : if (!hp) {
746 : 0 : rte_bbdev_log(ERR, "Unable to get hugepage info");
747 : : ret = -ENOMEM;
748 : 0 : goto err;
749 : : }
750 : :
751 : : rte_bbdev_log_debug("0x%" PRIx64 " %p 0x%" PRIx64,
752 : : hp->paddr, hp->vaddr, hp->len);
753 : :
754 : 0 : ipc_priv = rte_zmalloc(0, sizeof(ipc_userspace_t), 0);
755 [ # # ]: 0 : if (ipc_priv == NULL) {
756 : 0 : rte_bbdev_log(ERR,
757 : : "Unable to allocate memory for ipc priv");
758 : : ret = -ENOMEM;
759 : 0 : goto err;
760 : : }
761 : :
762 [ # # ]: 0 : for (i = 0; i < IPC_MAX_CHANNEL_COUNT; i++) {
763 : 0 : ipc_priv_ch = rte_zmalloc(0,
764 : : sizeof(ipc_channel_us_t), 0);
765 [ # # ]: 0 : if (ipc_priv_ch == NULL) {
766 : 0 : rte_bbdev_log(ERR,
767 : : "Unable to allocate memory for channels");
768 : : ret = -ENOMEM;
769 : : }
770 : 0 : ipc_priv->channels[i] = ipc_priv_ch;
771 : : }
772 : :
773 : : dev_mem = open("/dev/mem", O_RDWR);
774 [ # # ]: 0 : if (dev_mem < 0) {
775 : 0 : rte_bbdev_log(ERR, "Error: Cannot open /dev/mem");
776 : 0 : ret = -errno;
777 : 0 : goto err;
778 : : }
779 : :
780 : 0 : ipc_priv->instance_id = 0;
781 : 0 : ipc_priv->dev_mem = dev_mem;
782 : :
783 : : rte_bbdev_log_debug("hugepg input 0x%" PRIx64 "%p 0x%" PRIx64,
784 : : hp->paddr, hp->vaddr, hp->len);
785 : :
786 : 0 : ipc_priv->sys_map.hugepg_start.host_phys = hp->paddr;
787 : 0 : ipc_priv->sys_map.hugepg_start.size = hp->len;
788 : :
789 : 0 : ipc_priv->hugepg_start.host_phys = hp->paddr;
790 : 0 : ipc_priv->hugepg_start.host_vaddr = hp->vaddr;
791 : 0 : ipc_priv->hugepg_start.size = hp->len;
792 : :
793 : 0 : rte_free(hp);
794 : : hp = NULL;
795 : : }
796 : :
797 : 0 : dev_ipc = open_ipc_dev(priv->modem_id);
798 [ # # ]: 0 : if (dev_ipc < 0) {
799 : 0 : rte_bbdev_log(ERR, "Error: open_ipc_dev failed");
800 : 0 : goto err;
801 : : }
802 : 0 : ipc_priv->dev_ipc = dev_ipc;
803 : :
804 : 0 : ret = ioctl(ipc_priv->dev_ipc, IOCTL_GUL_IPC_GET_SYS_MAP,
805 : : &ipc_priv->sys_map);
806 [ # # ]: 0 : if (ret) {
807 : 0 : rte_bbdev_log(ERR,
808 : : "IOCTL_GUL_IPC_GET_SYS_MAP ioctl failed");
809 : 0 : goto err;
810 : : }
811 : :
812 : 0 : phy_align = (ipc_priv->sys_map.mhif_start.host_phys % 0x1000);
813 : 0 : ipc_priv->mhif_start.host_vaddr =
814 : 0 : mmap(0, ipc_priv->sys_map.mhif_start.size + phy_align,
815 : : (PROT_READ | PROT_WRITE), MAP_SHARED, ipc_priv->dev_mem,
816 : 0 : (ipc_priv->sys_map.mhif_start.host_phys - phy_align));
817 [ # # ]: 0 : if (ipc_priv->mhif_start.host_vaddr == MAP_FAILED) {
818 : 0 : rte_bbdev_log(ERR, "MAP failed:");
819 : 0 : ret = -errno;
820 : 0 : goto err;
821 : : }
822 : :
823 : 0 : ipc_priv->mhif_start.host_vaddr = (void *) ((uintptr_t)
824 : 0 : (ipc_priv->mhif_start.host_vaddr) + phy_align);
825 : :
826 : 0 : phy_align = (ipc_priv->sys_map.peb_start.host_phys % 0x1000);
827 : 0 : ipc_priv->peb_start.host_vaddr =
828 : 0 : mmap(0, ipc_priv->sys_map.peb_start.size + phy_align,
829 : : (PROT_READ | PROT_WRITE), MAP_SHARED, ipc_priv->dev_mem,
830 : 0 : (ipc_priv->sys_map.peb_start.host_phys - phy_align));
831 [ # # ]: 0 : if (ipc_priv->peb_start.host_vaddr == MAP_FAILED) {
832 : 0 : rte_bbdev_log(ERR, "MAP failed:");
833 : 0 : ret = -errno;
834 : 0 : goto err;
835 : : }
836 : :
837 : 0 : ipc_priv->peb_start.host_vaddr = (void *)((uintptr_t)
838 : 0 : (ipc_priv->peb_start.host_vaddr) + phy_align);
839 : :
840 : 0 : phy_align = (ipc_priv->sys_map.modem_ccsrbar.host_phys % 0x1000);
841 : 0 : ipc_priv->modem_ccsrbar.host_vaddr =
842 : 0 : mmap(0, ipc_priv->sys_map.modem_ccsrbar.size + phy_align,
843 : : (PROT_READ | PROT_WRITE), MAP_SHARED, ipc_priv->dev_mem,
844 : 0 : (ipc_priv->sys_map.modem_ccsrbar.host_phys - phy_align));
845 [ # # ]: 0 : if (ipc_priv->modem_ccsrbar.host_vaddr == MAP_FAILED) {
846 : 0 : rte_bbdev_log(ERR, "MAP failed:");
847 : 0 : ret = -errno;
848 : 0 : goto err;
849 : : }
850 : :
851 : 0 : ipc_priv->modem_ccsrbar.host_vaddr = (void *)((uintptr_t)
852 : 0 : (ipc_priv->modem_ccsrbar.host_vaddr) + phy_align);
853 : :
854 : 0 : ipc_priv->hugepg_start.modem_phys =
855 : 0 : ipc_priv->sys_map.hugepg_start.modem_phys;
856 : :
857 : 0 : ipc_priv->mhif_start.host_phys =
858 : 0 : ipc_priv->sys_map.mhif_start.host_phys;
859 : 0 : ipc_priv->mhif_start.size = ipc_priv->sys_map.mhif_start.size;
860 : 0 : ipc_priv->peb_start.host_phys = ipc_priv->sys_map.peb_start.host_phys;
861 : 0 : ipc_priv->peb_start.size = ipc_priv->sys_map.peb_start.size;
862 : :
863 : 0 : rte_bbdev_log(INFO, "peb 0x%" PRIx64 "%p 0x%" PRIx32,
864 : : ipc_priv->peb_start.host_phys,
865 : : ipc_priv->peb_start.host_vaddr,
866 : : ipc_priv->peb_start.size);
867 : 0 : rte_bbdev_log(INFO, "hugepg 0x%" PRIx64 "%p 0x%" PRIx32,
868 : : ipc_priv->hugepg_start.host_phys,
869 : : ipc_priv->hugepg_start.host_vaddr,
870 : : ipc_priv->hugepg_start.size);
871 : 0 : rte_bbdev_log(INFO, "mhif 0x%" PRIx64 "%p 0x%" PRIx32,
872 : : ipc_priv->mhif_start.host_phys,
873 : : ipc_priv->mhif_start.host_vaddr,
874 : : ipc_priv->mhif_start.size);
875 : 0 : mhif = (struct gul_hif *)ipc_priv->mhif_start.host_vaddr;
876 : :
877 : : /* offset is from start of PEB */
878 : 0 : ipc_md = (ipc_metadata_t *)((uintptr_t)ipc_priv->peb_start.host_vaddr +
879 : 0 : mhif->ipc_regs.ipc_mdata_offset);
880 : :
881 [ # # ]: 0 : if (sizeof(ipc_metadata_t) != mhif->ipc_regs.ipc_mdata_size) {
882 : 0 : rte_bbdev_log(ERR,
883 : : "ipc_metadata_t =0x%" PRIx64
884 : : ", mhif->ipc_regs.ipc_mdata_size=0x%" PRIx32,
885 : : (uint64_t)(sizeof(ipc_metadata_t)),
886 : : mhif->ipc_regs.ipc_mdata_size);
887 : 0 : rte_bbdev_log(ERR, "--> mhif->ipc_regs.ipc_mdata_offset= 0x%"
888 : : PRIx32, mhif->ipc_regs.ipc_mdata_offset);
889 : 0 : rte_bbdev_log(ERR, "gul_hif size=0x%" PRIx64,
890 : : (uint64_t)(sizeof(struct gul_hif)));
891 : 0 : return IPC_MD_SZ_MISS_MATCH;
892 : : }
893 : :
894 : 0 : ipc_priv->instance = (ipc_instance_t *)
895 : 0 : (&ipc_md->instance_list[ipc_priv->instance_id]);
896 : :
897 : : rte_bbdev_log_debug("finish host init");
898 : :
899 : 0 : priv->ipc_priv = ipc_priv;
900 : :
901 : 0 : return 0;
902 : :
903 : 0 : err:
904 : 0 : rte_free(hp);
905 : 0 : rte_free(ipc_priv);
906 : 0 : rte_free(ipc_priv_ch);
907 [ # # ]: 0 : if (dev_mem)
908 : 0 : close(dev_mem);
909 [ # # ]: 0 : if (dev_ipc)
910 : 0 : close(dev_ipc);
911 : :
912 : : return ret;
913 : : }
914 : :
915 : : static inline int
916 : 0 : parse_u16_arg(const char *key, const char *value, void *extra_args)
917 : : {
918 : : uint16_t *u16 = extra_args;
919 : :
920 : : uint64_t result;
921 [ # # ]: 0 : if ((value == NULL) || (extra_args == NULL))
922 : : return -EINVAL;
923 : 0 : errno = 0;
924 : 0 : result = strtoul(value, NULL, 0);
925 [ # # # # ]: 0 : if ((result >= (1 << 16)) || (errno != 0)) {
926 : 0 : rte_bbdev_log(ERR, "Invalid value %" PRIu64 " for %s",
927 : : result, key);
928 : 0 : return -ERANGE;
929 : : }
930 : 0 : *u16 = (uint16_t)result;
931 : 0 : return 0;
932 : : }
933 : :
934 : : /* Parse integer from integer argument */
935 : : static int
936 : 0 : parse_integer_arg(const char *key __rte_unused,
937 : : const char *value, void *extra_args)
938 : : {
939 : : int i;
940 : : char *end;
941 : :
942 : 0 : errno = 0;
943 : :
944 : 0 : i = strtol(value, &end, 10);
945 [ # # # # : 0 : if (*end != 0 || errno != 0 || i < 0 || i > LA12XX_MAX_MODEM) {
# # ]
946 : 0 : rte_bbdev_log(ERR, "Supported Port IDS are 0 to %d",
947 : : LA12XX_MAX_MODEM - 1);
948 : 0 : return -EINVAL;
949 : : }
950 : :
951 : 0 : *((uint32_t *)extra_args) = i;
952 : :
953 : 0 : return 0;
954 : : }
955 : :
956 : : /* Parse parameters used to create device */
957 : : static int
958 : 0 : parse_bbdev_la12xx_params(struct bbdev_la12xx_params *params,
959 : : const char *input_args)
960 : : {
961 : : struct rte_kvargs *kvlist = NULL;
962 : : int ret = 0;
963 : :
964 [ # # ]: 0 : if (params == NULL)
965 : : return -EINVAL;
966 [ # # ]: 0 : if (input_args) {
967 : 0 : kvlist = rte_kvargs_parse(input_args,
968 : : bbdev_la12xx_valid_params);
969 [ # # ]: 0 : if (kvlist == NULL)
970 : : return -EFAULT;
971 : :
972 : 0 : ret = rte_kvargs_process(kvlist, bbdev_la12xx_valid_params[0],
973 : 0 : &parse_u16_arg, ¶ms->queues_num);
974 [ # # ]: 0 : if (ret < 0)
975 : 0 : goto exit;
976 : :
977 : 0 : ret = rte_kvargs_process(kvlist,
978 : : bbdev_la12xx_valid_params[1],
979 : : &parse_integer_arg,
980 : 0 : ¶ms->modem_id);
981 : :
982 [ # # ]: 0 : if (params->modem_id >= LA12XX_MAX_MODEM) {
983 : 0 : rte_bbdev_log(ERR, "Invalid modem id, must be < %u",
984 : : LA12XX_MAX_MODEM);
985 : 0 : goto exit;
986 : : }
987 : : }
988 : :
989 : 0 : exit:
990 : 0 : rte_kvargs_free(kvlist);
991 : 0 : return ret;
992 : : }
993 : :
994 : : /* Create device */
995 : : static int
996 [ # # ]: 0 : la12xx_bbdev_create(struct rte_vdev_device *vdev,
997 : : struct bbdev_la12xx_params *init_params)
998 : : {
999 : : struct rte_bbdev *bbdev;
1000 : : const char *name = rte_vdev_device_name(vdev);
1001 : : struct bbdev_la12xx_private *priv;
1002 : : int ret;
1003 : :
1004 : : PMD_INIT_FUNC_TRACE();
1005 : :
1006 : 0 : bbdev = rte_bbdev_allocate(name);
1007 [ # # ]: 0 : if (bbdev == NULL)
1008 : : return -ENODEV;
1009 : :
1010 : 0 : bbdev->data->dev_private = rte_zmalloc(name,
1011 : : sizeof(struct bbdev_la12xx_private),
1012 : : RTE_CACHE_LINE_SIZE);
1013 [ # # ]: 0 : if (bbdev->data->dev_private == NULL) {
1014 : 0 : rte_bbdev_release(bbdev);
1015 : 0 : return -ENOMEM;
1016 : : }
1017 : :
1018 : : priv = bbdev->data->dev_private;
1019 : 0 : priv->modem_id = init_params->modem_id;
1020 : : /* if modem id is not configured */
1021 [ # # ]: 0 : if (priv->modem_id == -1)
1022 : 0 : priv->modem_id = bbdev->data->dev_id;
1023 : :
1024 : : /* Reset Global variables */
1025 : 0 : priv->num_ldpc_enc_queues = 0;
1026 : 0 : priv->num_ldpc_dec_queues = 0;
1027 : 0 : priv->num_valid_queues = 0;
1028 : 0 : priv->max_nb_queues = init_params->queues_num;
1029 : :
1030 : 0 : rte_bbdev_log(INFO, "Setting Up %s: DevId=%d, ModemId=%d",
1031 : : name, bbdev->data->dev_id, priv->modem_id);
1032 : 0 : ret = setup_la12xx_dev(bbdev);
1033 [ # # ]: 0 : if (ret) {
1034 : 0 : rte_bbdev_log(ERR, "IPC Setup failed for %s", name);
1035 : 0 : rte_free(bbdev->data->dev_private);
1036 : 0 : return ret;
1037 : : }
1038 : 0 : bbdev->dev_ops = &pmd_ops;
1039 : 0 : bbdev->device = &vdev->device;
1040 : 0 : bbdev->data->socket_id = 0;
1041 : 0 : bbdev->intr_handle = NULL;
1042 : :
1043 : : /* register rx/tx burst functions for data path */
1044 : 0 : bbdev->dequeue_enc_ops = NULL;
1045 : 0 : bbdev->dequeue_dec_ops = NULL;
1046 : 0 : bbdev->enqueue_enc_ops = NULL;
1047 : 0 : bbdev->enqueue_dec_ops = NULL;
1048 : 0 : bbdev->dequeue_ldpc_enc_ops = dequeue_enc_ops;
1049 : 0 : bbdev->dequeue_ldpc_dec_ops = dequeue_dec_ops;
1050 : 0 : bbdev->enqueue_ldpc_enc_ops = enqueue_enc_ops;
1051 : 0 : bbdev->enqueue_ldpc_dec_ops = enqueue_dec_ops;
1052 : :
1053 : 0 : return 0;
1054 : : }
1055 : :
1056 : : /* Initialise device */
1057 : : static int
1058 : 0 : la12xx_bbdev_probe(struct rte_vdev_device *vdev)
1059 : : {
1060 : 0 : struct bbdev_la12xx_params init_params = {
1061 : : 8, -1,
1062 : : };
1063 : : const char *name;
1064 : : const char *input_args;
1065 : :
1066 : : PMD_INIT_FUNC_TRACE();
1067 : :
1068 [ # # ]: 0 : if (vdev == NULL)
1069 : : return -EINVAL;
1070 : :
1071 : : name = rte_vdev_device_name(vdev);
1072 : : if (name == NULL)
1073 : : return -EINVAL;
1074 : :
1075 : : input_args = rte_vdev_device_args(vdev);
1076 : 0 : parse_bbdev_la12xx_params(&init_params, input_args);
1077 : :
1078 : 0 : return la12xx_bbdev_create(vdev, &init_params);
1079 : : }
1080 : :
1081 : : /* Uninitialise device */
1082 : : static int
1083 : 0 : la12xx_bbdev_remove(struct rte_vdev_device *vdev)
1084 : : {
1085 : : struct rte_bbdev *bbdev;
1086 : : const char *name;
1087 : :
1088 : : PMD_INIT_FUNC_TRACE();
1089 : :
1090 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1091 : : return 0;
1092 : :
1093 [ # # ]: 0 : if (vdev == NULL)
1094 : : return -EINVAL;
1095 : :
1096 : : name = rte_vdev_device_name(vdev);
1097 : : if (name == NULL)
1098 : : return -EINVAL;
1099 : :
1100 : 0 : bbdev = rte_bbdev_get_named_dev(name);
1101 [ # # ]: 0 : if (bbdev == NULL)
1102 : : return -EINVAL;
1103 : :
1104 : 0 : rte_free(bbdev->data->dev_private);
1105 : :
1106 : 0 : return rte_bbdev_release(bbdev);
1107 : : }
1108 : :
1109 : : static struct rte_vdev_driver bbdev_la12xx_pmd_drv = {
1110 : : .probe = la12xx_bbdev_probe,
1111 : : .remove = la12xx_bbdev_remove
1112 : : };
1113 : :
1114 : 251 : RTE_PMD_REGISTER_VDEV(DRIVER_NAME, bbdev_la12xx_pmd_drv);
1115 : : RTE_PMD_REGISTER_PARAM_STRING(DRIVER_NAME,
1116 : : LA12XX_MAX_NB_QUEUES_ARG"=<int>"
1117 : : LA12XX_VDEV_MODEM_ID_ARG "=<int> ");
1118 [ - + ]: 251 : RTE_LOG_REGISTER_DEFAULT(bbdev_la12xx_logtype, NOTICE);
|