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