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_ */
|