LCOV - code coverage report
Current view: top level - drivers/baseband/acc - acc_common.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 358 0.0 %
Date: 2025-03-01 20:23:48 Functions: 0 15 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 370 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2022 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #ifndef _ACC_COMMON_H_
       6                 :            : #define _ACC_COMMON_H_
       7                 :            : 
       8                 :            : #include <bus_pci_driver.h>
       9                 :            : #include "rte_acc_common_cfg.h"
      10                 :            : 
      11                 :            : /* Values used in filling in descriptors */
      12                 :            : #define ACC_DMA_DESC_TYPE           2
      13                 :            : #define ACC_DMA_BLKID_FCW           1
      14                 :            : #define ACC_DMA_BLKID_IN            2
      15                 :            : #define ACC_DMA_BLKID_OUT_ENC       1
      16                 :            : #define ACC_DMA_BLKID_OUT_HARD      1
      17                 :            : #define ACC_DMA_BLKID_OUT_SOFT      2
      18                 :            : #define ACC_DMA_BLKID_OUT_HARQ      3
      19                 :            : #define ACC_DMA_BLKID_IN_HARQ       3
      20                 :            : #define ACC_DMA_BLKID_IN_MLD_R      3
      21                 :            : #define ACC_DMA_BLKID_DEWIN_IN      3
      22                 :            : 
      23                 :            : /* Values used in filling in decode FCWs */
      24                 :            : #define ACC_FCW_TD_VER              1
      25                 :            : #define ACC_FCW_TD_EXT_COLD_REG_EN  1
      26                 :            : #define ACC_FCW_TD_AUTOMAP          0x0f
      27                 :            : #define ACC_FCW_TD_RVIDX_0          2
      28                 :            : #define ACC_FCW_TD_RVIDX_1          26
      29                 :            : #define ACC_FCW_TD_RVIDX_2          50
      30                 :            : #define ACC_FCW_TD_RVIDX_3          74
      31                 :            : 
      32                 :            : #define ACC_SIZE_64MBYTE            (64*1024*1024)
      33                 :            : /* Number of elements in an Info Ring */
      34                 :            : #define ACC_INFO_RING_NUM_ENTRIES   1024
      35                 :            : /* Number of elements in HARQ layout memory
      36                 :            :  * 128M x 32kB = 4GB addressable memory
      37                 :            :  */
      38                 :            : #define ACC_HARQ_LAYOUT             (128 * 1024 * 1024)
      39                 :            : /* Assume offset for HARQ in memory */
      40                 :            : #define ACC_HARQ_OFFSET             (32 * 1024)
      41                 :            : #define ACC_HARQ_OFFSET_SHIFT       15
      42                 :            : #define ACC_HARQ_OFFSET_MASK        0x7ffffff
      43                 :            : #define ACC_HARQ_OFFSET_THRESHOLD   1024
      44                 :            : /* Mask used to calculate an index in an Info Ring array (not a byte offset) */
      45                 :            : #define ACC_INFO_RING_MASK          (ACC_INFO_RING_NUM_ENTRIES-1)
      46                 :            : 
      47                 :            : #define MAX_ENQ_BATCH_SIZE              255
      48                 :            : 
      49                 :            : /* All ACC100 Registers alignment are 32bits = 4B */
      50                 :            : #define ACC_BYTES_IN_WORD                 4
      51                 :            : #define ACC_MAX_E_MBUF                64000
      52                 :            : 
      53                 :            : #define ACC_VF_OFFSET_QOS   16 /* offset in Memory specific to QoS Mon */
      54                 :            : #define ACC_TMPL_PRI_0      0x03020100
      55                 :            : #define ACC_TMPL_PRI_1      0x07060504
      56                 :            : #define ACC_TMPL_PRI_2      0x0b0a0908
      57                 :            : #define ACC_TMPL_PRI_3      0x0f0e0d0c
      58                 :            : #define ACC_TMPL_PRI_4      0x13121110
      59                 :            : #define ACC_TMPL_PRI_5      0x17161514
      60                 :            : #define ACC_TMPL_PRI_6      0x1b1a1918
      61                 :            : #define ACC_TMPL_PRI_7      0x1f1e1d1c
      62                 :            : #define ACC_QUEUE_ENABLE    0x80000000  /* Bit to mark Queue as Enabled */
      63                 :            : #define ACC_FDONE           0x80000000
      64                 :            : #define ACC_SDONE           0x40000000
      65                 :            : 
      66                 :            : #define ACC_NUM_TMPL       32
      67                 :            : 
      68                 :            : #define ACC_ACCMAP_0       0
      69                 :            : #define ACC_ACCMAP_1       2
      70                 :            : #define ACC_ACCMAP_2       1
      71                 :            : #define ACC_ACCMAP_3       3
      72                 :            : #define ACC_ACCMAP_4       4
      73                 :            : #define ACC_ACCMAP_5       5
      74                 :            : #define ACC_PF_VAL         2
      75                 :            : 
      76                 :            : /* max number of iterations to allocate memory block for all rings */
      77                 :            : #define ACC_SW_RING_MEM_ALLOC_ATTEMPTS 5
      78                 :            : #define ACC_MAX_QUEUE_DEPTH            1024
      79                 :            : #define ACC_DMA_MAX_NUM_POINTERS       14
      80                 :            : #define ACC_DMA_MAX_NUM_POINTERS_IN    7
      81                 :            : #define ACC_DMA_DESC_PADDINGS          8
      82                 :            : #define ACC_FCW_PADDING                12
      83                 :            : #define ACC_DESC_FCW_OFFSET            192
      84                 :            : #define ACC_DESC_SIZE                  256
      85                 :            : #define ACC_DESC_OFFSET                (ACC_DESC_SIZE / 64)
      86                 :            : #define ACC_FCW_TE_BLEN                32
      87                 :            : #define ACC_FCW_TD_BLEN                24
      88                 :            : #define ACC_FCW_LE_BLEN                32
      89                 :            : #define ACC_FCW_LD_BLEN                36
      90                 :            : #define ACC_FCW_FFT_BLEN               28
      91                 :            : #define ACC_FCW_MLDTS_BLEN             32
      92                 :            : #define ACC_5GUL_SIZE_0                16
      93                 :            : #define ACC_5GUL_SIZE_1                40
      94                 :            : #define ACC_5GUL_OFFSET_0              36
      95                 :            : #define ACC_COMPANION_PTRS             8
      96                 :            : #define ACC_FCW_VER                    2
      97                 :            : #define ACC_MUX_5GDL_DESC              6
      98                 :            : #define ACC_CMP_ENC_SIZE               (sizeof(struct rte_bbdev_op_ldpc_enc) - ACC_ENC_OFFSET)
      99                 :            : #define ACC_CMP_DEC_SIZE               (sizeof(struct rte_bbdev_op_ldpc_dec) - ACC_DEC_OFFSET)
     100                 :            : #define ACC_ENC_OFFSET                (32)
     101                 :            : #define ACC_DEC_OFFSET                (80)
     102                 :            : #define ACC_LIMIT_DL_MUX_BITS          534
     103                 :            : #define ACC_NUM_QGRPS_PER_WORD         8
     104                 :            : #define ACC_MAX_NUM_QGRPS              32
     105                 :            : #define ACC_RING_SIZE_GRANULARITY      64
     106                 :            : #define ACC_MAX_FCW_SIZE              128
     107                 :            : #define ACC_IQ_SIZE                    4
     108                 :            : 
     109                 :            : #define ACC_FCW_FFT_BLEN_VRB2         128
     110                 :            : 
     111                 :            : /* Constants from K0 computation from 3GPP 38.212 Table 5.4.2.1-2 */
     112                 :            : #define ACC_N_ZC_1 66 /* N = 66 Zc for BG 1 */
     113                 :            : #define ACC_N_ZC_2 50 /* N = 50 Zc for BG 2 */
     114                 :            : #define ACC_K_ZC_1 22 /* K = 22 Zc for BG 1 */
     115                 :            : #define ACC_K_ZC_2 10 /* K = 10 Zc for BG 2 */
     116                 :            : #define ACC_K0_1_1 17 /* K0 fraction numerator for rv 1 and BG 1 */
     117                 :            : #define ACC_K0_1_2 13 /* K0 fraction numerator for rv 1 and BG 2 */
     118                 :            : #define ACC_K0_2_1 33 /* K0 fraction numerator for rv 2 and BG 1 */
     119                 :            : #define ACC_K0_2_2 25 /* K0 fraction numerator for rv 2 and BG 2 */
     120                 :            : #define ACC_K0_3_1 56 /* K0 fraction numerator for rv 3 and BG 1 */
     121                 :            : #define ACC_K0_3_2 43 /* K0 fraction numerator for rv 3 and BG 2 */
     122                 :            : 
     123                 :            : #define ACC_ENGINE_OFFSET    0x1000
     124                 :            : #define ACC_LONG_WAIT        1000
     125                 :            : #define ACC_MS_IN_US         (1000)
     126                 :            : 
     127                 :            : #define ACC_ALGO_SPA                0
     128                 :            : #define ACC_ALGO_MSA                1
     129                 :            : #define ACC_HARQ_ALIGN_64B          64
     130                 :            : #define ACC_MAX_ZC                  384
     131                 :            : 
     132                 :            : /* De-ratematch code rate limitation for recommended operation */
     133                 :            : #define ACC_LIM_03 2  /* 0.03 */
     134                 :            : #define ACC_LIM_09 6  /* 0.09 */
     135                 :            : #define ACC_LIM_14 9  /* 0.14 */
     136                 :            : #define ACC_LIM_21 14 /* 0.21 */
     137                 :            : #define ACC_LIM_31 20 /* 0.31 */
     138                 :            : #define ACC_MAX_E (128 * 1024 - 2)
     139                 :            : #define ACC_MAX_CS 12
     140                 :            : 
     141                 :            : #define ACC100_VARIANT          0
     142                 :            : #define VRB1_VARIANT            2
     143                 :            : #define VRB2_VARIANT            3
     144                 :            : 
     145                 :            : /* Queue Index Hierarchy */
     146                 :            : #define VRB1_GRP_ID_SHIFT    10
     147                 :            : #define VRB1_VF_ID_SHIFT     4
     148                 :            : #define VRB2_GRP_ID_SHIFT    12
     149                 :            : #define VRB2_VF_ID_SHIFT     6
     150                 :            : 
     151                 :            : #define ACC_MAX_FFT_WIN      16
     152                 :            : #define ACC_MAX_RING_BUFFER  64
     153                 :            : #define VRB2_MAX_Q_PER_OP 256
     154                 :            : 
     155                 :            : extern int acc_common_logtype;
     156                 :            : #define RTE_LOGTYPE_ACC_COMMON acc_common_logtype
     157                 :            : 
     158                 :            : /* Helper macro for logging */
     159                 :            : #define rte_acc_log(level, ...) \
     160                 :            :         RTE_LOG_LINE(level, ACC_COMMON, __VA_ARGS__)
     161                 :            : 
     162                 :            : /* ACC100 DMA Descriptor triplet */
     163                 :            : struct __rte_packed_begin acc_dma_triplet {
     164                 :            :         uint64_t address;
     165                 :            :         uint32_t blen:20,
     166                 :            :                 res0:4,
     167                 :            :                 last:1,
     168                 :            :                 dma_ext:1,
     169                 :            :                 res1:2,
     170                 :            :                 blkid:4;
     171                 :            : } __rte_packed_end;
     172                 :            : 
     173                 :            : 
     174                 :            : /* ACC100 Queue Manager Enqueue PCI Register */
     175                 :            : union acc_enqueue_reg_fmt {
     176                 :            :         uint32_t val;
     177                 :            :         struct {
     178                 :            :                 uint32_t num_elem:8,
     179                 :            :                         addr_offset:3,
     180                 :            :                         rsrvd:1,
     181                 :            :                         req_elem_addr:20;
     182                 :            :         };
     183                 :            : };
     184                 :            : 
     185                 :            : /* FEC 4G Uplink Frame Control Word */
     186                 :            : struct __rte_packed_begin acc_fcw_td {
     187                 :            :         uint8_t fcw_ver:4,
     188                 :            :                 num_maps:4; /* Unused in ACC100 */
     189                 :            :         uint8_t filler:6, /* Unused in ACC100 */
     190                 :            :                 rsrvd0:1,
     191                 :            :                 bypass_sb_deint:1;
     192                 :            :         uint16_t k_pos;
     193                 :            :         uint16_t k_neg; /* Unused in ACC100 */
     194                 :            :         uint8_t c_neg; /* Unused in ACC100 */
     195                 :            :         uint8_t c; /* Unused in ACC100 */
     196                 :            :         uint32_t ea; /* Unused in ACC100 */
     197                 :            :         uint32_t eb; /* Unused in ACC100 */
     198                 :            :         uint8_t cab; /* Unused in ACC100 */
     199                 :            :         uint8_t k0_start_col; /* Unused in ACC100 */
     200                 :            :         uint8_t rsrvd1;
     201                 :            :         uint8_t code_block_mode:1, /* Unused in ACC100 */
     202                 :            :                 turbo_crc_type:1,
     203                 :            :                 rsrvd2:3,
     204                 :            :                 bypass_teq:1, /* Unused in ACC100 */
     205                 :            :                 soft_output_en:1, /* Unused in ACC100 */
     206                 :            :                 ext_td_cold_reg_en:1;
     207                 :            :         union { /* External Cold register */
     208                 :            :                 uint32_t ext_td_cold_reg;
     209                 :            :                 struct {
     210                 :            :                         uint32_t min_iter:4, /* Unused in ACC100 */
     211                 :            :                                 max_iter:4,
     212                 :            :                                 ext_scale:5, /* Unused in ACC100 */
     213                 :            :                                 rsrvd3:3,
     214                 :            :                                 early_stop_en:1, /* Unused in ACC100 */
     215                 :            :                                 sw_soft_out_dis:1, /* Unused in ACC100 */
     216                 :            :                                 sw_et_cont:1, /* Unused in ACC100 */
     217                 :            :                                 sw_soft_out_saturation:1, /* Unused in ACC100 */
     218                 :            :                                 half_iter_on:1, /* Unused in ACC100 */
     219                 :            :                                 raw_decoder_input_on:1, /* Unused in ACC100 */
     220                 :            :                                 rsrvd4:10;
     221                 :            :                 };
     222                 :            :         };
     223                 :            : } __rte_packed_end;
     224                 :            : 
     225                 :            : /* FEC 4G Downlink Frame Control Word */
     226                 :            : struct __rte_packed_begin acc_fcw_te {
     227                 :            :         uint16_t k_neg;
     228                 :            :         uint16_t k_pos;
     229                 :            :         uint8_t c_neg;
     230                 :            :         uint8_t c;
     231                 :            :         uint8_t filler;
     232                 :            :         uint8_t cab;
     233                 :            :         uint32_t ea:17,
     234                 :            :                 rsrvd0:15;
     235                 :            :         uint32_t eb:17,
     236                 :            :                 rsrvd1:15;
     237                 :            :         uint16_t ncb_neg;
     238                 :            :         uint16_t ncb_pos;
     239                 :            :         uint8_t rv_idx0:2,
     240                 :            :                 rsrvd2:2,
     241                 :            :                 rv_idx1:2,
     242                 :            :                 rsrvd3:2;
     243                 :            :         uint8_t bypass_rv_idx0:1,
     244                 :            :                 bypass_rv_idx1:1,
     245                 :            :                 bypass_rm:1,
     246                 :            :                 rsrvd4:5;
     247                 :            :         uint8_t rsrvd5:1,
     248                 :            :                 rsrvd6:3,
     249                 :            :                 code_block_crc:1,
     250                 :            :                 rsrvd7:3;
     251                 :            :         uint8_t code_block_mode:1,
     252                 :            :                 rsrvd8:7;
     253                 :            :         uint64_t rsrvd9;
     254                 :            : } __rte_packed_end;
     255                 :            : 
     256                 :            : /* FEC 5GNR Downlink Frame Control Word */
     257                 :            : struct __rte_packed_begin acc_fcw_le {
     258                 :            :         uint32_t FCWversion:4,
     259                 :            :                 qm:4,
     260                 :            :                 nfiller:11,
     261                 :            :                 BG:1,
     262                 :            :                 Zc:9,
     263                 :            :                 res0:3;
     264                 :            :         uint32_t ncb:16,
     265                 :            :                 k0:16;
     266                 :            :         uint32_t rm_e:22,
     267                 :            :                 res1:4,
     268                 :            :                 crc_select:1,
     269                 :            :                 res2:1,
     270                 :            :                 bypass_intlv:1,
     271                 :            :                 res3:3;
     272                 :            :         uint32_t res4_a:12,
     273                 :            :                 mcb_count:3,
     274                 :            :                 res4_b:1,
     275                 :            :                 C:8,
     276                 :            :                 Cab:8;
     277                 :            :         uint32_t rm_e_b:22,
     278                 :            :                 res5:10;
     279                 :            :         uint32_t res6;
     280                 :            :         uint32_t res7;
     281                 :            :         uint32_t res8;
     282                 :            : } __rte_packed_end;
     283                 :            : 
     284                 :            : /* FEC 5GNR Uplink Frame Control Word */
     285                 :            : struct __rte_packed_begin acc_fcw_ld {
     286                 :            :         uint32_t FCWversion:4,
     287                 :            :                 qm:4,
     288                 :            :                 nfiller:11,
     289                 :            :                 BG:1,
     290                 :            :                 Zc:9,
     291                 :            :                 cnu_algo:1, /* Not supported in ACC100 */
     292                 :            :                 synd_precoder:1,
     293                 :            :                 synd_post:1;
     294                 :            :         uint32_t ncb:16,
     295                 :            :                 k0:16;
     296                 :            :         uint32_t rm_e:24,
     297                 :            :                 hcin_en:1,
     298                 :            :                 hcout_en:1,
     299                 :            :                 crc_select:1,
     300                 :            :                 bypass_dec:1,
     301                 :            :                 bypass_intlv:1,
     302                 :            :                 so_en:1,
     303                 :            :                 so_bypass_rm:1,
     304                 :            :                 so_bypass_intlv:1;
     305                 :            :         uint32_t hcin_offset:16,
     306                 :            :                 hcin_size0:16;
     307                 :            :         uint32_t hcin_size1:16,
     308                 :            :                 hcin_decomp_mode:3,
     309                 :            :                 llr_pack_mode:1,
     310                 :            :                 hcout_comp_mode:3,
     311                 :            :                 saturate_input:1, /* Not supported in VRB1 */
     312                 :            :                 dec_convllr:4,
     313                 :            :                 hcout_convllr:4;
     314                 :            :         uint32_t itmax:7,
     315                 :            :                 itstop:1,
     316                 :            :                 so_it:7,
     317                 :            :                 minsum_offset:1,  /* Not supported in VRB1 */
     318                 :            :                 hcout_offset:16;
     319                 :            :         uint32_t hcout_size0:16,
     320                 :            :                 hcout_size1:16;
     321                 :            :         uint32_t gain_i:8,
     322                 :            :                 gain_h:8,
     323                 :            :                 negstop_th:16;
     324                 :            :         uint32_t negstop_it:7,
     325                 :            :                 negstop_en:1,
     326                 :            :                 tb_crc_select:2, /* Not supported in ACC100 */
     327                 :            :                 dec_llrclip:2,  /* Not supported in VRB1 */
     328                 :            :                 tb_trailer_size:20; /* Not supported in ACC100 */
     329                 :            : } __rte_packed_end;
     330                 :            : 
     331                 :            : /* FFT Frame Control Word */
     332                 :            : struct __rte_packed_begin acc_fcw_fft {
     333                 :            :         uint32_t in_frame_size:16,
     334                 :            :                 leading_pad_size:16;
     335                 :            :         uint32_t out_frame_size:16,
     336                 :            :                 leading_depad_size:16;
     337                 :            :         uint32_t cs_window_sel;
     338                 :            :         uint32_t cs_window_sel2:16,
     339                 :            :                 cs_enable_bmap:16;
     340                 :            :         uint32_t num_antennas:8,
     341                 :            :                 idft_size:8,
     342                 :            :                 dft_size:8,
     343                 :            :                 cs_offset:8;
     344                 :            :         uint32_t idft_shift:8,
     345                 :            :                 dft_shift:8,
     346                 :            :                 cs_multiplier:16;
     347                 :            :         uint32_t bypass:2,
     348                 :            :                 fp16_in:1, /* Not supported in VRB1 */
     349                 :            :                 fp16_out:1,
     350                 :            :                 exp_adj:4,
     351                 :            :                 power_shift:4,
     352                 :            :                 power_en:1,
     353                 :            :                 res:19;
     354                 :            : } __rte_packed_end;
     355                 :            : 
     356                 :            : /* FFT Frame Control Word. */
     357                 :            : struct __rte_packed_begin acc_fcw_fft_3 {
     358                 :            :         uint32_t in_frame_size:16,
     359                 :            :                 leading_pad_size:16;
     360                 :            :         uint32_t out_frame_size:16,
     361                 :            :                 leading_depad_size:16;
     362                 :            :         uint32_t cs_window_sel;
     363                 :            :         uint32_t cs_window_sel2:16,
     364                 :            :                 cs_enable_bmap:16;
     365                 :            :         uint32_t num_antennas:8,
     366                 :            :                 idft_size:8,
     367                 :            :                 dft_size:8,
     368                 :            :                 cs_offset:8;
     369                 :            :         uint32_t idft_shift:8,
     370                 :            :                 dft_shift:8,
     371                 :            :                 cs_multiplier:16;
     372                 :            :         uint32_t bypass:2,
     373                 :            :                 fp16_in:1,
     374                 :            :                 fp16_out:1,
     375                 :            :                 exp_adj:4,
     376                 :            :                 power_shift:4,
     377                 :            :                 power_en:1,
     378                 :            :                 enable_dewin:1,
     379                 :            :                 freq_resample_mode:2,
     380                 :            :                 depad_output_size:16;
     381                 :            :         uint16_t cs_theta_0[ACC_MAX_CS];
     382                 :            :         uint32_t cs_theta_d[ACC_MAX_CS];
     383                 :            :         int8_t cs_time_offset[ACC_MAX_CS];
     384                 :            : } __rte_packed_end;
     385                 :            : 
     386                 :            : 
     387                 :            : /* MLD-TS Frame Control Word */
     388                 :            : struct __rte_packed_begin acc_fcw_mldts {
     389                 :            :         uint32_t fcw_version:4,
     390                 :            :                 res0:12,
     391                 :            :                 nrb:13, /* 1 to 1925 */
     392                 :            :                 res1:3;
     393                 :            :         uint32_t NLayers:2, /* 1: 2L... 3: 4L */
     394                 :            :                 res2:14,
     395                 :            :                 Qmod0:2, /* 0: 2...3: 8 */
     396                 :            :                 res3_0:2,
     397                 :            :                 Qmod1:2,
     398                 :            :                 res3_1:2,
     399                 :            :                 Qmod2:2,
     400                 :            :                 res3_2:2,
     401                 :            :                 Qmod3:2,
     402                 :            :                 res3_3:2;
     403                 :            :         uint32_t Rrep:3, /* 0 to 5 */
     404                 :            :                 res4:1,
     405                 :            :                 Crep:3, /* 0 to 6 */
     406                 :            :                 res5:25;
     407                 :            :         uint32_t pad0;
     408                 :            :         uint32_t pad1;
     409                 :            :         uint32_t pad2;
     410                 :            :         uint32_t pad3;
     411                 :            :         uint32_t pad4;
     412                 :            : } __rte_packed_end;
     413                 :            : 
     414                 :            : /* DMA Response Descriptor */
     415                 :            : union acc_dma_rsp_desc {
     416                 :            :         uint32_t val;
     417                 :            :         struct {
     418                 :            :                 uint32_t crc_status:1,
     419                 :            :                         synd_ok:1,
     420                 :            :                         dma_err:1,
     421                 :            :                         neg_stop:1,
     422                 :            :                         fcw_err:1,
     423                 :            :                         output_truncate:1,
     424                 :            :                         input_err:1,
     425                 :            :                         tsen_pagefault:1,
     426                 :            :                         iterCountFrac:8,
     427                 :            :                         iter_cnt:8,
     428                 :            :                         engine_hung:1,
     429                 :            :                         core_reset:5,
     430                 :            :                         sdone:1,
     431                 :            :                         fdone:1;
     432                 :            :                 uint32_t add_info_0;
     433                 :            :                 uint32_t add_info_1;
     434                 :            :         };
     435                 :            : };
     436                 :            : 
     437                 :            : /* DMA Request Descriptor */
     438                 :            : struct __rte_packed_begin acc_dma_req_desc {
     439                 :            :         union {
     440                 :            :                 struct{
     441                 :            :                         uint32_t type:4,
     442                 :            :                                 rsrvd0:26,
     443                 :            :                                 sdone:1,
     444                 :            :                                 fdone:1;
     445                 :            :                         uint32_t ib_ant_offset:16, /* Not supported in ACC100 */
     446                 :            :                                 res2:12,
     447                 :            :                                 num_ant:4;
     448                 :            :                         uint32_t ob_ant_offset:16,
     449                 :            :                                 ob_cyc_offset:12,
     450                 :            :                                 num_cs:4;
     451                 :            :                         uint32_t pass_param:8,
     452                 :            :                                 sdone_enable:1,
     453                 :            :                                 irq_enable:1,
     454                 :            :                                 timeStampEn:1,
     455                 :            :                                 dltb:1, /* Not supported in VRB1 */
     456                 :            :                                 res0:4,
     457                 :            :                                 numCBs:8,
     458                 :            :                                 m2dlen:4,
     459                 :            :                                 d2mlen:4;
     460                 :            :                 };
     461                 :            :                 struct{
     462                 :            :                         uint32_t word0;
     463                 :            :                         uint32_t word1;
     464                 :            :                         uint32_t word2;
     465                 :            :                         uint32_t word3;
     466                 :            :                 };
     467                 :            :         };
     468                 :            :         struct acc_dma_triplet data_ptrs[ACC_DMA_MAX_NUM_POINTERS];
     469                 :            : 
     470                 :            :         /* Virtual addresses used to retrieve SW context info */
     471                 :            :         union {
     472                 :            :                 void *op_addr;
     473                 :            :                 uint64_t pad1;  /* pad to 64 bits */
     474                 :            :         };
     475                 :            :         /*
     476                 :            :          * Stores additional information needed for driver processing:
     477                 :            :          * - last_desc_in_batch - flag used to mark last descriptor (CB)
     478                 :            :          *                        in batch
     479                 :            :          * - cbs_in_tb - stores information about total number of Code Blocks
     480                 :            :          *               in currently processed Transport Block
     481                 :            :          */
     482                 :            :         union {
     483                 :            :                 struct {
     484                 :            :                         union {
     485                 :            :                                 struct acc_fcw_ld fcw_ld;
     486                 :            :                                 struct acc_fcw_td fcw_td;
     487                 :            :                                 struct acc_fcw_le fcw_le;
     488                 :            :                                 struct acc_fcw_te fcw_te;
     489                 :            :                                 struct acc_fcw_fft fcw_fft;
     490                 :            :                                 struct acc_fcw_mldts fcw_mldts;
     491                 :            :                                 uint32_t pad2[ACC_FCW_PADDING];
     492                 :            :                         };
     493                 :            :                         uint32_t last_desc_in_batch :8,
     494                 :            :                                 cbs_in_tb:8,
     495                 :            :                                 pad4 : 16;
     496                 :            :                 };
     497                 :            :                 uint64_t pad3[ACC_DMA_DESC_PADDINGS]; /* pad to 64 bits */
     498                 :            :         };
     499                 :            : } __rte_packed_end;
     500                 :            : 
     501                 :            : /* ACC100 DMA Descriptor */
     502                 :            : union acc_dma_desc {
     503                 :            :         struct acc_dma_req_desc req;
     504                 :            :         union acc_dma_rsp_desc rsp;
     505                 :            :         uint64_t atom_hdr;
     506                 :            : };
     507                 :            : 
     508                 :            : /* Union describing Info Ring entry */
     509                 :            : union __rte_packed_begin acc_info_ring_data {
     510                 :            :         uint32_t val;
     511                 :            :         struct {
     512                 :            :                 union {
     513                 :            :                         uint16_t detailed_info;
     514                 :            :                         struct {
     515                 :            :                                 uint16_t aq_id: 4;
     516                 :            :                                 uint16_t qg_id: 4;
     517                 :            :                                 uint16_t vf_id: 6;
     518                 :            :                                 uint16_t reserved: 2;
     519                 :            :                         };
     520                 :            :                 };
     521                 :            :                 uint16_t int_nb: 7;
     522                 :            :                 uint16_t msi_0: 1;
     523                 :            :                 uint16_t vf2pf: 6;
     524                 :            :                 uint16_t loop: 1;
     525                 :            :                 uint16_t valid: 1;
     526                 :            :         };
     527                 :            :         struct {
     528                 :            :                 uint32_t aq_id_vrb2: 6;
     529                 :            :                 uint32_t qg_id_vrb2: 5;
     530                 :            :                 uint32_t vf_id_vrb2: 6;
     531                 :            :                 uint32_t int_nb_vrb2: 6;
     532                 :            :                 uint32_t msi_0_vrb2: 1;
     533                 :            :                 uint32_t vf2pf_vrb2: 6;
     534                 :            :                 uint32_t loop_vrb2: 1;
     535                 :            :                 uint32_t valid_vrb2: 1;
     536                 :            :         };
     537                 :            : } __rte_packed_end;
     538                 :            : 
     539                 :            : struct __rte_packed_begin acc_pad_ptr {
     540                 :            :         void *op_addr;
     541                 :            :         uint64_t pad1;  /* pad to 64 bits */
     542                 :            : } __rte_packed_end;
     543                 :            : 
     544                 :            : struct __rte_packed_begin acc_ptrs {
     545                 :            :         struct acc_pad_ptr ptr[ACC_COMPANION_PTRS];
     546                 :            : } __rte_packed_end;
     547                 :            : 
     548                 :            : /* Union describing Info Ring entry */
     549                 :            : union __rte_packed_begin acc_harq_layout_data {
     550                 :            :         uint32_t val;
     551                 :            :         struct {
     552                 :            :                 uint16_t offset;
     553                 :            :                 uint16_t size0;
     554                 :            :         };
     555                 :            : } __rte_packed_end;
     556                 :            : 
     557                 :            : /**
     558                 :            :  * Structure with details about RTE_BBDEV_EVENT_DEQUEUE event. It's passed to
     559                 :            :  * the callback function.
     560                 :            :  */
     561                 :            : struct acc_deq_intr_details {
     562                 :            :         uint16_t queue_id;
     563                 :            : };
     564                 :            : 
     565                 :            : /* TIP VF2PF Comms */
     566                 :            : enum {
     567                 :            :         ACC_VF2PF_STATUS_REQUEST = 1,
     568                 :            :         ACC_VF2PF_USING_VF = 2,
     569                 :            :         ACC_VF2PF_LUT_VER_REQUEST = 3,
     570                 :            :         ACC_VF2PF_FFT_WIN_REQUEST = 4,
     571                 :            : };
     572                 :            : 
     573                 :            : 
     574                 :            : typedef void (*acc10x_fcw_ld_fill_fun_t)(struct rte_bbdev_dec_op *op,
     575                 :            :                 struct acc_fcw_ld *fcw,
     576                 :            :                 union acc_harq_layout_data *harq_layout);
     577                 :            : typedef uint32_t (*queue_offset_fun_t)(bool pf_device, uint8_t vf_id,
     578                 :            :                 uint8_t qgrp_id, uint16_t aq_id);
     579                 :            : 
     580                 :            : /* Private data structure for each ACC100 device */
     581                 :            : struct acc_device {
     582                 :            :         void *mmio_base;  /**< Base address of MMIO registers (BAR0) */
     583                 :            :         void *sw_rings_base;  /* Base addr of un-aligned memory for sw rings */
     584                 :            :         void *sw_rings;  /* 64MBs of 64MB aligned memory for sw rings */
     585                 :            :         rte_iova_t sw_rings_iova;  /* IOVA address of sw_rings */
     586                 :            :         void *sw_rings_array[ACC_MAX_RING_BUFFER];  /* Array of aligned memory for sw rings. */
     587                 :            :         rte_iova_t sw_rings_iova_array[ACC_MAX_RING_BUFFER];  /* Array of sw_rings IOVA. */
     588                 :            :         uint32_t queue_index[ACC_MAX_RING_BUFFER]; /* Tracking queue index per ring buffer. */
     589                 :            :         /* Virtual address of the info memory routed to the this function under
     590                 :            :          * operation, whether it is PF or VF.
     591                 :            :          * HW may DMA information data at this location asynchronously
     592                 :            :          */
     593                 :            :         union acc_info_ring_data *info_ring;
     594                 :            : 
     595                 :            :         union acc_harq_layout_data *harq_layout;
     596                 :            :         /* Virtual Info Ring head */
     597                 :            :         uint16_t info_ring_head;
     598                 :            :         /* Number of bytes available for each queue in device, depending on
     599                 :            :          * how many queues are enabled with configure()
     600                 :            :          */
     601                 :            :         uint32_t sw_ring_size;
     602                 :            :         uint32_t ddr_size; /* Size in kB */
     603                 :            :         uint32_t *tail_ptrs; /* Base address of response tail pointer buffer */
     604                 :            :         rte_iova_t tail_ptr_iova; /* IOVA address of tail pointers */
     605                 :            :         /* Max number of entries available for each queue in device, depending
     606                 :            :          * on how many queues are enabled with configure()
     607                 :            :          */
     608                 :            :         uint32_t sw_ring_max_depth;
     609                 :            :         struct rte_acc_conf acc_conf; /* ACC100 Initial configuration */
     610                 :            :         /* Bitmap capturing which Queues have already been assigned */
     611                 :            :         uint64_t q_assigned_bit_map[ACC_MAX_NUM_QGRPS];
     612                 :            :         bool pf_device; /**< True if this is a PF ACC100 device */
     613                 :            :         bool configured; /**< True if this ACC100 device is configured */
     614                 :            :         uint16_t device_variant;  /**< Device variant */
     615                 :            :         const struct acc_registry_addr *reg_addr;
     616                 :            :         acc10x_fcw_ld_fill_fun_t fcw_ld_fill;  /**< 5GUL FCW generation function */
     617                 :            :         queue_offset_fun_t queue_offset;  /* Device specific queue offset */
     618                 :            :         uint16_t num_qgroups;
     619                 :            :         uint16_t num_aqs;
     620                 :            :         uint16_t fft_window_width[ACC_MAX_FFT_WIN]; /* FFT windowing size. */
     621                 :            : };
     622                 :            : 
     623                 :            : /* Structure associated with each queue. */
     624                 :            : struct __rte_cache_aligned acc_queue {
     625                 :            :         union acc_dma_desc *ring_addr;  /* Virtual address of sw ring */
     626                 :            :         rte_iova_t ring_addr_iova;  /* IOVA address of software ring */
     627                 :            :         uint32_t sw_ring_head;  /* software ring head */
     628                 :            :         uint32_t sw_ring_tail;  /* software ring tail */
     629                 :            :         /* software ring size (descriptors, not bytes) */
     630                 :            :         uint32_t sw_ring_depth;
     631                 :            :         /* mask used to wrap enqueued descriptors on the sw ring */
     632                 :            :         uint32_t sw_ring_wrap_mask;
     633                 :            :         /* Virtual address of companion ring */
     634                 :            :         struct acc_ptrs *companion_ring_addr;
     635                 :            :         /* MMIO register used to enqueue descriptors */
     636                 :            :         void *mmio_reg_enqueue;
     637                 :            :         uint8_t vf_id;  /* VF ID (max = 63) */
     638                 :            :         uint8_t qgrp_id;  /* Queue Group ID */
     639                 :            :         uint16_t aq_id;  /* Atomic Queue ID */
     640                 :            :         uint16_t aq_depth;  /* Depth of atomic queue */
     641                 :            :         uint32_t aq_enqueued;  /* Count how many "batches" have been enqueued */
     642                 :            :         uint32_t aq_dequeued;  /* Count how many "batches" have been dequeued */
     643                 :            :         uint32_t irq_enable;  /* Enable ops dequeue interrupts if set to 1 */
     644                 :            :         enum rte_bbdev_op_type op_type;  /* Type of this Queue: TE or TD */
     645                 :            :         /* Internal Buffers for loopback input */
     646                 :            :         uint8_t *lb_in;
     647                 :            :         uint8_t *lb_out;
     648                 :            :         uint8_t *fcw_ring;
     649                 :            :         rte_iova_t lb_in_addr_iova;
     650                 :            :         rte_iova_t lb_out_addr_iova;
     651                 :            :         rte_iova_t fcw_ring_addr_iova;
     652                 :            :         int8_t *derm_buffer; /* interim buffer for de-rm in SDK */
     653                 :            :         struct acc_device *d;
     654                 :            : };
     655                 :            : 
     656                 :            : /* Write to MMIO register address */
     657                 :            : static inline void
     658                 :            : mmio_write(void *addr, uint32_t value)
     659                 :            : {
     660                 :          0 :         *((volatile uint32_t *)(addr)) = rte_cpu_to_le_32(value);
     661                 :            : }
     662                 :            : 
     663                 :            : /* Write a register of a ACC100 device */
     664                 :            : static inline void
     665                 :            : acc_reg_write(struct acc_device *d, uint32_t offset, uint32_t value)
     666                 :            : {
     667                 :          0 :         void *reg_addr = RTE_PTR_ADD(d->mmio_base, offset);
     668                 :            :         mmio_write(reg_addr, value);
     669                 :          0 :         usleep(ACC_LONG_WAIT);
     670                 :          0 : }
     671                 :            : 
     672                 :            : /* Read a register of a ACC100 device */
     673                 :            : static inline uint32_t
     674                 :            : acc_reg_read(struct acc_device *d, uint32_t offset)
     675                 :            : {
     676                 :            : 
     677                 :          0 :         void *reg_addr = RTE_PTR_ADD(d->mmio_base, offset);
     678   [ #  #  #  #  :          0 :         uint32_t ret = *((volatile uint32_t *)(reg_addr));
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     679                 :            :         return rte_le_to_cpu_32(ret);
     680                 :            : }
     681                 :            : 
     682                 :            : /* Basic Implementation of Log2 for exact 2^N */
     683                 :            : static inline uint32_t
     684                 :            : log2_basic(uint32_t value)
     685                 :            : {
     686         [ #  # ]:          0 :         return (value == 0) ? 0 : rte_bsf32(value);
     687                 :            : }
     688                 :            : 
     689                 :            : /* Calculate memory alignment offset assuming alignment is 2^N */
     690                 :            : static inline uint32_t
     691                 :            : calc_mem_alignment_offset(void *unaligned_virt_mem, uint32_t alignment)
     692                 :            : {
     693                 :          0 :         rte_iova_t unaligned_phy_mem = rte_malloc_virt2iova(unaligned_virt_mem);
     694                 :          0 :         return (uint32_t)(alignment -
     695                 :          0 :                         (unaligned_phy_mem & (alignment-1)));
     696                 :            : }
     697                 :            : 
     698                 :            : static void
     699                 :            : free_base_addresses(void **base_addrs, int size)
     700                 :            : {
     701                 :            :         int i;
     702         [ #  # ]:          0 :         for (i = 0; i < size; i++)
     703                 :          0 :                 rte_free(base_addrs[i]);
     704                 :            : }
     705                 :            : 
     706                 :            : /* Read flag value 0/1 from bitmap */
     707                 :            : static inline bool
     708                 :            : check_bit(uint32_t bitmap, uint32_t bitmask)
     709                 :            : {
     710   [ #  #  #  #  :          0 :         return bitmap & bitmask;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     711                 :            : }
     712                 :            : 
     713                 :            : static inline char *
     714                 :            : mbuf_append(struct rte_mbuf *m_head, struct rte_mbuf *m, uint16_t len)
     715                 :            : {
     716   [ #  #  #  #  :          0 :         if (unlikely(len > rte_pktmbuf_tailroom(m)))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     717                 :            :                 return NULL;
     718                 :            : 
     719                 :          0 :         char *tail = (char *)m->buf_addr + m->data_off + m->data_len;
     720                 :          0 :         m->data_len = (uint16_t)(m->data_len + len);
     721                 :          0 :         m_head->pkt_len  = (m_head->pkt_len + len);
     722                 :          0 :         return tail;
     723                 :            : }
     724                 :            : 
     725                 :            : 
     726                 :            : static inline uint32_t
     727                 :            : get_desc_len(void)
     728                 :            : {
     729                 :            :         return sizeof(union acc_dma_desc);
     730                 :            : }
     731                 :            : 
     732                 :            : /* Allocate the 2 * 64MB block for the sw rings */
     733                 :            : static inline int
     734                 :          0 : alloc_2x64mb_sw_rings_mem(struct rte_bbdev *dev, struct acc_device *d,
     735                 :            :                 int socket)
     736                 :            : {
     737                 :            :         uint32_t sw_ring_size = ACC_SIZE_64MBYTE;
     738                 :          0 :         d->sw_rings_base = rte_zmalloc_socket(dev->device->driver->name,
     739                 :            :                         2 * sw_ring_size, RTE_CACHE_LINE_SIZE, socket);
     740         [ #  # ]:          0 :         if (d->sw_rings_base == NULL) {
     741                 :          0 :                 rte_acc_log(ERR, "Failed to allocate memory for %s:%u",
     742                 :            :                                 dev->device->driver->name,
     743                 :            :                                 dev->data->dev_id);
     744                 :          0 :                 return -ENOMEM;
     745                 :            :         }
     746                 :            :         uint32_t next_64mb_align_offset = calc_mem_alignment_offset(
     747                 :            :                         d->sw_rings_base, ACC_SIZE_64MBYTE);
     748                 :          0 :         d->sw_rings = RTE_PTR_ADD(d->sw_rings_base, next_64mb_align_offset);
     749                 :          0 :         d->sw_rings_iova = rte_malloc_virt2iova(d->sw_rings_base) +
     750                 :            :                         next_64mb_align_offset;
     751                 :          0 :         d->sw_ring_size = ACC_MAX_QUEUE_DEPTH * get_desc_len();
     752                 :          0 :         d->sw_ring_max_depth = ACC_MAX_QUEUE_DEPTH;
     753                 :            : 
     754                 :          0 :         return 0;
     755                 :            : }
     756                 :            : 
     757                 :            : /* Attempt to allocate minimised memory space for sw rings */
     758                 :            : static inline void
     759                 :          0 : alloc_sw_rings_min_mem(struct rte_bbdev *dev, struct acc_device *d,
     760                 :            :                 uint16_t num_queues, int socket)
     761                 :            : {
     762                 :            :         rte_iova_t sw_rings_base_iova, next_64mb_align_addr_iova;
     763                 :            :         uint32_t next_64mb_align_offset;
     764                 :            :         rte_iova_t sw_ring_iova_end_addr;
     765                 :            :         void *base_addrs[ACC_SW_RING_MEM_ALLOC_ATTEMPTS];
     766                 :            :         void *sw_rings_base;
     767                 :            :         int i = 0;
     768                 :            :         uint32_t q_sw_ring_size = ACC_MAX_QUEUE_DEPTH * get_desc_len();
     769                 :          0 :         uint32_t dev_sw_ring_size = q_sw_ring_size * num_queues;
     770                 :          0 :         uint32_t alignment = q_sw_ring_size * rte_align32pow2(num_queues);
     771                 :            :         /* Free first in case this is a reconfiguration */
     772                 :          0 :         rte_free(d->sw_rings_base);
     773                 :            : 
     774                 :            :         /* Find an aligned block of memory to store sw rings */
     775         [ #  # ]:          0 :         while (i < ACC_SW_RING_MEM_ALLOC_ATTEMPTS) {
     776                 :            :                 /*
     777                 :            :                  * sw_ring allocated memory is guaranteed to be aligned to
     778                 :            :                  * the variable 'alignment' at the condition that the requested
     779                 :            :                  * size is less than the page size
     780                 :            :                  */
     781                 :          0 :                 sw_rings_base = rte_zmalloc_socket(
     782                 :          0 :                                 dev->device->driver->name,
     783                 :            :                                 dev_sw_ring_size, alignment, socket);
     784                 :            : 
     785         [ #  # ]:          0 :                 if (sw_rings_base == NULL) {
     786                 :          0 :                         rte_acc_log(ERR,
     787                 :            :                                         "Failed to allocate memory for %s:%u",
     788                 :            :                                         dev->device->driver->name,
     789                 :            :                                         dev->data->dev_id);
     790                 :          0 :                         break;
     791                 :            :                 }
     792                 :            : 
     793                 :          0 :                 sw_rings_base_iova = rte_malloc_virt2iova(sw_rings_base);
     794                 :            :                 next_64mb_align_offset = calc_mem_alignment_offset(
     795                 :            :                                 sw_rings_base, ACC_SIZE_64MBYTE);
     796                 :          0 :                 next_64mb_align_addr_iova = sw_rings_base_iova +
     797                 :            :                                 next_64mb_align_offset;
     798                 :          0 :                 sw_ring_iova_end_addr = sw_rings_base_iova + dev_sw_ring_size - 1;
     799                 :            : 
     800                 :            :                 /* Check if the end of the sw ring memory block is before the
     801                 :            :                  * start of next 64MB aligned mem address
     802                 :            :                  */
     803         [ #  # ]:          0 :                 if (sw_ring_iova_end_addr < next_64mb_align_addr_iova) {
     804                 :          0 :                         d->sw_rings_iova = sw_rings_base_iova;
     805                 :          0 :                         d->sw_rings = sw_rings_base;
     806                 :          0 :                         d->sw_rings_base = sw_rings_base;
     807                 :          0 :                         d->sw_ring_size = q_sw_ring_size;
     808                 :          0 :                         d->sw_ring_max_depth = ACC_MAX_QUEUE_DEPTH;
     809                 :          0 :                         break;
     810                 :            :                 }
     811                 :            :                 /* Store the address of the unaligned mem block */
     812                 :          0 :                 base_addrs[i] = sw_rings_base;
     813                 :          0 :                 i++;
     814                 :            :         }
     815                 :            : 
     816                 :            :         /* Free all unaligned blocks of mem allocated in the loop */
     817                 :            :         free_base_addresses(base_addrs, i);
     818                 :          0 : }
     819                 :            : 
     820                 :            : /* Wrapper to provide VF index from ring data. */
     821                 :            : static inline uint16_t
     822                 :            : vf_from_ring(const union acc_info_ring_data ring_data, uint16_t device_variant)
     823                 :            : {
     824         [ #  # ]:          0 :         if (device_variant == VRB2_VARIANT)
     825                 :          0 :                 return ring_data.vf_id_vrb2;
     826                 :            :         else
     827                 :          0 :                 return ring_data.vf_id;
     828                 :            : }
     829                 :            : 
     830                 :            : /* Wrapper to provide QG index from ring data. */
     831                 :            : static inline uint16_t
     832                 :            : qg_from_ring(const union acc_info_ring_data ring_data, uint16_t device_variant)
     833                 :            : {
     834         [ #  # ]:          0 :         if (device_variant == VRB2_VARIANT)
     835                 :          0 :                 return ring_data.qg_id_vrb2;
     836                 :            :         else
     837                 :          0 :                 return ring_data.qg_id;
     838                 :            : }
     839                 :            : 
     840                 :            : /* Wrapper to provide AQ index from ring data. */
     841                 :            : static inline uint16_t
     842                 :            : aq_from_ring(const union acc_info_ring_data ring_data, uint16_t device_variant)
     843                 :            : {
     844         [ #  # ]:          0 :         if (device_variant == VRB2_VARIANT)
     845                 :          0 :                 return ring_data.aq_id_vrb2;
     846                 :            :         else
     847                 :          0 :                 return ring_data.aq_id;
     848                 :            : }
     849                 :            : 
     850                 :            : /* Wrapper to provide int index from ring data. */
     851                 :            : static inline uint16_t
     852                 :            : int_from_ring(const union acc_info_ring_data ring_data, uint16_t device_variant)
     853                 :            : {
     854   [ #  #  #  #  :          0 :         if (device_variant == VRB2_VARIANT)
                   #  # ]
     855                 :          0 :                 return ring_data.int_nb_vrb2;
     856                 :            :         else
     857                 :          0 :                 return ring_data.int_nb;
     858                 :            : }
     859                 :            : 
     860                 :            : /* Wrapper to provide queue index from group and aq index. */
     861                 :            : static inline int
     862                 :            : queue_index(uint16_t group_idx, uint16_t aq_idx, uint16_t device_variant)
     863                 :            : {
     864         [ #  # ]:          0 :         if (device_variant == VRB2_VARIANT)
     865                 :          0 :                 return (group_idx << VRB2_GRP_ID_SHIFT) + aq_idx;
     866                 :            :         else
     867                 :          0 :                 return (group_idx << VRB1_GRP_ID_SHIFT) + aq_idx;
     868                 :            : }
     869                 :            : 
     870                 :            : /* Wrapper to provide queue group from queue index. */
     871                 :            : static inline int
     872                 :            : qg_from_q(uint32_t q_idx, uint16_t device_variant)
     873                 :            : {
     874         [ #  # ]:          0 :         if (device_variant == VRB2_VARIANT)
     875                 :          0 :                 return (q_idx >> VRB2_GRP_ID_SHIFT) & 0x1F;
     876                 :            :         else
     877                 :          0 :                 return (q_idx >> VRB1_GRP_ID_SHIFT) & 0xF;
     878                 :            : }
     879                 :            : 
     880                 :            : /* Wrapper to provide vf from queue index. */
     881                 :            : static inline int32_t
     882                 :            : vf_from_q(uint32_t q_idx, uint16_t device_variant)
     883                 :            : {
     884         [ #  # ]:          0 :         if (device_variant == VRB2_VARIANT)
     885                 :          0 :                 return (q_idx >> VRB2_VF_ID_SHIFT)  & 0x3F;
     886                 :            :         else
     887                 :          0 :                 return (q_idx >> VRB1_VF_ID_SHIFT)  & 0x3F;
     888                 :            : }
     889                 :            : 
     890                 :            : /* Wrapper to provide aq index from queue index. */
     891                 :            : static inline int32_t
     892                 :            : aq_from_q(uint32_t q_idx, uint16_t device_variant)
     893                 :            : {
     894         [ #  # ]:          0 :         if (device_variant == VRB2_VARIANT)
     895                 :          0 :                 return q_idx & 0x3F;
     896                 :            :         else
     897                 :          0 :                 return q_idx & 0xF;
     898                 :            : }
     899                 :            : 
     900                 :            : /* Wrapper to set VF index in ring data. */
     901                 :            : static inline int32_t
     902                 :            : set_vf_in_ring(volatile union acc_info_ring_data *ring_data,
     903                 :            :                 uint16_t device_variant, uint16_t value)
     904                 :            : {
     905         [ #  # ]:          0 :         if (device_variant == VRB2_VARIANT)
     906                 :          0 :                 return ring_data->vf_id_vrb2 = value;
     907                 :            :         else
     908                 :          0 :                 return ring_data->vf_id = value;
     909                 :            : }
     910                 :            : 
     911                 :            : /*
     912                 :            :  * Find queue_id of a device queue based on details from the Info Ring.
     913                 :            :  * If a queue isn't found UINT16_MAX is returned.
     914                 :            :  */
     915                 :            : static inline uint16_t
     916                 :          0 : get_queue_id_from_ring_info(struct rte_bbdev_data *data, const union acc_info_ring_data ring_data)
     917                 :            : {
     918                 :            :         uint16_t queue_id;
     919                 :            :         struct acc_queue *acc_q;
     920                 :          0 :         struct acc_device *d = data->dev_private;
     921                 :            : 
     922         [ #  # ]:          0 :         for (queue_id = 0; queue_id < data->num_queues; ++queue_id) {
     923                 :          0 :                 acc_q = data->queues[queue_id].queue_private;
     924                 :            : 
     925   [ #  #  #  #  :          0 :                 if (acc_q != NULL && acc_q->aq_id == aq_from_ring(ring_data, d->device_variant) &&
                   #  # ]
     926   [ #  #  #  # ]:          0 :                                 acc_q->qgrp_id == qg_from_ring(ring_data, d->device_variant) &&
     927   [ #  #  #  # ]:          0 :                                 acc_q->vf_id == vf_from_ring(ring_data, d->device_variant))
     928                 :          0 :                         return queue_id;
     929                 :            :         }
     930                 :            : 
     931                 :            :         return UINT16_MAX;
     932                 :            : }
     933                 :            : 
     934                 :            : /* Fill in a frame control word for turbo encoding. */
     935                 :            : static inline void
     936                 :          0 : acc_fcw_te_fill(const struct rte_bbdev_enc_op *op, struct acc_fcw_te *fcw)
     937                 :            : {
     938                 :          0 :         fcw->code_block_mode = op->turbo_enc.code_block_mode;
     939         [ #  # ]:          0 :         if (fcw->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
     940                 :          0 :                 fcw->k_neg = op->turbo_enc.tb_params.k_neg;
     941                 :          0 :                 fcw->k_pos = op->turbo_enc.tb_params.k_pos;
     942                 :          0 :                 fcw->c_neg = op->turbo_enc.tb_params.c_neg;
     943                 :          0 :                 fcw->c = op->turbo_enc.tb_params.c;
     944                 :          0 :                 fcw->ncb_neg = op->turbo_enc.tb_params.ncb_neg;
     945                 :          0 :                 fcw->ncb_pos = op->turbo_enc.tb_params.ncb_pos;
     946                 :            : 
     947         [ #  # ]:          0 :                 if (check_bit(op->turbo_enc.op_flags,
     948                 :            :                                 RTE_BBDEV_TURBO_RATE_MATCH)) {
     949                 :          0 :                         fcw->bypass_rm = 0;
     950                 :          0 :                         fcw->cab = op->turbo_enc.tb_params.cab;
     951                 :          0 :                         fcw->ea = op->turbo_enc.tb_params.ea;
     952                 :          0 :                         fcw->eb = op->turbo_enc.tb_params.eb;
     953                 :            :                 } else {
     954                 :            :                         /* E is set to the encoding output size when RM is
     955                 :            :                          * bypassed.
     956                 :            :                          */
     957                 :          0 :                         fcw->bypass_rm = 1;
     958                 :          0 :                         fcw->cab = fcw->c_neg;
     959                 :          0 :                         fcw->ea = 3 * fcw->k_neg + 12;
     960                 :          0 :                         fcw->eb = 3 * fcw->k_pos + 12;
     961                 :            :                 }
     962                 :            :         } else { /* For CB mode */
     963                 :          0 :                 fcw->k_pos = op->turbo_enc.cb_params.k;
     964                 :          0 :                 fcw->ncb_pos = op->turbo_enc.cb_params.ncb;
     965                 :            : 
     966         [ #  # ]:          0 :                 if (check_bit(op->turbo_enc.op_flags,
     967                 :            :                                 RTE_BBDEV_TURBO_RATE_MATCH)) {
     968                 :          0 :                         fcw->bypass_rm = 0;
     969                 :          0 :                         fcw->eb = op->turbo_enc.cb_params.e;
     970                 :            :                 } else {
     971                 :            :                         /* E is set to the encoding output size when RM is
     972                 :            :                          * bypassed.
     973                 :            :                          */
     974                 :          0 :                         fcw->bypass_rm = 1;
     975                 :          0 :                         fcw->eb = 3 * fcw->k_pos + 12;
     976                 :            :                 }
     977                 :            :         }
     978                 :            : 
     979                 :          0 :         fcw->bypass_rv_idx1 = check_bit(op->turbo_enc.op_flags,
     980                 :            :                         RTE_BBDEV_TURBO_RV_INDEX_BYPASS);
     981                 :          0 :         fcw->code_block_crc = check_bit(op->turbo_enc.op_flags,
     982                 :            :                         RTE_BBDEV_TURBO_CRC_24B_ATTACH);
     983                 :          0 :         fcw->rv_idx1 = op->turbo_enc.rv_index;
     984                 :          0 : }
     985                 :            : 
     986                 :            : /* Compute value of k0.
     987                 :            :  * Based on 3GPP 38.212 Table 5.4.2.1-2
     988                 :            :  * Starting position of different redundancy versions, k0
     989                 :            :  */
     990                 :            : static inline uint16_t
     991                 :          0 : get_k0(uint16_t n_cb, uint16_t z_c, uint8_t bg, uint8_t rv_index, uint16_t k0)
     992                 :            : {
     993         [ #  # ]:          0 :         if (k0 > 0)
     994                 :            :                 return k0;
     995         [ #  # ]:          0 :         if (rv_index == 0)
     996                 :            :                 return 0;
     997         [ #  # ]:          0 :         uint16_t n = (bg == 1 ? ACC_N_ZC_1 : ACC_N_ZC_2) * z_c;
     998         [ #  # ]:          0 :         if (n_cb == n) {
     999         [ #  # ]:          0 :                 if (rv_index == 1)
    1000         [ #  # ]:          0 :                         return (bg == 1 ? ACC_K0_1_1 : ACC_K0_1_2) * z_c;
    1001         [ #  # ]:          0 :                 else if (rv_index == 2)
    1002         [ #  # ]:          0 :                         return (bg == 1 ? ACC_K0_2_1 : ACC_K0_2_2) * z_c;
    1003                 :            :                 else
    1004         [ #  # ]:          0 :                         return (bg == 1 ? ACC_K0_3_1 : ACC_K0_3_2) * z_c;
    1005                 :            :         }
    1006                 :            :         /* LBRM case - includes a division by N */
    1007         [ #  # ]:          0 :         if (unlikely(z_c == 0))
    1008                 :            :                 return 0;
    1009         [ #  # ]:          0 :         if (rv_index == 1)
    1010         [ #  # ]:          0 :                 return (((bg == 1 ? ACC_K0_1_1 : ACC_K0_1_2) * n_cb)
    1011                 :          0 :                                 / n) * z_c;
    1012         [ #  # ]:          0 :         else if (rv_index == 2)
    1013         [ #  # ]:          0 :                 return (((bg == 1 ? ACC_K0_2_1 : ACC_K0_2_2) * n_cb)
    1014                 :          0 :                                 / n) * z_c;
    1015                 :            :         else
    1016         [ #  # ]:          0 :                 return (((bg == 1 ? ACC_K0_3_1 : ACC_K0_3_2) * n_cb)
    1017                 :          0 :                                 / n) * z_c;
    1018                 :            : }
    1019                 :            : 
    1020                 :            : /* Fill in a frame control word for LDPC encoding. */
    1021                 :            : static inline void
    1022                 :          0 : acc_fcw_le_fill(const struct rte_bbdev_enc_op *op,
    1023                 :            :                 struct acc_fcw_le *fcw, int num_cb, uint32_t default_e)
    1024                 :            : {
    1025                 :          0 :         fcw->qm = op->ldpc_enc.q_m;
    1026                 :          0 :         fcw->nfiller = op->ldpc_enc.n_filler;
    1027                 :          0 :         fcw->BG = (op->ldpc_enc.basegraph - 1);
    1028                 :          0 :         fcw->Zc = op->ldpc_enc.z_c;
    1029                 :          0 :         fcw->ncb = op->ldpc_enc.n_cb;
    1030                 :          0 :         fcw->k0 = get_k0(fcw->ncb, fcw->Zc, op->ldpc_enc.basegraph,
    1031                 :          0 :                         op->ldpc_enc.rv_index, 0);
    1032         [ #  # ]:          0 :         fcw->rm_e = (default_e == 0) ? op->ldpc_enc.cb_params.e : default_e;
    1033                 :          0 :         fcw->crc_select = check_bit(op->ldpc_enc.op_flags,
    1034                 :            :                         RTE_BBDEV_LDPC_CRC_24B_ATTACH);
    1035                 :          0 :         fcw->bypass_intlv = check_bit(op->ldpc_enc.op_flags,
    1036                 :            :                         RTE_BBDEV_LDPC_INTERLEAVER_BYPASS);
    1037                 :          0 :         fcw->mcb_count = num_cb;
    1038                 :          0 : }
    1039                 :            : 
    1040                 :            : /* Provide the descriptor index on a given queue */
    1041                 :            : static inline uint16_t
    1042                 :            : acc_desc_idx(struct acc_queue *q, uint16_t offset)
    1043                 :            : {
    1044         [ #  # ]:          0 :         return (q->sw_ring_head + offset) & q->sw_ring_wrap_mask;
    1045                 :            : }
    1046                 :            : 
    1047                 :            : /* Provide the descriptor pointer on a given queue */
    1048                 :            : static inline union acc_dma_desc*
    1049                 :            : acc_desc(struct acc_queue *q, uint16_t offset)
    1050                 :            : {
    1051   [ #  #  #  #  :          0 :         return q->ring_addr + acc_desc_idx(q, offset);
             #  #  #  # ]
    1052                 :            : }
    1053                 :            : 
    1054                 :            : /* Provide the descriptor index for the tail of a given queue */
    1055                 :            : static inline uint16_t
    1056                 :            : acc_desc_idx_tail(struct acc_queue *q, uint16_t offset)
    1057                 :            : {
    1058         [ #  # ]:          0 :         return (q->sw_ring_tail + offset) & q->sw_ring_wrap_mask;
    1059                 :            : }
    1060                 :            : 
    1061                 :            : /* Provide the descriptor tail pointer on a given queue */
    1062                 :            : static inline union acc_dma_desc*
    1063                 :            : acc_desc_tail(struct acc_queue *q, uint16_t offset)
    1064                 :            : {
    1065   [ #  #  #  #  :          0 :         return q->ring_addr + acc_desc_idx_tail(q, offset);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    1066                 :            : }
    1067                 :            : 
    1068                 :            : /* Provide the operation pointer from the tail of a given queue */
    1069                 :            : static inline void*
    1070                 :            : acc_op_tail(struct acc_queue *q, uint16_t offset)
    1071                 :            : {
    1072   [ #  #  #  #  :          0 :         return (q->ring_addr + ((q->sw_ring_tail + offset) & q->sw_ring_wrap_mask))->req.op_addr;
             #  #  #  # ]
    1073                 :            : }
    1074                 :            : 
    1075                 :            : /* Enqueue a number of operations to HW and update software rings */
    1076                 :            : static inline void
    1077                 :          0 : acc_dma_enqueue(struct acc_queue *q, uint16_t n,
    1078                 :            :                 struct rte_bbdev_stats *queue_stats)
    1079                 :            : {
    1080                 :            :         union acc_enqueue_reg_fmt enq_req;
    1081                 :            :         union acc_dma_desc *desc;
    1082                 :            :         uint64_t start_time = 0;
    1083                 :          0 :         queue_stats->acc_offload_cycles = 0;
    1084                 :            : 
    1085                 :            :         /* Set Sdone and IRQ enable bit on last descriptor. */
    1086                 :          0 :         desc = acc_desc(q, n - 1);
    1087                 :          0 :         desc->req.sdone_enable = 1;
    1088                 :          0 :         desc->req.irq_enable = q->irq_enable;
    1089                 :            : 
    1090                 :          0 :         enq_req.val = 0;
    1091                 :            :         /* Setting offset, 100b for 256 DMA Desc */
    1092                 :          0 :         enq_req.addr_offset = ACC_DESC_OFFSET;
    1093                 :            : 
    1094                 :            :         /* Split ops into batches */
    1095                 :            :         do {
    1096                 :            :                 uint16_t enq_batch_size;
    1097                 :            :                 uint64_t offset;
    1098                 :            :                 rte_iova_t req_elem_addr;
    1099                 :            : 
    1100                 :          0 :                 enq_batch_size = RTE_MIN(n, MAX_ENQ_BATCH_SIZE);
    1101                 :            : 
    1102                 :            :                 /* Set flag on last descriptor in a batch */
    1103                 :          0 :                 desc = acc_desc(q, enq_batch_size - 1);
    1104                 :          0 :                 desc->req.last_desc_in_batch = 1;
    1105                 :            : 
    1106                 :            :                 /* Calculate the 1st descriptor's address */
    1107                 :          0 :                 offset = ((q->sw_ring_head & q->sw_ring_wrap_mask) * sizeof(union acc_dma_desc));
    1108                 :          0 :                 req_elem_addr = q->ring_addr_iova + offset;
    1109                 :            : 
    1110                 :            :                 /* Fill enqueue struct */
    1111                 :          0 :                 enq_req.num_elem = enq_batch_size;
    1112                 :            :                 /* low 6 bits are not needed */
    1113                 :          0 :                 enq_req.req_elem_addr = (uint32_t)(req_elem_addr >> 6);
    1114                 :            : 
    1115                 :            : #ifdef RTE_LIBRTE_BBDEV_DEBUG
    1116                 :            :                 rte_memdump(stderr, "Req sdone", desc, sizeof(*desc));
    1117                 :            : #endif
    1118                 :          0 :                 rte_acc_log(DEBUG, "Enqueue %u reqs (phys %#"PRIx64") to reg %p",
    1119                 :            :                                 enq_batch_size,
    1120                 :            :                                 req_elem_addr,
    1121                 :            :                                 (void *)q->mmio_reg_enqueue);
    1122                 :            : 
    1123                 :          0 :                 q->aq_enqueued++;
    1124                 :          0 :                 q->sw_ring_head += enq_batch_size;
    1125                 :            : 
    1126                 :            :                 rte_wmb();
    1127                 :            : 
    1128                 :            :                 /* Start time measurement for enqueue function offload. */
    1129                 :            :                 start_time = rte_rdtsc_precise();
    1130                 :            : 
    1131                 :          0 :                 rte_acc_log(DEBUG, "Debug : MMIO Enqueue");
    1132                 :          0 :                 mmio_write(q->mmio_reg_enqueue, enq_req.val);
    1133                 :            : 
    1134                 :          0 :                 queue_stats->acc_offload_cycles += rte_rdtsc_precise() - start_time;
    1135                 :            : 
    1136                 :          0 :                 n -= enq_batch_size;
    1137                 :            : 
    1138         [ #  # ]:          0 :         } while (n);
    1139                 :            : 
    1140                 :            : 
    1141                 :          0 : }
    1142                 :            : 
    1143                 :            : /* Convert offset to harq index for harq_layout structure */
    1144                 :            : static inline uint32_t hq_index(uint32_t offset)
    1145                 :            : {
    1146   [ #  #  #  # ]:          0 :         return (offset >> ACC_HARQ_OFFSET_SHIFT) & ACC_HARQ_OFFSET_MASK;
    1147                 :            : }
    1148                 :            : 
    1149                 :            : /* Calculates number of CBs in processed encoder TB based on 'r' and input
    1150                 :            :  * length.
    1151                 :            :  */
    1152                 :            : static inline uint8_t
    1153                 :          0 : get_num_cbs_in_tb_enc(struct rte_bbdev_op_turbo_enc *turbo_enc)
    1154                 :            : {
    1155                 :            :         uint8_t c, c_neg, r, crc24_bits = 0;
    1156                 :            :         uint16_t k, k_neg, k_pos;
    1157                 :            :         uint8_t cbs_in_tb = 0;
    1158                 :            :         int32_t length;
    1159                 :            : 
    1160                 :          0 :         length = turbo_enc->input.length;
    1161                 :          0 :         r = turbo_enc->tb_params.r;
    1162                 :          0 :         c = turbo_enc->tb_params.c;
    1163                 :          0 :         c_neg = turbo_enc->tb_params.c_neg;
    1164                 :          0 :         k_neg = turbo_enc->tb_params.k_neg;
    1165                 :          0 :         k_pos = turbo_enc->tb_params.k_pos;
    1166                 :            :         crc24_bits = 0;
    1167         [ #  # ]:          0 :         if (check_bit(turbo_enc->op_flags, RTE_BBDEV_TURBO_CRC_24B_ATTACH))
    1168                 :            :                 crc24_bits = 24;
    1169         [ #  # ]:          0 :         while (length > 0 && r < c) {
    1170         [ #  # ]:          0 :                 k = (r < c_neg) ? k_neg : k_pos;
    1171                 :          0 :                 length -= (k - crc24_bits) >> 3;
    1172                 :          0 :                 r++;
    1173                 :          0 :                 cbs_in_tb++;
    1174                 :            :         }
    1175                 :            : 
    1176                 :          0 :         return cbs_in_tb;
    1177                 :            : }
    1178                 :            : 
    1179                 :            : /* Calculates number of CBs in processed decoder TB based on 'r' and input
    1180                 :            :  * length.
    1181                 :            :  */
    1182                 :            : static inline uint16_t
    1183                 :            : get_num_cbs_in_tb_dec(struct rte_bbdev_op_turbo_dec *turbo_dec)
    1184                 :            : {
    1185                 :            :         uint8_t c, c_neg, r = 0;
    1186                 :            :         uint16_t kw, k, k_neg, k_pos, cbs_in_tb = 0;
    1187                 :            :         int32_t length;
    1188                 :            : 
    1189                 :          0 :         length = turbo_dec->input.length;
    1190                 :          0 :         r = turbo_dec->tb_params.r;
    1191                 :          0 :         c = turbo_dec->tb_params.c;
    1192                 :          0 :         c_neg = turbo_dec->tb_params.c_neg;
    1193                 :          0 :         k_neg = turbo_dec->tb_params.k_neg;
    1194                 :          0 :         k_pos = turbo_dec->tb_params.k_pos;
    1195         [ #  # ]:          0 :         while (length > 0 && r < c) {
    1196         [ #  # ]:          0 :                 k = (r < c_neg) ? k_neg : k_pos;
    1197                 :          0 :                 kw = RTE_ALIGN_CEIL(k + 4, 32) * 3;
    1198                 :          0 :                 length -= kw;
    1199                 :          0 :                 r++;
    1200                 :          0 :                 cbs_in_tb++;
    1201                 :            :         }
    1202                 :            : 
    1203                 :            :         return cbs_in_tb;
    1204                 :            : }
    1205                 :            : 
    1206                 :            : /* Calculates number of CBs in processed decoder TB based on 'r' and input
    1207                 :            :  * length.
    1208                 :            :  */
    1209                 :            : static inline uint16_t
    1210                 :            : get_num_cbs_in_tb_ldpc_dec(struct rte_bbdev_op_ldpc_dec *ldpc_dec)
    1211                 :            : {
    1212                 :            :         uint16_t r, cbs_in_tb = 0;
    1213                 :          0 :         int32_t length = ldpc_dec->input.length;
    1214                 :          0 :         r = ldpc_dec->tb_params.r;
    1215   [ #  #  #  # ]:          0 :         while (length > 0 && r < ldpc_dec->tb_params.c) {
    1216                 :          0 :                 length -=  (r < ldpc_dec->tb_params.cab) ?
    1217         [ #  # ]:          0 :                                 ldpc_dec->tb_params.ea :
    1218                 :            :                                 ldpc_dec->tb_params.eb;
    1219                 :          0 :                 r++;
    1220                 :          0 :                 cbs_in_tb++;
    1221                 :            :         }
    1222                 :            :         return cbs_in_tb;
    1223                 :            : }
    1224                 :            : 
    1225                 :            : /* Check we can mux encode operations with common FCW */
    1226                 :            : static inline int16_t
    1227                 :          0 : check_mux(struct rte_bbdev_enc_op **ops, uint16_t num) {
    1228                 :            :         uint16_t i;
    1229         [ #  # ]:          0 :         if (num <= 1)
    1230                 :            :                 return 1;
    1231         [ #  # ]:          0 :         for (i = 1; i < num; ++i) {
    1232                 :            :                 /* Only mux compatible code blocks */
    1233                 :          0 :                 if (memcmp((uint8_t *)(&ops[i]->ldpc_enc) + ACC_ENC_OFFSET,
    1234         [ #  # ]:          0 :                                 (uint8_t *)(&ops[0]->ldpc_enc) +
    1235                 :            :                                 ACC_ENC_OFFSET,
    1236                 :            :                                 ACC_CMP_ENC_SIZE) != 0)
    1237                 :          0 :                         return i;
    1238                 :            :         }
    1239                 :            :         /* Avoid multiplexing small inbound size frames */
    1240         [ #  # ]:          0 :         int Kp = (ops[0]->ldpc_enc.basegraph == 1 ? 22 : 10) *
    1241                 :          0 :                         ops[0]->ldpc_enc.z_c - ops[0]->ldpc_enc.n_filler;
    1242         [ #  # ]:          0 :         if (Kp  <= ACC_LIMIT_DL_MUX_BITS)
    1243                 :            :                 return 1;
    1244                 :          0 :         return num;
    1245                 :            : }
    1246                 :            : 
    1247                 :            : /* Check we can mux encode operations with common FCW */
    1248                 :            : static inline bool
    1249                 :            : cmp_ldpc_dec_op(struct rte_bbdev_dec_op **ops) {
    1250                 :            :         /* Only mux compatible code blocks */
    1251                 :            :         if (memcmp((uint8_t *)(&ops[0]->ldpc_dec) + ACC_DEC_OFFSET,
    1252                 :            :                         (uint8_t *)(&ops[1]->ldpc_dec) +
    1253                 :            :                         ACC_DEC_OFFSET, ACC_CMP_DEC_SIZE) != 0) {
    1254                 :            :                 return false;
    1255                 :            :         } else
    1256                 :            :                 return true;
    1257                 :            : }
    1258                 :            : 
    1259                 :            : /**
    1260                 :            :  * Fills descriptor with data pointers of one block type.
    1261                 :            :  *
    1262                 :            :  * @param desc
    1263                 :            :  *   Pointer to DMA descriptor.
    1264                 :            :  * @param input
    1265                 :            :  *   Pointer to pointer to input data which will be encoded. It can be changed
    1266                 :            :  *   and points to next segment in scatter-gather case.
    1267                 :            :  * @param offset
    1268                 :            :  *   Input offset in rte_mbuf structure. It is used for calculating the point
    1269                 :            :  *   where data is starting.
    1270                 :            :  * @param cb_len
    1271                 :            :  *   Length of currently processed Code Block
    1272                 :            :  * @param seg_total_left
    1273                 :            :  *   It indicates how many bytes still left in segment (mbuf) for further
    1274                 :            :  *   processing.
    1275                 :            :  * @param op_flags
    1276                 :            :  *   Store information about device capabilities
    1277                 :            :  * @param next_triplet
    1278                 :            :  *   Index for VRB1 DMA Descriptor triplet
    1279                 :            :  * @param scattergather
    1280                 :            :  *   Flag to support scatter-gather for the mbuf
    1281                 :            :  *
    1282                 :            :  * @return
    1283                 :            :  *   Returns index of next triplet on success, other value if lengths of
    1284                 :            :  *   pkt and processed cb do not match.
    1285                 :            :  *
    1286                 :            :  */
    1287                 :            : static inline int
    1288                 :          0 : acc_dma_fill_blk_type_in(struct acc_dma_req_desc *desc,
    1289                 :            :                 struct rte_mbuf **input, uint32_t *offset, uint32_t cb_len,
    1290                 :            :                 uint32_t *seg_total_left, int next_triplet,
    1291                 :            :                 bool scattergather)
    1292                 :            : {
    1293                 :            :         uint32_t part_len;
    1294                 :          0 :         struct rte_mbuf *m = *input;
    1295         [ #  # ]:          0 :         if (scattergather)
    1296                 :          0 :                 part_len = (*seg_total_left < cb_len) ?
    1297                 :            :                                 *seg_total_left : cb_len;
    1298                 :            :         else
    1299                 :            :                 part_len = cb_len;
    1300                 :          0 :         cb_len -= part_len;
    1301                 :          0 :         *seg_total_left -= part_len;
    1302                 :            : 
    1303                 :          0 :         desc->data_ptrs[next_triplet].address =
    1304                 :          0 :                         rte_pktmbuf_iova_offset(m, *offset);
    1305                 :          0 :         desc->data_ptrs[next_triplet].blen = part_len;
    1306                 :          0 :         desc->data_ptrs[next_triplet].blkid = ACC_DMA_BLKID_IN;
    1307                 :          0 :         desc->data_ptrs[next_triplet].last = 0;
    1308                 :          0 :         desc->data_ptrs[next_triplet].dma_ext = 0;
    1309                 :          0 :         *offset += part_len;
    1310                 :          0 :         next_triplet++;
    1311                 :            : 
    1312         [ #  # ]:          0 :         while (cb_len > 0) {
    1313   [ #  #  #  # ]:          0 :                 if (next_triplet < ACC_DMA_MAX_NUM_POINTERS_IN && m->next != NULL) {
    1314                 :            : 
    1315                 :            :                         m = m->next;
    1316                 :          0 :                         *seg_total_left = rte_pktmbuf_data_len(m);
    1317                 :          0 :                         part_len = (*seg_total_left < cb_len) ?
    1318                 :            :                                         *seg_total_left :
    1319                 :            :                                         cb_len;
    1320                 :          0 :                         desc->data_ptrs[next_triplet].address =
    1321                 :          0 :                                         rte_pktmbuf_iova_offset(m, 0);
    1322                 :          0 :                         desc->data_ptrs[next_triplet].blen = part_len;
    1323                 :          0 :                         desc->data_ptrs[next_triplet].blkid =
    1324                 :            :                                         ACC_DMA_BLKID_IN;
    1325                 :          0 :                         desc->data_ptrs[next_triplet].last = 0;
    1326                 :          0 :                         desc->data_ptrs[next_triplet].dma_ext = 0;
    1327                 :          0 :                         cb_len -= part_len;
    1328                 :          0 :                         *seg_total_left -= part_len;
    1329                 :            :                         /* Initializing offset for next segment (mbuf) */
    1330                 :          0 :                         *offset = part_len;
    1331                 :          0 :                         next_triplet++;
    1332                 :            :                 } else {
    1333                 :          0 :                         rte_acc_log(ERR,
    1334                 :            :                                 "Some data still left for processing: "
    1335                 :            :                                 "data_left: %u, next_triplet: %u, next_mbuf: %p",
    1336                 :            :                                 cb_len, next_triplet, m->next);
    1337                 :          0 :                         return -EINVAL;
    1338                 :            :                 }
    1339                 :            :         }
    1340                 :            :         /* Storing new mbuf as it could be changed in scatter-gather case*/
    1341                 :          0 :         *input = m;
    1342                 :            : 
    1343                 :          0 :         return next_triplet;
    1344                 :            : }
    1345                 :            : 
    1346                 :            : /* Fills descriptor with data pointers of one block type.
    1347                 :            :  * Returns index of next triplet
    1348                 :            :  */
    1349                 :            : static inline int
    1350                 :            : acc_dma_fill_blk_type(struct acc_dma_req_desc *desc,
    1351                 :            :                 struct rte_mbuf *mbuf, uint32_t offset,
    1352                 :            :                 uint32_t len, int next_triplet, int blk_id)
    1353                 :            : {
    1354                 :          0 :         desc->data_ptrs[next_triplet].address =
    1355                 :          0 :                         rte_pktmbuf_iova_offset(mbuf, offset);
    1356                 :          0 :         desc->data_ptrs[next_triplet].blen = len;
    1357                 :          0 :         desc->data_ptrs[next_triplet].blkid = blk_id;
    1358                 :          0 :         desc->data_ptrs[next_triplet].last = 0;
    1359         [ #  # ]:          0 :         desc->data_ptrs[next_triplet].dma_ext = 0;
    1360   [ #  #  #  #  :          0 :         next_triplet++;
             #  #  #  # ]
    1361                 :            : 
    1362                 :            :         return next_triplet;
    1363                 :            : }
    1364                 :            : 
    1365                 :            : static inline void
    1366                 :            : acc_header_init(struct acc_dma_req_desc *desc)
    1367                 :            : {
    1368                 :          0 :         desc->word0 = ACC_DMA_DESC_TYPE;
    1369                 :          0 :         desc->word1 = 0; /**< Timestamp could be disabled */
    1370                 :          0 :         desc->word2 = 0;
    1371         [ #  # ]:          0 :         desc->word3 = 0;
    1372   [ #  #  #  #  :          0 :         desc->numCBs = 1;
             #  #  #  # ]
    1373                 :            : }
    1374                 :            : 
    1375                 :            : #ifdef RTE_LIBRTE_BBDEV_DEBUG
    1376                 :            : /* Check if any input data is unexpectedly left for processing */
    1377                 :            : static inline int
    1378                 :            : check_mbuf_total_left(uint32_t mbuf_total_left)
    1379                 :            : {
    1380                 :            :         if (mbuf_total_left == 0)
    1381                 :            :                 return 0;
    1382                 :            :         rte_acc_log(ERR,
    1383                 :            :                 "Some date still left for processing: mbuf_total_left = %u",
    1384                 :            :                 mbuf_total_left);
    1385                 :            :         return -EINVAL;
    1386                 :            : }
    1387                 :            : #endif
    1388                 :            : 
    1389                 :            : static inline int
    1390                 :          0 : acc_dma_desc_te_fill(struct rte_bbdev_enc_op *op,
    1391                 :            :                 struct acc_dma_req_desc *desc, struct rte_mbuf **input,
    1392                 :            :                 struct rte_mbuf *output, uint32_t *in_offset,
    1393                 :            :                 uint32_t *out_offset, uint32_t *out_length,
    1394                 :            :                 uint32_t *mbuf_total_left, uint32_t *seg_total_left, uint8_t r)
    1395                 :            : {
    1396                 :            :         int next_triplet = 1; /* FCW already done */
    1397                 :            :         uint32_t e, ea, eb, length;
    1398                 :            :         uint16_t k, k_neg, k_pos;
    1399                 :            :         uint8_t cab, c_neg;
    1400                 :            : 
    1401                 :          0 :         desc->word0 = ACC_DMA_DESC_TYPE;
    1402                 :          0 :         desc->word1 = 0; /**< Timestamp could be disabled */
    1403                 :          0 :         desc->word2 = 0;
    1404                 :          0 :         desc->word3 = 0;
    1405                 :          0 :         desc->numCBs = 1;
    1406                 :            : 
    1407         [ #  # ]:          0 :         if (op->turbo_enc.code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
    1408                 :          0 :                 ea = op->turbo_enc.tb_params.ea;
    1409                 :          0 :                 eb = op->turbo_enc.tb_params.eb;
    1410                 :          0 :                 cab = op->turbo_enc.tb_params.cab;
    1411                 :          0 :                 k_neg = op->turbo_enc.tb_params.k_neg;
    1412                 :          0 :                 k_pos = op->turbo_enc.tb_params.k_pos;
    1413                 :          0 :                 c_neg = op->turbo_enc.tb_params.c_neg;
    1414         [ #  # ]:          0 :                 e = (r < cab) ? ea : eb;
    1415         [ #  # ]:          0 :                 k = (r < c_neg) ? k_neg : k_pos;
    1416                 :            :         } else {
    1417                 :          0 :                 e = op->turbo_enc.cb_params.e;
    1418                 :          0 :                 k = op->turbo_enc.cb_params.k;
    1419                 :            :         }
    1420                 :            : 
    1421         [ #  # ]:          0 :         if (check_bit(op->turbo_enc.op_flags, RTE_BBDEV_TURBO_CRC_24B_ATTACH))
    1422                 :          0 :                 length = (k - 24) >> 3;
    1423                 :            :         else
    1424                 :          0 :                 length = k >> 3;
    1425                 :            : 
    1426   [ #  #  #  # ]:          0 :         if (unlikely((*mbuf_total_left == 0) || (*mbuf_total_left < length))) {
    1427                 :          0 :                 rte_acc_log(ERR,
    1428                 :            :                                 "Mismatch between mbuf length and included CB sizes: mbuf len %u, cb len %u",
    1429                 :            :                                 *mbuf_total_left, length);
    1430                 :          0 :                 return -1;
    1431                 :            :         }
    1432                 :            : 
    1433                 :          0 :         next_triplet = acc_dma_fill_blk_type_in(desc, input, in_offset,
    1434                 :            :                         length, seg_total_left, next_triplet,
    1435                 :            :                         check_bit(op->turbo_enc.op_flags,
    1436                 :            :                         RTE_BBDEV_TURBO_ENC_SCATTER_GATHER));
    1437         [ #  # ]:          0 :         if (unlikely(next_triplet < 0)) {
    1438                 :          0 :                 rte_acc_log(ERR,
    1439                 :            :                                 "Mismatch between data to process and mbuf data length in bbdev_op: %p",
    1440                 :            :                                 op);
    1441                 :          0 :                 return -1;
    1442                 :            :         }
    1443                 :          0 :         desc->data_ptrs[next_triplet - 1].last = 1;
    1444                 :          0 :         desc->m2dlen = next_triplet;
    1445                 :          0 :         *mbuf_total_left -= length;
    1446                 :            : 
    1447                 :            :         /* Set output length */
    1448         [ #  # ]:          0 :         if (check_bit(op->turbo_enc.op_flags, RTE_BBDEV_TURBO_RATE_MATCH))
    1449                 :            :                 /* Integer round up division by 8 */
    1450                 :          0 :                 *out_length = (e + 7) >> 3;
    1451                 :            :         else
    1452                 :          0 :                 *out_length = (k >> 3) * 3 + 2;
    1453                 :            : 
    1454         [ #  # ]:          0 :         next_triplet = acc_dma_fill_blk_type(desc, output, *out_offset,
    1455                 :            :                         *out_length, next_triplet, ACC_DMA_BLKID_OUT_ENC);
    1456         [ #  # ]:          0 :         if (unlikely(next_triplet < 0)) {
    1457                 :          0 :                 rte_acc_log(ERR,
    1458                 :            :                                 "Mismatch between data to process and mbuf data length in bbdev_op: %p",
    1459                 :            :                                 op);
    1460                 :          0 :                 return -1;
    1461                 :            :         }
    1462                 :          0 :         op->turbo_enc.output.length += *out_length;
    1463                 :          0 :         *out_offset += *out_length;
    1464                 :          0 :         desc->data_ptrs[next_triplet - 1].last = 1;
    1465                 :          0 :         desc->d2mlen = next_triplet - desc->m2dlen;
    1466                 :            : 
    1467                 :          0 :         desc->op_addr = op;
    1468                 :            : 
    1469                 :          0 :         return 0;
    1470                 :            : }
    1471                 :            : 
    1472                 :            : static inline int
    1473                 :          0 : acc_pci_remove(struct rte_pci_device *pci_dev)
    1474                 :            : {
    1475                 :            :         struct rte_bbdev *bbdev;
    1476                 :            :         int ret;
    1477                 :            :         uint8_t dev_id;
    1478                 :            : 
    1479         [ #  # ]:          0 :         if (pci_dev == NULL)
    1480                 :            :                 return -EINVAL;
    1481                 :            : 
    1482                 :            :         /* Find device */
    1483                 :          0 :         bbdev = rte_bbdev_get_named_dev(pci_dev->device.name);
    1484         [ #  # ]:          0 :         if (bbdev == NULL) {
    1485                 :          0 :                 rte_acc_log(CRIT,
    1486                 :            :                                 "Couldn't find HW dev \"%s\" to uninitialise it",
    1487                 :            :                                 pci_dev->device.name);
    1488                 :          0 :                 return -ENODEV;
    1489                 :            :         }
    1490                 :          0 :         dev_id = bbdev->data->dev_id;
    1491                 :            : 
    1492                 :            :         /* free device private memory before close */
    1493                 :          0 :         rte_free(bbdev->data->dev_private);
    1494                 :            : 
    1495                 :            :         /* Close device */
    1496                 :          0 :         ret = rte_bbdev_close(dev_id);
    1497         [ #  # ]:          0 :         if (ret < 0)
    1498                 :          0 :                 rte_acc_log(ERR,
    1499                 :            :                                 "Device %i failed to close during uninit: %i",
    1500                 :            :                                 dev_id, ret);
    1501                 :            : 
    1502                 :            :         /* release bbdev from library */
    1503                 :          0 :         rte_bbdev_release(bbdev);
    1504                 :            : 
    1505                 :          0 :         return 0;
    1506                 :            : }
    1507                 :            : 
    1508                 :            : static inline void
    1509                 :          0 : acc_enqueue_status(struct rte_bbdev_queue_data *q_data,
    1510                 :            :                 enum rte_bbdev_enqueue_status status)
    1511                 :            : {
    1512                 :          0 :         q_data->enqueue_status = status;
    1513                 :          0 :         q_data->queue_stats.enqueue_status_count[status]++;
    1514                 :            : 
    1515                 :          0 :         rte_acc_log(WARNING, "Enqueue Status: %s %#"PRIx64"",
    1516                 :            :                         rte_bbdev_enqueue_status_str(status),
    1517                 :            :                         q_data->queue_stats.enqueue_status_count[status]);
    1518                 :          0 : }
    1519                 :            : 
    1520                 :            : static inline void
    1521                 :            : acc_enqueue_invalid(struct rte_bbdev_queue_data *q_data)
    1522                 :            : {
    1523                 :          0 :         acc_enqueue_status(q_data, RTE_BBDEV_ENQ_STATUS_INVALID_OP);
    1524                 :          0 : }
    1525                 :            : 
    1526                 :            : static inline void
    1527                 :            : acc_enqueue_ring_full(struct rte_bbdev_queue_data *q_data)
    1528                 :            : {
    1529                 :          0 :         acc_enqueue_status(q_data, RTE_BBDEV_ENQ_STATUS_RING_FULL);
    1530                 :          0 : }
    1531                 :            : 
    1532                 :            : static inline void
    1533                 :            : acc_enqueue_queue_full(struct rte_bbdev_queue_data *q_data)
    1534                 :            : {
    1535                 :          0 :         acc_enqueue_status(q_data, RTE_BBDEV_ENQ_STATUS_QUEUE_FULL);
    1536                 :          0 : }
    1537                 :            : 
    1538                 :            : /* Number of available descriptor in ring to enqueue */
    1539                 :            : static inline uint32_t
    1540                 :            : acc_ring_avail_enq(struct acc_queue *q)
    1541                 :            : {
    1542                 :          0 :         return (q->sw_ring_depth - 1 + q->sw_ring_tail - q->sw_ring_head) & q->sw_ring_wrap_mask;
    1543                 :            : }
    1544                 :            : 
    1545                 :            : /* Number of available descriptor in ring to dequeue */
    1546                 :            : static inline uint32_t
    1547                 :            : acc_ring_avail_deq(struct acc_queue *q)
    1548                 :            : {
    1549   [ #  #  #  # ]:          0 :         return (q->sw_ring_depth + q->sw_ring_head - q->sw_ring_tail) & q->sw_ring_wrap_mask;
    1550                 :            : }
    1551                 :            : 
    1552                 :            : /* Check room in AQ for the enqueues batches into Qmgr */
    1553                 :            : static inline int32_t
    1554                 :          0 : acc_aq_avail(struct rte_bbdev_queue_data *q_data, uint16_t num_ops)
    1555                 :            : {
    1556                 :          0 :         struct acc_queue *q = q_data->queue_private;
    1557                 :          0 :         int32_t aq_avail = q->aq_depth -
    1558                 :          0 :                         ((q->aq_enqueued - q->aq_dequeued +
    1559                 :          0 :                         ACC_MAX_QUEUE_DEPTH) % ACC_MAX_QUEUE_DEPTH)
    1560                 :          0 :                         - (num_ops >> 7);
    1561         [ #  # ]:          0 :         if (aq_avail <= 0)
    1562                 :            :                 acc_enqueue_queue_full(q_data);
    1563                 :          0 :         return aq_avail;
    1564                 :            : }
    1565                 :            : 
    1566                 :            : /* Update queue stats during enqueue. */
    1567                 :            : static inline void
    1568                 :            : acc_update_qstat_enqueue(struct rte_bbdev_queue_data *q_data,
    1569                 :            :                 uint16_t enq_count, uint16_t enq_err_count)
    1570                 :            : {
    1571                 :          0 :         q_data->queue_stats.enqueued_count += enq_count;
    1572                 :          0 :         q_data->queue_stats.enqueue_err_count += enq_err_count;
    1573                 :          0 :         q_data->queue_stats.enqueue_depth_avail = acc_aq_avail(q_data, 0);
    1574                 :            : }
    1575                 :            : 
    1576                 :            : /* Update queue stats during dequeue. */
    1577                 :            : static inline void
    1578                 :            : acc_update_qstat_dequeue(struct rte_bbdev_queue_data *q_data, uint16_t deq_count)
    1579                 :            : {
    1580                 :          0 :         q_data->queue_stats.dequeued_count += deq_count;
    1581                 :          0 :         q_data->queue_stats.enqueue_depth_avail = acc_aq_avail(q_data, 0);
    1582                 :            : }
    1583                 :            : 
    1584                 :            : /* Calculates number of CBs in processed encoder TB based on 'r' and input
    1585                 :            :  * length.
    1586                 :            :  */
    1587                 :            : static inline uint8_t
    1588                 :          0 : get_num_cbs_in_tb_ldpc_enc(struct rte_bbdev_op_ldpc_enc *ldpc_enc)
    1589                 :            : {
    1590                 :            :         uint8_t c, r, crc24_bits = 0;
    1591                 :          0 :         uint16_t k = (ldpc_enc->basegraph == 1 ? 22 : 10) * ldpc_enc->z_c
    1592         [ #  # ]:          0 :                 - ldpc_enc->n_filler;
    1593                 :            :         uint8_t cbs_in_tb = 0;
    1594                 :            :         int32_t length;
    1595                 :            : 
    1596                 :          0 :         length = ldpc_enc->input.length;
    1597                 :          0 :         r = ldpc_enc->tb_params.r;
    1598                 :          0 :         c = ldpc_enc->tb_params.c;
    1599                 :            :         crc24_bits = 0;
    1600         [ #  # ]:          0 :         if (check_bit(ldpc_enc->op_flags, RTE_BBDEV_LDPC_CRC_24B_ATTACH))
    1601                 :            :                 crc24_bits = 24;
    1602         [ #  # ]:          0 :         while (length > 0 && r < c) {
    1603                 :          0 :                 length -= (k - crc24_bits) >> 3;
    1604                 :          0 :                 r++;
    1605                 :          0 :                 cbs_in_tb++;
    1606                 :            :         }
    1607                 :          0 :         return cbs_in_tb;
    1608                 :            : }
    1609                 :            : 
    1610                 :            : static inline void
    1611                 :            : acc_reg_fast_write(struct acc_device *d, uint32_t offset, uint32_t value)
    1612                 :            : {
    1613                 :          0 :         void *reg_addr = RTE_PTR_ADD(d->mmio_base, offset);
    1614                 :            :         mmio_write(reg_addr, value);
    1615                 :            : }
    1616                 :            : 
    1617                 :            : #endif /* _ACC_COMMON_H_ */

Generated by: LCOV version 1.14