From 030aa253e8e7ab58838318942d6ad6dd398168dc Mon Sep 17 00:00:00 2001
From: Hongzhi Wang <hongzhi.wang@openairinterface.com>
Date: Fri, 18 Jun 2021 15:28:04 +0200
Subject: [PATCH] adding temporarily bbdev testsuite in ldpc_decoder_offload to
 check t1 card connection

---
 cmake_targets/CMakeLists.txt                  |   6 +-
 .../nrLDPC_decoder/nrLDPC_decoder_offload.c   | 438 +++++++++++++++++-
 openair1/PHY/CODING/nrLDPC_defs.h             |   7 +-
 openair1/PHY/CODING/nrLDPC_extern.h           |   4 +
 openair1/PHY/CODING/nrLDPC_load.c             |  11 +
 openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c |   2 +-
 openair1/SIMULATION/NR_PHY/ulsim.c            |   1 +
 targets/ARCH/test-bbdev/test_bbdev_perf.c     |  10 +-
 targets/ARCH/test-bbdev/test_bbdev_vector.c   |   8 +-
 9 files changed, 460 insertions(+), 27 deletions(-)

diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 636ac6006c..2d3f422072 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -824,7 +824,8 @@ include_directories ("/usr/local/include")
 
 set(HWLIB_LDPC_OFFLOAD_SOURCE
    ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c
-#  ${OPENAIR_TARGETS}/ARCH/test-bbdev/test_bbdev.c
+   ${OPENAIR_TARGETS}/ARCH/test-bbdev/test_bbdev.c
+#   ${OPENAIR_TARGETS}/ARCH/test-bbdev/main.c
    ${OPENAIR_TARGETS}/ARCH/test-bbdev/test_bbdev_perf.c
    ${OPENAIR_TARGETS}/ARCH/test-bbdev/test_bbdev_vector.c
   )
@@ -832,7 +833,7 @@ add_library(ldpc_offload MODULE ${HWLIB_LDPC_OFFLOAD_SOURCE} )
 
 set_target_properties(ldpc_offload PROPERTIES COMPILE_FLAGS "-include rte_config.h  -march=native -I/usr/local/include")
 
