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