xref: /dpdk/examples/bbdev_app/main.c (revision 1ffee690eaa10b1b50deb230755ea4ceaa373e0f)
1*1ffee690SAmr Mokhtar /* SPDX-License-Identifier: BSD-3-Clause
2*1ffee690SAmr Mokhtar  * Copyright(c) 2017 Intel Corporation
3*1ffee690SAmr Mokhtar  */
4*1ffee690SAmr Mokhtar 
5*1ffee690SAmr Mokhtar #include <stdio.h>
6*1ffee690SAmr Mokhtar #include <stdlib.h>
7*1ffee690SAmr Mokhtar #include <string.h>
8*1ffee690SAmr Mokhtar #include <stdint.h>
9*1ffee690SAmr Mokhtar #include <inttypes.h>
10*1ffee690SAmr Mokhtar #include <sys/types.h>
11*1ffee690SAmr Mokhtar #include <sys/unistd.h>
12*1ffee690SAmr Mokhtar #include <sys/queue.h>
13*1ffee690SAmr Mokhtar #include <stdarg.h>
14*1ffee690SAmr Mokhtar #include <ctype.h>
15*1ffee690SAmr Mokhtar #include <errno.h>
16*1ffee690SAmr Mokhtar #include <math.h>
17*1ffee690SAmr Mokhtar #include <assert.h>
18*1ffee690SAmr Mokhtar #include <getopt.h>
19*1ffee690SAmr Mokhtar #include <signal.h>
20*1ffee690SAmr Mokhtar 
21*1ffee690SAmr Mokhtar #include "rte_atomic.h"
22*1ffee690SAmr Mokhtar #include "rte_common.h"
23*1ffee690SAmr Mokhtar #include "rte_eal.h"
24*1ffee690SAmr Mokhtar #include "rte_cycles.h"
25*1ffee690SAmr Mokhtar #include "rte_ether.h"
26*1ffee690SAmr Mokhtar #include "rte_ethdev.h"
27*1ffee690SAmr Mokhtar #include "rte_ip.h"
28*1ffee690SAmr Mokhtar #include "rte_lcore.h"
29*1ffee690SAmr Mokhtar #include "rte_malloc.h"
30*1ffee690SAmr Mokhtar #include "rte_mbuf.h"
31*1ffee690SAmr Mokhtar #include "rte_memory.h"
32*1ffee690SAmr Mokhtar #include "rte_mempool.h"
33*1ffee690SAmr Mokhtar #include "rte_log.h"
34*1ffee690SAmr Mokhtar #include "rte_bbdev.h"
35*1ffee690SAmr Mokhtar #include "rte_bbdev_op.h"
36*1ffee690SAmr Mokhtar 
37*1ffee690SAmr Mokhtar /* LLR values - negative value for '1' bit */
38*1ffee690SAmr Mokhtar #define LLR_1_BIT 0x81
39*1ffee690SAmr Mokhtar #define LLR_0_BIT 0x7F
40*1ffee690SAmr Mokhtar 
41*1ffee690SAmr Mokhtar #define MAX_PKT_BURST 32
42*1ffee690SAmr Mokhtar #define NB_MBUF 8191
43*1ffee690SAmr Mokhtar #define MEMPOOL_CACHE_SIZE 256
44*1ffee690SAmr Mokhtar 
45*1ffee690SAmr Mokhtar /* Hardcoded K value */
46*1ffee690SAmr Mokhtar #define K 40
47*1ffee690SAmr Mokhtar #define NCB (3 * RTE_ALIGN_CEIL(K + 4, 32))
48*1ffee690SAmr Mokhtar 
49*1ffee690SAmr Mokhtar #define CRC_24B_LEN 3
50*1ffee690SAmr Mokhtar 
51*1ffee690SAmr Mokhtar /* Configurable number of RX/TX ring descriptors */
52*1ffee690SAmr Mokhtar #define RTE_TEST_RX_DESC_DEFAULT 128
53*1ffee690SAmr Mokhtar #define RTE_TEST_TX_DESC_DEFAULT 512
54*1ffee690SAmr Mokhtar 
55*1ffee690SAmr Mokhtar #define BBDEV_ASSERT(a) do { \
56*1ffee690SAmr Mokhtar 	if (!(a)) { \
57*1ffee690SAmr Mokhtar 		usage(prgname); \
58*1ffee690SAmr Mokhtar 		return -1; \
59*1ffee690SAmr Mokhtar 	} \
60*1ffee690SAmr Mokhtar } while (0)
61*1ffee690SAmr Mokhtar 
62*1ffee690SAmr Mokhtar static const struct rte_eth_conf port_conf = {
63*1ffee690SAmr Mokhtar 	.rxmode = {
64*1ffee690SAmr Mokhtar 		.mq_mode = ETH_MQ_RX_NONE,
65*1ffee690SAmr Mokhtar 		.max_rx_pkt_len = ETHER_MAX_LEN,
66*1ffee690SAmr Mokhtar 		.split_hdr_size = 0,
67*1ffee690SAmr Mokhtar 		.header_split = 0, /**< Header Split disabled */
68*1ffee690SAmr Mokhtar 		.hw_ip_checksum = 0, /**< IP checksum offload disabled */
69*1ffee690SAmr Mokhtar 		.hw_vlan_filter = 0, /**< VLAN filtering disabled */
70*1ffee690SAmr Mokhtar 		.jumbo_frame = 0, /**< Jumbo Frame Support disabled */
71*1ffee690SAmr Mokhtar 		.hw_strip_crc = 0, /**< CRC stripped by hardware */
72*1ffee690SAmr Mokhtar 	},
73*1ffee690SAmr Mokhtar 	.txmode = {
74*1ffee690SAmr Mokhtar 		.mq_mode = ETH_MQ_TX_NONE,
75*1ffee690SAmr Mokhtar 	},
76*1ffee690SAmr Mokhtar };
77*1ffee690SAmr Mokhtar 
78*1ffee690SAmr Mokhtar struct rte_bbdev_op_turbo_enc def_op_enc = {
79*1ffee690SAmr Mokhtar 	/* These values are arbitrarily put, and does not map to the real
80*1ffee690SAmr Mokhtar 	 * values for the data received from ethdev ports
81*1ffee690SAmr Mokhtar 	 */
82*1ffee690SAmr Mokhtar 	.rv_index = 0,
83*1ffee690SAmr Mokhtar 	.code_block_mode = 1,
84*1ffee690SAmr Mokhtar 	.cb_params = {
85*1ffee690SAmr Mokhtar 		.k = K,
86*1ffee690SAmr Mokhtar 	},
87*1ffee690SAmr Mokhtar 	.op_flags = RTE_BBDEV_TURBO_CRC_24A_ATTACH
88*1ffee690SAmr Mokhtar };
89*1ffee690SAmr Mokhtar 
90*1ffee690SAmr Mokhtar struct rte_bbdev_op_turbo_dec def_op_dec = {
91*1ffee690SAmr Mokhtar 	/* These values are arbitrarily put, and does not map to the real
92*1ffee690SAmr Mokhtar 	 * values for the data received from ethdev ports
93*1ffee690SAmr Mokhtar 	 */
94*1ffee690SAmr Mokhtar 	.code_block_mode = 1,
95*1ffee690SAmr Mokhtar 	.cb_params = {
96*1ffee690SAmr Mokhtar 		.k = K,
97*1ffee690SAmr Mokhtar 	},
98*1ffee690SAmr Mokhtar 	.rv_index = 0,
99*1ffee690SAmr Mokhtar 	.iter_max = 8,
100*1ffee690SAmr Mokhtar 	.iter_min = 4,
101*1ffee690SAmr Mokhtar 	.ext_scale = 15,
102*1ffee690SAmr Mokhtar 	.num_maps = 0,
103*1ffee690SAmr Mokhtar 	.op_flags = RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN
104*1ffee690SAmr Mokhtar };
105*1ffee690SAmr Mokhtar 
106*1ffee690SAmr Mokhtar struct app_config_params {
107*1ffee690SAmr Mokhtar 	/* Placeholders for app params */
108*1ffee690SAmr Mokhtar 	uint16_t port_id;
109*1ffee690SAmr Mokhtar 	uint16_t bbdev_id;
110*1ffee690SAmr Mokhtar 	uint64_t enc_core_mask;
111*1ffee690SAmr Mokhtar 	uint64_t dec_core_mask;
112*1ffee690SAmr Mokhtar 
113*1ffee690SAmr Mokhtar 	/* Values filled during init time */
114*1ffee690SAmr Mokhtar 	uint16_t enc_queue_ids[RTE_MAX_LCORE];
115*1ffee690SAmr Mokhtar 	uint16_t dec_queue_ids[RTE_MAX_LCORE];
116*1ffee690SAmr Mokhtar 	uint16_t num_enc_cores;
117*1ffee690SAmr Mokhtar 	uint16_t num_dec_cores;
118*1ffee690SAmr Mokhtar };
119*1ffee690SAmr Mokhtar 
120*1ffee690SAmr Mokhtar struct lcore_statistics {
121*1ffee690SAmr Mokhtar 	unsigned int enqueued;
122*1ffee690SAmr Mokhtar 	unsigned int dequeued;
123*1ffee690SAmr Mokhtar 	unsigned int rx_lost_packets;
124*1ffee690SAmr Mokhtar 	unsigned int enc_to_dec_lost_packets;
125*1ffee690SAmr Mokhtar 	unsigned int tx_lost_packets;
126*1ffee690SAmr Mokhtar } __rte_cache_aligned;
127*1ffee690SAmr Mokhtar 
128*1ffee690SAmr Mokhtar /** each lcore configuration */
129*1ffee690SAmr Mokhtar struct lcore_conf {
130*1ffee690SAmr Mokhtar 	uint64_t core_type;
131*1ffee690SAmr Mokhtar 
132*1ffee690SAmr Mokhtar 	unsigned int port_id;
133*1ffee690SAmr Mokhtar 	unsigned int rx_queue_id;
134*1ffee690SAmr Mokhtar 	unsigned int tx_queue_id;
135*1ffee690SAmr Mokhtar 
136*1ffee690SAmr Mokhtar 	unsigned int bbdev_id;
137*1ffee690SAmr Mokhtar 	unsigned int enc_queue_id;
138*1ffee690SAmr Mokhtar 	unsigned int dec_queue_id;
139*1ffee690SAmr Mokhtar 
140*1ffee690SAmr Mokhtar 	uint8_t llr_temp_buf[NCB];
141*1ffee690SAmr Mokhtar 
142*1ffee690SAmr Mokhtar 	struct rte_mempool *bbdev_dec_op_pool;
143*1ffee690SAmr Mokhtar 	struct rte_mempool *bbdev_enc_op_pool;
144*1ffee690SAmr Mokhtar 	struct rte_mempool *enc_out_pool;
145*1ffee690SAmr Mokhtar 	struct rte_ring *enc_to_dec_ring;
146*1ffee690SAmr Mokhtar 
147*1ffee690SAmr Mokhtar 	struct lcore_statistics *lcore_stats;
148*1ffee690SAmr Mokhtar } __rte_cache_aligned;
149*1ffee690SAmr Mokhtar 
150*1ffee690SAmr Mokhtar struct stats_lcore_params {
151*1ffee690SAmr Mokhtar 	struct lcore_conf *lconf;
152*1ffee690SAmr Mokhtar 	struct app_config_params *app_params;
153*1ffee690SAmr Mokhtar };
154*1ffee690SAmr Mokhtar 
155*1ffee690SAmr Mokhtar 
156*1ffee690SAmr Mokhtar static const struct app_config_params def_app_config = {
157*1ffee690SAmr Mokhtar 	.port_id = 0,
158*1ffee690SAmr Mokhtar 	.bbdev_id = 0,
159*1ffee690SAmr Mokhtar 	.enc_core_mask = 0x2,
160*1ffee690SAmr Mokhtar 	.dec_core_mask = 0x4,
161*1ffee690SAmr Mokhtar 	.num_enc_cores = 1,
162*1ffee690SAmr Mokhtar 	.num_dec_cores = 1,
163*1ffee690SAmr Mokhtar };
164*1ffee690SAmr Mokhtar 
165*1ffee690SAmr Mokhtar static rte_atomic16_t global_exit_flag;
166*1ffee690SAmr Mokhtar 
167*1ffee690SAmr Mokhtar /* display usage */
168*1ffee690SAmr Mokhtar static inline void
169*1ffee690SAmr Mokhtar usage(const char *prgname)
170*1ffee690SAmr Mokhtar {
171*1ffee690SAmr Mokhtar 	printf("%s [EAL options] "
172*1ffee690SAmr Mokhtar 			"  --\n"
173*1ffee690SAmr Mokhtar 			"  --enc_cores - number of encoding cores (default = 0x2)\n"
174*1ffee690SAmr Mokhtar 			"  --dec_cores - number of decoding cores (default = 0x4)\n"
175*1ffee690SAmr Mokhtar 			"  --port_id - Ethernet port ID (default = 0)\n"
176*1ffee690SAmr Mokhtar 			"  --bbdev_id - BBDev ID (default = 0)\n"
177*1ffee690SAmr Mokhtar 			"\n", prgname);
178*1ffee690SAmr Mokhtar }
179*1ffee690SAmr Mokhtar 
180*1ffee690SAmr Mokhtar /* parse core mask */
181*1ffee690SAmr Mokhtar static inline
182*1ffee690SAmr Mokhtar uint16_t bbdev_parse_mask(const char *mask)
183*1ffee690SAmr Mokhtar {
184*1ffee690SAmr Mokhtar 	char *end = NULL;
185*1ffee690SAmr Mokhtar 	unsigned long pm;
186*1ffee690SAmr Mokhtar 
187*1ffee690SAmr Mokhtar 	/* parse hexadecimal string */
188*1ffee690SAmr Mokhtar 	pm = strtoul(mask, &end, 16);
189*1ffee690SAmr Mokhtar 	if ((mask[0] == '\0') || (end == NULL) || (*end != '\0'))
190*1ffee690SAmr Mokhtar 		return 0;
191*1ffee690SAmr Mokhtar 
192*1ffee690SAmr Mokhtar 	return pm;
193*1ffee690SAmr Mokhtar }
194*1ffee690SAmr Mokhtar 
195*1ffee690SAmr Mokhtar /* parse core mask */
196*1ffee690SAmr Mokhtar static inline
197*1ffee690SAmr Mokhtar uint16_t bbdev_parse_number(const char *mask)
198*1ffee690SAmr Mokhtar {
199*1ffee690SAmr Mokhtar 	char *end = NULL;
200*1ffee690SAmr Mokhtar 	unsigned long pm;
201*1ffee690SAmr Mokhtar 
202*1ffee690SAmr Mokhtar 	/* parse hexadecimal string */
203*1ffee690SAmr Mokhtar 	pm = strtoul(mask, &end, 10);
204*1ffee690SAmr Mokhtar 	if ((mask[0] == '\0') || (end == NULL) || (*end != '\0'))
205*1ffee690SAmr Mokhtar 		return 0;
206*1ffee690SAmr Mokhtar 
207*1ffee690SAmr Mokhtar 	return pm;
208*1ffee690SAmr Mokhtar }
209*1ffee690SAmr Mokhtar 
210*1ffee690SAmr Mokhtar static int
211*1ffee690SAmr Mokhtar bbdev_parse_args(int argc, char **argv,
212*1ffee690SAmr Mokhtar 		struct app_config_params *app_params)
213*1ffee690SAmr Mokhtar {
214*1ffee690SAmr Mokhtar 	int optind = 0;
215*1ffee690SAmr Mokhtar 	int opt;
216*1ffee690SAmr Mokhtar 	int opt_indx = 0;
217*1ffee690SAmr Mokhtar 	char *prgname = argv[0];
218*1ffee690SAmr Mokhtar 
219*1ffee690SAmr Mokhtar 	static struct option lgopts[] = {
220*1ffee690SAmr Mokhtar 		{ "enc_core_mask", required_argument, 0, 'e' },
221*1ffee690SAmr Mokhtar 		{ "dec_core_mask", required_argument, 0, 'd' },
222*1ffee690SAmr Mokhtar 		{ "port_id", required_argument, 0, 'p' },
223*1ffee690SAmr Mokhtar 		{ "bbdev_id", required_argument, 0, 'b' },
224*1ffee690SAmr Mokhtar 		{ NULL, 0, 0, 0 }
225*1ffee690SAmr Mokhtar 	};
226*1ffee690SAmr Mokhtar 
227*1ffee690SAmr Mokhtar 	BBDEV_ASSERT(argc != 0);
228*1ffee690SAmr Mokhtar 	BBDEV_ASSERT(argv != NULL);
229*1ffee690SAmr Mokhtar 	BBDEV_ASSERT(app_params != NULL);
230*1ffee690SAmr Mokhtar 
231*1ffee690SAmr Mokhtar 	while ((opt = getopt_long(argc, argv, "e:d:p:b:", lgopts, &opt_indx)) !=
232*1ffee690SAmr Mokhtar 		EOF) {
233*1ffee690SAmr Mokhtar 		switch (opt) {
234*1ffee690SAmr Mokhtar 		case 'e':
235*1ffee690SAmr Mokhtar 			app_params->enc_core_mask =
236*1ffee690SAmr Mokhtar 				bbdev_parse_mask(optarg);
237*1ffee690SAmr Mokhtar 			if (app_params->enc_core_mask == 0) {
238*1ffee690SAmr Mokhtar 				usage(prgname);
239*1ffee690SAmr Mokhtar 				return -1;
240*1ffee690SAmr Mokhtar 			}
241*1ffee690SAmr Mokhtar 			app_params->num_enc_cores =
242*1ffee690SAmr Mokhtar 				__builtin_popcount(app_params->enc_core_mask);
243*1ffee690SAmr Mokhtar 			break;
244*1ffee690SAmr Mokhtar 
245*1ffee690SAmr Mokhtar 		case 'd':
246*1ffee690SAmr Mokhtar 			app_params->dec_core_mask =
247*1ffee690SAmr Mokhtar 				bbdev_parse_mask(optarg);
248*1ffee690SAmr Mokhtar 			if (app_params->dec_core_mask == 0) {
249*1ffee690SAmr Mokhtar 				usage(prgname);
250*1ffee690SAmr Mokhtar 				return -1;
251*1ffee690SAmr Mokhtar 			}
252*1ffee690SAmr Mokhtar 			app_params->num_dec_cores =
253*1ffee690SAmr Mokhtar 				__builtin_popcount(app_params->dec_core_mask);
254*1ffee690SAmr Mokhtar 			break;
255*1ffee690SAmr Mokhtar 
256*1ffee690SAmr Mokhtar 		case 'p':
257*1ffee690SAmr Mokhtar 			app_params->port_id = bbdev_parse_number(optarg);
258*1ffee690SAmr Mokhtar 			break;
259*1ffee690SAmr Mokhtar 
260*1ffee690SAmr Mokhtar 		case 'b':
261*1ffee690SAmr Mokhtar 			app_params->bbdev_id = bbdev_parse_number(optarg);
262*1ffee690SAmr Mokhtar 			break;
263*1ffee690SAmr Mokhtar 
264*1ffee690SAmr Mokhtar 		default:
265*1ffee690SAmr Mokhtar 			usage(prgname);
266*1ffee690SAmr Mokhtar 			return -1;
267*1ffee690SAmr Mokhtar 		}
268*1ffee690SAmr Mokhtar 	}
269*1ffee690SAmr Mokhtar 	optind = 0;
270*1ffee690SAmr Mokhtar 	return optind;
271*1ffee690SAmr Mokhtar }
272*1ffee690SAmr Mokhtar 
273*1ffee690SAmr Mokhtar static void
274*1ffee690SAmr Mokhtar signal_handler(int signum)
275*1ffee690SAmr Mokhtar {
276*1ffee690SAmr Mokhtar 	printf("\nSignal %d received\n", signum);
277*1ffee690SAmr Mokhtar 	rte_atomic16_set(&global_exit_flag, 1);
278*1ffee690SAmr Mokhtar }
279*1ffee690SAmr Mokhtar 
280*1ffee690SAmr Mokhtar static void
281*1ffee690SAmr Mokhtar print_mac(unsigned int portid, struct ether_addr *bbdev_ports_eth_address)
282*1ffee690SAmr Mokhtar {
283*1ffee690SAmr Mokhtar 	printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n",
284*1ffee690SAmr Mokhtar 			(unsigned int) portid,
285*1ffee690SAmr Mokhtar 			bbdev_ports_eth_address[portid].addr_bytes[0],
286*1ffee690SAmr Mokhtar 			bbdev_ports_eth_address[portid].addr_bytes[1],
287*1ffee690SAmr Mokhtar 			bbdev_ports_eth_address[portid].addr_bytes[2],
288*1ffee690SAmr Mokhtar 			bbdev_ports_eth_address[portid].addr_bytes[3],
289*1ffee690SAmr Mokhtar 			bbdev_ports_eth_address[portid].addr_bytes[4],
290*1ffee690SAmr Mokhtar 			bbdev_ports_eth_address[portid].addr_bytes[5]);
291*1ffee690SAmr Mokhtar }
292*1ffee690SAmr Mokhtar 
293*1ffee690SAmr Mokhtar static inline void
294*1ffee690SAmr Mokhtar pktmbuf_free_bulk(struct rte_mbuf **mbufs, unsigned int nb_to_free)
295*1ffee690SAmr Mokhtar {
296*1ffee690SAmr Mokhtar 	unsigned int i;
297*1ffee690SAmr Mokhtar 	for (i = 0; i < nb_to_free; ++i)
298*1ffee690SAmr Mokhtar 		rte_pktmbuf_free(mbufs[i]);
299*1ffee690SAmr Mokhtar }
300*1ffee690SAmr Mokhtar 
301*1ffee690SAmr Mokhtar static inline void
302*1ffee690SAmr Mokhtar pktmbuf_userdata_free_bulk(struct rte_mbuf **mbufs, unsigned int nb_to_free)
303*1ffee690SAmr Mokhtar {
304*1ffee690SAmr Mokhtar 	unsigned int i;
305*1ffee690SAmr Mokhtar 	for (i = 0; i < nb_to_free; ++i) {
306*1ffee690SAmr Mokhtar 		struct rte_mbuf *rx_pkt = mbufs[i]->userdata;
307*1ffee690SAmr Mokhtar 		rte_pktmbuf_free(rx_pkt);
308*1ffee690SAmr Mokhtar 		rte_pktmbuf_free(mbufs[i]);
309*1ffee690SAmr Mokhtar 	}
310*1ffee690SAmr Mokhtar }
311*1ffee690SAmr Mokhtar 
312*1ffee690SAmr Mokhtar /* Check the link status of all ports in up to 9s, and print them finally */
313*1ffee690SAmr Mokhtar static int
314*1ffee690SAmr Mokhtar check_port_link_status(uint16_t port_id)
315*1ffee690SAmr Mokhtar {
316*1ffee690SAmr Mokhtar #define CHECK_INTERVAL 100 /* 100ms */
317*1ffee690SAmr Mokhtar #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
318*1ffee690SAmr Mokhtar 	uint8_t count;
319*1ffee690SAmr Mokhtar 	struct rte_eth_link link;
320*1ffee690SAmr Mokhtar 
321*1ffee690SAmr Mokhtar 	printf("\nChecking link status.");
322*1ffee690SAmr Mokhtar 	fflush(stdout);
323*1ffee690SAmr Mokhtar 
324*1ffee690SAmr Mokhtar 	for (count = 0; count <= MAX_CHECK_TIME &&
325*1ffee690SAmr Mokhtar 			!rte_atomic16_read(&global_exit_flag); count++) {
326*1ffee690SAmr Mokhtar 		memset(&link, 0, sizeof(link));
327*1ffee690SAmr Mokhtar 		rte_eth_link_get_nowait(port_id, &link);
328*1ffee690SAmr Mokhtar 
329*1ffee690SAmr Mokhtar 		if (link.link_status) {
330*1ffee690SAmr Mokhtar 			const char *dp = (link.link_duplex ==
331*1ffee690SAmr Mokhtar 				ETH_LINK_FULL_DUPLEX) ?
332*1ffee690SAmr Mokhtar 				"full-duplex" : "half-duplex";
333*1ffee690SAmr Mokhtar 			printf("\nPort %u Link Up - speed %u Mbps - %s\n",
334*1ffee690SAmr Mokhtar 				port_id, link.link_speed, dp);
335*1ffee690SAmr Mokhtar 			return 0;
336*1ffee690SAmr Mokhtar 		}
337*1ffee690SAmr Mokhtar 		printf(".");
338*1ffee690SAmr Mokhtar 		fflush(stdout);
339*1ffee690SAmr Mokhtar 		rte_delay_ms(CHECK_INTERVAL);
340*1ffee690SAmr Mokhtar 	}
341*1ffee690SAmr Mokhtar 
342*1ffee690SAmr Mokhtar 	printf("\nPort %d Link Down\n", port_id);
343*1ffee690SAmr Mokhtar 	return 0;
344*1ffee690SAmr Mokhtar }
345*1ffee690SAmr Mokhtar 
346*1ffee690SAmr Mokhtar static inline void
347*1ffee690SAmr Mokhtar add_ether_hdr(struct rte_mbuf *pkt_src, struct rte_mbuf *pkt_dst)
348*1ffee690SAmr Mokhtar {
349*1ffee690SAmr Mokhtar 	struct ether_hdr *eth_from;
350*1ffee690SAmr Mokhtar 	struct ether_hdr *eth_to;
351*1ffee690SAmr Mokhtar 
352*1ffee690SAmr Mokhtar 	eth_from = rte_pktmbuf_mtod(pkt_src, struct ether_hdr *);
353*1ffee690SAmr Mokhtar 	eth_to = rte_pktmbuf_mtod(pkt_dst, struct ether_hdr *);
354*1ffee690SAmr Mokhtar 
355*1ffee690SAmr Mokhtar 	/* copy header */
356*1ffee690SAmr Mokhtar 	rte_memcpy(eth_to, eth_from, sizeof(struct ether_hdr));
357*1ffee690SAmr Mokhtar }
358*1ffee690SAmr Mokhtar 
359*1ffee690SAmr Mokhtar static inline void
360*1ffee690SAmr Mokhtar add_awgn(struct rte_mbuf **mbufs, uint16_t num_pkts)
361*1ffee690SAmr Mokhtar {
362*1ffee690SAmr Mokhtar 	RTE_SET_USED(mbufs);
363*1ffee690SAmr Mokhtar 	RTE_SET_USED(num_pkts);
364*1ffee690SAmr Mokhtar }
365*1ffee690SAmr Mokhtar 
366*1ffee690SAmr Mokhtar /* Encoder output to Decoder input adapter. The Decoder accepts only soft input
367*1ffee690SAmr Mokhtar  * so each bit of the encoder output must be translated into one byte of LLR. If
368*1ffee690SAmr Mokhtar  * Sub-block Deinterleaver is bypassed, which is the case, the padding bytes
369*1ffee690SAmr Mokhtar  * must additionally be insterted at the end of each sub-block.
370*1ffee690SAmr Mokhtar  */
371*1ffee690SAmr Mokhtar static inline void
372*1ffee690SAmr Mokhtar transform_enc_out_dec_in(struct rte_mbuf **mbufs, uint8_t *temp_buf,
373*1ffee690SAmr Mokhtar 		uint16_t num_pkts, uint16_t k)
374*1ffee690SAmr Mokhtar {
375*1ffee690SAmr Mokhtar 	uint16_t i, l, j;
376*1ffee690SAmr Mokhtar 	uint16_t start_bit_idx;
377*1ffee690SAmr Mokhtar 	uint16_t out_idx;
378*1ffee690SAmr Mokhtar 	uint16_t d = k + 4;
379*1ffee690SAmr Mokhtar 	uint16_t kpi = RTE_ALIGN_CEIL(d, 32);
380*1ffee690SAmr Mokhtar 	uint16_t nd = kpi - d;
381*1ffee690SAmr Mokhtar 	uint16_t ncb = 3 * kpi;
382*1ffee690SAmr Mokhtar 
383*1ffee690SAmr Mokhtar 	for (i = 0; i < num_pkts; ++i) {
384*1ffee690SAmr Mokhtar 		uint16_t pkt_data_len = rte_pktmbuf_data_len(mbufs[i]) -
385*1ffee690SAmr Mokhtar 				sizeof(struct ether_hdr);
386*1ffee690SAmr Mokhtar 
387*1ffee690SAmr Mokhtar 		/* Resize the packet if needed */
388*1ffee690SAmr Mokhtar 		if (pkt_data_len < ncb) {
389*1ffee690SAmr Mokhtar 			char *data = rte_pktmbuf_append(mbufs[i],
390*1ffee690SAmr Mokhtar 					ncb - pkt_data_len);
391*1ffee690SAmr Mokhtar 			if (data == NULL)
392*1ffee690SAmr Mokhtar 				printf(
393*1ffee690SAmr Mokhtar 					"Not enough space in decoder input packet");
394*1ffee690SAmr Mokhtar 		}
395*1ffee690SAmr Mokhtar 
396*1ffee690SAmr Mokhtar 		/* Translate each bit into 1 LLR byte. */
397*1ffee690SAmr Mokhtar 		start_bit_idx = 0;
398*1ffee690SAmr Mokhtar 		out_idx = 0;
399*1ffee690SAmr Mokhtar 		for (j = 0; j < 3; ++j) {
400*1ffee690SAmr Mokhtar 			for (l = start_bit_idx; l < start_bit_idx + d; ++l) {
401*1ffee690SAmr Mokhtar 				uint8_t *data = rte_pktmbuf_mtod_offset(
402*1ffee690SAmr Mokhtar 					mbufs[i], uint8_t *,
403*1ffee690SAmr Mokhtar 					sizeof(struct ether_hdr) + (l >> 3));
404*1ffee690SAmr Mokhtar 				if (*data & (0x80 >> (l & 7)))
405*1ffee690SAmr Mokhtar 					temp_buf[out_idx] = LLR_1_BIT;
406*1ffee690SAmr Mokhtar 				else
407*1ffee690SAmr Mokhtar 					temp_buf[out_idx] = LLR_0_BIT;
408*1ffee690SAmr Mokhtar 				++out_idx;
409*1ffee690SAmr Mokhtar 			}
410*1ffee690SAmr Mokhtar 			/* Padding bytes should be at the end of the sub-block.
411*1ffee690SAmr Mokhtar 			 */
412*1ffee690SAmr Mokhtar 			memset(&temp_buf[out_idx], 0, nd);
413*1ffee690SAmr Mokhtar 			out_idx += nd;
414*1ffee690SAmr Mokhtar 			start_bit_idx += d;
415*1ffee690SAmr Mokhtar 		}
416*1ffee690SAmr Mokhtar 
417*1ffee690SAmr Mokhtar 		rte_memcpy(rte_pktmbuf_mtod_offset(mbufs[i], uint8_t *,
418*1ffee690SAmr Mokhtar 				sizeof(struct ether_hdr)), temp_buf, ncb);
419*1ffee690SAmr Mokhtar 	}
420*1ffee690SAmr Mokhtar }
421*1ffee690SAmr Mokhtar 
422*1ffee690SAmr Mokhtar static inline void
423*1ffee690SAmr Mokhtar verify_data(struct rte_mbuf **mbufs, uint16_t num_pkts)
424*1ffee690SAmr Mokhtar {
425*1ffee690SAmr Mokhtar 	uint16_t i;
426*1ffee690SAmr Mokhtar 	for (i = 0; i < num_pkts; ++i) {
427*1ffee690SAmr Mokhtar 		struct rte_mbuf *out = mbufs[i];
428*1ffee690SAmr Mokhtar 		struct rte_mbuf *in = out->userdata;
429*1ffee690SAmr Mokhtar 
430*1ffee690SAmr Mokhtar 		if (memcmp(rte_pktmbuf_mtod_offset(in, uint8_t *,
431*1ffee690SAmr Mokhtar 				sizeof(struct ether_hdr)),
432*1ffee690SAmr Mokhtar 				rte_pktmbuf_mtod_offset(out, uint8_t *,
433*1ffee690SAmr Mokhtar 				sizeof(struct ether_hdr)),
434*1ffee690SAmr Mokhtar 				K / 8 - CRC_24B_LEN))
435*1ffee690SAmr Mokhtar 			printf("Input and output buffers are not equal!\n");
436*1ffee690SAmr Mokhtar 	}
437*1ffee690SAmr Mokhtar }
438*1ffee690SAmr Mokhtar 
439*1ffee690SAmr Mokhtar static int
440*1ffee690SAmr Mokhtar initialize_ports(struct app_config_params *app_params,
441*1ffee690SAmr Mokhtar 		struct rte_mempool *ethdev_mbuf_mempool)
442*1ffee690SAmr Mokhtar {
443*1ffee690SAmr Mokhtar 	int ret;
444*1ffee690SAmr Mokhtar 	uint16_t port_id = app_params->port_id;
445*1ffee690SAmr Mokhtar 	uint16_t q;
446*1ffee690SAmr Mokhtar 	/* ethernet addresses of ports */
447*1ffee690SAmr Mokhtar 	struct ether_addr bbdev_port_eth_addr;
448*1ffee690SAmr Mokhtar 
449*1ffee690SAmr Mokhtar 	/* initialize ports */
450*1ffee690SAmr Mokhtar 	printf("\nInitializing port %u...\n", app_params->port_id);
451*1ffee690SAmr Mokhtar 	ret = rte_eth_dev_configure(port_id, app_params->num_enc_cores,
452*1ffee690SAmr Mokhtar 		app_params->num_dec_cores, &port_conf);
453*1ffee690SAmr Mokhtar 
454*1ffee690SAmr Mokhtar 	if (ret < 0) {
455*1ffee690SAmr Mokhtar 		printf("Cannot configure device: err=%d, port=%u\n",
456*1ffee690SAmr Mokhtar 			ret, port_id);
457*1ffee690SAmr Mokhtar 		return -1;
458*1ffee690SAmr Mokhtar 	}
459*1ffee690SAmr Mokhtar 
460*1ffee690SAmr Mokhtar 	/* initialize RX queues for encoder */
461*1ffee690SAmr Mokhtar 	for (q = 0; q < app_params->num_enc_cores; q++) {
462*1ffee690SAmr Mokhtar 		ret = rte_eth_rx_queue_setup(port_id, q,
463*1ffee690SAmr Mokhtar 			RTE_TEST_RX_DESC_DEFAULT,
464*1ffee690SAmr Mokhtar 			rte_eth_dev_socket_id(port_id),
465*1ffee690SAmr Mokhtar 			NULL, ethdev_mbuf_mempool);
466*1ffee690SAmr Mokhtar 		if (ret < 0) {
467*1ffee690SAmr Mokhtar 			printf("rte_eth_rx_queue_setup: err=%d, queue=%u\n",
468*1ffee690SAmr Mokhtar 				ret, q);
469*1ffee690SAmr Mokhtar 			return -1;
470*1ffee690SAmr Mokhtar 		}
471*1ffee690SAmr Mokhtar 	}
472*1ffee690SAmr Mokhtar 	/* initialize TX queues for decoder */
473*1ffee690SAmr Mokhtar 	for (q = 0; q < app_params->num_dec_cores; q++) {
474*1ffee690SAmr Mokhtar 		ret = rte_eth_tx_queue_setup(port_id, q,
475*1ffee690SAmr Mokhtar 			RTE_TEST_TX_DESC_DEFAULT,
476*1ffee690SAmr Mokhtar 			rte_eth_dev_socket_id(port_id), NULL);
477*1ffee690SAmr Mokhtar 		if (ret < 0) {
478*1ffee690SAmr Mokhtar 			printf("rte_eth_tx_queue_setup: err=%d, queue=%u\n",
479*1ffee690SAmr Mokhtar 				ret, q);
480*1ffee690SAmr Mokhtar 			return -1;
481*1ffee690SAmr Mokhtar 		}
482*1ffee690SAmr Mokhtar 	}
483*1ffee690SAmr Mokhtar 
484*1ffee690SAmr Mokhtar 	rte_eth_promiscuous_enable(port_id);
485*1ffee690SAmr Mokhtar 
486*1ffee690SAmr Mokhtar 	rte_eth_macaddr_get(port_id, &bbdev_port_eth_addr);
487*1ffee690SAmr Mokhtar 	print_mac(port_id, &bbdev_port_eth_addr);
488*1ffee690SAmr Mokhtar 
489*1ffee690SAmr Mokhtar 	return 0;
490*1ffee690SAmr Mokhtar }
491*1ffee690SAmr Mokhtar 
492*1ffee690SAmr Mokhtar static void
493*1ffee690SAmr Mokhtar lcore_conf_init(struct app_config_params *app_params,
494*1ffee690SAmr Mokhtar 		struct lcore_conf *lcore_conf,
495*1ffee690SAmr Mokhtar 		struct rte_mempool **bbdev_op_pools,
496*1ffee690SAmr Mokhtar 		struct rte_mempool *bbdev_mbuf_mempool,
497*1ffee690SAmr Mokhtar 		struct rte_ring *enc_to_dec_ring,
498*1ffee690SAmr Mokhtar 		struct lcore_statistics *lcore_stats)
499*1ffee690SAmr Mokhtar {
500*1ffee690SAmr Mokhtar 	unsigned int lcore_id;
501*1ffee690SAmr Mokhtar 	struct lcore_conf *lconf;
502*1ffee690SAmr Mokhtar 	uint16_t rx_queue_id = 0;
503*1ffee690SAmr Mokhtar 	uint16_t tx_queue_id = 0;
504*1ffee690SAmr Mokhtar 	uint16_t enc_q_id = 0;
505*1ffee690SAmr Mokhtar 	uint16_t dec_q_id = 0;
506*1ffee690SAmr Mokhtar 
507*1ffee690SAmr Mokhtar 	/* Configure lcores */
508*1ffee690SAmr Mokhtar 	for (lcore_id = 0; lcore_id < 8 * sizeof(uint64_t); ++lcore_id) {
509*1ffee690SAmr Mokhtar 		lconf = &lcore_conf[lcore_id];
510*1ffee690SAmr Mokhtar 		lconf->core_type = 0;
511*1ffee690SAmr Mokhtar 
512*1ffee690SAmr Mokhtar 		if ((1ULL << lcore_id) & app_params->enc_core_mask) {
513*1ffee690SAmr Mokhtar 			lconf->core_type |= (1 << RTE_BBDEV_OP_TURBO_ENC);
514*1ffee690SAmr Mokhtar 			lconf->rx_queue_id = rx_queue_id++;
515*1ffee690SAmr Mokhtar 			lconf->enc_queue_id =
516*1ffee690SAmr Mokhtar 					app_params->enc_queue_ids[enc_q_id++];
517*1ffee690SAmr Mokhtar 		}
518*1ffee690SAmr Mokhtar 
519*1ffee690SAmr Mokhtar 		if ((1ULL << lcore_id) & app_params->dec_core_mask) {
520*1ffee690SAmr Mokhtar 			lconf->core_type |= (1 << RTE_BBDEV_OP_TURBO_DEC);
521*1ffee690SAmr Mokhtar 			lconf->tx_queue_id = tx_queue_id++;
522*1ffee690SAmr Mokhtar 			lconf->dec_queue_id =
523*1ffee690SAmr Mokhtar 					app_params->dec_queue_ids[dec_q_id++];
524*1ffee690SAmr Mokhtar 		}
525*1ffee690SAmr Mokhtar 
526*1ffee690SAmr Mokhtar 		lconf->bbdev_enc_op_pool =
527*1ffee690SAmr Mokhtar 				bbdev_op_pools[RTE_BBDEV_OP_TURBO_ENC];
528*1ffee690SAmr Mokhtar 		lconf->bbdev_dec_op_pool =
529*1ffee690SAmr Mokhtar 				bbdev_op_pools[RTE_BBDEV_OP_TURBO_DEC];
530*1ffee690SAmr Mokhtar 		lconf->bbdev_id = app_params->bbdev_id;
531*1ffee690SAmr Mokhtar 		lconf->port_id = app_params->port_id;
532*1ffee690SAmr Mokhtar 		lconf->enc_out_pool = bbdev_mbuf_mempool;
533*1ffee690SAmr Mokhtar 		lconf->enc_to_dec_ring = enc_to_dec_ring;
534*1ffee690SAmr Mokhtar 		lconf->lcore_stats = &lcore_stats[lcore_id];
535*1ffee690SAmr Mokhtar 	}
536*1ffee690SAmr Mokhtar }
537*1ffee690SAmr Mokhtar 
538*1ffee690SAmr Mokhtar static void
539*1ffee690SAmr Mokhtar print_lcore_stats(struct lcore_statistics *lstats, unsigned int lcore_id)
540*1ffee690SAmr Mokhtar {
541*1ffee690SAmr Mokhtar 	static const char *stats_border = "_______";
542*1ffee690SAmr Mokhtar 
543*1ffee690SAmr Mokhtar 	printf("\nLcore %d: %s enqueued count:\t\t%u\n",
544*1ffee690SAmr Mokhtar 			lcore_id, stats_border, lstats->enqueued);
545*1ffee690SAmr Mokhtar 	printf("Lcore %d: %s dequeued count:\t\t%u\n",
546*1ffee690SAmr Mokhtar 			lcore_id, stats_border, lstats->dequeued);
547*1ffee690SAmr Mokhtar 	printf("Lcore %d: %s RX lost packets count:\t\t%u\n",
548*1ffee690SAmr Mokhtar 			lcore_id, stats_border, lstats->rx_lost_packets);
549*1ffee690SAmr Mokhtar 	printf("Lcore %d: %s encoder-to-decoder lost count:\t%u\n",
550*1ffee690SAmr Mokhtar 			lcore_id, stats_border,
551*1ffee690SAmr Mokhtar 			lstats->enc_to_dec_lost_packets);
552*1ffee690SAmr Mokhtar 	printf("Lcore %d: %s TX lost packets count:\t\t%u\n",
553*1ffee690SAmr Mokhtar 			lcore_id, stats_border, lstats->tx_lost_packets);
554*1ffee690SAmr Mokhtar }
555*1ffee690SAmr Mokhtar 
556*1ffee690SAmr Mokhtar static void
557*1ffee690SAmr Mokhtar print_stats(struct stats_lcore_params *stats_lcore)
558*1ffee690SAmr Mokhtar {
559*1ffee690SAmr Mokhtar 	unsigned int l_id;
560*1ffee690SAmr Mokhtar 	unsigned int bbdev_id = stats_lcore->app_params->bbdev_id;
561*1ffee690SAmr Mokhtar 	unsigned int port_id = stats_lcore->app_params->port_id;
562*1ffee690SAmr Mokhtar 	int len, ret, i;
563*1ffee690SAmr Mokhtar 
564*1ffee690SAmr Mokhtar 	struct rte_eth_xstat *xstats;
565*1ffee690SAmr Mokhtar 	struct rte_eth_xstat_name *xstats_names;
566*1ffee690SAmr Mokhtar 	struct rte_bbdev_stats bbstats;
567*1ffee690SAmr Mokhtar 	static const char *stats_border = "_______";
568*1ffee690SAmr Mokhtar 
569*1ffee690SAmr Mokhtar 	const char clr[] = { 27, '[', '2', 'J', '\0' };
570*1ffee690SAmr Mokhtar 	const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' };
571*1ffee690SAmr Mokhtar 
572*1ffee690SAmr Mokhtar 	/* Clear screen and move to top left */
573*1ffee690SAmr Mokhtar 	printf("%s%s", clr, topLeft);
574*1ffee690SAmr Mokhtar 
575*1ffee690SAmr Mokhtar 	printf("PORT STATISTICS:\n================\n");
576*1ffee690SAmr Mokhtar 	len = rte_eth_xstats_get(port_id, NULL, 0);
577*1ffee690SAmr Mokhtar 	if (len < 0)
578*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE,
579*1ffee690SAmr Mokhtar 				"rte_eth_xstats_get(%u) failed: %d", port_id,
580*1ffee690SAmr Mokhtar 				len);
581*1ffee690SAmr Mokhtar 
582*1ffee690SAmr Mokhtar 	xstats = calloc(len, sizeof(*xstats));
583*1ffee690SAmr Mokhtar 	if (xstats == NULL)
584*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE,
585*1ffee690SAmr Mokhtar 				"Failed to calloc memory for xstats");
586*1ffee690SAmr Mokhtar 
587*1ffee690SAmr Mokhtar 	ret = rte_eth_xstats_get(port_id, xstats, len);
588*1ffee690SAmr Mokhtar 	if (ret < 0 || ret > len)
589*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE,
590*1ffee690SAmr Mokhtar 				"rte_eth_xstats_get(%u) len%i failed: %d",
591*1ffee690SAmr Mokhtar 				port_id, len, ret);
592*1ffee690SAmr Mokhtar 
593*1ffee690SAmr Mokhtar 	xstats_names = calloc(len, sizeof(*xstats_names));
594*1ffee690SAmr Mokhtar 	if (xstats_names == NULL)
595*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE,
596*1ffee690SAmr Mokhtar 				"Failed to calloc memory for xstats_names");
597*1ffee690SAmr Mokhtar 
598*1ffee690SAmr Mokhtar 	ret = rte_eth_xstats_get_names(port_id, xstats_names, len);
599*1ffee690SAmr Mokhtar 	if (ret < 0 || ret > len)
600*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE,
601*1ffee690SAmr Mokhtar 				"rte_eth_xstats_get_names(%u) len%i failed: %d",
602*1ffee690SAmr Mokhtar 				port_id, len, ret);
603*1ffee690SAmr Mokhtar 
604*1ffee690SAmr Mokhtar 	for (i = 0; i < len; i++) {
605*1ffee690SAmr Mokhtar 		if (xstats[i].value > 0)
606*1ffee690SAmr Mokhtar 			printf("Port %u: %s %s:\t\t%"PRIu64"\n",
607*1ffee690SAmr Mokhtar 					port_id, stats_border,
608*1ffee690SAmr Mokhtar 					xstats_names[i].name,
609*1ffee690SAmr Mokhtar 					xstats[i].value);
610*1ffee690SAmr Mokhtar 	}
611*1ffee690SAmr Mokhtar 
612*1ffee690SAmr Mokhtar 	printf("\nBBDEV STATISTICS:\n=================\n");
613*1ffee690SAmr Mokhtar 	rte_bbdev_stats_get(bbdev_id, &bbstats);
614*1ffee690SAmr Mokhtar 	printf("BBDEV %u: %s enqueue count:\t\t%"PRIu64"\n",
615*1ffee690SAmr Mokhtar 			bbdev_id, stats_border,
616*1ffee690SAmr Mokhtar 			bbstats.enqueued_count);
617*1ffee690SAmr Mokhtar 	printf("BBDEV %u: %s dequeue count:\t\t%"PRIu64"\n",
618*1ffee690SAmr Mokhtar 			bbdev_id, stats_border,
619*1ffee690SAmr Mokhtar 			bbstats.dequeued_count);
620*1ffee690SAmr Mokhtar 	printf("BBDEV %u: %s enqueue error count:\t\t%"PRIu64"\n",
621*1ffee690SAmr Mokhtar 			bbdev_id, stats_border,
622*1ffee690SAmr Mokhtar 			bbstats.enqueue_err_count);
623*1ffee690SAmr Mokhtar 	printf("BBDEV %u: %s dequeue error count:\t\t%"PRIu64"\n\n",
624*1ffee690SAmr Mokhtar 			bbdev_id, stats_border,
625*1ffee690SAmr Mokhtar 			bbstats.dequeue_err_count);
626*1ffee690SAmr Mokhtar 
627*1ffee690SAmr Mokhtar 	printf("LCORE STATISTICS:\n=================\n");
628*1ffee690SAmr Mokhtar 	for (l_id = 0; l_id < RTE_MAX_LCORE; ++l_id) {
629*1ffee690SAmr Mokhtar 		if (stats_lcore->lconf[l_id].core_type == 0)
630*1ffee690SAmr Mokhtar 			continue;
631*1ffee690SAmr Mokhtar 		print_lcore_stats(stats_lcore->lconf[l_id].lcore_stats, l_id);
632*1ffee690SAmr Mokhtar 	}
633*1ffee690SAmr Mokhtar }
634*1ffee690SAmr Mokhtar 
635*1ffee690SAmr Mokhtar static int
636*1ffee690SAmr Mokhtar stats_loop(void *arg)
637*1ffee690SAmr Mokhtar {
638*1ffee690SAmr Mokhtar 	struct stats_lcore_params *stats_lcore = arg;
639*1ffee690SAmr Mokhtar 
640*1ffee690SAmr Mokhtar 	while (!rte_atomic16_read(&global_exit_flag)) {
641*1ffee690SAmr Mokhtar 		print_stats(stats_lcore);
642*1ffee690SAmr Mokhtar 		rte_delay_ms(500);
643*1ffee690SAmr Mokhtar 	}
644*1ffee690SAmr Mokhtar 
645*1ffee690SAmr Mokhtar 	return 0;
646*1ffee690SAmr Mokhtar }
647*1ffee690SAmr Mokhtar 
648*1ffee690SAmr Mokhtar static inline void
649*1ffee690SAmr Mokhtar run_encoding(struct lcore_conf *lcore_conf)
650*1ffee690SAmr Mokhtar {
651*1ffee690SAmr Mokhtar 	uint16_t i;
652*1ffee690SAmr Mokhtar 	uint16_t port_id, rx_queue_id;
653*1ffee690SAmr Mokhtar 	uint16_t bbdev_id, enc_queue_id;
654*1ffee690SAmr Mokhtar 	uint16_t nb_rx, nb_enq, nb_deq, nb_sent;
655*1ffee690SAmr Mokhtar 	struct rte_mbuf *rx_pkts_burst[MAX_PKT_BURST];
656*1ffee690SAmr Mokhtar 	struct rte_mbuf *enc_out_pkts[MAX_PKT_BURST];
657*1ffee690SAmr Mokhtar 	struct rte_bbdev_enc_op *bbdev_ops_burst[MAX_PKT_BURST];
658*1ffee690SAmr Mokhtar 	struct lcore_statistics *lcore_stats;
659*1ffee690SAmr Mokhtar 	struct rte_mempool *bbdev_op_pool, *enc_out_pool;
660*1ffee690SAmr Mokhtar 	struct rte_ring *enc_to_dec_ring;
661*1ffee690SAmr Mokhtar 	const int in_data_len = (def_op_enc.cb_params.k / 8) - CRC_24B_LEN;
662*1ffee690SAmr Mokhtar 
663*1ffee690SAmr Mokhtar 	lcore_stats = lcore_conf->lcore_stats;
664*1ffee690SAmr Mokhtar 	port_id = lcore_conf->port_id;
665*1ffee690SAmr Mokhtar 	rx_queue_id = lcore_conf->rx_queue_id;
666*1ffee690SAmr Mokhtar 	bbdev_id = lcore_conf->bbdev_id;
667*1ffee690SAmr Mokhtar 	enc_queue_id = lcore_conf->enc_queue_id;
668*1ffee690SAmr Mokhtar 	bbdev_op_pool = lcore_conf->bbdev_enc_op_pool;
669*1ffee690SAmr Mokhtar 	enc_out_pool = lcore_conf->enc_out_pool;
670*1ffee690SAmr Mokhtar 	enc_to_dec_ring = lcore_conf->enc_to_dec_ring;
671*1ffee690SAmr Mokhtar 
672*1ffee690SAmr Mokhtar 	/* Read packet from RX queues*/
673*1ffee690SAmr Mokhtar 	nb_rx = rte_eth_rx_burst(port_id, rx_queue_id, rx_pkts_burst,
674*1ffee690SAmr Mokhtar 			MAX_PKT_BURST);
675*1ffee690SAmr Mokhtar 	if (!nb_rx)
676*1ffee690SAmr Mokhtar 		return;
677*1ffee690SAmr Mokhtar 
678*1ffee690SAmr Mokhtar 	if (unlikely(rte_mempool_get_bulk(enc_out_pool, (void **)enc_out_pkts,
679*1ffee690SAmr Mokhtar 			nb_rx) != 0)) {
680*1ffee690SAmr Mokhtar 		pktmbuf_free_bulk(rx_pkts_burst, nb_rx);
681*1ffee690SAmr Mokhtar 		lcore_stats->rx_lost_packets += nb_rx;
682*1ffee690SAmr Mokhtar 		return;
683*1ffee690SAmr Mokhtar 	}
684*1ffee690SAmr Mokhtar 
685*1ffee690SAmr Mokhtar 	if (unlikely(rte_bbdev_enc_op_alloc_bulk(bbdev_op_pool, bbdev_ops_burst,
686*1ffee690SAmr Mokhtar 			nb_rx) != 0)) {
687*1ffee690SAmr Mokhtar 		pktmbuf_free_bulk(enc_out_pkts, nb_rx);
688*1ffee690SAmr Mokhtar 		pktmbuf_free_bulk(rx_pkts_burst, nb_rx);
689*1ffee690SAmr Mokhtar 		lcore_stats->rx_lost_packets += nb_rx;
690*1ffee690SAmr Mokhtar 		return;
691*1ffee690SAmr Mokhtar 	}
692*1ffee690SAmr Mokhtar 
693*1ffee690SAmr Mokhtar 	for (i = 0; i < nb_rx; i++) {
694*1ffee690SAmr Mokhtar 		char *data;
695*1ffee690SAmr Mokhtar 		const uint16_t pkt_data_len =
696*1ffee690SAmr Mokhtar 				rte_pktmbuf_data_len(rx_pkts_burst[i]) -
697*1ffee690SAmr Mokhtar 				sizeof(struct ether_hdr);
698*1ffee690SAmr Mokhtar 		/* save input mbuf pointer for later comparison */
699*1ffee690SAmr Mokhtar 		enc_out_pkts[i]->userdata = rx_pkts_burst[i];
700*1ffee690SAmr Mokhtar 
701*1ffee690SAmr Mokhtar 		/* copy ethernet header */
702*1ffee690SAmr Mokhtar 		rte_pktmbuf_reset(enc_out_pkts[i]);
703*1ffee690SAmr Mokhtar 		data = rte_pktmbuf_append(enc_out_pkts[i],
704*1ffee690SAmr Mokhtar 				sizeof(struct ether_hdr));
705*1ffee690SAmr Mokhtar 		if (data == NULL) {
706*1ffee690SAmr Mokhtar 			printf(
707*1ffee690SAmr Mokhtar 				"Not enough space for ethernet header in encoder output mbuf\n");
708*1ffee690SAmr Mokhtar 			continue;
709*1ffee690SAmr Mokhtar 		}
710*1ffee690SAmr Mokhtar 		add_ether_hdr(rx_pkts_burst[i], enc_out_pkts[i]);
711*1ffee690SAmr Mokhtar 
712*1ffee690SAmr Mokhtar 		/* set op */
713*1ffee690SAmr Mokhtar 		bbdev_ops_burst[i]->turbo_enc = def_op_enc;
714*1ffee690SAmr Mokhtar 
715*1ffee690SAmr Mokhtar 		bbdev_ops_burst[i]->turbo_enc.input.data =
716*1ffee690SAmr Mokhtar 				rx_pkts_burst[i];
717*1ffee690SAmr Mokhtar 		bbdev_ops_burst[i]->turbo_enc.input.offset =
718*1ffee690SAmr Mokhtar 				sizeof(struct ether_hdr);
719*1ffee690SAmr Mokhtar 		/* Encoder will attach the CRC24B, adjust the length */
720*1ffee690SAmr Mokhtar 		bbdev_ops_burst[i]->turbo_enc.input.length = in_data_len;
721*1ffee690SAmr Mokhtar 
722*1ffee690SAmr Mokhtar 		if (in_data_len < pkt_data_len)
723*1ffee690SAmr Mokhtar 			rte_pktmbuf_trim(rx_pkts_burst[i], pkt_data_len -
724*1ffee690SAmr Mokhtar 					in_data_len);
725*1ffee690SAmr Mokhtar 		else if (in_data_len > pkt_data_len) {
726*1ffee690SAmr Mokhtar 			data = rte_pktmbuf_append(rx_pkts_burst[i],
727*1ffee690SAmr Mokhtar 					in_data_len - pkt_data_len);
728*1ffee690SAmr Mokhtar 			if (data == NULL)
729*1ffee690SAmr Mokhtar 				printf(
730*1ffee690SAmr Mokhtar 					"Not enough storage in mbuf to perform the encoding\n");
731*1ffee690SAmr Mokhtar 		}
732*1ffee690SAmr Mokhtar 
733*1ffee690SAmr Mokhtar 		bbdev_ops_burst[i]->turbo_enc.output.data =
734*1ffee690SAmr Mokhtar 				enc_out_pkts[i];
735*1ffee690SAmr Mokhtar 		bbdev_ops_burst[i]->turbo_enc.output.offset =
736*1ffee690SAmr Mokhtar 				sizeof(struct ether_hdr);
737*1ffee690SAmr Mokhtar 	}
738*1ffee690SAmr Mokhtar 
739*1ffee690SAmr Mokhtar 	/* Enqueue packets on BBDevice */
740*1ffee690SAmr Mokhtar 	nb_enq = rte_bbdev_enqueue_enc_ops(bbdev_id, enc_queue_id,
741*1ffee690SAmr Mokhtar 			bbdev_ops_burst, nb_rx);
742*1ffee690SAmr Mokhtar 	if (unlikely(nb_enq < nb_rx)) {
743*1ffee690SAmr Mokhtar 		pktmbuf_userdata_free_bulk(&enc_out_pkts[nb_enq],
744*1ffee690SAmr Mokhtar 				nb_rx - nb_enq);
745*1ffee690SAmr Mokhtar 		rte_bbdev_enc_op_free_bulk(&bbdev_ops_burst[nb_enq],
746*1ffee690SAmr Mokhtar 				nb_rx - nb_enq);
747*1ffee690SAmr Mokhtar 		lcore_stats->rx_lost_packets += nb_rx - nb_enq;
748*1ffee690SAmr Mokhtar 
749*1ffee690SAmr Mokhtar 		if (!nb_enq)
750*1ffee690SAmr Mokhtar 			return;
751*1ffee690SAmr Mokhtar 	}
752*1ffee690SAmr Mokhtar 
753*1ffee690SAmr Mokhtar 	lcore_stats->enqueued += nb_enq;
754*1ffee690SAmr Mokhtar 
755*1ffee690SAmr Mokhtar 	/* Dequeue packets from bbdev device*/
756*1ffee690SAmr Mokhtar 	nb_deq = 0;
757*1ffee690SAmr Mokhtar 	do {
758*1ffee690SAmr Mokhtar 		nb_deq += rte_bbdev_dequeue_enc_ops(bbdev_id, enc_queue_id,
759*1ffee690SAmr Mokhtar 				&bbdev_ops_burst[nb_deq], nb_enq - nb_deq);
760*1ffee690SAmr Mokhtar 	} while (unlikely(nb_deq < nb_enq));
761*1ffee690SAmr Mokhtar 
762*1ffee690SAmr Mokhtar 	lcore_stats->dequeued += nb_deq;
763*1ffee690SAmr Mokhtar 
764*1ffee690SAmr Mokhtar 	/* Generate and add AWGN */
765*1ffee690SAmr Mokhtar 	add_awgn(enc_out_pkts, nb_deq);
766*1ffee690SAmr Mokhtar 
767*1ffee690SAmr Mokhtar 	rte_bbdev_enc_op_free_bulk(bbdev_ops_burst, nb_deq);
768*1ffee690SAmr Mokhtar 
769*1ffee690SAmr Mokhtar 	/* Enqueue packets to encoder-to-decoder ring */
770*1ffee690SAmr Mokhtar 	nb_sent = rte_ring_enqueue_burst(enc_to_dec_ring, (void **)enc_out_pkts,
771*1ffee690SAmr Mokhtar 			nb_deq, NULL);
772*1ffee690SAmr Mokhtar 	if (unlikely(nb_sent < nb_deq)) {
773*1ffee690SAmr Mokhtar 		pktmbuf_userdata_free_bulk(&enc_out_pkts[nb_sent],
774*1ffee690SAmr Mokhtar 				nb_deq - nb_sent);
775*1ffee690SAmr Mokhtar 		lcore_stats->enc_to_dec_lost_packets += nb_deq - nb_sent;
776*1ffee690SAmr Mokhtar 	}
777*1ffee690SAmr Mokhtar }
778*1ffee690SAmr Mokhtar 
779*1ffee690SAmr Mokhtar static void
780*1ffee690SAmr Mokhtar run_decoding(struct lcore_conf *lcore_conf)
781*1ffee690SAmr Mokhtar {
782*1ffee690SAmr Mokhtar 	uint16_t i;
783*1ffee690SAmr Mokhtar 	uint16_t port_id, tx_queue_id;
784*1ffee690SAmr Mokhtar 	uint16_t bbdev_id, bbdev_queue_id;
785*1ffee690SAmr Mokhtar 	uint16_t nb_recv, nb_enq, nb_deq, nb_tx;
786*1ffee690SAmr Mokhtar 	uint8_t *llr_temp_buf;
787*1ffee690SAmr Mokhtar 	struct rte_mbuf *recv_pkts_burst[MAX_PKT_BURST];
788*1ffee690SAmr Mokhtar 	struct rte_bbdev_dec_op *bbdev_ops_burst[MAX_PKT_BURST];
789*1ffee690SAmr Mokhtar 	struct lcore_statistics *lcore_stats;
790*1ffee690SAmr Mokhtar 	struct rte_mempool *bbdev_op_pool;
791*1ffee690SAmr Mokhtar 	struct rte_ring *enc_to_dec_ring;
792*1ffee690SAmr Mokhtar 
793*1ffee690SAmr Mokhtar 	lcore_stats = lcore_conf->lcore_stats;
794*1ffee690SAmr Mokhtar 	port_id = lcore_conf->port_id;
795*1ffee690SAmr Mokhtar 	tx_queue_id = lcore_conf->tx_queue_id;
796*1ffee690SAmr Mokhtar 	bbdev_id = lcore_conf->bbdev_id;
797*1ffee690SAmr Mokhtar 	bbdev_queue_id = lcore_conf->dec_queue_id;
798*1ffee690SAmr Mokhtar 	bbdev_op_pool = lcore_conf->bbdev_dec_op_pool;
799*1ffee690SAmr Mokhtar 	enc_to_dec_ring = lcore_conf->enc_to_dec_ring;
800*1ffee690SAmr Mokhtar 	llr_temp_buf = lcore_conf->llr_temp_buf;
801*1ffee690SAmr Mokhtar 
802*1ffee690SAmr Mokhtar 	/* Dequeue packets from the ring */
803*1ffee690SAmr Mokhtar 	nb_recv = rte_ring_dequeue_burst(enc_to_dec_ring,
804*1ffee690SAmr Mokhtar 			(void **)recv_pkts_burst, MAX_PKT_BURST, NULL);
805*1ffee690SAmr Mokhtar 	if (!nb_recv)
806*1ffee690SAmr Mokhtar 		return;
807*1ffee690SAmr Mokhtar 
808*1ffee690SAmr Mokhtar 	if (unlikely(rte_bbdev_dec_op_alloc_bulk(bbdev_op_pool, bbdev_ops_burst,
809*1ffee690SAmr Mokhtar 			nb_recv) != 0)) {
810*1ffee690SAmr Mokhtar 		pktmbuf_userdata_free_bulk(recv_pkts_burst, nb_recv);
811*1ffee690SAmr Mokhtar 		lcore_stats->rx_lost_packets += nb_recv;
812*1ffee690SAmr Mokhtar 		return;
813*1ffee690SAmr Mokhtar 	}
814*1ffee690SAmr Mokhtar 
815*1ffee690SAmr Mokhtar 	transform_enc_out_dec_in(recv_pkts_burst, llr_temp_buf, nb_recv,
816*1ffee690SAmr Mokhtar 			def_op_dec.cb_params.k);
817*1ffee690SAmr Mokhtar 
818*1ffee690SAmr Mokhtar 	for (i = 0; i < nb_recv; i++) {
819*1ffee690SAmr Mokhtar 		/* set op */
820*1ffee690SAmr Mokhtar 		bbdev_ops_burst[i]->turbo_dec = def_op_dec;
821*1ffee690SAmr Mokhtar 
822*1ffee690SAmr Mokhtar 		bbdev_ops_burst[i]->turbo_dec.input.data = recv_pkts_burst[i];
823*1ffee690SAmr Mokhtar 		bbdev_ops_burst[i]->turbo_dec.input.offset =
824*1ffee690SAmr Mokhtar 				sizeof(struct ether_hdr);
825*1ffee690SAmr Mokhtar 		bbdev_ops_burst[i]->turbo_dec.input.length =
826*1ffee690SAmr Mokhtar 				rte_pktmbuf_data_len(recv_pkts_burst[i])
827*1ffee690SAmr Mokhtar 				- sizeof(struct ether_hdr);
828*1ffee690SAmr Mokhtar 
829*1ffee690SAmr Mokhtar 		bbdev_ops_burst[i]->turbo_dec.hard_output.data =
830*1ffee690SAmr Mokhtar 				recv_pkts_burst[i];
831*1ffee690SAmr Mokhtar 		bbdev_ops_burst[i]->turbo_dec.hard_output.offset =
832*1ffee690SAmr Mokhtar 				sizeof(struct ether_hdr);
833*1ffee690SAmr Mokhtar 	}
834*1ffee690SAmr Mokhtar 
835*1ffee690SAmr Mokhtar 	/* Enqueue packets on BBDevice */
836*1ffee690SAmr Mokhtar 	nb_enq = rte_bbdev_enqueue_dec_ops(bbdev_id, bbdev_queue_id,
837*1ffee690SAmr Mokhtar 			bbdev_ops_burst, nb_recv);
838*1ffee690SAmr Mokhtar 	if (unlikely(nb_enq < nb_recv)) {
839*1ffee690SAmr Mokhtar 		pktmbuf_userdata_free_bulk(&recv_pkts_burst[nb_enq],
840*1ffee690SAmr Mokhtar 				nb_recv - nb_enq);
841*1ffee690SAmr Mokhtar 		rte_bbdev_dec_op_free_bulk(&bbdev_ops_burst[nb_enq],
842*1ffee690SAmr Mokhtar 				nb_recv - nb_enq);
843*1ffee690SAmr Mokhtar 		lcore_stats->rx_lost_packets += nb_recv - nb_enq;
844*1ffee690SAmr Mokhtar 
845*1ffee690SAmr Mokhtar 		if (!nb_enq)
846*1ffee690SAmr Mokhtar 			return;
847*1ffee690SAmr Mokhtar 	}
848*1ffee690SAmr Mokhtar 
849*1ffee690SAmr Mokhtar 	lcore_stats->enqueued += nb_enq;
850*1ffee690SAmr Mokhtar 
851*1ffee690SAmr Mokhtar 	/* Dequeue packets from BBDevice */
852*1ffee690SAmr Mokhtar 	nb_deq = 0;
853*1ffee690SAmr Mokhtar 	do {
854*1ffee690SAmr Mokhtar 		nb_deq += rte_bbdev_dequeue_dec_ops(bbdev_id, bbdev_queue_id,
855*1ffee690SAmr Mokhtar 				&bbdev_ops_burst[nb_deq], nb_enq - nb_deq);
856*1ffee690SAmr Mokhtar 	} while (unlikely(nb_deq < nb_enq));
857*1ffee690SAmr Mokhtar 
858*1ffee690SAmr Mokhtar 	lcore_stats->dequeued += nb_deq;
859*1ffee690SAmr Mokhtar 
860*1ffee690SAmr Mokhtar 	rte_bbdev_dec_op_free_bulk(bbdev_ops_burst, nb_deq);
861*1ffee690SAmr Mokhtar 
862*1ffee690SAmr Mokhtar 	verify_data(recv_pkts_burst, nb_deq);
863*1ffee690SAmr Mokhtar 
864*1ffee690SAmr Mokhtar 	/* Free the RX mbufs after verification */
865*1ffee690SAmr Mokhtar 	for (i = 0; i < nb_deq; ++i)
866*1ffee690SAmr Mokhtar 		rte_pktmbuf_free(recv_pkts_burst[i]->userdata);
867*1ffee690SAmr Mokhtar 
868*1ffee690SAmr Mokhtar 	/* Transmit the packets */
869*1ffee690SAmr Mokhtar 	nb_tx = rte_eth_tx_burst(port_id, tx_queue_id, recv_pkts_burst, nb_deq);
870*1ffee690SAmr Mokhtar 	if (unlikely(nb_tx < nb_deq)) {
871*1ffee690SAmr Mokhtar 		pktmbuf_userdata_free_bulk(&recv_pkts_burst[nb_tx],
872*1ffee690SAmr Mokhtar 				nb_deq - nb_tx);
873*1ffee690SAmr Mokhtar 		lcore_stats->tx_lost_packets += nb_deq - nb_tx;
874*1ffee690SAmr Mokhtar 	}
875*1ffee690SAmr Mokhtar }
876*1ffee690SAmr Mokhtar 
877*1ffee690SAmr Mokhtar static int
878*1ffee690SAmr Mokhtar processing_loop(void *arg)
879*1ffee690SAmr Mokhtar {
880*1ffee690SAmr Mokhtar 	struct lcore_conf *lcore_conf = arg;
881*1ffee690SAmr Mokhtar 	const bool run_encoder = (lcore_conf->core_type &
882*1ffee690SAmr Mokhtar 			(1 << RTE_BBDEV_OP_TURBO_ENC));
883*1ffee690SAmr Mokhtar 	const bool run_decoder = (lcore_conf->core_type &
884*1ffee690SAmr Mokhtar 			(1 << RTE_BBDEV_OP_TURBO_DEC));
885*1ffee690SAmr Mokhtar 
886*1ffee690SAmr Mokhtar 	while (!rte_atomic16_read(&global_exit_flag)) {
887*1ffee690SAmr Mokhtar 		if (run_encoder)
888*1ffee690SAmr Mokhtar 			run_encoding(lcore_conf);
889*1ffee690SAmr Mokhtar 		if (run_decoder)
890*1ffee690SAmr Mokhtar 			run_decoding(lcore_conf);
891*1ffee690SAmr Mokhtar 	}
892*1ffee690SAmr Mokhtar 
893*1ffee690SAmr Mokhtar 	return 0;
894*1ffee690SAmr Mokhtar }
895*1ffee690SAmr Mokhtar 
896*1ffee690SAmr Mokhtar static int
897*1ffee690SAmr Mokhtar prepare_bbdev_device(unsigned int dev_id, struct rte_bbdev_info *info,
898*1ffee690SAmr Mokhtar 		struct app_config_params *app_params)
899*1ffee690SAmr Mokhtar {
900*1ffee690SAmr Mokhtar 	int ret;
901*1ffee690SAmr Mokhtar 	unsigned int q_id, dec_q_id, enc_q_id;
902*1ffee690SAmr Mokhtar 	struct rte_bbdev_queue_conf qconf = {0};
903*1ffee690SAmr Mokhtar 	uint16_t dec_qs_nb = app_params->num_dec_cores;
904*1ffee690SAmr Mokhtar 	uint16_t enc_qs_nb = app_params->num_enc_cores;
905*1ffee690SAmr Mokhtar 	uint16_t tot_qs = dec_qs_nb + enc_qs_nb;
906*1ffee690SAmr Mokhtar 
907*1ffee690SAmr Mokhtar 	ret = rte_bbdev_setup_queues(dev_id, tot_qs, info->socket_id);
908*1ffee690SAmr Mokhtar 	if (ret < 0)
909*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE,
910*1ffee690SAmr Mokhtar 				"ERROR(%d): BBDEV %u not configured properly\n",
911*1ffee690SAmr Mokhtar 				ret, dev_id);
912*1ffee690SAmr Mokhtar 
913*1ffee690SAmr Mokhtar 	/* setup device DEC queues */
914*1ffee690SAmr Mokhtar 	qconf.socket = info->socket_id;
915*1ffee690SAmr Mokhtar 	qconf.queue_size = info->drv.queue_size_lim;
916*1ffee690SAmr Mokhtar 	qconf.op_type = RTE_BBDEV_OP_TURBO_DEC;
917*1ffee690SAmr Mokhtar 
918*1ffee690SAmr Mokhtar 	for (q_id = 0, dec_q_id = 0; q_id < dec_qs_nb; q_id++) {
919*1ffee690SAmr Mokhtar 		ret = rte_bbdev_queue_configure(dev_id, q_id, &qconf);
920*1ffee690SAmr Mokhtar 		if (ret < 0)
921*1ffee690SAmr Mokhtar 			rte_exit(EXIT_FAILURE,
922*1ffee690SAmr Mokhtar 					"ERROR(%d): BBDEV %u DEC queue %u not configured properly\n",
923*1ffee690SAmr Mokhtar 					ret, dev_id, q_id);
924*1ffee690SAmr Mokhtar 		app_params->dec_queue_ids[dec_q_id++] = q_id;
925*1ffee690SAmr Mokhtar 	}
926*1ffee690SAmr Mokhtar 
927*1ffee690SAmr Mokhtar 	/* setup device ENC queues */
928*1ffee690SAmr Mokhtar 	qconf.op_type = RTE_BBDEV_OP_TURBO_ENC;
929*1ffee690SAmr Mokhtar 
930*1ffee690SAmr Mokhtar 	for (q_id = dec_qs_nb, enc_q_id = 0; q_id < tot_qs; q_id++) {
931*1ffee690SAmr Mokhtar 		ret = rte_bbdev_queue_configure(dev_id, q_id, &qconf);
932*1ffee690SAmr Mokhtar 		if (ret < 0)
933*1ffee690SAmr Mokhtar 			rte_exit(EXIT_FAILURE,
934*1ffee690SAmr Mokhtar 					"ERROR(%d): BBDEV %u ENC queue %u not configured properly\n",
935*1ffee690SAmr Mokhtar 					ret, dev_id, q_id);
936*1ffee690SAmr Mokhtar 		app_params->enc_queue_ids[enc_q_id++] = q_id;
937*1ffee690SAmr Mokhtar 	}
938*1ffee690SAmr Mokhtar 
939*1ffee690SAmr Mokhtar 	ret = rte_bbdev_start(dev_id);
940*1ffee690SAmr Mokhtar 
941*1ffee690SAmr Mokhtar 	if (ret != 0)
942*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE, "ERROR(%d): BBDEV %u not started\n",
943*1ffee690SAmr Mokhtar 			ret, dev_id);
944*1ffee690SAmr Mokhtar 
945*1ffee690SAmr Mokhtar 	printf("BBdev %u started\n", dev_id);
946*1ffee690SAmr Mokhtar 
947*1ffee690SAmr Mokhtar 	return 0;
948*1ffee690SAmr Mokhtar }
949*1ffee690SAmr Mokhtar 
950*1ffee690SAmr Mokhtar static inline bool
951*1ffee690SAmr Mokhtar check_matching_capabilities(uint64_t mask, uint64_t required_mask)
952*1ffee690SAmr Mokhtar {
953*1ffee690SAmr Mokhtar 	return (mask & required_mask) == required_mask;
954*1ffee690SAmr Mokhtar }
955*1ffee690SAmr Mokhtar 
956*1ffee690SAmr Mokhtar static void
957*1ffee690SAmr Mokhtar enable_bbdev(struct app_config_params *app_params)
958*1ffee690SAmr Mokhtar {
959*1ffee690SAmr Mokhtar 	struct rte_bbdev_info dev_info;
960*1ffee690SAmr Mokhtar 	const struct rte_bbdev_op_cap *op_cap;
961*1ffee690SAmr Mokhtar 	uint16_t bbdev_id = app_params->bbdev_id;
962*1ffee690SAmr Mokhtar 	bool encoder_capable = false;
963*1ffee690SAmr Mokhtar 	bool decoder_capable = false;
964*1ffee690SAmr Mokhtar 
965*1ffee690SAmr Mokhtar 	rte_bbdev_info_get(bbdev_id, &dev_info);
966*1ffee690SAmr Mokhtar 	op_cap = dev_info.drv.capabilities;
967*1ffee690SAmr Mokhtar 
968*1ffee690SAmr Mokhtar 	while (op_cap->type != RTE_BBDEV_OP_NONE) {
969*1ffee690SAmr Mokhtar 		if (op_cap->type == RTE_BBDEV_OP_TURBO_ENC) {
970*1ffee690SAmr Mokhtar 			if (check_matching_capabilities(
971*1ffee690SAmr Mokhtar 					op_cap->cap.turbo_enc.capability_flags,
972*1ffee690SAmr Mokhtar 					def_op_enc.op_flags))
973*1ffee690SAmr Mokhtar 				encoder_capable = true;
974*1ffee690SAmr Mokhtar 		}
975*1ffee690SAmr Mokhtar 
976*1ffee690SAmr Mokhtar 		if (op_cap->type == RTE_BBDEV_OP_TURBO_DEC) {
977*1ffee690SAmr Mokhtar 			if (check_matching_capabilities(
978*1ffee690SAmr Mokhtar 					op_cap->cap.turbo_dec.capability_flags,
979*1ffee690SAmr Mokhtar 					def_op_dec.op_flags))
980*1ffee690SAmr Mokhtar 				decoder_capable = true;
981*1ffee690SAmr Mokhtar 		}
982*1ffee690SAmr Mokhtar 
983*1ffee690SAmr Mokhtar 		op_cap++;
984*1ffee690SAmr Mokhtar 	}
985*1ffee690SAmr Mokhtar 
986*1ffee690SAmr Mokhtar 	if (encoder_capable == false)
987*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE,
988*1ffee690SAmr Mokhtar 			"The specified BBDev %u doesn't have required encoder capabilities!\n",
989*1ffee690SAmr Mokhtar 			bbdev_id);
990*1ffee690SAmr Mokhtar 	if (decoder_capable == false)
991*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE,
992*1ffee690SAmr Mokhtar 			"The specified BBDev %u doesn't have required decoder capabilities!\n",
993*1ffee690SAmr Mokhtar 			bbdev_id);
994*1ffee690SAmr Mokhtar 
995*1ffee690SAmr Mokhtar 	prepare_bbdev_device(bbdev_id, &dev_info, app_params);
996*1ffee690SAmr Mokhtar }
997*1ffee690SAmr Mokhtar 
998*1ffee690SAmr Mokhtar int
999*1ffee690SAmr Mokhtar main(int argc, char **argv)
1000*1ffee690SAmr Mokhtar {
1001*1ffee690SAmr Mokhtar 	int ret;
1002*1ffee690SAmr Mokhtar 	unsigned int nb_bbdevs, nb_ports, flags, lcore_id;
1003*1ffee690SAmr Mokhtar 	void *sigret;
1004*1ffee690SAmr Mokhtar 	struct app_config_params app_params = def_app_config;
1005*1ffee690SAmr Mokhtar 	struct rte_mempool *ethdev_mbuf_mempool, *bbdev_mbuf_mempool;
1006*1ffee690SAmr Mokhtar 	struct rte_mempool *bbdev_op_pools[RTE_BBDEV_OP_TYPE_COUNT];
1007*1ffee690SAmr Mokhtar 	struct lcore_conf lcore_conf[RTE_MAX_LCORE] = { {0} };
1008*1ffee690SAmr Mokhtar 	struct lcore_statistics lcore_stats[RTE_MAX_LCORE] = { {0} };
1009*1ffee690SAmr Mokhtar 	struct stats_lcore_params stats_lcore;
1010*1ffee690SAmr Mokhtar 	struct rte_ring *enc_to_dec_ring;
1011*1ffee690SAmr Mokhtar 	bool stats_thread_started = false;
1012*1ffee690SAmr Mokhtar 	unsigned int master_lcore_id = rte_get_master_lcore();
1013*1ffee690SAmr Mokhtar 
1014*1ffee690SAmr Mokhtar 	rte_atomic16_init(&global_exit_flag);
1015*1ffee690SAmr Mokhtar 
1016*1ffee690SAmr Mokhtar 	sigret = signal(SIGTERM, signal_handler);
1017*1ffee690SAmr Mokhtar 	if (sigret == SIG_ERR)
1018*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE, "signal(%d, ...) failed", SIGTERM);
1019*1ffee690SAmr Mokhtar 
1020*1ffee690SAmr Mokhtar 	sigret = signal(SIGINT, signal_handler);
1021*1ffee690SAmr Mokhtar 	if (sigret == SIG_ERR)
1022*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE, "signal(%d, ...) failed", SIGINT);
1023*1ffee690SAmr Mokhtar 
1024*1ffee690SAmr Mokhtar 	ret = rte_eal_init(argc, argv);
1025*1ffee690SAmr Mokhtar 	if (ret < 0)
1026*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");
1027*1ffee690SAmr Mokhtar 
1028*1ffee690SAmr Mokhtar 	argc -= ret;
1029*1ffee690SAmr Mokhtar 	argv += ret;
1030*1ffee690SAmr Mokhtar 
1031*1ffee690SAmr Mokhtar 	/* parse application arguments (after the EAL ones) */
1032*1ffee690SAmr Mokhtar 	ret = bbdev_parse_args(argc, argv, &app_params);
1033*1ffee690SAmr Mokhtar 	if (ret < 0)
1034*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE, "Invalid BBDEV arguments\n");
1035*1ffee690SAmr Mokhtar 
1036*1ffee690SAmr Mokhtar 	/*create bbdev op pools*/
1037*1ffee690SAmr Mokhtar 	bbdev_op_pools[RTE_BBDEV_OP_TURBO_DEC] =
1038*1ffee690SAmr Mokhtar 			rte_bbdev_op_pool_create("bbdev_op_pool_dec",
1039*1ffee690SAmr Mokhtar 			RTE_BBDEV_OP_TURBO_DEC, NB_MBUF, 128, rte_socket_id());
1040*1ffee690SAmr Mokhtar 	bbdev_op_pools[RTE_BBDEV_OP_TURBO_ENC] =
1041*1ffee690SAmr Mokhtar 			rte_bbdev_op_pool_create("bbdev_op_pool_enc",
1042*1ffee690SAmr Mokhtar 			RTE_BBDEV_OP_TURBO_ENC, NB_MBUF, 128, rte_socket_id());
1043*1ffee690SAmr Mokhtar 
1044*1ffee690SAmr Mokhtar 	if ((bbdev_op_pools[RTE_BBDEV_OP_TURBO_DEC] == NULL) ||
1045*1ffee690SAmr Mokhtar 			(bbdev_op_pools[RTE_BBDEV_OP_TURBO_ENC] == NULL))
1046*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE, "Cannot create bbdev op pools\n");
1047*1ffee690SAmr Mokhtar 
1048*1ffee690SAmr Mokhtar 	/* Create encoder to decoder ring */
1049*1ffee690SAmr Mokhtar 	flags = (app_params.num_enc_cores == 1) ? RING_F_SP_ENQ : 0;
1050*1ffee690SAmr Mokhtar 	if (app_params.num_dec_cores == 1)
1051*1ffee690SAmr Mokhtar 		flags |= RING_F_SC_DEQ;
1052*1ffee690SAmr Mokhtar 
1053*1ffee690SAmr Mokhtar 	enc_to_dec_ring = rte_ring_create("enc_to_dec_ring",
1054*1ffee690SAmr Mokhtar 		rte_align32pow2(NB_MBUF), rte_socket_id(), flags);
1055*1ffee690SAmr Mokhtar 
1056*1ffee690SAmr Mokhtar 	/* Get the number of available bbdev devices */
1057*1ffee690SAmr Mokhtar 	nb_bbdevs = rte_bbdev_count();
1058*1ffee690SAmr Mokhtar 	if (nb_bbdevs <= app_params.bbdev_id)
1059*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE,
1060*1ffee690SAmr Mokhtar 				"%u BBDevs detected, cannot use BBDev with ID %u!\n",
1061*1ffee690SAmr Mokhtar 				nb_bbdevs, app_params.bbdev_id);
1062*1ffee690SAmr Mokhtar 	printf("Number of bbdevs detected: %d\n", nb_bbdevs);
1063*1ffee690SAmr Mokhtar 
1064*1ffee690SAmr Mokhtar 	/* Get the number of available ethdev devices */
1065*1ffee690SAmr Mokhtar 	nb_ports = rte_eth_dev_count();
1066*1ffee690SAmr Mokhtar 	if (nb_ports <= app_params.port_id)
1067*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE,
1068*1ffee690SAmr Mokhtar 				"%u ports detected, cannot use port with ID %u!\n",
1069*1ffee690SAmr Mokhtar 				nb_ports, app_params.port_id);
1070*1ffee690SAmr Mokhtar 
1071*1ffee690SAmr Mokhtar 	/* create the mbuf mempool for ethdev pkts */
1072*1ffee690SAmr Mokhtar 	ethdev_mbuf_mempool = rte_pktmbuf_pool_create("ethdev_mbuf_pool",
1073*1ffee690SAmr Mokhtar 			NB_MBUF, MEMPOOL_CACHE_SIZE, 0,
1074*1ffee690SAmr Mokhtar 			RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
1075*1ffee690SAmr Mokhtar 	if (ethdev_mbuf_mempool == NULL)
1076*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE, "Cannot create ethdev mbuf mempool\n");
1077*1ffee690SAmr Mokhtar 
1078*1ffee690SAmr Mokhtar 	/* create the mbuf mempool for encoder output */
1079*1ffee690SAmr Mokhtar 	bbdev_mbuf_mempool = rte_pktmbuf_pool_create("bbdev_mbuf_pool",
1080*1ffee690SAmr Mokhtar 			NB_MBUF, MEMPOOL_CACHE_SIZE, 0,
1081*1ffee690SAmr Mokhtar 			RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
1082*1ffee690SAmr Mokhtar 	if (bbdev_mbuf_mempool == NULL)
1083*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE, "Cannot create ethdev mbuf mempool\n");
1084*1ffee690SAmr Mokhtar 
1085*1ffee690SAmr Mokhtar 	/* initialize ports */
1086*1ffee690SAmr Mokhtar 	ret = initialize_ports(&app_params, ethdev_mbuf_mempool);
1087*1ffee690SAmr Mokhtar 
1088*1ffee690SAmr Mokhtar 	/* Check if all requested lcores are available */
1089*1ffee690SAmr Mokhtar 	for (lcore_id = 0; lcore_id < 8 * sizeof(uint64_t); ++lcore_id)
1090*1ffee690SAmr Mokhtar 		if (((1ULL << lcore_id) & app_params.enc_core_mask) ||
1091*1ffee690SAmr Mokhtar 				((1ULL << lcore_id) & app_params.dec_core_mask))
1092*1ffee690SAmr Mokhtar 			if (!rte_lcore_is_enabled(lcore_id))
1093*1ffee690SAmr Mokhtar 				rte_exit(EXIT_FAILURE,
1094*1ffee690SAmr Mokhtar 						"Requested lcore_id %u is not enabled!\n",
1095*1ffee690SAmr Mokhtar 						lcore_id);
1096*1ffee690SAmr Mokhtar 
1097*1ffee690SAmr Mokhtar 	/* Start ethernet port */
1098*1ffee690SAmr Mokhtar 	ret = rte_eth_dev_start(app_params.port_id);
1099*1ffee690SAmr Mokhtar 	if (ret < 0)
1100*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%u\n",
1101*1ffee690SAmr Mokhtar 				ret, app_params.port_id);
1102*1ffee690SAmr Mokhtar 
1103*1ffee690SAmr Mokhtar 	ret = check_port_link_status(app_params.port_id);
1104*1ffee690SAmr Mokhtar 	if (ret < 0)
1105*1ffee690SAmr Mokhtar 		exit(EXIT_FAILURE);
1106*1ffee690SAmr Mokhtar 
1107*1ffee690SAmr Mokhtar 	/* start BBDevice and save BBDev queue IDs */
1108*1ffee690SAmr Mokhtar 	enable_bbdev(&app_params);
1109*1ffee690SAmr Mokhtar 
1110*1ffee690SAmr Mokhtar 	/* Initialize the port/queue configuration of each logical core */
1111*1ffee690SAmr Mokhtar 	lcore_conf_init(&app_params, lcore_conf, bbdev_op_pools,
1112*1ffee690SAmr Mokhtar 			bbdev_mbuf_mempool, enc_to_dec_ring, lcore_stats);
1113*1ffee690SAmr Mokhtar 
1114*1ffee690SAmr Mokhtar 	stats_lcore.app_params = &app_params;
1115*1ffee690SAmr Mokhtar 	stats_lcore.lconf = lcore_conf;
1116*1ffee690SAmr Mokhtar 
1117*1ffee690SAmr Mokhtar 	RTE_LCORE_FOREACH_SLAVE(lcore_id) {
1118*1ffee690SAmr Mokhtar 		if (lcore_conf[lcore_id].core_type != 0)
1119*1ffee690SAmr Mokhtar 			/* launch per-lcore processing loop on slave lcores */
1120*1ffee690SAmr Mokhtar 			rte_eal_remote_launch(processing_loop,
1121*1ffee690SAmr Mokhtar 					&lcore_conf[lcore_id], lcore_id);
1122*1ffee690SAmr Mokhtar 		else if (!stats_thread_started) {
1123*1ffee690SAmr Mokhtar 			/* launch statistics printing loop */
1124*1ffee690SAmr Mokhtar 			rte_eal_remote_launch(stats_loop, &stats_lcore,
1125*1ffee690SAmr Mokhtar 					lcore_id);
1126*1ffee690SAmr Mokhtar 			stats_thread_started = true;
1127*1ffee690SAmr Mokhtar 		}
1128*1ffee690SAmr Mokhtar 	}
1129*1ffee690SAmr Mokhtar 
1130*1ffee690SAmr Mokhtar 	if (!stats_thread_started &&
1131*1ffee690SAmr Mokhtar 			lcore_conf[master_lcore_id].core_type != 0)
1132*1ffee690SAmr Mokhtar 		rte_exit(EXIT_FAILURE,
1133*1ffee690SAmr Mokhtar 				"Not enough lcores to run the statistics printing loop!");
1134*1ffee690SAmr Mokhtar 	else if (lcore_conf[master_lcore_id].core_type != 0)
1135*1ffee690SAmr Mokhtar 		processing_loop(&lcore_conf[master_lcore_id]);
1136*1ffee690SAmr Mokhtar 	else if (!stats_thread_started)
1137*1ffee690SAmr Mokhtar 		stats_loop(&stats_lcore);
1138*1ffee690SAmr Mokhtar 
1139*1ffee690SAmr Mokhtar 	RTE_LCORE_FOREACH_SLAVE(lcore_id) {
1140*1ffee690SAmr Mokhtar 		ret |= rte_eal_wait_lcore(lcore_id);
1141*1ffee690SAmr Mokhtar 	}
1142*1ffee690SAmr Mokhtar 
1143*1ffee690SAmr Mokhtar 	return ret;
1144*1ffee690SAmr Mokhtar }
1145