-SET(T1_DPDK_LIBS "-Wl,-rpath,/home/wang/dpdk-20.05/build/include -L/usr/local/lib64 -lrte_node -lrte_graph -lrte_bpf -lrte_flow_classify -lrte_pipeline -lrte_table -lrte_port -lrte_fib -lrte_ipsec -lrte_vhost -lrte_stack -lrte_security -lrte_sched -lrte_reorder -lrte_rib -lrte_rawdev -lrte_pdump -lrte_power -lrte_member -lrte_lpm -lrte_latencystats -lrte_kni -lrte_jobstats -lrte_ip_frag -lrte_gso -lrte_gro -lrte_eventdev -lrte_efd -lrte_distributor -lrte_cryptodev -lrte_compressdev -lrte_cfgfile -lrte_bitratestats -lrte_bbdev -lrte_acl -lrte_timer -lrte_hash -lrte_metrics -lrte_cmdline -lrte_pci -lrte_ethdev -lrte_meter -lrte_net -lrte_mbuf -lrte_mempool -lrte_rcu -lrte_ring -lrte_eal -lrte_telemetry -lrte_kvargs -Wl,--whole-archive -L/usr/local/lib64 -lrte_common_cpt -lrte_common_dpaax -lrte_common_iavf -lrte_common_octeontx -lrte_common_octeontx2 -lrte_bus_dpaa -lrte_bus_fslmc -lrte_bus_ifpga -lrte_bus_pci -lrte_bus_vdev -lrte_bus_vmbus -lrte_mempool_bucket -lrte_mempool_dpaa -lrte_mempool_dpaa2 -lrte_mempool_octeontx -lrte_mempool_octeontx2 -lrte_mempool_ring -lrte_mempool_stack -lrte_pmd_af_packet -lrte_pmd_ark -lrte_pmd_atlantic -lrte_pmd_avp -lrte_pmd_axgbe -lrte_pmd_bond -lrte_pmd_bnx2x -lrte_pmd_bnxt -lrte_pmd_cxgbe -lrte_pmd_dpaa -lrte_pmd_dpaa2 -lrte_pmd_e1000 -lrte_pmd_ena -lrte_pmd_enetc -lrte_pmd_enic -lrte_pmd_failsafe -lrte_pmd_fm10k -lrte_pmd_i40e -lrte_pmd_hinic -lrte_pmd_hns3 -lrte_pmd_iavf -lrte_pmd_ice -lrte_pmd_igc -lrte_pmd_ixgbe -lrte_pmd_kni -lrte_pmd_liquidio -lrte_pmd_memif -lrte_pmd_netvsc -lrte_pmd_nfp -lrte_pmd_null -lrte_pmd_octeontx -lrte_pmd_octeontx2 -lrte_pmd_pcap -lrte_pmd_pfe -lrte_pmd_qede -lrte_pmd_ring -lrte_pmd_sfc -lrte_pmd_softnic -lrte_pmd_tap -lrte_pmd_thunderx -lrte_pmd_vdev_netvsc -lrte_pmd_vhost -lrte_pmd_virtio -lrte_pmd_vmxnet3 -lrte_rawdev_dpaa2_cmdif -lrte_rawdev_dpaa2_qdma -lrte_rawdev_ioat -lrte_rawdev_ntb -lrte_rawdev_octeontx2_dma -lrte_rawdev_octeontx2_ep -lrte_rawdev_skeleton -lrte_pmd_caam_jr -lrte_pmd_ccp -lrte_pmd_dpaa_sec -lrte_pmd_dpaa2_sec -lrte_pmd_nitrox -lrte_pmd_null_crypto -lrte_pmd_octeontx_crypto -lrte_pmd_octeontx2_crypto -lrte_pmd_openssl -lrte_pmd_crypto_scheduler -lrte_pmd_virtio_crypto -lrte_pmd_octeontx_compress -lrte_pmd_qat -lrte_pmd_zlib -lrte_pmd_ifc -lrte_pmd_dpaa_event -lrte_pmd_dpaa2_event -lrte_pmd_octeontx2_event -lrte_pmd_opdl_event -lrte_pmd_skeleton_event -lrte_pmd_sw_event -lrte_pmd_dsw_event -lrte_pmd_octeontx_event -lrte_pmd_bbdev_null -lrte_pmd_bbdev_turbo_sw -lrte_pmd_bbdev_fpga_lte_fec -lrte_pmd_bbdev_fpga_5gnr_fec -Wl,--no-whole-archive -lrte_node -lrte_graph -lrte_bpf -lrte_flow_classify -lrte_pipeline -lrte_table -lrte_port -lrte_fib -lrte_ipsec -lrte_vhost -lrte_stack -lrte_security -lrte_sched -lrte_reorder -lrte_rib -lrte_rawdev -lrte_pdump -lrte_power -lrte_member -lrte_lpm -lrte_latencystats -lrte_kni -lrte_jobstats -lrte_ip_frag -lrte_gso -lrte_gro -lrte_eventdev -lrte_efd -lrte_distributor -lrte_cryptodev -lrte_compressdev -lrte_cfgfile -lrte_bitratestats -lrte_bbdev -lrte_acl -lrte_timer -lrte_hash -lrte_metrics -lrte_cmdline -lrte_pci -lrte_ethdev -lrte_meter -lrte_net -lrte_mbuf -lrte_mempool -lrte_rcu -lrte_ring -lrte_eal -lrte_telemetry -lrte_kvargs -Wl,-Bdynamic -pthread -lm -ldl -lnuma -lpcap")
+SET(T1_DPDK_LIBS "-Wl,-rpath,/usr/local/include -L/usr/local/lib64 -lrte_node -lrte_graph -lrte_bpf -lrte_flow_classify -lrte_pipeline -lrte_table -lrte_port -lrte_fib -lrte_ipsec -lrte_vhost -lrte_stack -lrte_security -lrte_sched -lrte_reorder -lrte_rib -lrte_rawdev -lrte_pdump -lrte_power -lrte_member -lrte_lpm -lrte_latencystats -lrte_kni -lrte_jobstats -lrte_ip_frag -lrte_gso -lrte_gro -lrte_eventdev -lrte_efd -lrte_distributor -lrte_cryptodev -lrte_compressdev -lrte_cfgfile -lrte_bitratestats -lrte_bbdev -lrte_acl -lrte_timer -lrte_hash -lrte_metrics -lrte_cmdline -lrte_pci -lrte_ethdev -lrte_meter -lrte_net -lrte_mbuf -lrte_mempool -lrte_rcu -lrte_ring -lrte_eal -lrte_telemetry -lrte_kvargs -Wl,--whole-archive -L/usr/local/lib64 -lrte_common_cpt -lrte_common_dpaax -lrte_common_iavf -lrte_common_octeontx -lrte_common_octeontx2 -lrte_bus_dpaa -lrte_bus_fslmc -lrte_bus_ifpga -lrte_bus_pci -lrte_bus_vdev -lrte_bus_vmbus -lrte_mempool_bucket -lrte_mempool_dpaa -lrte_mempool_dpaa2 -lrte_mempool_octeontx -lrte_mempool_octeontx2 -lrte_mempool_ring -lrte_mempool_stack -lrte_pmd_af_packet -lrte_pmd_ark -lrte_pmd_atlantic -lrte_pmd_avp -lrte_pmd_axgbe -lrte_pmd_bond -lrte_pmd_bnx2x -lrte_pmd_bnxt -lrte_pmd_cxgbe -lrte_pmd_dpaa -lrte_pmd_dpaa2 -lrte_pmd_e1000 -lrte_pmd_ena -lrte_pmd_enetc -lrte_pmd_enic -lrte_pmd_failsafe -lrte_pmd_fm10k -lrte_pmd_i40e -lrte_pmd_hinic -lrte_pmd_hns3 -lrte_pmd_iavf -lrte_pmd_ice -lrte_pmd_igc -lrte_pmd_ixgbe -lrte_pmd_kni -lrte_pmd_liquidio -lrte_pmd_memif -lrte_pmd_netvsc -lrte_pmd_nfp -lrte_pmd_null -lrte_pmd_octeontx -lrte_pmd_octeontx2 -lrte_pmd_pcap -lrte_pmd_pfe -lrte_pmd_qede -lrte_pmd_ring -lrte_pmd_sfc -lrte_pmd_softnic -lrte_pmd_tap -lrte_pmd_thunderx -lrte_pmd_vdev_netvsc -lrte_pmd_vhost -lrte_pmd_virtio -lrte_pmd_vmxnet3 -lrte_rawdev_dpaa2_cmdif -lrte_rawdev_dpaa2_qdma -lrte_rawdev_ioat -lrte_rawdev_ntb -lrte_rawdev_octeontx2_dma -lrte_rawdev_octeontx2_ep -lrte_rawdev_skeleton -lrte_pmd_caam_jr -lrte_pmd_ccp -lrte_pmd_dpaa_sec -lrte_pmd_dpaa2_sec -lrte_pmd_nitrox -lrte_pmd_null_crypto -lrte_pmd_octeontx_crypto -lrte_pmd_octeontx2_crypto -lrte_pmd_openssl -lrte_pmd_crypto_scheduler -lrte_pmd_virtio_crypto -lrte_pmd_octeontx_compress -lrte_pmd_qat -lrte_pmd_zlib -lrte_pmd_ifc -lrte_pmd_dpaa_event -lrte_pmd_dpaa2_event -lrte_pmd_octeontx2_event -lrte_pmd_opdl_event -lrte_pmd_skeleton_event -lrte_pmd_sw_event -lrte_pmd_dsw_event -lrte_pmd_octeontx_event -lrte_pmd_bbdev_null -lrte_pmd_bbdev_turbo_sw -lrte_pmd_bbdev_fpga_lte_fec -lrte_pmd_bbdev_fpga_5gnr_fec -Wl,--no-whole-archive -lrte_node -lrte_graph -lrte_bpf -lrte_flow_classify -lrte_pipeline -lrte_table -lrte_port -lrte_fib -lrte_ipsec -lrte_vhost -lrte_stack -lrte_security -lrte_sched -lrte_reorder -lrte_rib -lrte_rawdev -lrte_pdump -lrte_power -lrte_member -lrte_lpm -lrte_latencystats -lrte_kni -lrte_jobstats -lrte_ip_frag -lrte_gso -lrte_gro -lrte_eventdev -lrte_efd -lrte_distributor -lrte_cryptodev -lrte_compressdev -lrte_cfgfile -lrte_bitratestats -lrte_bbdev -lrte_acl -lrte_timer -lrte_hash -lrte_metrics -lrte_cmdline -lrte_pci -lrte_ethdev -lrte_meter -lrte_net -lrte_mbuf -lrte_mempool -lrte_rcu -lrte_ring -lrte_eal -lrte_telemetry -lrte_kvargs -Wl,-Bdynamic -pthread -lm -ldl -lnuma -lpcap")
 TARGET_LINK_LIBRARIES(ldpc_offload ${T1_DPDK_LIBS})
 TARGET_LINK_LIBRARIES(ldpc_offload pthread dl rt m numa)
 
