LCOV - code coverage report
Current view: top level - drivers/baseband/la12xx - bbdev_la12xx.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 2 452 0.4 %
Date: 2025-01-02 22:41:34 Functions: 2 25 8.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1 181 0.6 %

           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, &params->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 :                                         &params->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);

Generated by: LCOV version 1.14