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