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