DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH v1 0/5] baseband/fpga_5gnr: maintenance changes to fpga_5gnr PMD
@ 2022-05-09 20:17 Hernan
  2022-05-09 20:17 ` [PATCH v1 1/5] baseband/fpga_5gnr_fec: remove FLR timeout Hernan
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Hernan @ 2022-05-09 20:17 UTC (permalink / raw)
  To: dev, gakhil, trix; +Cc: nicolas.chautru, qi.z.zhang, Hernan

Few PMD changes as part of maintenance of the driver. These are not required on the stable variants. Aiming to upstream these in 22.07.

Hernan (5):
  baseband/fpga_5gnr_fec: remove FLR timeout
  baseband/fpga_5gnr_fec: add FPGA Mutex
  baseband/fpga_5gnr_fec: add check for HARQ input length
  baseband/fpga_5gnr_fec: enable validate LDPC enc/dec
  baseband/fpga_5gnr_fec: remove filler from HARQ

 app/test-bbdev/test_bbdev_perf.c              |   4 -
 .../baseband/fpga_5gnr_fec/fpga_5gnr_fec.h    |   9 +-
 .../fpga_5gnr_fec/rte_fpga_5gnr_fec.c         | 581 ++++++++++++++----
 .../fpga_5gnr_fec/rte_pmd_fpga_5gnr_fec.h     |   2 -
 4 files changed, 451 insertions(+), 145 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v1 1/5] baseband/fpga_5gnr_fec: remove FLR timeout
  2022-05-09 20:17 [PATCH v1 0/5] baseband/fpga_5gnr: maintenance changes to fpga_5gnr PMD Hernan
@ 2022-05-09 20:17 ` Hernan
  2022-05-09 20:17 ` [PATCH v1 2/5] baseband/fpga_5gnr_fec: add FPGA Mutex Hernan
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Hernan @ 2022-05-09 20:17 UTC (permalink / raw)
  To: dev, gakhil, trix; +Cc: nicolas.chautru, qi.z.zhang, Hernan

FLR timeout register is not used in 5GNR FPGA.

Signed-off-by: Hernan <hernan.vargas@intel.com>
---
 app/test-bbdev/test_bbdev_perf.c                       | 4 ----
 drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h         | 2 --
 drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c     | 9 ---------
 drivers/baseband/fpga_5gnr_fec/rte_pmd_fpga_5gnr_fec.h | 2 --
 4 files changed, 17 deletions(-)

diff --git a/app/test-bbdev/test_bbdev_perf.c b/app/test-bbdev/test_bbdev_perf.c
index 0fa119a502..fad3b1e49d 100644
--- a/app/test-bbdev/test_bbdev_perf.c
+++ b/app/test-bbdev/test_bbdev_perf.c
@@ -50,7 +50,6 @@
 #define DL_5G_BANDWIDTH 3
 #define UL_5G_LOAD_BALANCE 128
 #define DL_5G_LOAD_BALANCE 128
-#define FLR_5G_TIMEOUT 610
 #endif
 
 #ifdef RTE_BASEBAND_ACC100
@@ -699,9 +698,6 @@ add_bbdev_dev(uint8_t dev_id, struct rte_bbdev_info *info,
 		conf.ul_load_balance = UL_5G_LOAD_BALANCE;
 		conf.dl_load_balance = DL_5G_LOAD_BALANCE;
 
-		/**< FLR timeout value */
-		conf.flr_time_out = FLR_5G_TIMEOUT;
-
 		/* setup FPGA PF with configuration information */
 		ret = rte_fpga_5gnr_fec_configure(info->dev_name, &conf);
 		TEST_ASSERT_SUCCESS(ret,
diff --git a/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h b/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
index e72c95e936..ed8ce26eaa 100644
--- a/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
+++ b/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
@@ -36,7 +36,6 @@
 #define FPGA_RING_DESC_LEN_UNIT_BYTES (32)
 /* Maximum size of queue */
 #define FPGA_RING_MAX_SIZE (1024)
-#define FPGA_FLR_TIMEOUT_UNIT (16.384)
 
 #define FPGA_NUM_UL_QUEUES (32)
 #define FPGA_NUM_DL_QUEUES (32)
@@ -70,7 +69,6 @@ enum {
 	FPGA_5GNR_FEC_QUEUE_PF_VF_MAP_DONE = 0x00000008, /* len: 1B */
 	FPGA_5GNR_FEC_LOAD_BALANCE_FACTOR = 0x0000000a, /* len: 2B */
 	FPGA_5GNR_FEC_RING_DESC_LEN = 0x0000000c, /* len: 2B */
-	FPGA_5GNR_FEC_FLR_TIME_OUT = 0x0000000e, /* len: 2B */
 	FPGA_5GNR_FEC_VFQ_FLUSH_STATUS_LW = 0x00000018, /* len: 4B */
 	FPGA_5GNR_FEC_VFQ_FLUSH_STATUS_HI = 0x0000001c, /* len: 4B */
 	FPGA_5GNR_FEC_QUEUE_MAP = 0x00000040, /* len: 256B */
diff --git a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
index 15d23d6269..6737b74901 100644
--- a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
+++ b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
@@ -83,8 +83,6 @@ print_static_reg_debug_info(void *mmio_base)
 			FPGA_5GNR_FEC_LOAD_BALANCE_FACTOR);
 	uint16_t ring_desc_len = fpga_reg_read_16(mmio_base,
 			FPGA_5GNR_FEC_RING_DESC_LEN);
-	uint16_t flr_time_out = fpga_reg_read_16(mmio_base,
-			FPGA_5GNR_FEC_FLR_TIME_OUT);
 
 	rte_bbdev_log_debug("UL.DL Weights = %u.%u",
 			((uint8_t)config), ((uint8_t)(config >> 8)));
@@ -94,8 +92,6 @@ print_static_reg_debug_info(void *mmio_base)
 			(qmap_done > 0) ? "READY" : "NOT-READY");
 	rte_bbdev_log_debug("Ring Descriptor Size = %u bytes",
 			ring_desc_len*FPGA_RING_DESC_LEN_UNIT_BYTES);
-	rte_bbdev_log_debug("FLR Timeout = %f usec",
-			(float)flr_time_out*FPGA_FLR_TIMEOUT_UNIT);
 }
 
 /* Print decode DMA Descriptor of FPGA 5GNR Decoder device */
@@ -2120,11 +2116,6 @@ rte_fpga_5gnr_fec_configure(const char *dev_name,
 	address = FPGA_5GNR_FEC_RING_DESC_LEN;
 	fpga_reg_write_16(d->mmio_base, address, payload_16);
 
-	/* Setting FLR timeout value */
-	payload_16 = conf->flr_time_out;
-	address = FPGA_5GNR_FEC_FLR_TIME_OUT;
-	fpga_reg_write_16(d->mmio_base, address, payload_16);
-
 	/* Queue PF/VF mapping table is ready */
 	payload_8 = 0x1;
 	address = FPGA_5GNR_FEC_QUEUE_PF_VF_MAP_DONE;
diff --git a/drivers/baseband/fpga_5gnr_fec/rte_pmd_fpga_5gnr_fec.h b/drivers/baseband/fpga_5gnr_fec/rte_pmd_fpga_5gnr_fec.h
index c2752fbd52..93a87c8e82 100644
--- a/drivers/baseband/fpga_5gnr_fec/rte_pmd_fpga_5gnr_fec.h
+++ b/drivers/baseband/fpga_5gnr_fec/rte_pmd_fpga_5gnr_fec.h
@@ -45,8 +45,6 @@ struct rte_fpga_5gnr_fec_conf {
 	uint8_t ul_load_balance;
 	/** DL Load Balance */
 	uint8_t dl_load_balance;
-	/** FLR timeout value */
-	uint16_t flr_time_out;
 };
 
 /**
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v1 2/5] baseband/fpga_5gnr_fec: add FPGA Mutex
  2022-05-09 20:17 [PATCH v1 0/5] baseband/fpga_5gnr: maintenance changes to fpga_5gnr PMD Hernan
  2022-05-09 20:17 ` [PATCH v1 1/5] baseband/fpga_5gnr_fec: remove FLR timeout Hernan
