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

Generated by: LCOV version 1.14