@@ -2818,6 +2819,7 @@ if (CUDA_FOUND)
    add_dependencies( nr-uesoftmodem ldpc_cuda)
    add_dependencies( nr-softmodem ldpc_cuda)
 endif (CUDA_FOUND)
+
 ###################################"
 # Addexecutables for tests
 ####################################
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c
index 8a54e9e8ff..6b4038a964 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c
@@ -68,12 +68,14 @@
 #include <rte_random.h>
 #include <rte_hexdump.h>
 #include <rte_interrupts.h>
+#include "../../../targets/ARCH/test-bbdev/main.h"
+#include "../../../targets/ARCH/test-bbdev/test_bbdev_vector.h"
 
 #define MAX_QUEUES RTE_MAX_LCORE
 #define TEST_REPETITIONS 1000
 /* Switch between PMD and Interrupt for throughput TC */
 static bool intr_enabled;
-
+static struct test_bbdev_vector test_vector;
 /* LLR arithmetic representation for numerical conversion */
 static int ldpc_llr_decimals;
 static int ldpc_llr_size;
@@ -144,7 +146,7 @@ struct thread_params {
 static const char tc_sep = ',';
 
 /* Declare structure for command line test parameters and options */
-/*static struct test_params {
+static struct test_params {
 	struct test_command *test_to_run[MAX_CMDLINE_TESTCASES];
 	unsigned int num_tests;
 	unsigned int num_ops;
@@ -164,7 +166,84 @@ add_test_command(struct test_command *t)
 {
 	TAILQ_INSERT_TAIL(&commands_list, t, next);
 }
-
+int
+unit_test_suite_runner(struct unit_test_suite *suite)
+{
+	int test_result = TEST_SUCCESS;
+	unsigned int total = 0, skipped = 0, succeeded = 0, failed = 0;
+	uint64_t start, end;
+
+	printf("\n===========================================================\n");
+	printf("Starting Test Suite : %s\n", suite->suite_name);
+
+	start = rte_rdtsc_precise();
+
+	if (suite->setup) {
+		test_result = suite->setup();
+		if (test_result == TEST_FAILED) {
+			printf(" + Test suite setup %s failed!\n",
+					suite->suite_name);
+			printf(" + ------------------------------------------------------- +\n");
+			return 1;
+		}
+		if (test_result == TEST_SKIPPED) {
+			printf(" + Test suite setup %s skipped!\n",
+					suite->suite_name);
+			printf(" + ------------------------------------------------------- +\n");
+			return 0;
+		}
+	}
+
+	while (suite->unit_test_cases[total].testcase) {
+		if (suite->unit_test_cases[total].setup)
+			test_result = suite->unit_test_cases[total].setup();
+
+		if (test_result == TEST_SUCCESS)
+			test_result = suite->unit_test_cases[total].testcase();
+
+		if (suite->unit_test_cases[total].teardown)
+			suite->unit_test_cases[total].teardown();
+
+		if (test_result == TEST_SUCCESS) {
+			succeeded++;
+			printf("TestCase [%2d] : %s passed\n", total,
+					suite->unit_test_cases[total].name);
+		} else if (test_result == TEST_SKIPPED) {
+			skipped++;
+			printf("TestCase [%2d] : %s skipped\n", total,
+					suite->unit_test_cases[total].name);
+		} else {
+			failed++;
+			printf("TestCase [%2d] : %s failed\n", total,
+					suite->unit_test_cases[total].name);
+		}
+
+		total++;
+	}
+
+	/* Run test suite teardown */
+	if (suite->teardown)
+		suite->teardown();
+
+	end = rte_rdtsc_precise();
+
+	printf(" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +\n");
+	printf(" + Test Suite Summary : %s\n", suite->suite_name);
+	printf(" + Tests Total :       %2d\n", total);
+	printf(" + Tests Skipped :     %2d\n", skipped);
+	printf(" + Tests Passed :      %2d\n", succeeded);
+	printf(" + Tests Failed :      %2d\n", failed);
+	printf(" + Tests Lasted :       %lg ms\n",
+			((end - start) * 1000) / (double)rte_get_tsc_hz());
+	printf(" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +\n");
+
+	return (failed > 0) ? 1 : 0;
+}
+const char *
+get_vector_filename(void)
+{
+	return test_params.test_vector_filename;
+}
 unsigned int
 get_num_ops(void)
 {
@@ -200,7 +279,156 @@ get_init_device(void)
 {
 	return test_params.init_device;
 }
+static void
+print_usage(const char *prog_name)
+{
+	struct test_command *t;
+
+	printf("***Usage: %s [EAL params] [-- [-n/--num-ops NUM_OPS]\n"
+			"\t[-b/--burst-size BURST_SIZE]\n"
+			"\t[-v/--test-vector VECTOR_FILE]\n"
+			"\t[-c/--test-cases TEST_CASE[,TEST_CASE,...]]]\n",
+			prog_name);
+
+	printf("Available testcases: ");
+	TAILQ_FOREACH(t, &commands_list, next)
+		printf("%s ", t->command);
+	printf("\n");
+}
 
+static int
+parse_args(int argc, char **argv, struct test_params *tp)
+{
+	int opt, option_index;
+	unsigned int num_tests = 0;
+	bool test_cases_present = false;
+	bool test_vector_present = false;
+	struct test_command *t;
+	char *tokens[MAX_CMDLINE_TESTCASES];
+	int tc, ret;
+
+	static struct option lgopts[] = {
+		{ "num-ops", 1, 0, 'n' },
+		{ "burst-size", 1, 0, 'b' },
+		{ "test-cases", 1, 0, 'c' },
+		{ "test-vector", 1, 0, 'v' },
+		{ "lcores", 1, 0, 'l' },
+		{ "snr", 1, 0, 's' },
+		{ "iter_max", 6, 0, 't' },
+		{ "init-device", 0, 0, 'i'},
+		{ "help", 0, 0, 'h' },
+		{ NULL,  0, 0, 0 }
+	};
+	tp->iter_max = DEFAULT_ITER;
+
+	while ((opt = getopt_long(argc, argv, "hin:b:c:v:l:s:t:", lgopts,
+			&option_index)) != EOF)
+		switch (opt) {
+		case 'n':
+			TEST_ASSERT(strlen(optarg) > 0,
+					"Num of operations is not provided");
+			tp->num_ops = strtol(optarg, NULL, 10);
+			break;
+		case 'b':
+			TEST_ASSERT(strlen(optarg) > 0,
+					"Burst size is not provided");
+			tp->burst_sz = strtol(optarg, NULL, 10);
+			TEST_ASSERT(tp->burst_sz <= MAX_BURST,
+					"Burst size mustn't be greater than %u",
+					MAX_BURST);
+			break;
+		case 'c':
+			TEST_ASSERT(test_cases_present == false,
+					"Test cases provided more than once");
+			test_cases_present = true;
+
+			ret = rte_strsplit(optarg, strlen(optarg),
+					tokens, MAX_CMDLINE_TESTCASES, tc_sep);
+
+			TEST_ASSERT(ret <= MAX_CMDLINE_TESTCASES,
+					"Too many test cases (max=%d)",
+					MAX_CMDLINE_TESTCASES);
+
+			for (tc = 0; tc < ret; ++tc) {
+				/* Find matching test case */
+				TAILQ_FOREACH(t, &commands_list, next)
+					if (!strcmp(tokens[tc], t->command))
+						tp->test_to_run[num_tests] = t;
+
+				TEST_ASSERT(tp->test_to_run[num_tests] != NULL,
+						"Unknown test case: %s",
+						tokens[tc]);
+				++num_tests;
+			}
+			break;
+		case 'v':
+			TEST_ASSERT(test_vector_present == false,
+					"Test vector provided more than once");
+			test_vector_present = true;
+
+			TEST_ASSERT(strlen(optarg) > 0,
+					"Config file name is null");
+
+			snprintf(tp->test_vector_filename,
+					sizeof(tp->test_vector_filename),
+					"%s", optarg);
+			break;
+		case 's':
+			TEST_ASSERT(strlen(optarg) > 0,
+					"SNR is not provided");
+			tp->snr = strtod(optarg, NULL);
+			break;
+		case 't':
+			TEST_ASSERT(strlen(optarg) > 0,
+					"Iter_max is not provided");
+			tp->iter_max = strtol(optarg, NULL, 10);
+			break;
+		case 'l':
+			TEST_ASSERT(strlen(optarg) > 0,
+					"Num of lcores is not provided");
+			tp->num_lcores = strtol(optarg, NULL, 10);
+			TEST_ASSERT(tp->num_lcores <= RTE_MAX_LCORE,
+					"Num of lcores mustn't be greater than %u",
+					RTE_MAX_LCORE);
+			break;
+		case 'i':
+			/* indicate fpga fec config required */
+			tp->init_device = true;
+			break;
+		case 'h':
+			print_usage(argv[0]);
+			return 0;
+		default:
+			printf("ERROR: Unknown option: -%c\n", opt);
+			return -1;
+		}
+
+	if (tp->num_ops == 0) {
+		printf(
+			"WARNING: Num of operations was not provided or was set 0. Set to default (%u)\n",
+			DEFAULT_OPS);
+		tp->num_ops = DEFAULT_OPS;
+	}
+	if (tp->burst_sz == 0) {
+		printf(
+			"WARNING: Burst size was not provided or was set 0. Set to default (%u)\n",
+			DEFAULT_BURST);
+		tp->burst_sz = DEFAULT_BURST;
+	}
+	if (tp->num_lcores == 0) {
+		printf(
+			"WARNING: Num of lcores was not provided or was set 0. Set to value from RTE config (%u)\n",
+			rte_lcore_count());
+		tp->num_lcores = rte_lcore_count();
+	}
+
+	TEST_ASSERT(tp->burst_sz <= tp->num_ops,
+			"Burst size (%u) mustn't be greater than num ops (%u)",
+			tp->burst_sz, tp->num_ops);
+
+	tp->num_tests = num_tests;
+	return 0;
+}
 static int
 run_all_tests(void)
 {
@@ -224,37 +452,221 @@ run_parsed_tests(struct test_params *tp)
 
 	return ret;
 }
-*/
-int32_t nrLDPC_decod_offload(t_nrLDPC_dec_params* p_decParams, uint8_t C, uint8_t rv, uint32_t F, int8_t* w, int8_t* p_out)
+
+static void
+create_reference_ldpc_dec_op(struct rte_bbdev_dec_op *op)
+{
+	unsigned int i;
+	struct op_data_entries *entry;
+
+	op->ldpc_dec = test_vector.ldpc_dec;
+	entry = &test_vector.entries[DATA_INPUT];
+	for (i = 0; i < entry->nb_segments; ++i)
+		op->ldpc_dec.input.length +=
+				entry->segments[i].length;
+	if (test_vector.ldpc_dec.op_flags &
+			RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE) {
+		entry = &test_vector.entries[DATA_HARQ_INPUT];
+		for (i = 0; i < entry->nb_segments; ++i)
+			op->ldpc_dec.harq_combined_input.length +=
+				entry->segments[i].length;
+	}
+}
+/* Read flag value 0/1 from bitmap */
+static inline bool
+check_bit(uint32_t bitmap, uint32_t bitmask)
+{
+	return bitmap & bitmask;
+}
+static void
+copy_reference_ldpc_dec_op(struct rte_bbdev_dec_op **ops, unsigned int n,
+		unsigned int start_idx,
+		struct rte_bbdev_op_data *inputs,
+		struct rte_bbdev_op_data *hard_outputs,
+		struct rte_bbdev_op_data *soft_outputs,
+		struct rte_bbdev_op_data *harq_inputs,
+		struct rte_bbdev_op_data *harq_outputs,
+		struct rte_bbdev_dec_op *ref_op)
+{
+	unsigned int i;
+	struct rte_bbdev_op_ldpc_dec *ldpc_dec = &ref_op->ldpc_dec;
+	struct rte_mbuf *m = inputs->data;
+
+	for (i = 0; i < n; ++i) {
+		if (ldpc_dec->code_block_mode == 0) {
+			ops[i]->ldpc_dec.tb_params.ea =
+					ldpc_dec->tb_params.ea;
+			ops[i]->ldpc_dec.tb_params.eb =
+					ldpc_dec->tb_params.eb;
+			ops[i]->ldpc_dec.tb_params.c =
+					ldpc_dec->tb_params.c;
+			ops[i]->ldpc_dec.tb_params.cab =
+					ldpc_dec->tb_params.cab;
+			ops[i]->ldpc_dec.tb_params.r =
+					ldpc_dec->tb_params.r;
+					printf("code block ea %d eb %d c %d cab %d r %d\n",ldpc_dec->tb_params.ea,ldpc_dec->tb_params.eb,ldpc_dec->tb_params.c, ldpc_dec->tb_params.cab, ldpc_dec->tb_params.r);
+		} else {
+			ops[i]->ldpc_dec.cb_params.e = ldpc_dec->cb_params.e;
+		}
+
+		ops[i]->ldpc_dec.basegraph = ldpc_dec->basegraph;
+		ops[i]->ldpc_dec.z_c = ldpc_dec->z_c;
+		ops[i]->ldpc_dec.q_m = ldpc_dec->q_m;
+		ops[i]->ldpc_dec.n_filler = ldpc_dec->n_filler;
+		ops[i]->ldpc_dec.n_cb = ldpc_dec->n_cb;
+		ops[i]->ldpc_dec.iter_max = ldpc_dec->iter_max;
+		ops[i]->ldpc_dec.rv_index = ldpc_dec->rv_index;
+		ops[i]->ldpc_dec.op_flags = ldpc_dec->op_flags;
+		ops[i]->ldpc_dec.code_block_mode = ldpc_dec->code_block_mode;
+		
+		printf("reference bg %d zc %d qm %d nfiller n_filler, n_cb %d iter max %d rv %d\n", ldpc_dec->basegraph, ldpc_dec->z_c, ldpc_dec->q_m,ldpc_dec->n_filler,ldpc_dec->n_cb,ldpc_dec->iter_max,ldpc_dec->rv_index);
+
+if (i<10)
+printf("input %x\n",inputs[start_idx+i]);
+
+		if (hard_outputs != NULL)
+			ops[i]->ldpc_dec.hard_output =
+					hard_outputs[start_idx + i];
+		if (inputs != NULL)
+			ops[i]->ldpc_dec.input =
+					inputs[start_idx + i];
+		if (soft_outputs != NULL)
+			ops[i]->ldpc_dec.soft_output =
+					soft_outputs[start_idx + i];
+		if (harq_inputs != NULL)
+			ops[i]->ldpc_dec.harq_combined_input =
+					harq_inputs[start_idx + i];
+		if (harq_outputs != NULL)
+			ops[i]->ldpc_dec.harq_combined_output =
+					harq_outputs[start_idx + i];
+					
+//					if (i<10)
+//printf("ldpc_dec input %x\n",*ops[i]->ldpc_dec.input->data->buf_addr);
+
+
+
+
+	}
+}
+int32_t nrLDPC_decod_offload(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler)
+//int32_t nrLDPC_decod_offload(t_nrLDPC_dec_params* p_decParams, uint8_t C, uint8_t rv, uint32_t F, int8_t* w, int8_t* p_out)
 {
     uint32_t numIter = 0;
     struct thread_params *t_params_tp;
+    /* Allocate memory for thread parameters structure */
     uint16_t num_lcores=1;
-    /*uint16_t enq, deq;
+    /*	t_params_tp = rte_zmalloc(NULL, num_lcores * sizeof(struct thread_params),
+			RTE_CACHE_LINE_SIZE);
+	TEST_ASSERT_NOT_NULL(t_params_tp, "Failed to alloc %zuB for t_params",
+			RTE_ALIGN(sizeof(struct thread_params) * num_lcores,
+				RTE_CACHE_LINE_SIZE));    
+   */ 
+    uint16_t enq, deq;
 	const uint16_t queue_id = 1; //tp->queue_id;
 	const uint16_t burst_sz = 128; //tp->op_params->burst_sz;
 	const uint16_t num_ops = 128; //tp->op_params->num_to_process;
 	struct rte_bbdev_dec_op *ops_enq[num_ops];
 	struct rte_bbdev_dec_op *ops_deq[num_ops];
+        struct thread_params *tp=&t_params_tp[0];
 
+    //    struct rte_bbdev_dec_op *ref_op = tp->op_params->ref_dec_op;
 	struct test_buffers *bufs = NULL;
 	int i, j, ret;
 	struct rte_bbdev_info info;
 	uint16_t num_to_enq;
-   */	
-        bool extDdr = check_bit(ldpc_cap_flags,
-			RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE);
+   	
+//int ret; 
+int argc_re=4;
+char *argv_re[15];
+argv_re[0] = "./build/app/testbbdev";
+argv_re[1] = "--"; //./build/app/testbbdev"; 
+argv_re[2] = "-v";
+argv_re[3] = "../../../targets/ARCH/test-bbdev/test_vectors/ldpc_dec_v8480.data";
+printf("argcre %d argvre %s %s %s %s\n", argc_re, argv_re[0], argv_re[1], argv_re[2], argv_re[3],argv_re[4]);
+
+        ret = rte_eal_init(argc_re, argv_re);
+
+argc_re = 3;
+argv_re[0] = "--"; //./build/app/testbbdev"; 
+argv_re[1] = "-v";
+argv_re[2] = "../../../targets/ARCH/test-bbdev/test_vectors/ldpc_dec_v8480.data";
+
+//printf("after ......ret %d argc %d argv %s %s %s %s\n", ret,argc, argv[0], argv[1], argv[2], argv[3],argv[4]);
+        /* Parse application arguments (after the EAL ones) */
+      //  ret = parse_args(argc_re, argv_re, &test_params);
+        /*if (ret < 0) {
+                print_usage(argv_re[0]);
+                return 1;
+        }
+*/
+snprintf(test_params.test_vector_filename,sizeof(test_params.test_vector_filename),"%s", argv_re[2]); 
+
+test_params.num_ops=128;
+test_params.burst_sz=128;
+test_params.num_lcores=1;		
+test_params.num_tests = 1;
+run_all_tests();
 
-        /* Allocate memory for thread parameters structure */
+ /*       bool extDdr = check_bit(ldpc_cap_flags,
+			RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE);
+	bool loopback = check_bit(ref_op->ldpc_dec.op_flags,
+			RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK);
+	bool hc_out = check_bit(ref_op->ldpc_dec.op_flags,
+			RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE);
 	t_params_tp = rte_zmalloc(NULL, num_lcores * sizeof(struct thread_params),
 			RTE_CACHE_LINE_SIZE);
 	TEST_ASSERT_NOT_NULL(t_params_tp, "Failed to alloc %zuB for t_params",
 			RTE_ALIGN(sizeof(struct thread_params) * num_lcores,
 				RTE_CACHE_LINE_SIZE));
-
+*/
        // throughput_pmd_lcore_ldpc_dec(&t_params_tp[0]);
-
-
+     /*   ref_op->ldpc_dec.iter_max = get_iter_max();
+	ref_op->ldpc_dec.iter_count = ref_op->ldpc_dec.iter_max;
+
+	if (test_vector.op_type != RTE_BBDEV_OP_NONE)
+		copy_reference_ldpc_dec_op(ops_enq, num_ops, 0, bufs->inputs,
+				bufs->hard_outputs, bufs->soft_outputs,
+				bufs->harq_inputs, bufs->harq_outputs, ref_op);
+
+	for (j = 0; j < num_ops; ++j)
+		ops_enq[j]->opaque_data = (void *)(uintptr_t)j;
+
+	for (i = 0; i < TEST_REPETITIONS; ++i) {
+		for (j = 0; j < num_ops; ++j) {
+			if (!loopback)
+				mbuf_reset(
+				ops_enq[j]->ldpc_dec.hard_output.data);
+			if (hc_out || loopback)
+				mbuf_reset(
+				ops_enq[j]->ldpc_dec.harq_combined_output.data);
+		}
+		if (extDdr) {
+			bool preload = i == (TEST_REPETITIONS - 1);
+			preload_harq_ddr(tp->dev_id, queue_id, ops_enq,
+					num_ops, preload);
+		}
+
+		for (enq = 0, deq = 0; enq < num_ops;) {
+			num_to_enq = burst_sz;
+
+			if (unlikely(num_ops - enq < num_to_enq))
+				num_to_enq = num_ops - enq;
+				
+
+			enq += rte_bbdev_enqueue_ldpc_dec_ops(tp->dev_id,
+					queue_id, &ops_enq[enq], num_to_enq);
+
+			deq += rte_bbdev_dequeue_ldpc_dec_ops(tp->dev_id,
+					queue_id, &ops_deq[deq], enq - deq);
+		}
+
+		while (deq < enq) {
+			deq += rte_bbdev_dequeue_ldpc_dec_ops(tp->dev_id,
+					queue_id, &ops_deq[deq], enq - deq);
+		}
+
+	}
+*/
     return numIter;
 }
 
diff --git a/openair1/PHY/CODING/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_defs.h
index 72bafbead9..8f32c9a768 100644
--- a/openair1/PHY/CODING/nrLDPC_defs.h
+++ b/openair1/PHY/CODING/nrLDPC_defs.h
@@ -71,7 +71,10 @@ typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,sho
    \param p_llrOut Output vector
    \param p_profiler LDPC profiler statistics
 */
-typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params *, int8_t *, int8_t *, t_nrLDPC_procBuf *, t_nrLDPC_time_stats * );
-typedef int32_t(*nrLDPC_decoffloadfunc_t)(t_nrLDPC_dec_params* , uint8_t , uint8_t, uint32_t , int8_t*, int8_t* );
+
+typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_procBuf* , t_nrLDPC_time_stats* );
+typedef int32_t(*nrLDPC_decoffloadfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_procBuf* , t_nrLDPC_time_stats* );
+//typedef int32_t(*nrLDPC_decoffloadfunc_t)(t_nrLDPC_dec_params* , uint8_t , uint8_t, uint32_t , int8_t*, int8_t* );
+typedef int32_t(*nrLDPC_dectopfunc_t)(void);
 
 #endif