@ 2022-05-09 20:17 ` Hernan
  2022-05-16 18:08   ` [EXT] " Akhil Goyal
  2022-05-09 20:17 ` [PATCH v1 3/5] baseband/fpga_5gnr_fec: add check for HARQ input length Hernan
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Hernan @ 2022-05-09 20:17 UTC (permalink / raw)
  To: dev, gakhil, trix; +Cc: nicolas.chautru, qi.z.zhang, Hernan

FPGA mutex acquisition and mutex free implemented.

Signed-off-by: Hernan <hernan.vargas@intel.com>
---
 .../baseband/fpga_5gnr_fec/fpga_5gnr_fec.h    |  6 +-
 .../fpga_5gnr_fec/rte_fpga_5gnr_fec.c         | 77 ++++++++++++++-----
 2 files changed, 62 insertions(+), 21 deletions(-)

diff --git a/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h b/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
index ed8ce26eaa..993cf61974 100644
--- a/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
+++ b/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
@@ -82,7 +82,9 @@ enum {
 	FPGA_5GNR_FEC_DDR4_RD_DATA_REGS = 0x00000A30, /* len: 8B */
 	FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS = 0x00000A38, /* len: 1B */
 	FPGA_5GNR_FEC_HARQ_BUF_SIZE_RDY_REGS = 0x00000A40, /* len: 1B */
-	FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS = 0x00000A48  /* len: 4B */
+	FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS = 0x00000A48, /* len: 4B */
+	FPGA_5GNR_FEC_MUTEX = 0x00000A60, /* len: 4B */
+	FPGA_5GNR_FEC_MUTEX_RESET = 0x00000A68  /* len: 4B */
 };
 
 /* FPGA 5GNR FEC Ring Control Registers */
@@ -264,6 +266,8 @@ struct __rte_cache_aligned fpga_queue {
 	uint32_t sw_ring_wrap_mask;
 	uint32_t irq_enable;  /* Enable ops dequeue interrupts if set to 1 */
 	uint8_t q_idx;  /* Queue index */
+	/** uuid used for MUTEX acquision for DDR */
+	uint16_t ddr_mutex_uuid;
 	struct fpga_5gnr_fec_device *d;
 	/* MMIO register of shadow_tail used to enqueue descriptors */
 	void *shadow_tail_addr;
diff --git a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
index 6737b74901..435b4d90d8 100644
--- a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
+++ b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
@@ -1194,11 +1194,45 @@ validate_dec_op(struct rte_bbdev_dec_op *op __rte_unused)
 }
 #endif
 
+static inline void
+fpga_mutex_acquisition(struct fpga_queue *q)
+{
+	uint32_t mutex_ctrl, mutex_read, cnt = 0;
+	/* Assign a unique id for the duration of the DDR access */
+	q->ddr_mutex_uuid = rand();
+	/* Request and wait for acquisition of the mutex */
+	mutex_ctrl = (q->ddr_mutex_uuid << 16) + 1;
+	do {
+		if (cnt > 0)
+			usleep(FPGA_TIMEOUT_CHECK_INTERVAL);
+		rte_bbdev_log_debug("Acquiring Mutex for %x\n",
+				q->ddr_mutex_uuid);
+		fpga_reg_write_32(q->d->mmio_base,
+				FPGA_5GNR_FEC_MUTEX,
+				mutex_ctrl);
+		mutex_read = fpga_reg_read_32(q->d->mmio_base,
+				FPGA_5GNR_FEC_MUTEX);
+		rte_bbdev_log_debug("Mutex %x cnt %d owner %x\n",
+				mutex_read, cnt, q->ddr_mutex_uuid);
+		cnt++;
+	} while ((mutex_read >> 16) != q->ddr_mutex_uuid);
+}
+
+static inline void
+fpga_mutex_free(struct fpga_queue *q)
+{
+	uint32_t mutex_ctrl = q->ddr_mutex_uuid << 16;
+	fpga_reg_write_32(q->d->mmio_base,
+			FPGA_5GNR_FEC_MUTEX,
+			mutex_ctrl);
+}
+
 static inline int
-fpga_harq_write_loopback(struct fpga_5gnr_fec_device *fpga_dev,
+fpga_harq_write_loopback(struct fpga_queue *q,
 		struct rte_mbuf *harq_input, uint16_t harq_in_length,
 		uint32_t harq_in_offset, uint32_t harq_out_offset)
 {
+	fpga_mutex_acquisition(q);
 	uint32_t out_offset = harq_out_offset;
 	uint32_t in_offset = harq_in_offset;
 	uint32_t left_length = harq_in_length;
@@ -1215,7 +1249,7 @@ fpga_harq_write_loopback(struct fpga_5gnr_fec_device *fpga_dev,
 	 * 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,
+	reg_32 = fpga_reg_read_32(q->d->mmio_base,
 			FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);
 	if (reg_32 < harq_in_length) {
 		left_length = reg_32;
@@ -1226,46 +1260,48 @@ fpga_harq_write_loopback(struct fpga_5gnr_fec_device *fpga_dev,
 			uint8_t *, in_offset);
 
 	while (left_length > 0) {
-		if (fpga_reg_read_8(fpga_dev->mmio_base,
+		if (fpga_reg_read_8(q->d->mmio_base,
 				FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS) ==  1) {
-			fpga_reg_write_32(fpga_dev->mmio_base,
+			fpga_reg_write_32(q->d->mmio_base,
 					FPGA_5GNR_FEC_DDR4_WR_ADDR_REGS,
 					out_offset);
-			fpga_reg_write_64(fpga_dev->mmio_base,
+			fpga_reg_write_64(q->d->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_reg_write_8(q->d->mmio_base,
 					FPGA_5GNR_FEC_DDR4_WR_DONE_REGS, 1);
 		}
 	}
 	while (last_transaction > 0) {
-		if (fpga_reg_read_8(fpga_dev->mmio_base,
+		if (fpga_reg_read_8(q->d->mmio_base,
 				FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS) ==  1) {
-			fpga_reg_write_32(fpga_dev->mmio_base,
+			fpga_reg_write_32(q->d->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_reg_write_64(q->d->mmio_base,
 					FPGA_5GNR_FEC_DDR4_WR_DATA_REGS,
 					last_word);
-			fpga_reg_write_8(fpga_dev->mmio_base,
+			fpga_reg_write_8(q->d->mmio_base,
 					FPGA_5GNR_FEC_DDR4_WR_DONE_REGS, 1);
 			last_transaction = 0;
 		}
 	}
+	fpga_mutex_free(q);
 	return 1;
 }
 
 static inline int
-fpga_harq_read_loopback(struct fpga_5gnr_fec_device *fpga_dev,
+fpga_harq_read_loopback(struct fpga_queue *q,
 		struct rte_mbuf *harq_output, uint16_t harq_in_length,
 		uint32_t harq_in_offset, uint32_t harq_out_offset)
 {
+	fpga_mutex_acquisition(q);
 	uint32_t left_length, in_offset = harq_in_offset;
 	uint64_t reg;
 	uint32_t increment = 0;
@@ -1276,7 +1312,7 @@ fpga_harq_read_loopback(struct fpga_5gnr_fec_device *fpga_dev,
 	if (last_transaction > 0)
 		harq_in_length += (8 - last_transaction);
 
-	reg = fpga_reg_read_32(fpga_dev->mmio_base,
+	reg = fpga_reg_read_32(q->d->mmio_base,
 			FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);
 	if (reg < harq_in_length) {
 		harq_in_length = reg;
@@ -1302,14 +1338,14 @@ fpga_harq_read_loopback(struct fpga_5gnr_fec_device *fpga_dev,
 			uint8_t *, harq_out_offset);
 
 	while (left_length > 0) {
-		fpga_reg_write_32(fpga_dev->mmio_base,
+		fpga_reg_write_32(q->d->mmio_base,
 			FPGA_5GNR_FEC_DDR4_RD_ADDR_REGS, in_offset);
-		fpga_reg_write_8(fpga_dev->mmio_base,
+		fpga_reg_write_8(q->d->mmio_base,
 				FPGA_5GNR_FEC_DDR4_RD_DONE_REGS, 1);
-		reg = fpga_reg_read_8(fpga_dev->mmio_base,
+		reg = fpga_reg_read_8(q->d->mmio_base,
 			FPGA_5GNR_FEC_DDR4_RD_RDY_REGS);
 		while (reg != 1) {
-			reg = fpga_reg_read_8(fpga_dev->mmio_base,
+			reg = fpga_reg_read_8(q->d->mmio_base,
 				FPGA_5GNR_FEC_DDR4_RD_RDY_REGS);
 			if (reg == FPGA_DDR_OVERFLOW) {
 				rte_bbdev_log(ERR,
@@ -1317,14 +1353,15 @@ fpga_harq_read_loopback(struct fpga_5gnr_fec_device *fpga_dev,
 				return -1;
 			}
 		}
-		input[increment] = fpga_reg_read_64(fpga_dev->mmio_base,
+		input[increment] = fpga_reg_read_64(q->d->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_reg_write_8(q->d->mmio_base,
 				FPGA_5GNR_FEC_DDR4_RD_DONE_REGS, 0);
 	}
+	fpga_mutex_free(q);
 	return 1;
 }
 
@@ -1467,13 +1504,13 @@ enqueue_ldpc_dec_one_op_cb(struct fpga_queue *q, struct rte_bbdev_dec_op *op,
 		if (check_bit(dec->op_flags,
 				RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE
 				)) {
-			ret = fpga_harq_write_loopback(q->d, harq_in,
+			ret = fpga_harq_write_loopback(q, harq_in,
 					harq_in_length, harq_in_offset,
 					harq_out_offset);
 		} else if (check_bit(dec->op_flags,
 				RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE
 				)) {
-			ret = fpga_harq_read_loopback(q->d, harq_out,
+			ret = fpga_harq_read_loopback(q, harq_out,
 				harq_in_length, harq_in_offset,
 				harq_out_offset);
 			dec->harq_combined_output.length = harq_in_length;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v1 3/5] baseband/fpga_5gnr_fec: add check for HARQ input length
  2022-05-09 20:17 [PATCH v1 0/5] baseband/fpga_5gnr: maintenance changes to fpga_5gnr PMD Hernan
  2022-05-09 20:17 ` [PATCH v1 1/5] baseband/fpga_5gnr_fec: remove FLR timeout Hernan
  2022-05-09 20:17 ` [PATCH v1 2/5] baseband/fpga_5gnr_fec: add FPGA Mutex Hernan
@ 2022-05-09 20:17 ` Hernan
  2022-05-09 20:17 ` [PATCH v1 4/5] baseband/fpga_5gnr_fec: enable validate LDPC enc/dec Hernan
  2022-05-09 20:17 ` [PATCH v1 5/5] baseband/fpga_5gnr_fec: remove filler from HARQ Hernan
  4 siblings, 0 replies; 11+ messages in thread
From: Hernan @ 2022-05-09 20:17 UTC (permalink / raw)
  To: dev, gakhil, trix; +Cc: nicolas.chautru, qi.z.zhang, Hernan

Add new case DESC_ERR_HARQ_INPUT_LEN to check for valid HARQ input
length.

Signed-off-by: Hernan <hernan.vargas@intel.com>
---
 drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h     | 1 +
 drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h b/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
