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