diff --git a/openair1/PHY/CODING/nrLDPC_extern.h b/openair1/PHY/CODING/nrLDPC_extern.h
index 4aa0ed5a2b..5cf9f80aec 100644
--- a/openair1/PHY/CODING/nrLDPC_extern.h
+++ b/openair1/PHY/CODING/nrLDPC_extern.h
@@ -25,6 +25,7 @@ nrLDPC_decoderfunc_t nrLDPC_decoder;
 nrLDPC_encoderfunc_t nrLDPC_encoder;
 nrLDPC_initcallfunc_t nrLDPC_initcall;
 nrLDPC_decoffloadfunc_t nrLDPC_decoder_offload;
+nrLDPC_dectopfunc_t top_testsuite;
 #else
 /* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */
 extern int load_nrLDPClib(char *version) ;
@@ -36,6 +37,9 @@ extern nrLDPC_initcallfunc_t nrLDPC_initcall;
 extern nrLDPC_decoderfunc_t nrLDPC_decoder;
 extern nrLDPC_encoderfunc_t nrLDPC_encoder;
 extern nrLDPC_decoffloadfunc_t nrLDPC_decoder_offload;
+
+extern nrLDPC_dectopfunc_t top_testsuite;
+
 // inline functions:
 #include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h"
 #endif
