1*d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*d30ea906Sjfb8856606  * Copyright(c) 2017 Intel Corporation
3*d30ea906Sjfb8856606  */
4*d30ea906Sjfb8856606 
5*d30ea906Sjfb8856606 #include <stdio.h>
6*d30ea906Sjfb8856606 #include <inttypes.h>
7*d30ea906Sjfb8856606 #include <math.h>
8*d30ea906Sjfb8856606 
9*d30ea906Sjfb8856606 #include <rte_eal.h>
10*d30ea906Sjfb8856606 #include <rte_common.h>
11*d30ea906Sjfb8856606 #include <rte_dev.h>
12*d30ea906Sjfb8856606 #include <rte_launch.h>
13*d30ea906Sjfb8856606 #include <rte_bbdev.h>
14*d30ea906Sjfb8856606 #include <rte_cycles.h>
15*d30ea906Sjfb8856606 #include <rte_lcore.h>
16*d30ea906Sjfb8856606 #include <rte_malloc.h>
17*d30ea906Sjfb8856606 #include <rte_random.h>
18*d30ea906Sjfb8856606 #include <rte_hexdump.h>
19*d30ea906Sjfb8856606 
20*d30ea906Sjfb8856606 #include "main.h"
21*d30ea906Sjfb8856606 #include "test_bbdev_vector.h"
22*d30ea906Sjfb8856606 
23*d30ea906Sjfb8856606 #define GET_SOCKET(socket_id) (((socket_id) == SOCKET_ID_ANY) ? 0 : (socket_id))
24*d30ea906Sjfb8856606 
25*d30ea906Sjfb8856606 #define MAX_QUEUES RTE_MAX_LCORE
26*d30ea906Sjfb8856606 
27*d30ea906Sjfb8856606 #define OPS_CACHE_SIZE 256U
28*d30ea906Sjfb8856606 #define OPS_POOL_SIZE_MIN 511U /* 0.5K per queue */
29*d30ea906Sjfb8856606 
30*d30ea906Sjfb8856606 #define SYNC_WAIT 0
31*d30ea906Sjfb8856606 #define SYNC_START 1
32*d30ea906Sjfb8856606 
33*d30ea906Sjfb8856606 #define INVALID_QUEUE_ID -1
34*d30ea906Sjfb8856606 
35*d30ea906Sjfb8856606 static struct test_bbdev_vector test_vector;
36*d30ea906Sjfb8856606 
37*d30ea906Sjfb8856606 /* Switch between PMD and Interrupt for throughput TC */
38*d30ea906Sjfb8856606 static bool intr_enabled;
39*d30ea906Sjfb8856606 
40*d30ea906Sjfb8856606 /* Represents tested active devices */
41*d30ea906Sjfb8856606 static struct active_device {
42*d30ea906Sjfb8856606 	const char *driver_name;
43*d30ea906Sjfb8856606 	uint8_t dev_id;
44*d30ea906Sjfb8856606 	uint16_t supported_ops;
45*d30ea906Sjfb8856606 	uint16_t queue_ids[MAX_QUEUES];
46*d30ea906Sjfb8856606 	uint16_t nb_queues;
47*d30ea906Sjfb8856606 	struct rte_mempool *ops_mempool;
48*d30ea906Sjfb8856606 	struct rte_mempool *in_mbuf_pool;
49*d30ea906Sjfb8856606 	struct rte_mempool *hard_out_mbuf_pool;
50*d30ea906Sjfb8856606 	struct rte_mempool *soft_out_mbuf_pool;
51*d30ea906Sjfb8856606 } active_devs[RTE_BBDEV_MAX_DEVS];
52*d30ea906Sjfb8856606 
53*d30ea906Sjfb8856606 static uint8_t nb_active_devs;
54*d30ea906Sjfb8856606 
55*d30ea906Sjfb8856606 /* Data buffers used by BBDEV ops */
56*d30ea906Sjfb8856606 struct test_buffers {
57*d30ea906Sjfb8856606 	struct rte_bbdev_op_data *inputs;
58*d30ea906Sjfb8856606 	struct rte_bbdev_op_data *hard_outputs;
59*d30ea906Sjfb8856606 	struct rte_bbdev_op_data *soft_outputs;
60*d30ea906Sjfb8856606 };
61*d30ea906Sjfb8856606 
62*d30ea906Sjfb8856606 /* Operation parameters specific for given test case */
63*d30ea906Sjfb8856606 struct test_op_params {
64*d30ea906Sjfb8856606 	struct rte_mempool *mp;
65*d30ea906Sjfb8856606 	struct rte_bbdev_dec_op *ref_dec_op;
66*d30ea906Sjfb8856606 	struct rte_bbdev_enc_op *ref_enc_op;
67*d30ea906Sjfb8856606 	uint16_t burst_sz;
68*d30ea906Sjfb8856606 	uint16_t num_to_process;
69*d30ea906Sjfb8856606 	uint16_t num_lcores;
70*d30ea906Sjfb8856606 	int vector_mask;
71*d30ea906Sjfb8856606 	rte_atomic16_t sync;
72*d30ea906Sjfb8856606 	struct test_buffers q_bufs[RTE_MAX_NUMA_NODES][MAX_QUEUES];
73*d30ea906Sjfb8856606 };
74*d30ea906Sjfb8856606 
75*d30ea906Sjfb8856606 /* Contains per lcore params */
76*d30ea906Sjfb8856606 struct thread_params {
77*d30ea906Sjfb8856606 	uint8_t dev_id;
78*d30ea906Sjfb8856606 	uint16_t queue_id;
79*d30ea906Sjfb8856606 	uint64_t start_time;
80*d30ea906Sjfb8856606 	double mops;
81*d30ea906Sjfb8856606 	double mbps;
82*d30ea906Sjfb8856606 	rte_atomic16_t nb_dequeued;
83*d30ea906Sjfb8856606 	rte_atomic16_t processing_status;
84*d30ea906Sjfb8856606 	struct test_op_params *op_params;
85*d30ea906Sjfb8856606 };
86*d30ea906Sjfb8856606 
87*d30ea906Sjfb8856606 #ifdef RTE_BBDEV_OFFLOAD_COST
88*d30ea906Sjfb8856606 /* Stores time statistics */
89*d30ea906Sjfb8856606 struct test_time_stats {
90*d30ea906Sjfb8856606 	/* Stores software enqueue total working time */
91*d30ea906Sjfb8856606 	uint64_t enq_sw_tot_time;
92*d30ea906Sjfb8856606 	/* Stores minimum value of software enqueue working time */
93*d30ea906Sjfb8856606 	uint64_t enq_sw_min_time;
94*d30ea906Sjfb8856606 	/* Stores maximum value of software enqueue working time */
95*d30ea906Sjfb8856606 	uint64_t enq_sw_max_time;
96*d30ea906Sjfb8856606 	/* Stores turbo enqueue total working time */
97*d30ea906Sjfb8856606 	uint64_t enq_tur_tot_time;
98*d30ea906Sjfb8856606 	/* Stores minimum value of turbo enqueue working time */
99*d30ea906Sjfb8856606 	uint64_t enq_tur_min_time;
100*d30ea906Sjfb8856606 	/* Stores maximum value of turbo enqueue working time */
101*d30ea906Sjfb8856606 	uint64_t enq_tur_max_time;
102*d30ea906Sjfb8856606 	/* Stores dequeue total working time */
103*d30ea906Sjfb8856606 	uint64_t deq_tot_time;
104*d30ea906Sjfb8856606 	/* Stores minimum value of dequeue working time */
105*d30ea906Sjfb8856606 	uint64_t deq_min_time;
106*d30ea906Sjfb8856606 	/* Stores maximum value of dequeue working time */
107*d30ea906Sjfb8856606 	uint64_t deq_max_time;
108*d30ea906Sjfb8856606 };
109*d30ea906Sjfb8856606 #endif
110*d30ea906Sjfb8856606 
111*d30ea906Sjfb8856606 typedef int (test_case_function)(struct active_device *ad,
112*d30ea906Sjfb8856606 		struct test_op_params *op_params);
113*d30ea906Sjfb8856606 
114*d30ea906Sjfb8856606 static inline void
115*d30ea906Sjfb8856606 set_avail_op(struct active_device *ad, enum rte_bbdev_op_type op_type)
116*d30ea906Sjfb8856606 {
117*d30ea906Sjfb8856606 	ad->supported_ops |= (1 << op_type);
118*d30ea906Sjfb8856606 }
119*d30ea906Sjfb8856606 
120*d30ea906Sjfb8856606 static inline bool
121*d30ea906Sjfb8856606 is_avail_op(struct active_device *ad, enum rte_bbdev_op_type op_type)
122*d30ea906Sjfb8856606 {
123*d30ea906Sjfb8856606 	return ad->supported_ops & (1 << op_type);
124*d30ea906Sjfb8856606 }
125*d30ea906Sjfb8856606 
126*d30ea906Sjfb8856606 static inline bool
127*d30ea906Sjfb8856606 flags_match(uint32_t flags_req, uint32_t flags_present)
128*d30ea906Sjfb8856606 {
129*d30ea906Sjfb8856606 	return (flags_req & flags_present) == flags_req;
130*d30ea906Sjfb8856606 }
131*d30ea906Sjfb8856606 
132*d30ea906Sjfb8856606 static void
133*d30ea906Sjfb8856606 clear_soft_out_cap(uint32_t *op_flags)
134*d30ea906Sjfb8856606 {
135*d30ea906Sjfb8856606 	*op_flags &= ~RTE_BBDEV_TURBO_SOFT_OUTPUT;
136*d30ea906Sjfb8856606 	*op_flags &= ~RTE_BBDEV_TURBO_POS_LLR_1_BIT_SOFT_OUT;
137*d30ea906Sjfb8856606 	*op_flags &= ~RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT;
138*d30ea906Sjfb8856606 }
139*d30ea906Sjfb8856606 
140*d30ea906Sjfb8856606 static int
141*d30ea906Sjfb8856606 check_dev_cap(const struct rte_bbdev_info *dev_info)
142*d30ea906Sjfb8856606 {
143*d30ea906Sjfb8856606 	unsigned int i;
144*d30ea906Sjfb8856606 	unsigned int nb_inputs, nb_soft_outputs, nb_hard_outputs;
145*d30ea906Sjfb8856606 	const struct rte_bbdev_op_cap *op_cap = dev_info->drv.capabilities;
146*d30ea906Sjfb8856606 
147*d30ea906Sjfb8856606 	nb_inputs = test_vector.entries[DATA_INPUT].nb_segments;
148*d30ea906Sjfb8856606 	nb_soft_outputs = test_vector.entries[DATA_SOFT_OUTPUT].nb_segments;
149*d30ea906Sjfb8856606 	nb_hard_outputs = test_vector.entries[DATA_HARD_OUTPUT].nb_segments;
150*d30ea906Sjfb8856606 
151*d30ea906Sjfb8856606 	for (i = 0; op_cap->type != RTE_BBDEV_OP_NONE; ++i, ++op_cap) {
152*d30ea906Sjfb8856606 		if (op_cap->type != test_vector.op_type)
153*d30ea906Sjfb8856606 			continue;
154*d30ea906Sjfb8856606 
155*d30ea906Sjfb8856606 		if (op_cap->type == RTE_BBDEV_OP_TURBO_DEC) {
156*d30ea906Sjfb8856606 			const struct rte_bbdev_op_cap_turbo_dec *cap =
157*d30ea906Sjfb8856606 					&op_cap->cap.turbo_dec;
158*d30ea906Sjfb8856606 			/* Ignore lack of soft output capability, just skip
159*d30ea906Sjfb8856606 			 * checking if soft output is valid.
160*d30ea906Sjfb8856606 			 */
161*d30ea906Sjfb8856606 			if ((test_vector.turbo_dec.op_flags &
162*d30ea906Sjfb8856606 					RTE_BBDEV_TURBO_SOFT_OUTPUT) &&
163*d30ea906Sjfb8856606 					!(cap->capability_flags &
164*d30ea906Sjfb8856606 					RTE_BBDEV_TURBO_SOFT_OUTPUT)) {
165*d30ea906Sjfb8856606 				printf(
166*d30ea906Sjfb8856606 					"WARNING: Device \"%s\" does not support soft output - soft output flags will be ignored.\n",
167*d30ea906Sjfb8856606 					dev_info->dev_name);
168*d30ea906Sjfb8856606 				clear_soft_out_cap(
169*d30ea906Sjfb8856606 					&test_vector.turbo_dec.op_flags);
170*d30ea906Sjfb8856606 			}
171*d30ea906Sjfb8856606 
172*d30ea906Sjfb8856606 			if (!flags_match(test_vector.turbo_dec.op_flags,
173*d30ea906Sjfb8856606 					cap->capability_flags))
174*d30ea906Sjfb8856606 				return TEST_FAILED;
175*d30ea906Sjfb8856606 			if (nb_inputs > cap->num_buffers_src) {
176*d30ea906Sjfb8856606 				printf("Too many inputs defined: %u, max: %u\n",
177*d30ea906Sjfb8856606 					nb_inputs, cap->num_buffers_src);
178*d30ea906Sjfb8856606 				return TEST_FAILED;
179*d30ea906Sjfb8856606 			}
180*d30ea906Sjfb8856606 			if (nb_soft_outputs > cap->num_buffers_soft_out &&
181*d30ea906Sjfb8856606 					(test_vector.turbo_dec.op_flags &
182*d30ea906Sjfb8856606 					RTE_BBDEV_TURBO_SOFT_OUTPUT)) {
183*d30ea906Sjfb8856606 				printf(
184*d30ea906Sjfb8856606 					"Too many soft outputs defined: %u, max: %u\n",
185*d30ea906Sjfb8856606 						nb_soft_outputs,
186*d30ea906Sjfb8856606 						cap->num_buffers_soft_out);
187*d30ea906Sjfb8856606 				return TEST_FAILED;
188*d30ea906Sjfb8856606 			}
189*d30ea906Sjfb8856606 			if (nb_hard_outputs > cap->num_buffers_hard_out) {
190*d30ea906Sjfb8856606 				printf(
191*d30ea906Sjfb8856606 					"Too many hard outputs defined: %u, max: %u\n",
192*d30ea906Sjfb8856606 						nb_hard_outputs,
193*d30ea906Sjfb8856606 						cap->num_buffers_hard_out);
194*d30ea906Sjfb8856606 				return TEST_FAILED;
195*d30ea906Sjfb8856606 			}
196*d30ea906Sjfb8856606 			if (intr_enabled && !(cap->capability_flags &
197*d30ea906Sjfb8856606 					RTE_BBDEV_TURBO_DEC_INTERRUPTS)) {
198*d30ea906Sjfb8856606 				printf(
199*d30ea906Sjfb8856606 					"Dequeue interrupts are not supported!\n");
200*d30ea906Sjfb8856606 				return TEST_FAILED;
201*d30ea906Sjfb8856606 			}
202*d30ea906Sjfb8856606 
203*d30ea906Sjfb8856606 			return TEST_SUCCESS;
204*d30ea906Sjfb8856606 		} else if (op_cap->type == RTE_BBDEV_OP_TURBO_ENC) {
205*d30ea906Sjfb8856606 			const struct rte_bbdev_op_cap_turbo_enc *cap =
206*d30ea906Sjfb8856606 					&op_cap->cap.turbo_enc;
207*d30ea906Sjfb8856606 
208*d30ea906Sjfb8856606 			if (!flags_match(test_vector.turbo_enc.op_flags,
209*d30ea906Sjfb8856606 					cap->capability_flags))
210*d30ea906Sjfb8856606 				return TEST_FAILED;
211*d30ea906Sjfb8856606 			if (nb_inputs > cap->num_buffers_src) {
212*d30ea906Sjfb8856606 				printf("Too many inputs defined: %u, max: %u\n",
213*d30ea906Sjfb8856606 					nb_inputs, cap->num_buffers_src);
214*d30ea906Sjfb8856606 				return TEST_FAILED;
215*d30ea906Sjfb8856606 			}
216*d30ea906Sjfb8856606 			if (nb_hard_outputs > cap->num_buffers_dst) {
217*d30ea906Sjfb8856606 				printf(
218*d30ea906Sjfb8856606 					"Too many hard outputs defined: %u, max: %u\n",
219*d30ea906Sjfb8856606 					nb_hard_outputs, cap->num_buffers_src);
220*d30ea906Sjfb8856606 				return TEST_FAILED;
221*d30ea906Sjfb8856606 			}
222*d30ea906Sjfb8856606 			if (intr_enabled && !(cap->capability_flags &
223*d30ea906Sjfb8856606 					RTE_BBDEV_TURBO_ENC_INTERRUPTS)) {
224*d30ea906Sjfb8856606 				printf(
225*d30ea906Sjfb8856606 					"Dequeue interrupts are not supported!\n");
226*d30ea906Sjfb8856606 				return TEST_FAILED;
227*d30ea906Sjfb8856606 			}
228*d30ea906Sjfb8856606 
229*d30ea906Sjfb8856606 			return TEST_SUCCESS;
230*d30ea906Sjfb8856606 		}
231*d30ea906Sjfb8856606 	}
232*d30ea906Sjfb8856606 
233*d30ea906Sjfb8856606 	if ((i == 0) && (test_vector.op_type == RTE_BBDEV_OP_NONE))
234*d30ea906Sjfb8856606 		return TEST_SUCCESS; /* Special case for NULL device */
235*d30ea906Sjfb8856606 
236*d30ea906Sjfb8856606 	return TEST_FAILED;
237*d30ea906Sjfb8856606 }
238*d30ea906Sjfb8856606 
239*d30ea906Sjfb8856606 /* calculates optimal mempool size not smaller than the val */
240*d30ea906Sjfb8856606 static unsigned int
241*d30ea906Sjfb8856606 optimal_mempool_size(unsigned int val)
242*d30ea906Sjfb8856606 {
243*d30ea906Sjfb8856606 	return rte_align32pow2(val + 1) - 1;
244*d30ea906Sjfb8856606 }
245*d30ea906Sjfb8856606 
246*d30ea906Sjfb8856606 /* allocates mbuf mempool for inputs and outputs */
247*d30ea906Sjfb8856606 static struct rte_mempool *
248*d30ea906Sjfb8856606 create_mbuf_pool(struct op_data_entries *entries, uint8_t dev_id,
249*d30ea906Sjfb8856606 		int socket_id, unsigned int mbuf_pool_size,
250*d30ea906Sjfb8856606 		const char *op_type_str)
251*d30ea906Sjfb8856606 {
252*d30ea906Sjfb8856606 	unsigned int i;
253*d30ea906Sjfb8856606 	uint32_t max_seg_sz = 0;
254*d30ea906Sjfb8856606 	char pool_name[RTE_MEMPOOL_NAMESIZE];
255*d30ea906Sjfb8856606 
256*d30ea906Sjfb8856606 	/* find max input segment size */
257*d30ea906Sjfb8856606 	for (i = 0; i < entries->nb_segments; ++i)
258*d30ea906Sjfb8856606 		if (entries->segments[i].length > max_seg_sz)
259*d30ea906Sjfb8856606 			max_seg_sz = entries->segments[i].length;
260*d30ea906Sjfb8856606 
261*d30ea906Sjfb8856606 	snprintf(pool_name, sizeof(pool_name), "%s_pool_%u", op_type_str,
262*d30ea906Sjfb8856606 			dev_id);
263*d30ea906Sjfb8856606 	return rte_pktmbuf_pool_create(pool_name, mbuf_pool_size, 0, 0,
264*d30ea906Sjfb8856606 			RTE_MAX(max_seg_sz + RTE_PKTMBUF_HEADROOM,
265*d30ea906Sjfb8856606 			(unsigned int)RTE_MBUF_DEFAULT_BUF_SIZE), socket_id);
266*d30ea906Sjfb8856606 }
267*d30ea906Sjfb8856606 
268*d30ea906Sjfb8856606 static int
269*d30ea906Sjfb8856606 create_mempools(struct active_device *ad, int socket_id,
270*d30ea906Sjfb8856606 		enum rte_bbdev_op_type org_op_type, uint16_t num_ops)
271*d30ea906Sjfb8856606 {
272*d30ea906Sjfb8856606 	struct rte_mempool *mp;
273*d30ea906Sjfb8856606 	unsigned int ops_pool_size, mbuf_pool_size = 0;
274*d30ea906Sjfb8856606 	char pool_name[RTE_MEMPOOL_NAMESIZE];
275*d30ea906Sjfb8856606 	const char *op_type_str;
276*d30ea906Sjfb8856606 	enum rte_bbdev_op_type op_type = org_op_type;
277*d30ea906Sjfb8856606 
278*d30ea906Sjfb8856606 	struct op_data_entries *in = &test_vector.entries[DATA_INPUT];
279*d30ea906Sjfb8856606 	struct op_data_entries *hard_out =
280*d30ea906Sjfb8856606 			&test_vector.entries[DATA_HARD_OUTPUT];
281*d30ea906Sjfb8856606 	struct op_data_entries *soft_out =
282*d30ea906Sjfb8856606 			&test_vector.entries[DATA_SOFT_OUTPUT];
283*d30ea906Sjfb8856606 
284*d30ea906Sjfb8856606 	/* allocate ops mempool */
285*d30ea906Sjfb8856606 	ops_pool_size = optimal_mempool_size(RTE_MAX(
286*d30ea906Sjfb8856606 			/* Ops used plus 1 reference op */
287*d30ea906Sjfb8856606 			RTE_MAX((unsigned int)(ad->nb_queues * num_ops + 1),
288*d30ea906Sjfb8856606 			/* Minimal cache size plus 1 reference op */
289*d30ea906Sjfb8856606 			(unsigned int)(1.5 * rte_lcore_count() *
290*d30ea906Sjfb8856606 					OPS_CACHE_SIZE + 1)),
291*d30ea906Sjfb8856606 			OPS_POOL_SIZE_MIN));
292*d30ea906Sjfb8856606 
293*d30ea906Sjfb8856606 	if (org_op_type == RTE_BBDEV_OP_NONE)
294*d30ea906Sjfb8856606 		op_type = RTE_BBDEV_OP_TURBO_ENC;
295*d30ea906Sjfb8856606 
296*d30ea906Sjfb8856606 	op_type_str = rte_bbdev_op_type_str(op_type);
297*d30ea906Sjfb8856606 	TEST_ASSERT_NOT_NULL(op_type_str, "Invalid op type: %u", op_type);
298*d30ea906Sjfb8856606 
299*d30ea906Sjfb8856606 	snprintf(pool_name, sizeof(pool_name), "%s_pool_%u", op_type_str,
300*d30ea906Sjfb8856606 			ad->dev_id);
301*d30ea906Sjfb8856606 	mp = rte_bbdev_op_pool_create(pool_name, op_type,
302*d30ea906Sjfb8856606 			ops_pool_size, OPS_CACHE_SIZE, socket_id);
303*d30ea906Sjfb8856606 	TEST_ASSERT_NOT_NULL(mp,
304*d30ea906Sjfb8856606 			"ERROR Failed to create %u items ops pool for dev %u on socket %u.",
305*d30ea906Sjfb8856606 			ops_pool_size,
306*d30ea906Sjfb8856606 			ad->dev_id,
307*d30ea906Sjfb8856606 			socket_id);
308*d30ea906Sjfb8856606 	ad->ops_mempool = mp;
309*d30ea906Sjfb8856606 
310*d30ea906Sjfb8856606 	/* Do not create inputs and outputs mbufs for BaseBand Null Device */
311*d30ea906Sjfb8856606 	if (org_op_type == RTE_BBDEV_OP_NONE)
312*d30ea906Sjfb8856606 		return TEST_SUCCESS;
313*d30ea906Sjfb8856606 
314*d30ea906Sjfb8856606 	/* Inputs */
315*d30ea906Sjfb8856606 	mbuf_pool_size = optimal_mempool_size(ops_pool_size * in->nb_segments);
316*d30ea906Sjfb8856606 	mp = create_mbuf_pool(in, ad->dev_id, socket_id, mbuf_pool_size, "in");
317*d30ea906Sjfb8856606 	TEST_ASSERT_NOT_NULL(mp,
318*d30ea906Sjfb8856606 			"ERROR Failed to create %u items input pktmbuf pool for dev %u on socket %u.",
319*d30ea906Sjfb8856606 			mbuf_pool_size,
320*d30ea906Sjfb8856606 			ad->dev_id,
321*d30ea906Sjfb8856606 			socket_id);
322*d30ea906Sjfb8856606 	ad->in_mbuf_pool = mp;
323*d30ea906Sjfb8856606 
324*d30ea906Sjfb8856606 	/* Hard outputs */
325*d30ea906Sjfb8856606 	mbuf_pool_size = optimal_mempool_size(ops_pool_size *
326*d30ea906Sjfb8856606 			hard_out->nb_segments);
327*d30ea906Sjfb8856606 	mp = create_mbuf_pool(hard_out, ad->dev_id, socket_id, mbuf_pool_size,
328*d30ea906Sjfb8856606 			"hard_out");
329*d30ea906Sjfb8856606 	TEST_ASSERT_NOT_NULL(mp,
330*d30ea906Sjfb8856606 			"ERROR Failed to create %u items hard output pktmbuf pool for dev %u on socket %u.",
331*d30ea906Sjfb8856606 			mbuf_pool_size,
332*d30ea906Sjfb8856606 			ad->dev_id,
333*d30ea906Sjfb8856606 			socket_id);
334*d30ea906Sjfb8856606 	ad->hard_out_mbuf_pool = mp;
335*d30ea906Sjfb8856606 
336*d30ea906Sjfb8856606 	if (soft_out->nb_segments == 0)
337*d30ea906Sjfb8856606 		return TEST_SUCCESS;
338*d30ea906Sjfb8856606 
339*d30ea906Sjfb8856606 	/* Soft outputs */
340*d30ea906Sjfb8856606 	mbuf_pool_size = optimal_mempool_size(ops_pool_size *
341*d30ea906Sjfb8856606 			soft_out->nb_segments);
342*d30ea906Sjfb8856606 	mp = create_mbuf_pool(soft_out, ad->dev_id, socket_id, mbuf_pool_size,
343*d30ea906Sjfb8856606 			"soft_out");
344*d30ea906Sjfb8856606 	TEST_ASSERT_NOT_NULL(mp,
345*d30ea906Sjfb8856606 			"ERROR Failed to create %uB soft output pktmbuf pool for dev %u on socket %u.",
346*d30ea906Sjfb8856606 			mbuf_pool_size,
347*d30ea906Sjfb8856606 			ad->dev_id,
348*d30ea906Sjfb8856606 			socket_id);
349*d30ea906Sjfb8856606 	ad->soft_out_mbuf_pool = mp;
350*d30ea906Sjfb8856606 
351*d30ea906Sjfb8856606 	return 0;
352*d30ea906Sjfb8856606 }
353*d30ea906Sjfb8856606 
354*d30ea906Sjfb8856606 static int
355*d30ea906Sjfb8856606 add_bbdev_dev(uint8_t dev_id, struct rte_bbdev_info *info,
356*d30ea906Sjfb8856606 		struct test_bbdev_vector *vector)
357*d30ea906Sjfb8856606 {
358*d30ea906Sjfb8856606 	int ret;
359*d30ea906Sjfb8856606 	unsigned int queue_id;
360*d30ea906Sjfb8856606 	struct rte_bbdev_queue_conf qconf;
361*d30ea906Sjfb8856606 	struct active_device *ad = &active_devs[nb_active_devs];
362*d30ea906Sjfb8856606 	unsigned int nb_queues;
363*d30ea906Sjfb8856606 	enum rte_bbdev_op_type op_type = vector->op_type;
364*d30ea906Sjfb8856606 
365*d30ea906Sjfb8856606 	nb_queues = RTE_MIN(rte_lcore_count(), info->drv.max_num_queues);
366*d30ea906Sjfb8856606 	/* setup device */
367*d30ea906Sjfb8856606 	ret = rte_bbdev_setup_queues(dev_id, nb_queues, info->socket_id);
368*d30ea906Sjfb8856606 	if (ret < 0) {
369*d30ea906Sjfb8856606 		printf("rte_bbdev_setup_queues(%u, %u, %d) ret %i\n",
370*d30ea906Sjfb8856606 				dev_id, nb_queues, info->socket_id, ret);
371*d30ea906Sjfb8856606 		return TEST_FAILED;
372*d30ea906Sjfb8856606 	}
373*d30ea906Sjfb8856606 
374*d30ea906Sjfb8856606 	/* configure interrupts if needed */
375*d30ea906Sjfb8856606 	if (intr_enabled) {
376*d30ea906Sjfb8856606 		ret = rte_bbdev_intr_enable(dev_id);
377*d30ea906Sjfb8856606 		if (ret < 0) {
378*d30ea906Sjfb8856606 			printf("rte_bbdev_intr_enable(%u) ret %i\n", dev_id,
379*d30ea906Sjfb8856606 					ret);
380*d30ea906Sjfb8856606 			return TEST_FAILED;
381*d30ea906Sjfb8856606 		}
382*d30ea906Sjfb8856606 	}
383*d30ea906Sjfb8856606 
384*d30ea906Sjfb8856606 	/* setup device queues */
385*d30ea906Sjfb8856606 	qconf.socket = info->socket_id;
386*d30ea906Sjfb8856606 	qconf.queue_size = info->drv.default_queue_conf.queue_size;
387*d30ea906Sjfb8856606 	qconf.priority = 0;
388*d30ea906Sjfb8856606 	qconf.deferred_start = 0;
389*d30ea906Sjfb8856606 	qconf.op_type = op_type;
390*d30ea906Sjfb8856606 
391*d30ea906Sjfb8856606 	for (queue_id = 0; queue_id < nb_queues; ++queue_id) {
392*d30ea906Sjfb8856606 		ret = rte_bbdev_queue_configure(dev_id, queue_id, &qconf);
393*d30ea906Sjfb8856606 		if (ret != 0) {
394*d30ea906Sjfb8856606 			printf(
395*d30ea906Sjfb8856606 					"Allocated all queues (id=%u) at prio%u on dev%u\n",
396*d30ea906Sjfb8856606 					queue_id, qconf.priority, dev_id);
397*d30ea906Sjfb8856606 			qconf.priority++;
398*d30ea906Sjfb8856606 			ret = rte_bbdev_queue_configure(ad->dev_id, queue_id,
399*d30ea906Sjfb8856606 					&qconf);
400*d30ea906Sjfb8856606 		}
401*d30ea906Sjfb8856606 		if (ret != 0) {
402*d30ea906Sjfb8856606 			printf("All queues on dev %u allocated: %u\n",
403*d30ea906Sjfb8856606 					dev_id, queue_id);
404*d30ea906Sjfb8856606 			break;
405*d30ea906Sjfb8856606 		}
406*d30ea906Sjfb8856606 		ad->queue_ids[queue_id] = queue_id;
407*d30ea906Sjfb8856606 	}
408*d30ea906Sjfb8856606 	TEST_ASSERT(queue_id != 0,
409*d30ea906Sjfb8856606 			"ERROR Failed to configure any queues on dev %u",
410*d30ea906Sjfb8856606 			dev_id);
411*d30ea906Sjfb8856606 	ad->nb_queues = queue_id;
412*d30ea906Sjfb8856606 
413*d30ea906Sjfb8856606 	set_avail_op(ad, op_type);
414*d30ea906Sjfb8856606 
415*d30ea906Sjfb8856606 	return TEST_SUCCESS;
416*d30ea906Sjfb8856606 }
417*d30ea906Sjfb8856606 
418*d30ea906Sjfb8856606 static int
419*d30ea906Sjfb8856606 add_active_device(uint8_t dev_id, struct rte_bbdev_info *info,
420*d30ea906Sjfb8856606 		struct test_bbdev_vector *vector)
421*d30ea906Sjfb8856606 {
422*d30ea906Sjfb8856606 	int ret;
423*d30ea906Sjfb8856606 
424*d30ea906Sjfb8856606 	active_devs[nb_active_devs].driver_name = info->drv.driver_name;
425*d30ea906Sjfb8856606 	active_devs[nb_active_devs].dev_id = dev_id;
426*d30ea906Sjfb8856606 
427*d30ea906Sjfb8856606 	ret = add_bbdev_dev(dev_id, info, vector);
428*d30ea906Sjfb8856606 	if (ret == TEST_SUCCESS)
429*d30ea906Sjfb8856606 		++nb_active_devs;
430*d30ea906Sjfb8856606 	return ret;
431*d30ea906Sjfb8856606 }
432*d30ea906Sjfb8856606 
433*d30ea906Sjfb8856606 static uint8_t
434*d30ea906Sjfb8856606 populate_active_devices(void)
435*d30ea906Sjfb8856606 {
436*d30ea906Sjfb8856606 	int ret;
437*d30ea906Sjfb8856606 	uint8_t dev_id;
438*d30ea906Sjfb8856606 	uint8_t nb_devs_added = 0;
439*d30ea906Sjfb8856606 	struct rte_bbdev_info info;
440*d30ea906Sjfb8856606 
441*d30ea906Sjfb8856606 	RTE_BBDEV_FOREACH(dev_id) {
442*d30ea906Sjfb8856606 		rte_bbdev_info_get(dev_id, &info);
443*d30ea906Sjfb8856606 
444*d30ea906Sjfb8856606 		if (check_dev_cap(&info)) {
445*d30ea906Sjfb8856606 			printf(
446*d30ea906Sjfb8856606 				"Device %d (%s) does not support specified capabilities\n",
447*d30ea906Sjfb8856606 					dev_id, info.dev_name);
448*d30ea906Sjfb8856606 			continue;
449*d30ea906Sjfb8856606 		}
450*d30ea906Sjfb8856606 
451*d30ea906Sjfb8856606 		ret = add_active_device(dev_id, &info, &test_vector);
452*d30ea906Sjfb8856606 		if (ret != 0) {
453*d30ea906Sjfb8856606 			printf("Adding active bbdev %s skipped\n",
454*d30ea906Sjfb8856606 					info.dev_name);
455*d30ea906Sjfb8856606 			continue;
456*d30ea906Sjfb8856606 		}
457*d30ea906Sjfb8856606 		nb_devs_added++;
458*d30ea906Sjfb8856606 	}
459*d30ea906Sjfb8856606 
460*d30ea906Sjfb8856606 	return nb_devs_added;
461*d30ea906Sjfb8856606 }
462*d30ea906Sjfb8856606 
463*d30ea906Sjfb8856606 static int
464*d30ea906Sjfb8856606 read_test_vector(void)
465*d30ea906Sjfb8856606 {
466*d30ea906Sjfb8856606 	int ret;
467*d30ea906Sjfb8856606 
468*d30ea906Sjfb8856606 	memset(&test_vector, 0, sizeof(test_vector));
469*d30ea906Sjfb8856606 	printf("Test vector file = %s\n", get_vector_filename());
470*d30ea906Sjfb8856606 	ret = test_bbdev_vector_read(get_vector_filename(), &test_vector);
471*d30ea906Sjfb8856606 	TEST_ASSERT_SUCCESS(ret, "Failed to parse file %s\n",
472*d30ea906Sjfb8856606 			get_vector_filename());
473*d30ea906Sjfb8856606 
474*d30ea906Sjfb8856606 	return TEST_SUCCESS;
475*d30ea906Sjfb8856606 }
476*d30ea906Sjfb8856606 
477*d30ea906Sjfb8856606 static int
478*d30ea906Sjfb8856606 testsuite_setup(void)
479*d30ea906Sjfb8856606 {
480*d30ea906Sjfb8856606 	TEST_ASSERT_SUCCESS(read_test_vector(), "Test suite setup failed\n");
481*d30ea906Sjfb8856606 
482*d30ea906Sjfb8856606 	if (populate_active_devices() == 0) {
483*d30ea906Sjfb8856606 		printf("No suitable devices found!\n");
484*d30ea906Sjfb8856606 		return TEST_SKIPPED;
485*d30ea906Sjfb8856606 	}
486*d30ea906Sjfb8856606 
487*d30ea906Sjfb8856606 	return TEST_SUCCESS;
488*d30ea906Sjfb8856606 }
489*d30ea906Sjfb8856606 
490*d30ea906Sjfb8856606 static int
491*d30ea906Sjfb8856606 interrupt_testsuite_setup(void)
492*d30ea906Sjfb8856606 {
493*d30ea906Sjfb8856606 	TEST_ASSERT_SUCCESS(read_test_vector(), "Test suite setup failed\n");
494*d30ea906Sjfb8856606 
495*d30ea906Sjfb8856606 	/* Enable interrupts */
496*d30ea906Sjfb8856606 	intr_enabled = true;
497*d30ea906Sjfb8856606 
498*d30ea906Sjfb8856606 	/* Special case for NULL device (RTE_BBDEV_OP_NONE) */
499*d30ea906Sjfb8856606 	if (populate_active_devices() == 0 ||
500*d30ea906Sjfb8856606 			test_vector.op_type == RTE_BBDEV_OP_NONE) {
501*d30ea906Sjfb8856606 		intr_enabled = false;
502*d30ea906Sjfb8856606 		printf("No suitable devices found!\n");
503*d30ea906Sjfb8856606 		return TEST_SKIPPED;
504*d30ea906Sjfb8856606 	}
505*d30ea906Sjfb8856606 
506*d30ea906Sjfb8856606 	return TEST_SUCCESS;
507*d30ea906Sjfb8856606 }
508*d30ea906Sjfb8856606 
509*d30ea906Sjfb8856606 static void
510*d30ea906Sjfb8856606 testsuite_teardown(void)
511*d30ea906Sjfb8856606 {
512*d30ea906Sjfb8856606 	uint8_t dev_id;
513*d30ea906Sjfb8856606 
514*d30ea906Sjfb8856606 	/* Unconfigure devices */
515*d30ea906Sjfb8856606 	RTE_BBDEV_FOREACH(dev_id)
516*d30ea906Sjfb8856606 		rte_bbdev_close(dev_id);
517*d30ea906Sjfb8856606 
518*d30ea906Sjfb8856606 	/* Clear active devices structs. */
519*d30ea906Sjfb8856606 	memset(active_devs, 0, sizeof(active_devs));
520*d30ea906Sjfb8856606 	nb_active_devs = 0;
521*d30ea906Sjfb8856606 }
522*d30ea906Sjfb8856606 
523*d30ea906Sjfb8856606 static int
524*d30ea906Sjfb8856606 ut_setup(void)
525*d30ea906Sjfb8856606 {
526*d30ea906Sjfb8856606 	uint8_t i, dev_id;
527*d30ea906Sjfb8856606 
528*d30ea906Sjfb8856606 	for (i = 0; i < nb_active_devs; i++) {
529*d30ea906Sjfb8856606 		dev_id = active_devs[i].dev_id;
530*d30ea906Sjfb8856606 		/* reset bbdev stats */
531*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(rte_bbdev_stats_reset(dev_id),
532*d30ea906Sjfb8856606 				"Failed to reset stats of bbdev %u", dev_id);
533*d30ea906Sjfb8856606 		/* start the device */
534*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(rte_bbdev_start(dev_id),
535*d30ea906Sjfb8856606 				"Failed to start bbdev %u", dev_id);
536*d30ea906Sjfb8856606 	}
537*d30ea906Sjfb8856606 
538*d30ea906Sjfb8856606 	return TEST_SUCCESS;
539*d30ea906Sjfb8856606 }
540*d30ea906Sjfb8856606 
541*d30ea906Sjfb8856606 static void
542*d30ea906Sjfb8856606 ut_teardown(void)
543*d30ea906Sjfb8856606 {
544*d30ea906Sjfb8856606 	uint8_t i, dev_id;
545*d30ea906Sjfb8856606 	struct rte_bbdev_stats stats;
546*d30ea906Sjfb8856606 
547*d30ea906Sjfb8856606 	for (i = 0; i < nb_active_devs; i++) {
548*d30ea906Sjfb8856606 		dev_id = active_devs[i].dev_id;
549*d30ea906Sjfb8856606 		/* read stats and print */
550*d30ea906Sjfb8856606 		rte_bbdev_stats_get(dev_id, &stats);
551*d30ea906Sjfb8856606 		/* Stop the device */
552*d30ea906Sjfb8856606 		rte_bbdev_stop(dev_id);
553*d30ea906Sjfb8856606 	}
554*d30ea906Sjfb8856606 }
555*d30ea906Sjfb8856606 
556*d30ea906Sjfb8856606 static int
557*d30ea906Sjfb8856606 init_op_data_objs(struct rte_bbdev_op_data *bufs,
558*d30ea906Sjfb8856606 		struct op_data_entries *ref_entries,
559*d30ea906Sjfb8856606 		struct rte_mempool *mbuf_pool, const uint16_t n,
560*d30ea906Sjfb8856606 		enum op_data_type op_type, uint16_t min_alignment)
561*d30ea906Sjfb8856606 {
562*d30ea906Sjfb8856606 	int ret;
563*d30ea906Sjfb8856606 	unsigned int i, j;
564*d30ea906Sjfb8856606 
565*d30ea906Sjfb8856606 	for (i = 0; i < n; ++i) {
566*d30ea906Sjfb8856606 		char *data;
567*d30ea906Sjfb8856606 		struct op_data_buf *seg = &ref_entries->segments[0];
568*d30ea906Sjfb8856606 		struct rte_mbuf *m_head = rte_pktmbuf_alloc(mbuf_pool);
569*d30ea906Sjfb8856606 		TEST_ASSERT_NOT_NULL(m_head,
570*d30ea906Sjfb8856606 				"Not enough mbufs in %d data type mbuf pool (needed %u, available %u)",
571*d30ea906Sjfb8856606 				op_type, n * ref_entries->nb_segments,
572*d30ea906Sjfb8856606 				mbuf_pool->size);
573*d30ea906Sjfb8856606 
574*d30ea906Sjfb8856606 		bufs[i].data = m_head;
575*d30ea906Sjfb8856606 		bufs[i].offset = 0;
576*d30ea906Sjfb8856606 		bufs[i].length = 0;
577*d30ea906Sjfb8856606 
578*d30ea906Sjfb8856606 		if (op_type == DATA_INPUT) {
579*d30ea906Sjfb8856606 			data = rte_pktmbuf_append(m_head, seg->length);
580*d30ea906Sjfb8856606 			TEST_ASSERT_NOT_NULL(data,
581*d30ea906Sjfb8856606 					"Couldn't append %u bytes to mbuf from %d data type mbuf pool",
582*d30ea906Sjfb8856606 					seg->length, op_type);
583*d30ea906Sjfb8856606 
584*d30ea906Sjfb8856606 			TEST_ASSERT(data == RTE_PTR_ALIGN(data, min_alignment),
585*d30ea906Sjfb8856606 					"Data addr in mbuf (%p) is not aligned to device min alignment (%u)",
586*d30ea906Sjfb8856606 					data, min_alignment);
587*d30ea906Sjfb8856606 			rte_memcpy(data, seg->addr, seg->length);
588*d30ea906Sjfb8856606 			bufs[i].length += seg->length;
589*d30ea906Sjfb8856606 
590*d30ea906Sjfb8856606 
591*d30ea906Sjfb8856606 			for (j = 1; j < ref_entries->nb_segments; ++j) {
592*d30ea906Sjfb8856606 				struct rte_mbuf *m_tail =
593*d30ea906Sjfb8856606 						rte_pktmbuf_alloc(mbuf_pool);
594*d30ea906Sjfb8856606 				TEST_ASSERT_NOT_NULL(m_tail,
595*d30ea906Sjfb8856606 						"Not enough mbufs in %d data type mbuf pool (needed %u, available %u)",
596*d30ea906Sjfb8856606 						op_type,
597*d30ea906Sjfb8856606 						n * ref_entries->nb_segments,
598*d30ea906Sjfb8856606 						mbuf_pool->size);
599*d30ea906Sjfb8856606 				seg += 1;
600*d30ea906Sjfb8856606 
601*d30ea906Sjfb8856606 				data = rte_pktmbuf_append(m_tail, seg->length);
602*d30ea906Sjfb8856606 				TEST_ASSERT_NOT_NULL(data,
603*d30ea906Sjfb8856606 						"Couldn't append %u bytes to mbuf from %d data type mbuf pool",
604*d30ea906Sjfb8856606 						seg->length, op_type);
605*d30ea906Sjfb8856606 
606*d30ea906Sjfb8856606 				TEST_ASSERT(data == RTE_PTR_ALIGN(data,
607*d30ea906Sjfb8856606 						min_alignment),
608*d30ea906Sjfb8856606 						"Data addr in mbuf (%p) is not aligned to device min alignment (%u)",
609*d30ea906Sjfb8856606 						data, min_alignment);
610*d30ea906Sjfb8856606 				rte_memcpy(data, seg->addr, seg->length);
611*d30ea906Sjfb8856606 				bufs[i].length += seg->length;
612*d30ea906Sjfb8856606 
613*d30ea906Sjfb8856606 				ret = rte_pktmbuf_chain(m_head, m_tail);
614*d30ea906Sjfb8856606 				TEST_ASSERT_SUCCESS(ret,
615*d30ea906Sjfb8856606 						"Couldn't chain mbufs from %d data type mbuf pool",
616*d30ea906Sjfb8856606 						op_type);
617*d30ea906Sjfb8856606 			}
618*d30ea906Sjfb8856606 		}
619*d30ea906Sjfb8856606 	}
620*d30ea906Sjfb8856606 
621*d30ea906Sjfb8856606 	return 0;
622*d30ea906Sjfb8856606 }
623*d30ea906Sjfb8856606 
624*d30ea906Sjfb8856606 static int
625*d30ea906Sjfb8856606 allocate_buffers_on_socket(struct rte_bbdev_op_data **buffers, const int len,
626*d30ea906Sjfb8856606 		const int socket)
627*d30ea906Sjfb8856606 {
628*d30ea906Sjfb8856606 	int i;
629*d30ea906Sjfb8856606 
630*d30ea906Sjfb8856606 	*buffers = rte_zmalloc_socket(NULL, len, 0, socket);
631*d30ea906Sjfb8856606 	if (*buffers == NULL) {
632*d30ea906Sjfb8856606 		printf("WARNING: Failed to allocate op_data on socket %d\n",
633*d30ea906Sjfb8856606 				socket);
634*d30ea906Sjfb8856606 		/* try to allocate memory on other detected sockets */
635*d30ea906Sjfb8856606 		for (i = 0; i < socket; i++) {
636*d30ea906Sjfb8856606 			*buffers = rte_zmalloc_socket(NULL, len, 0, i);
637*d30ea906Sjfb8856606 			if (*buffers != NULL)
638*d30ea906Sjfb8856606 				break;
639*d30ea906Sjfb8856606 		}
640*d30ea906Sjfb8856606 	}
641*d30ea906Sjfb8856606 
642*d30ea906Sjfb8856606 	return (*buffers == NULL) ? TEST_FAILED : TEST_SUCCESS;
643*d30ea906Sjfb8856606 }
644*d30ea906Sjfb8856606 
645*d30ea906Sjfb8856606 static void
646*d30ea906Sjfb8856606 limit_input_llr_val_range(struct rte_bbdev_op_data *input_ops,
647*d30ea906Sjfb8856606 		uint16_t n, int8_t max_llr_modulus)
648*d30ea906Sjfb8856606 {
649*d30ea906Sjfb8856606 	uint16_t i, byte_idx;
650*d30ea906Sjfb8856606 
651*d30ea906Sjfb8856606 	for (i = 0; i < n; ++i) {
652*d30ea906Sjfb8856606 		struct rte_mbuf *m = input_ops[i].data;
653*d30ea906Sjfb8856606 		while (m != NULL) {
654*d30ea906Sjfb8856606 			int8_t *llr = rte_pktmbuf_mtod_offset(m, int8_t *,
655*d30ea906Sjfb8856606 					input_ops[i].offset);
656*d30ea906Sjfb8856606 			for (byte_idx = 0; byte_idx < input_ops[i].length;
657*d30ea906Sjfb8856606 					++byte_idx)
658*d30ea906Sjfb8856606 				llr[byte_idx] = round((double)max_llr_modulus *
659*d30ea906Sjfb8856606 						llr[byte_idx] / INT8_MAX);
660*d30ea906Sjfb8856606 
661*d30ea906Sjfb8856606 			m = m->next;
662*d30ea906Sjfb8856606 		}
663*d30ea906Sjfb8856606 	}
664*d30ea906Sjfb8856606 }
665*d30ea906Sjfb8856606 
666*d30ea906Sjfb8856606 static int
667*d30ea906Sjfb8856606 fill_queue_buffers(struct test_op_params *op_params,
668*d30ea906Sjfb8856606 		struct rte_mempool *in_mp, struct rte_mempool *hard_out_mp,
669*d30ea906Sjfb8856606 		struct rte_mempool *soft_out_mp, uint16_t queue_id,
670*d30ea906Sjfb8856606 		const struct rte_bbdev_op_cap *capabilities,
671*d30ea906Sjfb8856606 		uint16_t min_alignment, const int socket_id)
672*d30ea906Sjfb8856606 {
673*d30ea906Sjfb8856606 	int ret;
674*d30ea906Sjfb8856606 	enum op_data_type type;
675*d30ea906Sjfb8856606 	const uint16_t n = op_params->num_to_process;
676*d30ea906Sjfb8856606 
677*d30ea906Sjfb8856606 	struct rte_mempool *mbuf_pools[DATA_NUM_TYPES] = {
678*d30ea906Sjfb8856606 		in_mp,
679*d30ea906Sjfb8856606 		soft_out_mp,
680*d30ea906Sjfb8856606 		hard_out_mp,
681*d30ea906Sjfb8856606 	};
682*d30ea906Sjfb8856606 
683*d30ea906Sjfb8856606 	struct rte_bbdev_op_data **queue_ops[DATA_NUM_TYPES] = {
684*d30ea906Sjfb8856606 		&op_params->q_bufs[socket_id][queue_id].inputs,
685*d30ea906Sjfb8856606 		&op_params->q_bufs[socket_id][queue_id].soft_outputs,
686*d30ea906Sjfb8856606 		&op_params->q_bufs[socket_id][queue_id].hard_outputs,
687*d30ea906Sjfb8856606 	};
688*d30ea906Sjfb8856606 
689*d30ea906Sjfb8856606 	for (type = DATA_INPUT; type < DATA_NUM_TYPES; ++type) {
690*d30ea906Sjfb8856606 		struct op_data_entries *ref_entries =
691*d30ea906Sjfb8856606 				&test_vector.entries[type];
692*d30ea906Sjfb8856606 		if (ref_entries->nb_segments == 0)
693*d30ea906Sjfb8856606 			continue;
694*d30ea906Sjfb8856606 
695*d30ea906Sjfb8856606 		ret = allocate_buffers_on_socket(queue_ops[type],
696*d30ea906Sjfb8856606 				n * sizeof(struct rte_bbdev_op_data),
697*d30ea906Sjfb8856606 				socket_id);
698*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(ret,
699*d30ea906Sjfb8856606 				"Couldn't allocate memory for rte_bbdev_op_data structs");
700*d30ea906Sjfb8856606 
701*d30ea906Sjfb8856606 		ret = init_op_data_objs(*queue_ops[type], ref_entries,
702*d30ea906Sjfb8856606 				mbuf_pools[type], n, type, min_alignment);
703*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(ret,
704*d30ea906Sjfb8856606 				"Couldn't init rte_bbdev_op_data structs");
705*d30ea906Sjfb8856606 	}
706*d30ea906Sjfb8856606 
707*d30ea906Sjfb8856606 	if (test_vector.op_type == RTE_BBDEV_OP_TURBO_DEC)
708*d30ea906Sjfb8856606 		limit_input_llr_val_range(*queue_ops[DATA_INPUT], n,
709*d30ea906Sjfb8856606 			capabilities->cap.turbo_dec.max_llr_modulus);
710*d30ea906Sjfb8856606 
711*d30ea906Sjfb8856606 	return 0;
712*d30ea906Sjfb8856606 }
713*d30ea906Sjfb8856606 
714*d30ea906Sjfb8856606 static void
715*d30ea906Sjfb8856606 free_buffers(struct active_device *ad, struct test_op_params *op_params)
716*d30ea906Sjfb8856606 {
717*d30ea906Sjfb8856606 	unsigned int i, j;
718*d30ea906Sjfb8856606 
719*d30ea906Sjfb8856606 	rte_mempool_free(ad->ops_mempool);
720*d30ea906Sjfb8856606 	rte_mempool_free(ad->in_mbuf_pool);
721*d30ea906Sjfb8856606 	rte_mempool_free(ad->hard_out_mbuf_pool);
722*d30ea906Sjfb8856606 	rte_mempool_free(ad->soft_out_mbuf_pool);
723*d30ea906Sjfb8856606 
724*d30ea906Sjfb8856606 	for (i = 0; i < rte_lcore_count(); ++i) {
725*d30ea906Sjfb8856606 		for (j = 0; j < RTE_MAX_NUMA_NODES; ++j) {
726*d30ea906Sjfb8856606 			rte_free(op_params->q_bufs[j][i].inputs);
727*d30ea906Sjfb8856606 			rte_free(op_params->q_bufs[j][i].hard_outputs);
728*d30ea906Sjfb8856606 			rte_free(op_params->q_bufs[j][i].soft_outputs);
729*d30ea906Sjfb8856606 		}
730*d30ea906Sjfb8856606 	}
731*d30ea906Sjfb8856606 }
732*d30ea906Sjfb8856606 
733*d30ea906Sjfb8856606 static void
734*d30ea906Sjfb8856606 copy_reference_dec_op(struct rte_bbdev_dec_op **ops, unsigned int n,
735*d30ea906Sjfb8856606 		unsigned int start_idx,
736*d30ea906Sjfb8856606 		struct rte_bbdev_op_data *inputs,
737*d30ea906Sjfb8856606 		struct rte_bbdev_op_data *hard_outputs,
738*d30ea906Sjfb8856606 		struct rte_bbdev_op_data *soft_outputs,
739*d30ea906Sjfb8856606 		struct rte_bbdev_dec_op *ref_op)
740*d30ea906Sjfb8856606 {
741*d30ea906Sjfb8856606 	unsigned int i;
742*d30ea906Sjfb8856606 	struct rte_bbdev_op_turbo_dec *turbo_dec = &ref_op->turbo_dec;
743*d30ea906Sjfb8856606 
744*d30ea906Sjfb8856606 	for (i = 0; i < n; ++i) {
745*d30ea906Sjfb8856606 		if (turbo_dec->code_block_mode == 0) {
746*d30ea906Sjfb8856606 			ops[i]->turbo_dec.tb_params.ea =
747*d30ea906Sjfb8856606 					turbo_dec->tb_params.ea;
748*d30ea906Sjfb8856606 			ops[i]->turbo_dec.tb_params.eb =
749*d30ea906Sjfb8856606 					turbo_dec->tb_params.eb;
750*d30ea906Sjfb8856606 			ops[i]->turbo_dec.tb_params.k_pos =
751*d30ea906Sjfb8856606 					turbo_dec->tb_params.k_pos;
752*d30ea906Sjfb8856606 			ops[i]->turbo_dec.tb_params.k_neg =
753*d30ea906Sjfb8856606 					turbo_dec->tb_params.k_neg;
754*d30ea906Sjfb8856606 			ops[i]->turbo_dec.tb_params.c =
755*d30ea906Sjfb8856606 					turbo_dec->tb_params.c;
756*d30ea906Sjfb8856606 			ops[i]->turbo_dec.tb_params.c_neg =
757*d30ea906Sjfb8856606 					turbo_dec->tb_params.c_neg;
758*d30ea906Sjfb8856606 			ops[i]->turbo_dec.tb_params.cab =
759*d30ea906Sjfb8856606 					turbo_dec->tb_params.cab;
760*d30ea906Sjfb8856606 		} else {
761*d30ea906Sjfb8856606 			ops[i]->turbo_dec.cb_params.e = turbo_dec->cb_params.e;
762*d30ea906Sjfb8856606 			ops[i]->turbo_dec.cb_params.k = turbo_dec->cb_params.k;
763*d30ea906Sjfb8856606 		}
764*d30ea906Sjfb8856606 
765*d30ea906Sjfb8856606 		ops[i]->turbo_dec.ext_scale = turbo_dec->ext_scale;
766*d30ea906Sjfb8856606 		ops[i]->turbo_dec.iter_max = turbo_dec->iter_max;
767*d30ea906Sjfb8856606 		ops[i]->turbo_dec.iter_min = turbo_dec->iter_min;
768*d30ea906Sjfb8856606 		ops[i]->turbo_dec.op_flags = turbo_dec->op_flags;
769*d30ea906Sjfb8856606 		ops[i]->turbo_dec.rv_index = turbo_dec->rv_index;
770*d30ea906Sjfb8856606 		ops[i]->turbo_dec.num_maps = turbo_dec->num_maps;
771*d30ea906Sjfb8856606 		ops[i]->turbo_dec.code_block_mode = turbo_dec->code_block_mode;
772*d30ea906Sjfb8856606 
773*d30ea906Sjfb8856606 		ops[i]->turbo_dec.hard_output = hard_outputs[start_idx + i];
774*d30ea906Sjfb8856606 		ops[i]->turbo_dec.input = inputs[start_idx + i];
775*d30ea906Sjfb8856606 		if (soft_outputs != NULL)
776*d30ea906Sjfb8856606 			ops[i]->turbo_dec.soft_output =
777*d30ea906Sjfb8856606 				soft_outputs[start_idx + i];
778*d30ea906Sjfb8856606 	}
779*d30ea906Sjfb8856606 }
780*d30ea906Sjfb8856606 
781*d30ea906Sjfb8856606 static void
782*d30ea906Sjfb8856606 copy_reference_enc_op(struct rte_bbdev_enc_op **ops, unsigned int n,
783*d30ea906Sjfb8856606 		unsigned int start_idx,
784*d30ea906Sjfb8856606 		struct rte_bbdev_op_data *inputs,
785*d30ea906Sjfb8856606 		struct rte_bbdev_op_data *outputs,
786*d30ea906Sjfb8856606 		struct rte_bbdev_enc_op *ref_op)
787*d30ea906Sjfb8856606 {
788*d30ea906Sjfb8856606 	unsigned int i;
789*d30ea906Sjfb8856606 	struct rte_bbdev_op_turbo_enc *turbo_enc = &ref_op->turbo_enc;
790*d30ea906Sjfb8856606 	for (i = 0; i < n; ++i) {
791*d30ea906Sjfb8856606 		if (turbo_enc->code_block_mode == 0) {
792*d30ea906Sjfb8856606 			ops[i]->turbo_enc.tb_params.ea =
793*d30ea906Sjfb8856606 					turbo_enc->tb_params.ea;
794*d30ea906Sjfb8856606 			ops[i]->turbo_enc.tb_params.eb =
795*d30ea906Sjfb8856606 					turbo_enc->tb_params.eb;
796*d30ea906Sjfb8856606 			ops[i]->turbo_enc.tb_params.k_pos =
797*d30ea906Sjfb8856606 					turbo_enc->tb_params.k_pos;
798*d30ea906Sjfb8856606 			ops[i]->turbo_enc.tb_params.k_neg =
799*d30ea906Sjfb8856606 					turbo_enc->tb_params.k_neg;
800*d30ea906Sjfb8856606 			ops[i]->turbo_enc.tb_params.c =
801*d30ea906Sjfb8856606 					turbo_enc->tb_params.c;
802*d30ea906Sjfb8856606 			ops[i]->turbo_enc.tb_params.c_neg =
803*d30ea906Sjfb8856606 					turbo_enc->tb_params.c_neg;
804*d30ea906Sjfb8856606 			ops[i]->turbo_enc.tb_params.cab =
805*d30ea906Sjfb8856606 					turbo_enc->tb_params.cab;
806*d30ea906Sjfb8856606 			ops[i]->turbo_enc.tb_params.ncb_pos =
807*d30ea906Sjfb8856606 					turbo_enc->tb_params.ncb_pos;
808*d30ea906Sjfb8856606 			ops[i]->turbo_enc.tb_params.ncb_neg =
809*d30ea906Sjfb8856606 					turbo_enc->tb_params.ncb_neg;
810*d30ea906Sjfb8856606 			ops[i]->turbo_enc.tb_params.r = turbo_enc->tb_params.r;
811*d30ea906Sjfb8856606 		} else {
812*d30ea906Sjfb8856606 			ops[i]->turbo_enc.cb_params.e = turbo_enc->cb_params.e;
813*d30ea906Sjfb8856606 			ops[i]->turbo_enc.cb_params.k = turbo_enc->cb_params.k;
814*d30ea906Sjfb8856606 			ops[i]->turbo_enc.cb_params.ncb =
815*d30ea906Sjfb8856606 					turbo_enc->cb_params.ncb;
816*d30ea906Sjfb8856606 		}
817*d30ea906Sjfb8856606 		ops[i]->turbo_enc.rv_index = turbo_enc->rv_index;
818*d30ea906Sjfb8856606 		ops[i]->turbo_enc.op_flags = turbo_enc->op_flags;
819*d30ea906Sjfb8856606 		ops[i]->turbo_enc.code_block_mode = turbo_enc->code_block_mode;
820*d30ea906Sjfb8856606 
821*d30ea906Sjfb8856606 		ops[i]->turbo_enc.output = outputs[start_idx + i];
822*d30ea906Sjfb8856606 		ops[i]->turbo_enc.input = inputs[start_idx + i];
823*d30ea906Sjfb8856606 	}
824*d30ea906Sjfb8856606 }
825*d30ea906Sjfb8856606 
826*d30ea906Sjfb8856606 static int
827*d30ea906Sjfb8856606 check_dec_status_and_ordering(struct rte_bbdev_dec_op *op,
828*d30ea906Sjfb8856606 		unsigned int order_idx, const int expected_status)
829*d30ea906Sjfb8856606 {
830*d30ea906Sjfb8856606 	TEST_ASSERT(op->status == expected_status,
831*d30ea906Sjfb8856606 			"op_status (%d) != expected_status (%d)",
832*d30ea906Sjfb8856606 			op->status, expected_status);
833*d30ea906Sjfb8856606 
834*d30ea906Sjfb8856606 	TEST_ASSERT((void *)(uintptr_t)order_idx == op->opaque_data,
835*d30ea906Sjfb8856606 			"Ordering error, expected %p, got %p",
836*d30ea906Sjfb8856606 			(void *)(uintptr_t)order_idx, op->opaque_data);
837*d30ea906Sjfb8856606 
838*d30ea906Sjfb8856606 	return TEST_SUCCESS;
839*d30ea906Sjfb8856606 }
840*d30ea906Sjfb8856606 
841*d30ea906Sjfb8856606 static int
842*d30ea906Sjfb8856606 check_enc_status_and_ordering(struct rte_bbdev_enc_op *op,
843*d30ea906Sjfb8856606 		unsigned int order_idx, const int expected_status)
844*d30ea906Sjfb8856606 {
845*d30ea906Sjfb8856606 	TEST_ASSERT(op->status == expected_status,
846*d30ea906Sjfb8856606 			"op_status (%d) != expected_status (%d)",
847*d30ea906Sjfb8856606 			op->status, expected_status);
848*d30ea906Sjfb8856606 
849*d30ea906Sjfb8856606 	TEST_ASSERT((void *)(uintptr_t)order_idx == op->opaque_data,
850*d30ea906Sjfb8856606 			"Ordering error, expected %p, got %p",
851*d30ea906Sjfb8856606 			(void *)(uintptr_t)order_idx, op->opaque_data);
852*d30ea906Sjfb8856606 
853*d30ea906Sjfb8856606 	return TEST_SUCCESS;
854*d30ea906Sjfb8856606 }
855*d30ea906Sjfb8856606 
856*d30ea906Sjfb8856606 static inline int
857*d30ea906Sjfb8856606 validate_op_chain(struct rte_bbdev_op_data *op,
858*d30ea906Sjfb8856606 		struct op_data_entries *orig_op)
859*d30ea906Sjfb8856606 {
860*d30ea906Sjfb8856606 	uint8_t i;
861*d30ea906Sjfb8856606 	struct rte_mbuf *m = op->data;
862*d30ea906Sjfb8856606 	uint8_t nb_dst_segments = orig_op->nb_segments;
863*d30ea906Sjfb8856606 
864*d30ea906Sjfb8856606 	TEST_ASSERT(nb_dst_segments == m->nb_segs,
865*d30ea906Sjfb8856606 			"Number of segments differ in original (%u) and filled (%u) op",
866*d30ea906Sjfb8856606 			nb_dst_segments, m->nb_segs);
867*d30ea906Sjfb8856606 
868*d30ea906Sjfb8856606 	for (i = 0; i < nb_dst_segments; ++i) {
869*d30ea906Sjfb8856606 		/* Apply offset to the first mbuf segment */
870*d30ea906Sjfb8856606 		uint16_t offset = (i == 0) ? op->offset : 0;
871*d30ea906Sjfb8856606 		uint16_t data_len = m->data_len - offset;
872*d30ea906Sjfb8856606 
873*d30ea906Sjfb8856606 		TEST_ASSERT(orig_op->segments[i].length == data_len,
874*d30ea906Sjfb8856606 				"Length of segment differ in original (%u) and filled (%u) op",
875*d30ea906Sjfb8856606 				orig_op->segments[i].length, data_len);
876*d30ea906Sjfb8856606 		TEST_ASSERT_BUFFERS_ARE_EQUAL(orig_op->segments[i].addr,
877*d30ea906Sjfb8856606 				rte_pktmbuf_mtod_offset(m, uint32_t *, offset),
878*d30ea906Sjfb8856606 				data_len,
879*d30ea906Sjfb8856606 				"Output buffers (CB=%u) are not equal", i);
880*d30ea906Sjfb8856606 		m = m->next;
881*d30ea906Sjfb8856606 	}
882*d30ea906Sjfb8856606 
883*d30ea906Sjfb8856606 	return TEST_SUCCESS;
884*d30ea906Sjfb8856606 }
885*d30ea906Sjfb8856606 
886*d30ea906Sjfb8856606 static int
887*d30ea906Sjfb8856606 validate_dec_buffers(struct rte_bbdev_dec_op *ref_op, struct test_buffers *bufs,
888*d30ea906Sjfb8856606 		const uint16_t num_to_process)
889*d30ea906Sjfb8856606 {
890*d30ea906Sjfb8856606 	int i;
891*d30ea906Sjfb8856606 
892*d30ea906Sjfb8856606 	struct op_data_entries *hard_data_orig =
893*d30ea906Sjfb8856606 			&test_vector.entries[DATA_HARD_OUTPUT];
894*d30ea906Sjfb8856606 	struct op_data_entries *soft_data_orig =
895*d30ea906Sjfb8856606 			&test_vector.entries[DATA_SOFT_OUTPUT];
896*d30ea906Sjfb8856606 
897*d30ea906Sjfb8856606 	for (i = 0; i < num_to_process; i++) {
898*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(validate_op_chain(&bufs->hard_outputs[i],
899*d30ea906Sjfb8856606 				hard_data_orig),
900*d30ea906Sjfb8856606 				"Hard output buffers are not equal");
901*d30ea906Sjfb8856606 		if (ref_op->turbo_dec.op_flags &
902*d30ea906Sjfb8856606 				RTE_BBDEV_TURBO_SOFT_OUTPUT)
903*d30ea906Sjfb8856606 			TEST_ASSERT_SUCCESS(validate_op_chain(
904*d30ea906Sjfb8856606 					&bufs->soft_outputs[i],
905*d30ea906Sjfb8856606 					soft_data_orig),
906*d30ea906Sjfb8856606 					"Soft output buffers are not equal");
907*d30ea906Sjfb8856606 	}
908*d30ea906Sjfb8856606 
909*d30ea906Sjfb8856606 	return TEST_SUCCESS;
910*d30ea906Sjfb8856606 }
911*d30ea906Sjfb8856606 
912*d30ea906Sjfb8856606 static int
913*d30ea906Sjfb8856606 validate_enc_buffers(struct test_buffers *bufs, const uint16_t num_to_process)
914*d30ea906Sjfb8856606 {
915*d30ea906Sjfb8856606 	int i;
916*d30ea906Sjfb8856606 
917*d30ea906Sjfb8856606 	struct op_data_entries *hard_data_orig =
918*d30ea906Sjfb8856606 			&test_vector.entries[DATA_HARD_OUTPUT];
919*d30ea906Sjfb8856606 
920*d30ea906Sjfb8856606 	for (i = 0; i < num_to_process; i++)
921*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(validate_op_chain(&bufs->hard_outputs[i],
922*d30ea906Sjfb8856606 				hard_data_orig), "");
923*d30ea906Sjfb8856606 
924*d30ea906Sjfb8856606 	return TEST_SUCCESS;
925*d30ea906Sjfb8856606 }
926*d30ea906Sjfb8856606 
927*d30ea906Sjfb8856606 static int
928*d30ea906Sjfb8856606 validate_dec_op(struct rte_bbdev_dec_op **ops, const uint16_t n,
929*d30ea906Sjfb8856606 		struct rte_bbdev_dec_op *ref_op, const int vector_mask)
930*d30ea906Sjfb8856606 {
931*d30ea906Sjfb8856606 	unsigned int i;
932*d30ea906Sjfb8856606 	int ret;
933*d30ea906Sjfb8856606 	struct op_data_entries *hard_data_orig =
934*d30ea906Sjfb8856606 			&test_vector.entries[DATA_HARD_OUTPUT];
935*d30ea906Sjfb8856606 	struct op_data_entries *soft_data_orig =
936*d30ea906Sjfb8856606 			&test_vector.entries[DATA_SOFT_OUTPUT];
937*d30ea906Sjfb8856606 	struct rte_bbdev_op_turbo_dec *ops_td;
938*d30ea906Sjfb8856606 	struct rte_bbdev_op_data *hard_output;
939*d30ea906Sjfb8856606 	struct rte_bbdev_op_data *soft_output;
940*d30ea906Sjfb8856606 	struct rte_bbdev_op_turbo_dec *ref_td = &ref_op->turbo_dec;
941*d30ea906Sjfb8856606 
942*d30ea906Sjfb8856606 	for (i = 0; i < n; ++i) {
943*d30ea906Sjfb8856606 		ops_td = &ops[i]->turbo_dec;
944*d30ea906Sjfb8856606 		hard_output = &ops_td->hard_output;
945*d30ea906Sjfb8856606 		soft_output = &ops_td->soft_output;
946*d30ea906Sjfb8856606 
947*d30ea906Sjfb8856606 		if (vector_mask & TEST_BBDEV_VF_EXPECTED_ITER_COUNT)
948*d30ea906Sjfb8856606 			TEST_ASSERT(ops_td->iter_count <= ref_td->iter_count,
949*d30ea906Sjfb8856606 					"Returned iter_count (%d) > expected iter_count (%d)",
950*d30ea906Sjfb8856606 					ops_td->iter_count, ref_td->iter_count);
951*d30ea906Sjfb8856606 		ret = check_dec_status_and_ordering(ops[i], i, ref_op->status);
952*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(ret,
953*d30ea906Sjfb8856606 				"Checking status and ordering for decoder failed");
954*d30ea906Sjfb8856606 
955*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(validate_op_chain(hard_output,
956*d30ea906Sjfb8856606 				hard_data_orig),
957*d30ea906Sjfb8856606 				"Hard output buffers (CB=%u) are not equal",
958*d30ea906Sjfb8856606 				i);
959*d30ea906Sjfb8856606 
960*d30ea906Sjfb8856606 		if (ref_op->turbo_dec.op_flags & RTE_BBDEV_TURBO_SOFT_OUTPUT)
961*d30ea906Sjfb8856606 			TEST_ASSERT_SUCCESS(validate_op_chain(soft_output,
962*d30ea906Sjfb8856606 					soft_data_orig),
963*d30ea906Sjfb8856606 					"Soft output buffers (CB=%u) are not equal",
964*d30ea906Sjfb8856606 					i);
965*d30ea906Sjfb8856606 	}
966*d30ea906Sjfb8856606 
967*d30ea906Sjfb8856606 	return TEST_SUCCESS;
968*d30ea906Sjfb8856606 }
969*d30ea906Sjfb8856606 
970*d30ea906Sjfb8856606 static int
971*d30ea906Sjfb8856606 validate_enc_op(struct rte_bbdev_enc_op **ops, const uint16_t n,
972*d30ea906Sjfb8856606 		struct rte_bbdev_enc_op *ref_op)
973*d30ea906Sjfb8856606 {
974*d30ea906Sjfb8856606 	unsigned int i;
975*d30ea906Sjfb8856606 	int ret;
976*d30ea906Sjfb8856606 	struct op_data_entries *hard_data_orig =
977*d30ea906Sjfb8856606 			&test_vector.entries[DATA_HARD_OUTPUT];
978*d30ea906Sjfb8856606 
979*d30ea906Sjfb8856606 	for (i = 0; i < n; ++i) {
980*d30ea906Sjfb8856606 		ret = check_enc_status_and_ordering(ops[i], i, ref_op->status);
981*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(ret,
982*d30ea906Sjfb8856606 				"Checking status and ordering for encoder failed");
983*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(validate_op_chain(
984*d30ea906Sjfb8856606 				&ops[i]->turbo_enc.output,
985*d30ea906Sjfb8856606 				hard_data_orig),
986*d30ea906Sjfb8856606 				"Output buffers (CB=%u) are not equal",
987*d30ea906Sjfb8856606 				i);
988*d30ea906Sjfb8856606 	}
989*d30ea906Sjfb8856606 
990*d30ea906Sjfb8856606 	return TEST_SUCCESS;
991*d30ea906Sjfb8856606 }
992*d30ea906Sjfb8856606 
993*d30ea906Sjfb8856606 static void
994*d30ea906Sjfb8856606 create_reference_dec_op(struct rte_bbdev_dec_op *op)
995*d30ea906Sjfb8856606 {
996*d30ea906Sjfb8856606 	unsigned int i;
997*d30ea906Sjfb8856606 	struct op_data_entries *entry;
998*d30ea906Sjfb8856606 
999*d30ea906Sjfb8856606 	op->turbo_dec = test_vector.turbo_dec;
1000*d30ea906Sjfb8856606 	entry = &test_vector.entries[DATA_INPUT];
1001*d30ea906Sjfb8856606 	for (i = 0; i < entry->nb_segments; ++i)
1002*d30ea906Sjfb8856606 		op->turbo_dec.input.length +=
1003*d30ea906Sjfb8856606 				entry->segments[i].length;
1004*d30ea906Sjfb8856606 }
1005*d30ea906Sjfb8856606 
1006*d30ea906Sjfb8856606 static void
1007*d30ea906Sjfb8856606 create_reference_enc_op(struct rte_bbdev_enc_op *op)
1008*d30ea906Sjfb8856606 {
1009*d30ea906Sjfb8856606 	unsigned int i;
1010*d30ea906Sjfb8856606 	struct op_data_entries *entry;
1011*d30ea906Sjfb8856606 
1012*d30ea906Sjfb8856606 	op->turbo_enc = test_vector.turbo_enc;
1013*d30ea906Sjfb8856606 	entry = &test_vector.entries[DATA_INPUT];
1014*d30ea906Sjfb8856606 	for (i = 0; i < entry->nb_segments; ++i)
1015*d30ea906Sjfb8856606 		op->turbo_enc.input.length +=
1016*d30ea906Sjfb8856606 				entry->segments[i].length;
1017*d30ea906Sjfb8856606 }
1018*d30ea906Sjfb8856606 
1019*d30ea906Sjfb8856606 static int
1020*d30ea906Sjfb8856606 init_test_op_params(struct test_op_params *op_params,
1021*d30ea906Sjfb8856606 		enum rte_bbdev_op_type op_type, const int expected_status,
1022*d30ea906Sjfb8856606 		const int vector_mask, struct rte_mempool *ops_mp,
1023*d30ea906Sjfb8856606 		uint16_t burst_sz, uint16_t num_to_process, uint16_t num_lcores)
1024*d30ea906Sjfb8856606 {
1025*d30ea906Sjfb8856606 	int ret = 0;
1026*d30ea906Sjfb8856606 	if (op_type == RTE_BBDEV_OP_TURBO_DEC)
1027*d30ea906Sjfb8856606 		ret = rte_bbdev_dec_op_alloc_bulk(ops_mp,
1028*d30ea906Sjfb8856606 				&op_params->ref_dec_op, 1);
1029*d30ea906Sjfb8856606 	else
1030*d30ea906Sjfb8856606 		ret = rte_bbdev_enc_op_alloc_bulk(ops_mp,
1031*d30ea906Sjfb8856606 				&op_params->ref_enc_op, 1);
1032*d30ea906Sjfb8856606 
1033*d30ea906Sjfb8856606 	TEST_ASSERT_SUCCESS(ret, "rte_bbdev_op_alloc_bulk() failed");
1034*d30ea906Sjfb8856606 
1035*d30ea906Sjfb8856606 	op_params->mp = ops_mp;
1036*d30ea906Sjfb8856606 	op_params->burst_sz = burst_sz;
1037*d30ea906Sjfb8856606 	op_params->num_to_process = num_to_process;
1038*d30ea906Sjfb8856606 	op_params->num_lcores = num_lcores;
1039*d30ea906Sjfb8856606 	op_params->vector_mask = vector_mask;
1040*d30ea906Sjfb8856606 	if (op_type == RTE_BBDEV_OP_TURBO_DEC)
1041*d30ea906Sjfb8856606 		op_params->ref_dec_op->status = expected_status;
1042*d30ea906Sjfb8856606 	else if (op_type == RTE_BBDEV_OP_TURBO_ENC)
1043*d30ea906Sjfb8856606 		op_params->ref_enc_op->status = expected_status;
1044*d30ea906Sjfb8856606 
1045*d30ea906Sjfb8856606 	return 0;
1046*d30ea906Sjfb8856606 }
1047*d30ea906Sjfb8856606 
1048*d30ea906Sjfb8856606 static int
1049*d30ea906Sjfb8856606 run_test_case_on_device(test_case_function *test_case_func, uint8_t dev_id,
1050*d30ea906Sjfb8856606 		struct test_op_params *op_params)
1051*d30ea906Sjfb8856606 {
1052*d30ea906Sjfb8856606 	int t_ret, f_ret, socket_id = SOCKET_ID_ANY;
1053*d30ea906Sjfb8856606 	unsigned int i;
1054*d30ea906Sjfb8856606 	struct active_device *ad;
1055*d30ea906Sjfb8856606 	unsigned int burst_sz = get_burst_sz();
1056*d30ea906Sjfb8856606 	enum rte_bbdev_op_type op_type = test_vector.op_type;
1057*d30ea906Sjfb8856606 	const struct rte_bbdev_op_cap *capabilities = NULL;
1058*d30ea906Sjfb8856606 
1059*d30ea906Sjfb8856606 	ad = &active_devs[dev_id];
1060*d30ea906Sjfb8856606 
1061*d30ea906Sjfb8856606 	/* Check if device supports op_type */
1062*d30ea906Sjfb8856606 	if (!is_avail_op(ad, test_vector.op_type))
1063*d30ea906Sjfb8856606 		return TEST_SUCCESS;
1064*d30ea906Sjfb8856606 
1065*d30ea906Sjfb8856606 	struct rte_bbdev_info info;
1066*d30ea906Sjfb8856606 	rte_bbdev_info_get(ad->dev_id, &info);
1067*d30ea906Sjfb8856606 	socket_id = GET_SOCKET(info.socket_id);
1068*d30ea906Sjfb8856606 
1069*d30ea906Sjfb8856606 	f_ret = create_mempools(ad, socket_id, op_type,
1070*d30ea906Sjfb8856606 			get_num_ops());
1071*d30ea906Sjfb8856606 	if (f_ret != TEST_SUCCESS) {
1072*d30ea906Sjfb8856606 		printf("Couldn't create mempools");
1073*d30ea906Sjfb8856606 		goto fail;
1074*d30ea906Sjfb8856606 	}
1075*d30ea906Sjfb8856606 	if (op_type == RTE_BBDEV_OP_NONE)
1076*d30ea906Sjfb8856606 		op_type = RTE_BBDEV_OP_TURBO_ENC;
1077*d30ea906Sjfb8856606 
1078*d30ea906Sjfb8856606 	f_ret = init_test_op_params(op_params, test_vector.op_type,
1079*d30ea906Sjfb8856606 			test_vector.expected_status,
1080*d30ea906Sjfb8856606 			test_vector.mask,
1081*d30ea906Sjfb8856606 			ad->ops_mempool,
1082*d30ea906Sjfb8856606 			burst_sz,
1083*d30ea906Sjfb8856606 			get_num_ops(),
1084*d30ea906Sjfb8856606 			get_num_lcores());
1085*d30ea906Sjfb8856606 	if (f_ret != TEST_SUCCESS) {
1086*d30ea906Sjfb8856606 		printf("Couldn't init test op params");
1087*d30ea906Sjfb8856606 		goto fail;
1088*d30ea906Sjfb8856606 	}
1089*d30ea906Sjfb8856606 
1090*d30ea906Sjfb8856606 	if (test_vector.op_type == RTE_BBDEV_OP_TURBO_DEC) {
1091*d30ea906Sjfb8856606 		/* Find Decoder capabilities */
1092*d30ea906Sjfb8856606 		const struct rte_bbdev_op_cap *cap = info.drv.capabilities;
1093*d30ea906Sjfb8856606 		while (cap->type != RTE_BBDEV_OP_NONE) {
1094*d30ea906Sjfb8856606 			if (cap->type == RTE_BBDEV_OP_TURBO_DEC) {
1095*d30ea906Sjfb8856606 				capabilities = cap;
1096*d30ea906Sjfb8856606 				break;
1097*d30ea906Sjfb8856606 			}
1098*d30ea906Sjfb8856606 		}
1099*d30ea906Sjfb8856606 		TEST_ASSERT_NOT_NULL(capabilities,
1100*d30ea906Sjfb8856606 				"Couldn't find Decoder capabilities");
1101*d30ea906Sjfb8856606 
1102*d30ea906Sjfb8856606 		create_reference_dec_op(op_params->ref_dec_op);
1103*d30ea906Sjfb8856606 	} else if (test_vector.op_type == RTE_BBDEV_OP_TURBO_ENC)
1104*d30ea906Sjfb8856606 		create_reference_enc_op(op_params->ref_enc_op);
1105*d30ea906Sjfb8856606 
1106*d30ea906Sjfb8856606 	for (i = 0; i < ad->nb_queues; ++i) {
1107*d30ea906Sjfb8856606 		f_ret = fill_queue_buffers(op_params,
1108*d30ea906Sjfb8856606 				ad->in_mbuf_pool,
1109*d30ea906Sjfb8856606 				ad->hard_out_mbuf_pool,
1110*d30ea906Sjfb8856606 				ad->soft_out_mbuf_pool,
1111*d30ea906Sjfb8856606 				ad->queue_ids[i],
1112*d30ea906Sjfb8856606 				capabilities,
1113*d30ea906Sjfb8856606 				info.drv.min_alignment,
1114*d30ea906Sjfb8856606 				socket_id);
1115*d30ea906Sjfb8856606 		if (f_ret != TEST_SUCCESS) {
1116*d30ea906Sjfb8856606 			printf("Couldn't init queue buffers");
1117*d30ea906Sjfb8856606 			goto fail;
1118*d30ea906Sjfb8856606 		}
1119*d30ea906Sjfb8856606 	}
1120*d30ea906Sjfb8856606 
1121*d30ea906Sjfb8856606 	/* Run test case function */
1122*d30ea906Sjfb8856606 	t_ret = test_case_func(ad, op_params);
1123*d30ea906Sjfb8856606 
1124*d30ea906Sjfb8856606 	/* Free active device resources and return */
1125*d30ea906Sjfb8856606 	free_buffers(ad, op_params);
1126*d30ea906Sjfb8856606 	return t_ret;
1127*d30ea906Sjfb8856606 
1128*d30ea906Sjfb8856606 fail:
1129*d30ea906Sjfb8856606 	free_buffers(ad, op_params);
1130*d30ea906Sjfb8856606 	return TEST_FAILED;
1131*d30ea906Sjfb8856606 }
1132*d30ea906Sjfb8856606 
1133*d30ea906Sjfb8856606 /* Run given test function per active device per supported op type
1134*d30ea906Sjfb8856606  * per burst size.
1135*d30ea906Sjfb8856606  */
1136*d30ea906Sjfb8856606 static int
1137*d30ea906Sjfb8856606 run_test_case(test_case_function *test_case_func)
1138*d30ea906Sjfb8856606 {
1139*d30ea906Sjfb8856606 	int ret = 0;
1140*d30ea906Sjfb8856606 	uint8_t dev;
1141*d30ea906Sjfb8856606 
1142*d30ea906Sjfb8856606 	/* Alloc op_params */
1143*d30ea906Sjfb8856606 	struct test_op_params *op_params = rte_zmalloc(NULL,
1144*d30ea906Sjfb8856606 			sizeof(struct test_op_params), RTE_CACHE_LINE_SIZE);
1145*d30ea906Sjfb8856606 	TEST_ASSERT_NOT_NULL(op_params, "Failed to alloc %zuB for op_params",
1146*d30ea906Sjfb8856606 			RTE_ALIGN(sizeof(struct test_op_params),
1147*d30ea906Sjfb8856606 				RTE_CACHE_LINE_SIZE));
1148*d30ea906Sjfb8856606 
1149*d30ea906Sjfb8856606 	/* For each device run test case function */
1150*d30ea906Sjfb8856606 	for (dev = 0; dev < nb_active_devs; ++dev)
1151*d30ea906Sjfb8856606 		ret |= run_test_case_on_device(test_case_func, dev, op_params);
1152*d30ea906Sjfb8856606 
1153*d30ea906Sjfb8856606 	rte_free(op_params);
1154*d30ea906Sjfb8856606 
1155*d30ea906Sjfb8856606 	return ret;
1156*d30ea906Sjfb8856606 }
1157*d30ea906Sjfb8856606 
1158*d30ea906Sjfb8856606 static void
1159*d30ea906Sjfb8856606 dequeue_event_callback(uint16_t dev_id,
1160*d30ea906Sjfb8856606 		enum rte_bbdev_event_type event, void *cb_arg,
1161*d30ea906Sjfb8856606 		void *ret_param)
1162*d30ea906Sjfb8856606 {
1163*d30ea906Sjfb8856606 	int ret;
1164*d30ea906Sjfb8856606 	uint16_t i;
1165*d30ea906Sjfb8856606 	uint64_t total_time;
1166*d30ea906Sjfb8856606 	uint16_t deq, burst_sz, num_to_process;
1167*d30ea906Sjfb8856606 	uint16_t queue_id = INVALID_QUEUE_ID;
1168*d30ea906Sjfb8856606 	struct rte_bbdev_dec_op *dec_ops[MAX_BURST];
1169*d30ea906Sjfb8856606 	struct rte_bbdev_enc_op *enc_ops[MAX_BURST];
1170*d30ea906Sjfb8856606 	struct test_buffers *bufs;
1171*d30ea906Sjfb8856606 	struct rte_bbdev_info info;
1172*d30ea906Sjfb8856606 
1173*d30ea906Sjfb8856606 	/* Input length in bytes, million operations per second,
1174*d30ea906Sjfb8856606 	 * million bits per second.
1175*d30ea906Sjfb8856606 	 */
1176*d30ea906Sjfb8856606 	double in_len;
1177*d30ea906Sjfb8856606 
1178*d30ea906Sjfb8856606 	struct thread_params *tp = cb_arg;
1179*d30ea906Sjfb8856606 	RTE_SET_USED(ret_param);
1180*d30ea906Sjfb8856606 	queue_id = tp->queue_id;
1181*d30ea906Sjfb8856606 
1182*d30ea906Sjfb8856606 	/* Find matching thread params using queue_id */
1183*d30ea906Sjfb8856606 	for (i = 0; i < MAX_QUEUES; ++i, ++tp)
1184*d30ea906Sjfb8856606 		if (tp->queue_id == queue_id)
1185*d30ea906Sjfb8856606 			break;
1186*d30ea906Sjfb8856606 
1187*d30ea906Sjfb8856606 	if (i == MAX_QUEUES) {
1188*d30ea906Sjfb8856606 		printf("%s: Queue_id from interrupt details was not found!\n",
1189*d30ea906Sjfb8856606 				__func__);
1190*d30ea906Sjfb8856606 		return;
1191*d30ea906Sjfb8856606 	}
1192*d30ea906Sjfb8856606 
1193*d30ea906Sjfb8856606 	if (unlikely(event != RTE_BBDEV_EVENT_DEQUEUE)) {
1194*d30ea906Sjfb8856606 		rte_atomic16_set(&tp->processing_status, TEST_FAILED);
1195*d30ea906Sjfb8856606 		printf(
1196*d30ea906Sjfb8856606 			"Dequeue interrupt handler called for incorrect event!\n");
1197*d30ea906Sjfb8856606 		return;
1198*d30ea906Sjfb8856606 	}
1199*d30ea906Sjfb8856606 
1200*d30ea906Sjfb8856606 	burst_sz = tp->op_params->burst_sz;
1201*d30ea906Sjfb8856606 	num_to_process = tp->op_params->num_to_process;
1202*d30ea906Sjfb8856606 
1203*d30ea906Sjfb8856606 	if (test_vector.op_type == RTE_BBDEV_OP_TURBO_DEC)
1204*d30ea906Sjfb8856606 		deq = rte_bbdev_dequeue_dec_ops(dev_id, queue_id, dec_ops,
1205*d30ea906Sjfb8856606 				burst_sz);
1206*d30ea906Sjfb8856606 	else
1207*d30ea906Sjfb8856606 		deq = rte_bbdev_dequeue_enc_ops(dev_id, queue_id, enc_ops,
1208*d30ea906Sjfb8856606 				burst_sz);
1209*d30ea906Sjfb8856606 
1210*d30ea906Sjfb8856606 	if (deq < burst_sz) {
1211*d30ea906Sjfb8856606 		printf(
1212*d30ea906Sjfb8856606 			"After receiving the interrupt all operations should be dequeued. Expected: %u, got: %u\n",
1213*d30ea906Sjfb8856606 			burst_sz, deq);
1214*d30ea906Sjfb8856606 		rte_atomic16_set(&tp->processing_status, TEST_FAILED);
1215*d30ea906Sjfb8856606 		return;
1216*d30ea906Sjfb8856606 	}
1217*d30ea906Sjfb8856606 
1218*d30ea906Sjfb8856606 	if (rte_atomic16_read(&tp->nb_dequeued) + deq < num_to_process) {
1219*d30ea906Sjfb8856606 		rte_atomic16_add(&tp->nb_dequeued, deq);
1220*d30ea906Sjfb8856606 		return;
1221*d30ea906Sjfb8856606 	}
1222*d30ea906Sjfb8856606 
1223*d30ea906Sjfb8856606 	total_time = rte_rdtsc_precise() - tp->start_time;
1224*d30ea906Sjfb8856606 
1225*d30ea906Sjfb8856606 	rte_bbdev_info_get(dev_id, &info);
1226*d30ea906Sjfb8856606 
1227*d30ea906Sjfb8856606 	bufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];
1228*d30ea906Sjfb8856606 
1229*d30ea906Sjfb8856606 	ret = TEST_SUCCESS;
1230*d30ea906Sjfb8856606 	if (test_vector.op_type == RTE_BBDEV_OP_TURBO_DEC)
1231*d30ea906Sjfb8856606 		ret = validate_dec_buffers(tp->op_params->ref_dec_op, bufs,
1232*d30ea906Sjfb8856606 				num_to_process);
1233*d30ea906Sjfb8856606 	else if (test_vector.op_type == RTE_BBDEV_OP_TURBO_ENC)
1234*d30ea906Sjfb8856606 		ret = validate_enc_buffers(bufs, num_to_process);
1235*d30ea906Sjfb8856606 
1236*d30ea906Sjfb8856606 	if (ret) {
1237*d30ea906Sjfb8856606 		printf("Buffers validation failed\n");
1238*d30ea906Sjfb8856606 		rte_atomic16_set(&tp->processing_status, TEST_FAILED);
1239*d30ea906Sjfb8856606 	}
1240*d30ea906Sjfb8856606 
1241*d30ea906Sjfb8856606 	switch (test_vector.op_type) {
1242*d30ea906Sjfb8856606 	case RTE_BBDEV_OP_TURBO_DEC:
1243*d30ea906Sjfb8856606 		in_len = tp->op_params->ref_dec_op->turbo_dec.input.length;
1244*d30ea906Sjfb8856606 		break;
1245*d30ea906Sjfb8856606 	case RTE_BBDEV_OP_TURBO_ENC:
1246*d30ea906Sjfb8856606 		in_len = tp->op_params->ref_enc_op->turbo_enc.input.length;
1247*d30ea906Sjfb8856606 		break;
1248*d30ea906Sjfb8856606 	case RTE_BBDEV_OP_NONE:
1249*d30ea906Sjfb8856606 		in_len = 0.0;
1250*d30ea906Sjfb8856606 		break;
1251*d30ea906Sjfb8856606 	default:
1252*d30ea906Sjfb8856606 		printf("Unknown op type: %d\n", test_vector.op_type);
1253*d30ea906Sjfb8856606 		rte_atomic16_set(&tp->processing_status, TEST_FAILED);
1254*d30ea906Sjfb8856606 		return;
1255*d30ea906Sjfb8856606 	}
1256*d30ea906Sjfb8856606 
1257*d30ea906Sjfb8856606 	tp->mops = ((double)num_to_process / 1000000.0) /
1258*d30ea906Sjfb8856606 			((double)total_time / (double)rte_get_tsc_hz());
1259*d30ea906Sjfb8856606 	tp->mbps = ((double)num_to_process * in_len * 8 / 1000000.0) /
1260*d30ea906Sjfb8856606 			((double)total_time / (double)rte_get_tsc_hz());
1261*d30ea906Sjfb8856606 
1262*d30ea906Sjfb8856606 	rte_atomic16_add(&tp->nb_dequeued, deq);
1263*d30ea906Sjfb8856606 }
1264*d30ea906Sjfb8856606 
1265*d30ea906Sjfb8856606 static int
1266*d30ea906Sjfb8856606 throughput_intr_lcore_dec(void *arg)
1267*d30ea906Sjfb8856606 {
1268*d30ea906Sjfb8856606 	struct thread_params *tp = arg;
1269*d30ea906Sjfb8856606 	unsigned int enqueued;
1270*d30ea906Sjfb8856606 	struct rte_bbdev_dec_op *ops[MAX_BURST];
1271*d30ea906Sjfb8856606 	const uint16_t queue_id = tp->queue_id;
1272*d30ea906Sjfb8856606 	const uint16_t burst_sz = tp->op_params->burst_sz;
1273*d30ea906Sjfb8856606 	const uint16_t num_to_process = tp->op_params->num_to_process;
1274*d30ea906Sjfb8856606 	struct test_buffers *bufs = NULL;
1275*d30ea906Sjfb8856606 	unsigned int allocs_failed = 0;
1276*d30ea906Sjfb8856606 	struct rte_bbdev_info info;
1277*d30ea906Sjfb8856606 	int ret;
1278*d30ea906Sjfb8856606 
1279*d30ea906Sjfb8856606 	TEST_ASSERT_SUCCESS((burst_sz > MAX_BURST),
1280*d30ea906Sjfb8856606 			"BURST_SIZE should be <= %u", MAX_BURST);
1281*d30ea906Sjfb8856606 
1282*d30ea906Sjfb8856606 	TEST_ASSERT_SUCCESS(rte_bbdev_queue_intr_enable(tp->dev_id, queue_id),
1283*d30ea906Sjfb8856606 			"Failed to enable interrupts for dev: %u, queue_id: %u",
1284*d30ea906Sjfb8856606 			tp->dev_id, queue_id);
1285*d30ea906Sjfb8856606 
1286*d30ea906Sjfb8856606 	rte_bbdev_info_get(tp->dev_id, &info);
1287*d30ea906Sjfb8856606 	bufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];
1288*d30ea906Sjfb8856606 
1289*d30ea906Sjfb8856606 	rte_atomic16_clear(&tp->processing_status);
1290*d30ea906Sjfb8856606 	rte_atomic16_clear(&tp->nb_dequeued);
1291*d30ea906Sjfb8856606 
1292*d30ea906Sjfb8856606 	while (rte_atomic16_read(&tp->op_params->sync) == SYNC_WAIT)
1293*d30ea906Sjfb8856606 		rte_pause();
1294*d30ea906Sjfb8856606 
1295*d30ea906Sjfb8856606 	tp->start_time = rte_rdtsc_precise();
1296*d30ea906Sjfb8856606 	for (enqueued = 0; enqueued < num_to_process;) {
1297*d30ea906Sjfb8856606 
1298*d30ea906Sjfb8856606 		uint16_t num_to_enq = burst_sz;
1299*d30ea906Sjfb8856606 
1300*d30ea906Sjfb8856606 		if (unlikely(num_to_process - enqueued < num_to_enq))
1301*d30ea906Sjfb8856606 			num_to_enq = num_to_process - enqueued;
1302*d30ea906Sjfb8856606 
1303*d30ea906Sjfb8856606 		ret = rte_bbdev_dec_op_alloc_bulk(tp->op_params->mp, ops,
1304*d30ea906Sjfb8856606 				num_to_enq);
1305*d30ea906Sjfb8856606 		if (ret != 0) {
1306*d30ea906Sjfb8856606 			allocs_failed++;
1307*d30ea906Sjfb8856606 			continue;
1308*d30ea906Sjfb8856606 		}
1309*d30ea906Sjfb8856606 
1310*d30ea906Sjfb8856606 		if (test_vector.op_type != RTE_BBDEV_OP_NONE)
1311*d30ea906Sjfb8856606 			copy_reference_dec_op(ops, num_to_enq, enqueued,
1312*d30ea906Sjfb8856606 					bufs->inputs,
1313*d30ea906Sjfb8856606 					bufs->hard_outputs,
1314*d30ea906Sjfb8856606 					bufs->soft_outputs,
1315*d30ea906Sjfb8856606 					tp->op_params->ref_dec_op);
1316*d30ea906Sjfb8856606 
1317*d30ea906Sjfb8856606 		enqueued += rte_bbdev_enqueue_dec_ops(tp->dev_id, queue_id, ops,
1318*d30ea906Sjfb8856606 				num_to_enq);
1319*d30ea906Sjfb8856606 
1320*d30ea906Sjfb8856606 		rte_bbdev_dec_op_free_bulk(ops, num_to_enq);
1321*d30ea906Sjfb8856606 	}
1322*d30ea906Sjfb8856606 
1323*d30ea906Sjfb8856606 	if (allocs_failed > 0)
1324*d30ea906Sjfb8856606 		printf("WARNING: op allocations failed: %u times\n",
1325*d30ea906Sjfb8856606 				allocs_failed);
1326*d30ea906Sjfb8856606 
1327*d30ea906Sjfb8856606 	return TEST_SUCCESS;
1328*d30ea906Sjfb8856606 }
1329*d30ea906Sjfb8856606 
1330*d30ea906Sjfb8856606 static int
1331*d30ea906Sjfb8856606 throughput_intr_lcore_enc(void *arg)
1332*d30ea906Sjfb8856606 {
1333*d30ea906Sjfb8856606 	struct thread_params *tp = arg;
1334*d30ea906Sjfb8856606 	unsigned int enqueued;
1335*d30ea906Sjfb8856606 	struct rte_bbdev_enc_op *ops[MAX_BURST];
1336*d30ea906Sjfb8856606 	const uint16_t queue_id = tp->queue_id;
1337*d30ea906Sjfb8856606 	const uint16_t burst_sz = tp->op_params->burst_sz;
1338*d30ea906Sjfb8856606 	const uint16_t num_to_process = tp->op_params->num_to_process;
1339*d30ea906Sjfb8856606 	struct test_buffers *bufs = NULL;
1340*d30ea906Sjfb8856606 	unsigned int allocs_failed = 0;
1341*d30ea906Sjfb8856606 	struct rte_bbdev_info info;
1342*d30ea906Sjfb8856606 	int ret;
1343*d30ea906Sjfb8856606 
1344*d30ea906Sjfb8856606 	TEST_ASSERT_SUCCESS((burst_sz > MAX_BURST),
1345*d30ea906Sjfb8856606 			"BURST_SIZE should be <= %u", MAX_BURST);
1346*d30ea906Sjfb8856606 
1347*d30ea906Sjfb8856606 	TEST_ASSERT_SUCCESS(rte_bbdev_queue_intr_enable(tp->dev_id, queue_id),
1348*d30ea906Sjfb8856606 			"Failed to enable interrupts for dev: %u, queue_id: %u",
1349*d30ea906Sjfb8856606 			tp->dev_id, queue_id);
1350*d30ea906Sjfb8856606 
1351*d30ea906Sjfb8856606 	rte_bbdev_info_get(tp->dev_id, &info);
1352*d30ea906Sjfb8856606 	bufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];
1353*d30ea906Sjfb8856606 
1354*d30ea906Sjfb8856606 	rte_atomic16_clear(&tp->processing_status);
1355*d30ea906Sjfb8856606 	rte_atomic16_clear(&tp->nb_dequeued);
1356*d30ea906Sjfb8856606 
1357*d30ea906Sjfb8856606 	while (rte_atomic16_read(&tp->op_params->sync) == SYNC_WAIT)
1358*d30ea906Sjfb8856606 		rte_pause();
1359*d30ea906Sjfb8856606 
1360*d30ea906Sjfb8856606 	tp->start_time = rte_rdtsc_precise();
1361*d30ea906Sjfb8856606 	for (enqueued = 0; enqueued < num_to_process;) {
1362*d30ea906Sjfb8856606 
1363*d30ea906Sjfb8856606 		uint16_t num_to_enq = burst_sz;
1364*d30ea906Sjfb8856606 
1365*d30ea906Sjfb8856606 		if (unlikely(num_to_process - enqueued < num_to_enq))
1366*d30ea906Sjfb8856606 			num_to_enq = num_to_process - enqueued;
1367*d30ea906Sjfb8856606 
1368*d30ea906Sjfb8856606 		ret = rte_bbdev_enc_op_alloc_bulk(tp->op_params->mp, ops,
1369*d30ea906Sjfb8856606 				num_to_enq);
1370*d30ea906Sjfb8856606 		if (ret != 0) {
1371*d30ea906Sjfb8856606 			allocs_failed++;
1372*d30ea906Sjfb8856606 			continue;
1373*d30ea906Sjfb8856606 		}
1374*d30ea906Sjfb8856606 
1375*d30ea906Sjfb8856606 		if (test_vector.op_type != RTE_BBDEV_OP_NONE)
1376*d30ea906Sjfb8856606 			copy_reference_enc_op(ops, num_to_enq, enqueued,
1377*d30ea906Sjfb8856606 					bufs->inputs,
1378*d30ea906Sjfb8856606 					bufs->hard_outputs,
1379*d30ea906Sjfb8856606 					tp->op_params->ref_enc_op);
1380*d30ea906Sjfb8856606 
1381*d30ea906Sjfb8856606 		enqueued += rte_bbdev_enqueue_enc_ops(tp->dev_id, queue_id, ops,
1382*d30ea906Sjfb8856606 				num_to_enq);
1383*d30ea906Sjfb8856606 
1384*d30ea906Sjfb8856606 		rte_bbdev_enc_op_free_bulk(ops, num_to_enq);
1385*d30ea906Sjfb8856606 	}
1386*d30ea906Sjfb8856606 
1387*d30ea906Sjfb8856606 	if (allocs_failed > 0)
1388*d30ea906Sjfb8856606 		printf("WARNING: op allocations failed: %u times\n",
1389*d30ea906Sjfb8856606 				allocs_failed);
1390*d30ea906Sjfb8856606 
1391*d30ea906Sjfb8856606 	return TEST_SUCCESS;
1392*d30ea906Sjfb8856606 }
1393*d30ea906Sjfb8856606 
1394*d30ea906Sjfb8856606 static int
1395*d30ea906Sjfb8856606 throughput_pmd_lcore_dec(void *arg)
1396*d30ea906Sjfb8856606 {
1397*d30ea906Sjfb8856606 	struct thread_params *tp = arg;
1398*d30ea906Sjfb8856606 	unsigned int enqueued, dequeued;
1399*d30ea906Sjfb8856606 	struct rte_bbdev_dec_op *ops_enq[MAX_BURST], *ops_deq[MAX_BURST];
1400*d30ea906Sjfb8856606 	uint64_t total_time, start_time;
1401*d30ea906Sjfb8856606 	const uint16_t queue_id = tp->queue_id;
1402*d30ea906Sjfb8856606 	const uint16_t burst_sz = tp->op_params->burst_sz;
1403*d30ea906Sjfb8856606 	const uint16_t num_to_process = tp->op_params->num_to_process;
1404*d30ea906Sjfb8856606 	struct rte_bbdev_dec_op *ref_op = tp->op_params->ref_dec_op;
1405*d30ea906Sjfb8856606 	struct test_buffers *bufs = NULL;
1406*d30ea906Sjfb8856606 	unsigned int allocs_failed = 0;
1407*d30ea906Sjfb8856606 	int ret;
1408*d30ea906Sjfb8856606 	struct rte_bbdev_info info;
1409*d30ea906Sjfb8856606 
1410*d30ea906Sjfb8856606 	/* Input length in bytes, million operations per second, million bits
1411*d30ea906Sjfb8856606 	 * per second.
1412*d30ea906Sjfb8856606 	 */
1413*d30ea906Sjfb8856606 	double in_len;
1414*d30ea906Sjfb8856606 
1415*d30ea906Sjfb8856606 	TEST_ASSERT_SUCCESS((burst_sz > MAX_BURST),
1416*d30ea906Sjfb8856606 			"BURST_SIZE should be <= %u", MAX_BURST);
1417*d30ea906Sjfb8856606 
1418*d30ea906Sjfb8856606 	rte_bbdev_info_get(tp->dev_id, &info);
1419*d30ea906Sjfb8856606 	bufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];
1420*d30ea906Sjfb8856606 
1421*d30ea906Sjfb8856606 	while (rte_atomic16_read(&tp->op_params->sync) == SYNC_WAIT)
1422*d30ea906Sjfb8856606 		rte_pause();
1423*d30ea906Sjfb8856606 
1424*d30ea906Sjfb8856606 	start_time = rte_rdtsc_precise();
1425*d30ea906Sjfb8856606 	for (enqueued = 0, dequeued = 0; dequeued < num_to_process;) {
1426*d30ea906Sjfb8856606 		uint16_t deq;
1427*d30ea906Sjfb8856606 
1428*d30ea906Sjfb8856606 		if (likely(enqueued < num_to_process)) {
1429*d30ea906Sjfb8856606 
1430*d30ea906Sjfb8856606 			uint16_t num_to_enq = burst_sz;
1431*d30ea906Sjfb8856606 
1432*d30ea906Sjfb8856606 			if (unlikely(num_to_process - enqueued < num_to_enq))
1433*d30ea906Sjfb8856606 				num_to_enq = num_to_process - enqueued;
1434*d30ea906Sjfb8856606 
1435*d30ea906Sjfb8856606 			ret = rte_bbdev_dec_op_alloc_bulk(tp->op_params->mp,
1436*d30ea906Sjfb8856606 					ops_enq, num_to_enq);
1437*d30ea906Sjfb8856606 			if (ret != 0) {
1438*d30ea906Sjfb8856606 				allocs_failed++;
1439*d30ea906Sjfb8856606 				goto do_dequeue;
1440*d30ea906Sjfb8856606 			}
1441*d30ea906Sjfb8856606 
1442*d30ea906Sjfb8856606 			if (test_vector.op_type != RTE_BBDEV_OP_NONE)
1443*d30ea906Sjfb8856606 				copy_reference_dec_op(ops_enq, num_to_enq,
1444*d30ea906Sjfb8856606 						enqueued,
1445*d30ea906Sjfb8856606 						bufs->inputs,
1446*d30ea906Sjfb8856606 						bufs->hard_outputs,
1447*d30ea906Sjfb8856606 						bufs->soft_outputs,
1448*d30ea906Sjfb8856606 						ref_op);
1449*d30ea906Sjfb8856606 
1450*d30ea906Sjfb8856606 			enqueued += rte_bbdev_enqueue_dec_ops(tp->dev_id,
1451*d30ea906Sjfb8856606 					queue_id, ops_enq, num_to_enq);
1452*d30ea906Sjfb8856606 		}
1453*d30ea906Sjfb8856606 do_dequeue:
1454*d30ea906Sjfb8856606 		deq = rte_bbdev_dequeue_dec_ops(tp->dev_id, queue_id, ops_deq,
1455*d30ea906Sjfb8856606 				burst_sz);
1456*d30ea906Sjfb8856606 		dequeued += deq;
1457*d30ea906Sjfb8856606 		rte_bbdev_dec_op_free_bulk(ops_enq, deq);
1458*d30ea906Sjfb8856606 	}
1459*d30ea906Sjfb8856606 	total_time = rte_rdtsc_precise() - start_time;
1460*d30ea906Sjfb8856606 
1461*d30ea906Sjfb8856606 	if (allocs_failed > 0)
1462*d30ea906Sjfb8856606 		printf("WARNING: op allocations failed: %u times\n",
1463*d30ea906Sjfb8856606 				allocs_failed);
1464*d30ea906Sjfb8856606 
1465*d30ea906Sjfb8856606 	TEST_ASSERT(enqueued == dequeued, "enqueued (%u) != dequeued (%u)",
1466*d30ea906Sjfb8856606 			enqueued, dequeued);
1467*d30ea906Sjfb8856606 
1468*d30ea906Sjfb8856606 	if (test_vector.op_type != RTE_BBDEV_OP_NONE) {
1469*d30ea906Sjfb8856606 		ret = validate_dec_buffers(ref_op, bufs, num_to_process);
1470*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(ret, "Buffers validation failed");
1471*d30ea906Sjfb8856606 	}
1472*d30ea906Sjfb8856606 
1473*d30ea906Sjfb8856606 	in_len = ref_op->turbo_dec.input.length;
1474*d30ea906Sjfb8856606 	tp->mops = ((double)num_to_process / 1000000.0) /
1475*d30ea906Sjfb8856606 			((double)total_time / (double)rte_get_tsc_hz());
1476*d30ea906Sjfb8856606 	tp->mbps = ((double)num_to_process * in_len * 8 / 1000000.0) /
1477*d30ea906Sjfb8856606 			((double)total_time / (double)rte_get_tsc_hz());
1478*d30ea906Sjfb8856606 
1479*d30ea906Sjfb8856606 	return TEST_SUCCESS;
1480*d30ea906Sjfb8856606 }
1481*d30ea906Sjfb8856606 
1482*d30ea906Sjfb8856606 static int
1483*d30ea906Sjfb8856606 throughput_pmd_lcore_enc(void *arg)
1484*d30ea906Sjfb8856606 {
1485*d30ea906Sjfb8856606 	struct thread_params *tp = arg;
1486*d30ea906Sjfb8856606 	unsigned int enqueued, dequeued;
1487*d30ea906Sjfb8856606 	struct rte_bbdev_enc_op *ops_enq[MAX_BURST], *ops_deq[MAX_BURST];
1488*d30ea906Sjfb8856606 	uint64_t total_time, start_time;
1489*d30ea906Sjfb8856606 	const uint16_t queue_id = tp->queue_id;
1490*d30ea906Sjfb8856606 	const uint16_t burst_sz = tp->op_params->burst_sz;
1491*d30ea906Sjfb8856606 	const uint16_t num_to_process = tp->op_params->num_to_process;
1492*d30ea906Sjfb8856606 	struct rte_bbdev_enc_op *ref_op = tp->op_params->ref_enc_op;
1493*d30ea906Sjfb8856606 	struct test_buffers *bufs = NULL;
1494*d30ea906Sjfb8856606 	unsigned int allocs_failed = 0;
1495*d30ea906Sjfb8856606 	int ret;
1496*d30ea906Sjfb8856606 	struct rte_bbdev_info info;
1497*d30ea906Sjfb8856606 
1498*d30ea906Sjfb8856606 	/* Input length in bytes, million operations per second, million bits
1499*d30ea906Sjfb8856606 	 * per second.
1500*d30ea906Sjfb8856606 	 */
1501*d30ea906Sjfb8856606 	double in_len;
1502*d30ea906Sjfb8856606 
1503*d30ea906Sjfb8856606 	TEST_ASSERT_SUCCESS((burst_sz > MAX_BURST),
1504*d30ea906Sjfb8856606 			"BURST_SIZE should be <= %u", MAX_BURST);
1505*d30ea906Sjfb8856606 
1506*d30ea906Sjfb8856606 	rte_bbdev_info_get(tp->dev_id, &info);
1507*d30ea906Sjfb8856606 	bufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];
1508*d30ea906Sjfb8856606 
1509*d30ea906Sjfb8856606 	while (rte_atomic16_read(&tp->op_params->sync) == SYNC_WAIT)
1510*d30ea906Sjfb8856606 		rte_pause();
1511*d30ea906Sjfb8856606 
1512*d30ea906Sjfb8856606 	start_time = rte_rdtsc_precise();
1513*d30ea906Sjfb8856606 	for (enqueued = 0, dequeued = 0; dequeued < num_to_process;) {
1514*d30ea906Sjfb8856606 		uint16_t deq;
1515*d30ea906Sjfb8856606 
1516*d30ea906Sjfb8856606 		if (likely(enqueued < num_to_process)) {
1517*d30ea906Sjfb8856606 
1518*d30ea906Sjfb8856606 			uint16_t num_to_enq = burst_sz;
1519*d30ea906Sjfb8856606 
1520*d30ea906Sjfb8856606 			if (unlikely(num_to_process - enqueued < num_to_enq))
1521*d30ea906Sjfb8856606 				num_to_enq = num_to_process - enqueued;
1522*d30ea906Sjfb8856606 
1523*d30ea906Sjfb8856606 			ret = rte_bbdev_enc_op_alloc_bulk(tp->op_params->mp,
1524*d30ea906Sjfb8856606 					ops_enq, num_to_enq);
1525*d30ea906Sjfb8856606 			if (ret != 0) {
1526*d30ea906Sjfb8856606 				allocs_failed++;
1527*d30ea906Sjfb8856606 				goto do_dequeue;
1528*d30ea906Sjfb8856606 			}
1529*d30ea906Sjfb8856606 
1530*d30ea906Sjfb8856606 			if (test_vector.op_type != RTE_BBDEV_OP_NONE)
1531*d30ea906Sjfb8856606 				copy_reference_enc_op(ops_enq, num_to_enq,
1532*d30ea906Sjfb8856606 						enqueued,
1533*d30ea906Sjfb8856606 						bufs->inputs,
1534*d30ea906Sjfb8856606 						bufs->hard_outputs,
1535*d30ea906Sjfb8856606 						ref_op);
1536*d30ea906Sjfb8856606 
1537*d30ea906Sjfb8856606 			enqueued += rte_bbdev_enqueue_enc_ops(tp->dev_id,
1538*d30ea906Sjfb8856606 					queue_id, ops_enq, num_to_enq);
1539*d30ea906Sjfb8856606 		}
1540*d30ea906Sjfb8856606 do_dequeue:
1541*d30ea906Sjfb8856606 		deq = rte_bbdev_dequeue_enc_ops(tp->dev_id, queue_id, ops_deq,
1542*d30ea906Sjfb8856606 				burst_sz);
1543*d30ea906Sjfb8856606 		dequeued += deq;
1544*d30ea906Sjfb8856606 		rte_bbdev_enc_op_free_bulk(ops_enq, deq);
1545*d30ea906Sjfb8856606 	}
1546*d30ea906Sjfb8856606 	total_time = rte_rdtsc_precise() - start_time;
1547*d30ea906Sjfb8856606 
1548*d30ea906Sjfb8856606 	if (allocs_failed > 0)
1549*d30ea906Sjfb8856606 		printf("WARNING: op allocations failed: %u times\n",
1550*d30ea906Sjfb8856606 				allocs_failed);
1551*d30ea906Sjfb8856606 
1552*d30ea906Sjfb8856606 	TEST_ASSERT(enqueued == dequeued, "enqueued (%u) != dequeued (%u)",
1553*d30ea906Sjfb8856606 			enqueued, dequeued);
1554*d30ea906Sjfb8856606 
1555*d30ea906Sjfb8856606 	if (test_vector.op_type != RTE_BBDEV_OP_NONE) {
1556*d30ea906Sjfb8856606 		ret = validate_enc_buffers(bufs, num_to_process);
1557*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(ret, "Buffers validation failed");
1558*d30ea906Sjfb8856606 	}
1559*d30ea906Sjfb8856606 
1560*d30ea906Sjfb8856606 	in_len = ref_op->turbo_enc.input.length;
1561*d30ea906Sjfb8856606 
1562*d30ea906Sjfb8856606 	tp->mops = ((double)num_to_process / 1000000.0) /
1563*d30ea906Sjfb8856606 			((double)total_time / (double)rte_get_tsc_hz());
1564*d30ea906Sjfb8856606 	tp->mbps = ((double)num_to_process * in_len * 8 / 1000000.0) /
1565*d30ea906Sjfb8856606 			((double)total_time / (double)rte_get_tsc_hz());
1566*d30ea906Sjfb8856606 
1567*d30ea906Sjfb8856606 	return TEST_SUCCESS;
1568*d30ea906Sjfb8856606 }
1569*d30ea906Sjfb8856606 static void
1570*d30ea906Sjfb8856606 print_throughput(struct thread_params *t_params, unsigned int used_cores)
1571*d30ea906Sjfb8856606 {
1572*d30ea906Sjfb8856606 	unsigned int lcore_id, iter = 0;
1573*d30ea906Sjfb8856606 	double total_mops = 0, total_mbps = 0;
1574*d30ea906Sjfb8856606 
1575*d30ea906Sjfb8856606 	RTE_LCORE_FOREACH(lcore_id) {
1576*d30ea906Sjfb8856606 		if (iter++ >= used_cores)
1577*d30ea906Sjfb8856606 			break;
1578*d30ea906Sjfb8856606 		printf("\tlcore_id: %u, throughput: %.8lg MOPS, %.8lg Mbps\n",
1579*d30ea906Sjfb8856606 		lcore_id, t_params[lcore_id].mops, t_params[lcore_id].mbps);
1580*d30ea906Sjfb8856606 		total_mops += t_params[lcore_id].mops;
1581*d30ea906Sjfb8856606 		total_mbps += t_params[lcore_id].mbps;
1582*d30ea906Sjfb8856606 	}
1583*d30ea906Sjfb8856606 	printf(
1584*d30ea906Sjfb8856606 		"\n\tTotal stats for %u cores: throughput: %.8lg MOPS, %.8lg Mbps\n",
1585*d30ea906Sjfb8856606 		used_cores, total_mops, total_mbps);
1586*d30ea906Sjfb8856606 }
1587*d30ea906Sjfb8856606 
1588*d30ea906Sjfb8856606 /*
1589*d30ea906Sjfb8856606  * Test function that determines how long an enqueue + dequeue of a burst
1590*d30ea906Sjfb8856606  * takes on available lcores.
1591*d30ea906Sjfb8856606  */
1592*d30ea906Sjfb8856606 static int
1593*d30ea906Sjfb8856606 throughput_test(struct active_device *ad,
1594*d30ea906Sjfb8856606 		struct test_op_params *op_params)
1595*d30ea906Sjfb8856606 {
1596*d30ea906Sjfb8856606 	int ret;
1597*d30ea906Sjfb8856606 	unsigned int lcore_id, used_cores = 0;
1598*d30ea906Sjfb8856606 	struct thread_params t_params[MAX_QUEUES];
1599*d30ea906Sjfb8856606 	struct rte_bbdev_info info;
1600*d30ea906Sjfb8856606 	lcore_function_t *throughput_function;
1601*d30ea906Sjfb8856606 	struct thread_params *tp;
1602*d30ea906Sjfb8856606 	uint16_t num_lcores;
1603*d30ea906Sjfb8856606 	const char *op_type_str;
1604*d30ea906Sjfb8856606 
1605*d30ea906Sjfb8856606 	rte_bbdev_info_get(ad->dev_id, &info);
1606*d30ea906Sjfb8856606 
1607*d30ea906Sjfb8856606 	op_type_str = rte_bbdev_op_type_str(test_vector.op_type);
1608*d30ea906Sjfb8856606 	TEST_ASSERT_NOT_NULL(op_type_str, "Invalid op type: %u",
1609*d30ea906Sjfb8856606 			test_vector.op_type);
1610*d30ea906Sjfb8856606 
1611*d30ea906Sjfb8856606 	printf(
1612*d30ea906Sjfb8856606 		"Throughput test: dev: %s, nb_queues: %u, burst size: %u, num ops: %u, num_lcores: %u, op type: %s, int mode: %s, GHz: %lg\n",
1613*d30ea906Sjfb8856606 			info.dev_name, ad->nb_queues, op_params->burst_sz,
1614*d30ea906Sjfb8856606 			op_params->num_to_process, op_params->num_lcores,
1615*d30ea906Sjfb8856606 			op_type_str,
1616*d30ea906Sjfb8856606 			intr_enabled ? "Interrupt mode" : "PMD mode",
1617*d30ea906Sjfb8856606 			(double)rte_get_tsc_hz() / 1000000000.0);
1618*d30ea906Sjfb8856606 
1619*d30ea906Sjfb8856606 	/* Set number of lcores */
1620*d30ea906Sjfb8856606 	num_lcores = (ad->nb_queues < (op_params->num_lcores))
1621*d30ea906Sjfb8856606 			? ad->nb_queues
1622*d30ea906Sjfb8856606 			: op_params->num_lcores;
1623*d30ea906Sjfb8856606 
1624*d30ea906Sjfb8856606 	if (intr_enabled) {
1625*d30ea906Sjfb8856606 		if (test_vector.op_type == RTE_BBDEV_OP_TURBO_DEC)
1626*d30ea906Sjfb8856606 			throughput_function = throughput_intr_lcore_dec;
1627*d30ea906Sjfb8856606 		else
1628*d30ea906Sjfb8856606 			throughput_function = throughput_intr_lcore_enc;
1629*d30ea906Sjfb8856606 
1630*d30ea906Sjfb8856606 		/* Dequeue interrupt callback registration */
1631*d30ea906Sjfb8856606 		ret = rte_bbdev_callback_register(ad->dev_id,
1632*d30ea906Sjfb8856606 				RTE_BBDEV_EVENT_DEQUEUE, dequeue_event_callback,
1633*d30ea906Sjfb8856606 				&t_params);
1634*d30ea906Sjfb8856606 		if (ret < 0)
1635*d30ea906Sjfb8856606 			return ret;
1636*d30ea906Sjfb8856606 	} else {
1637*d30ea906Sjfb8856606 		if (test_vector.op_type == RTE_BBDEV_OP_TURBO_DEC)
1638*d30ea906Sjfb8856606 			throughput_function = throughput_pmd_lcore_dec;
1639*d30ea906Sjfb8856606 		else
1640*d30ea906Sjfb8856606 			throughput_function = throughput_pmd_lcore_enc;
1641*d30ea906Sjfb8856606 	}
1642*d30ea906Sjfb8856606 
1643*d30ea906Sjfb8856606 	rte_atomic16_set(&op_params->sync, SYNC_WAIT);
1644*d30ea906Sjfb8856606 
1645*d30ea906Sjfb8856606 	t_params[rte_lcore_id()].dev_id = ad->dev_id;
1646*d30ea906Sjfb8856606 	t_params[rte_lcore_id()].op_params = op_params;
1647*d30ea906Sjfb8856606 	t_params[rte_lcore_id()].queue_id =
1648*d30ea906Sjfb8856606 			ad->queue_ids[used_cores++];
1649*d30ea906Sjfb8856606 
1650*d30ea906Sjfb8856606 	RTE_LCORE_FOREACH_SLAVE(lcore_id) {
1651*d30ea906Sjfb8856606 		if (used_cores >= num_lcores)
1652*d30ea906Sjfb8856606 			break;
1653*d30ea906Sjfb8856606 
1654*d30ea906Sjfb8856606 		t_params[lcore_id].dev_id = ad->dev_id;
1655*d30ea906Sjfb8856606 		t_params[lcore_id].op_params = op_params;
1656*d30ea906Sjfb8856606 		t_params[lcore_id].queue_id = ad->queue_ids[used_cores++];
1657*d30ea906Sjfb8856606 
1658*d30ea906Sjfb8856606 		rte_eal_remote_launch(throughput_function, &t_params[lcore_id],
1659*d30ea906Sjfb8856606 				lcore_id);
1660*d30ea906Sjfb8856606 	}
1661*d30ea906Sjfb8856606 
1662*d30ea906Sjfb8856606 	rte_atomic16_set(&op_params->sync, SYNC_START);
1663*d30ea906Sjfb8856606 	ret = throughput_function(&t_params[rte_lcore_id()]);
1664*d30ea906Sjfb8856606 
1665*d30ea906Sjfb8856606 	/* Master core is always used */
1666*d30ea906Sjfb8856606 	used_cores = 1;
1667*d30ea906Sjfb8856606 	RTE_LCORE_FOREACH_SLAVE(lcore_id) {
1668*d30ea906Sjfb8856606 		if (used_cores++ >= num_lcores)
1669*d30ea906Sjfb8856606 			break;
1670*d30ea906Sjfb8856606 
1671*d30ea906Sjfb8856606 		ret |= rte_eal_wait_lcore(lcore_id);
1672*d30ea906Sjfb8856606 	}
1673*d30ea906Sjfb8856606 
1674*d30ea906Sjfb8856606 	/* Return if test failed */
1675*d30ea906Sjfb8856606 	if (ret)
1676*d30ea906Sjfb8856606 		return ret;
1677*d30ea906Sjfb8856606 
1678*d30ea906Sjfb8856606 	/* Print throughput if interrupts are disabled and test passed */
1679*d30ea906Sjfb8856606 	if (!intr_enabled) {
1680*d30ea906Sjfb8856606 		if (test_vector.op_type != RTE_BBDEV_OP_NONE)
1681*d30ea906Sjfb8856606 			print_throughput(t_params, num_lcores);
1682*d30ea906Sjfb8856606 		return ret;
1683*d30ea906Sjfb8856606 	}
1684*d30ea906Sjfb8856606 
1685*d30ea906Sjfb8856606 	/* In interrupt TC we need to wait for the interrupt callback to deqeue
1686*d30ea906Sjfb8856606 	 * all pending operations. Skip waiting for queues which reported an
1687*d30ea906Sjfb8856606 	 * error using processing_status variable.
1688*d30ea906Sjfb8856606 	 * Wait for master lcore operations.
1689*d30ea906Sjfb8856606 	 */
1690*d30ea906Sjfb8856606 	tp = &t_params[rte_lcore_id()];
1691*d30ea906Sjfb8856606 	while ((rte_atomic16_read(&tp->nb_dequeued) <
1692*d30ea906Sjfb8856606 			op_params->num_to_process) &&
1693*d30ea906Sjfb8856606 			(rte_atomic16_read(&tp->processing_status) !=
1694*d30ea906Sjfb8856606 			TEST_FAILED))
1695*d30ea906Sjfb8856606 		rte_pause();
1696*d30ea906Sjfb8856606 
1697*d30ea906Sjfb8856606 	ret |= rte_atomic16_read(&tp->processing_status);
1698*d30ea906Sjfb8856606 
1699*d30ea906Sjfb8856606 	/* Wait for slave lcores operations */
1700*d30ea906Sjfb8856606 	used_cores = 1;
1701*d30ea906Sjfb8856606 	RTE_LCORE_FOREACH_SLAVE(lcore_id) {
1702*d30ea906Sjfb8856606 		tp = &t_params[lcore_id];
1703*d30ea906Sjfb8856606 		if (used_cores++ >= num_lcores)
1704*d30ea906Sjfb8856606 			break;
1705*d30ea906Sjfb8856606 
1706*d30ea906Sjfb8856606 		while ((rte_atomic16_read(&tp->nb_dequeued) <
1707*d30ea906Sjfb8856606 				op_params->num_to_process) &&
1708*d30ea906Sjfb8856606 				(rte_atomic16_read(&tp->processing_status) !=
1709*d30ea906Sjfb8856606 				TEST_FAILED))
1710*d30ea906Sjfb8856606 			rte_pause();
1711*d30ea906Sjfb8856606 
1712*d30ea906Sjfb8856606 		ret |= rte_atomic16_read(&tp->processing_status);
1713*d30ea906Sjfb8856606 	}
1714*d30ea906Sjfb8856606 
1715*d30ea906Sjfb8856606 	/* Print throughput if test passed */
1716*d30ea906Sjfb8856606 	if (!ret && test_vector.op_type != RTE_BBDEV_OP_NONE)
1717*d30ea906Sjfb8856606 		print_throughput(t_params, num_lcores);
1718*d30ea906Sjfb8856606 
1719*d30ea906Sjfb8856606 	return ret;
1720*d30ea906Sjfb8856606 }
1721*d30ea906Sjfb8856606 
1722*d30ea906Sjfb8856606 static int
1723*d30ea906Sjfb8856606 latency_test_dec(struct rte_mempool *mempool,
1724*d30ea906Sjfb8856606 		struct test_buffers *bufs, struct rte_bbdev_dec_op *ref_op,
1725*d30ea906Sjfb8856606 		int vector_mask, uint16_t dev_id, uint16_t queue_id,
1726*d30ea906Sjfb8856606 		const uint16_t num_to_process, uint16_t burst_sz,
1727*d30ea906Sjfb8856606 		uint64_t *total_time, uint64_t *min_time, uint64_t *max_time)
1728*d30ea906Sjfb8856606 {
1729*d30ea906Sjfb8856606 	int ret = TEST_SUCCESS;
1730*d30ea906Sjfb8856606 	uint16_t i, j, dequeued;
1731*d30ea906Sjfb8856606 	struct rte_bbdev_dec_op *ops_enq[MAX_BURST], *ops_deq[MAX_BURST];
1732*d30ea906Sjfb8856606 	uint64_t start_time = 0, last_time = 0;
1733*d30ea906Sjfb8856606 
1734*d30ea906Sjfb8856606 	for (i = 0, dequeued = 0; dequeued < num_to_process; ++i) {
1735*d30ea906Sjfb8856606 		uint16_t enq = 0, deq = 0;
1736*d30ea906Sjfb8856606 		bool first_time = true;
1737*d30ea906Sjfb8856606 		last_time = 0;
1738*d30ea906Sjfb8856606 
1739*d30ea906Sjfb8856606 		if (unlikely(num_to_process - dequeued < burst_sz))
1740*d30ea906Sjfb8856606 			burst_sz = num_to_process - dequeued;
1741*d30ea906Sjfb8856606 
1742*d30ea906Sjfb8856606 		ret = rte_bbdev_dec_op_alloc_bulk(mempool, ops_enq, burst_sz);
1743*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(ret,
1744*d30ea906Sjfb8856606 				"rte_bbdev_dec_op_alloc_bulk() failed");
1745*d30ea906Sjfb8856606 		if (test_vector.op_type != RTE_BBDEV_OP_NONE)
1746*d30ea906Sjfb8856606 			copy_reference_dec_op(ops_enq, burst_sz, dequeued,
1747*d30ea906Sjfb8856606 					bufs->inputs,
1748*d30ea906Sjfb8856606 					bufs->hard_outputs,
1749*d30ea906Sjfb8856606 					bufs->soft_outputs,
1750*d30ea906Sjfb8856606 					ref_op);
1751*d30ea906Sjfb8856606 
1752*d30ea906Sjfb8856606 		/* Set counter to validate the ordering */
1753*d30ea906Sjfb8856606 		for (j = 0; j < burst_sz; ++j)
1754*d30ea906Sjfb8856606 			ops_enq[j]->opaque_data = (void *)(uintptr_t)j;
1755*d30ea906Sjfb8856606 
1756*d30ea906Sjfb8856606 		start_time = rte_rdtsc_precise();
1757*d30ea906Sjfb8856606 
1758*d30ea906Sjfb8856606 		enq = rte_bbdev_enqueue_dec_ops(dev_id, queue_id, &ops_enq[enq],
1759*d30ea906Sjfb8856606 				burst_sz);
1760*d30ea906Sjfb8856606 		TEST_ASSERT(enq == burst_sz,
1761*d30ea906Sjfb8856606 				"Error enqueueing burst, expected %u, got %u",
1762*d30ea906Sjfb8856606 				burst_sz, enq);
1763*d30ea906Sjfb8856606 
1764*d30ea906Sjfb8856606 		/* Dequeue */
1765*d30ea906Sjfb8856606 		do {
1766*d30ea906Sjfb8856606 			deq += rte_bbdev_dequeue_dec_ops(dev_id, queue_id,
1767*d30ea906Sjfb8856606 					&ops_deq[deq], burst_sz - deq);
1768*d30ea906Sjfb8856606 			if (likely(first_time && (deq > 0))) {
1769*d30ea906Sjfb8856606 				last_time = rte_rdtsc_precise() - start_time;
1770*d30ea906Sjfb8856606 				first_time = false;
1771*d30ea906Sjfb8856606 			}
1772*d30ea906Sjfb8856606 		} while (unlikely(burst_sz != deq));
1773*d30ea906Sjfb8856606 
1774*d30ea906Sjfb8856606 		*max_time = RTE_MAX(*max_time, last_time);
1775*d30ea906Sjfb8856606 		*min_time = RTE_MIN(*min_time, last_time);
1776*d30ea906Sjfb8856606 		*total_time += last_time;
1777*d30ea906Sjfb8856606 
1778*d30ea906Sjfb8856606 		if (test_vector.op_type != RTE_BBDEV_OP_NONE) {
1779*d30ea906Sjfb8856606 			ret = validate_dec_op(ops_deq, burst_sz, ref_op,
1780*d30ea906Sjfb8856606 					vector_mask);
1781*d30ea906Sjfb8856606 			TEST_ASSERT_SUCCESS(ret, "Validation failed!");
1782*d30ea906Sjfb8856606 		}
1783*d30ea906Sjfb8856606 
1784*d30ea906Sjfb8856606 		rte_bbdev_dec_op_free_bulk(ops_enq, deq);
1785*d30ea906Sjfb8856606 		dequeued += deq;
1786*d30ea906Sjfb8856606 	}
1787*d30ea906Sjfb8856606 
1788*d30ea906Sjfb8856606 	return i;
1789*d30ea906Sjfb8856606 }
1790*d30ea906Sjfb8856606 
1791*d30ea906Sjfb8856606 static int
1792*d30ea906Sjfb8856606 latency_test_enc(struct rte_mempool *mempool,
1793*d30ea906Sjfb8856606 		struct test_buffers *bufs, struct rte_bbdev_enc_op *ref_op,
1794*d30ea906Sjfb8856606 		uint16_t dev_id, uint16_t queue_id,
1795*d30ea906Sjfb8856606 		const uint16_t num_to_process, uint16_t burst_sz,
1796*d30ea906Sjfb8856606 		uint64_t *total_time, uint64_t *min_time, uint64_t *max_time)
1797*d30ea906Sjfb8856606 {
1798*d30ea906Sjfb8856606 	int ret = TEST_SUCCESS;
1799*d30ea906Sjfb8856606 	uint16_t i, j, dequeued;
1800*d30ea906Sjfb8856606 	struct rte_bbdev_enc_op *ops_enq[MAX_BURST], *ops_deq[MAX_BURST];
1801*d30ea906Sjfb8856606 	uint64_t start_time = 0, last_time = 0;
1802*d30ea906Sjfb8856606 
1803*d30ea906Sjfb8856606 	for (i = 0, dequeued = 0; dequeued < num_to_process; ++i) {
1804*d30ea906Sjfb8856606 		uint16_t enq = 0, deq = 0;
1805*d30ea906Sjfb8856606 		bool first_time = true;
1806*d30ea906Sjfb8856606 		last_time = 0;
1807*d30ea906Sjfb8856606 
1808*d30ea906Sjfb8856606 		if (unlikely(num_to_process - dequeued < burst_sz))
1809*d30ea906Sjfb8856606 			burst_sz = num_to_process - dequeued;
1810*d30ea906Sjfb8856606 
1811*d30ea906Sjfb8856606 		ret = rte_bbdev_enc_op_alloc_bulk(mempool, ops_enq, burst_sz);
1812*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(ret,
1813*d30ea906Sjfb8856606 				"rte_bbdev_enc_op_alloc_bulk() failed");
1814*d30ea906Sjfb8856606 		if (test_vector.op_type != RTE_BBDEV_OP_NONE)
1815*d30ea906Sjfb8856606 			copy_reference_enc_op(ops_enq, burst_sz, dequeued,
1816*d30ea906Sjfb8856606 					bufs->inputs,
1817*d30ea906Sjfb8856606 					bufs->hard_outputs,
1818*d30ea906Sjfb8856606 					ref_op);
1819*d30ea906Sjfb8856606 
1820*d30ea906Sjfb8856606 		/* Set counter to validate the ordering */
1821*d30ea906Sjfb8856606 		for (j = 0; j < burst_sz; ++j)
1822*d30ea906Sjfb8856606 			ops_enq[j]->opaque_data = (void *)(uintptr_t)j;
1823*d30ea906Sjfb8856606 
1824*d30ea906Sjfb8856606 		start_time = rte_rdtsc_precise();
1825*d30ea906Sjfb8856606 
1826*d30ea906Sjfb8856606 		enq = rte_bbdev_enqueue_enc_ops(dev_id, queue_id, &ops_enq[enq],
1827*d30ea906Sjfb8856606 				burst_sz);
1828*d30ea906Sjfb8856606 		TEST_ASSERT(enq == burst_sz,
1829*d30ea906Sjfb8856606 				"Error enqueueing burst, expected %u, got %u",
1830*d30ea906Sjfb8856606 				burst_sz, enq);
1831*d30ea906Sjfb8856606 
1832*d30ea906Sjfb8856606 		/* Dequeue */
1833*d30ea906Sjfb8856606 		do {
1834*d30ea906Sjfb8856606 			deq += rte_bbdev_dequeue_enc_ops(dev_id, queue_id,
1835*d30ea906Sjfb8856606 					&ops_deq[deq], burst_sz - deq);
1836*d30ea906Sjfb8856606 			if (likely(first_time && (deq > 0))) {
1837*d30ea906Sjfb8856606 				last_time += rte_rdtsc_precise() - start_time;
1838*d30ea906Sjfb8856606 				first_time = false;
1839*d30ea906Sjfb8856606 			}
1840*d30ea906Sjfb8856606 		} while (unlikely(burst_sz != deq));
1841*d30ea906Sjfb8856606 
1842*d30ea906Sjfb8856606 		*max_time = RTE_MAX(*max_time, last_time);
1843*d30ea906Sjfb8856606 		*min_time = RTE_MIN(*min_time, last_time);
1844*d30ea906Sjfb8856606 		*total_time += last_time;
1845*d30ea906Sjfb8856606 
1846*d30ea906Sjfb8856606 		if (test_vector.op_type != RTE_BBDEV_OP_NONE) {
1847*d30ea906Sjfb8856606 			ret = validate_enc_op(ops_deq, burst_sz, ref_op);
1848*d30ea906Sjfb8856606 			TEST_ASSERT_SUCCESS(ret, "Validation failed!");
1849*d30ea906Sjfb8856606 		}
1850*d30ea906Sjfb8856606 
1851*d30ea906Sjfb8856606 		rte_bbdev_enc_op_free_bulk(ops_enq, deq);
1852*d30ea906Sjfb8856606 		dequeued += deq;
1853*d30ea906Sjfb8856606 	}
1854*d30ea906Sjfb8856606 
1855*d30ea906Sjfb8856606 	return i;
1856*d30ea906Sjfb8856606 }
1857*d30ea906Sjfb8856606 
1858*d30ea906Sjfb8856606 static int
1859*d30ea906Sjfb8856606 latency_test(struct active_device *ad,
1860*d30ea906Sjfb8856606 		struct test_op_params *op_params)
1861*d30ea906Sjfb8856606 {
1862*d30ea906Sjfb8856606 	int iter;
1863*d30ea906Sjfb8856606 	uint16_t burst_sz = op_params->burst_sz;
1864*d30ea906Sjfb8856606 	const uint16_t num_to_process = op_params->num_to_process;
1865*d30ea906Sjfb8856606 	const enum rte_bbdev_op_type op_type = test_vector.op_type;
1866*d30ea906Sjfb8856606 	const uint16_t queue_id = ad->queue_ids[0];
1867*d30ea906Sjfb8856606 	struct test_buffers *bufs = NULL;
1868*d30ea906Sjfb8856606 	struct rte_bbdev_info info;
1869*d30ea906Sjfb8856606 	uint64_t total_time, min_time, max_time;
1870*d30ea906Sjfb8856606 	const char *op_type_str;
1871*d30ea906Sjfb8856606 
1872*d30ea906Sjfb8856606 	total_time = max_time = 0;
1873*d30ea906Sjfb8856606 	min_time = UINT64_MAX;
1874*d30ea906Sjfb8856606 
1875*d30ea906Sjfb8856606 	TEST_ASSERT_SUCCESS((burst_sz > MAX_BURST),
1876*d30ea906Sjfb8856606 			"BURST_SIZE should be <= %u", MAX_BURST);
1877*d30ea906Sjfb8856606 
1878*d30ea906Sjfb8856606 	rte_bbdev_info_get(ad->dev_id, &info);
1879*d30ea906Sjfb8856606 	bufs = &op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];
1880*d30ea906Sjfb8856606 
1881*d30ea906Sjfb8856606 	op_type_str = rte_bbdev_op_type_str(op_type);
1882*d30ea906Sjfb8856606 	TEST_ASSERT_NOT_NULL(op_type_str, "Invalid op type: %u", op_type);
1883*d30ea906Sjfb8856606 
1884*d30ea906Sjfb8856606 	printf(
1885*d30ea906Sjfb8856606 		"Validation/Latency test: dev: %s, burst size: %u, num ops: %u, op type: %s\n",
1886*d30ea906Sjfb8856606 			info.dev_name, burst_sz, num_to_process, op_type_str);
1887*d30ea906Sjfb8856606 
1888*d30ea906Sjfb8856606 	if (op_type == RTE_BBDEV_OP_TURBO_DEC)
1889*d30ea906Sjfb8856606 		iter = latency_test_dec(op_params->mp, bufs,
1890*d30ea906Sjfb8856606 				op_params->ref_dec_op, op_params->vector_mask,
1891*d30ea906Sjfb8856606 				ad->dev_id, queue_id, num_to_process,
1892*d30ea906Sjfb8856606 				burst_sz, &total_time, &min_time, &max_time);
1893*d30ea906Sjfb8856606 	else
1894*d30ea906Sjfb8856606 		iter = latency_test_enc(op_params->mp, bufs,
1895*d30ea906Sjfb8856606 				op_params->ref_enc_op, ad->dev_id, queue_id,
1896*d30ea906Sjfb8856606 				num_to_process, burst_sz, &total_time,
1897*d30ea906Sjfb8856606 				&min_time, &max_time);
1898*d30ea906Sjfb8856606 
1899*d30ea906Sjfb8856606 	if (iter <= 0)
1900*d30ea906Sjfb8856606 		return TEST_FAILED;
1901*d30ea906Sjfb8856606 
1902*d30ea906Sjfb8856606 	printf("\toperation latency:\n"
1903*d30ea906Sjfb8856606 			"\t\tavg latency: %lg cycles, %lg us\n"
1904*d30ea906Sjfb8856606 			"\t\tmin latency: %lg cycles, %lg us\n"
1905*d30ea906Sjfb8856606 			"\t\tmax latency: %lg cycles, %lg us\n",
1906*d30ea906Sjfb8856606 			(double)total_time / (double)iter,
1907*d30ea906Sjfb8856606 			(double)(total_time * 1000000) / (double)iter /
1908*d30ea906Sjfb8856606 			(double)rte_get_tsc_hz(), (double)min_time,
1909*d30ea906Sjfb8856606 			(double)(min_time * 1000000) / (double)rte_get_tsc_hz(),
1910*d30ea906Sjfb8856606 			(double)max_time, (double)(max_time * 1000000) /
1911*d30ea906Sjfb8856606 			(double)rte_get_tsc_hz());
1912*d30ea906Sjfb8856606 
1913*d30ea906Sjfb8856606 	return TEST_SUCCESS;
1914*d30ea906Sjfb8856606 }
1915*d30ea906Sjfb8856606 
1916*d30ea906Sjfb8856606 #ifdef RTE_BBDEV_OFFLOAD_COST
1917*d30ea906Sjfb8856606 static int
1918*d30ea906Sjfb8856606 get_bbdev_queue_stats(uint16_t dev_id, uint16_t queue_id,
1919*d30ea906Sjfb8856606 		struct rte_bbdev_stats *stats)
1920*d30ea906Sjfb8856606 {
1921*d30ea906Sjfb8856606 	struct rte_bbdev *dev = &rte_bbdev_devices[dev_id];
1922*d30ea906Sjfb8856606 	struct rte_bbdev_stats *q_stats;
1923*d30ea906Sjfb8856606 
1924*d30ea906Sjfb8856606 	if (queue_id >= dev->data->num_queues)
1925*d30ea906Sjfb8856606 		return -1;
1926*d30ea906Sjfb8856606 
1927*d30ea906Sjfb8856606 	q_stats = &dev->data->queues[queue_id].queue_stats;
1928*d30ea906Sjfb8856606 
1929*d30ea906Sjfb8856606 	stats->enqueued_count = q_stats->enqueued_count;
1930*d30ea906Sjfb8856606 	stats->dequeued_count = q_stats->dequeued_count;
1931*d30ea906Sjfb8856606 	stats->enqueue_err_count = q_stats->enqueue_err_count;
1932*d30ea906Sjfb8856606 	stats->dequeue_err_count = q_stats->dequeue_err_count;
1933*d30ea906Sjfb8856606 	stats->offload_time = q_stats->offload_time;
1934*d30ea906Sjfb8856606 
1935*d30ea906Sjfb8856606 	return 0;
1936*d30ea906Sjfb8856606 }
1937*d30ea906Sjfb8856606 
1938*d30ea906Sjfb8856606 static int
1939*d30ea906Sjfb8856606 offload_latency_test_dec(struct rte_mempool *mempool, struct test_buffers *bufs,
1940*d30ea906Sjfb8856606 		struct rte_bbdev_dec_op *ref_op, uint16_t dev_id,
1941*d30ea906Sjfb8856606 		uint16_t queue_id, const uint16_t num_to_process,
1942*d30ea906Sjfb8856606 		uint16_t burst_sz, struct test_time_stats *time_st)
1943*d30ea906Sjfb8856606 {
1944*d30ea906Sjfb8856606 	int i, dequeued, ret;
1945*d30ea906Sjfb8856606 	struct rte_bbdev_dec_op *ops_enq[MAX_BURST], *ops_deq[MAX_BURST];
1946*d30ea906Sjfb8856606 	uint64_t enq_start_time, deq_start_time;
1947*d30ea906Sjfb8856606 	uint64_t enq_sw_last_time, deq_last_time;
1948*d30ea906Sjfb8856606 	struct rte_bbdev_stats stats;
1949*d30ea906Sjfb8856606 
1950*d30ea906Sjfb8856606 	for (i = 0, dequeued = 0; dequeued < num_to_process; ++i) {
1951*d30ea906Sjfb8856606 		uint16_t enq = 0, deq = 0;
1952*d30ea906Sjfb8856606 
1953*d30ea906Sjfb8856606 		if (unlikely(num_to_process - dequeued < burst_sz))
1954*d30ea906Sjfb8856606 			burst_sz = num_to_process - dequeued;
1955*d30ea906Sjfb8856606 
1956*d30ea906Sjfb8856606 		rte_bbdev_dec_op_alloc_bulk(mempool, ops_enq, burst_sz);
1957*d30ea906Sjfb8856606 		if (test_vector.op_type != RTE_BBDEV_OP_NONE)
1958*d30ea906Sjfb8856606 			copy_reference_dec_op(ops_enq, burst_sz, dequeued,
1959*d30ea906Sjfb8856606 					bufs->inputs,
1960*d30ea906Sjfb8856606 					bufs->hard_outputs,
1961*d30ea906Sjfb8856606 					bufs->soft_outputs,
1962*d30ea906Sjfb8856606 					ref_op);
1963*d30ea906Sjfb8856606 
1964*d30ea906Sjfb8856606 		/* Start time meas for enqueue function offload latency */
1965*d30ea906Sjfb8856606 		enq_start_time = rte_rdtsc_precise();
1966*d30ea906Sjfb8856606 		do {
1967*d30ea906Sjfb8856606 			enq += rte_bbdev_enqueue_dec_ops(dev_id, queue_id,
1968*d30ea906Sjfb8856606 					&ops_enq[enq], burst_sz - enq);
1969*d30ea906Sjfb8856606 		} while (unlikely(burst_sz != enq));
1970*d30ea906Sjfb8856606 
1971*d30ea906Sjfb8856606 		ret = get_bbdev_queue_stats(dev_id, queue_id, &stats);
1972*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(ret,
1973*d30ea906Sjfb8856606 				"Failed to get stats for queue (%u) of device (%u)",
1974*d30ea906Sjfb8856606 				queue_id, dev_id);
1975*d30ea906Sjfb8856606 
1976*d30ea906Sjfb8856606 		enq_sw_last_time = rte_rdtsc_precise() - enq_start_time -
1977*d30ea906Sjfb8856606 				stats.offload_time;
1978*d30ea906Sjfb8856606 		time_st->enq_sw_max_time = RTE_MAX(time_st->enq_sw_max_time,
1979*d30ea906Sjfb8856606 				enq_sw_last_time);
1980*d30ea906Sjfb8856606 		time_st->enq_sw_min_time = RTE_MIN(time_st->enq_sw_min_time,
1981*d30ea906Sjfb8856606 				enq_sw_last_time);
1982*d30ea906Sjfb8856606 		time_st->enq_sw_tot_time += enq_sw_last_time;
1983*d30ea906Sjfb8856606 
1984*d30ea906Sjfb8856606 		time_st->enq_tur_max_time = RTE_MAX(time_st->enq_tur_max_time,
1985*d30ea906Sjfb8856606 				stats.offload_time);
1986*d30ea906Sjfb8856606 		time_st->enq_tur_min_time = RTE_MIN(time_st->enq_tur_min_time,
1987*d30ea906Sjfb8856606 				stats.offload_time);
1988*d30ea906Sjfb8856606 		time_st->enq_tur_tot_time += stats.offload_time;
1989*d30ea906Sjfb8856606 
1990*d30ea906Sjfb8856606 		/* ensure enqueue has been completed */
1991*d30ea906Sjfb8856606 		rte_delay_ms(10);
1992*d30ea906Sjfb8856606 
1993*d30ea906Sjfb8856606 		/* Start time meas for dequeue function offload latency */
1994*d30ea906Sjfb8856606 		deq_start_time = rte_rdtsc_precise();
1995*d30ea906Sjfb8856606 		/* Dequeue one operation */
1996*d30ea906Sjfb8856606 		do {
1997*d30ea906Sjfb8856606 			deq += rte_bbdev_dequeue_dec_ops(dev_id, queue_id,
1998*d30ea906Sjfb8856606 					&ops_deq[deq], 1);
1999*d30ea906Sjfb8856606 		} while (unlikely(deq != 1));
2000*d30ea906Sjfb8856606 
2001*d30ea906Sjfb8856606 		deq_last_time = rte_rdtsc_precise() - deq_start_time;
2002*d30ea906Sjfb8856606 		time_st->deq_max_time = RTE_MAX(time_st->deq_max_time,
2003*d30ea906Sjfb8856606 				deq_last_time);
2004*d30ea906Sjfb8856606 		time_st->deq_min_time = RTE_MIN(time_st->deq_min_time,
2005*d30ea906Sjfb8856606 				deq_last_time);
2006*d30ea906Sjfb8856606 		time_st->deq_tot_time += deq_last_time;
2007*d30ea906Sjfb8856606 
2008*d30ea906Sjfb8856606 		/* Dequeue remaining operations if needed*/
2009*d30ea906Sjfb8856606 		while (burst_sz != deq)
2010*d30ea906Sjfb8856606 			deq += rte_bbdev_dequeue_dec_ops(dev_id, queue_id,
2011*d30ea906Sjfb8856606 					&ops_deq[deq], burst_sz - deq);
2012*d30ea906Sjfb8856606 
2013*d30ea906Sjfb8856606 		rte_bbdev_dec_op_free_bulk(ops_enq, deq);
2014*d30ea906Sjfb8856606 		dequeued += deq;
2015*d30ea906Sjfb8856606 	}
2016*d30ea906Sjfb8856606 
2017*d30ea906Sjfb8856606 	return i;
2018*d30ea906Sjfb8856606 }
2019*d30ea906Sjfb8856606 
2020*d30ea906Sjfb8856606 static int
2021*d30ea906Sjfb8856606 offload_latency_test_enc(struct rte_mempool *mempool, struct test_buffers *bufs,
2022*d30ea906Sjfb8856606 		struct rte_bbdev_enc_op *ref_op, uint16_t dev_id,
2023*d30ea906Sjfb8856606 		uint16_t queue_id, const uint16_t num_to_process,
2024*d30ea906Sjfb8856606 		uint16_t burst_sz, struct test_time_stats *time_st)
2025*d30ea906Sjfb8856606 {
2026*d30ea906Sjfb8856606 	int i, dequeued, ret;
2027*d30ea906Sjfb8856606 	struct rte_bbdev_enc_op *ops_enq[MAX_BURST], *ops_deq[MAX_BURST];
2028*d30ea906Sjfb8856606 	uint64_t enq_start_time, deq_start_time;
2029*d30ea906Sjfb8856606 	uint64_t enq_sw_last_time, deq_last_time;
2030*d30ea906Sjfb8856606 	struct rte_bbdev_stats stats;
2031*d30ea906Sjfb8856606 
2032*d30ea906Sjfb8856606 	for (i = 0, dequeued = 0; dequeued < num_to_process; ++i) {
2033*d30ea906Sjfb8856606 		uint16_t enq = 0, deq = 0;
2034*d30ea906Sjfb8856606 
2035*d30ea906Sjfb8856606 		if (unlikely(num_to_process - dequeued < burst_sz))
2036*d30ea906Sjfb8856606 			burst_sz = num_to_process - dequeued;
2037*d30ea906Sjfb8856606 
2038*d30ea906Sjfb8856606 		rte_bbdev_enc_op_alloc_bulk(mempool, ops_enq, burst_sz);
2039*d30ea906Sjfb8856606 		if (test_vector.op_type != RTE_BBDEV_OP_NONE)
2040*d30ea906Sjfb8856606 			copy_reference_enc_op(ops_enq, burst_sz, dequeued,
2041*d30ea906Sjfb8856606 					bufs->inputs,
2042*d30ea906Sjfb8856606 					bufs->hard_outputs,
2043*d30ea906Sjfb8856606 					ref_op);
2044*d30ea906Sjfb8856606 
2045*d30ea906Sjfb8856606 		/* Start time meas for enqueue function offload latency */
2046*d30ea906Sjfb8856606 		enq_start_time = rte_rdtsc_precise();
2047*d30ea906Sjfb8856606 		do {
2048*d30ea906Sjfb8856606 			enq += rte_bbdev_enqueue_enc_ops(dev_id, queue_id,
2049*d30ea906Sjfb8856606 					&ops_enq[enq], burst_sz - enq);
2050*d30ea906Sjfb8856606 		} while (unlikely(burst_sz != enq));
2051*d30ea906Sjfb8856606 
2052*d30ea906Sjfb8856606 		ret = get_bbdev_queue_stats(dev_id, queue_id, &stats);
2053*d30ea906Sjfb8856606 		TEST_ASSERT_SUCCESS(ret,
2054*d30ea906Sjfb8856606 				"Failed to get stats for queue (%u) of device (%u)",
2055*d30ea906Sjfb8856606 				queue_id, dev_id);
2056*d30ea906Sjfb8856606 
2057*d30ea906Sjfb8856606 		enq_sw_last_time = rte_rdtsc_precise() - enq_start_time -
2058*d30ea906Sjfb8856606 				stats.offload_time;
2059*d30ea906Sjfb8856606 		time_st->enq_sw_max_time = RTE_MAX(time_st->enq_sw_max_time,
2060*d30ea906Sjfb8856606 				enq_sw_last_time);
2061*d30ea906Sjfb8856606 		time_st->enq_sw_min_time = RTE_MIN(time_st->enq_sw_min_time,
2062*d30ea906Sjfb8856606 				enq_sw_last_time);
2063*d30ea906Sjfb8856606 		time_st->enq_sw_tot_time += enq_sw_last_time;
2064*d30ea906Sjfb8856606 
2065*d30ea906Sjfb8856606 		time_st->enq_tur_max_time = RTE_MAX(time_st->enq_tur_max_time,
2066*d30ea906Sjfb8856606 				stats.offload_time);
2067*d30ea906Sjfb8856606 		time_st->enq_tur_min_time = RTE_MIN(time_st->enq_tur_min_time,
2068*d30ea906Sjfb8856606 				stats.offload_time);
2069*d30ea906Sjfb8856606 		time_st->enq_tur_tot_time += stats.offload_time;
2070*d30ea906Sjfb8856606 
2071*d30ea906Sjfb8856606 		/* ensure enqueue has been completed */
2072*d30ea906Sjfb8856606 		rte_delay_ms(10);
2073*d30ea906Sjfb8856606 
2074*d30ea906Sjfb8856606 		/* Start time meas for dequeue function offload latency */
2075*d30ea906Sjfb8856606 		deq_start_time = rte_rdtsc_precise();
2076*d30ea906Sjfb8856606 		/* Dequeue one operation */
2077*d30ea906Sjfb8856606 		do {
2078*d30ea906Sjfb8856606 			deq += rte_bbdev_dequeue_enc_ops(dev_id, queue_id,
2079*d30ea906Sjfb8856606 					&ops_deq[deq], 1);
2080*d30ea906Sjfb8856606 		} while (unlikely(deq != 1));
2081*d30ea906Sjfb8856606 
2082*d30ea906Sjfb8856606 		deq_last_time = rte_rdtsc_precise() - deq_start_time;
2083*d30ea906Sjfb8856606 		time_st->deq_max_time = RTE_MAX(time_st->deq_max_time,
2084*d30ea906Sjfb8856606 				deq_last_time);
2085*d30ea906Sjfb8856606 		time_st->deq_min_time = RTE_MIN(time_st->deq_min_time,
2086*d30ea906Sjfb8856606 				deq_last_time);
2087*d30ea906Sjfb8856606 		time_st->deq_tot_time += deq_last_time;
2088*d30ea906Sjfb8856606 
2089*d30ea906Sjfb8856606 		while (burst_sz != deq)
2090*d30ea906Sjfb8856606 			deq += rte_bbdev_dequeue_enc_ops(dev_id, queue_id,
2091*d30ea906Sjfb8856606 					&ops_deq[deq], burst_sz - deq);
2092*d30ea906Sjfb8856606 
2093*d30ea906Sjfb8856606 		rte_bbdev_enc_op_free_bulk(ops_enq, deq);
2094*d30ea906Sjfb8856606 		dequeued += deq;
2095*d30ea906Sjfb8856606 	}
2096*d30ea906Sjfb8856606 
2097*d30ea906Sjfb8856606 	return i;
2098*d30ea906Sjfb8856606 }
2099*d30ea906Sjfb8856606 #endif
2100*d30ea906Sjfb8856606 
2101*d30ea906Sjfb8856606 static int
2102*d30ea906Sjfb8856606 offload_cost_test(struct active_device *ad,
2103*d30ea906Sjfb8856606 		struct test_op_params *op_params)
2104*d30ea906Sjfb8856606 {
2105*d30ea906Sjfb8856606 #ifndef RTE_BBDEV_OFFLOAD_COST
2106*d30ea906Sjfb8856606 	RTE_SET_USED(ad);
2107*d30ea906Sjfb8856606 	RTE_SET_USED(op_params);
2108*d30ea906Sjfb8856606 	printf("Offload latency test is disabled.\n");
2109*d30ea906Sjfb8856606 	printf("Set RTE_BBDEV_OFFLOAD_COST to 'y' to turn the test on.\n");
2110*d30ea906Sjfb8856606 	return TEST_SKIPPED;
2111*d30ea906Sjfb8856606 #else
2112*d30ea906Sjfb8856606 	int iter;
2113*d30ea906Sjfb8856606 	uint16_t burst_sz = op_params->burst_sz;
2114*d30ea906Sjfb8856606 	const uint16_t num_to_process = op_params->num_to_process;
2115*d30ea906Sjfb8856606 	const enum rte_bbdev_op_type op_type = test_vector.op_type;
2116*d30ea906Sjfb8856606 	const uint16_t queue_id = ad->queue_ids[0];
2117*d30ea906Sjfb8856606 	struct test_buffers *bufs = NULL;
2118*d30ea906Sjfb8856606 	struct rte_bbdev_info info;
2119*d30ea906Sjfb8856606 	const char *op_type_str;
2120*d30ea906Sjfb8856606 	struct test_time_stats time_st;
2121*d30ea906Sjfb8856606 
2122*d30ea906Sjfb8856606 	memset(&time_st, 0, sizeof(struct test_time_stats));
2123*d30ea906Sjfb8856606 	time_st.enq_sw_min_time = UINT64_MAX;
2124*d30ea906Sjfb8856606 	time_st.enq_tur_min_time = UINT64_MAX;
2125*d30ea906Sjfb8856606 	time_st.deq_min_time = UINT64_MAX;
2126*d30ea906Sjfb8856606 
2127*d30ea906Sjfb8856606 	TEST_ASSERT_SUCCESS((burst_sz > MAX_BURST),
2128*d30ea906Sjfb8856606 			"BURST_SIZE should be <= %u", MAX_BURST);
2129*d30ea906Sjfb8856606 
2130*d30ea906Sjfb8856606 	rte_bbdev_info_get(ad->dev_id, &info);
2131*d30ea906Sjfb8856606 	bufs = &op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];
2132*d30ea906Sjfb8856606 
2133*d30ea906Sjfb8856606 	op_type_str = rte_bbdev_op_type_str(op_type);
2134*d30ea906Sjfb8856606 	TEST_ASSERT_NOT_NULL(op_type_str, "Invalid op type: %u", op_type);
2135*d30ea906Sjfb8856606 
2136*d30ea906Sjfb8856606 	printf(
2137*d30ea906Sjfb8856606 		"Offload latency test: dev: %s, burst size: %u, num ops: %u, op type: %s\n",
2138*d30ea906Sjfb8856606 			info.dev_name, burst_sz, num_to_process, op_type_str);
2139*d30ea906Sjfb8856606 
2140*d30ea906Sjfb8856606 	if (op_type == RTE_BBDEV_OP_TURBO_DEC)
2141*d30ea906Sjfb8856606 		iter = offload_latency_test_dec(op_params->mp, bufs,
2142*d30ea906Sjfb8856606 				op_params->ref_dec_op, ad->dev_id, queue_id,
2143*d30ea906Sjfb8856606 				num_to_process, burst_sz, &time_st);
2144*d30ea906Sjfb8856606 	else
2145*d30ea906Sjfb8856606 		iter = offload_latency_test_enc(op_params->mp, bufs,
2146*d30ea906Sjfb8856606 				op_params->ref_enc_op, ad->dev_id, queue_id,
2147*d30ea906Sjfb8856606 				num_to_process, burst_sz, &time_st);
2148*d30ea906Sjfb8856606 
2149*d30ea906Sjfb8856606 	if (iter <= 0)
2150*d30ea906Sjfb8856606 		return TEST_FAILED;
2151*d30ea906Sjfb8856606 
2152*d30ea906Sjfb8856606 	printf("\tenq offload cost latency:\n"
2153*d30ea906Sjfb8856606 			"\t\tsoftware avg %lg cycles, %lg us\n"
2154*d30ea906Sjfb8856606 			"\t\tsoftware min %lg cycles, %lg us\n"
2155*d30ea906Sjfb8856606 			"\t\tsoftware max %lg cycles, %lg us\n"
2156*d30ea906Sjfb8856606 			"\t\tturbo avg %lg cycles, %lg us\n"
2157*d30ea906Sjfb8856606 			"\t\tturbo min %lg cycles, %lg us\n"
2158*d30ea906Sjfb8856606 			"\t\tturbo max %lg cycles, %lg us\n",
2159*d30ea906Sjfb8856606 			(double)time_st.enq_sw_tot_time / (double)iter,
2160*d30ea906Sjfb8856606 			(double)(time_st.enq_sw_tot_time * 1000000) /
2161*d30ea906Sjfb8856606 			(double)iter / (double)rte_get_tsc_hz(),
2162*d30ea906Sjfb8856606 			(double)time_st.enq_sw_min_time,
2163*d30ea906Sjfb8856606 			(double)(time_st.enq_sw_min_time * 1000000) /
2164*d30ea906Sjfb8856606 			rte_get_tsc_hz(), (double)time_st.enq_sw_max_time,
2165*d30ea906Sjfb8856606 			(double)(time_st.enq_sw_max_time * 1000000) /
2166*d30ea906Sjfb8856606 			rte_get_tsc_hz(), (double)time_st.enq_tur_tot_time /
2167*d30ea906Sjfb8856606 			(double)iter,
2168*d30ea906Sjfb8856606 			(double)(time_st.enq_tur_tot_time * 1000000) /
2169*d30ea906Sjfb8856606 			(double)iter / (double)rte_get_tsc_hz(),
2170*d30ea906Sjfb8856606 			(double)time_st.enq_tur_min_time,
2171*d30ea906Sjfb8856606 			(double)(time_st.enq_tur_min_time * 1000000) /
2172*d30ea906Sjfb8856606 			rte_get_tsc_hz(), (double)time_st.enq_tur_max_time,
2173*d30ea906Sjfb8856606 			(double)(time_st.enq_tur_max_time * 1000000) /
2174*d30ea906Sjfb8856606 			rte_get_tsc_hz());
2175*d30ea906Sjfb8856606 
2176*d30ea906Sjfb8856606 	printf("\tdeq offload cost latency - one op:\n"
2177*d30ea906Sjfb8856606 			"\t\tavg %lg cycles, %lg us\n"
2178*d30ea906Sjfb8856606 			"\t\tmin %lg cycles, %lg us\n"
2179*d30ea906Sjfb8856606 			"\t\tmax %lg cycles, %lg us\n",
2180*d30ea906Sjfb8856606 			(double)time_st.deq_tot_time / (double)iter,
2181*d30ea906Sjfb8856606 			(double)(time_st.deq_tot_time * 1000000) /
2182*d30ea906Sjfb8856606 			(double)iter / (double)rte_get_tsc_hz(),
2183*d30ea906Sjfb8856606 			(double)time_st.deq_min_time,
2184*d30ea906Sjfb8856606 			(double)(time_st.deq_min_time * 1000000) /
2185*d30ea906Sjfb8856606 			rte_get_tsc_hz(), (double)time_st.deq_max_time,
2186*d30ea906Sjfb8856606 			(double)(time_st.deq_max_time * 1000000) /
2187*d30ea906Sjfb8856606 			rte_get_tsc_hz());
2188*d30ea906Sjfb8856606 
2189*d30ea906Sjfb8856606 	return TEST_SUCCESS;
2190*d30ea906Sjfb8856606 #endif
2191*d30ea906Sjfb8856606 }
2192*d30ea906Sjfb8856606 
2193*d30ea906Sjfb8856606 #ifdef RTE_BBDEV_OFFLOAD_COST
2194*d30ea906Sjfb8856606 static int
2195*d30ea906Sjfb8856606 offload_latency_empty_q_test_dec(uint16_t dev_id, uint16_t queue_id,
2196*d30ea906Sjfb8856606 		const uint16_t num_to_process, uint16_t burst_sz,
2197*d30ea906Sjfb8856606 		uint64_t *deq_tot_time, uint64_t *deq_min_time,
2198*d30ea906Sjfb8856606 		uint64_t *deq_max_time)
2199*d30ea906Sjfb8856606 {
2200*d30ea906Sjfb8856606 	int i, deq_total;
2201*d30ea906Sjfb8856606 	struct rte_bbdev_dec_op *ops[MAX_BURST];
2202*d30ea906Sjfb8856606 	uint64_t deq_start_time, deq_last_time;
2203*d30ea906Sjfb8856606 
2204*d30ea906Sjfb8856606 	/* Test deq offload latency from an empty queue */
2205*d30ea906Sjfb8856606 
2206*d30ea906Sjfb8856606 	for (i = 0, deq_total = 0; deq_total < num_to_process;
2207*d30ea906Sjfb8856606 			++i, deq_total += burst_sz) {
2208*d30ea906Sjfb8856606 		deq_start_time = rte_rdtsc_precise();
2209*d30ea906Sjfb8856606 
2210*d30ea906Sjfb8856606 		if (unlikely(num_to_process - deq_total < burst_sz))
2211*d30ea906Sjfb8856606 			burst_sz = num_to_process - deq_total;
2212*d30ea906Sjfb8856606 		rte_bbdev_dequeue_dec_ops(dev_id, queue_id, ops, burst_sz);
2213*d30ea906Sjfb8856606 
2214*d30ea906Sjfb8856606 		deq_last_time = rte_rdtsc_precise() - deq_start_time;
2215*d30ea906Sjfb8856606 		*deq_max_time = RTE_MAX(*deq_max_time, deq_last_time);
2216*d30ea906Sjfb8856606 		*deq_min_time = RTE_MIN(*deq_min_time, deq_last_time);
2217*d30ea906Sjfb8856606 		*deq_tot_time += deq_last_time;
2218*d30ea906Sjfb8856606 	}
2219*d30ea906Sjfb8856606 
2220*d30ea906Sjfb8856606 	return i;
2221*d30ea906Sjfb8856606 }
2222*d30ea906Sjfb8856606 
2223*d30ea906Sjfb8856606 static int
2224*d30ea906Sjfb8856606 offload_latency_empty_q_test_enc(uint16_t dev_id, uint16_t queue_id,
2225*d30ea906Sjfb8856606 		const uint16_t num_to_process, uint16_t burst_sz,
2226*d30ea906Sjfb8856606 		uint64_t *deq_tot_time, uint64_t *deq_min_time,
2227*d30ea906Sjfb8856606 		uint64_t *deq_max_time)
2228*d30ea906Sjfb8856606 {
2229*d30ea906Sjfb8856606 	int i, deq_total;
2230*d30ea906Sjfb8856606 	struct rte_bbdev_enc_op *ops[MAX_BURST];
2231*d30ea906Sjfb8856606 	uint64_t deq_start_time, deq_last_time;
2232*d30ea906Sjfb8856606 
2233*d30ea906Sjfb8856606 	/* Test deq offload latency from an empty queue */
2234*d30ea906Sjfb8856606 	for (i = 0, deq_total = 0; deq_total < num_to_process;
2235*d30ea906Sjfb8856606 			++i, deq_total += burst_sz) {
2236*d30ea906Sjfb8856606 		deq_start_time = rte_rdtsc_precise();
2237*d30ea906Sjfb8856606 
2238*d30ea906Sjfb8856606 		if (unlikely(num_to_process - deq_total < burst_sz))
2239*d30ea906Sjfb8856606 			burst_sz = num_to_process - deq_total;
2240*d30ea906Sjfb8856606 		rte_bbdev_dequeue_enc_ops(dev_id, queue_id, ops, burst_sz);
2241*d30ea906Sjfb8856606 
2242*d30ea906Sjfb8856606 		deq_last_time = rte_rdtsc_precise() - deq_start_time;
2243*d30ea906Sjfb8856606 		*deq_max_time = RTE_MAX(*deq_max_time, deq_last_time);
2244*d30ea906Sjfb8856606 		*deq_min_time = RTE_MIN(*deq_min_time, deq_last_time);
2245*d30ea906Sjfb8856606 		*deq_tot_time += deq_last_time;
2246*d30ea906Sjfb8856606 	}
2247*d30ea906Sjfb8856606 
2248*d30ea906Sjfb8856606 	return i;
2249*d30ea906Sjfb8856606 }
2250*d30ea906Sjfb8856606 #endif
2251*d30ea906Sjfb8856606 
2252*d30ea906Sjfb8856606 static int
2253*d30ea906Sjfb8856606 offload_latency_empty_q_test(struct active_device *ad,
2254*d30ea906Sjfb8856606 		struct test_op_params *op_params)
2255*d30ea906Sjfb8856606 {
2256*d30ea906Sjfb8856606 #ifndef RTE_BBDEV_OFFLOAD_COST
2257*d30ea906Sjfb8856606 	RTE_SET_USED(ad);
2258*d30ea906Sjfb8856606 	RTE_SET_USED(op_params);
2259*d30ea906Sjfb8856606 	printf("Offload latency empty dequeue test is disabled.\n");
2260*d30ea906Sjfb8856606 	printf("Set RTE_BBDEV_OFFLOAD_COST to 'y' to turn the test on.\n");
2261*d30ea906Sjfb8856606 	return TEST_SKIPPED;
2262*d30ea906Sjfb8856606 #else
2263*d30ea906Sjfb8856606 	int iter;
2264*d30ea906Sjfb8856606 	uint64_t deq_tot_time, deq_min_time, deq_max_time;
2265*d30ea906Sjfb8856606 	uint16_t burst_sz = op_params->burst_sz;
2266*d30ea906Sjfb8856606 	const uint16_t num_to_process = op_params->num_to_process;
2267*d30ea906Sjfb8856606 	const enum rte_bbdev_op_type op_type = test_vector.op_type;
2268*d30ea906Sjfb8856606 	const uint16_t queue_id = ad->queue_ids[0];
2269*d30ea906Sjfb8856606 	struct rte_bbdev_info info;
2270*d30ea906Sjfb8856606 	const char *op_type_str;
2271*d30ea906Sjfb8856606 
2272*d30ea906Sjfb8856606 	deq_tot_time = deq_max_time = 0;
2273*d30ea906Sjfb8856606 	deq_min_time = UINT64_MAX;
2274*d30ea906Sjfb8856606 
2275*d30ea906Sjfb8856606 	TEST_ASSERT_SUCCESS((burst_sz > MAX_BURST),
2276*d30ea906Sjfb8856606 			"BURST_SIZE should be <= %u", MAX_BURST);
2277*d30ea906Sjfb8856606 
2278*d30ea906Sjfb8856606 	rte_bbdev_info_get(ad->dev_id, &info);
2279*d30ea906Sjfb8856606 
2280*d30ea906Sjfb8856606 	op_type_str = rte_bbdev_op_type_str(op_type);
2281*d30ea906Sjfb8856606 	TEST_ASSERT_NOT_NULL(op_type_str, "Invalid op type: %u", op_type);
2282*d30ea906Sjfb8856606 
2283*d30ea906Sjfb8856606 	printf(
2284*d30ea906Sjfb8856606 		"Offload latency empty dequeue test: dev: %s, burst size: %u, num ops: %u, op type: %s\n",
2285*d30ea906Sjfb8856606 			info.dev_name, burst_sz, num_to_process, op_type_str);
2286*d30ea906Sjfb8856606 
2287*d30ea906Sjfb8856606 	if (op_type == RTE_BBDEV_OP_TURBO_DEC)
2288*d30ea906Sjfb8856606 		iter = offload_latency_empty_q_test_dec(ad->dev_id, queue_id,
2289*d30ea906Sjfb8856606 				num_to_process, burst_sz, &deq_tot_time,
2290*d30ea906Sjfb8856606 				&deq_min_time, &deq_max_time);
2291*d30ea906Sjfb8856606 	else
2292*d30ea906Sjfb8856606 		iter = offload_latency_empty_q_test_enc(ad->dev_id, queue_id,
2293*d30ea906Sjfb8856606 				num_to_process, burst_sz, &deq_tot_time,
2294*d30ea906Sjfb8856606 				&deq_min_time, &deq_max_time);
2295*d30ea906Sjfb8856606 
2296*d30ea906Sjfb8856606 	if (iter <= 0)
2297*d30ea906Sjfb8856606 		return TEST_FAILED;
2298*d30ea906Sjfb8856606 
2299*d30ea906Sjfb8856606 	printf("\tempty deq offload\n"
2300*d30ea906Sjfb8856606 			"\t\tavg. latency: %lg cycles, %lg us\n"
2301*d30ea906Sjfb8856606 			"\t\tmin. latency: %lg cycles, %lg us\n"
2302*d30ea906Sjfb8856606 			"\t\tmax. latency: %lg cycles, %lg us\n",
2303*d30ea906Sjfb8856606 			(double)deq_tot_time / (double)iter,
2304*d30ea906Sjfb8856606 			(double)(deq_tot_time * 1000000) / (double)iter /
2305*d30ea906Sjfb8856606 			(double)rte_get_tsc_hz(), (double)deq_min_time,
2306*d30ea906Sjfb8856606 			(double)(deq_min_time * 1000000) / rte_get_tsc_hz(),
2307*d30ea906Sjfb8856606 			(double)deq_max_time, (double)(deq_max_time * 1000000) /
2308*d30ea906Sjfb8856606 			rte_get_tsc_hz());
2309*d30ea906Sjfb8856606 
2310*d30ea906Sjfb8856606 	return TEST_SUCCESS;
2311*d30ea906Sjfb8856606 #endif
2312*d30ea906Sjfb8856606 }
2313*d30ea906Sjfb8856606 
2314*d30ea906Sjfb8856606 static int
2315*d30ea906Sjfb8856606 throughput_tc(void)
2316*d30ea906Sjfb8856606 {
2317*d30ea906Sjfb8856606 	return run_test_case(throughput_test);
2318*d30ea906Sjfb8856606 }
2319*d30ea906Sjfb8856606 
2320*d30ea906Sjfb8856606 static int
2321*d30ea906Sjfb8856606 offload_cost_tc(void)
2322*d30ea906Sjfb8856606 {
2323*d30ea906Sjfb8856606 	return run_test_case(offload_cost_test);
2324*d30ea906Sjfb8856606 }
2325*d30ea906Sjfb8856606 
2326*d30ea906Sjfb8856606 static int
2327*d30ea906Sjfb8856606 offload_latency_empty_q_tc(void)
2328*d30ea906Sjfb8856606 {
2329*d30ea906Sjfb8856606 	return run_test_case(offload_latency_empty_q_test);
2330*d30ea906Sjfb8856606 }
2331*d30ea906Sjfb8856606 
2332*d30ea906Sjfb8856606 static int
2333*d30ea906Sjfb8856606 latency_tc(void)
2334*d30ea906Sjfb8856606 {
2335*d30ea906Sjfb8856606 	return run_test_case(latency_test);
2336*d30ea906Sjfb8856606 }
2337*d30ea906Sjfb8856606 
2338*d30ea906Sjfb8856606 static int
2339*d30ea906Sjfb8856606 interrupt_tc(void)
2340*d30ea906Sjfb8856606 {
2341*d30ea906Sjfb8856606 	return run_test_case(throughput_test);
2342*d30ea906Sjfb8856606 }
2343*d30ea906Sjfb8856606 
2344*d30ea906Sjfb8856606 static struct unit_test_suite bbdev_throughput_testsuite = {
2345*d30ea906Sjfb8856606 	.suite_name = "BBdev Throughput Tests",
2346*d30ea906Sjfb8856606 	.setup = testsuite_setup,
2347*d30ea906Sjfb8856606 	.teardown = testsuite_teardown,
2348*d30ea906Sjfb8856606 	.unit_test_cases = {
2349*d30ea906Sjfb8856606 		TEST_CASE_ST(ut_setup, ut_teardown, throughput_tc),
2350*d30ea906Sjfb8856606 		TEST_CASES_END() /**< NULL terminate unit test array */
2351*d30ea906Sjfb8856606 	}
2352*d30ea906Sjfb8856606 };
2353*d30ea906Sjfb8856606 
2354*d30ea906Sjfb8856606 static struct unit_test_suite bbdev_validation_testsuite = {
2355*d30ea906Sjfb8856606 	.suite_name = "BBdev Validation Tests",
2356*d30ea906Sjfb8856606 	.setup = testsuite_setup,
2357*d30ea906Sjfb8856606 	.teardown = testsuite_teardown,
2358*d30ea906Sjfb8856606 	.unit_test_cases = {
2359*d30ea906Sjfb8856606 		TEST_CASE_ST(ut_setup, ut_teardown, latency_tc),
2360*d30ea906Sjfb8856606 		TEST_CASES_END() /**< NULL terminate unit test array */
2361*d30ea906Sjfb8856606 	}
2362*d30ea906Sjfb8856606 };
2363*d30ea906Sjfb8856606 
2364*d30ea906Sjfb8856606 static struct unit_test_suite bbdev_latency_testsuite = {
2365*d30ea906Sjfb8856606 	.suite_name = "BBdev Latency Tests",
2366*d30ea906Sjfb8856606 	.setup = testsuite_setup,
2367*d30ea906Sjfb8856606 	.teardown = testsuite_teardown,
2368*d30ea906Sjfb8856606 	.unit_test_cases = {
2369*d30ea906Sjfb8856606 		TEST_CASE_ST(ut_setup, ut_teardown, latency_tc),
2370*d30ea906Sjfb8856606 		TEST_CASES_END() /**< NULL terminate unit test array */
2371*d30ea906Sjfb8856606 	}
2372*d30ea906Sjfb8856606 };
2373*d30ea906Sjfb8856606 
2374*d30ea906Sjfb8856606 static struct unit_test_suite bbdev_offload_cost_testsuite = {
2375*d30ea906Sjfb8856606 	.suite_name = "BBdev Offload Cost Tests",
2376*d30ea906Sjfb8856606 	.setup = testsuite_setup,
2377*d30ea906Sjfb8856606 	.teardown = testsuite_teardown,
2378*d30ea906Sjfb8856606 	.unit_test_cases = {
2379*d30ea906Sjfb8856606 		TEST_CASE_ST(ut_setup, ut_teardown, offload_cost_tc),
2380*d30ea906Sjfb8856606 		TEST_CASE_ST(ut_setup, ut_teardown, offload_latency_empty_q_tc),
2381*d30ea906Sjfb8856606 		TEST_CASES_END() /**< NULL terminate unit test array */
2382*d30ea906Sjfb8856606 	}
2383*d30ea906Sjfb8856606 };
2384*d30ea906Sjfb8856606 
2385*d30ea906Sjfb8856606 static struct unit_test_suite bbdev_interrupt_testsuite = {
2386*d30ea906Sjfb8856606 	.suite_name = "BBdev Interrupt Tests",
2387*d30ea906Sjfb8856606 	.setup = interrupt_testsuite_setup,
2388*d30ea906Sjfb8856606 	.teardown = testsuite_teardown,
2389*d30ea906Sjfb8856606 	.unit_test_cases = {
2390*d30ea906Sjfb8856606 		TEST_CASE_ST(ut_setup, ut_teardown, interrupt_tc),
2391*d30ea906Sjfb8856606 		TEST_CASES_END() /**< NULL terminate unit test array */
2392*d30ea906Sjfb8856606 	}
2393*d30ea906Sjfb8856606 };
2394*d30ea906Sjfb8856606 
2395*d30ea906Sjfb8856606 REGISTER_TEST_COMMAND(throughput, bbdev_throughput_testsuite);
2396*d30ea906Sjfb8856606 REGISTER_TEST_COMMAND(validation, bbdev_validation_testsuite);
2397*d30ea906Sjfb8856606 REGISTER_TEST_COMMAND(latency, bbdev_latency_testsuite);
2398*d30ea906Sjfb8856606 REGISTER_TEST_COMMAND(offload, bbdev_offload_cost_testsuite);
2399*d30ea906Sjfb8856606 REGISTER_TEST_COMMAND(interrupt, bbdev_interrupt_testsuite);
2400