1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2020-2021 NXP
12 #include <rte_common.h>
13 #include <rte_bus_vdev.h>
14 #include <rte_malloc.h>
16 #include <rte_kvargs.h>
18 #include <rte_bbdev.h>
19 #include <rte_bbdev_pmd.h>
21 #include <bbdev_la12xx_pmd_logs.h>
22 #include <bbdev_la12xx_ipc.h>
23 #include <bbdev_la12xx.h>
25 #define DRIVER_NAME baseband_la12xx
27 /* Initialisation params structure that can be used by LA12xx BBDEV driver */
28 struct bbdev_la12xx_params {
29 uint8_t queues_num; /*< LA12xx BBDEV queues number */
30 int8_t modem_id; /*< LA12xx modem instance id */
33 #define LA12XX_MAX_NB_QUEUES_ARG "max_nb_queues"
34 #define LA12XX_VDEV_MODEM_ID_ARG "modem"
35 #define LA12XX_MAX_MODEM 4
37 #define LA12XX_MAX_CORES 4
38 #define LA12XX_LDPC_ENC_CORE 0
39 #define LA12XX_LDPC_DEC_CORE 1
41 #define LA12XX_MAX_LDPC_ENC_QUEUES 4
42 #define LA12XX_MAX_LDPC_DEC_QUEUES 4
44 static const char * const bbdev_la12xx_valid_params[] = {
45 LA12XX_MAX_NB_QUEUES_ARG,
46 LA12XX_VDEV_MODEM_ID_ARG,
49 static const struct rte_bbdev_op_cap bbdev_capabilities[] = {
51 .type = RTE_BBDEV_OP_LDPC_ENC,
54 RTE_BBDEV_LDPC_RATE_MATCH |
55 RTE_BBDEV_LDPC_CRC_24A_ATTACH |
56 RTE_BBDEV_LDPC_CRC_24B_ATTACH,
58 RTE_BBDEV_LDPC_MAX_CODE_BLOCKS,
60 RTE_BBDEV_LDPC_MAX_CODE_BLOCKS,
64 .type = RTE_BBDEV_OP_LDPC_DEC,
67 RTE_BBDEV_LDPC_CRC_TYPE_24A_CHECK |
68 RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK |
69 RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP,
71 RTE_BBDEV_LDPC_MAX_CODE_BLOCKS,
72 .num_buffers_hard_out =
73 RTE_BBDEV_LDPC_MAX_CODE_BLOCKS,
78 RTE_BBDEV_END_OF_CAPABILITIES_LIST()
81 static struct rte_bbdev_queue_conf default_queue_conf = {
82 .queue_size = MAX_CHANNEL_DEPTH,
87 la12xx_info_get(struct rte_bbdev *dev __rte_unused,
88 struct rte_bbdev_driver_info *dev_info)
90 PMD_INIT_FUNC_TRACE();
92 dev_info->driver_name = RTE_STR(DRIVER_NAME);
93 dev_info->max_num_queues = LA12XX_MAX_QUEUES;
94 dev_info->queue_size_lim = MAX_CHANNEL_DEPTH;
95 dev_info->hardware_accelerated = true;
96 dev_info->max_dl_queue_priority = 0;
97 dev_info->max_ul_queue_priority = 0;
98 dev_info->data_endianness = RTE_BIG_ENDIAN;
99 dev_info->default_queue_conf = default_queue_conf;
100 dev_info->capabilities = bbdev_capabilities;
101 dev_info->cpu_flag_reqs = NULL;
102 dev_info->min_alignment = 64;
104 rte_bbdev_log_debug("got device info from %u", dev->data->dev_id);
109 la12xx_queue_release(struct rte_bbdev *dev, uint16_t q_id)
114 PMD_INIT_FUNC_TRACE();
119 #define HUGEPG_OFFSET(A) \
120 ((uint64_t) ((unsigned long) (A) \
121 - ((uint64_t)ipc_priv->hugepg_start.host_vaddr)))
123 #define MODEM_P2V(A) \
124 ((uint64_t) ((unsigned long) (A) \
125 + (unsigned long)(ipc_priv->peb_start.host_vaddr)))
128 ipc_queue_configure(uint32_t channel_id,
130 struct bbdev_la12xx_q_priv *q_priv)
132 ipc_userspace_t *ipc_priv = (ipc_userspace_t *)instance;
133 ipc_instance_t *ipc_instance = ipc_priv->instance;
137 uint32_t msg_size = sizeof(struct bbdev_ipc_enqueue_op);
139 PMD_INIT_FUNC_TRACE();
141 rte_bbdev_log_debug("%x %p", ipc_instance->initialized,
143 ch = &(ipc_instance->ch_list[channel_id]);
145 rte_bbdev_log_debug("channel: %u, depth: %u, msg size: %u",
146 channel_id, q_priv->queue_size, msg_size);
148 /* Start init of channel */
149 ch->md.ring_size = rte_cpu_to_be_32(q_priv->queue_size);
152 ch->md.msg_size = msg_size;
153 for (i = 0; i < q_priv->queue_size; i++) {
154 vaddr = rte_malloc(NULL, msg_size, RTE_CACHE_LINE_SIZE);
156 return IPC_HOST_BUF_ALLOC_FAIL;
157 /* Only offset now */
158 ch->bd_h[i].modem_ptr =
159 rte_cpu_to_be_32(HUGEPG_OFFSET(vaddr));
160 ch->bd_h[i].host_virt_l = lower_32_bits(vaddr);
161 ch->bd_h[i].host_virt_h = upper_32_bits(vaddr);
162 q_priv->msg_ch_vaddr[i] = vaddr;
163 /* Not sure use of this len may be for CRC*/
166 ch->host_ipc_params =
167 rte_cpu_to_be_32(HUGEPG_OFFSET(q_priv->host_params));
169 rte_bbdev_log_debug("Channel configured");
174 la12xx_e200_queue_setup(struct rte_bbdev *dev,
175 struct bbdev_la12xx_q_priv *q_priv)
177 struct bbdev_la12xx_private *priv = dev->data->dev_private;
178 ipc_userspace_t *ipc_priv = priv->ipc_priv;
179 struct gul_hif *mhif;
180 ipc_metadata_t *ipc_md;
182 int instance_id = 0, i;
185 PMD_INIT_FUNC_TRACE();
187 switch (q_priv->op_type) {
188 case RTE_BBDEV_OP_LDPC_ENC:
189 q_priv->la12xx_core_id = LA12XX_LDPC_ENC_CORE;
191 case RTE_BBDEV_OP_LDPC_DEC:
192 q_priv->la12xx_core_id = LA12XX_LDPC_DEC_CORE;
195 rte_bbdev_log(ERR, "Unsupported op type\n");
199 mhif = (struct gul_hif *)ipc_priv->mhif_start.host_vaddr;
200 /* offset is from start of PEB */
201 ipc_md = (ipc_metadata_t *)((uintptr_t)ipc_priv->peb_start.host_vaddr +
202 mhif->ipc_regs.ipc_mdata_offset);
203 ch = &ipc_md->instance_list[instance_id].ch_list[q_priv->q_id];
205 if (q_priv->q_id < priv->num_valid_queues) {
206 ipc_br_md_t *md = &(ch->md);
208 q_priv->feca_blk_id = rte_cpu_to_be_32(ch->feca_blk_id);
209 q_priv->feca_blk_id_be32 = ch->feca_blk_id;
210 q_priv->host_pi = rte_be_to_cpu_32(md->pi);
211 q_priv->host_ci = rte_be_to_cpu_32(md->ci);
212 q_priv->host_params = (host_ipc_params_t *)(uintptr_t)
213 (rte_be_to_cpu_32(ch->host_ipc_params) +
214 ((uint64_t)ipc_priv->hugepg_start.host_vaddr));
216 for (i = 0; i < q_priv->queue_size; i++) {
219 h = ch->bd_h[i].host_virt_h;
220 l = ch->bd_h[i].host_virt_l;
221 q_priv->msg_ch_vaddr[i] = (void *)join_32_bits(h, l);
224 rte_bbdev_log(WARNING,
225 "Queue [%d] already configured, not configuring again",
230 rte_bbdev_log_debug("setting up queue %d", q_priv->q_id);
232 /* Call ipc_configure_channel */
233 ret = ipc_queue_configure(q_priv->q_id, ipc_priv, q_priv);
235 rte_bbdev_log(ERR, "Unable to setup queue (%d) (err=%d)",
240 /* Set queue properties for LA12xx device */
241 switch (q_priv->op_type) {
242 case RTE_BBDEV_OP_LDPC_ENC:
243 if (priv->num_ldpc_enc_queues >= LA12XX_MAX_LDPC_ENC_QUEUES) {
245 "num_ldpc_enc_queues reached max value");
249 rte_cpu_to_be_32(LA12XX_LDPC_ENC_CORE);
250 ch->feca_blk_id = rte_cpu_to_be_32(priv->num_ldpc_enc_queues++);
252 case RTE_BBDEV_OP_LDPC_DEC:
253 if (priv->num_ldpc_dec_queues >= LA12XX_MAX_LDPC_DEC_QUEUES) {
255 "num_ldpc_dec_queues reached max value");
259 rte_cpu_to_be_32(LA12XX_LDPC_DEC_CORE);
260 ch->feca_blk_id = rte_cpu_to_be_32(priv->num_ldpc_dec_queues++);
263 rte_bbdev_log(ERR, "Not supported op type\n");
266 ch->op_type = rte_cpu_to_be_32(q_priv->op_type);
267 ch->depth = rte_cpu_to_be_32(q_priv->queue_size);
269 /* Store queue config here */
270 q_priv->feca_blk_id = rte_cpu_to_be_32(ch->feca_blk_id);
271 q_priv->feca_blk_id_be32 = ch->feca_blk_id;
278 la12xx_queue_setup(struct rte_bbdev *dev, uint16_t q_id,
279 const struct rte_bbdev_queue_conf *queue_conf)
281 struct bbdev_la12xx_private *priv = dev->data->dev_private;
282 struct rte_bbdev_queue_data *q_data;
283 struct bbdev_la12xx_q_priv *q_priv;
286 PMD_INIT_FUNC_TRACE();
288 /* Move to setup_queues callback */
289 q_data = &dev->data->queues[q_id];
290 q_data->queue_private = rte_zmalloc(NULL,
291 sizeof(struct bbdev_la12xx_q_priv), 0);
292 if (!q_data->queue_private) {
293 rte_bbdev_log(ERR, "Memory allocation failed for qpriv");
296 q_priv = q_data->queue_private;
298 q_priv->bbdev_priv = dev->data->dev_private;
299 q_priv->queue_size = queue_conf->queue_size;
300 q_priv->op_type = queue_conf->op_type;
302 ret = la12xx_e200_queue_setup(dev, q_priv);
304 rte_bbdev_log(ERR, "e200_queue_setup failed for qid: %d",
309 /* Store queue config here */
310 priv->num_valid_queues++;
316 la12xx_start(struct rte_bbdev *dev)
318 struct bbdev_la12xx_private *priv = dev->data->dev_private;
319 ipc_userspace_t *ipc_priv = priv->ipc_priv;
321 struct gul_hif *hif_start;
323 PMD_INIT_FUNC_TRACE();
325 hif_start = (struct gul_hif *)ipc_priv->mhif_start.host_vaddr;
327 /* Set Host Read bit */
328 SET_HIF_HOST_RDY(hif_start, HIF_HOST_READY_IPC_APP);
330 /* Now wait for modem ready bit */
332 ready = CHK_HIF_MOD_RDY(hif_start, HIF_MOD_READY_IPC_APP);
337 static const struct rte_bbdev_ops pmd_ops = {
338 .info_get = la12xx_info_get,
339 .queue_setup = la12xx_queue_setup,
340 .queue_release = la12xx_queue_release,
341 .start = la12xx_start
345 is_bd_ring_full(uint32_t ci, uint32_t ci_flag,
346 uint32_t pi, uint32_t pi_flag)
349 if (pi_flag != ci_flag)
350 return 1; /* Ring is Full */
356 prepare_ldpc_enc_op(struct rte_bbdev_enc_op *bbdev_enc_op,
357 struct bbdev_la12xx_q_priv *q_priv __rte_unused,
358 struct rte_bbdev_op_data *in_op_data __rte_unused,
359 struct rte_bbdev_op_data *out_op_data)
361 struct rte_bbdev_op_ldpc_enc *ldpc_enc = &bbdev_enc_op->ldpc_enc;
362 uint32_t total_out_bits;
364 total_out_bits = (ldpc_enc->tb_params.cab *
365 ldpc_enc->tb_params.ea) + (ldpc_enc->tb_params.c -
366 ldpc_enc->tb_params.cab) * ldpc_enc->tb_params.eb;
368 ldpc_enc->output.length = (total_out_bits + 7)/8;
370 rte_pktmbuf_append(out_op_data->data, ldpc_enc->output.length);
376 prepare_ldpc_dec_op(struct rte_bbdev_dec_op *bbdev_dec_op,
377 struct bbdev_ipc_dequeue_op *bbdev_ipc_op,
378 struct bbdev_la12xx_q_priv *q_priv __rte_unused,
379 struct rte_bbdev_op_data *out_op_data __rte_unused)
381 struct rte_bbdev_op_ldpc_dec *ldpc_dec = &bbdev_dec_op->ldpc_dec;
382 uint32_t total_out_bits;
383 uint32_t num_code_blocks = 0;
386 sys_cols = (ldpc_dec->basegraph == 1) ? 22 : 10;
387 if (ldpc_dec->tb_params.c == 1) {
388 total_out_bits = ((sys_cols * ldpc_dec->z_c) -
390 /* 5G-NR protocol uses 16 bit CRC when output packet
391 * size <= 3824 (bits). Otherwise 24 bit CRC is used.
392 * Adjust the output bits accordingly
394 if (total_out_bits - 16 <= 3824)
395 total_out_bits -= 16;
397 total_out_bits -= 24;
398 ldpc_dec->hard_output.length = (total_out_bits / 8);
400 total_out_bits = (((sys_cols * ldpc_dec->z_c) -
401 ldpc_dec->n_filler - 24) *
402 ldpc_dec->tb_params.c);
403 ldpc_dec->hard_output.length = (total_out_bits / 8) - 3;
406 num_code_blocks = ldpc_dec->tb_params.c;
408 bbdev_ipc_op->num_code_blocks = rte_cpu_to_be_32(num_code_blocks);
414 enqueue_single_op(struct bbdev_la12xx_q_priv *q_priv, void *bbdev_op)
416 struct bbdev_la12xx_private *priv = q_priv->bbdev_priv;
417 ipc_userspace_t *ipc_priv = priv->ipc_priv;
418 ipc_instance_t *ipc_instance = ipc_priv->instance;
419 struct bbdev_ipc_dequeue_op *bbdev_ipc_op;
420 struct rte_bbdev_op_ldpc_enc *ldpc_enc;
421 struct rte_bbdev_op_ldpc_dec *ldpc_dec;
422 uint32_t q_id = q_priv->q_id;
423 uint32_t ci, ci_flag, pi, pi_flag;
424 ipc_ch_t *ch = &(ipc_instance->ch_list[q_id]);
425 ipc_br_md_t *md = &(ch->md);
427 char *huge_start_addr =
428 (char *)q_priv->bbdev_priv->ipc_priv->hugepg_start.host_vaddr;
429 struct rte_bbdev_op_data *in_op_data, *out_op_data;
431 uint32_t l1_pcie_addr;
434 ci = IPC_GET_CI_INDEX(q_priv->host_ci);
435 ci_flag = IPC_GET_CI_FLAG(q_priv->host_ci);
437 pi = IPC_GET_PI_INDEX(q_priv->host_pi);
438 pi_flag = IPC_GET_PI_FLAG(q_priv->host_pi);
440 rte_bbdev_dp_log(DEBUG, "before bd_ring_full: pi: %u, ci: %u,"
441 "pi_flag: %u, ci_flag: %u, ring size: %u",
442 pi, ci, pi_flag, ci_flag, q_priv->queue_size);
444 if (is_bd_ring_full(ci, ci_flag, pi, pi_flag)) {
445 rte_bbdev_dp_log(DEBUG, "bd ring full for queue id: %d", q_id);
449 virt = MODEM_P2V(q_priv->host_params->bd_m_modem_ptr[pi]);
450 bbdev_ipc_op = (struct bbdev_ipc_dequeue_op *)virt;
451 q_priv->bbdev_op[pi] = bbdev_op;
453 switch (q_priv->op_type) {
454 case RTE_BBDEV_OP_LDPC_ENC:
455 ldpc_enc = &(((struct rte_bbdev_enc_op *)bbdev_op)->ldpc_enc);
456 in_op_data = &ldpc_enc->input;
457 out_op_data = &ldpc_enc->output;
459 ret = prepare_ldpc_enc_op(bbdev_op, q_priv,
460 in_op_data, out_op_data);
462 rte_bbdev_log(ERR, "process_ldpc_enc_op fail, ret: %d",
468 case RTE_BBDEV_OP_LDPC_DEC:
469 ldpc_dec = &(((struct rte_bbdev_dec_op *)bbdev_op)->ldpc_dec);
470 in_op_data = &ldpc_dec->input;
472 out_op_data = &ldpc_dec->hard_output;
474 ret = prepare_ldpc_dec_op(bbdev_op, bbdev_ipc_op,
475 q_priv, out_op_data);
477 rte_bbdev_log(ERR, "process_ldpc_dec_op fail, ret: %d",
484 rte_bbdev_log(ERR, "unsupported bbdev_ipc op type");
488 if (in_op_data->data) {
489 data_ptr = rte_pktmbuf_mtod(in_op_data->data, char *);
490 l1_pcie_addr = (uint32_t)GUL_USER_HUGE_PAGE_ADDR +
491 data_ptr - huge_start_addr;
492 bbdev_ipc_op->in_addr = l1_pcie_addr;
493 bbdev_ipc_op->in_len = in_op_data->length;
496 if (out_op_data->data) {
497 data_ptr = rte_pktmbuf_mtod(out_op_data->data, char *);
498 l1_pcie_addr = (uint32_t)GUL_USER_HUGE_PAGE_ADDR +
499 data_ptr - huge_start_addr;
500 bbdev_ipc_op->out_addr = rte_cpu_to_be_32(l1_pcie_addr);
501 bbdev_ipc_op->out_len = rte_cpu_to_be_32(out_op_data->length);
504 /* Move Producer Index forward */
506 /* Flip the PI flag, if wrapping */
507 if (unlikely(q_priv->queue_size == pi)) {
509 pi_flag = pi_flag ? 0 : 1;
515 IPC_RESET_PI_FLAG(pi);
516 q_priv->host_pi = pi;
518 /* Wait for Data Copy & pi_flag update to complete before updating pi */
521 md->pi = rte_cpu_to_be_32(pi);
523 rte_bbdev_dp_log(DEBUG, "enter: pi: %u, ci: %u,"
524 "pi_flag: %u, ci_flag: %u, ring size: %u",
525 pi, ci, pi_flag, ci_flag, q_priv->queue_size);
530 /* Enqueue decode burst */
532 enqueue_dec_ops(struct rte_bbdev_queue_data *q_data,
533 struct rte_bbdev_dec_op **ops, uint16_t nb_ops)
535 struct bbdev_la12xx_q_priv *q_priv = q_data->queue_private;
536 int nb_enqueued, ret;
538 for (nb_enqueued = 0; nb_enqueued < nb_ops; nb_enqueued++) {
539 ret = enqueue_single_op(q_priv, ops[nb_enqueued]);
544 q_data->queue_stats.enqueue_err_count += nb_ops - nb_enqueued;
545 q_data->queue_stats.enqueued_count += nb_enqueued;
550 /* Enqueue encode burst */
552 enqueue_enc_ops(struct rte_bbdev_queue_data *q_data,
553 struct rte_bbdev_enc_op **ops, uint16_t nb_ops)
555 struct bbdev_la12xx_q_priv *q_priv = q_data->queue_private;
556 int nb_enqueued, ret;
558 for (nb_enqueued = 0; nb_enqueued < nb_ops; nb_enqueued++) {
559 ret = enqueue_single_op(q_priv, ops[nb_enqueued]);
564 q_data->queue_stats.enqueue_err_count += nb_ops - nb_enqueued;
565 q_data->queue_stats.enqueued_count += nb_enqueued;
570 /* Dequeue encode burst */
572 dequeue_single_op(struct bbdev_la12xx_q_priv *q_priv, void *dst)
575 uint32_t ci, ci_flag;
578 temp_ci = q_priv->host_params->ci;
579 if (temp_ci == q_priv->host_ci)
582 ci = IPC_GET_CI_INDEX(q_priv->host_ci);
583 ci_flag = IPC_GET_CI_FLAG(q_priv->host_ci);
585 rte_bbdev_dp_log(DEBUG,
586 "ci: %u, ci_flag: %u, ring size: %u",
587 ci, ci_flag, q_priv->queue_size);
589 op = q_priv->bbdev_op[ci];
591 rte_memcpy(dst, q_priv->msg_ch_vaddr[ci],
592 sizeof(struct bbdev_ipc_enqueue_op));
594 /* Move Consumer Index forward */
596 /* Flip the CI flag, if wrapping */
597 if (q_priv->queue_size == ci) {
599 ci_flag = ci_flag ? 0 : 1;
604 IPC_RESET_CI_FLAG(ci);
606 q_priv->host_ci = ci;
608 rte_bbdev_dp_log(DEBUG,
609 "exit: ci: %u, ci_flag: %u, ring size: %u",
610 ci, ci_flag, q_priv->queue_size);
615 /* Dequeue decode burst */
617 dequeue_dec_ops(struct rte_bbdev_queue_data *q_data,
618 struct rte_bbdev_dec_op **ops, uint16_t nb_ops)
620 struct bbdev_la12xx_q_priv *q_priv = q_data->queue_private;
621 struct bbdev_ipc_enqueue_op bbdev_ipc_op;
624 for (nb_dequeued = 0; nb_dequeued < nb_ops; nb_dequeued++) {
625 ops[nb_dequeued] = dequeue_single_op(q_priv, &bbdev_ipc_op);
626 if (!ops[nb_dequeued])
628 ops[nb_dequeued]->status = bbdev_ipc_op.status;
630 q_data->queue_stats.dequeued_count += nb_dequeued;
635 /* Dequeue encode burst */
637 dequeue_enc_ops(struct rte_bbdev_queue_data *q_data,
638 struct rte_bbdev_enc_op **ops, uint16_t nb_ops)
640 struct bbdev_la12xx_q_priv *q_priv = q_data->queue_private;
641 struct bbdev_ipc_enqueue_op bbdev_ipc_op;
644 for (nb_enqueued = 0; nb_enqueued < nb_ops; nb_enqueued++) {
645 ops[nb_enqueued] = dequeue_single_op(q_priv, &bbdev_ipc_op);
646 if (!ops[nb_enqueued])
648 ops[nb_enqueued]->status = bbdev_ipc_op.status;
650 q_data->queue_stats.enqueued_count += nb_enqueued;
655 static struct hugepage_info *
656 get_hugepage_info(void)
658 struct hugepage_info *hp_info;
659 struct rte_memseg *mseg;
661 PMD_INIT_FUNC_TRACE();
663 /* TODO - find a better way */
664 hp_info = rte_malloc(NULL, sizeof(struct hugepage_info), 0);
666 rte_bbdev_log(ERR, "Unable to allocate on local heap");
670 mseg = rte_mem_virt2memseg(hp_info, NULL);
671 hp_info->vaddr = mseg->addr;
672 hp_info->paddr = rte_mem_virt2phy(mseg->addr);
673 hp_info->len = mseg->len;
679 open_ipc_dev(int modem_id)
681 char dev_initials[16], dev_path[PATH_MAX];
682 struct dirent *entry;
686 dir = opendir("/dev/");
688 rte_bbdev_log(ERR, "Unable to open /dev/");
692 sprintf(dev_initials, "gulipcgul%d", modem_id);
694 while ((entry = readdir(dir)) != NULL) {
695 if (!strncmp(dev_initials, entry->d_name,
696 sizeof(dev_initials) - 1))
701 rte_bbdev_log(ERR, "Error: No gulipcgul%d device", modem_id);
705 sprintf(dev_path, "/dev/%s", entry->d_name);
706 dev_ipc = open(dev_path, O_RDWR);
708 rte_bbdev_log(ERR, "Error: Cannot open %s", dev_path);
716 setup_la12xx_dev(struct rte_bbdev *dev)
718 struct bbdev_la12xx_private *priv = dev->data->dev_private;
719 ipc_userspace_t *ipc_priv = priv->ipc_priv;
720 struct hugepage_info *hp = NULL;
721 ipc_channel_us_t *ipc_priv_ch = NULL;
722 int dev_ipc = 0, dev_mem = 0, i;
723 ipc_metadata_t *ipc_md;
724 struct gul_hif *mhif;
725 uint32_t phy_align = 0;
728 PMD_INIT_FUNC_TRACE();
731 /* TODO - get a better way */
732 /* Get the hugepage info against it */
733 hp = get_hugepage_info();
735 rte_bbdev_log(ERR, "Unable to get hugepage info");
740 rte_bbdev_log_debug("0x%" PRIx64 " %p 0x%" PRIx64,
741 hp->paddr, hp->vaddr, hp->len);
743 ipc_priv = rte_zmalloc(0, sizeof(ipc_userspace_t), 0);
744 if (ipc_priv == NULL) {
746 "Unable to allocate memory for ipc priv");
751 for (i = 0; i < IPC_MAX_CHANNEL_COUNT; i++) {
752 ipc_priv_ch = rte_zmalloc(0,
753 sizeof(ipc_channel_us_t), 0);
754 if (ipc_priv_ch == NULL) {
756 "Unable to allocate memory for channels");
759 ipc_priv->channels[i] = ipc_priv_ch;
762 dev_mem = open("/dev/mem", O_RDWR);
764 rte_bbdev_log(ERR, "Error: Cannot open /dev/mem");
769 ipc_priv->instance_id = 0;
770 ipc_priv->dev_mem = dev_mem;
772 rte_bbdev_log_debug("hugepg input 0x%" PRIx64 "%p 0x%" PRIx64,
773 hp->paddr, hp->vaddr, hp->len);
775 ipc_priv->sys_map.hugepg_start.host_phys = hp->paddr;
776 ipc_priv->sys_map.hugepg_start.size = hp->len;
778 ipc_priv->hugepg_start.host_phys = hp->paddr;
779 ipc_priv->hugepg_start.host_vaddr = hp->vaddr;
780 ipc_priv->hugepg_start.size = hp->len;
785 dev_ipc = open_ipc_dev(priv->modem_id);
787 rte_bbdev_log(ERR, "Error: open_ipc_dev failed");
790 ipc_priv->dev_ipc = dev_ipc;
792 ret = ioctl(ipc_priv->dev_ipc, IOCTL_GUL_IPC_GET_SYS_MAP,
796 "IOCTL_GUL_IPC_GET_SYS_MAP ioctl failed");
800 phy_align = (ipc_priv->sys_map.mhif_start.host_phys % 0x1000);
801 ipc_priv->mhif_start.host_vaddr =
802 mmap(0, ipc_priv->sys_map.mhif_start.size + phy_align,
803 (PROT_READ | PROT_WRITE), MAP_SHARED, ipc_priv->dev_mem,
804 (ipc_priv->sys_map.mhif_start.host_phys - phy_align));
805 if (ipc_priv->mhif_start.host_vaddr == MAP_FAILED) {
806 rte_bbdev_log(ERR, "MAP failed:");
811 ipc_priv->mhif_start.host_vaddr = (void *) ((uintptr_t)
812 (ipc_priv->mhif_start.host_vaddr) + phy_align);
814 phy_align = (ipc_priv->sys_map.peb_start.host_phys % 0x1000);
815 ipc_priv->peb_start.host_vaddr =
816 mmap(0, ipc_priv->sys_map.peb_start.size + phy_align,
817 (PROT_READ | PROT_WRITE), MAP_SHARED, ipc_priv->dev_mem,
818 (ipc_priv->sys_map.peb_start.host_phys - phy_align));
819 if (ipc_priv->peb_start.host_vaddr == MAP_FAILED) {
820 rte_bbdev_log(ERR, "MAP failed:");
825 ipc_priv->peb_start.host_vaddr = (void *)((uintptr_t)
826 (ipc_priv->peb_start.host_vaddr) + phy_align);
828 phy_align = (ipc_priv->sys_map.modem_ccsrbar.host_phys % 0x1000);
829 ipc_priv->modem_ccsrbar.host_vaddr =
830 mmap(0, ipc_priv->sys_map.modem_ccsrbar.size + phy_align,
831 (PROT_READ | PROT_WRITE), MAP_SHARED, ipc_priv->dev_mem,
832 (ipc_priv->sys_map.modem_ccsrbar.host_phys - phy_align));
833 if (ipc_priv->modem_ccsrbar.host_vaddr == MAP_FAILED) {
834 rte_bbdev_log(ERR, "MAP failed:");
839 ipc_priv->modem_ccsrbar.host_vaddr = (void *)((uintptr_t)
840 (ipc_priv->modem_ccsrbar.host_vaddr) + phy_align);
842 ipc_priv->hugepg_start.modem_phys =
843 ipc_priv->sys_map.hugepg_start.modem_phys;
845 ipc_priv->mhif_start.host_phys =
846 ipc_priv->sys_map.mhif_start.host_phys;
847 ipc_priv->mhif_start.size = ipc_priv->sys_map.mhif_start.size;
848 ipc_priv->peb_start.host_phys = ipc_priv->sys_map.peb_start.host_phys;
849 ipc_priv->peb_start.size = ipc_priv->sys_map.peb_start.size;
851 rte_bbdev_log(INFO, "peb 0x%" PRIx64 "%p 0x%" PRIx32,
852 ipc_priv->peb_start.host_phys,
853 ipc_priv->peb_start.host_vaddr,
854 ipc_priv->peb_start.size);
855 rte_bbdev_log(INFO, "hugepg 0x%" PRIx64 "%p 0x%" PRIx32,
856 ipc_priv->hugepg_start.host_phys,
857 ipc_priv->hugepg_start.host_vaddr,
858 ipc_priv->hugepg_start.size);
859 rte_bbdev_log(INFO, "mhif 0x%" PRIx64 "%p 0x%" PRIx32,
860 ipc_priv->mhif_start.host_phys,
861 ipc_priv->mhif_start.host_vaddr,
862 ipc_priv->mhif_start.size);
863 mhif = (struct gul_hif *)ipc_priv->mhif_start.host_vaddr;
865 /* offset is from start of PEB */
866 ipc_md = (ipc_metadata_t *)((uintptr_t)ipc_priv->peb_start.host_vaddr +
867 mhif->ipc_regs.ipc_mdata_offset);
869 if (sizeof(ipc_metadata_t) != mhif->ipc_regs.ipc_mdata_size) {
871 "ipc_metadata_t =0x%" PRIx64
872 ", mhif->ipc_regs.ipc_mdata_size=0x%" PRIx32,
873 (uint64_t)(sizeof(ipc_metadata_t)),
874 mhif->ipc_regs.ipc_mdata_size);
875 rte_bbdev_log(ERR, "--> mhif->ipc_regs.ipc_mdata_offset= 0x%"
876 PRIx32, mhif->ipc_regs.ipc_mdata_offset);
877 rte_bbdev_log(ERR, "gul_hif size=0x%" PRIx64,
878 (uint64_t)(sizeof(struct gul_hif)));
879 return IPC_MD_SZ_MISS_MATCH;
882 ipc_priv->instance = (ipc_instance_t *)
883 (&ipc_md->instance_list[ipc_priv->instance_id]);
885 rte_bbdev_log_debug("finish host init");
887 priv->ipc_priv = ipc_priv;
894 rte_free(ipc_priv_ch);
904 parse_u16_arg(const char *key, const char *value, void *extra_args)
906 uint16_t *u16 = extra_args;
909 if ((value == NULL) || (extra_args == NULL))
912 result = strtoul(value, NULL, 0);
913 if ((result >= (1 << 16)) || (errno != 0)) {
914 rte_bbdev_log(ERR, "Invalid value %" PRIu64 " for %s",
918 *u16 = (uint16_t)result;
922 /* Parse integer from integer argument */
924 parse_integer_arg(const char *key __rte_unused,
925 const char *value, void *extra_args)
932 i = strtol(value, &end, 10);
933 if (*end != 0 || errno != 0 || i < 0 || i > LA12XX_MAX_MODEM) {
934 rte_bbdev_log(ERR, "Supported Port IDS are 0 to %d",
935 LA12XX_MAX_MODEM - 1);
939 *((uint32_t *)extra_args) = i;
944 /* Parse parameters used to create device */
946 parse_bbdev_la12xx_params(struct bbdev_la12xx_params *params,
947 const char *input_args)
949 struct rte_kvargs *kvlist = NULL;
955 kvlist = rte_kvargs_parse(input_args,
956 bbdev_la12xx_valid_params);
960 ret = rte_kvargs_process(kvlist, bbdev_la12xx_valid_params[0],
961 &parse_u16_arg, ¶ms->queues_num);
965 ret = rte_kvargs_process(kvlist,
966 bbdev_la12xx_valid_params[1],
970 if (params->modem_id >= LA12XX_MAX_MODEM) {
971 rte_bbdev_log(ERR, "Invalid modem id, must be < %u",
978 rte_kvargs_free(kvlist);
984 la12xx_bbdev_create(struct rte_vdev_device *vdev,
985 struct bbdev_la12xx_params *init_params)
987 struct rte_bbdev *bbdev;
988 const char *name = rte_vdev_device_name(vdev);
989 struct bbdev_la12xx_private *priv;
992 PMD_INIT_FUNC_TRACE();
994 bbdev = rte_bbdev_allocate(name);
998 bbdev->data->dev_private = rte_zmalloc(name,
999 sizeof(struct bbdev_la12xx_private),
1000 RTE_CACHE_LINE_SIZE);
1001 if (bbdev->data->dev_private == NULL) {
1002 rte_bbdev_release(bbdev);
1006 priv = bbdev->data->dev_private;
1007 priv->modem_id = init_params->modem_id;
1008 /* if modem id is not configured */
1009 if (priv->modem_id == -1)
1010 priv->modem_id = bbdev->data->dev_id;
1012 /* Reset Global variables */
1013 priv->num_ldpc_enc_queues = 0;
1014 priv->num_ldpc_dec_queues = 0;
1015 priv->num_valid_queues = 0;
1016 priv->max_nb_queues = init_params->queues_num;
1018 rte_bbdev_log(INFO, "Setting Up %s: DevId=%d, ModemId=%d",
1019 name, bbdev->data->dev_id, priv->modem_id);
1020 ret = setup_la12xx_dev(bbdev);
1022 rte_bbdev_log(ERR, "IPC Setup failed for %s", name);
1023 rte_free(bbdev->data->dev_private);
1026 bbdev->dev_ops = &pmd_ops;
1027 bbdev->device = &vdev->device;
1028 bbdev->data->socket_id = 0;
1029 bbdev->intr_handle = NULL;
1031 /* register rx/tx burst functions for data path */
1032 bbdev->dequeue_enc_ops = NULL;
1033 bbdev->dequeue_dec_ops = NULL;
1034 bbdev->enqueue_enc_ops = NULL;
1035 bbdev->enqueue_dec_ops = NULL;
1036 bbdev->dequeue_ldpc_enc_ops = dequeue_enc_ops;
1037 bbdev->dequeue_ldpc_dec_ops = dequeue_dec_ops;
1038 bbdev->enqueue_ldpc_enc_ops = enqueue_enc_ops;
1039 bbdev->enqueue_ldpc_dec_ops = enqueue_dec_ops;
1044 /* Initialise device */
1046 la12xx_bbdev_probe(struct rte_vdev_device *vdev)
1048 struct bbdev_la12xx_params init_params = {
1052 const char *input_args;
1054 PMD_INIT_FUNC_TRACE();
1059 name = rte_vdev_device_name(vdev);
1063 input_args = rte_vdev_device_args(vdev);
1064 parse_bbdev_la12xx_params(&init_params, input_args);
1066 return la12xx_bbdev_create(vdev, &init_params);
1069 /* Uninitialise device */
1071 la12xx_bbdev_remove(struct rte_vdev_device *vdev)
1073 struct rte_bbdev *bbdev;
1076 PMD_INIT_FUNC_TRACE();
1081 name = rte_vdev_device_name(vdev);
1085 bbdev = rte_bbdev_get_named_dev(name);
1089 rte_free(bbdev->data->dev_private);
1091 return rte_bbdev_release(bbdev);
1094 static struct rte_vdev_driver bbdev_la12xx_pmd_drv = {
1095 .probe = la12xx_bbdev_probe,
1096 .remove = la12xx_bbdev_remove
1099 RTE_PMD_REGISTER_VDEV(DRIVER_NAME, bbdev_la12xx_pmd_drv);
1100 RTE_PMD_REGISTER_PARAM_STRING(DRIVER_NAME,
1101 LA12XX_MAX_NB_QUEUES_ARG"=<int>"
1102 LA12XX_VDEV_MODEM_ID_ARG "=<int> ");
1103 RTE_LOG_REGISTER_DEFAULT(bbdev_la12xx_logtype, NOTICE);