diff --git a/openair1/PHY/CODING/nrLDPC_load.c b/openair1/PHY/CODING/nrLDPC_load.c
index 7ac8768b63..44502193a9 100644
--- a/openair1/PHY/CODING/nrLDPC_load.c
+++ b/openair1/PHY/CODING/nrLDPC_load.c
@@ -81,6 +81,17 @@ int load_nrLDPClib_offload(void) {
 return 0;
 }
 
+/*int load_nrLDPClib_offload(void) {
+     loader_shlibfunc_t shlib_decoffload_fdesc;
+
+     shlib_decoffload_fdesc.fname = "top_testsuite";
+     int ret=load_module_shlib("ldpc_offload",&shlib_decoffload_fdesc,1,NULL);
+     AssertFatal( (ret >= 0),"Error loading ldpc decoder offload");
+     top_testsuite = (nrLDPC_dectopfunc_t)shlib_decoffload_fdesc.fptr;
+return 0;
+}
+*/
+
 int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr) {
 	loader_shlibfunc_t shlib_encoder_fdesc;
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index e9ed278bb1..79a726b6c6 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -357,7 +357,7 @@ void nr_processULSegment(void* arg) {
 
   ////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
 
-  no_iteration_ldpc = nrLDPC_decoder(p_decoderParms,
+  no_iteration_ldpc = nrLDPC_decoder_offload(p_decoderParms,
                                      (int8_t*)&pl[0],
                                      llrProcBuf,
                                      ulsch_harq->p_nrLDPC_procBuf[r],
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 76d896a047..cfefd4e612 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -640,6 +640,7 @@ int main(int argc, char **argv)
   get_softmodem_params()->do_ra = 0;
   get_softmodem_params()->usim_test = 1;
 
+  load_nrLDPClib_offload();
 
   if (snr1set == 0)
     snr1 = snr0 + 10;
diff --git a/targets/ARCH/test-bbdev/test_bbdev_perf.c b/targets/ARCH/test-bbdev/test_bbdev_perf.c
index 7bf4890cc7..c29c1d5a14 100644
--- a/targets/ARCH/test-bbdev/test_bbdev_perf.c
+++ b/targets/ARCH/test-bbdev/test_bbdev_perf.c
@@ -5050,9 +5050,9 @@ static struct unit_test_suite bbdev_interrupt_testsuite = {
 	}
 };
 
-REGISTER_TEST_COMMAND(bler, bbdev_bler_testsuite);
-REGISTER_TEST_COMMAND(throughput, bbdev_throughput_testsuite);
+//REGISTER_TEST_COMMAND(bler, bbdev_bler_testsuite);
+//REGISTER_TEST_COMMAND(throughput, bbdev_throughput_testsuite);
 REGISTER_TEST_COMMAND(validation, bbdev_validation_testsuite);
-REGISTER_TEST_COMMAND(latency, bbdev_latency_testsuite);
-REGISTER_TEST_COMMAND(offload, bbdev_offload_cost_testsuite);
-REGISTER_TEST_COMMAND(interrupt, bbdev_interrupt_testsuite);
+//REGISTER_TEST_COMMAND(latency, bbdev_latency_testsuite);
+//REGISTER_TEST_COMMAND(offload, bbdev_offload_cost_testsuite);
+//REGISTER_TEST_COMMAND(interrupt, bbdev_interrupt_testsuite);
diff --git a/targets/ARCH/test-bbdev/test_bbdev_vector.c b/targets/ARCH/test-bbdev/test_bbdev_vector.c
index cdbc813285..cc9a47a48a 100644
--- a/targets/ARCH/test-bbdev/test_bbdev_vector.c
+++ b/targets/ARCH/test-bbdev/test_bbdev_vector.c
@@ -392,11 +392,11 @@ parse_data_entry(const char *key_token, char *token,
 		printf("Unknown op type: %d!\n", type);
 		return -1;
 	}
-printf("parse data entry \n");
+//printf("parse data entry \n");
 
 	op_data = vector->entries[type].segments;
 	nb_ops = &vector->entries[type].nb_segments;
-printf("nb segments %d\n",*nb_ops);
+//printf("nb segments %d\n",*nb_ops);
 
 	if (*nb_ops >= RTE_BBDEV_TURBO_MAX_CODE_BLOCKS) {
 		printf("Too many segments (code blocks defined): %u, max %d!\n",
@@ -858,7 +858,7 @@ parse_ldpc_decoder_params(const char *key_token, char *token,
 static int
 parse_entry(char *entry, struct test_bbdev_vector *vector)
 {
-printf("parse entry \n");
+//printf("parse entry \n");
 	int ret = 0;
 	char *token, *key_token;
 	enum rte_bbdev_op_type op_type = RTE_BBDEV_OP_NONE;
@@ -1366,7 +1366,7 @@ test_bbdev_vector_read(const char *filename,
 	FILE *fp = NULL;
 	char *line = NULL;
 	char *entry = NULL;
-
+//sprintf(filename, "/home/wang/oai/openairinterface5g/targets/ARCH/test-bbdev/test_vectors/ldpc_dec_v8480.data");
 	fp = fopen(filename, "r");
 	if (fp == NULL) {
 		printf("File %s does not exist\n", filename);
-- 
2.26.2