+static inline int
+fpga_harq_write_loopback(struct fpga_5gnr_fec_device *fpga_dev,
+ struct rte_mbuf *harq_input, uint16_t harq_in_length,
+ uint32_t harq_in_offset, uint32_t harq_out_offset)
+{
+ uint32_t out_offset = harq_out_offset;
+ uint32_t in_offset = harq_in_offset;
+ uint32_t left_length = harq_in_length;
+ uint32_t reg_32, increment = 0;
+ uint64_t *input = NULL;
+ uint32_t last_transaction = left_length
+ % FPGA_5GNR_FEC_DDR_WR_DATA_LEN_IN_BYTES;
+ uint64_t last_word;
+
+ if (last_transaction > 0)
+ left_length -= last_transaction;
+
+ /*
+ * Get HARQ buffer size for each VF/PF: When 0x00, there is no
+ * available DDR space for the corresponding VF/PF.
+ */
+ reg_32 = fpga_reg_read_32(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);
+ if (reg_32 < harq_in_length) {
+ left_length = reg_32;
+ rte_bbdev_log(ERR, "HARQ in length > HARQ buffer size\n");
+ }
+
+ input = (uint64_t *)rte_pktmbuf_mtod_offset(harq_input,
+ uint8_t *, in_offset);
+
+ while (left_length > 0) {
+ if (fpga_reg_read_8(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS) == 1) {
+ fpga_reg_write_32(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_WR_ADDR_REGS,
+ out_offset);
+ fpga_reg_write_64(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_WR_DATA_REGS,
+ input[increment]);
+ left_length -= FPGA_5GNR_FEC_DDR_WR_DATA_LEN_IN_BYTES;
+ out_offset += FPGA_5GNR_FEC_DDR_WR_DATA_LEN_IN_BYTES;
+ increment++;
+ fpga_reg_write_8(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_WR_DONE_REGS, 1);
+ }
+ }
+ while (last_transaction > 0) {
+ if (fpga_reg_read_8(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS) == 1) {
+ fpga_reg_write_32(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_WR_ADDR_REGS,
+ out_offset);
+ last_word = input[increment];
+ last_word &= (uint64_t)(1 << (last_transaction * 4))
+ - 1;
+ fpga_reg_write_64(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_WR_DATA_REGS,
+ last_word);
+ fpga_reg_write_8(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_WR_DONE_REGS, 1);
+ last_transaction = 0;
+ }
+ }
+ return 1;
+}
+
+static inline int
+fpga_harq_read_loopback(struct fpga_5gnr_fec_device *fpga_dev,
+ struct rte_mbuf *harq_output, uint16_t harq_in_length,
+ uint32_t harq_in_offset, uint32_t harq_out_offset)
+{
+ uint32_t left_length, in_offset = harq_in_offset;
+ uint64_t reg;
+ uint32_t increment = 0;
+ uint64_t *input = NULL;
+ uint32_t last_transaction = harq_in_length
+ % FPGA_5GNR_FEC_DDR_WR_DATA_LEN_IN_BYTES;
+
+ if (last_transaction > 0)
+ harq_in_length += (8 - last_transaction);
+
+ reg = fpga_reg_read_32(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);
+ if (reg < harq_in_length) {
+ harq_in_length = reg;
+ rte_bbdev_log(ERR, "HARQ in length > HARQ buffer size\n");
+ }
+
+ if (!mbuf_append(harq_output, harq_output, harq_in_length)) {
+ rte_bbdev_log(ERR, "HARQ output buffer warning %d %d\n",
+ harq_output->buf_len -
+ rte_pktmbuf_headroom(harq_output),
+ harq_in_length);
+ harq_in_length = harq_output->buf_len -
+ rte_pktmbuf_headroom(harq_output);
+ if (!mbuf_append(harq_output, harq_output, harq_in_length)) {
+ rte_bbdev_log(ERR, "HARQ output buffer issue %d %d\n",
+ harq_output->buf_len, harq_in_length);
+ return -1;
+ }
+ }
+ left_length = harq_in_length;
+
+ input = (uint64_t *)rte_pktmbuf_mtod_offset(harq_output,
+ uint8_t *, harq_out_offset);
+
+ while (left_length > 0) {
+ fpga_reg_write_32(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_RD_ADDR_REGS, in_offset);
+ fpga_reg_write_8(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_RD_DONE_REGS, 1);
+ reg = fpga_reg_read_8(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_RD_RDY_REGS);
+ while (reg != 1) {
+ reg = fpga_reg_read_8(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_RD_RDY_REGS);
+ if (reg == FPGA_DDR_OVERFLOW) {
+ rte_bbdev_log(ERR,
+ "Read address is overflow!\n");
+ return -1;
+ }
+ }
+ input[increment] = fpga_reg_read_64(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_RD_DATA_REGS);
+ left_length -= FPGA_5GNR_FEC_DDR_RD_DATA_LEN_IN_BYTES;
+ in_offset += FPGA_5GNR_FEC_DDR_WR_DATA_LEN_IN_BYTES;
+ increment++;
+ fpga_reg_write_8(fpga_dev->mmio_base,
+ FPGA_5GNR_FEC_DDR4_RD_DONE_REGS, 0);
+ }
+ return 1;
+}
+