index 993cf61974..e3038112fa 100644
--- a/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
+++ b/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
@@ -107,6 +107,7 @@ enum {
 	DESC_ERR_DESC_READ_FAIL = 0x8,
 	DESC_ERR_DESC_READ_TIMEOUT = 0x9,
 	DESC_ERR_DESC_READ_TLP_POISONED = 0xA,
+	DESC_ERR_HARQ_INPUT_LEN = 0xB,
 	DESC_ERR_CB_READ_FAIL = 0xC,
 	DESC_ERR_CB_READ_TIMEOUT = 0xD,
 	DESC_ERR_CB_READ_TLP_POISONED = 0xE,
diff --git a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
index 435b4d90d8..2d4b58067d 100644
--- a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
+++ b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
@@ -848,6 +848,9 @@ check_desc_error(uint32_t error_code) {
 	case DESC_ERR_DESC_READ_TLP_POISONED:
 		rte_bbdev_log(ERR, "Descriptor read TLP poisoned");
 		break;
+	case DESC_ERR_HARQ_INPUT_LEN:
+		rte_bbdev_log(ERR, "HARQ input length is invalid");
+		break;
 	case DESC_ERR_CB_READ_FAIL:
 		rte_bbdev_log(ERR, "Unsuccessful completion for code block");
 		break;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v1 4/5] baseband/fpga_5gnr_fec: enable validate LDPC enc/dec
  2022-05-09 20:17 [PATCH v1 0/5] baseband/fpga_5gnr: maintenance changes to fpga_5gnr PMD Hernan
                   ` (2 preceding siblings ...)
  2022-05-09 20:17 ` [PATCH v1 3/5] baseband/fpga_5gnr_fec: add check for HARQ input length Hernan
@ 2022-05-09 20:17 ` Hernan
  2022-05-09 21:04   ` Chautru, Nicolas
  2022-05-09 20:17 ` [PATCH v1 5/5] baseband/fpga_5gnr_fec: remove filler from HARQ Hernan
  4 siblings, 1 reply; 11+ messages in thread
From: Hernan @ 2022-05-09 20:17 UTC (permalink / raw)
  To: dev, gakhil, trix; +Cc: nicolas.chautru, qi.z.zhang, Hernan

Enable validate_ldpc_enc_op and validate_ldpc_dec_op

Signed-off-by: Hernan <hernan.vargas@intel.com>
---
 .../fpga_5gnr_fec/rte_fpga_5gnr_fec.c         | 490 ++++++++++++++----
 1 file changed, 384 insertions(+), 106 deletions(-)

diff --git a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
index 2d4b58067d..8fdb44c94a 100644
--- a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
+++ b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
@@ -1032,23 +1032,11 @@ fpga_dma_desc_ld_fill(struct rte_bbdev_dec_op *op,
 	return 0;
 }
 
-#ifdef RTE_LIBRTE_BBDEV_DEBUG
 /* Validates LDPC encoder parameters */
-static int
-validate_enc_op(struct rte_bbdev_enc_op *op __rte_unused)
+static inline int
+validate_ldpc_enc_op(struct rte_bbdev_enc_op *op)
 {
 	struct rte_bbdev_op_ldpc_enc *ldpc_enc = &op->ldpc_enc;
-	struct rte_bbdev_op_enc_ldpc_cb_params *cb = NULL;
-	struct rte_bbdev_op_enc_ldpc_tb_params *tb = NULL;
-
-
-	if (ldpc_enc->input.length >
-			RTE_BBDEV_LDPC_MAX_CB_SIZE >> 3) {
-		rte_bbdev_log(ERR, "CB size (%u) is too big, max: %d",
-				ldpc_enc->input.length,
-				RTE_BBDEV_LDPC_MAX_CB_SIZE);
-		return -1;
-	}
 
 	if (op->mempool == NULL) {
 		rte_bbdev_log(ERR, "Invalid mempool pointer");
@@ -1062,140 +1050,437 @@ validate_enc_op(struct rte_bbdev_enc_op *op __rte_unused)
 		rte_bbdev_log(ERR, "Invalid output pointer");
 		return -1;
 	}
+	if (ldpc_enc->input.length == 0) {
+		rte_bbdev_log(ERR, "CB size (%u) is null",
+				ldpc_enc->input.length);
+		return -1;
+	}
 	if ((ldpc_enc->basegraph > 2) || (ldpc_enc->basegraph == 0)) {
 		rte_bbdev_log(ERR,
-				"basegraph (%u) is out of range 1 <= value <= 2",
+				"BG (%u) is out of range 1 <= value <= 2",
 				ldpc_enc->basegraph);
 		return -1;
 	}
+	if (ldpc_enc->rv_index > 3) {
+		rte_bbdev_log(ERR,
+				"rv_index (%u) is out of range 0 <= value <= 3",
+				ldpc_enc->rv_index);
+		return -1;
+	}
 	if (ldpc_enc->code_block_mode > RTE_BBDEV_CODE_BLOCK) {
 		rte_bbdev_log(ERR,
-				"code_block_mode (%u) is out of range 0:Tb 1:CB",
+				"code_block_mode (%u) is out of range 0 <= value <= 1",
 				ldpc_enc->code_block_mode);
 		return -1;
 	}
 
-	if (ldpc_enc->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
-		tb = &ldpc_enc->tb_params;
-		if (tb->c == 0) {
-			rte_bbdev_log(ERR,
-					"c (%u) is out of range 1 <= value <= %u",
-					tb->c, RTE_BBDEV_LDPC_MAX_CODE_BLOCKS);
+	if (ldpc_enc->input.length >
+		RTE_BBDEV_LDPC_MAX_CB_SIZE >> 3) {
+		rte_bbdev_log(ERR, "CB size (%u) is too big, max: %d",
+				ldpc_enc->input.length,
+				RTE_BBDEV_LDPC_MAX_CB_SIZE);
+		return -1;
+	}
+	int z_c = ldpc_enc->z_c;
+	/* Check Zc is valid value */
+	if ((z_c > 384) || (z_c < 4)) {
+		rte_bbdev_log(ERR, "Zc (%u) is out of range", z_c);
+		return -1;
+	}
+	if (z_c > 256) {
+		if ((z_c % 32) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-		if (tb->cab > tb->c) {
-			rte_bbdev_log(ERR,
-					"cab (%u) is greater than c (%u)",
-					tb->cab, tb->c);
+	} else if (z_c > 128) {
+		if ((z_c % 16) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-		if ((tb->ea < RTE_BBDEV_LDPC_MIN_CB_SIZE)
-				&& tb->r < tb->cab) {
-			rte_bbdev_log(ERR,
-					"ea (%u) is less than %u or it is not even",
-					tb->ea, RTE_BBDEV_LDPC_MIN_CB_SIZE);
+	} else if (z_c > 64) {
+		if ((z_c % 8) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-		if ((tb->eb < RTE_BBDEV_LDPC_MIN_CB_SIZE)
-				&& tb->c > tb->cab) {
-			rte_bbdev_log(ERR,
-					"eb (%u) is less than %u",
-					tb->eb, RTE_BBDEV_LDPC_MIN_CB_SIZE);
+	} else if (z_c > 32) {
+		if ((z_c % 4) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-		if (tb->r > (tb->c - 1)) {
-			rte_bbdev_log(ERR,
-					"r (%u) is greater than c - 1 (%u)",
-					tb->r, tb->c - 1);
+	} else if (z_c > 16) {
+		if ((z_c % 2) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-	} else {
-		cb = &ldpc_enc->cb_params;
-		if (cb->e < RTE_BBDEV_LDPC_MIN_CB_SIZE) {
-			rte_bbdev_log(ERR,
-					"e (%u) is less than %u or it is not even",
-					cb->e, RTE_BBDEV_LDPC_MIN_CB_SIZE);
+	}
+
+	int n_filler = ldpc_enc->n_filler;
+	int K = (ldpc_enc->basegraph == 1 ? 22 : 10) * ldpc_enc->z_c;
+	int Kp = K - n_filler;
+	int q_m = ldpc_enc->q_m;
+	int n_cb = ldpc_enc->n_cb;
+	int N = (ldpc_enc->basegraph == 1 ? N_ZC_1 : N_ZC_2) * z_c;
+	int k0 = k0 = get_k0(n_cb, z_c, ldpc_enc->basegraph,
+			ldpc_enc->rv_index);
+	int crc24 = 0;
+	int32_t L, Lcb, cw, cw_rm;
+	int32_t e = ldpc_enc->cb_params.e;
+	if (check_bit(op->ldpc_enc.op_flags,
+			RTE_BBDEV_LDPC_CRC_24B_ATTACH))
+		crc24 = 24;
+
+	if (K < (int) (ldpc_enc->input.length * 8 + n_filler) + crc24) {
+		rte_bbdev_log(ERR, "K and F not matching input size %u %u %u",
+				K, n_filler, ldpc_enc->input.length);
+		return -1;
+	}
+	if (ldpc_enc->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
+		rte_bbdev_log(ERR, "TB mode not supported");
+		return -1;
+
+	}
+
+	/* K' range check */
+	if (Kp % 8 > 0) {
+		rte_bbdev_log(ERR, "K' not byte aligned %u", Kp);
+		return -1;
+	}
+	if ((crc24 > 0) && (Kp < 292)) {
+		rte_bbdev_log(ERR, "Invalid CRC24 for small block %u", Kp);
+		return -1;
+	}
+	if (Kp < 24) {
+		rte_bbdev_log(ERR, "K' too small %u", Kp);
+		return -1;
+	}
+	if (n_filler >= (K - 2 * z_c)) {
+		rte_bbdev_log(ERR, "K - F invalid %u %u", K, n_filler);
+		return -1;
+	}
+	/* Ncb range check */
+	if ((n_cb > N) || (n_cb < 32) || (n_cb <= (Kp - crc24))) {
+		rte_bbdev_log(ERR, "Ncb (%u) is out of range K  %d N %d", n_cb, K, N);
+		return -1;
+	}
+	/* Qm range check */
+	if (!check_bit(op->ldpc_enc.op_flags, RTE_BBDEV_LDPC_INTERLEAVER_BYPASS) &&
+			((q_m == 0) || ((q_m > 2) && ((q_m % 2) == 1)) || (q_m > 8))) {
+		rte_bbdev_log(ERR, "Qm (%u) is out of range", q_m);
+		return -1;
+	}
+	/* K0 range check */
+	if (((k0 % z_c) > 0) || (k0 >= n_cb) || ((k0 >= (Kp - 2 * z_c))
+			&& (k0 < (K - 2 * z_c)))) {
+		rte_bbdev_log(ERR, "K0 (%u) is out of range", k0);
+		return -1;
+	}
+	/* E range check */
+	if (e <= RTE_MAX(32, z_c)) {
+		rte_bbdev_log(ERR, "E is too small %"PRIu32"", e);
+		return -1;
+	}
+	if ((e > 0xFFFF)) {
+		rte_bbdev_log(ERR, "E is too large for N3000 %"PRIu32" > 64k", e);
+		return -1;
+	}
+	if (q_m > 0) {
+		if (e % q_m > 0) {
+			rte_bbdev_log(ERR, "E %"PRIu32" not multiple of qm %d", e, q_m);
 			return -1;
 		}
 	}
+	/* Code word in RM range check */
+	if (k0 > (Kp - 2 * z_c))
+		L = k0 + e;
+	else
+		L = k0 + e + n_filler;
+	Lcb = RTE_MIN(L, n_cb);
+	if (ldpc_enc->basegraph == 1) {
+		if (Lcb <= 25 * z_c)
+			cw = 25 * z_c;
+		else if (Lcb <= 27 * z_c)
+			cw = 27 * z_c;
+		else if (Lcb <= 30 * z_c)
+			cw = 30 * z_c;
+		else if (Lcb <= 33 * z_c)
+			cw = 33 * z_c;
+		else if (Lcb <= 44 * z_c)
+			cw = 44 * z_c;
+		else if (Lcb <= 55 * z_c)
+			cw = 55 * z_c;
+		else
+			cw = 66 * z_c;
+	} else {
+		if (Lcb <= 15 * z_c)
+			cw = 15 * z_c;
+		else if (Lcb <= 20 * z_c)
+			cw = 20 * z_c;
+		else if (Lcb <= 25 * z_c)
+			cw = 25 * z_c;
+		else if (Lcb <= 30 * z_c)
+			cw = 30 * z_c;
+		else
+			cw = 50 * z_c;
+	}
+	if (n_cb < Kp - 2 * z_c)
+		cw_rm = n_cb;
+	else if ((Kp - 2 * z_c <= n_cb) && (n_cb < K - 2 * z_c))
+		cw_rm = Kp - 2 * z_c;
+	else if ((K - 2 * z_c <= n_cb) && (n_cb < cw))
+		cw_rm = n_cb - n_filler;
+	else
+		cw_rm = cw - n_filler;
+	if (cw_rm <= 32) {
+		rte_bbdev_log(ERR,
+				"Invalid Ratematching");
+		return -1;
+	}
 	return 0;
 }
-#endif
-
-static inline char *
-mbuf_append(struct rte_mbuf *m_head, struct rte_mbuf *m, uint16_t len)
-{
-	if (unlikely(len > rte_pktmbuf_tailroom(m)))
-		return NULL;
-
-	char *tail = (char *)m->buf_addr + m->data_off + m->data_len;
-	m->data_len = (uint16_t)(m->data_len + len);
-	m_head->pkt_len  = (m_head->pkt_len + len);
-	return tail;
-}
 
-#ifdef RTE_LIBRTE_BBDEV_DEBUG
 /* Validates LDPC decoder parameters */
-static int
-validate_dec_op(struct rte_bbdev_dec_op *op __rte_unused)
+static inline int
+validate_ldpc_dec_op(struct rte_bbdev_dec_op *op)
 {
 	struct rte_bbdev_op_ldpc_dec *ldpc_dec = &op->ldpc_dec;
-	struct rte_bbdev_op_dec_ldpc_cb_params *cb = NULL;
-	struct rte_bbdev_op_dec_ldpc_tb_params *tb = NULL;
-
-	if (op->mempool == NULL) {
-		rte_bbdev_log(ERR, "Invalid mempool pointer");
+	if (check_bit(ldpc_dec->op_flags,
+			RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK))
+		return 0;
+	if (ldpc_dec->input.data == NULL) {
+		rte_bbdev_log(ERR, "Invalid input pointer");
 		return -1;
 	}
-	if (ldpc_dec->rv_index > 3) {
+	if (ldpc_dec->hard_output.data == NULL) {
+		rte_bbdev_log(ERR, "Invalid output pointer");
+		return -1;
+	}
+	if (ldpc_dec->input.length == 0) {
+		rte_bbdev_log(ERR, "input is null");
+		return -1;
+	}
+	if ((ldpc_dec->basegraph > 2) || (ldpc_dec->basegraph == 0)) {
 		rte_bbdev_log(ERR,
-				"rv_index (%u) is out of range 0 <= value <= 3",
-				ldpc_dec->rv_index);
+				"BG (%u) is out of range 1 <= value <= 2",
+				ldpc_dec->basegraph);
 		return -1;
 	}
-
 	if (ldpc_dec->iter_max == 0) {
 		rte_bbdev_log(ERR,
 				"iter_max (%u) is equal to 0",
 				ldpc_dec->iter_max);
 		return -1;
 	}
-
+	if (ldpc_dec->rv_index > 3) {
+		rte_bbdev_log(ERR,
+				"rv_index (%u) is out of range 0 <= value <= 3",
+				ldpc_dec->rv_index);
+		return -1;
+	}
 	if (ldpc_dec->code_block_mode > RTE_BBDEV_CODE_BLOCK) {
 		rte_bbdev_log(ERR,
 				"code_block_mode (%u) is out of range 0 <= value <= 1",
 				ldpc_dec->code_block_mode);
 		return -1;
 	}
-
-	if (ldpc_dec->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
-		tb = &ldpc_dec->tb_params;
-		if (tb->c < 1) {
-			rte_bbdev_log(ERR,
-					"c (%u) is out of range 1 <= value <= %u",
-					tb->c, RTE_BBDEV_LDPC_MAX_CODE_BLOCKS);
+	if (check_bit(op->ldpc_dec.op_flags,
+			RTE_BBDEV_LDPC_DECODE_BYPASS)) {
+		rte_bbdev_log(ERR, "Avoid LDPC Decode bypass");
+		return -1;
+	}
+	int z_c = ldpc_dec->z_c;
+	/* Check Zc is valid value */
+	if ((z_c > 384) || (z_c < 4)) {
+		rte_bbdev_log(ERR,
+				"Zc (%u) is out of range",
+				z_c);
+		return -1;
+	}
+	if (z_c > 256) {
+		if ((z_c % 32) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-		if (tb->cab > tb->c) {
-			rte_bbdev_log(ERR,
-					"cab (%u) is greater than c (%u)",
-					tb->cab, tb->c);
+	} else if (z_c > 128) {
+		if ((z_c % 16) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-	} else {
-		cb = &ldpc_dec->cb_params;
-		if (cb->e < RTE_BBDEV_LDPC_MIN_CB_SIZE) {
-			rte_bbdev_log(ERR,
-					"e (%u) is out of range %u <= value <= %u",
-					cb->e, RTE_BBDEV_LDPC_MIN_CB_SIZE,
-					RTE_BBDEV_LDPC_MAX_CB_SIZE);
+	} else if (z_c > 64) {
+		if ((z_c % 8) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
+			return -1;
+		}
+	} else if (z_c > 32) {
+		if ((z_c % 4) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
+			return -1;
+		}
+	} else if (z_c > 16) {
+		if ((z_c % 2) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
 	}
 
+	int n_filler = ldpc_dec->n_filler;
+	int K = (ldpc_dec->basegraph == 1 ? 22 : 10) * ldpc_dec->z_c;
+	int Kp = K - n_filler;
+	int q_m = ldpc_dec->q_m;
+	int n_cb = ldpc_dec->n_cb;
+	int N = (ldpc_dec->basegraph == 1 ? N_ZC_1 : N_ZC_2) * z_c;
+	int k0 = k0 = get_k0(n_cb, z_c, ldpc_dec->basegraph,
+			ldpc_dec->rv_index);
+	int crc24 = 0;
+	int32_t L, Lcb, cw, cw_rm;
+	int32_t e = ldpc_dec->cb_params.e;
+	if (check_bit(op->ldpc_dec.op_flags,
+			RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK))
+		crc24 = 24;
+
+	if (ldpc_dec->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
+		rte_bbdev_log(ERR,
+				"TB mode not supported");
+		return -1;
+	}
+	/* Enforce HARQ input length */
+	ldpc_dec->harq_combined_input.length = RTE_MIN((uint32_t) n_cb,
+			ldpc_dec->harq_combined_input.length);
+	if ((ldpc_dec->harq_combined_input.length == 0) &&
+			check_bit(ldpc_dec->op_flags,
+			RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE)) {
+		rte_bbdev_log(ERR,
+				"HARQ input length (%u) should not be null",
+				ldpc_dec->harq_combined_input.length);
+		return -1;
+	}
+	if ((ldpc_dec->harq_combined_input.length > 0) &&
+			!check_bit(ldpc_dec->op_flags,
+			RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE)) {
+		ldpc_dec->harq_combined_input.length = 0;
+	}
+
+	/* K' range check */
+	if (Kp % 8 > 0) {
+		rte_bbdev_log(ERR,
+				"K' not byte aligned %u",
+				Kp);
+		return -1;
+	}
+	if ((crc24 > 0) && (Kp < 292)) {
+		rte_bbdev_log(ERR,
+				"Invalid CRC24 for small block %u",
+				Kp);
+		return -1;
+	}
+	if (Kp < 24) {
+		rte_bbdev_log(ERR,
+				"K' too small %u",
+				Kp);
+		return -1;
+	}
+	if (n_filler >= (K - 2 * z_c)) {
+		rte_bbdev_log(ERR,
+				"K - F invalid %u %u",
+				K, n_filler);
+		return -1;
+	}
+	/* Ncb range check */
+	if (n_cb != N) {
+		rte_bbdev_log(ERR,
+				"Ncb (%u) is out of range K  %d N %d",
+				n_cb, K, N);
+		return -1;
+	}
+	/* Qm range check */
+	if (!check_bit(op->ldpc_dec.op_flags,
+			RTE_BBDEV_LDPC_INTERLEAVER_BYPASS) &&
+			((q_m == 0) || ((q_m > 2) && ((q_m % 2) == 1))
+			|| (q_m > 8))) {
+		rte_bbdev_log(ERR,
+				"Qm (%u) is out of range",
+				q_m);
+		return -1;
+	}
+	/* K0 range check */
+	if (((k0 % z_c) > 0) || (k0 >= n_cb) || ((k0 >= (Kp - 2 * z_c))
+			&& (k0 < (K - 2 * z_c)))) {
+		rte_bbdev_log(ERR,
+				"K0 (%u) is out of range",
+				k0);
+		return -1;
+	}
+	/* E range check */
+	if (e <= RTE_MAX(32, z_c)) {
+		rte_bbdev_log(ERR,
+				"E is too small");
+		return -1;
+	}
+	if ((e > 0xFFFF)) {
+		rte_bbdev_log(ERR,
+				"E is too large");
+		return -1;
+	}
+	if (q_m > 0) {
+		if (e % q_m > 0) {
+			rte_bbdev_log(ERR,
+					"E not multiple of qm %d", q_m);
+			return -1;
+		}
+	}
+	/* Code word in RM range check */
+	if (k0 > (Kp - 2 * z_c))
+		L = k0 + e;
+	else
+		L = k0 + e + n_filler;
+	Lcb = RTE_MIN(n_cb, RTE_MAX(L,
+			(int32_t) ldpc_dec->harq_combined_input.length));
+	if (ldpc_dec->basegraph == 1) {
+		if (Lcb <= 25 * z_c)
+			cw = 25 * z_c;
+		else if (Lcb <= 27 * z_c)
+			cw = 27 * z_c;
+		else if (Lcb <= 30 * z_c)
+			cw = 30 * z_c;
+		else if (Lcb <= 33 * z_c)
+			cw = 33 * z_c;
+		else if (Lcb <= 44 * z_c)
+			cw = 44 * z_c;
+		else if (Lcb <= 55 * z_c)
+			cw = 55 * z_c;
+		else
+			cw = 66 * z_c;
+	} else {
+		if (Lcb <= 15 * z_c)
+			cw = 15 * z_c;
+		else if (Lcb <= 20 * z_c)
+			cw = 20 * z_c;
+		else if (Lcb <= 25 * z_c)
+			cw = 25 * z_c;
+		else if (Lcb <= 30 * z_c)
+			cw = 30 * z_c;
+		else
+			cw = 50 * z_c;
+	}
+	cw_rm = cw - n_filler;
+	if (cw_rm <= 32) {
+		rte_bbdev_log(ERR,
+				"Invalid Ratematching");
+		return -1;
+	}
 	return 0;
 }
-#endif
+
+static inline char *
+mbuf_append(struct rte_mbuf *m_head, struct rte_mbuf *m, uint16_t len)
+{
+	if (unlikely(len > rte_pktmbuf_tailroom(m)))
+		return NULL;
+
+	char *tail = (char *)m->buf_addr + m->data_off + m->data_len;
+	m->data_len = (uint16_t)(m->data_len + len);
+	m_head->pkt_len  = (m_head->pkt_len + len);
+	return tail;
+}
 
 static inline void
 fpga_mutex_acquisition(struct fpga_queue *q)
@@ -1386,14 +1671,11 @@ enqueue_ldpc_enc_one_op_cb(struct fpga_queue *q, struct rte_bbdev_enc_op *op,
 	uint16_t ring_offset;
 	uint16_t K, k_;
 
-#ifdef RTE_LIBRTE_BBDEV_DEBUG
-	/* Validate op structure */
-	/* FIXME */
-	if (validate_enc_op(op) == -1) {
-		rte_bbdev_log(ERR, "LDPC encoder validation failed");
+
+	if (validate_ldpc_enc_op(op) == -1) {
+		rte_bbdev_log(ERR, "LDPC encoder validation rejected");
 		return -EINVAL;
 	}
-#endif
 
 	/* Clear op status */
 	op->status = 0;
@@ -1481,13 +1763,10 @@ enqueue_ldpc_dec_one_op_cb(struct fpga_queue *q, struct rte_bbdev_dec_op *op,
 	uint16_t out_offset = dec->hard_output.offset;
 	uint32_t harq_offset = 0;
 
-#ifdef RTE_LIBRTE_BBDEV_DEBUG
-		/* Validate op structure */
-		if (validate_dec_op(op) == -1) {
-			rte_bbdev_log(ERR, "LDPC decoder validation failed");
-			return -EINVAL;
-		}
-#endif
+	if (validate_ldpc_dec_op(op) == -1) {
+		rte_bbdev_log(ERR, "LDPC decoder validation rejected");
+		return -EINVAL;
+	}
 
 	/* Clear op status */
 	op->status = 0;
@@ -1717,8 +1996,7 @@ fpga_enqueue_ldpc_dec(struct rte_bbdev_queue_data *q_data,
 
 
 static inline int
-dequeue_ldpc_enc_one_op_cb(struct fpga_queue *q,
-		struct rte_bbdev_enc_op **op,
+dequeue_ldpc_enc_one_op_cb(struct fpga_queue *q, struct rte_bbdev_enc_op **op,
 		uint16_t desc_offset)
 {
 	union fpga_dma_desc *desc;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v1 5/5] baseband/fpga_5gnr_fec: remove filler from HARQ
  2022-05-09 20:17 [PATCH v1 0/5] baseband/fpga_5gnr: maintenance changes to fpga_5gnr PMD Hernan
                   ` (3 preceding siblings ...)
  2022-05-09 20:17 ` [PATCH v1 4/5] baseband/fpga_5gnr_fec: enable validate LDPC enc/dec Hernan
@ 2022-05-09 20:17 ` Hernan
  2022-05-16 18:07   ` [EXT] " Akhil Goyal
  4 siblings, 1 reply; 11+ messages in thread
From: Hernan @ 2022-05-09 20:17 UTC (permalink / raw)
  To: dev, gakhil, trix; +Cc: nicolas.chautru, qi.z.zhang, Hernan

Removed dec->n_filler from harq_out_length calculation.

Signed-off-by: Hernan <hernan.vargas@intel.com>
---
 drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
index 8fdb44c94a..22a548a336 100644
--- a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
+++ b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
@@ -1844,7 +1844,7 @@ enqueue_ldpc_dec_one_op_cb(struct fpga_queue *q, struct rte_bbdev_dec_op *op,
 		else
 			l = k0 + e + dec->n_filler;
 		harq_out_length = RTE_MIN(RTE_MAX(harq_in_length, l),
-				dec->n_cb - dec->n_filler);
+				dec->n_cb);
 		dec->harq_combined_output.length = harq_out_length;
 	}
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [PATCH v1 4/5] baseband/fpga_5gnr_fec: enable validate LDPC enc/dec
  2022-05-09 20:17 ` [PATCH v1 4/5] baseband/fpga_5gnr_fec: enable validate LDPC enc/dec Hernan
@ 2022-05-09 21:04   ` Chautru, Nicolas
  0 siblings, 0 replies; 11+ messages in thread
From: Chautru, Nicolas @ 2022-05-09 21:04 UTC (permalink / raw)
  To: Vargas, Hernan, dev, gakhil, trix; +Cc: Zhang, Qi Z



> -----Original Message-----
> From: Vargas, Hernan <hernan.vargas@intel.com>
> Sent: Monday, May 9, 2022 1:18 PM
> To: dev@dpdk.org; gakhil@marvell.com; trix@redhat.com
> Cc: Chautru, Nicolas <nicolas.chautru@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Vargas, Hernan <hernan.vargas@intel.com>
> Subject: [PATCH v1 4/5] baseband/fpga_5gnr_fec: enable validate LDPC
> enc/dec
> 
> Enable validate_ldpc_enc_op and validate_ldpc_dec_op
> 
> Signed-off-by: Hernan <hernan.vargas@intel.com>
> ---
>  .../fpga_5gnr_fec/rte_fpga_5gnr_fec.c         | 490 ++++++++++++++----
>  1 file changed, 384 insertions(+), 106 deletions(-)
> 
> diff --git a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> index 2d4b58067d..8fdb44c94a 100644
> --- a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> +++ b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> @@ -1032,23 +1032,11 @@ fpga_dma_desc_ld_fill(struct rte_bbdev_dec_op
> *op,
>  	return 0;
>  }
> 
> -#ifdef RTE_LIBRTE_BBDEV_DEBUG
>  /* Validates LDPC encoder parameters */ -static int -validate_enc_op(struct
> rte_bbdev_enc_op *op __rte_unused)
> +static inline int
> +validate_ldpc_enc_op(struct rte_bbdev_enc_op *op)
>  {
>  	struct rte_bbdev_op_ldpc_enc *ldpc_enc = &op->ldpc_enc;
> -	struct rte_bbdev_op_enc_ldpc_cb_params *cb = NULL;
> -	struct rte_bbdev_op_enc_ldpc_tb_params *tb = NULL;
> -
> -
> -	if (ldpc_enc->input.length >
> -			RTE_BBDEV_LDPC_MAX_CB_SIZE >> 3) {
> -		rte_bbdev_log(ERR, "CB size (%u) is too big, max: %d",
> -				ldpc_enc->input.length,
> -				RTE_BBDEV_LDPC_MAX_CB_SIZE);
> -		return -1;
> -	}
> 
>  	if (op->mempool == NULL) {
>  		rte_bbdev_log(ERR, "Invalid mempool pointer"); @@ -
> 1062,140 +1050,437 @@ validate_enc_op(struct rte_bbdev_enc_op *op
> __rte_unused)
>  		rte_bbdev_log(ERR, "Invalid output pointer");
>  		return -1;
>  	}
> +	if (ldpc_enc->input.length == 0) {
> +		rte_bbdev_log(ERR, "CB size (%u) is null",
> +				ldpc_enc->input.length);
> +		return -1;
> +	}
>  	if ((ldpc_enc->basegraph > 2) || (ldpc_enc->basegraph == 0)) {
>  		rte_bbdev_log(ERR,
> -				"basegraph (%u) is out of range 1 <= value <=
> 2",
> +				"BG (%u) is out of range 1 <= value <= 2",
>  				ldpc_enc->basegraph);
>  		return -1;
>  	}
> +	if (ldpc_enc->rv_index > 3) {
> +		rte_bbdev_log(ERR,
> +				"rv_index (%u) is out of range 0 <= value <=
> 3",
> +				ldpc_enc->rv_index);
> +		return -1;
> +	}
>  	if (ldpc_enc->code_block_mode > RTE_BBDEV_CODE_BLOCK) {
>  		rte_bbdev_log(ERR,
> -				"code_block_mode (%u) is out of range 0:Tb
> 1:CB",
> +				"code_block_mode (%u) is out of range 0 <=
> value <= 1",
>  				ldpc_enc->code_block_mode);
>  		return -1;
>  	}
> 
> -	if (ldpc_enc->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
> -		tb = &ldpc_enc->tb_params;
> -		if (tb->c == 0) {
> -			rte_bbdev_log(ERR,
> -					"c (%u) is out of range 1 <= value <=
> %u",
> -					tb->c,
> RTE_BBDEV_LDPC_MAX_CODE_BLOCKS);
> +	if (ldpc_enc->input.length >
> +		RTE_BBDEV_LDPC_MAX_CB_SIZE >> 3) {
> +		rte_bbdev_log(ERR, "CB size (%u) is too big, max: %d",
> +				ldpc_enc->input.length,
> +				RTE_BBDEV_LDPC_MAX_CB_SIZE);
> +		return -1;
> +	}
> +	int z_c = ldpc_enc->z_c;
> +	/* Check Zc is valid value */
> +	if ((z_c > 384) || (z_c < 4)) {
> +		rte_bbdev_log(ERR, "Zc (%u) is out of range", z_c);
> +		return -1;
> +	}
> +	if (z_c > 256) {
> +		if ((z_c % 32) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -		if (tb->cab > tb->c) {
> -			rte_bbdev_log(ERR,
> -					"cab (%u) is greater than c (%u)",
> -					tb->cab, tb->c);
> +	} else if (z_c > 128) {
> +		if ((z_c % 16) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -		if ((tb->ea < RTE_BBDEV_LDPC_MIN_CB_SIZE)
> -				&& tb->r < tb->cab) {
> -			rte_bbdev_log(ERR,
> -					"ea (%u) is less than %u or it is not
> even",
> -					tb->ea,
> RTE_BBDEV_LDPC_MIN_CB_SIZE);
> +	} else if (z_c > 64) {
> +		if ((z_c % 8) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -		if ((tb->eb < RTE_BBDEV_LDPC_MIN_CB_SIZE)
> -				&& tb->c > tb->cab) {
> -			rte_bbdev_log(ERR,
> -					"eb (%u) is less than %u",
> -					tb->eb,
> RTE_BBDEV_LDPC_MIN_CB_SIZE);
> +	} else if (z_c > 32) {
> +		if ((z_c % 4) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -		if (tb->r > (tb->c - 1)) {
> -			rte_bbdev_log(ERR,
> -					"r (%u) is greater than c - 1 (%u)",
> -					tb->r, tb->c - 1);
> +	} else if (z_c > 16) {
> +		if ((z_c % 2) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -	} else {
> -		cb = &ldpc_enc->cb_params;
> -		if (cb->e < RTE_BBDEV_LDPC_MIN_CB_SIZE) {
> -			rte_bbdev_log(ERR,
> -					"e (%u) is less than %u or it is not
> even",
> -					cb->e,
> RTE_BBDEV_LDPC_MIN_CB_SIZE);
> +	}
> +
> +	int n_filler = ldpc_enc->n_filler;
> +	int K = (ldpc_enc->basegraph == 1 ? 22 : 10) * ldpc_enc->z_c;
> +	int Kp = K - n_filler;
> +	int q_m = ldpc_enc->q_m;
> +	int n_cb = ldpc_enc->n_cb;
> +	int N = (ldpc_enc->basegraph == 1 ? N_ZC_1 : N_ZC_2) * z_c;
> +	int k0 = k0 = get_k0(n_cb, z_c, ldpc_enc->basegraph,
> +			ldpc_enc->rv_index);

There is a typo here. And the same one below. 

> +	int crc24 = 0;
> +	int32_t L, Lcb, cw, cw_rm;
> +	int32_t e = ldpc_enc->cb_params.e;
> +	if (check_bit(op->ldpc_enc.op_flags,
> +			RTE_BBDEV_LDPC_CRC_24B_ATTACH))
> +		crc24 = 24;
> +
> +	if (K < (int) (ldpc_enc->input.length * 8 + n_filler) + crc24) {
> +		rte_bbdev_log(ERR, "K and F not matching input size %u %u
> %u",
> +				K, n_filler, ldpc_enc->input.length);
> +		return -1;
> +	}
> +	if (ldpc_enc->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
> +		rte_bbdev_log(ERR, "TB mode not supported");
> +		return -1;
> +
> +	}
> +
> +	/* K' range check */
> +	if (Kp % 8 > 0) {
> +		rte_bbdev_log(ERR, "K' not byte aligned %u", Kp);
> +		return -1;
> +	}
> +	if ((crc24 > 0) && (Kp < 292)) {
> +		rte_bbdev_log(ERR, "Invalid CRC24 for small block %u", Kp);
> +		return -1;
> +	}
> +	if (Kp < 24) {
> +		rte_bbdev_log(ERR, "K' too small %u", Kp);
> +		return -1;
> +	}
> +	if (n_filler >= (K - 2 * z_c)) {
> +		rte_bbdev_log(ERR, "K - F invalid %u %u", K, n_filler);
> +		return -1;
> +	}
> +	/* Ncb range check */
> +	if ((n_cb > N) || (n_cb < 32) || (n_cb <= (Kp - crc24))) {
> +		rte_bbdev_log(ERR, "Ncb (%u) is out of range K  %d N %d",
> n_cb, K, N);
> +		return -1;
> +	}
> +	/* Qm range check */
> +	if (!check_bit(op->ldpc_enc.op_flags,
> RTE_BBDEV_LDPC_INTERLEAVER_BYPASS) &&
> +			((q_m == 0) || ((q_m > 2) && ((q_m % 2) == 1)) ||
> (q_m > 8))) {
> +		rte_bbdev_log(ERR, "Qm (%u) is out of range", q_m);
> +		return -1;
> +	}
> +	/* K0 range check */
> +	if (((k0 % z_c) > 0) || (k0 >= n_cb) || ((k0 >= (Kp - 2 * z_c))
> +			&& (k0 < (K - 2 * z_c)))) {
> +		rte_bbdev_log(ERR, "K0 (%u) is out of range", k0);
> +		return -1;
> +	}
> +	/* E range check */
> +	if (e <= RTE_MAX(32, z_c)) {
> +		rte_bbdev_log(ERR, "E is too small %"PRIu32"", e);
> +		return -1;
> +	}
> +	if ((e > 0xFFFF)) {
> +		rte_bbdev_log(ERR, "E is too large for N3000 %"PRIu32" >
> 64k", e);
> +		return -1;
> +	}
> +	if (q_m > 0) {
> +		if (e % q_m > 0) {
> +			rte_bbdev_log(ERR, "E %"PRIu32" not multiple of qm
> %d", e, q_m);
>  			return -1;
>  		}
>  	}
> +	/* Code word in RM range check */
> +	if (k0 > (Kp - 2 * z_c))
> +		L = k0 + e;
> +	else
> +		L = k0 + e + n_filler;
> +	Lcb = RTE_MIN(L, n_cb);
> +	if (ldpc_enc->basegraph == 1) {
> +		if (Lcb <= 25 * z_c)
> +			cw = 25 * z_c;
> +		else if (Lcb <= 27 * z_c)
> +			cw = 27 * z_c;
> +		else if (Lcb <= 30 * z_c)
> +			cw = 30 * z_c;
> +		else if (Lcb <= 33 * z_c)
> +			cw = 33 * z_c;
> +		else if (Lcb <= 44 * z_c)
> +			cw = 44 * z_c;
> +		else if (Lcb <= 55 * z_c)
> +			cw = 55 * z_c;
> +		else
> +			cw = 66 * z_c;
> +	} else {
> +		if (Lcb <= 15 * z_c)
> +			cw = 15 * z_c;
> +		else if (Lcb <= 20 * z_c)
> +			cw = 20 * z_c;
> +		else if (Lcb <= 25 * z_c)
> +			cw = 25 * z_c;
> +		else if (Lcb <= 30 * z_c)
> +			cw = 30 * z_c;
> +		else
> +			cw = 50 * z_c;
> +	}
> +	if (n_cb < Kp - 2 * z_c)
> +		cw_rm = n_cb;
> +	else if ((Kp - 2 * z_c <= n_cb) && (n_cb < K - 2 * z_c))
> +		cw_rm = Kp - 2 * z_c;
> +	else if ((K - 2 * z_c <= n_cb) && (n_cb < cw))
> +		cw_rm = n_cb - n_filler;
> +	else
> +		cw_rm = cw - n_filler;
> +	if (cw_rm <= 32) {
> +		rte_bbdev_log(ERR,
> +				"Invalid Ratematching");
> +		return -1;
> +	}
>  	return 0;
>  }
> -#endif
> -
> -static inline char *
> -mbuf_append(struct rte_mbuf *m_head, struct rte_mbuf *m, uint16_t len) -{
> -	if (unlikely(len > rte_pktmbuf_tailroom(m)))
> -		return NULL;
> -
> -	char *tail = (char *)m->buf_addr + m->data_off + m->data_len;
> -	m->data_len = (uint16_t)(m->data_len + len);
> -	m_head->pkt_len  = (m_head->pkt_len + len);
> -	return tail;
> -}
> 
> -#ifdef RTE_LIBRTE_BBDEV_DEBUG
>  /* Validates LDPC decoder parameters */ -static int -validate_dec_op(struct
> rte_bbdev_dec_op *op __rte_unused)
> +static inline int
> +validate_ldpc_dec_op(struct rte_bbdev_dec_op *op)
>  {
>  	struct rte_bbdev_op_ldpc_dec *ldpc_dec = &op->ldpc_dec;
> -	struct rte_bbdev_op_dec_ldpc_cb_params *cb = NULL;
> -	struct rte_bbdev_op_dec_ldpc_tb_params *tb = NULL;
> -
> -	if (op->mempool == NULL) {
> -		rte_bbdev_log(ERR, "Invalid mempool pointer");
> +	if (check_bit(ldpc_dec->op_flags,
> +
> 	RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK))
> +		return 0;
> +	if (ldpc_dec->input.data == NULL) {
> +		rte_bbdev_log(ERR, "Invalid input pointer");
>  		return -1;
>  	}
> -	if (ldpc_dec->rv_index > 3) {
> +	if (ldpc_dec->hard_output.data == NULL) {
> +		rte_bbdev_log(ERR, "Invalid output pointer");
> +		return -1;
> +	}
> +	if (ldpc_dec->input.length == 0) {
> +		rte_bbdev_log(ERR, "input is null");
> +		return -1;
> +	}
> +	if ((ldpc_dec->basegraph > 2) || (ldpc_dec->basegraph == 0)) {
>  		rte_bbdev_log(ERR,
> -				"rv_index (%u) is out of range 0 <= value <=
> 3",
> -				ldpc_dec->rv_index);
> +				"BG (%u) is out of range 1 <= value <= 2",
> +				ldpc_dec->basegraph);
>  		return -1;
>  	}
> -
>  	if (ldpc_dec->iter_max == 0) {
>  		rte_bbdev_log(ERR,
>  				"iter_max (%u) is equal to 0",
>  				ldpc_dec->iter_max);
>  		return -1;
>  	}
> -
> +	if (ldpc_dec->rv_index > 3) {
> +		rte_bbdev_log(ERR,
> +				"rv_index (%u) is out of range 0 <= value <=
> 3",
> +				ldpc_dec->rv_index);
> +		return -1;
> +	}
>  	if (ldpc_dec->code_block_mode > RTE_BBDEV_CODE_BLOCK) {
>  		rte_bbdev_log(ERR,
>  				"code_block_mode (%u) is out of range 0 <=
> value <= 1",
>  				ldpc_dec->code_block_mode);
>  		return -1;
>  	}
> -
> -	if (ldpc_dec->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
> -		tb = &ldpc_dec->tb_params;
> -		if (tb->c < 1) {
> -			rte_bbdev_log(ERR,
> -					"c (%u) is out of range 1 <= value <=
> %u",
> -					tb->c,
> RTE_BBDEV_LDPC_MAX_CODE_BLOCKS);
> +	if (check_bit(op->ldpc_dec.op_flags,
> +			RTE_BBDEV_LDPC_DECODE_BYPASS)) {
> +		rte_bbdev_log(ERR, "Avoid LDPC Decode bypass");
> +		return -1;
> +	}
> +	int z_c = ldpc_dec->z_c;
> +	/* Check Zc is valid value */
> +	if ((z_c > 384) || (z_c < 4)) {
> +		rte_bbdev_log(ERR,
> +				"Zc (%u) is out of range",
> +				z_c);
> +		return -1;
> +	}
> +	if (z_c > 256) {
> +		if ((z_c % 32) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -		if (tb->cab > tb->c) {
> -			rte_bbdev_log(ERR,
> -					"cab (%u) is greater than c (%u)",
> -					tb->cab, tb->c);
> +	} else if (z_c > 128) {
> +		if ((z_c % 16) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -	} else {
> -		cb = &ldpc_dec->cb_params;
> -		if (cb->e < RTE_BBDEV_LDPC_MIN_CB_SIZE) {
> -			rte_bbdev_log(ERR,
> -					"e (%u) is out of range %u <= value <=
> %u",
> -					cb->e,
> RTE_BBDEV_LDPC_MIN_CB_SIZE,
> -					RTE_BBDEV_LDPC_MAX_CB_SIZE);
> +	} else if (z_c > 64) {
> +		if ((z_c % 8) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
> +			return -1;
> +		}
> +	} else if (z_c > 32) {
> +		if ((z_c % 4) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
> +			return -1;
> +		}
> +	} else if (z_c > 16) {
> +		if ((z_c % 2) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
>  	}
> 
> +	int n_filler = ldpc_dec->n_filler;
> +	int K = (ldpc_dec->basegraph == 1 ? 22 : 10) * ldpc_dec->z_c;
> +	int Kp = K - n_filler;
> +	int q_m = ldpc_dec->q_m;
> +	int n_cb = ldpc_dec->n_cb;
> +	int N = (ldpc_dec->basegraph == 1 ? N_ZC_1 : N_ZC_2) * z_c;
> +	int k0 = k0 = get_k0(n_cb, z_c, ldpc_dec->basegraph,
> +			ldpc_dec->rv_index);
> +	int crc24 = 0;
> +	int32_t L, Lcb, cw, cw_rm;
> +	int32_t e = ldpc_dec->cb_params.e;
> +	if (check_bit(op->ldpc_dec.op_flags,
> +			RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK))
> +		crc24 = 24;
> +
> +	if (ldpc_dec->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
> +		rte_bbdev_log(ERR,
> +				"TB mode not supported");
> +		return -1;
> +	}
> +	/* Enforce HARQ input length */
> +	ldpc_dec->harq_combined_input.length = RTE_MIN((uint32_t) n_cb,
> +			ldpc_dec->harq_combined_input.length);
> +	if ((ldpc_dec->harq_combined_input.length == 0) &&
> +			check_bit(ldpc_dec->op_flags,
> +			RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE)) {
> +		rte_bbdev_log(ERR,
> +				"HARQ input length (%u) should not be null",
> +				ldpc_dec->harq_combined_input.length);
> +		return -1;
> +	}
> +	if ((ldpc_dec->harq_combined_input.length > 0) &&
> +			!check_bit(ldpc_dec->op_flags,
> +			RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE)) {
> +		ldpc_dec->harq_combined_input.length = 0;
> +	}
> +
> +	/* K' range check */
> +	if (Kp % 8 > 0) {
> +		rte_bbdev_log(ERR,
> +				"K' not byte aligned %u",
> +				Kp);
> +		return -1;
> +	}
> +	if ((crc24 > 0) && (Kp < 292)) {
> +		rte_bbdev_log(ERR,
> +				"Invalid CRC24 for small block %u",
> +				Kp);
> +		return -1;
> +	}
> +	if (Kp < 24) {
> +		rte_bbdev_log(ERR,
> +				"K' too small %u",
> +				Kp);
> +		return -1;
> +	}
> +	if (n_filler >= (K - 2 * z_c)) {
> +		rte_bbdev_log(ERR,
> +				"K - F invalid %u %u",
> +				K, n_filler);
> +		return -1;
> +	}
> +	/* Ncb range check */
> +	if (n_cb != N) {
> +		rte_bbdev_log(ERR,
> +				"Ncb (%u) is out of range K  %d N %d",
> +				n_cb, K, N);
> +		return -1;
> +	}
> +	/* Qm range check */
> +	if (!check_bit(op->ldpc_dec.op_flags,
> +			RTE_BBDEV_LDPC_INTERLEAVER_BYPASS) &&
> +			((q_m == 0) || ((q_m > 2) && ((q_m % 2) == 1))
> +			|| (q_m > 8))) {
> +		rte_bbdev_log(ERR,
> +				"Qm (%u) is out of range",
> +				q_m);
> +		return -1;
> +	}
> +	/* K0 range check */
> +	if (((k0 % z_c) > 0) || (k0 >= n_cb) || ((k0 >= (Kp - 2 * z_c))
> +			&& (k0 < (K - 2 * z_c)))) {
> +		rte_bbdev_log(ERR,
> +				"K0 (%u) is out of range",
> +				k0);
> +		return -1;
> +	}
> +	/* E range check */
> +	if (e <= RTE_MAX(32, z_c)) {
> +		rte_bbdev_log(ERR,
> +				"E is too small");
> +		return -1;
> +	}
> +	if ((e > 0xFFFF)) {
> +		rte_bbdev_log(ERR,
> +				"E is too large");
> +		return -1;
> +	}
> +	if (q_m > 0) {
> +		if (e % q_m > 0) {
> +			rte_bbdev_log(ERR,
> +					"E not multiple of qm %d", q_m);
> +			return -1;
> +		}
> +	}
> +	/* Code word in RM range check */
> +	if (k0 > (Kp - 2 * z_c))
> +		L = k0 + e;
> +	else
> +		L = k0 + e + n_filler;
> +	Lcb = RTE_MIN(n_cb, RTE_MAX(L,
> +			(int32_t) ldpc_dec->harq_combined_input.length));
> +	if (ldpc_dec->basegraph == 1) {
> +		if (Lcb <= 25 * z_c)
> +			cw = 25 * z_c;
> +		else if (Lcb <= 27 * z_c)
> +			cw = 27 * z_c;
> +		else if (Lcb <= 30 * z_c)
> +			cw = 30 * z_c;
> +		else if (Lcb <= 33 * z_c)
> +			cw = 33 * z_c;
> +		else if (Lcb <= 44 * z_c)
> +			cw = 44 * z_c;
> +		else if (Lcb <= 55 * z_c)
> +			cw = 55 * z_c;
> +		else
> +			cw = 66 * z_c;
> +	} else {
> +		if (Lcb <= 15 * z_c)
> +			cw = 15 * z_c;
> +		else if (Lcb <= 20 * z_c)
> +			cw = 20 * z_c;
> +		else if (Lcb <= 25 * z_c)
> +			cw = 25 * z_c;
> +		else if (Lcb <= 30 * z_c)
> +			cw = 30 * z_c;
> +		else
> +			cw = 50 * z_c;
> +	}
> +	cw_rm = cw - n_filler;
> +	if (cw_rm <= 32) {
> +		rte_bbdev_log(ERR,
> +				"Invalid Ratematching");
> +		return -1;
> +	}
>  	return 0;
>  }
> -#endif
> +
> +static inline char *
> +mbuf_append(struct rte_mbuf *m_head, struct rte_mbuf *m, uint16_t len)
> +{
> +	if (unlikely(len > rte_pktmbuf_tailroom(m)))
> +		return NULL;
> +
> +	char *tail = (char *)m->buf_addr + m->data_off + m->data_len;
> +	m->data_len = (uint16_t)(m->data_len + len);
> +	m_head->pkt_len  = (m_head->pkt_len + len);
> +	return tail;
> +}
> 
>  static inline void
>  fpga_mutex_acquisition(struct fpga_queue *q) @@ -1386,14 +1671,11 @@
> enqueue_ldpc_enc_one_op_cb(struct fpga_queue *q, struct
> rte_bbdev_enc_op *op,
>  	uint16_t ring_offset;
>  	uint16_t K, k_;
> 
> -#ifdef RTE_LIBRTE_BBDEV_DEBUG
> -	/* Validate op structure */
> -	/* FIXME */
> -	if (validate_enc_op(op) == -1) {
> -		rte_bbdev_log(ERR, "LDPC encoder validation failed");
> +
> +	if (validate_ldpc_enc_op(op) == -1) {
> +		rte_bbdev_log(ERR, "LDPC encoder validation rejected");
>  		return -EINVAL;
>  	}
> -#endif
> 
>  	/* Clear op status */
>  	op->status = 0;
> @@ -1481,13 +1763,10 @@ enqueue_ldpc_dec_one_op_cb(struct
> fpga_queue *q, struct rte_bbdev_dec_op *op,
>  	uint16_t out_offset = dec->hard_output.offset;
>  	uint32_t harq_offset = 0;
> 
> -#ifdef RTE_LIBRTE_BBDEV_DEBUG
> -		/* Validate op structure */
> -		if (validate_dec_op(op) == -1) {
> -			rte_bbdev_log(ERR, "LDPC decoder validation failed");
> -			return -EINVAL;
> -		}
> -#endif
> +	if (validate_ldpc_dec_op(op) == -1) {
> +		rte_bbdev_log(ERR, "LDPC decoder validation rejected");
> +		return -EINVAL;
> +	}
> 
>  	/* Clear op status */
>  	op->status = 0;
> @@ -1717,8 +1996,7 @@ fpga_enqueue_ldpc_dec(struct
> rte_bbdev_queue_data *q_data,
> 
> 
>  static inline int
> -dequeue_ldpc_enc_one_op_cb(struct fpga_queue *q,
> -		struct rte_bbdev_enc_op **op,
> +dequeue_ldpc_enc_one_op_cb(struct fpga_queue *q, struct
> +rte_bbdev_enc_op **op,
>  		uint16_t desc_offset)
>  {
>  	union fpga_dma_desc *desc;
> --
> 2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [EXT] [PATCH v1 5/5] baseband/fpga_5gnr_fec: remove filler from HARQ
  2022-05-09 20:17 ` [PATCH v1 5/5] baseband/fpga_5gnr_fec: remove filler from HARQ Hernan
@ 2022-05-16 18:07   ` Akhil Goyal
  2022-05-20  1:25     ` Chautru, Nicolas
  0 siblings, 1 reply; 11+ messages in thread
From: Akhil Goyal @ 2022-05-16 18:07 UTC (permalink / raw)
  To: Hernan, dev, trix; +Cc: nicolas.chautru, qi.z.zhang

> Removed dec->n_filler from harq_out_length calculation.
> 
Please provide a better description describing the reason to remove it.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [EXT] [PATCH v1 2/5] baseband/fpga_5gnr_fec: add FPGA Mutex
  2022-05-09 20:17 ` [PATCH v1 2/5] baseband/fpga_5gnr_fec: add FPGA Mutex Hernan
@ 2022-05-16 18:08   ` Akhil Goyal
  2022-05-20  1:30     ` Chautru, Nicolas
  0 siblings, 1 reply; 11+ messages in thread
From: Akhil Goyal @ 2022-05-16 18:08 UTC (permalink / raw)
  To: Hernan, dev, trix; +Cc: nicolas.chautru, qi.z.zhang

> FPGA mutex acquisition and mutex free implemented.

Please provide better description to the patches.

> 
> Signed-off-by: Hernan <hernan.vargas@intel.com>
> ---
>  .../baseband/fpga_5gnr_fec/fpga_5gnr_fec.h    |  6 +-
>  .../fpga_5gnr_fec/rte_fpga_5gnr_fec.c         | 77 ++++++++++++++-----
>  2 files changed, 62 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
> b/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
> index ed8ce26eaa..993cf61974 100644
> --- a/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
> +++ b/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
> @@ -82,7 +82,9 @@ enum {
>  	FPGA_5GNR_FEC_DDR4_RD_DATA_REGS = 0x00000A30, /* len: 8B */
>  	FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS = 0x00000A38, /* len: 1B */
>  	FPGA_5GNR_FEC_HARQ_BUF_SIZE_RDY_REGS = 0x00000A40, /* len: 1B
> */
> -	FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS = 0x00000A48  /* len: 4B */
> +	FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS = 0x00000A48, /* len: 4B */
> +	FPGA_5GNR_FEC_MUTEX = 0x00000A60, /* len: 4B */
> +	FPGA_5GNR_FEC_MUTEX_RESET = 0x00000A68  /* len: 4B */
>  };
> 
>  /* FPGA 5GNR FEC Ring Control Registers */
> @@ -264,6 +266,8 @@ struct __rte_cache_aligned fpga_queue {
>  	uint32_t sw_ring_wrap_mask;
>  	uint32_t irq_enable;  /* Enable ops dequeue interrupts if set to 1 */
>  	uint8_t q_idx;  /* Queue index */
> +	/** uuid used for MUTEX acquision for DDR */
> +	uint16_t ddr_mutex_uuid;
>  	struct fpga_5gnr_fec_device *d;
>  	/* MMIO register of shadow_tail used to enqueue descriptors */
>  	void *shadow_tail_addr;
> diff --git a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> index 6737b74901..435b4d90d8 100644
> --- a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> +++ b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> @@ -1194,11 +1194,45 @@ validate_dec_op(struct rte_bbdev_dec_op *op
> __rte_unused)
>  }
>  #endif
> 
> +static inline void
> +fpga_mutex_acquisition(struct fpga_queue *q)
> +{
> +	uint32_t mutex_ctrl, mutex_read, cnt = 0;
> +	/* Assign a unique id for the duration of the DDR access */
> +	q->ddr_mutex_uuid = rand();
> +	/* Request and wait for acquisition of the mutex */
> +	mutex_ctrl = (q->ddr_mutex_uuid << 16) + 1;
> +	do {
> +		if (cnt > 0)
> +			usleep(FPGA_TIMEOUT_CHECK_INTERVAL);
> +		rte_bbdev_log_debug("Acquiring Mutex for %x\n",
> +				q->ddr_mutex_uuid);
> +		fpga_reg_write_32(q->d->mmio_base,
> +				FPGA_5GNR_FEC_MUTEX,
> +				mutex_ctrl);
> +		mutex_read = fpga_reg_read_32(q->d->mmio_base,
> +				FPGA_5GNR_FEC_MUTEX);
> +		rte_bbdev_log_debug("Mutex %x cnt %d owner %x\n",
> +				mutex_read, cnt, q->ddr_mutex_uuid);
> +		cnt++;
> +	} while ((mutex_read >> 16) != q->ddr_mutex_uuid);
> +}
> +
> +static inline void
> +fpga_mutex_free(struct fpga_queue *q)
> +{
> +	uint32_t mutex_ctrl = q->ddr_mutex_uuid << 16;
> +	fpga_reg_write_32(q->d->mmio_base,
> +			FPGA_5GNR_FEC_MUTEX,
> +			mutex_ctrl);
> +}
> +
>  static inline int
> -fpga_harq_write_loopback(struct fpga_5gnr_fec_device *fpga_dev,
> +fpga_harq_write_loopback(struct fpga_queue *q,
>  		struct rte_mbuf *harq_input, uint16_t harq_in_length,
>  		uint32_t harq_in_offset, uint32_t harq_out_offset)
>  {
> +	fpga_mutex_acquisition(q);
>  	uint32_t out_offset = harq_out_offset;
>  	uint32_t in_offset = harq_in_offset;
>  	uint32_t left_length = harq_in_length;
> @@ -1215,7 +1249,7 @@ fpga_harq_write_loopback(struct
> fpga_5gnr_fec_device *fpga_dev,
>  	 * 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,
> +	reg_32 = fpga_reg_read_32(q->d->mmio_base,
>  			FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);
>  	if (reg_32 < harq_in_length) {
>  		left_length = reg_32;
> @@ -1226,46 +1260,48 @@ fpga_harq_write_loopback(struct
> fpga_5gnr_fec_device *fpga_dev,
>  			uint8_t *, in_offset);
> 
>  	while (left_length > 0) {
> -		if (fpga_reg_read_8(fpga_dev->mmio_base,
> +		if (fpga_reg_read_8(q->d->mmio_base,
>  				FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS) ==
> 1) {
> -			fpga_reg_write_32(fpga_dev->mmio_base,
> +			fpga_reg_write_32(q->d->mmio_base,
> 
> 	FPGA_5GNR_FEC_DDR4_WR_ADDR_REGS,
>  					out_offset);
> -			fpga_reg_write_64(fpga_dev->mmio_base,
> +			fpga_reg_write_64(q->d->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_reg_write_8(q->d->mmio_base,
> 
> 	FPGA_5GNR_FEC_DDR4_WR_DONE_REGS, 1);
>  		}
>  	}
>  	while (last_transaction > 0) {
> -		if (fpga_reg_read_8(fpga_dev->mmio_base,
> +		if (fpga_reg_read_8(q->d->mmio_base,
>  				FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS) ==
> 1) {
> -			fpga_reg_write_32(fpga_dev->mmio_base,
> +			fpga_reg_write_32(q->d->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_reg_write_64(q->d->mmio_base,
> 
> 	FPGA_5GNR_FEC_DDR4_WR_DATA_REGS,
>  					last_word);
> -			fpga_reg_write_8(fpga_dev->mmio_base,
> +			fpga_reg_write_8(q->d->mmio_base,
> 
> 	FPGA_5GNR_FEC_DDR4_WR_DONE_REGS, 1);
>  			last_transaction = 0;
>  		}
>  	}
> +	fpga_mutex_free(q);
>  	return 1;
>  }
> 
>  static inline int
> -fpga_harq_read_loopback(struct fpga_5gnr_fec_device *fpga_dev,
> +fpga_harq_read_loopback(struct fpga_queue *q,
>  		struct rte_mbuf *harq_output, uint16_t harq_in_length,
>  		uint32_t harq_in_offset, uint32_t harq_out_offset)
>  {
> +	fpga_mutex_acquisition(q);
>  	uint32_t left_length, in_offset = harq_in_offset;
>  	uint64_t reg;
>  	uint32_t increment = 0;
> @@ -1276,7 +1312,7 @@ fpga_harq_read_loopback(struct
> fpga_5gnr_fec_device *fpga_dev,
>  	if (last_transaction > 0)
>  		harq_in_length += (8 - last_transaction);
> 
> -	reg = fpga_reg_read_32(fpga_dev->mmio_base,
> +	reg = fpga_reg_read_32(q->d->mmio_base,
>  			FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);
>  	if (reg < harq_in_length) {
>  		harq_in_length = reg;
> @@ -1302,14 +1338,14 @@ fpga_harq_read_loopback(struct
> fpga_5gnr_fec_device *fpga_dev,
>  			uint8_t *, harq_out_offset);
> 
>  	while (left_length > 0) {
> -		fpga_reg_write_32(fpga_dev->mmio_base,
> +		fpga_reg_write_32(q->d->mmio_base,
>  			FPGA_5GNR_FEC_DDR4_RD_ADDR_REGS, in_offset);
> -		fpga_reg_write_8(fpga_dev->mmio_base,
> +		fpga_reg_write_8(q->d->mmio_base,
>  				FPGA_5GNR_FEC_DDR4_RD_DONE_REGS, 1);
> -		reg = fpga_reg_read_8(fpga_dev->mmio_base,
> +		reg = fpga_reg_read_8(q->d->mmio_base,
>  			FPGA_5GNR_FEC_DDR4_RD_RDY_REGS);
>  		while (reg != 1) {
> -			reg = fpga_reg_read_8(fpga_dev->mmio_base,
> +			reg = fpga_reg_read_8(q->d->mmio_base,
>  				FPGA_5GNR_FEC_DDR4_RD_RDY_REGS);
>  			if (reg == FPGA_DDR_OVERFLOW) {
>  				rte_bbdev_log(ERR,
> @@ -1317,14 +1353,15 @@ fpga_harq_read_loopback(struct
> fpga_5gnr_fec_device *fpga_dev,
>  				return -1;
>  			}
>  		}
> -		input[increment] = fpga_reg_read_64(fpga_dev->mmio_base,
> +		input[increment] = fpga_reg_read_64(q->d->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_reg_write_8(q->d->mmio_base,
>  				FPGA_5GNR_FEC_DDR4_RD_DONE_REGS, 0);
>  	}
> +	fpga_mutex_free(q);
>  	return 1;
>  }
> 
> @@ -1467,13 +1504,13 @@ enqueue_ldpc_dec_one_op_cb(struct fpga_queue
> *q, struct rte_bbdev_dec_op *op,
>  		if (check_bit(dec->op_flags,
> 
> 	RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE
>  				)) {
> -			ret = fpga_harq_write_loopback(q->d, harq_in,
> +			ret = fpga_harq_write_loopback(q, harq_in,
>  					harq_in_length, harq_in_offset,
>  					harq_out_offset);
>  		} else if (check_bit(dec->op_flags,
> 
> 	RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE
>  				)) {
> -			ret = fpga_harq_read_loopback(q->d, harq_out,
> +			ret = fpga_harq_read_loopback(q, harq_out,
>  				harq_in_length, harq_in_offset,
>  				harq_out_offset);
>  			dec->harq_combined_output.length = harq_in_length;
> --
> 2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [EXT] [PATCH v1 5/5] baseband/fpga_5gnr_fec: remove filler from HARQ
  2022-05-16 18:07   ` [EXT] " Akhil Goyal
@ 2022-05-20  1:25     ` Chautru, Nicolas
  0 siblings, 0 replies; 11+ messages in thread
From: Chautru, Nicolas @ 2022-05-20  1:25 UTC (permalink / raw)
  To: Akhil Goyal, Vargas, Hernan, dev, trix; +Cc: Zhang, Qi Z

Hernan, 

Please be more explicit on the commit description in the next patch version, suggesting below:

The computation of the HARQ output length should not include the filler bits on the N3000 HW implementation as these are already taken out by the deratematching step.
The change is only an optimization (no functional impact), no change required on stable branches.

Thanks
Nic

> -----Original Message-----
> From: Akhil Goyal <gakhil@marvell.com>
> Sent: Monday, May 16, 2022 11:07 AM
> To: Vargas, Hernan <hernan.vargas@intel.com>; dev@dpdk.org;
> trix@redhat.com
> Cc: Chautru, Nicolas <nicolas.chautru@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>
> Subject: RE: [EXT] [PATCH v1 5/5] baseband/fpga_5gnr_fec: remove filler
> from HARQ
> 
> > Removed dec->n_filler from harq_out_length calculation.
> >
> Please provide a better description describing the reason to remove it.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [EXT] [PATCH v1 2/5] baseband/fpga_5gnr_fec: add FPGA Mutex
  2022-05-16 18:08   ` [EXT] " Akhil Goyal
@ 2022-05-20  1:30     ` Chautru, Nicolas
  0 siblings, 0 replies; 11+ messages in thread
From: Chautru, Nicolas @ 2022-05-20  1:30 UTC (permalink / raw)
  To: Akhil Goyal, Vargas, Hernan, dev, trix; +Cc: Zhang, Qi Z

Hi Hernan, 

Let's be more explicit on the commit message.

An explicit mutex is added when using the register interface for HARQ memory preloading (used for unit test and/or troubleshoot) so that to prevent multiple threads to use the same interface in parallel. 
This feature is implemented through MMIO exposed per VF and common to all queues unlike the default enqueue operation where each queues are isolated by design.



> -----Original Message-----
> From: Akhil Goyal <gakhil@marvell.com>
> Sent: Monday, May 16, 2022 11:09 AM
> To: Vargas, Hernan <hernan.vargas@intel.com>; dev@dpdk.org;
> trix@redhat.com
> Cc: Chautru, Nicolas <nicolas.chautru@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>
> Subject: RE: [EXT] [PATCH v1 2/5] baseband/fpga_5gnr_fec: add FPGA Mutex
> 
> > FPGA mutex acquisition and mutex free implemented.
> 
> Please provide better description to the patches.
> 
> >
> > Signed-off-by: Hernan <hernan.vargas@intel.com>
> > ---
> >  .../baseband/fpga_5gnr_fec/fpga_5gnr_fec.h    |  6 +-
> >  .../fpga_5gnr_fec/rte_fpga_5gnr_fec.c         | 77 ++++++++++++++-----
> >  2 files changed, 62 insertions(+), 21 deletions(-)
> >
> > diff --git a/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
> > b/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
> > index ed8ce26eaa..993cf61974 100644
> > --- a/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
> > +++ b/drivers/baseband/fpga_5gnr_fec/fpga_5gnr_fec.h
> > @@ -82,7 +82,9 @@ enum {
> >  	FPGA_5GNR_FEC_DDR4_RD_DATA_REGS = 0x00000A30, /* len: 8B
> */
> >  	FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS = 0x00000A38, /* len: 1B
> */
> >  	FPGA_5GNR_FEC_HARQ_BUF_SIZE_RDY_REGS = 0x00000A40, /* len:
> 1B */
> > -	FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS = 0x00000A48  /* len: 4B */
> > +	FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS = 0x00000A48, /* len: 4B */
> > +	FPGA_5GNR_FEC_MUTEX = 0x00000A60, /* len: 4B */
> > +	FPGA_5GNR_FEC_MUTEX_RESET = 0x00000A68  /* len: 4B */
> >  };
> >
> >  /* FPGA 5GNR FEC Ring Control Registers */ @@ -264,6 +266,8 @@ struct
> > __rte_cache_aligned fpga_queue {
> >  	uint32_t sw_ring_wrap_mask;
> >  	uint32_t irq_enable;  /* Enable ops dequeue interrupts if set to 1 */
> >  	uint8_t q_idx;  /* Queue index */
> > +	/** uuid used for MUTEX acquision for DDR */
> > +	uint16_t ddr_mutex_uuid;
> >  	struct fpga_5gnr_fec_device *d;
> >  	/* MMIO register of shadow_tail used to enqueue descriptors */
> >  	void *shadow_tail_addr;
> > diff --git a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> > b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> > index 6737b74901..435b4d90d8 100644
> > --- a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> > +++ b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> > @@ -1194,11 +1194,45 @@ validate_dec_op(struct rte_bbdev_dec_op
> *op
> > __rte_unused)
> >  }
> >  #endif
> >
> > +static inline void
> > +fpga_mutex_acquisition(struct fpga_queue *q) {
> > +	uint32_t mutex_ctrl, mutex_read, cnt = 0;
> > +	/* Assign a unique id for the duration of the DDR access */
> > +	q->ddr_mutex_uuid = rand();
> > +	/* Request and wait for acquisition of the mutex */
> > +	mutex_ctrl = (q->ddr_mutex_uuid << 16) + 1;
> > +	do {
> > +		if (cnt > 0)
> > +			usleep(FPGA_TIMEOUT_CHECK_INTERVAL);
> > +		rte_bbdev_log_debug("Acquiring Mutex for %x\n",
> > +				q->ddr_mutex_uuid);
> > +		fpga_reg_write_32(q->d->mmio_base,
> > +				FPGA_5GNR_FEC_MUTEX,
> > +				mutex_ctrl);
> > +		mutex_read = fpga_reg_read_32(q->d->mmio_base,
> > +				FPGA_5GNR_FEC_MUTEX);
> > +		rte_bbdev_log_debug("Mutex %x cnt %d owner %x\n",
> > +				mutex_read, cnt, q->ddr_mutex_uuid);
> > +		cnt++;
> > +	} while ((mutex_read >> 16) != q->ddr_mutex_uuid); }
> > +
> > +static inline void
> > +fpga_mutex_free(struct fpga_queue *q) {
> > +	uint32_t mutex_ctrl = q->ddr_mutex_uuid << 16;
> > +	fpga_reg_write_32(q->d->mmio_base,
> > +			FPGA_5GNR_FEC_MUTEX,
> > +			mutex_ctrl);
> > +}
> > +
> >  static inline int
> > -fpga_harq_write_loopback(struct fpga_5gnr_fec_device *fpga_dev,
> > +fpga_harq_write_loopback(struct fpga_queue *q,
> >  		struct rte_mbuf *harq_input, uint16_t harq_in_length,
> >  		uint32_t harq_in_offset, uint32_t harq_out_offset)  {
> > +	fpga_mutex_acquisition(q);
> >  	uint32_t out_offset = harq_out_offset;
> >  	uint32_t in_offset = harq_in_offset;
> >  	uint32_t left_length = harq_in_length; @@ -1215,7 +1249,7 @@
> > fpga_harq_write_loopback(struct fpga_5gnr_fec_device *fpga_dev,
> >  	 * 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,
> > +	reg_32 = fpga_reg_read_32(q->d->mmio_base,
> >  			FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);
> >  	if (reg_32 < harq_in_length) {
> >  		left_length = reg_32;
> > @@ -1226,46 +1260,48 @@ fpga_harq_write_loopback(struct
> > fpga_5gnr_fec_device *fpga_dev,
> >  			uint8_t *, in_offset);
> >
> >  	while (left_length > 0) {
> > -		if (fpga_reg_read_8(fpga_dev->mmio_base,
> > +		if (fpga_reg_read_8(q->d->mmio_base,
> >  				FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS)
> ==
> > 1) {
> > -			fpga_reg_write_32(fpga_dev->mmio_base,
> > +			fpga_reg_write_32(q->d->mmio_base,
> >
> > 	FPGA_5GNR_FEC_DDR4_WR_ADDR_REGS,
> >  					out_offset);
> > -			fpga_reg_write_64(fpga_dev->mmio_base,
> > +			fpga_reg_write_64(q->d->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_reg_write_8(q->d->mmio_base,
> >
> > 	FPGA_5GNR_FEC_DDR4_WR_DONE_REGS, 1);
> >  		}
> >  	}
> >  	while (last_transaction > 0) {
> > -		if (fpga_reg_read_8(fpga_dev->mmio_base,
> > +		if (fpga_reg_read_8(q->d->mmio_base,
> >  				FPGA_5GNR_FEC_DDR4_ADDR_RDY_REGS)
> ==
> > 1) {
> > -			fpga_reg_write_32(fpga_dev->mmio_base,
> > +			fpga_reg_write_32(q->d->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_reg_write_64(q->d->mmio_base,
> >
> > 	FPGA_5GNR_FEC_DDR4_WR_DATA_REGS,
> >  					last_word);
> > -			fpga_reg_write_8(fpga_dev->mmio_base,
> > +			fpga_reg_write_8(q->d->mmio_base,
> >
> > 	FPGA_5GNR_FEC_DDR4_WR_DONE_REGS, 1);
> >  			last_transaction = 0;
> >  		}
> >  	}
> > +	fpga_mutex_free(q);
> >  	return 1;
> >  }
> >
> >  static inline int
> > -fpga_harq_read_loopback(struct fpga_5gnr_fec_device *fpga_dev,
> > +fpga_harq_read_loopback(struct fpga_queue *q,
> >  		struct rte_mbuf *harq_output, uint16_t harq_in_length,
> >  		uint32_t harq_in_offset, uint32_t harq_out_offset)  {
> > +	fpga_mutex_acquisition(q);
> >  	uint32_t left_length, in_offset = harq_in_offset;
> >  	uint64_t reg;
> >  	uint32_t increment = 0;
> > @@ -1276,7 +1312,7 @@ fpga_harq_read_loopback(struct
> > fpga_5gnr_fec_device *fpga_dev,
> >  	if (last_transaction > 0)
> >  		harq_in_length += (8 - last_transaction);
> >
> > -	reg = fpga_reg_read_32(fpga_dev->mmio_base,
> > +	reg = fpga_reg_read_32(q->d->mmio_base,
> >  			FPGA_5GNR_FEC_HARQ_BUF_SIZE_REGS);
> >  	if (reg < harq_in_length) {
> >  		harq_in_length = reg;
> > @@ -1302,14 +1338,14 @@ fpga_harq_read_loopback(struct
> > fpga_5gnr_fec_device *fpga_dev,
> >  			uint8_t *, harq_out_offset);
> >
> >  	while (left_length > 0) {
> > -		fpga_reg_write_32(fpga_dev->mmio_base,
> > +		fpga_reg_write_32(q->d->mmio_base,
> >  			FPGA_5GNR_FEC_DDR4_RD_ADDR_REGS, in_offset);
> > -		fpga_reg_write_8(fpga_dev->mmio_base,
> > +		fpga_reg_write_8(q->d->mmio_base,
> >  				FPGA_5GNR_FEC_DDR4_RD_DONE_REGS, 1);
> > -		reg = fpga_reg_read_8(fpga_dev->mmio_base,
> > +		reg = fpga_reg_read_8(q->d->mmio_base,
> >  			FPGA_5GNR_FEC_DDR4_RD_RDY_REGS);
> >  		while (reg != 1) {
> > -			reg = fpga_reg_read_8(fpga_dev->mmio_base,
> > +			reg = fpga_reg_read_8(q->d->mmio_base,
> >  				FPGA_5GNR_FEC_DDR4_RD_RDY_REGS);
> >  			if (reg == FPGA_DDR_OVERFLOW) {
> >  				rte_bbdev_log(ERR,
> > @@ -1317,14 +1353,15 @@ fpga_harq_read_loopback(struct
> > fpga_5gnr_fec_device *fpga_dev,
> >  				return -1;
> >  			}
> >  		}
> > -		input[increment] = fpga_reg_read_64(fpga_dev-
> >mmio_base,
> > +		input[increment] = fpga_reg_read_64(q->d->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_reg_write_8(q->d->mmio_base,
> >  				FPGA_5GNR_FEC_DDR4_RD_DONE_REGS, 0);
> >  	}
> > +	fpga_mutex_free(q);
> >  	return 1;
> >  }
> >
> > @@ -1467,13 +1504,13 @@ enqueue_ldpc_dec_one_op_cb(struct
> fpga_queue
> > *q, struct rte_bbdev_dec_op *op,
> >  		if (check_bit(dec->op_flags,
> >
> > 	RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE
> >  				)) {
> > -			ret = fpga_harq_write_loopback(q->d, harq_in,
> > +			ret = fpga_harq_write_loopback(q, harq_in,
> >  					harq_in_length, harq_in_offset,
> >  					harq_out_offset);
> >  		} else if (check_bit(dec->op_flags,
> >
> > 	RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE
> >  				)) {
> > -			ret = fpga_harq_read_loopback(q->d, harq_out,
> > +			ret = fpga_harq_read_loopback(q, harq_out,
> >  				harq_in_length, harq_in_offset,
> >  				harq_out_offset);
> >  			dec->harq_combined_output.length =
> harq_in_length;
> > --
> > 2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-05-20  1:30 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-09 20:17 [PATCH v1 0/5] baseband/fpga_5gnr: maintenance changes to fpga_5gnr PMD Hernan
2022-05-09 20:17 ` [PATCH v1 1/5] baseband/fpga_5gnr_fec: remove FLR timeout Hernan
2022-05-09 20:17 ` [PATCH v1 2/5] baseband/fpga_5gnr_fec: add FPGA Mutex Hernan
2022-05-16 18:08   ` [EXT] " Akhil Goyal
2022-05-20  1:30     ` Chautru, Nicolas
2022-05-09 20:17 ` [PATCH v1 3/5] baseband/fpga_5gnr_fec: add check for HARQ input length Hernan
2022-05-09 20:17 ` [PATCH v1 4/5] baseband/fpga_5gnr_fec: enable validate LDPC enc/dec Hernan
2022-05-09 21:04   ` Chautru, Nicolas
2022-05-09 20:17 ` [PATCH v1 5/5] baseband/fpga_5gnr_fec: remove filler from HARQ Hernan
2022-05-16 18:07   ` [EXT] " Akhil Goyal
2022-05-20  1:25     ` Chautru, Nicolas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).