examples/ipsec-secgw: remove limitation for crypto sessions
[dpdk.git] / drivers / baseband / fpga_5gnr_fec / rte_fpga_5gnr_fec.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Intel Corporation
3  */
4
5 #include <unistd.h>
6
7 #include <rte_common.h>
8 #include <rte_log.h>
9 #include <rte_dev.h>
10 #include <rte_malloc.h>
11 #include <rte_mempool.h>
12 #include <rte_errno.h>
13 #include <rte_pci.h>
14 #include <rte_bus_pci.h>
15 #include <rte_byteorder.h>
16 #ifdef RTE_BBDEV_OFFLOAD_COST
17 #include <rte_cycles.h>
18 #endif
19
20 #include <rte_bbdev.h>
21 #include <rte_bbdev_pmd.h>
22
23 #include "fpga_5gnr_fec.h"
24 #include "rte_pmd_fpga_5gnr_fec.h"
25
26 /* 5GNR SW PMD logging ID */
27 static int fpga_5gnr_fec_logtype;
28
29 #ifdef RTE_LIBRTE_BBDEV_DEBUG
30
31 /* Read Ring Control Register of FPGA 5GNR FEC device */
32 static inline void
33 print_ring_reg_debug_info(void *mmio_base, uint32_t offset)
34 {
35         rte_bbdev_log_debug(
36                 "FPGA MMIO base address @ %p | Ring Control Register @ offset = 0x%08"
37                 PRIx32, mmio_base, offset);
38         rte_bbdev_log_debug(
39                 "RING_BASE_ADDR = 0x%016"PRIx64,
40                 fpga_reg_read_64(mmio_base, offset));
41         rte_bbdev_log_debug(
42                 "RING_HEAD_ADDR = 0x%016"PRIx64,
43                 fpga_reg_read_64(mmio_base, offset +
44                                 FPGA_5GNR_FEC_RING_HEAD_ADDR));
45         rte_bbdev_log_debug(
46                 "RING_SIZE = 0x%04"PRIx16,
47                 fpga_reg_read_16(mmio_base, offset +
48                                 FPGA_5GNR_FEC_RING_SIZE));
49         rte_bbdev_log_debug(
50                 "RING_MISC = 0x%02"PRIx8,
51                 fpga_reg_read_8(mmio_base, offset +
52                                 FPGA_5GNR_FEC_RING_MISC));
53         rte_bbdev_log_debug(
54                 "RING_ENABLE = 0x%02"PRIx8,
55                 fpga_reg_read_8(mmio_base, offset +
56                                 FPGA_5GNR_FEC_RING_ENABLE));
57         rte_bbdev_log_debug(
58                 "RING_FLUSH_QUEUE_EN = 0x%02"PRIx8,
59                 fpga_reg_read_8(mmio_base, offset +
60                                 FPGA_5GNR_FEC_RING_FLUSH_QUEUE_EN));
61         rte_bbdev_log_debug(
62                 "RING_SHADOW_TAIL = 0x%04"PRIx16,
63                 fpga_reg_read_16(mmio_base, offset +
64                                 FPGA_5GNR_FEC_RING_SHADOW_TAIL));
65         rte_bbdev_log_debug(
66                 "RING_HEAD_POINT = 0x%04"PRIx16,
67                 fpga_reg_read_16(mmio_base, offset +
68                                 FPGA_5GNR_FEC_RING_HEAD_POINT));
69 }
70
71 /* Read Static Register of FPGA 5GNR FEC device */
72 static inline void
73 print_static_reg_debug_info(void *mmio_base)
74 {
75         uint16_t config = fpga_reg_read_16(mmio_base,
76                         FPGA_5GNR_FEC_CONFIGURATION);
77         uint8_t qmap_done = fpga_reg_read_8(mmio_base,
78                         FPGA_5GNR_FEC_QUEUE_PF_VF_MAP_DONE);
79         uint16_t lb_factor = fpga_reg_read_16(mmio_base,
80                         FPGA_5GNR_FEC_LOAD_BALANCE_FACTOR);
81         uint16_t ring_desc_len = fpga_reg_read_16(mmio_base,
82                         FPGA_5GNR_FEC_RING_DESC_LEN);
83         uint16_t flr_time_out = fpga_reg_read_16(mmio_base,
84                         FPGA_5GNR_FEC_FLR_TIME_OUT);
85
86         rte_bbdev_log_debug("UL.DL Weights = %u.%u",
87                         ((uint8_t)config), ((uint8_t)(config >> 8)));
88         rte_bbdev_log_debug("UL.DL Load Balance = %u.%u",
89                         ((uint8_t)lb_factor), ((uint8_t)(lb_factor >> 8)));
90         rte_bbdev_log_debug("Queue-PF/VF Mapping Table = %s",
91                         (qmap_done > 0) ? "READY" : "NOT-READY");
92         rte_bbdev_log_debug("Ring Descriptor Size = %u bytes",
93                         ring_desc_len*FPGA_RING_DESC_LEN_UNIT_BYTES);
94         rte_bbdev_log_debug("FLR Timeout = %f usec",
95                         (float)flr_time_out*FPGA_FLR_TIMEOUT_UNIT);
96 }
97
98 /* Print decode DMA Descriptor of FPGA 5GNR Decoder device */
99 static void
100 print_dma_dec_desc_debug_info(union fpga_dma_desc *desc)
101 {
102         rte_bbdev_log_debug("DMA response desc %p\n"
103                 "\t-- done(%"PRIu32") | iter(%"PRIu32") | et_pass(%"PRIu32")"
104                 " | crcb_pass (%"PRIu32") | error(%"PRIu32")\n"
105                 "\t-- qm_idx(%"PRIu32") | max_iter(%"PRIu32") | "
106                 "bg_idx (%"PRIu32") | harqin_en(%"PRIu32") | zc(%"PRIu32")\n"
107                 "\t-- hbstroe_offset(%"PRIu32") | num_null (%"PRIu32") "
108                 "| irq_en(%"PRIu32")\n"
109                 "\t-- ncb(%"PRIu32") | desc_idx (%"PRIu32") | "
110                 "drop_crc24b(%"PRIu32") | RV (%"PRIu32")\n"
111                 "\t-- crc24b_ind(%"PRIu32") | et_dis (%"PRIu32")\n"
112                 "\t-- harq_input_length(%"PRIu32") | rm_e(%"PRIu32")\n"
113                 "\t-- cbs_in_op(%"PRIu32") | in_add (0x%08"PRIx32"%08"PRIx32")"
114                 "| out_add (0x%08"PRIx32"%08"PRIx32")",
115                 desc,
116                 (uint32_t)desc->dec_req.done,
117                 (uint32_t)desc->dec_req.iter,
118                 (uint32_t)desc->dec_req.et_pass,
119                 (uint32_t)desc->dec_req.crcb_pass,
120                 (uint32_t)desc->dec_req.error,
121                 (uint32_t)desc->dec_req.qm_idx,
122                 (uint32_t)desc->dec_req.max_iter,
123                 (uint32_t)desc->dec_req.bg_idx,
124                 (uint32_t)desc->dec_req.harqin_en,
125                 (uint32_t)desc->dec_req.zc,
126                 (uint32_t)desc->dec_req.hbstroe_offset,
127                 (uint32_t)desc->dec_req.num_null,
128                 (uint32_t)desc->dec_req.irq_en,
129                 (uint32_t)desc->dec_req.ncb,
130                 (uint32_t)desc->dec_req.desc_idx,
131                 (uint32_t)desc->dec_req.drop_crc24b,
132                 (uint32_t)desc->dec_req.rv,
133                 (uint32_t)desc->dec_req.crc24b_ind,
134                 (uint32_t)desc->dec_req.et_dis,
135                 (uint32_t)desc->dec_req.harq_input_length,
136                 (uint32_t)desc->dec_req.rm_e,
137                 (uint32_t)desc->dec_req.cbs_in_op,
138                 (uint32_t)desc->dec_req.in_addr_hi,
139                 (uint32_t)desc->dec_req.in_addr_lw,
140                 (uint32_t)desc->dec_req.out_addr_hi,
141                 (uint32_t)desc->dec_req.out_addr_lw);
142         uint32_t *word = (uint32_t *) desc;
143         rte_bbdev_log_debug("%08"PRIx32"\n%08"PRIx32"\n%08"PRIx32"\n%08"PRIx32"\n"
144                         "%08"PRIx32"\n%08"PRIx32"\n%08"PRIx32"\n%08"PRIx32"\n",
145                         word[0], word[1], word[2], word[3],
146                         word[4], word[5], word[6], word[7]);
147 }
148
149 /* Print decode DMA Descriptor of FPGA 5GNR encoder device */
150 static void
151 print_dma_enc_desc_debug_info(union fpga_dma_desc *desc)
152 {
153         rte_bbdev_log_debug("DMA response desc %p\n"
154                         "%"PRIu32" %"PRIu32"\n"
155                         "K' %"PRIu32" E %"PRIu32" desc %"PRIu32" Z %"PRIu32"\n"
156                         "BG %"PRIu32" Qm %"PRIu32" CRC %"PRIu32" IRQ %"PRIu32"\n"
157                         "k0 %"PRIu32" Ncb %"PRIu32" F %"PRIu32"\n",
158                         desc,
159                         (uint32_t)desc->enc_req.done,
160                         (uint32_t)desc->enc_req.error,
161
162                         (uint32_t)desc->enc_req.k_,
163                         (uint32_t)desc->enc_req.rm_e,
164                         (uint32_t)desc->enc_req.desc_idx,
165                         (uint32_t)desc->enc_req.zc,
166
167                         (uint32_t)desc->enc_req.bg_idx,
168                         (uint32_t)desc->enc_req.qm_idx,
169                         (uint32_t)desc->enc_req.crc_en,
170                         (uint32_t)desc->enc_req.irq_en,
171
172                         (uint32_t)desc->enc_req.k0,
173                         (uint32_t)desc->enc_req.ncb,
174                         (uint32_t)desc->enc_req.num_null);
175         uint32_t *word = (uint32_t *) desc;
176         rte_bbdev_log_debug("%08"PRIx32"\n%08"PRIx32"\n%08"PRIx32"\n%08"PRIx32"\n"
177                         "%08"PRIx32"\n%08"PRIx32"\n%08"PRIx32"\n%08"PRIx32"\n",
178                         word[0], word[1], word[2], word[3],
179                         word[4], word[5], word[6], word[7]);
180 }
181
182 #endif
183
184 static int
185 fpga_setup_queues(struct rte_bbdev *dev, uint16_t num_queues, int socket_id)
186 {
187         /* Number of queues bound to a PF/VF */
188         uint32_t hw_q_num = 0;
189         uint32_t ring_size, payload, address, q_id, offset;
190         rte_iova_t phys_addr;
191         struct fpga_ring_ctrl_reg ring_reg;
192         struct fpga_5gnr_fec_device *fpga_dev = dev->data->dev_private;
193
194         address = FPGA_5GNR_FEC_QUEUE_PF_VF_MAP_DONE;
195         if (!(fpga_reg_read_32(fpga_dev->mmio_base, address) & 0x1)) {
196                 rte_bbdev_log(ERR,
197                                 "Queue-PF/VF mapping is not set! Was PF configured for device (%s) ?",
198                                 dev->data->name);
199                 return -EPERM;
200         }
201
202         /* Clear queue registers structure */
203         memset(&ring_reg, 0, sizeof(struct fpga_ring_ctrl_reg));
204
205         /* Scan queue map.
206          * If a queue is valid and mapped to a calling PF/VF the read value is
207          * replaced with a queue ID and if it's not then
208          * FPGA_INVALID_HW_QUEUE_ID is returned.
209          */
210         for (q_id = 0; q_id < FPGA_TOTAL_NUM_QUEUES; ++q_id) {
211                 uint32_t hw_q_id = fpga_reg_read_32(fpga_dev->mmio_base,
212                                 FPGA_5GNR_FEC_QUEUE_MAP + (q_id << 2));
213
214                 rte_bbdev_log_debug("%s: queue ID: %u, registry queue ID: %u",
215                                 dev->device->name, q_id, hw_q_id);
216
217                 if (hw_q_id != FPGA_INVALID_HW_QUEUE_ID) {
218                         fpga_dev->q_bound_bit_map |= (1ULL << q_id);
219                         /* Clear queue register of found queue */
220                         offset = FPGA_5GNR_FEC_RING_CTRL_REGS +
221                                 (sizeof(struct fpga_ring_ctrl_reg) * q_id);
222                         fpga_ring_reg_write(fpga_dev->mmio_base,
223                                         offset, ring_reg);
224                         ++hw_q_num;
225                 }
226         }
227         if (hw_q_num == 0) {
228                 rte_bbdev_log(ERR,
229                         "No HW queues assigned to this device. Probably this is a VF configured for PF mode. Check device configuration!");
230                 return -ENODEV;
231         }
232
233         if (num_queues > hw_q_num) {
234                 rte_bbdev_log(ERR,
235                         "Not enough queues for device %s! Requested: %u, available: %u",
236                         dev->device->name, num_queues, hw_q_num);
237                 return -EINVAL;
238         }
239
240         ring_size = FPGA_RING_MAX_SIZE * sizeof(struct fpga_dma_dec_desc);
241
242         /* Enforce 32 byte alignment */
243         RTE_BUILD_BUG_ON((RTE_CACHE_LINE_SIZE % 32) != 0);
244
245         /* Allocate memory for SW descriptor rings */
246         fpga_dev->sw_rings = rte_zmalloc_socket(dev->device->driver->name,
247                         num_queues * ring_size, RTE_CACHE_LINE_SIZE,
248                         socket_id);
249         if (fpga_dev->sw_rings == NULL) {
250                 rte_bbdev_log(ERR,
251                                 "Failed to allocate memory for %s:%u sw_rings",
252                                 dev->device->driver->name, dev->data->dev_id);
253                 return -ENOMEM;
254         }
255
256         fpga_dev->sw_rings_phys = rte_malloc_virt2iova(fpga_dev->sw_rings);
257         fpga_dev->sw_ring_size = ring_size;
258         fpga_dev->sw_ring_max_depth = FPGA_RING_MAX_SIZE;
259
260         /* Allocate memory for ring flush status */
261         fpga_dev->flush_queue_status = rte_zmalloc_socket(NULL,
262                         sizeof(uint64_t), RTE_CACHE_LINE_SIZE, socket_id);
263         if (fpga_dev->flush_queue_status == NULL) {
264                 rte_bbdev_log(ERR,
265                                 "Failed to allocate memory for %s:%u flush_queue_status",
266                                 dev->device->driver->name, dev->data->dev_id);
267                 return -ENOMEM;
268         }
269
270         /* Set the flush status address registers */
271         phys_addr = rte_malloc_virt2iova(fpga_dev->flush_queue_status);
272
273         address = FPGA_5GNR_FEC_VFQ_FLUSH_STATUS_LW;
274         payload = (uint32_t)(phys_addr);
275         fpga_reg_write_32(fpga_dev->mmio_base, address, payload);
276
277         address = FPGA_5GNR_FEC_VFQ_FLUSH_STATUS_HI;
278         payload = (uint32_t)(phys_addr >> 32);
279         fpga_reg_write_32(fpga_dev->mmio_base, address, payload);
280
281         return 0;
282 }
283
284 static int
285 fpga_dev_close(struct rte_bbdev *dev)
286 {
287         struct fpga_5gnr_fec_device *fpga_dev = dev->data->dev_private;
288
289         rte_free(fpga_dev->sw_rings);
290         rte_free(fpga_dev->flush_queue_status);
291
292         return 0;
293 }
294
295 static void
296 fpga_dev_info_get(struct rte_bbdev *dev,
297                 struct rte_bbdev_driver_info *dev_info)
298 {
299         struct fpga_5gnr_fec_device *d = dev->data->dev_private;
300         uint32_t q_id = 0;
301
302         static const struct rte_bbdev_op_cap bbdev_capabilities[] = {
303                 {
304                         .type   = RTE_BBDEV_OP_LDPC_ENC,
305                         .cap.ldpc_enc = {
306                                 .capability_flags =
307                                                 RTE_BBDEV_LDPC_RATE_MATCH |
308                                                 RTE_BBDEV_LDPC_ENC_INTERRUPTS |
309                                                 RTE_BBDEV_LDPC_CRC_24B_ATTACH,
310                                 .num_buffers_src =
311                                                 RTE_BBDEV_LDPC_MAX_CODE_BLOCKS,
312                                 .num_buffers_dst =
313                                                 RTE_BBDEV_LDPC_MAX_CODE_BLOCKS,
314                         }
315                 },
316                 {
317                 .type   = RTE_BBDEV_OP_LDPC_DEC,
318                 .cap.ldpc_dec = {
319                         .capability_flags =
320                                 RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK |
321                                 RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP |
322                                 RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE |
323                                 RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE |
324                                 RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE |
325                                 RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE |
326                                 RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE |
327                                 RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK |
328                                 RTE_BBDEV_LDPC_DEC_INTERRUPTS |
329                                 RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_FILLERS,
330                         .llr_size = 6,
331                         .llr_decimals = 2,
332                         .num_buffers_src =
333                                         RTE_BBDEV_LDPC_MAX_CODE_BLOCKS,
334                         .num_buffers_hard_out =
335                                         RTE_BBDEV_LDPC_MAX_CODE_BLOCKS,
336                         .num_buffers_soft_out = 0,
337                 }
338                 },
339                 RTE_BBDEV_END_OF_CAPABILITIES_LIST()
340         };
341
342         /* Check the HARQ DDR size available */
343         uint8_t timeout_counter = 0;
344         uint32_t harq_buf_ready = fpga_reg_read_32(d->mmio_base,
345                         FPGA_5GNR_FEC_HARQ_BUF_SIZE_RDY_REGS);
346         while (harq_buf_ready != 1) {
347                 usleep(FPGA_TIMEOUT_CHECK_INTERVAL);
348                 timeout_counter++;
349                 harq_buf_ready = fpga_reg_read_32(d->mmio_base,
350                                 FPGA_5GNR_FEC_HARQ_BUF_SIZE_RDY_REGS);
351                 if (timeout_counter > FPGA_HARQ_RDY_TIMEOUT) {
352                         rte_bbdev_log(ERR, "HARQ Buffer not ready %d",
353                                         harq_buf_ready);
354                         harq_buf_ready = 1;
355                 }
356         }
357         uint32_t harq_buf_size = fpga_reg_read_32(d->mmio_base,
358                         FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);
359
360         static struct rte_bbdev_queue_conf default_queue_conf;
361         default_queue_conf.socket = dev->data->socket_id;
362         default_queue_conf.queue_size = FPGA_RING_MAX_SIZE;
363
364         dev_info->driver_name = dev->device->driver->name;
365         dev_info->queue_size_lim = FPGA_RING_MAX_SIZE;
366         dev_info->hardware_accelerated = true;
367         dev_info->min_alignment = 64;
368         dev_info->harq_buffer_size = (harq_buf_size >> 10) + 1;
369         dev_info->default_queue_conf = default_queue_conf;
370         dev_info->capabilities = bbdev_capabilities;
371         dev_info->cpu_flag_reqs = NULL;
372
373         /* Calculates number of queues assigned to device */
374         dev_info->max_num_queues = 0;
375         for (q_id = 0; q_id < FPGA_TOTAL_NUM_QUEUES; ++q_id) {
376                 uint32_t hw_q_id = fpga_reg_read_32(d->mmio_base,
377                                 FPGA_5GNR_FEC_QUEUE_MAP + (q_id << 2));
378                 if (hw_q_id != FPGA_INVALID_HW_QUEUE_ID)
379                         dev_info->max_num_queues++;
380         }
381 }
382
383 /**
384  * Find index of queue bound to current PF/VF which is unassigned. Return -1
385  * when there is no available queue
386  */
387 static inline int
388 fpga_find_free_queue_idx(struct rte_bbdev *dev,
389                 const struct rte_bbdev_queue_conf *conf)
390 {
391         struct fpga_5gnr_fec_device *d = dev->data->dev_private;
392         uint64_t q_idx;
393         uint8_t i = 0;
394         uint8_t range = FPGA_TOTAL_NUM_QUEUES >> 1;
395
396         if (conf->op_type == RTE_BBDEV_OP_LDPC_ENC) {
397                 i = FPGA_NUM_DL_QUEUES;
398                 range = FPGA_TOTAL_NUM_QUEUES;
399         }
400
401         for (; i < range; ++i) {
402                 q_idx = 1ULL << i;
403                 /* Check if index of queue is bound to current PF/VF */
404                 if (d->q_bound_bit_map & q_idx)
405                         /* Check if found queue was not already assigned */
406                         if (!(d->q_assigned_bit_map & q_idx)) {
407                                 d->q_assigned_bit_map |= q_idx;
408                                 return i;
409                         }
410         }
411
412         rte_bbdev_log(INFO, "Failed to find free queue on %s", dev->data->name);
413
414         return -1;
415 }
416
417 static int
418 fpga_queue_setup(struct rte_bbdev *dev, uint16_t queue_id,
419                 const struct rte_bbdev_queue_conf *conf)
420 {
421         uint32_t address, ring_offset;
422         struct fpga_5gnr_fec_device *d = dev->data->dev_private;
423         struct fpga_queue *q;
424         int8_t q_idx;
425
426         /* Check if there is a free queue to assign */
427         q_idx = fpga_find_free_queue_idx(dev, conf);
428         if (q_idx == -1)
429                 return -1;
430
431         /* Allocate the queue data structure. */
432         q = rte_zmalloc_socket(dev->device->driver->name, sizeof(*q),
433                         RTE_CACHE_LINE_SIZE, conf->socket);
434         if (q == NULL) {
435                 /* Mark queue as un-assigned */
436                 d->q_assigned_bit_map &= (0xFFFFFFFF - (1ULL << q_idx));
437                 rte_bbdev_log(ERR, "Failed to allocate queue memory");
438                 return -ENOMEM;
439         }
440
441         q->d = d;
442         q->q_idx = q_idx;
443
444         /* Set ring_base_addr */
445         q->ring_addr = RTE_PTR_ADD(d->sw_rings, (d->sw_ring_size * queue_id));
446         q->ring_ctrl_reg.ring_base_addr = d->sw_rings_phys +
447                         (d->sw_ring_size * queue_id);
448
449         /* Allocate memory for Completion Head variable*/
450         q->ring_head_addr = rte_zmalloc_socket(dev->device->driver->name,
451                         sizeof(uint64_t), RTE_CACHE_LINE_SIZE, conf->socket);
452         if (q->ring_head_addr == NULL) {
453                 /* Mark queue as un-assigned */
454                 d->q_assigned_bit_map &= (0xFFFFFFFF - (1ULL << q_idx));
455                 rte_free(q);
456                 rte_bbdev_log(ERR,
457                                 "Failed to allocate memory for %s:%u completion_head",
458                                 dev->device->driver->name, dev->data->dev_id);
459                 return -ENOMEM;
460         }
461         /* Set ring_head_addr */
462         q->ring_ctrl_reg.ring_head_addr =
463                         rte_malloc_virt2iova(q->ring_head_addr);
464
465         /* Clear shadow_completion_head */
466         q->shadow_completion_head = 0;
467
468         /* Set ring_size */
469         if (conf->queue_size > FPGA_RING_MAX_SIZE) {
470                 /* Mark queue as un-assigned */
471                 d->q_assigned_bit_map &= (0xFFFFFFFF - (1ULL << q_idx));
472                 rte_free(q->ring_head_addr);
473                 rte_free(q);
474                 rte_bbdev_log(ERR,
475                                 "Size of queue is too big %d (MAX: %d ) for %s:%u",
476                                 conf->queue_size, FPGA_RING_MAX_SIZE,
477                                 dev->device->driver->name, dev->data->dev_id);
478                 return -EINVAL;
479         }
480         q->ring_ctrl_reg.ring_size = conf->queue_size;
481
482         /* Set Miscellaneous FPGA register*/
483         /* Max iteration number for TTI mitigation - todo */
484         q->ring_ctrl_reg.max_ul_dec = 0;
485         /* Enable max iteration number for TTI - todo */
486         q->ring_ctrl_reg.max_ul_dec_en = 0;
487
488         /* Enable the ring */
489         q->ring_ctrl_reg.enable = 1;
490
491         /* Set FPGA head_point and tail registers */
492         q->ring_ctrl_reg.head_point = q->tail = 0;
493
494         /* Set FPGA shadow_tail register */
495         q->ring_ctrl_reg.shadow_tail = q->tail;
496
497         /* Calculates the ring offset for found queue */
498         ring_offset = FPGA_5GNR_FEC_RING_CTRL_REGS +
499                         (sizeof(struct fpga_ring_ctrl_reg) * q_idx);
500
501         /* Set FPGA Ring Control Registers */
502         fpga_ring_reg_write(d->mmio_base, ring_offset, q->ring_ctrl_reg);
503
504         /* Store MMIO register of shadow_tail */
505         address = ring_offset + FPGA_5GNR_FEC_RING_SHADOW_TAIL;
506         q->shadow_tail_addr = RTE_PTR_ADD(d->mmio_base, address);
507
508         q->head_free_desc = q->tail;
509
510         /* Set wrap mask */
511         q->sw_ring_wrap_mask = conf->queue_size - 1;
512
513         rte_bbdev_log_debug("Setup dev%u q%u: queue_idx=%u",
514                         dev->data->dev_id, queue_id, q->q_idx);
515
516         dev->data->queues[queue_id].queue_private = q;
517
518         rte_bbdev_log_debug("BBDEV queue[%d] set up for FPGA queue[%d]",
519                         queue_id, q_idx);
520
521 #ifdef RTE_LIBRTE_BBDEV_DEBUG
522         /* Read FPGA Ring Control Registers after configuration*/
523         print_ring_reg_debug_info(d->mmio_base, ring_offset);
524 #endif
525         return 0;
526 }
527
528 static int
529 fpga_queue_release(struct rte_bbdev *dev, uint16_t queue_id)
530 {
531         struct fpga_5gnr_fec_device *d = dev->data->dev_private;
532         struct fpga_queue *q = dev->data->queues[queue_id].queue_private;
533         struct fpga_ring_ctrl_reg ring_reg;
534         uint32_t offset;
535
536         rte_bbdev_log_debug("FPGA Queue[%d] released", queue_id);
537
538         if (q != NULL) {
539                 memset(&ring_reg, 0, sizeof(struct fpga_ring_ctrl_reg));
540                 offset = FPGA_5GNR_FEC_RING_CTRL_REGS +
541                         (sizeof(struct fpga_ring_ctrl_reg) * q->q_idx);
542                 /* Disable queue */
543                 fpga_reg_write_8(d->mmio_base,
544                                 offset + FPGA_5GNR_FEC_RING_ENABLE, 0x00);
545                 /* Clear queue registers */
546                 fpga_ring_reg_write(d->mmio_base, offset, ring_reg);
547
548                 /* Mark the Queue as un-assigned */
549                 d->q_assigned_bit_map &= (0xFFFFFFFF - (1ULL << q->q_idx));
550                 rte_free(q->ring_head_addr);
551                 rte_free(q);
552                 dev->data->queues[queue_id].queue_private = NULL;
553         }
554
555         return 0;
556 }
557
558 /* Function starts a device queue. */
559 static int
560 fpga_queue_start(struct rte_bbdev *dev, uint16_t queue_id)
561 {
562         struct fpga_5gnr_fec_device *d = dev->data->dev_private;
563 #ifdef RTE_LIBRTE_BBDEV_DEBUG
564         if (d == NULL) {
565                 rte_bbdev_log(ERR, "Invalid device pointer");
566                 return -1;
567         }
568 #endif
569         struct fpga_queue *q = dev->data->queues[queue_id].queue_private;
570         uint32_t offset = FPGA_5GNR_FEC_RING_CTRL_REGS +
571                         (sizeof(struct fpga_ring_ctrl_reg) * q->q_idx);
572         uint8_t enable = 0x01;
573         uint16_t zero = 0x0000;
574
575         /* Clear queue head and tail variables */
576         q->tail = q->head_free_desc = 0;
577
578         /* Clear FPGA head_point and tail registers */
579         fpga_reg_write_16(d->mmio_base, offset + FPGA_5GNR_FEC_RING_HEAD_POINT,
580                         zero);
581         fpga_reg_write_16(d->mmio_base, offset + FPGA_5GNR_FEC_RING_SHADOW_TAIL,
582                         zero);
583
584         /* Enable queue */
585         fpga_reg_write_8(d->mmio_base, offset + FPGA_5GNR_FEC_RING_ENABLE,
586                         enable);
587
588         rte_bbdev_log_debug("FPGA Queue[%d] started", queue_id);
589         return 0;
590 }
591
592 /* Function stops a device queue. */
593 static int
594 fpga_queue_stop(struct rte_bbdev *dev, uint16_t queue_id)
595 {
596         struct fpga_5gnr_fec_device *d = dev->data->dev_private;
597 #ifdef RTE_LIBRTE_BBDEV_DEBUG
598         if (d == NULL) {
599                 rte_bbdev_log(ERR, "Invalid device pointer");
600                 return -1;
601         }
602 #endif
603         struct fpga_queue *q = dev->data->queues[queue_id].queue_private;
604         uint32_t offset = FPGA_5GNR_FEC_RING_CTRL_REGS +
605                         (sizeof(struct fpga_ring_ctrl_reg) * q->q_idx);
606         uint8_t payload = 0x01;
607         uint8_t counter = 0;
608         uint8_t timeout = FPGA_QUEUE_FLUSH_TIMEOUT_US /
609                         FPGA_TIMEOUT_CHECK_INTERVAL;
610
611         /* Set flush_queue_en bit to trigger queue flushing */
612         fpga_reg_write_8(d->mmio_base,
613                         offset + FPGA_5GNR_FEC_RING_FLUSH_QUEUE_EN, payload);
614
615         /** Check if queue flush is completed.
616          * FPGA will update the completion flag after queue flushing is
617          * completed. If completion flag is not updated within 1ms it is
618          * considered as a failure.
619          */
620         while (!(*((volatile uint8_t *)d->flush_queue_status + q->q_idx)
621                         & payload)) {
622                 if (counter > timeout) {
623                         rte_bbdev_log(ERR, "FPGA Queue Flush failed for queue %d",
624                                         queue_id);
625                         return -1;
626                 }
627                 usleep(FPGA_TIMEOUT_CHECK_INTERVAL);
628                 counter++;
629         }
630
631         /* Disable queue */
632         payload = 0x00;
633         fpga_reg_write_8(d->mmio_base, offset + FPGA_5GNR_FEC_RING_ENABLE,
634                         payload);
635
636         rte_bbdev_log_debug("FPGA Queue[%d] stopped", queue_id);
637         return 0;
638 }
639
640 static inline uint16_t
641 get_queue_id(struct rte_bbdev_data *data, uint8_t q_idx)
642 {
643         uint16_t queue_id;
644
645         for (queue_id = 0; queue_id < data->num_queues; ++queue_id) {
646                 struct fpga_queue *q = data->queues[queue_id].queue_private;
647                 if (q != NULL && q->q_idx == q_idx)
648                         return queue_id;
649         }
650
651         return -1;
652 }
653
654 /* Interrupt handler triggered by FPGA dev for handling specific interrupt */
655 static void
656 fpga_dev_interrupt_handler(void *cb_arg)
657 {
658         struct rte_bbdev *dev = cb_arg;
659         struct fpga_5gnr_fec_device *fpga_dev = dev->data->dev_private;
660         struct fpga_queue *q;
661         uint64_t ring_head;
662         uint64_t q_idx;
663         uint16_t queue_id;
664         uint8_t i;
665
666         /* Scan queue assigned to this device */
667         for (i = 0; i < FPGA_TOTAL_NUM_QUEUES; ++i) {
668                 q_idx = 1ULL << i;
669                 if (fpga_dev->q_bound_bit_map & q_idx) {
670                         queue_id = get_queue_id(dev->data, i);
671                         if (queue_id == (uint16_t) -1)
672                                 continue;
673
674                         /* Check if completion head was changed */
675                         q = dev->data->queues[queue_id].queue_private;
676                         ring_head = *q->ring_head_addr;
677                         if (q->shadow_completion_head != ring_head &&
678                                 q->irq_enable == 1) {
679                                 q->shadow_completion_head = ring_head;
680                                 rte_bbdev_pmd_callback_process(
681                                                 dev,
682                                                 RTE_BBDEV_EVENT_DEQUEUE,
683                                                 &queue_id);
684                         }
685                 }
686         }
687 }
688
689 static int
690 fpga_queue_intr_enable(struct rte_bbdev *dev, uint16_t queue_id)
691 {
692         struct fpga_queue *q = dev->data->queues[queue_id].queue_private;
693
694         if (!rte_intr_cap_multiple(dev->intr_handle))
695                 return -ENOTSUP;
696
697         q->irq_enable = 1;
698
699         return 0;
700 }
701
702 static int
703 fpga_queue_intr_disable(struct rte_bbdev *dev, uint16_t queue_id)
704 {
705         struct fpga_queue *q = dev->data->queues[queue_id].queue_private;
706         q->irq_enable = 0;
707
708         return 0;
709 }
710
711 static int
712 fpga_intr_enable(struct rte_bbdev *dev)
713 {
714         int ret;
715         uint8_t i;
716
717         if (!rte_intr_cap_multiple(dev->intr_handle)) {
718                 rte_bbdev_log(ERR, "Multiple intr vector is not supported by FPGA (%s)",
719                                 dev->data->name);
720                 return -ENOTSUP;
721         }
722
723         /* Create event file descriptors for each of 64 queue. Event fds will be
724          * mapped to FPGA IRQs in rte_intr_enable(). This is a 1:1 mapping where
725          * the IRQ number is a direct translation to the queue number.
726          *
727          * 63 (FPGA_NUM_INTR_VEC) event fds are created as rte_intr_enable()
728          * mapped the first IRQ to already created interrupt event file
729          * descriptor (intr_handle->fd).
730          */
731         if (rte_intr_efd_enable(dev->intr_handle, FPGA_NUM_INTR_VEC)) {
732                 rte_bbdev_log(ERR, "Failed to create fds for %u queues",
733                                 dev->data->num_queues);
734                 return -1;
735         }
736
737         /* TODO Each event file descriptor is overwritten by interrupt event
738          * file descriptor. That descriptor is added to epoll observed list.
739          * It ensures that callback function assigned to that descriptor will
740          * invoked when any FPGA queue issues interrupt.
741          */
742         for (i = 0; i < FPGA_NUM_INTR_VEC; ++i)
743                 dev->intr_handle->efds[i] = dev->intr_handle->fd;
744
745         if (!dev->intr_handle->intr_vec) {
746                 dev->intr_handle->intr_vec = rte_zmalloc("intr_vec",
747                                 dev->data->num_queues * sizeof(int), 0);
748                 if (!dev->intr_handle->intr_vec) {
749                         rte_bbdev_log(ERR, "Failed to allocate %u vectors",
750                                         dev->data->num_queues);
751                         return -ENOMEM;
752                 }
753         }
754
755         ret = rte_intr_enable(dev->intr_handle);
756         if (ret < 0) {
757                 rte_bbdev_log(ERR,
758                                 "Couldn't enable interrupts for device: %s",
759                                 dev->data->name);
760                 return ret;
761         }
762
763         ret = rte_intr_callback_register(dev->intr_handle,
764                         fpga_dev_interrupt_handler, dev);
765         if (ret < 0) {
766                 rte_bbdev_log(ERR,
767                                 "Couldn't register interrupt callback for device: %s",
768                                 dev->data->name);
769                 return ret;
770         }
771
772         return 0;
773 }
774
775 static const struct rte_bbdev_ops fpga_ops = {
776         .setup_queues = fpga_setup_queues,
777         .intr_enable = fpga_intr_enable,
778         .close = fpga_dev_close,
779         .info_get = fpga_dev_info_get,
780         .queue_setup = fpga_queue_setup,
781         .queue_stop = fpga_queue_stop,
782         .queue_start = fpga_queue_start,
783         .queue_release = fpga_queue_release,
784         .queue_intr_enable = fpga_queue_intr_enable,
785         .queue_intr_disable = fpga_queue_intr_disable
786 };
787
788 static inline void
789 fpga_dma_enqueue(struct fpga_queue *q, uint16_t num_desc,
790                 struct rte_bbdev_stats *queue_stats)
791 {
792 #ifdef RTE_BBDEV_OFFLOAD_COST
793         uint64_t start_time = 0;
794         queue_stats->acc_offload_cycles = 0;
795 #else
796         RTE_SET_USED(queue_stats);
797 #endif
798
799         /* Update tail and shadow_tail register */
800         q->tail = (q->tail + num_desc) & q->sw_ring_wrap_mask;
801
802         rte_wmb();
803
804 #ifdef RTE_BBDEV_OFFLOAD_COST
805         /* Start time measurement for enqueue function offload. */
806         start_time = rte_rdtsc_precise();
807 #endif
808         mmio_write_16(q->shadow_tail_addr, q->tail);
809
810 #ifdef RTE_BBDEV_OFFLOAD_COST
811         rte_wmb();
812         queue_stats->acc_offload_cycles += rte_rdtsc_precise() - start_time;
813 #endif
814 }
815
816 /* Read flag value 0/1/ from bitmap */
817 static inline bool
818 check_bit(uint32_t bitmap, uint32_t bitmask)
819 {
820         return bitmap & bitmask;
821 }
822
823 /* Print an error if a descriptor error has occurred.
824  *  Return 0 on success, 1 on failure
825  */
826 static inline int
827 check_desc_error(uint32_t error_code) {
828         switch (error_code) {
829         case DESC_ERR_NO_ERR:
830                 return 0;
831         case DESC_ERR_K_P_OUT_OF_RANGE:
832                 rte_bbdev_log(ERR, "Encode block size K' is out of range");
833                 break;
834         case DESC_ERR_Z_C_NOT_LEGAL:
835                 rte_bbdev_log(ERR, "Zc is illegal");
836                 break;
837         case DESC_ERR_DESC_OFFSET_ERR:
838                 rte_bbdev_log(ERR,
839                                 "Queue offset does not meet the expectation in the FPGA"
840                                 );
841                 break;
842         case DESC_ERR_DESC_READ_FAIL:
843                 rte_bbdev_log(ERR, "Unsuccessful completion for descriptor read");
844                 break;
845         case DESC_ERR_DESC_READ_TIMEOUT:
846                 rte_bbdev_log(ERR, "Descriptor read time-out");
847                 break;
848         case DESC_ERR_DESC_READ_TLP_POISONED:
849                 rte_bbdev_log(ERR, "Descriptor read TLP poisoned");
850                 break;
851         case DESC_ERR_CB_READ_FAIL:
852                 rte_bbdev_log(ERR, "Unsuccessful completion for code block");
853                 break;
854         case DESC_ERR_CB_READ_TIMEOUT:
855                 rte_bbdev_log(ERR, "Code block read time-out");
856                 break;
857         case DESC_ERR_CB_READ_TLP_POISONED:
858                 rte_bbdev_log(ERR, "Code block read TLP poisoned");
859                 break;
860         case DESC_ERR_HBSTORE_ERR:
861                 rte_bbdev_log(ERR, "Hbstroe exceeds HARQ buffer size.");
862                 break;
863         default:
864                 rte_bbdev_log(ERR, "Descriptor error unknown error code %u",
865                                 error_code);
866                 break;
867         }
868         return 1;
869 }
870
871 /* Compute value of k0.
872  * Based on 3GPP 38.212 Table 5.4.2.1-2
873  * Starting position of different redundancy versions, k0
874  */
875 static inline uint16_t
876 get_k0(uint16_t n_cb, uint16_t z_c, uint8_t bg, uint8_t rv_index)
877 {
878         if (rv_index == 0)
879                 return 0;
880         uint16_t n = (bg == 1 ? N_ZC_1 : N_ZC_2) * z_c;
881         if (n_cb == n) {
882                 if (rv_index == 1)
883                         return (bg == 1 ? K0_1_1 : K0_1_2) * z_c;
884                 else if (rv_index == 2)
885                         return (bg == 1 ? K0_2_1 : K0_2_2) * z_c;
886                 else
887                         return (bg == 1 ? K0_3_1 : K0_3_2) * z_c;
888         }
889         /* LBRM case - includes a division by N */
890         if (rv_index == 1)
891                 return (((bg == 1 ? K0_1_1 : K0_1_2) * n_cb)
892                                 / n) * z_c;
893         else if (rv_index == 2)
894                 return (((bg == 1 ? K0_2_1 : K0_2_2) * n_cb)
895                                 / n) * z_c;
896         else
897                 return (((bg == 1 ? K0_3_1 : K0_3_2) * n_cb)
898                                 / n) * z_c;
899 }
900
901 /**
902  * Set DMA descriptor for encode operation (1 Code Block)
903  *
904  * @param op
905  *   Pointer to a single encode operation.
906  * @param desc
907  *   Pointer to DMA descriptor.
908  * @param input
909  *   Pointer to pointer to input data which will be decoded.
910  * @param e
911  *   E value (length of output in bits).
912  * @param ncb
913  *   Ncb value (size of the soft buffer).
914  * @param out_length
915  *   Length of output buffer
916  * @param in_offset
917  *   Input offset in rte_mbuf structure. It is used for calculating the point
918  *   where data is starting.
919  * @param out_offset
920  *   Output offset in rte_mbuf structure. It is used for calculating the point
921  *   where hard output data will be stored.
922  * @param cbs_in_op
923  *   Number of CBs contained in one operation.
924  */
925 static inline int
926 fpga_dma_desc_te_fill(struct rte_bbdev_enc_op *op,
927                 struct fpga_dma_enc_desc *desc, struct rte_mbuf *input,
928                 struct rte_mbuf *output, uint16_t k_,  uint16_t e,
929                 uint32_t in_offset, uint32_t out_offset, uint16_t desc_offset,
930                 uint8_t cbs_in_op)
931 {
932         /* reset */
933         desc->done = 0;
934         desc->error = 0;
935         desc->k_ = k_;
936         desc->rm_e = e;
937         desc->desc_idx = desc_offset;
938         desc->zc = op->ldpc_enc.z_c;
939         desc->bg_idx = op->ldpc_enc.basegraph - 1;
940         desc->qm_idx = op->ldpc_enc.q_m / 2;
941         desc->crc_en = check_bit(op->ldpc_enc.op_flags,
942                         RTE_BBDEV_LDPC_CRC_24B_ATTACH);
943         desc->irq_en = 0;
944         desc->k0 = get_k0(op->ldpc_enc.n_cb, op->ldpc_enc.z_c,
945                         op->ldpc_enc.basegraph, op->ldpc_enc.rv_index);
946         desc->ncb = op->ldpc_enc.n_cb;
947         desc->num_null = op->ldpc_enc.n_filler;
948         /* Set inbound data buffer address */
949         desc->in_addr_hi = (uint32_t)(
950                         rte_pktmbuf_mtophys_offset(input, in_offset) >> 32);
951         desc->in_addr_lw = (uint32_t)(
952                         rte_pktmbuf_mtophys_offset(input, in_offset));
953
954         desc->out_addr_hi = (uint32_t)(
955                         rte_pktmbuf_mtophys_offset(output, out_offset) >> 32);
956         desc->out_addr_lw = (uint32_t)(
957                         rte_pktmbuf_mtophys_offset(output, out_offset));
958         /* Save software context needed for dequeue */
959         desc->op_addr = op;
960         /* Set total number of CBs in an op */
961         desc->cbs_in_op = cbs_in_op;
962         return 0;
963 }
964
965 /**
966  * Set DMA descriptor for decode operation (1 Code Block)
967  *
968  * @param op
969  *   Pointer to a single encode operation.
970  * @param desc
971  *   Pointer to DMA descriptor.
972  * @param input
973  *   Pointer to pointer to input data which will be decoded.
974  * @param in_offset
975  *   Input offset in rte_mbuf structure. It is used for calculating the point
976  *   where data is starting.
977  * @param out_offset
978  *   Output offset in rte_mbuf structure. It is used for calculating the point
979  *   where hard output data will be stored.
980  * @param cbs_in_op
981  *   Number of CBs contained in one operation.
982  */
983 static inline int
984 fpga_dma_desc_ld_fill(struct rte_bbdev_dec_op *op,
985                 struct fpga_dma_dec_desc *desc,
986                 struct rte_mbuf *input, struct rte_mbuf *output,
987                 uint16_t harq_in_length,
988                 uint32_t in_offset, uint32_t out_offset,
989                 uint32_t harq_offset,
990                 uint16_t desc_offset,
991                 uint8_t cbs_in_op)
992 {
993         /* reset */
994         desc->done = 0;
995         desc->error = 0;
996         /* Set inbound data buffer address */
997         desc->in_addr_hi = (uint32_t)(
998                         rte_pktmbuf_mtophys_offset(input, in_offset) >> 32);
999         desc->in_addr_lw = (uint32_t)(
1000                         rte_pktmbuf_mtophys_offset(input, in_offset));
1001         desc->rm_e = op->ldpc_dec.cb_params.e;
1002         desc->harq_input_length = harq_in_length;
1003         desc->et_dis = !check_bit(op->ldpc_dec.op_flags,
1004                         RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE);
1005         desc->rv = op->ldpc_dec.rv_index;
1006         desc->crc24b_ind = check_bit(op->ldpc_dec.op_flags,
1007                         RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK);
1008         desc->drop_crc24b = check_bit(op->ldpc_dec.op_flags,
1009                         RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP);
1010         desc->desc_idx = desc_offset;
1011         desc->ncb = op->ldpc_dec.n_cb;
1012         desc->num_null = op->ldpc_dec.n_filler;
1013         desc->hbstroe_offset = harq_offset >> 10;
1014         desc->zc = op->ldpc_dec.z_c;
1015         desc->harqin_en = check_bit(op->ldpc_dec.op_flags,
1016                         RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE);
1017         desc->bg_idx = op->ldpc_dec.basegraph - 1;
1018         desc->max_iter = op->ldpc_dec.iter_max;
1019         desc->qm_idx = op->ldpc_dec.q_m / 2;
1020         desc->out_addr_hi = (uint32_t)(
1021                         rte_pktmbuf_mtophys_offset(output, out_offset) >> 32);
1022         desc->out_addr_lw = (uint32_t)(
1023                         rte_pktmbuf_mtophys_offset(output, out_offset));
1024         /* Save software context needed for dequeue */
1025         desc->op_addr = op;
1026         /* Set total number of CBs in an op */
1027         desc->cbs_in_op = cbs_in_op;
1028
1029         return 0;
1030 }
1031
1032 #ifdef RTE_LIBRTE_BBDEV_DEBUG
1033 /* Validates LDPC encoder parameters */
1034 static int
1035 validate_enc_op(struct rte_bbdev_enc_op *op __rte_unused)
1036 {
1037         struct rte_bbdev_op_ldpc_enc *ldpc_enc = &op->ldpc_enc;
1038         struct rte_bbdev_op_enc_ldpc_cb_params *cb = NULL;
1039         struct rte_bbdev_op_enc_ldpc_tb_params *tb = NULL;
1040
1041
1042         if (ldpc_enc->input.length >
1043                         RTE_BBDEV_LDPC_MAX_CB_SIZE >> 3) {
1044                 rte_bbdev_log(ERR, "CB size (%u) is too big, max: %d",
1045                                 ldpc_enc->input.length,
1046                                 RTE_BBDEV_LDPC_MAX_CB_SIZE);
1047                 return -1;
1048         }
1049
1050         if (op->mempool == NULL) {
1051                 rte_bbdev_log(ERR, "Invalid mempool pointer");
1052                 return -1;
1053         }
1054         if (ldpc_enc->input.data == NULL) {
1055                 rte_bbdev_log(ERR, "Invalid input pointer");
1056                 return -1;
1057         }
1058         if (ldpc_enc->output.data == NULL) {
1059                 rte_bbdev_log(ERR, "Invalid output pointer");
1060                 return -1;
1061         }
1062         if ((ldpc_enc->basegraph > 2) || (ldpc_enc->basegraph == 0)) {
1063                 rte_bbdev_log(ERR,
1064                                 "basegraph (%u) is out of range 1 <= value <= 2",
1065                                 ldpc_enc->basegraph);
1066                 return -1;
1067         }
1068         if (ldpc_enc->code_block_mode > 1) {
1069                 rte_bbdev_log(ERR,
1070                                 "code_block_mode (%u) is out of range 0:Tb 1:CB",
1071                                 ldpc_enc->code_block_mode);
1072                 return -1;
1073         }
1074
1075         if (ldpc_enc->code_block_mode == 0) {
1076                 tb = &ldpc_enc->tb_params;
1077                 if (tb->c == 0) {
1078                         rte_bbdev_log(ERR,
1079                                         "c (%u) is out of range 1 <= value <= %u",
1080                                         tb->c, RTE_BBDEV_LDPC_MAX_CODE_BLOCKS);
1081                         return -1;
1082                 }
1083                 if (tb->cab > tb->c) {
1084                         rte_bbdev_log(ERR,
1085                                         "cab (%u) is greater than c (%u)",
1086                                         tb->cab, tb->c);
1087                         return -1;
1088                 }
1089                 if ((tb->ea < RTE_BBDEV_LDPC_MIN_CB_SIZE)
1090                                 && tb->r < tb->cab) {
1091                         rte_bbdev_log(ERR,
1092                                         "ea (%u) is less than %u or it is not even",
1093                                         tb->ea, RTE_BBDEV_LDPC_MIN_CB_SIZE);
1094                         return -1;
1095                 }
1096                 if ((tb->eb < RTE_BBDEV_LDPC_MIN_CB_SIZE)
1097                                 && tb->c > tb->cab) {
1098                         rte_bbdev_log(ERR,
1099                                         "eb (%u) is less than %u",
1100                                         tb->eb, RTE_BBDEV_LDPC_MIN_CB_SIZE);
1101                         return -1;
1102                 }
1103                 if (tb->r > (tb->c - 1)) {
1104                         rte_bbdev_log(ERR,
1105                                         "r (%u) is greater than c - 1 (%u)",
1106                                         tb->r, tb->c - 1);
1107                         return -1;
1108                 }
1109         } else {
1110                 cb = &ldpc_enc->cb_params;
1111                 if (cb->e < RTE_BBDEV_LDPC_MIN_CB_SIZE) {
1112                         rte_bbdev_log(ERR,
1113                                         "e (%u) is less than %u or it is not even",
1114                                         cb->e, RTE_BBDEV_LDPC_MIN_CB_SIZE);
1115                         return -1;
1116                 }
1117         }
1118         return 0;
1119 }
1120 #endif
1121
1122 static inline char *
1123 mbuf_append(struct rte_mbuf *m_head, struct rte_mbuf *m, uint16_t len)
1124 {
1125         if (unlikely(len > rte_pktmbuf_tailroom(m)))
1126                 return NULL;
1127
1128         char *tail = (char *)m->buf_addr + m->data_off + m->data_len;
1129         m->data_len = (uint16_t)(m->data_len + len);
1130         m_head->pkt_len  = (m_head->pkt_len + len);
1131         return tail;
1132 }
1133
1134 #ifdef RTE_LIBRTE_BBDEV_DEBUG
1135 /* Validates LDPC decoder parameters */
1136 static int
1137 validate_dec_op(struct rte_bbdev_dec_op *op __rte_unused)
1138 {
1139         struct rte_bbdev_op_ldpc_dec *ldpc_dec = &op->ldpc_dec;
1140         struct rte_bbdev_op_dec_ldpc_cb_params *cb = NULL;
1141         struct rte_bbdev_op_dec_ldpc_tb_params *tb = NULL;
1142
1143         if (op->mempool == NULL) {
1144                 rte_bbdev_log(ERR, "Invalid mempool pointer");
1145                 return -1;
1146         }
1147         if (ldpc_dec->rv_index > 3) {
1148                 rte_bbdev_log(ERR,
1149                                 "rv_index (%u) is out of range 0 <= value <= 3",
1150                                 ldpc_dec->rv_index);
1151                 return -1;
1152         }
1153
1154         if (ldpc_dec->iter_max == 0) {
1155                 rte_bbdev_log(ERR,
1156                                 "iter_max (%u) is equal to 0",
1157                                 ldpc_dec->iter_max);
1158                 return -1;
1159         }
1160
1161         if (ldpc_dec->code_block_mode > 1) {
1162                 rte_bbdev_log(ERR,
1163                                 "code_block_mode (%u) is out of range 0 <= value <= 1",
1164                                 ldpc_dec->code_block_mode);
1165                 return -1;
1166         }
1167
1168         if (ldpc_dec->code_block_mode == 0) {
1169                 tb = &ldpc_dec->tb_params;
1170                 if (tb->c < 1) {
1171                         rte_bbdev_log(ERR,
1172                                         "c (%u) is out of range 1 <= value <= %u",
1173                                         tb->c, RTE_BBDEV_LDPC_MAX_CODE_BLOCKS);
1174                         return -1;
1175                 }
1176                 if (tb->cab > tb->c) {
1177                         rte_bbdev_log(ERR,
1178                                         "cab (%u) is greater than c (%u)",
1179                                         tb->cab, tb->c);
1180                         return -1;
1181                 }
1182         } else {
1183                 cb = &ldpc_dec->cb_params;
1184                 if (cb->e < RTE_BBDEV_LDPC_MIN_CB_SIZE) {
1185                         rte_bbdev_log(ERR,
1186                                         "e (%u) is out of range %u <= value <= %u",
1187                                         cb->e, RTE_BBDEV_LDPC_MIN_CB_SIZE,
1188                                         RTE_BBDEV_LDPC_MAX_CB_SIZE);
1189                         return -1;
1190                 }
1191         }
1192
1193         return 0;
1194 }
1195 #endif
1196
1197 static inline int
1198 fpga_harq_write_loopback(struct fpga_5gnr_fec_device *fpga_dev,
1199                 struct rte_mbuf *harq_input, uint16_t harq_in_length,
1200                 uint32_t harq_in_offset, uint32_t harq_out_offset)
1201 {
1202         uint32_t out_offset = harq_out_offset;
1203         uint32_t in_offset = harq_in_offset;
1204         uint32_t left_length = harq_in_length;
1205         uint32_t reg_32, increment = 0;
1206         uint64_t *input = NULL;
1207         uint32_t last_transaction = left_length
1208                         % FPGA_5GNR_FEC_DDR_WR_DATA_LEN_IN_BYTES;
1209         uint64_t last_word;
1210
1211         if (last_transaction > 0)
1212                 left_length -= last_transaction;
1213
1214         /*
1215          * Get HARQ buffer size for each VF/PF: When 0x00, there is no
1216          * available DDR space for the corresponding VF/PF.
1217          */
1218         reg_32 = fpga_reg_read_32(fpga_dev->mmio_base,
1219                         FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);
1220         if (reg_32 < harq_in_length) {
1221                 left_length = reg_32;
1222                 rte_bbdev_log(ERR, "HARQ in length > HARQ buffer size\n");
1223         }
1224
1225         input = (uint64_t *)rte_pktmbuf_mtod_offset(harq_input,
1226                         uint8_t *, in_offset);
1227
1228         while (left_length > 0) {
1229                 if (fpga_reg_read_8(fpga_dev->mmio_base,
1230                                 FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS) ==  1) {
1231                         fpga_reg_write_32(fpga_dev->mmio_base,
1232                                         FPGA_5GNR_FEC_DDR4_WR_ADDR_REGS,
1233                                         out_offset);
1234                         fpga_reg_write_64(fpga_dev->mmio_base,
1235                                         FPGA_5GNR_FEC_DDR4_WR_DATA_REGS,
1236                                         input[increment]);
1237                         left_length -= FPGA_5GNR_FEC_DDR_WR_DATA_LEN_IN_BYTES;
1238                         out_offset += FPGA_5GNR_FEC_DDR_WR_DATA_LEN_IN_BYTES;
1239                         increment++;
1240                         fpga_reg_write_8(fpga_dev->mmio_base,
1241                                         FPGA_5GNR_FEC_DDR4_WR_DONE_REGS, 1);
1242                 }
1243         }
1244         while (last_transaction > 0) {
1245                 if (fpga_reg_read_8(fpga_dev->mmio_base,
1246                                 FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS) ==  1) {
1247                         fpga_reg_write_32(fpga_dev->mmio_base,
1248                                         FPGA_5GNR_FEC_DDR4_WR_ADDR_REGS,
1249                                         out_offset);
1250                         last_word = input[increment];
1251                         last_word &= (uint64_t)(1 << (last_transaction * 4))
1252                                         - 1;
1253                         fpga_reg_write_64(fpga_dev->mmio_base,
1254                                         FPGA_5GNR_FEC_DDR4_WR_DATA_REGS,
1255                                         last_word);
1256                         fpga_reg_write_8(fpga_dev->mmio_base,
1257                                         FPGA_5GNR_FEC_DDR4_WR_DONE_REGS, 1);
1258                         last_transaction = 0;
1259                 }
1260         }
1261         return 1;
1262 }
1263
1264 static inline int
1265 fpga_harq_read_loopback(struct fpga_5gnr_fec_device *fpga_dev,
1266                 struct rte_mbuf *harq_output, uint16_t harq_in_length,
1267                 uint32_t harq_in_offset, uint32_t harq_out_offset)
1268 {
1269         uint32_t left_length, in_offset = harq_in_offset;
1270         uint64_t reg;
1271         uint32_t increment = 0;
1272         uint64_t *input = NULL;
1273         uint32_t last_transaction = harq_in_length
1274                         % FPGA_5GNR_FEC_DDR_WR_DATA_LEN_IN_BYTES;
1275
1276         if (last_transaction > 0)
1277                 harq_in_length += (8 - last_transaction);
1278
1279         reg = fpga_reg_read_32(fpga_dev->mmio_base,
1280                         FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);
1281         if (reg < harq_in_length) {
1282                 harq_in_length = reg;
1283                 rte_bbdev_log(ERR, "HARQ in length > HARQ buffer size\n");
1284         }
1285
1286         if (!mbuf_append(harq_output, harq_output, harq_in_length)) {
1287                 rte_bbdev_log(ERR, "HARQ output buffer warning %d %d\n",
1288                                 harq_output->buf_len -
1289                                 rte_pktmbuf_headroom(harq_output),
1290                                 harq_in_length);
1291                 harq_in_length = harq_output->buf_len -
1292                                 rte_pktmbuf_headroom(harq_output);
1293                 if (!mbuf_append(harq_output, harq_output, harq_in_length)) {
1294                         rte_bbdev_log(ERR, "HARQ output buffer issue %d %d\n",
1295                                         harq_output->buf_len, harq_in_length);
1296                         return -1;
1297                 }
1298         }
1299         left_length = harq_in_length;
1300
1301         input = (uint64_t *)rte_pktmbuf_mtod_offset(harq_output,
1302                         uint8_t *, harq_out_offset);
1303
1304         while (left_length > 0) {
1305                 fpga_reg_write_32(fpga_dev->mmio_base,
1306                         FPGA_5GNR_FEC_DDR4_RD_ADDR_REGS, in_offset);
1307                 fpga_reg_write_8(fpga_dev->mmio_base,
1308                                 FPGA_5GNR_FEC_DDR4_RD_DONE_REGS, 1);
1309                 reg = fpga_reg_read_8(fpga_dev->mmio_base,
1310                         FPGA_5GNR_FEC_DDR4_RD_RDY_REGS);
1311                 while (reg != 1) {
1312                         reg = fpga_reg_read_8(fpga_dev->mmio_base,
1313                                 FPGA_5GNR_FEC_DDR4_RD_RDY_REGS);
1314                         if (reg == FPGA_DDR_OVERFLOW) {
1315                                 rte_bbdev_log(ERR,
1316                                                 "Read address is overflow!\n");
1317                                 return -1;
1318                         }
1319                 }
1320                 input[increment] = fpga_reg_read_64(fpga_dev->mmio_base,
1321                         FPGA_5GNR_FEC_DDR4_RD_DATA_REGS);
1322                 left_length -= FPGA_5GNR_FEC_DDR_RD_DATA_LEN_IN_BYTES;
1323                 in_offset += FPGA_5GNR_FEC_DDR_WR_DATA_LEN_IN_BYTES;
1324                 increment++;
1325                 fpga_reg_write_8(fpga_dev->mmio_base,
1326                                 FPGA_5GNR_FEC_DDR4_RD_DONE_REGS, 0);
1327         }
1328         return 1;
1329 }
1330
1331 static inline int
1332 enqueue_ldpc_enc_one_op_cb(struct fpga_queue *q, struct rte_bbdev_enc_op *op,
1333                 uint16_t desc_offset)
1334 {
1335         union fpga_dma_desc *desc;
1336         int ret;
1337         uint8_t c, crc24_bits = 0;
1338         struct rte_bbdev_op_ldpc_enc *enc = &op->ldpc_enc;
1339         uint16_t in_offset = enc->input.offset;
1340         uint16_t out_offset = enc->output.offset;
1341         struct rte_mbuf *m_in = enc->input.data;
1342         struct rte_mbuf *m_out = enc->output.data;
1343         struct rte_mbuf *m_out_head = enc->output.data;
1344         uint32_t in_length, out_length, e;
1345         uint16_t total_left = enc->input.length;
1346         uint16_t ring_offset;
1347         uint16_t K, k_;
1348
1349 #ifdef RTE_LIBRTE_BBDEV_DEBUG
1350         /* Validate op structure */
1351         /* FIXME */
1352         if (validate_enc_op(op) == -1) {
1353                 rte_bbdev_log(ERR, "LDPC encoder validation failed");
1354                 return -EINVAL;
1355         }
1356 #endif
1357
1358         /* Clear op status */
1359         op->status = 0;
1360
1361         if (m_in == NULL || m_out == NULL) {
1362                 rte_bbdev_log(ERR, "Invalid mbuf pointer");
1363                 op->status = 1 << RTE_BBDEV_DATA_ERROR;
1364                 return -EINVAL;
1365         }
1366
1367         if (enc->op_flags & RTE_BBDEV_LDPC_CRC_24B_ATTACH)
1368                 crc24_bits = 24;
1369
1370         if (enc->code_block_mode == 0) {
1371                 /* For Transport Block mode */
1372                 /* FIXME */
1373                 c = enc->tb_params.c;
1374                 e = enc->tb_params.ea;
1375         } else { /* For Code Block mode */
1376                 c = 1;
1377                 e = enc->cb_params.e;
1378         }
1379
1380         /* Update total_left */
1381         K = (enc->basegraph == 1 ? 22 : 10) * enc->z_c;
1382         k_ = K - enc->n_filler;
1383         in_length = (k_ - crc24_bits) >> 3;
1384         out_length = (e + 7) >> 3;
1385
1386         total_left = rte_pktmbuf_data_len(m_in) - in_offset;
1387
1388         /* Update offsets */
1389         if (total_left != in_length) {
1390                 op->status |= 1 << RTE_BBDEV_DATA_ERROR;
1391                 rte_bbdev_log(ERR,
1392                                 "Mismatch between mbuf length and included CBs sizes %d",
1393                                 total_left);
1394         }
1395
1396         mbuf_append(m_out_head, m_out, out_length);
1397
1398         /* Offset into the ring */
1399         ring_offset = ((q->tail + desc_offset) & q->sw_ring_wrap_mask);
1400         /* Setup DMA Descriptor */
1401         desc = q->ring_addr + ring_offset;
1402
1403         ret = fpga_dma_desc_te_fill(op, &desc->enc_req, m_in, m_out,
1404                         k_, e, in_offset, out_offset, ring_offset, c);
1405         if (unlikely(ret < 0))
1406                 return ret;
1407
1408         /* Update lengths */
1409         total_left -= in_length;
1410         op->ldpc_enc.output.length += out_length;
1411
1412         if (total_left > 0) {
1413                 rte_bbdev_log(ERR,
1414                         "Mismatch between mbuf length and included CB sizes: mbuf len %u, cb len %u",
1415                                 total_left, in_length);
1416                 return -1;
1417         }
1418
1419 #ifdef RTE_LIBRTE_BBDEV_DEBUG
1420         print_dma_enc_desc_debug_info(desc);
1421 #endif
1422         return 1;
1423 }
1424
1425 static inline int
1426 enqueue_ldpc_dec_one_op_cb(struct fpga_queue *q, struct rte_bbdev_dec_op *op,
1427                 uint16_t desc_offset)
1428 {
1429         union fpga_dma_desc *desc;
1430         int ret;
1431         uint16_t ring_offset;
1432         uint8_t c;
1433         uint16_t e, in_length, out_length, k0, l, seg_total_left, sys_cols;
1434         uint16_t K, parity_offset, harq_in_length = 0, harq_out_length = 0;
1435         uint16_t crc24_overlap = 0;
1436         struct rte_bbdev_op_ldpc_dec *dec = &op->ldpc_dec;
1437         struct rte_mbuf *m_in = dec->input.data;
1438         struct rte_mbuf *m_out = dec->hard_output.data;
1439         struct rte_mbuf *m_out_head = dec->hard_output.data;
1440         uint16_t in_offset = dec->input.offset;
1441         uint16_t out_offset = dec->hard_output.offset;
1442         uint32_t harq_offset = 0;
1443
1444 #ifdef RTE_LIBRTE_BBDEV_DEBUG
1445                 /* Validate op structure */
1446                 if (validate_dec_op(op) == -1) {
1447                         rte_bbdev_log(ERR, "LDPC decoder validation failed");
1448                         return -EINVAL;
1449                 }
1450 #endif
1451
1452         /* Clear op status */
1453         op->status = 0;
1454
1455         /* Setup DMA Descriptor */
1456         ring_offset = ((q->tail + desc_offset) & q->sw_ring_wrap_mask);
1457         desc = q->ring_addr + ring_offset;
1458
1459         if (check_bit(dec->op_flags,
1460                         RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK)) {
1461                 struct rte_mbuf *harq_in = dec->harq_combined_input.data;
1462                 struct rte_mbuf *harq_out = dec->harq_combined_output.data;
1463                 harq_in_length = dec->harq_combined_input.length;
1464                 uint32_t harq_in_offset = dec->harq_combined_input.offset;
1465                 uint32_t harq_out_offset = dec->harq_combined_output.offset;
1466
1467                 if (check_bit(dec->op_flags,
1468                                 RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE
1469                                 )) {
1470                         ret = fpga_harq_write_loopback(q->d, harq_in,
1471                                         harq_in_length, harq_in_offset,
1472                                         harq_out_offset);
1473                 } else if (check_bit(dec->op_flags,
1474                                 RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE
1475                                 )) {
1476                         ret = fpga_harq_read_loopback(q->d, harq_out,
1477                                 harq_in_length, harq_in_offset,
1478                                 harq_out_offset);
1479                         dec->harq_combined_output.length = harq_in_length;
1480                 } else {
1481                         rte_bbdev_log(ERR, "OP flag Err!");
1482                         ret = -1;
1483                 }
1484                 /* Set descriptor for dequeue */
1485                 desc->dec_req.done = 1;
1486                 desc->dec_req.error = 0;
1487                 desc->dec_req.op_addr = op;
1488                 desc->dec_req.cbs_in_op = 1;
1489                 /* Mark this dummy descriptor to be dropped by HW */
1490                 desc->dec_req.desc_idx = (ring_offset + 1)
1491                                 & q->sw_ring_wrap_mask;
1492                 return ret; /* Error or number of CB */
1493         }
1494
1495         if (m_in == NULL || m_out == NULL) {
1496                 rte_bbdev_log(ERR, "Invalid mbuf pointer");
1497                 op->status = 1 << RTE_BBDEV_DATA_ERROR;
1498                 return -1;
1499         }
1500
1501         c = 1;
1502         e = dec->cb_params.e;
1503
1504         if (check_bit(dec->op_flags, RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP))
1505                 crc24_overlap = 24;
1506
1507         sys_cols = (dec->basegraph == 1) ? 22 : 10;
1508         K = sys_cols * dec->z_c;
1509         parity_offset = K - 2 * dec->z_c;
1510
1511         out_length = ((K - crc24_overlap - dec->n_filler) >> 3);
1512         in_length = e;
1513         seg_total_left = dec->input.length;
1514
1515         if (check_bit(dec->op_flags, RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE)) {
1516                 harq_in_length = RTE_MIN(dec->harq_combined_input.length,
1517                                 (uint32_t)dec->n_cb);
1518         }
1519
1520         if (check_bit(dec->op_flags, RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE)) {
1521                 k0 = get_k0(dec->n_cb, dec->z_c,
1522                                 dec->basegraph, dec->rv_index);
1523                 if (k0 > parity_offset)
1524                         l = k0 + e;
1525                 else
1526                         l = k0 + e + dec->n_filler;
1527                 harq_out_length = RTE_MIN(RTE_MAX(harq_in_length, l),
1528                                 dec->n_cb - dec->n_filler);
1529                 dec->harq_combined_output.length = harq_out_length;
1530         }
1531
1532         mbuf_append(m_out_head, m_out, out_length);
1533         if (check_bit(dec->op_flags, RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE))
1534                 harq_offset = dec->harq_combined_input.offset;
1535         else if (check_bit(dec->op_flags, RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE))
1536                 harq_offset = dec->harq_combined_output.offset;
1537
1538         if ((harq_offset & 0x3FF) > 0) {
1539                 rte_bbdev_log(ERR, "Invalid HARQ offset %d", harq_offset);
1540                 op->status = 1 << RTE_BBDEV_DATA_ERROR;
1541                 return -1;
1542         }
1543
1544         ret = fpga_dma_desc_ld_fill(op, &desc->dec_req, m_in, m_out,
1545                 harq_in_length, in_offset, out_offset, harq_offset,
1546                 ring_offset, c);
1547         if (unlikely(ret < 0))
1548                 return ret;
1549         /* Update lengths */
1550         seg_total_left -= in_length;
1551         op->ldpc_dec.hard_output.length += out_length;
1552         if (seg_total_left > 0) {
1553                 rte_bbdev_log(ERR,
1554                                 "Mismatch between mbuf length and included CB sizes: mbuf len %u, cb len %u",
1555                                 seg_total_left, in_length);
1556                 return -1;
1557         }
1558
1559 #ifdef RTE_LIBRTE_BBDEV_DEBUG
1560         print_dma_dec_desc_debug_info(desc);
1561 #endif
1562
1563         return 1;
1564 }
1565
1566 static uint16_t
1567 fpga_enqueue_ldpc_enc(struct rte_bbdev_queue_data *q_data,
1568                 struct rte_bbdev_enc_op **ops, uint16_t num)
1569 {
1570         uint16_t i, total_enqueued_cbs = 0;
1571         int32_t avail;
1572         int enqueued_cbs;
1573         struct fpga_queue *q = q_data->queue_private;
1574         union fpga_dma_desc *desc;
1575
1576         /* Check if queue is not full */
1577         if (unlikely(((q->tail + 1) & q->sw_ring_wrap_mask) ==
1578                         q->head_free_desc))
1579                 return 0;
1580
1581         /* Calculates available space */
1582         avail = (q->head_free_desc > q->tail) ?
1583                 q->head_free_desc - q->tail - 1 :
1584                 q->ring_ctrl_reg.ring_size + q->head_free_desc - q->tail - 1;
1585
1586         for (i = 0; i < num; ++i) {
1587
1588                 /* Check if there is available space for further
1589                  * processing
1590                  */
1591                 if (unlikely(avail - 1 < 0))
1592                         break;
1593                 avail -= 1;
1594                 enqueued_cbs = enqueue_ldpc_enc_one_op_cb(q, ops[i],
1595                                 total_enqueued_cbs);
1596
1597                 if (enqueued_cbs < 0)
1598                         break;
1599
1600                 total_enqueued_cbs += enqueued_cbs;
1601
1602                 rte_bbdev_log_debug("enqueuing enc ops [%d/%d] | head %d | tail %d",
1603                                 total_enqueued_cbs, num,
1604                                 q->head_free_desc, q->tail);
1605         }
1606
1607         /* Set interrupt bit for last CB in enqueued ops. FPGA issues interrupt
1608          * only when all previous CBs were already processed.
1609          */
1610         desc = q->ring_addr + ((q->tail + total_enqueued_cbs - 1)
1611                         & q->sw_ring_wrap_mask);
1612         desc->enc_req.irq_en = q->irq_enable;
1613
1614         fpga_dma_enqueue(q, total_enqueued_cbs, &q_data->queue_stats);
1615
1616         /* Update stats */
1617         q_data->queue_stats.enqueued_count += i;
1618         q_data->queue_stats.enqueue_err_count += num - i;
1619
1620         return i;
1621 }
1622
1623 static uint16_t
1624 fpga_enqueue_ldpc_dec(struct rte_bbdev_queue_data *q_data,
1625                 struct rte_bbdev_dec_op **ops, uint16_t num)
1626 {
1627         uint16_t i, total_enqueued_cbs = 0;
1628         int32_t avail;
1629         int enqueued_cbs;
1630         struct fpga_queue *q = q_data->queue_private;
1631         union fpga_dma_desc *desc;
1632
1633         /* Check if queue is not full */
1634         if (unlikely(((q->tail + 1) & q->sw_ring_wrap_mask) ==
1635                         q->head_free_desc))
1636                 return 0;
1637
1638         /* Calculates available space */
1639         avail = (q->head_free_desc > q->tail) ?
1640                 q->head_free_desc - q->tail - 1 :
1641                 q->ring_ctrl_reg.ring_size + q->head_free_desc - q->tail - 1;
1642
1643         for (i = 0; i < num; ++i) {
1644
1645                 /* Check if there is available space for further
1646                  * processing
1647                  */
1648                 if (unlikely(avail - 1 < 0))
1649                         break;
1650                 avail -= 1;
1651                 enqueued_cbs = enqueue_ldpc_dec_one_op_cb(q, ops[i],
1652                                 total_enqueued_cbs);
1653
1654                 if (enqueued_cbs < 0)
1655                         break;
1656
1657                 total_enqueued_cbs += enqueued_cbs;
1658
1659                 rte_bbdev_log_debug("enqueuing dec ops [%d/%d] | head %d | tail %d",
1660                                 total_enqueued_cbs, num,
1661                                 q->head_free_desc, q->tail);
1662         }
1663
1664         /* Update stats */
1665         q_data->queue_stats.enqueued_count += i;
1666         q_data->queue_stats.enqueue_err_count += num - i;
1667
1668         /* Set interrupt bit for last CB in enqueued ops. FPGA issues interrupt
1669          * only when all previous CBs were already processed.
1670          */
1671         desc = q->ring_addr + ((q->tail + total_enqueued_cbs - 1)
1672                         & q->sw_ring_wrap_mask);
1673         desc->enc_req.irq_en = q->irq_enable;
1674         fpga_dma_enqueue(q, total_enqueued_cbs, &q_data->queue_stats);
1675         return i;
1676 }
1677
1678
1679 static inline int
1680 dequeue_ldpc_enc_one_op_cb(struct fpga_queue *q,
1681                 struct rte_bbdev_enc_op **op,
1682                 uint16_t desc_offset)
1683 {
1684         union fpga_dma_desc *desc;
1685         int desc_error;
1686         /* Set current desc */
1687         desc = q->ring_addr + ((q->head_free_desc + desc_offset)
1688                         & q->sw_ring_wrap_mask);
1689
1690         /*check if done */
1691         if (desc->enc_req.done == 0)
1692                 return -1;
1693
1694         /* make sure the response is read atomically */
1695         rte_smp_rmb();
1696
1697         rte_bbdev_log_debug("DMA response desc %p", desc);
1698
1699 #ifdef RTE_LIBRTE_BBDEV_DEBUG
1700         print_dma_enc_desc_debug_info(desc);
1701 #endif
1702
1703         *op = desc->enc_req.op_addr;
1704         /* Check the descriptor error field, return 1 on error */
1705         desc_error = check_desc_error(desc->enc_req.error);
1706         (*op)->status = desc_error << RTE_BBDEV_DATA_ERROR;
1707
1708         return 1;
1709 }
1710
1711
1712 static inline int
1713 dequeue_ldpc_dec_one_op_cb(struct fpga_queue *q, struct rte_bbdev_dec_op **op,
1714                 uint16_t desc_offset)
1715 {
1716         union fpga_dma_desc *desc;
1717         int desc_error;
1718         /* Set descriptor */
1719         desc = q->ring_addr + ((q->head_free_desc + desc_offset)
1720                         & q->sw_ring_wrap_mask);
1721
1722         /* Verify done bit is set */
1723         if (desc->dec_req.done == 0)
1724                 return -1;
1725
1726         /* make sure the response is read atomically */
1727         rte_smp_rmb();
1728
1729 #ifdef RTE_LIBRTE_BBDEV_DEBUG
1730         print_dma_dec_desc_debug_info(desc);
1731 #endif
1732
1733         *op = desc->dec_req.op_addr;
1734
1735         if (check_bit((*op)->ldpc_dec.op_flags,
1736                         RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK)) {
1737                 (*op)->status = 0;
1738                 return 1;
1739         }
1740
1741         /* FPGA reports iterations based on round-up minus 1 */
1742         (*op)->ldpc_dec.iter_count = desc->dec_req.iter + 1;
1743         /* CRC Check criteria */
1744         if (desc->dec_req.crc24b_ind && !(desc->dec_req.crcb_pass))
1745                 (*op)->status = 1 << RTE_BBDEV_CRC_ERROR;
1746         /* et_pass = 0 when decoder fails */
1747         (*op)->status |= !(desc->dec_req.et_pass) << RTE_BBDEV_SYNDROME_ERROR;
1748         /* Check the descriptor error field, return 1 on error */
1749         desc_error = check_desc_error(desc->dec_req.error);
1750         (*op)->status |= desc_error << RTE_BBDEV_DATA_ERROR;
1751         return 1;
1752 }
1753
1754 static uint16_t
1755 fpga_dequeue_ldpc_enc(struct rte_bbdev_queue_data *q_data,
1756                 struct rte_bbdev_enc_op **ops, uint16_t num)
1757 {
1758         struct fpga_queue *q = q_data->queue_private;
1759         uint32_t avail = (q->tail - q->head_free_desc) & q->sw_ring_wrap_mask;
1760         uint16_t i;
1761         uint16_t dequeued_cbs = 0;
1762         int ret;
1763
1764         for (i = 0; (i < num) && (dequeued_cbs < avail); ++i) {
1765                 ret = dequeue_ldpc_enc_one_op_cb(q, &ops[i], dequeued_cbs);
1766
1767                 if (ret < 0)
1768                         break;
1769
1770                 dequeued_cbs += ret;
1771
1772                 rte_bbdev_log_debug("dequeuing enc ops [%d/%d] | head %d | tail %d",
1773                                 dequeued_cbs, num, q->head_free_desc, q->tail);
1774         }
1775
1776         /* Update head */
1777         q->head_free_desc = (q->head_free_desc + dequeued_cbs) &
1778                         q->sw_ring_wrap_mask;
1779
1780         /* Update stats */
1781         q_data->queue_stats.dequeued_count += i;
1782
1783         return i;
1784 }
1785
1786 static uint16_t
1787 fpga_dequeue_ldpc_dec(struct rte_bbdev_queue_data *q_data,
1788                 struct rte_bbdev_dec_op **ops, uint16_t num)
1789 {
1790         struct fpga_queue *q = q_data->queue_private;
1791         uint32_t avail = (q->tail - q->head_free_desc) & q->sw_ring_wrap_mask;
1792         uint16_t i;
1793         uint16_t dequeued_cbs = 0;
1794         int ret;
1795
1796         for (i = 0; (i < num) && (dequeued_cbs < avail); ++i) {
1797                 ret = dequeue_ldpc_dec_one_op_cb(q, &ops[i], dequeued_cbs);
1798
1799                 if (ret < 0)
1800                         break;
1801
1802                 dequeued_cbs += ret;
1803
1804                 rte_bbdev_log_debug("dequeuing dec ops [%d/%d] | head %d | tail %d",
1805                                 dequeued_cbs, num, q->head_free_desc, q->tail);
1806         }
1807
1808         /* Update head */
1809         q->head_free_desc = (q->head_free_desc + dequeued_cbs) &
1810                         q->sw_ring_wrap_mask;
1811
1812         /* Update stats */
1813         q_data->queue_stats.dequeued_count += i;
1814
1815         return i;
1816 }
1817
1818
1819 /* Initialization Function */
1820 static void
1821 fpga_5gnr_fec_init(struct rte_bbdev *dev, struct rte_pci_driver *drv)
1822 {
1823         struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
1824
1825         dev->dev_ops = &fpga_ops;
1826         dev->enqueue_ldpc_enc_ops = fpga_enqueue_ldpc_enc;
1827         dev->enqueue_ldpc_dec_ops = fpga_enqueue_ldpc_dec;
1828         dev->dequeue_ldpc_enc_ops = fpga_dequeue_ldpc_enc;
1829         dev->dequeue_ldpc_dec_ops = fpga_dequeue_ldpc_dec;
1830
1831         ((struct fpga_5gnr_fec_device *) dev->data->dev_private)->pf_device =
1832                         !strcmp(drv->driver.name,
1833                                         RTE_STR(FPGA_5GNR_FEC_PF_DRIVER_NAME));
1834         ((struct fpga_5gnr_fec_device *) dev->data->dev_private)->mmio_base =
1835                         pci_dev->mem_resource[0].addr;
1836
1837         rte_bbdev_log_debug(
1838                         "Init device %s [%s] @ virtaddr %p phyaddr %#"PRIx64,
1839                         dev->device->driver->name, dev->data->name,
1840                         (void *)pci_dev->mem_resource[0].addr,
1841                         pci_dev->mem_resource[0].phys_addr);
1842 }
1843
1844 static int
1845 fpga_5gnr_fec_probe(struct rte_pci_driver *pci_drv,
1846         struct rte_pci_device *pci_dev)
1847 {
1848         struct rte_bbdev *bbdev = NULL;
1849         char dev_name[RTE_BBDEV_NAME_MAX_LEN];
1850
1851         if (pci_dev == NULL) {
1852                 rte_bbdev_log(ERR, "NULL PCI device");
1853                 return -EINVAL;
1854         }
1855
1856         rte_pci_device_name(&pci_dev->addr, dev_name, sizeof(dev_name));
1857
1858         /* Allocate memory to be used privately by drivers */
1859         bbdev = rte_bbdev_allocate(pci_dev->device.name);
1860         if (bbdev == NULL)
1861                 return -ENODEV;
1862
1863         /* allocate device private memory */
1864         bbdev->data->dev_private = rte_zmalloc_socket(dev_name,
1865                         sizeof(struct fpga_5gnr_fec_device),
1866                         RTE_CACHE_LINE_SIZE,
1867                         pci_dev->device.numa_node);
1868
1869         if (bbdev->data->dev_private == NULL) {
1870                 rte_bbdev_log(CRIT,
1871                                 "Allocate of %zu bytes for device \"%s\" failed",
1872                                 sizeof(struct fpga_5gnr_fec_device), dev_name);
1873                                 rte_bbdev_release(bbdev);
1874                         return -ENOMEM;
1875         }
1876
1877         /* Fill HW specific part of device structure */
1878         bbdev->device = &pci_dev->device;
1879         bbdev->intr_handle = &pci_dev->intr_handle;
1880         bbdev->data->socket_id = pci_dev->device.numa_node;
1881
1882         /* Invoke FEC FPGA device initialization function */
1883         fpga_5gnr_fec_init(bbdev, pci_drv);
1884
1885         rte_bbdev_log_debug("bbdev id = %u [%s]",
1886                         bbdev->data->dev_id, dev_name);
1887
1888         struct fpga_5gnr_fec_device *d = bbdev->data->dev_private;
1889         uint32_t version_id = fpga_reg_read_32(d->mmio_base,
1890                         FPGA_5GNR_FEC_VERSION_ID);
1891         rte_bbdev_log(INFO, "FEC FPGA RTL v%u.%u",
1892                 ((uint16_t)(version_id >> 16)), ((uint16_t)version_id));
1893
1894 #ifdef RTE_LIBRTE_BBDEV_DEBUG
1895         if (!strcmp(bbdev->device->driver->name,
1896                         RTE_STR(FPGA_5GNR_FEC_PF_DRIVER_NAME)))
1897                 print_static_reg_debug_info(d->mmio_base);
1898 #endif
1899         return 0;
1900 }
1901
1902 static int
1903 fpga_5gnr_fec_remove(struct rte_pci_device *pci_dev)
1904 {
1905         struct rte_bbdev *bbdev;
1906         int ret;
1907         uint8_t dev_id;
1908
1909         if (pci_dev == NULL)
1910                 return -EINVAL;
1911
1912         /* Find device */
1913         bbdev = rte_bbdev_get_named_dev(pci_dev->device.name);
1914         if (bbdev == NULL) {
1915                 rte_bbdev_log(CRIT,
1916                                 "Couldn't find HW dev \"%s\" to uninitialise it",
1917                                 pci_dev->device.name);
1918                 return -ENODEV;
1919         }
1920         dev_id = bbdev->data->dev_id;
1921
1922         /* free device private memory before close */
1923         rte_free(bbdev->data->dev_private);
1924
1925         /* Close device */
1926         ret = rte_bbdev_close(dev_id);
1927         if (ret < 0)
1928                 rte_bbdev_log(ERR,
1929                                 "Device %i failed to close during uninit: %i",
1930                                 dev_id, ret);
1931
1932         /* release bbdev from library */
1933         ret = rte_bbdev_release(bbdev);
1934         if (ret)
1935                 rte_bbdev_log(ERR, "Device %i failed to uninit: %i", dev_id,
1936                                 ret);
1937
1938         rte_bbdev_log_debug("Destroyed bbdev = %u", dev_id);
1939
1940         return 0;
1941 }
1942
1943 static inline void
1944 set_default_fpga_conf(struct fpga_5gnr_fec_conf *def_conf)
1945 {
1946         /* clear default configuration before initialization */
1947         memset(def_conf, 0, sizeof(struct fpga_5gnr_fec_conf));
1948         /* Set pf mode to true */
1949         def_conf->pf_mode_en = true;
1950
1951         /* Set ratio between UL and DL to 1:1 (unit of weight is 3 CBs) */
1952         def_conf->ul_bandwidth = 3;
1953         def_conf->dl_bandwidth = 3;
1954
1955         /* Set Load Balance Factor to 64 */
1956         def_conf->dl_load_balance = 64;
1957         def_conf->ul_load_balance = 64;
1958 }
1959
1960 /* Initial configuration of FPGA 5GNR FEC device */
1961 int
1962 fpga_5gnr_fec_configure(const char *dev_name,
1963                 const struct fpga_5gnr_fec_conf *conf)
1964 {
1965         uint32_t payload_32, address;
1966         uint16_t payload_16;
1967         uint8_t payload_8;
1968         uint16_t q_id, vf_id, total_q_id, total_ul_q_id, total_dl_q_id;
1969         struct rte_bbdev *bbdev = rte_bbdev_get_named_dev(dev_name);
1970         struct fpga_5gnr_fec_conf def_conf;
1971
1972         if (bbdev == NULL) {
1973                 rte_bbdev_log(ERR,
1974                                 "Invalid dev_name (%s), or device is not yet initialised",
1975                                 dev_name);
1976                 return -ENODEV;
1977         }
1978
1979         struct fpga_5gnr_fec_device *d = bbdev->data->dev_private;
1980
1981         if (conf == NULL) {
1982                 rte_bbdev_log(ERR,
1983                                 "FPGA Configuration was not provided. Default configuration will be loaded.");
1984                 set_default_fpga_conf(&def_conf);
1985                 conf = &def_conf;
1986         }
1987
1988         /*
1989          * Configure UL:DL ratio.
1990          * [7:0]: UL weight
1991          * [15:8]: DL weight
1992          */
1993         payload_16 = (conf->dl_bandwidth << 8) | conf->ul_bandwidth;
1994         address = FPGA_5GNR_FEC_CONFIGURATION;
1995         fpga_reg_write_16(d->mmio_base, address, payload_16);
1996
1997         /* Clear all queues registers */
1998         payload_32 = FPGA_INVALID_HW_QUEUE_ID;
1999         for (q_id = 0; q_id < FPGA_TOTAL_NUM_QUEUES; ++q_id) {
2000                 address = (q_id << 2) + FPGA_5GNR_FEC_QUEUE_MAP;
2001                 fpga_reg_write_32(d->mmio_base, address, payload_32);
2002         }
2003
2004         /*
2005          * If PF mode is enabled allocate all queues for PF only.
2006          *
2007          * For VF mode each VF can have different number of UL and DL queues.
2008          * Total number of queues to configure cannot exceed FPGA
2009          * capabilities - 64 queues - 32 queues for UL and 32 queues for DL.
2010          * Queues mapping is done according to configuration:
2011          *
2012          * UL queues:
2013          * |                Q_ID              | VF_ID |
2014          * |                 0                |   0   |
2015          * |                ...               |   0   |
2016          * | conf->vf_dl_queues_number[0] - 1 |   0   |
2017          * | conf->vf_dl_queues_number[0]     |   1   |
2018          * |                ...               |   1   |
2019          * | conf->vf_dl_queues_number[1] - 1 |   1   |
2020          * |                ...               |  ...  |
2021          * | conf->vf_dl_queues_number[7] - 1 |   7   |
2022          *
2023          * DL queues:
2024          * |                Q_ID              | VF_ID |
2025          * |                 32               |   0   |
2026          * |                ...               |   0   |
2027          * | conf->vf_ul_queues_number[0] - 1 |   0   |
2028          * | conf->vf_ul_queues_number[0]     |   1   |
2029          * |                ...               |   1   |
2030          * | conf->vf_ul_queues_number[1] - 1 |   1   |
2031          * |                ...               |  ...  |
2032          * | conf->vf_ul_queues_number[7] - 1 |   7   |
2033          *
2034          * Example of configuration:
2035          * conf->vf_ul_queues_number[0] = 4;  -> 4 UL queues for VF0
2036          * conf->vf_dl_queues_number[0] = 4;  -> 4 DL queues for VF0
2037          * conf->vf_ul_queues_number[1] = 2;  -> 2 UL queues for VF1
2038          * conf->vf_dl_queues_number[1] = 2;  -> 2 DL queues for VF1
2039          *
2040          * UL:
2041          * | Q_ID | VF_ID |
2042          * |   0  |   0   |
2043          * |   1  |   0   |
2044          * |   2  |   0   |
2045          * |   3  |   0   |
2046          * |   4  |   1   |
2047          * |   5  |   1   |
2048          *
2049          * DL:
2050          * | Q_ID | VF_ID |
2051          * |  32  |   0   |
2052          * |  33  |   0   |
2053          * |  34  |   0   |
2054          * |  35  |   0   |
2055          * |  36  |   1   |
2056          * |  37  |   1   |
2057          */
2058         if (conf->pf_mode_en) {
2059                 payload_32 = 0x1;
2060                 for (q_id = 0; q_id < FPGA_TOTAL_NUM_QUEUES; ++q_id) {
2061                         address = (q_id << 2) + FPGA_5GNR_FEC_QUEUE_MAP;
2062                         fpga_reg_write_32(d->mmio_base, address, payload_32);
2063                 }
2064         } else {
2065                 /* Calculate total number of UL and DL queues to configure */
2066                 total_ul_q_id = total_dl_q_id = 0;
2067                 for (vf_id = 0; vf_id < FPGA_5GNR_FEC_NUM_VFS; ++vf_id) {
2068                         total_ul_q_id += conf->vf_ul_queues_number[vf_id];
2069                         total_dl_q_id += conf->vf_dl_queues_number[vf_id];
2070                 }
2071                 total_q_id = total_dl_q_id + total_ul_q_id;
2072                 /*
2073                  * Check if total number of queues to configure does not exceed
2074                  * FPGA capabilities (64 queues - 32 UL and 32 DL queues)
2075                  */
2076                 if ((total_ul_q_id > FPGA_NUM_UL_QUEUES) ||
2077                         (total_dl_q_id > FPGA_NUM_DL_QUEUES) ||
2078                         (total_q_id > FPGA_TOTAL_NUM_QUEUES)) {
2079                         rte_bbdev_log(ERR,
2080                                         "FPGA Configuration failed. Too many queues to configure: UL_Q %u, DL_Q %u, FPGA_Q %u",
2081                                         total_ul_q_id, total_dl_q_id,
2082                                         FPGA_TOTAL_NUM_QUEUES);
2083                         return -EINVAL;
2084                 }
2085                 total_ul_q_id = 0;
2086                 for (vf_id = 0; vf_id < FPGA_5GNR_FEC_NUM_VFS; ++vf_id) {
2087                         for (q_id = 0; q_id < conf->vf_ul_queues_number[vf_id];
2088                                         ++q_id, ++total_ul_q_id) {
2089                                 address = (total_ul_q_id << 2) +
2090                                                 FPGA_5GNR_FEC_QUEUE_MAP;
2091                                 payload_32 = ((0x80 + vf_id) << 16) | 0x1;
2092                                 fpga_reg_write_32(d->mmio_base, address,
2093                                                 payload_32);
2094                         }
2095                 }
2096                 total_dl_q_id = 0;
2097                 for (vf_id = 0; vf_id < FPGA_5GNR_FEC_NUM_VFS; ++vf_id) {
2098                         for (q_id = 0; q_id < conf->vf_dl_queues_number[vf_id];
2099                                         ++q_id, ++total_dl_q_id) {
2100                                 address = ((total_dl_q_id + FPGA_NUM_UL_QUEUES)
2101                                                 << 2) + FPGA_5GNR_FEC_QUEUE_MAP;
2102                                 payload_32 = ((0x80 + vf_id) << 16) | 0x1;
2103                                 fpga_reg_write_32(d->mmio_base, address,
2104                                                 payload_32);
2105                         }
2106                 }
2107         }
2108
2109         /* Setting Load Balance Factor */
2110         payload_16 = (conf->dl_load_balance << 8) | (conf->ul_load_balance);
2111         address = FPGA_5GNR_FEC_LOAD_BALANCE_FACTOR;
2112         fpga_reg_write_16(d->mmio_base, address, payload_16);
2113
2114         /* Setting length of ring descriptor entry */
2115         payload_16 = FPGA_RING_DESC_ENTRY_LENGTH;
2116         address = FPGA_5GNR_FEC_RING_DESC_LEN;
2117         fpga_reg_write_16(d->mmio_base, address, payload_16);
2118
2119         /* Setting FLR timeout value */
2120         payload_16 = conf->flr_time_out;
2121         address = FPGA_5GNR_FEC_FLR_TIME_OUT;
2122         fpga_reg_write_16(d->mmio_base, address, payload_16);
2123
2124         /* Queue PF/VF mapping table is ready */
2125         payload_8 = 0x1;
2126         address = FPGA_5GNR_FEC_QUEUE_PF_VF_MAP_DONE;
2127         fpga_reg_write_8(d->mmio_base, address, payload_8);
2128
2129         rte_bbdev_log_debug("PF FPGA 5GNR FEC configuration complete for %s",
2130                         dev_name);
2131
2132 #ifdef RTE_LIBRTE_BBDEV_DEBUG
2133         print_static_reg_debug_info(d->mmio_base);
2134 #endif
2135         return 0;
2136 }
2137
2138 /* FPGA 5GNR FEC PCI PF address map */
2139 static struct rte_pci_id pci_id_fpga_5gnr_fec_pf_map[] = {
2140         {
2141                 RTE_PCI_DEVICE(FPGA_5GNR_FEC_VENDOR_ID,
2142                                 FPGA_5GNR_FEC_PF_DEVICE_ID)
2143         },
2144         {.device_id = 0},
2145 };
2146
2147 static struct rte_pci_driver fpga_5gnr_fec_pci_pf_driver = {
2148         .probe = fpga_5gnr_fec_probe,
2149         .remove = fpga_5gnr_fec_remove,
2150         .id_table = pci_id_fpga_5gnr_fec_pf_map,
2151         .drv_flags = RTE_PCI_DRV_NEED_MAPPING
2152 };
2153
2154 /* FPGA 5GNR FEC PCI VF address map */
2155 static struct rte_pci_id pci_id_fpga_5gnr_fec_vf_map[] = {
2156         {
2157                 RTE_PCI_DEVICE(FPGA_5GNR_FEC_VENDOR_ID,
2158                                 FPGA_5GNR_FEC_VF_DEVICE_ID)
2159         },
2160         {.device_id = 0},
2161 };
2162
2163 static struct rte_pci_driver fpga_5gnr_fec_pci_vf_driver = {
2164         .probe = fpga_5gnr_fec_probe,
2165         .remove = fpga_5gnr_fec_remove,
2166         .id_table = pci_id_fpga_5gnr_fec_vf_map,
2167         .drv_flags = RTE_PCI_DRV_NEED_MAPPING
2168 };
2169
2170
2171 RTE_PMD_REGISTER_PCI(FPGA_5GNR_FEC_PF_DRIVER_NAME, fpga_5gnr_fec_pci_pf_driver);
2172 RTE_PMD_REGISTER_PCI_TABLE(FPGA_5GNR_FEC_PF_DRIVER_NAME,
2173                 pci_id_fpga_5gnr_fec_pf_map);
2174 RTE_PMD_REGISTER_PCI(FPGA_5GNR_FEC_VF_DRIVER_NAME, fpga_5gnr_fec_pci_vf_driver);
2175 RTE_PMD_REGISTER_PCI_TABLE(FPGA_5GNR_FEC_VF_DRIVER_NAME,
2176                 pci_id_fpga_5gnr_fec_vf_map);
2177
2178 RTE_INIT(fpga_5gnr_fec_init_log)
2179 {
2180         fpga_5gnr_fec_logtype = rte_log_register("pmd.bb.fpga_5gnr_fec");
2181         if (fpga_5gnr_fec_logtype >= 0)
2182 #ifdef RTE_LIBRTE_BBDEV_DEBUG
2183                 rte_log_set_level(fpga_5gnr_fec_logtype, RTE_LOG_DEBUG);
2184 #else
2185                 rte_log_set_level(fpga_5gnr_fec_logtype, RTE_LOG_NOTICE);
2186 #endif
2187 }