8a50ddeef0704c574faad9ec9eb255fb0adb4940
[dpdk.git] / app / test-pmd / testpmd.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2017 Intel Corporation
3  */
4
5 #include <stdarg.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <signal.h>
9 #include <string.h>
10 #include <time.h>
11 #include <fcntl.h>
12 #include <sys/mman.h>
13 #include <sys/types.h>
14 #include <errno.h>
15 #include <stdbool.h>
16
17 #include <sys/queue.h>
18 #include <sys/stat.h>
19
20 #include <stdint.h>
21 #include <unistd.h>
22 #include <inttypes.h>
23
24 #include <rte_common.h>
25 #include <rte_errno.h>
26 #include <rte_byteorder.h>
27 #include <rte_log.h>
28 #include <rte_debug.h>
29 #include <rte_cycles.h>
30 #include <rte_malloc_heap.h>
31 #include <rte_memory.h>
32 #include <rte_memcpy.h>
33 #include <rte_launch.h>
34 #include <rte_eal.h>
35 #include <rte_alarm.h>
36 #include <rte_per_lcore.h>
37 #include <rte_lcore.h>
38 #include <rte_atomic.h>
39 #include <rte_branch_prediction.h>
40 #include <rte_mempool.h>
41 #include <rte_malloc.h>
42 #include <rte_mbuf.h>
43 #include <rte_mbuf_pool_ops.h>
44 #include <rte_interrupts.h>
45 #include <rte_pci.h>
46 #include <rte_ether.h>
47 #include <rte_ethdev.h>
48 #include <rte_dev.h>
49 #include <rte_string_fns.h>
50 #ifdef RTE_LIBRTE_IXGBE_PMD
51 #include <rte_pmd_ixgbe.h>
52 #endif
53 #ifdef RTE_LIBRTE_PDUMP
54 #include <rte_pdump.h>
55 #endif
56 #include <rte_flow.h>
57 #include <rte_metrics.h>
58 #ifdef RTE_LIBRTE_BITRATE
59 #include <rte_bitrate.h>
60 #endif
61 #ifdef RTE_LIBRTE_LATENCY_STATS
62 #include <rte_latencystats.h>
63 #endif
64
65 #include "testpmd.h"
66
67 #ifndef MAP_HUGETLB
68 /* FreeBSD may not have MAP_HUGETLB (in fact, it probably doesn't) */
69 #define HUGE_FLAG (0x40000)
70 #else
71 #define HUGE_FLAG MAP_HUGETLB
72 #endif
73
74 #ifndef MAP_HUGE_SHIFT
75 /* older kernels (or FreeBSD) will not have this define */
76 #define HUGE_SHIFT (26)
77 #else
78 #define HUGE_SHIFT MAP_HUGE_SHIFT
79 #endif
80
81 #define EXTMEM_HEAP_NAME "extmem"
82
83 uint16_t verbose_level = 0; /**< Silent by default. */
84 int testpmd_logtype; /**< Log type for testpmd logs */
85
86 /* use master core for command line ? */
87 uint8_t interactive = 0;
88 uint8_t auto_start = 0;
89 uint8_t tx_first;
90 char cmdline_filename[PATH_MAX] = {0};
91
92 /*
93  * NUMA support configuration.
94  * When set, the NUMA support attempts to dispatch the allocation of the
95  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
96  * probed ports among the CPU sockets 0 and 1.
97  * Otherwise, all memory is allocated from CPU socket 0.
98  */
99 uint8_t numa_support = 1; /**< numa enabled by default */
100
101 /*
102  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
103  * not configured.
104  */
105 uint8_t socket_num = UMA_NO_CONFIG;
106
107 /*
108  * Select mempool allocation type:
109  * - native: use regular DPDK memory
110  * - anon: use regular DPDK memory to create mempool, but populate using
111  *         anonymous memory (may not be IOVA-contiguous)
112  * - xmem: use externally allocated hugepage memory
113  */
114 uint8_t mp_alloc_type = MP_ALLOC_NATIVE;
115
116 /*
117  * Store specified sockets on which memory pool to be used by ports
118  * is allocated.
119  */
120 uint8_t port_numa[RTE_MAX_ETHPORTS];
121
122 /*
123  * Store specified sockets on which RX ring to be used by ports
124  * is allocated.
125  */
126 uint8_t rxring_numa[RTE_MAX_ETHPORTS];
127
128 /*
129  * Store specified sockets on which TX ring to be used by ports
130  * is allocated.
131  */
132 uint8_t txring_numa[RTE_MAX_ETHPORTS];
133
134 /*
135  * Record the Ethernet address of peer target ports to which packets are
136  * forwarded.
137  * Must be instantiated with the ethernet addresses of peer traffic generator
138  * ports.
139  */
140 struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
141 portid_t nb_peer_eth_addrs = 0;
142
143 /*
144  * Probed Target Environment.
145  */
146 struct rte_port *ports;        /**< For all probed ethernet ports. */
147 portid_t nb_ports;             /**< Number of probed ethernet ports. */
148 struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
149 lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
150
151 portid_t ports_ids[RTE_MAX_ETHPORTS]; /**< Store all port ids. */
152
153 /*
154  * Test Forwarding Configuration.
155  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
156  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
157  */
158 lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
159 lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
160 portid_t  nb_cfg_ports;  /**< Number of configured ports. */
161 portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
162
163 unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
164 portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
165
166 struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
167 streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
168
169 /*
170  * Forwarding engines.
171  */
172 struct fwd_engine * fwd_engines[] = {
173         &io_fwd_engine,
174         &mac_fwd_engine,
175         &mac_swap_engine,
176         &flow_gen_engine,
177         &rx_only_engine,
178         &tx_only_engine,
179         &csum_fwd_engine,
180         &icmp_echo_engine,
181 #if defined RTE_LIBRTE_PMD_SOFTNIC
182         &softnic_fwd_engine,
183 #endif
184 #ifdef RTE_LIBRTE_IEEE1588
185         &ieee1588_fwd_engine,
186 #endif
187         NULL,
188 };
189
190 struct fwd_config cur_fwd_config;
191 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
192 uint32_t retry_enabled;
193 uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
194 uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
195
196 uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
197 uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
198                                       * specified on command-line. */
199 uint16_t stats_period; /**< Period to show statistics (disabled by default) */
200
201 /*
202  * In container, it cannot terminate the process which running with 'stats-period'
203  * option. Set flag to exit stats period loop after received SIGINT/SIGTERM.
204  */
205 uint8_t f_quit;
206
207 /*
208  * Configuration of packet segments used by the "txonly" processing engine.
209  */
210 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
211 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
212         TXONLY_DEF_PACKET_LEN,
213 };
214 uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
215
216 enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
217 /**< Split policy for packets to TX. */
218
219 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
220 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
221
222 /* current configuration is in DCB or not,0 means it is not in DCB mode */
223 uint8_t dcb_config = 0;
224
225 /* Whether the dcb is in testing status */
226 uint8_t dcb_test = 0;
227
228 /*
229  * Configurable number of RX/TX queues.
230  */
231 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
232 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
233
234 /*
235  * Configurable number of RX/TX ring descriptors.
236  * Defaults are supplied by drivers via ethdev.
237  */
238 #define RTE_TEST_RX_DESC_DEFAULT 0
239 #define RTE_TEST_TX_DESC_DEFAULT 0
240 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
241 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
242
243 #define RTE_PMD_PARAM_UNSET -1
244 /*
245  * Configurable values of RX and TX ring threshold registers.
246  */
247
248 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
249 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
250 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
251
252 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
253 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
254 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
255
256 /*
257  * Configurable value of RX free threshold.
258  */
259 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
260
261 /*
262  * Configurable value of RX drop enable.
263  */
264 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
265
266 /*
267  * Configurable value of TX free threshold.
268  */
269 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
270
271 /*
272  * Configurable value of TX RS bit threshold.
273  */
274 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
275
276 /*
277  * Receive Side Scaling (RSS) configuration.
278  */
279 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
280
281 /*
282  * Port topology configuration
283  */
284 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
285
286 /*
287  * Avoids to flush all the RX streams before starts forwarding.
288  */
289 uint8_t no_flush_rx = 0; /* flush by default */
290
291 /*
292  * Flow API isolated mode.
293  */
294 uint8_t flow_isolate_all;
295
296 /*
297  * Avoids to check link status when starting/stopping a port.
298  */
299 uint8_t no_link_check = 0; /* check by default */
300
301 /*
302  * Enable link status change notification
303  */
304 uint8_t lsc_interrupt = 1; /* enabled by default */
305
306 /*
307  * Enable device removal notification.
308  */
309 uint8_t rmv_interrupt = 1; /* enabled by default */
310
311 uint8_t hot_plug = 0; /**< hotplug disabled by default. */
312
313 /*
314  * Display or mask ether events
315  * Default to all events except VF_MBOX
316  */
317 uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) |
318                             (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) |
319                             (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) |
320                             (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) |
321                             (UINT32_C(1) << RTE_ETH_EVENT_IPSEC) |
322                             (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) |
323                             (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV);
324 /*
325  * Decide if all memory are locked for performance.
326  */
327 int do_mlockall = 0;
328
329 /*
330  * NIC bypass mode configuration options.
331  */
332
333 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
334 /* The NIC bypass watchdog timeout. */
335 uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF;
336 #endif
337
338
339 #ifdef RTE_LIBRTE_LATENCY_STATS
340
341 /*
342  * Set when latency stats is enabled in the commandline
343  */
344 uint8_t latencystats_enabled;
345
346 /*
347  * Lcore ID to serive latency statistics.
348  */
349 lcoreid_t latencystats_lcore_id = -1;
350
351 #endif
352
353 /*
354  * Ethernet device configuration.
355  */
356 struct rte_eth_rxmode rx_mode = {
357         .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
358 };
359
360 struct rte_eth_txmode tx_mode = {
361         .offloads = DEV_TX_OFFLOAD_MBUF_FAST_FREE,
362 };
363
364 struct rte_fdir_conf fdir_conf = {
365         .mode = RTE_FDIR_MODE_NONE,
366         .pballoc = RTE_FDIR_PBALLOC_64K,
367         .status = RTE_FDIR_REPORT_STATUS,
368         .mask = {
369                 .vlan_tci_mask = 0xFFEF,
370                 .ipv4_mask     = {
371                         .src_ip = 0xFFFFFFFF,
372                         .dst_ip = 0xFFFFFFFF,
373                 },
374                 .ipv6_mask     = {
375                         .src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
376                         .dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
377                 },
378                 .src_port_mask = 0xFFFF,
379                 .dst_port_mask = 0xFFFF,
380                 .mac_addr_byte_mask = 0xFF,
381                 .tunnel_type_mask = 1,
382                 .tunnel_id_mask = 0xFFFFFFFF,
383         },
384         .drop_queue = 127,
385 };
386
387 volatile int test_done = 1; /* stop packet forwarding when set to 1. */
388
389 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
390 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
391
392 struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
393 struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
394
395 uint16_t nb_tx_queue_stats_mappings = 0;
396 uint16_t nb_rx_queue_stats_mappings = 0;
397
398 /*
399  * Display zero values by default for xstats
400  */
401 uint8_t xstats_hide_zero;
402
403 unsigned int num_sockets = 0;
404 unsigned int socket_ids[RTE_MAX_NUMA_NODES];
405
406 #ifdef RTE_LIBRTE_BITRATE
407 /* Bitrate statistics */
408 struct rte_stats_bitrates *bitrate_data;
409 lcoreid_t bitrate_lcore_id;
410 uint8_t bitrate_enabled;
411 #endif
412
413 struct gro_status gro_ports[RTE_MAX_ETHPORTS];
414 uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES;
415
416 struct vxlan_encap_conf vxlan_encap_conf = {
417         .select_ipv4 = 1,
418         .select_vlan = 0,
419         .vni = "\x00\x00\x00",
420         .udp_src = 0,
421         .udp_dst = RTE_BE16(4789),
422         .ipv4_src = IPv4(127, 0, 0, 1),
423         .ipv4_dst = IPv4(255, 255, 255, 255),
424         .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
425                 "\x00\x00\x00\x00\x00\x00\x00\x01",
426         .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
427                 "\x00\x00\x00\x00\x00\x00\x11\x11",
428         .vlan_tci = 0,
429         .eth_src = "\x00\x00\x00\x00\x00\x00",
430         .eth_dst = "\xff\xff\xff\xff\xff\xff",
431 };
432
433 struct nvgre_encap_conf nvgre_encap_conf = {
434         .select_ipv4 = 1,
435         .select_vlan = 0,
436         .tni = "\x00\x00\x00",
437         .ipv4_src = IPv4(127, 0, 0, 1),
438         .ipv4_dst = IPv4(255, 255, 255, 255),
439         .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
440                 "\x00\x00\x00\x00\x00\x00\x00\x01",
441         .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
442                 "\x00\x00\x00\x00\x00\x00\x11\x11",
443         .vlan_tci = 0,
444         .eth_src = "\x00\x00\x00\x00\x00\x00",
445         .eth_dst = "\xff\xff\xff\xff\xff\xff",
446 };
447
448 /* Forward function declarations */
449 static void map_port_queue_stats_mapping_registers(portid_t pi,
450                                                    struct rte_port *port);
451 static void check_all_ports_link_status(uint32_t port_mask);
452 static int eth_event_callback(portid_t port_id,
453                               enum rte_eth_event_type type,
454                               void *param, void *ret_param);
455 static void eth_dev_event_callback(char *device_name,
456                                 enum rte_dev_event_type type,
457                                 void *param);
458 static int eth_dev_event_callback_register(void);
459 static int eth_dev_event_callback_unregister(void);
460
461
462 /*
463  * Check if all the ports are started.
464  * If yes, return positive value. If not, return zero.
465  */
466 static int all_ports_started(void);
467
468 struct gso_status gso_ports[RTE_MAX_ETHPORTS];
469 uint16_t gso_max_segment_size = ETHER_MAX_LEN - ETHER_CRC_LEN;
470
471 /*
472  * Helper function to check if socket is already discovered.
473  * If yes, return positive value. If not, return zero.
474  */
475 int
476 new_socket_id(unsigned int socket_id)
477 {
478         unsigned int i;
479
480         for (i = 0; i < num_sockets; i++) {
481                 if (socket_ids[i] == socket_id)
482                         return 0;
483         }
484         return 1;
485 }
486
487 /*
488  * Setup default configuration.
489  */
490 static void
491 set_default_fwd_lcores_config(void)
492 {
493         unsigned int i;
494         unsigned int nb_lc;
495         unsigned int sock_num;
496
497         nb_lc = 0;
498         for (i = 0; i < RTE_MAX_LCORE; i++) {
499                 if (!rte_lcore_is_enabled(i))
500                         continue;
501                 sock_num = rte_lcore_to_socket_id(i);
502                 if (new_socket_id(sock_num)) {
503                         if (num_sockets >= RTE_MAX_NUMA_NODES) {
504                                 rte_exit(EXIT_FAILURE,
505                                          "Total sockets greater than %u\n",
506                                          RTE_MAX_NUMA_NODES);
507                         }
508                         socket_ids[num_sockets++] = sock_num;
509                 }
510                 if (i == rte_get_master_lcore())
511                         continue;
512                 fwd_lcores_cpuids[nb_lc++] = i;
513         }
514         nb_lcores = (lcoreid_t) nb_lc;
515         nb_cfg_lcores = nb_lcores;
516         nb_fwd_lcores = 1;
517 }
518
519 static void
520 set_def_peer_eth_addrs(void)
521 {
522         portid_t i;
523
524         for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
525                 peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
526                 peer_eth_addrs[i].addr_bytes[5] = i;
527         }
528 }
529
530 static void
531 set_default_fwd_ports_config(void)
532 {
533         portid_t pt_id;
534         int i = 0;
535
536         RTE_ETH_FOREACH_DEV(pt_id)
537                 fwd_ports_ids[i++] = pt_id;
538
539         nb_cfg_ports = nb_ports;
540         nb_fwd_ports = nb_ports;
541 }
542
543 void
544 set_def_fwd_config(void)
545 {
546         set_default_fwd_lcores_config();
547         set_def_peer_eth_addrs();
548         set_default_fwd_ports_config();
549 }
550
551 /* extremely pessimistic estimation of memory required to create a mempool */
552 static int
553 calc_mem_size(uint32_t nb_mbufs, uint32_t mbuf_sz, size_t pgsz, size_t *out)
554 {
555         unsigned int n_pages, mbuf_per_pg, leftover;
556         uint64_t total_mem, mbuf_mem, obj_sz;
557
558         /* there is no good way to predict how much space the mempool will
559          * occupy because it will allocate chunks on the fly, and some of those
560          * will come from default DPDK memory while some will come from our
561          * external memory, so just assume 128MB will be enough for everyone.
562          */
563         uint64_t hdr_mem = 128 << 20;
564
565         /* account for possible non-contiguousness */
566         obj_sz = rte_mempool_calc_obj_size(mbuf_sz, 0, NULL);
567         if (obj_sz > pgsz) {
568                 TESTPMD_LOG(ERR, "Object size is bigger than page size\n");
569                 return -1;
570         }
571
572         mbuf_per_pg = pgsz / obj_sz;
573         leftover = (nb_mbufs % mbuf_per_pg) > 0;
574         n_pages = (nb_mbufs / mbuf_per_pg) + leftover;
575
576         mbuf_mem = n_pages * pgsz;
577
578         total_mem = RTE_ALIGN(hdr_mem + mbuf_mem, pgsz);
579
580         if (total_mem > SIZE_MAX) {
581                 TESTPMD_LOG(ERR, "Memory size too big\n");
582                 return -1;
583         }
584         *out = (size_t)total_mem;
585
586         return 0;
587 }
588
589 static inline uint32_t
590 bsf64(uint64_t v)
591 {
592         return (uint32_t)__builtin_ctzll(v);
593 }
594
595 static inline uint32_t
596 log2_u64(uint64_t v)
597 {
598         if (v == 0)
599                 return 0;
600         v = rte_align64pow2(v);
601         return bsf64(v);
602 }
603
604 static int
605 pagesz_flags(uint64_t page_sz)
606 {
607         /* as per mmap() manpage, all page sizes are log2 of page size
608          * shifted by MAP_HUGE_SHIFT
609          */
610         int log2 = log2_u64(page_sz);
611
612         return (log2 << HUGE_SHIFT);
613 }
614
615 static void *
616 alloc_mem(size_t memsz, size_t pgsz, bool huge)
617 {
618         void *addr;
619         int flags;
620
621         /* allocate anonymous hugepages */
622         flags = MAP_ANONYMOUS | MAP_PRIVATE;
623         if (huge)
624                 flags |= HUGE_FLAG | pagesz_flags(pgsz);
625
626         addr = mmap(NULL, memsz, PROT_READ | PROT_WRITE, flags, -1, 0);
627         if (addr == MAP_FAILED)
628                 return NULL;
629
630         return addr;
631 }
632
633 struct extmem_param {
634         void *addr;
635         size_t len;
636         size_t pgsz;
637         rte_iova_t *iova_table;
638         unsigned int iova_table_len;
639 };
640
641 static int
642 create_extmem(uint32_t nb_mbufs, uint32_t mbuf_sz, struct extmem_param *param,
643                 bool huge)
644 {
645         uint64_t pgsizes[] = {RTE_PGSIZE_2M, RTE_PGSIZE_1G, /* x86_64, ARM */
646                         RTE_PGSIZE_16M, RTE_PGSIZE_16G};    /* POWER */
647         unsigned int cur_page, n_pages, pgsz_idx;
648         size_t mem_sz, cur_pgsz;
649         rte_iova_t *iovas = NULL;
650         void *addr;
651         int ret;
652
653         for (pgsz_idx = 0; pgsz_idx < RTE_DIM(pgsizes); pgsz_idx++) {
654                 /* skip anything that is too big */
655                 if (pgsizes[pgsz_idx] > SIZE_MAX)
656                         continue;
657
658                 cur_pgsz = pgsizes[pgsz_idx];
659
660                 /* if we were told not to allocate hugepages, override */
661                 if (!huge)
662                         cur_pgsz = sysconf(_SC_PAGESIZE);
663
664                 ret = calc_mem_size(nb_mbufs, mbuf_sz, cur_pgsz, &mem_sz);
665                 if (ret < 0) {
666                         TESTPMD_LOG(ERR, "Cannot calculate memory size\n");
667                         return -1;
668                 }
669
670                 /* allocate our memory */
671                 addr = alloc_mem(mem_sz, cur_pgsz, huge);
672
673                 /* if we couldn't allocate memory with a specified page size,
674                  * that doesn't mean we can't do it with other page sizes, so
675                  * try another one.
676                  */
677                 if (addr == NULL)
678                         continue;
679
680                 /* store IOVA addresses for every page in this memory area */
681                 n_pages = mem_sz / cur_pgsz;
682
683                 iovas = malloc(sizeof(*iovas) * n_pages);
684
685                 if (iovas == NULL) {
686                         TESTPMD_LOG(ERR, "Cannot allocate memory for iova addresses\n");
687                         goto fail;
688                 }
689                 /* lock memory if it's not huge pages */
690                 if (!huge)
691                         mlock(addr, mem_sz);
692
693                 /* populate IOVA addresses */
694                 for (cur_page = 0; cur_page < n_pages; cur_page++) {
695                         rte_iova_t iova;
696                         size_t offset;
697                         void *cur;
698
699                         offset = cur_pgsz * cur_page;
700                         cur = RTE_PTR_ADD(addr, offset);
701
702                         /* touch the page before getting its IOVA */
703                         *(volatile char *)cur = 0;
704
705                         iova = rte_mem_virt2iova(cur);
706
707                         iovas[cur_page] = iova;
708                 }
709
710                 break;
711         }
712         /* if we couldn't allocate anything */
713         if (iovas == NULL)
714                 return -1;
715
716         param->addr = addr;
717         param->len = mem_sz;
718         param->pgsz = cur_pgsz;
719         param->iova_table = iovas;
720         param->iova_table_len = n_pages;
721
722         return 0;
723 fail:
724         if (iovas)
725                 free(iovas);
726         if (addr)
727                 munmap(addr, mem_sz);
728
729         return -1;
730 }
731
732 static int
733 setup_extmem(uint32_t nb_mbufs, uint32_t mbuf_sz, bool huge)
734 {
735         struct extmem_param param;
736         int socket_id, ret;
737
738         memset(&param, 0, sizeof(param));
739
740         /* check if our heap exists */
741         socket_id = rte_malloc_heap_get_socket(EXTMEM_HEAP_NAME);
742         if (socket_id < 0) {
743                 /* create our heap */
744                 ret = rte_malloc_heap_create(EXTMEM_HEAP_NAME);
745                 if (ret < 0) {
746                         TESTPMD_LOG(ERR, "Cannot create heap\n");
747                         return -1;
748                 }
749         }
750
751         ret = create_extmem(nb_mbufs, mbuf_sz, &param, huge);
752         if (ret < 0) {
753                 TESTPMD_LOG(ERR, "Cannot create memory area\n");
754                 return -1;
755         }
756
757         /* we now have a valid memory area, so add it to heap */
758         ret = rte_malloc_heap_memory_add(EXTMEM_HEAP_NAME,
759                         param.addr, param.len, param.iova_table,
760                         param.iova_table_len, param.pgsz);
761
762         /* when using VFIO, memory is automatically mapped for DMA by EAL */
763
764         /* not needed any more */
765         free(param.iova_table);
766
767         if (ret < 0) {
768                 TESTPMD_LOG(ERR, "Cannot add memory to heap\n");
769                 munmap(param.addr, param.len);
770                 return -1;
771         }
772
773         /* success */
774
775         TESTPMD_LOG(DEBUG, "Allocated %zuMB of external memory\n",
776                         param.len >> 20);
777
778         return 0;
779 }
780
781 /*
782  * Configuration initialisation done once at init time.
783  */
784 static void
785 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
786                  unsigned int socket_id)
787 {
788         char pool_name[RTE_MEMPOOL_NAMESIZE];
789         struct rte_mempool *rte_mp = NULL;
790         uint32_t mb_size;
791
792         mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
793         mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
794
795         TESTPMD_LOG(INFO,
796                 "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
797                 pool_name, nb_mbuf, mbuf_seg_size, socket_id);
798
799         switch (mp_alloc_type) {
800         case MP_ALLOC_NATIVE:
801                 {
802                         /* wrapper to rte_mempool_create() */
803                         TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
804                                         rte_mbuf_best_mempool_ops());
805                         rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
806                                 mb_mempool_cache, 0, mbuf_seg_size, socket_id);
807                         break;
808                 }
809         case MP_ALLOC_ANON:
810                 {
811                         rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
812                                 mb_size, (unsigned int) mb_mempool_cache,
813                                 sizeof(struct rte_pktmbuf_pool_private),
814                                 socket_id, 0);
815                         if (rte_mp == NULL)
816                                 goto err;
817
818                         if (rte_mempool_populate_anon(rte_mp) == 0) {
819                                 rte_mempool_free(rte_mp);
820                                 rte_mp = NULL;
821                                 goto err;
822                         }
823                         rte_pktmbuf_pool_init(rte_mp, NULL);
824                         rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
825                         break;
826                 }
827         case MP_ALLOC_XMEM:
828         case MP_ALLOC_XMEM_HUGE:
829                 {
830                         int heap_socket;
831                         bool huge = mp_alloc_type == MP_ALLOC_XMEM_HUGE;
832
833                         if (setup_extmem(nb_mbuf, mbuf_seg_size, huge) < 0)
834                                 rte_exit(EXIT_FAILURE, "Could not create external memory\n");
835
836                         heap_socket =
837                                 rte_malloc_heap_get_socket(EXTMEM_HEAP_NAME);
838                         if (heap_socket < 0)
839                                 rte_exit(EXIT_FAILURE, "Could not get external memory socket ID\n");
840
841                         TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
842                                         rte_mbuf_best_mempool_ops());
843                         rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
844                                         mb_mempool_cache, 0, mbuf_seg_size,
845                                         heap_socket);
846                         break;
847                 }
848         default:
849                 {
850                         rte_exit(EXIT_FAILURE, "Invalid mempool creation mode\n");
851                 }
852         }
853
854 err:
855         if (rte_mp == NULL) {
856                 rte_exit(EXIT_FAILURE,
857                         "Creation of mbuf pool for socket %u failed: %s\n",
858                         socket_id, rte_strerror(rte_errno));
859         } else if (verbose_level > 0) {
860                 rte_mempool_dump(stdout, rte_mp);
861         }
862 }
863
864 /*
865  * Check given socket id is valid or not with NUMA mode,
866  * if valid, return 0, else return -1
867  */
868 static int
869 check_socket_id(const unsigned int socket_id)
870 {
871         static int warning_once = 0;
872
873         if (new_socket_id(socket_id)) {
874                 if (!warning_once && numa_support)
875                         printf("Warning: NUMA should be configured manually by"
876                                " using --port-numa-config and"
877                                " --ring-numa-config parameters along with"
878                                " --numa.\n");
879                 warning_once = 1;
880                 return -1;
881         }
882         return 0;
883 }
884
885 /*
886  * Get the allowed maximum number of RX queues.
887  * *pid return the port id which has minimal value of
888  * max_rx_queues in all ports.
889  */
890 queueid_t
891 get_allowed_max_nb_rxq(portid_t *pid)
892 {
893         queueid_t allowed_max_rxq = MAX_QUEUE_ID;
894         portid_t pi;
895         struct rte_eth_dev_info dev_info;
896
897         RTE_ETH_FOREACH_DEV(pi) {
898                 rte_eth_dev_info_get(pi, &dev_info);
899                 if (dev_info.max_rx_queues < allowed_max_rxq) {
900                         allowed_max_rxq = dev_info.max_rx_queues;
901                         *pid = pi;
902                 }
903         }
904         return allowed_max_rxq;
905 }
906
907 /*
908  * Check input rxq is valid or not.
909  * If input rxq is not greater than any of maximum number
910  * of RX queues of all ports, it is valid.
911  * if valid, return 0, else return -1
912  */
913 int
914 check_nb_rxq(queueid_t rxq)
915 {
916         queueid_t allowed_max_rxq;
917         portid_t pid = 0;
918
919         allowed_max_rxq = get_allowed_max_nb_rxq(&pid);
920         if (rxq > allowed_max_rxq) {
921                 printf("Fail: input rxq (%u) can't be greater "
922                        "than max_rx_queues (%u) of port %u\n",
923                        rxq,
924                        allowed_max_rxq,
925                        pid);
926                 return -1;
927         }
928         return 0;
929 }
930
931 /*
932  * Get the allowed maximum number of TX queues.
933  * *pid return the port id which has minimal value of
934  * max_tx_queues in all ports.
935  */
936 queueid_t
937 get_allowed_max_nb_txq(portid_t *pid)
938 {
939         queueid_t allowed_max_txq = MAX_QUEUE_ID;
940         portid_t pi;
941         struct rte_eth_dev_info dev_info;
942
943         RTE_ETH_FOREACH_DEV(pi) {
944                 rte_eth_dev_info_get(pi, &dev_info);
945                 if (dev_info.max_tx_queues < allowed_max_txq) {
946                         allowed_max_txq = dev_info.max_tx_queues;
947                         *pid = pi;
948                 }
949         }
950         return allowed_max_txq;
951 }
952
953 /*
954  * Check input txq is valid or not.
955  * If input txq is not greater than any of maximum number
956  * of TX queues of all ports, it is valid.
957  * if valid, return 0, else return -1
958  */
959 int
960 check_nb_txq(queueid_t txq)
961 {
962         queueid_t allowed_max_txq;
963         portid_t pid = 0;
964
965         allowed_max_txq = get_allowed_max_nb_txq(&pid);
966         if (txq > allowed_max_txq) {
967                 printf("Fail: input txq (%u) can't be greater "
968                        "than max_tx_queues (%u) of port %u\n",
969                        txq,
970                        allowed_max_txq,
971                        pid);
972                 return -1;
973         }
974         return 0;
975 }
976
977 static void
978 init_config(void)
979 {
980         portid_t pid;
981         struct rte_port *port;
982         struct rte_mempool *mbp;
983         unsigned int nb_mbuf_per_pool;
984         lcoreid_t  lc_id;
985         uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
986         struct rte_gro_param gro_param;
987         uint32_t gso_types;
988         int k;
989
990         memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
991
992         if (numa_support) {
993                 memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
994                 memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
995                 memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
996         }
997
998         /* Configuration of logical cores. */
999         fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
1000                                 sizeof(struct fwd_lcore *) * nb_lcores,
1001                                 RTE_CACHE_LINE_SIZE);
1002         if (fwd_lcores == NULL) {
1003                 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
1004                                                         "failed\n", nb_lcores);
1005         }
1006         for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1007                 fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
1008                                                sizeof(struct fwd_lcore),
1009                                                RTE_CACHE_LINE_SIZE);
1010                 if (fwd_lcores[lc_id] == NULL) {
1011                         rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
1012                                                                 "failed\n");
1013                 }
1014                 fwd_lcores[lc_id]->cpuid_idx = lc_id;
1015         }
1016
1017         RTE_ETH_FOREACH_DEV(pid) {
1018                 port = &ports[pid];
1019                 /* Apply default TxRx configuration for all ports */
1020                 port->dev_conf.txmode = tx_mode;
1021                 port->dev_conf.rxmode = rx_mode;
1022                 rte_eth_dev_info_get(pid, &port->dev_info);
1023
1024                 if (!(port->dev_info.tx_offload_capa &
1025                       DEV_TX_OFFLOAD_MBUF_FAST_FREE))
1026                         port->dev_conf.txmode.offloads &=
1027                                 ~DEV_TX_OFFLOAD_MBUF_FAST_FREE;
1028                 if (numa_support) {
1029                         if (port_numa[pid] != NUMA_NO_CONFIG)
1030                                 port_per_socket[port_numa[pid]]++;
1031                         else {
1032                                 uint32_t socket_id = rte_eth_dev_socket_id(pid);
1033
1034                                 /* if socket_id is invalid, set to 0 */
1035                                 if (check_socket_id(socket_id) < 0)
1036                                         socket_id = 0;
1037                                 port_per_socket[socket_id]++;
1038                         }
1039                 }
1040
1041                 /* Apply Rx offloads configuration */
1042                 for (k = 0; k < port->dev_info.max_rx_queues; k++)
1043                         port->rx_conf[k].offloads =
1044                                 port->dev_conf.rxmode.offloads;
1045                 /* Apply Tx offloads configuration */
1046                 for (k = 0; k < port->dev_info.max_tx_queues; k++)
1047                         port->tx_conf[k].offloads =
1048                                 port->dev_conf.txmode.offloads;
1049
1050                 /* set flag to initialize port/queue */
1051                 port->need_reconfig = 1;
1052                 port->need_reconfig_queues = 1;
1053         }
1054
1055         /*
1056          * Create pools of mbuf.
1057          * If NUMA support is disabled, create a single pool of mbuf in
1058          * socket 0 memory by default.
1059          * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
1060          *
1061          * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
1062          * nb_txd can be configured at run time.
1063          */
1064         if (param_total_num_mbufs)
1065                 nb_mbuf_per_pool = param_total_num_mbufs;
1066         else {
1067                 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
1068                         (nb_lcores * mb_mempool_cache) +
1069                         RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
1070                 nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
1071         }
1072
1073         if (numa_support) {
1074                 uint8_t i;
1075
1076                 for (i = 0; i < num_sockets; i++)
1077                         mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
1078                                          socket_ids[i]);
1079         } else {
1080                 if (socket_num == UMA_NO_CONFIG)
1081                         mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
1082                 else
1083                         mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
1084                                                  socket_num);
1085         }
1086
1087         init_port_config();
1088
1089         gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
1090                 DEV_TX_OFFLOAD_GRE_TNL_TSO | DEV_TX_OFFLOAD_UDP_TSO;
1091         /*
1092          * Records which Mbuf pool to use by each logical core, if needed.
1093          */
1094         for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1095                 mbp = mbuf_pool_find(
1096                         rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
1097
1098                 if (mbp == NULL)
1099                         mbp = mbuf_pool_find(0);
1100                 fwd_lcores[lc_id]->mbp = mbp;
1101                 /* initialize GSO context */
1102                 fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp;
1103                 fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp;
1104                 fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types;
1105                 fwd_lcores[lc_id]->gso_ctx.gso_size = ETHER_MAX_LEN -
1106                         ETHER_CRC_LEN;
1107                 fwd_lcores[lc_id]->gso_ctx.flag = 0;
1108         }
1109
1110         /* Configuration of packet forwarding streams. */
1111         if (init_fwd_streams() < 0)
1112                 rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
1113
1114         fwd_config_setup();
1115
1116         /* create a gro context for each lcore */
1117         gro_param.gro_types = RTE_GRO_TCP_IPV4;
1118         gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES;
1119         gro_param.max_item_per_flow = MAX_PKT_BURST;
1120         for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1121                 gro_param.socket_id = rte_lcore_to_socket_id(
1122                                 fwd_lcores_cpuids[lc_id]);
1123                 fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param);
1124                 if (fwd_lcores[lc_id]->gro_ctx == NULL) {
1125                         rte_exit(EXIT_FAILURE,
1126                                         "rte_gro_ctx_create() failed\n");
1127                 }
1128         }
1129
1130 #if defined RTE_LIBRTE_PMD_SOFTNIC
1131         if (strcmp(cur_fwd_eng->fwd_mode_name, "softnic") == 0) {
1132                 RTE_ETH_FOREACH_DEV(pid) {
1133                         port = &ports[pid];
1134                         const char *driver = port->dev_info.driver_name;
1135
1136                         if (strcmp(driver, "net_softnic") == 0)
1137                                 port->softport.fwd_lcore_arg = fwd_lcores;
1138                 }
1139         }
1140 #endif
1141
1142 }
1143
1144
1145 void
1146 reconfig(portid_t new_port_id, unsigned socket_id)
1147 {
1148         struct rte_port *port;
1149
1150         /* Reconfiguration of Ethernet ports. */
1151         port = &ports[new_port_id];
1152         rte_eth_dev_info_get(new_port_id, &port->dev_info);
1153
1154         /* set flag to initialize port/queue */
1155         port->need_reconfig = 1;
1156         port->need_reconfig_queues = 1;
1157         port->socket_id = socket_id;
1158
1159         init_port_config();
1160 }
1161
1162
1163 int
1164 init_fwd_streams(void)
1165 {
1166         portid_t pid;
1167         struct rte_port *port;
1168         streamid_t sm_id, nb_fwd_streams_new;
1169         queueid_t q;
1170
1171         /* set socket id according to numa or not */
1172         RTE_ETH_FOREACH_DEV(pid) {
1173                 port = &ports[pid];
1174                 if (nb_rxq > port->dev_info.max_rx_queues) {
1175                         printf("Fail: nb_rxq(%d) is greater than "
1176                                 "max_rx_queues(%d)\n", nb_rxq,
1177                                 port->dev_info.max_rx_queues);
1178                         return -1;
1179                 }
1180                 if (nb_txq > port->dev_info.max_tx_queues) {
1181                         printf("Fail: nb_txq(%d) is greater than "
1182                                 "max_tx_queues(%d)\n", nb_txq,
1183                                 port->dev_info.max_tx_queues);
1184                         return -1;
1185                 }
1186                 if (numa_support) {
1187                         if (port_numa[pid] != NUMA_NO_CONFIG)
1188                                 port->socket_id = port_numa[pid];
1189                         else {
1190                                 port->socket_id = rte_eth_dev_socket_id(pid);
1191
1192                                 /* if socket_id is invalid, set to 0 */
1193                                 if (check_socket_id(port->socket_id) < 0)
1194                                         port->socket_id = 0;
1195                         }
1196                 }
1197                 else {
1198                         if (socket_num == UMA_NO_CONFIG)
1199                                 port->socket_id = 0;
1200                         else
1201                                 port->socket_id = socket_num;
1202                 }
1203         }
1204
1205         q = RTE_MAX(nb_rxq, nb_txq);
1206         if (q == 0) {
1207                 printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
1208                 return -1;
1209         }
1210         nb_fwd_streams_new = (streamid_t)(nb_ports * q);
1211         if (nb_fwd_streams_new == nb_fwd_streams)
1212                 return 0;
1213         /* clear the old */
1214         if (fwd_streams != NULL) {
1215                 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
1216                         if (fwd_streams[sm_id] == NULL)
1217                                 continue;
1218                         rte_free(fwd_streams[sm_id]);
1219                         fwd_streams[sm_id] = NULL;
1220                 }
1221                 rte_free(fwd_streams);
1222                 fwd_streams = NULL;
1223         }
1224
1225         /* init new */
1226         nb_fwd_streams = nb_fwd_streams_new;
1227         if (nb_fwd_streams) {
1228                 fwd_streams = rte_zmalloc("testpmd: fwd_streams",
1229                         sizeof(struct fwd_stream *) * nb_fwd_streams,
1230                         RTE_CACHE_LINE_SIZE);
1231                 if (fwd_streams == NULL)
1232                         rte_exit(EXIT_FAILURE, "rte_zmalloc(%d"
1233                                  " (struct fwd_stream *)) failed\n",
1234                                  nb_fwd_streams);
1235
1236                 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
1237                         fwd_streams[sm_id] = rte_zmalloc("testpmd:"
1238                                 " struct fwd_stream", sizeof(struct fwd_stream),
1239                                 RTE_CACHE_LINE_SIZE);
1240                         if (fwd_streams[sm_id] == NULL)
1241                                 rte_exit(EXIT_FAILURE, "rte_zmalloc"
1242                                          "(struct fwd_stream) failed\n");
1243                 }
1244         }
1245
1246         return 0;
1247 }
1248
1249 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1250 static void
1251 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
1252 {
1253         unsigned int total_burst;
1254         unsigned int nb_burst;
1255         unsigned int burst_stats[3];
1256         uint16_t pktnb_stats[3];
1257         uint16_t nb_pkt;
1258         int burst_percent[3];
1259
1260         /*
1261          * First compute the total number of packet bursts and the
1262          * two highest numbers of bursts of the same number of packets.
1263          */
1264         total_burst = 0;
1265         burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
1266         pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
1267         for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
1268                 nb_burst = pbs->pkt_burst_spread[nb_pkt];
1269                 if (nb_burst == 0)
1270                         continue;
1271                 total_burst += nb_burst;
1272                 if (nb_burst > burst_stats[0]) {
1273                         burst_stats[1] = burst_stats[0];
1274                         pktnb_stats[1] = pktnb_stats[0];
1275                         burst_stats[0] = nb_burst;
1276                         pktnb_stats[0] = nb_pkt;
1277                 } else if (nb_burst > burst_stats[1]) {
1278                         burst_stats[1] = nb_burst;
1279                         pktnb_stats[1] = nb_pkt;
1280                 }
1281         }
1282         if (total_burst == 0)
1283                 return;
1284         burst_percent[0] = (burst_stats[0] * 100) / total_burst;
1285         printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
1286                burst_percent[0], (int) pktnb_stats[0]);
1287         if (burst_stats[0] == total_burst) {
1288                 printf("]\n");
1289                 return;
1290         }
1291         if (burst_stats[0] + burst_stats[1] == total_burst) {
1292                 printf(" + %d%% of %d pkts]\n",
1293                        100 - burst_percent[0], pktnb_stats[1]);
1294                 return;
1295         }
1296         burst_percent[1] = (burst_stats[1] * 100) / total_burst;
1297         burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
1298         if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
1299                 printf(" + %d%% of others]\n", 100 - burst_percent[0]);
1300                 return;
1301         }
1302         printf(" + %d%% of %d pkts + %d%% of others]\n",
1303                burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
1304 }
1305 #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
1306
1307 static void
1308 fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
1309 {
1310         struct rte_port *port;
1311         uint8_t i;
1312
1313         static const char *fwd_stats_border = "----------------------";
1314
1315         port = &ports[port_id];
1316         printf("\n  %s Forward statistics for port %-2d %s\n",
1317                fwd_stats_border, port_id, fwd_stats_border);
1318
1319         if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
1320                 printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1321                        "%-"PRIu64"\n",
1322                        stats->ipackets, stats->imissed,
1323                        (uint64_t) (stats->ipackets + stats->imissed));
1324
1325                 if (cur_fwd_eng == &csum_fwd_engine)
1326                         printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64"Bad-outer-l4csum: %-14"PRIu64"\n",
1327                                port->rx_bad_ip_csum, port->rx_bad_l4_csum,
1328                                port->rx_bad_outer_l4_csum);
1329                 if ((stats->ierrors + stats->rx_nombuf) > 0) {
1330                         printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
1331                         printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
1332                 }
1333
1334                 printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1335                        "%-"PRIu64"\n",
1336                        stats->opackets, port->tx_dropped,
1337                        (uint64_t) (stats->opackets + port->tx_dropped));
1338         }
1339         else {
1340                 printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
1341                        "%14"PRIu64"\n",
1342                        stats->ipackets, stats->imissed,
1343                        (uint64_t) (stats->ipackets + stats->imissed));
1344
1345                 if (cur_fwd_eng == &csum_fwd_engine)
1346                         printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"    Bad-outer-l4csum: %-14"PRIu64"\n",
1347                                port->rx_bad_ip_csum, port->rx_bad_l4_csum,
1348                                port->rx_bad_outer_l4_csum);
1349                 if ((stats->ierrors + stats->rx_nombuf) > 0) {
1350                         printf("  RX-error:%"PRIu64"\n", stats->ierrors);
1351                         printf("  RX-nombufs:             %14"PRIu64"\n",
1352                                stats->rx_nombuf);
1353                 }
1354
1355                 printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
1356                        "%14"PRIu64"\n",
1357                        stats->opackets, port->tx_dropped,
1358                        (uint64_t) (stats->opackets + port->tx_dropped));
1359         }
1360
1361 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1362         if (port->rx_stream)
1363                 pkt_burst_stats_display("RX",
1364                         &port->rx_stream->rx_burst_stats);
1365         if (port->tx_stream)
1366                 pkt_burst_stats_display("TX",
1367                         &port->tx_stream->tx_burst_stats);
1368 #endif
1369
1370         if (port->rx_queue_stats_mapping_enabled) {
1371                 printf("\n");
1372                 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
1373                         printf("  Stats reg %2d RX-packets:%14"PRIu64
1374                                "     RX-errors:%14"PRIu64
1375                                "    RX-bytes:%14"PRIu64"\n",
1376                                i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
1377                 }
1378                 printf("\n");
1379         }
1380         if (port->tx_queue_stats_mapping_enabled) {
1381                 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
1382                         printf("  Stats reg %2d TX-packets:%14"PRIu64
1383                                "                                 TX-bytes:%14"PRIu64"\n",
1384                                i, stats->q_opackets[i], stats->q_obytes[i]);
1385                 }
1386         }
1387
1388         printf("  %s--------------------------------%s\n",
1389                fwd_stats_border, fwd_stats_border);
1390 }
1391
1392 static void
1393 fwd_stream_stats_display(streamid_t stream_id)
1394 {
1395         struct fwd_stream *fs;
1396         static const char *fwd_top_stats_border = "-------";
1397
1398         fs = fwd_streams[stream_id];
1399         if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
1400             (fs->fwd_dropped == 0))
1401                 return;
1402         printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
1403                "TX Port=%2d/Queue=%2d %s\n",
1404                fwd_top_stats_border, fs->rx_port, fs->rx_queue,
1405                fs->tx_port, fs->tx_queue, fwd_top_stats_border);
1406         printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
1407                fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
1408
1409         /* if checksum mode */
1410         if (cur_fwd_eng == &csum_fwd_engine) {
1411                printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
1412                         "%-14u Rx- bad outer L4 checksum: %-14u\n",
1413                         fs->rx_bad_ip_csum, fs->rx_bad_l4_csum,
1414                         fs->rx_bad_outer_l4_csum);
1415         }
1416
1417 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1418         pkt_burst_stats_display("RX", &fs->rx_burst_stats);
1419         pkt_burst_stats_display("TX", &fs->tx_burst_stats);
1420 #endif
1421 }
1422
1423 static void
1424 flush_fwd_rx_queues(void)
1425 {
1426         struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1427         portid_t  rxp;
1428         portid_t port_id;
1429         queueid_t rxq;
1430         uint16_t  nb_rx;
1431         uint16_t  i;
1432         uint8_t   j;
1433         uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
1434         uint64_t timer_period;
1435
1436         /* convert to number of cycles */
1437         timer_period = rte_get_timer_hz(); /* 1 second timeout */
1438
1439         for (j = 0; j < 2; j++) {
1440                 for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
1441                         for (rxq = 0; rxq < nb_rxq; rxq++) {
1442                                 port_id = fwd_ports_ids[rxp];
1443                                 /**
1444                                 * testpmd can stuck in the below do while loop
1445                                 * if rte_eth_rx_burst() always returns nonzero
1446                                 * packets. So timer is added to exit this loop
1447                                 * after 1sec timer expiry.
1448                                 */
1449                                 prev_tsc = rte_rdtsc();
1450                                 do {
1451                                         nb_rx = rte_eth_rx_burst(port_id, rxq,
1452                                                 pkts_burst, MAX_PKT_BURST);
1453                                         for (i = 0; i < nb_rx; i++)
1454                                                 rte_pktmbuf_free(pkts_burst[i]);
1455
1456                                         cur_tsc = rte_rdtsc();
1457                                         diff_tsc = cur_tsc - prev_tsc;
1458                                         timer_tsc += diff_tsc;
1459                                 } while ((nb_rx > 0) &&
1460                                         (timer_tsc < timer_period));
1461                                 timer_tsc = 0;
1462                         }
1463                 }
1464                 rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
1465         }
1466 }
1467
1468 static void
1469 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
1470 {
1471         struct fwd_stream **fsm;
1472         streamid_t nb_fs;
1473         streamid_t sm_id;
1474 #ifdef RTE_LIBRTE_BITRATE
1475         uint64_t tics_per_1sec;
1476         uint64_t tics_datum;
1477         uint64_t tics_current;
1478         uint16_t i, cnt_ports;
1479
1480         cnt_ports = nb_ports;
1481         tics_datum = rte_rdtsc();
1482         tics_per_1sec = rte_get_timer_hz();
1483 #endif
1484         fsm = &fwd_streams[fc->stream_idx];
1485         nb_fs = fc->stream_nb;
1486         do {
1487                 for (sm_id = 0; sm_id < nb_fs; sm_id++)
1488                         (*pkt_fwd)(fsm[sm_id]);
1489 #ifdef RTE_LIBRTE_BITRATE
1490                 if (bitrate_enabled != 0 &&
1491                                 bitrate_lcore_id == rte_lcore_id()) {
1492                         tics_current = rte_rdtsc();
1493                         if (tics_current - tics_datum >= tics_per_1sec) {
1494                                 /* Periodic bitrate calculation */
1495                                 for (i = 0; i < cnt_ports; i++)
1496                                         rte_stats_bitrate_calc(bitrate_data,
1497                                                 ports_ids[i]);
1498                                 tics_datum = tics_current;
1499                         }
1500                 }
1501 #endif
1502 #ifdef RTE_LIBRTE_LATENCY_STATS
1503                 if (latencystats_enabled != 0 &&
1504                                 latencystats_lcore_id == rte_lcore_id())
1505                         rte_latencystats_update();
1506 #endif
1507
1508         } while (! fc->stopped);
1509 }
1510
1511 static int
1512 start_pkt_forward_on_core(void *fwd_arg)
1513 {
1514         run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
1515                              cur_fwd_config.fwd_eng->packet_fwd);
1516         return 0;
1517 }
1518
1519 /*
1520  * Run the TXONLY packet forwarding engine to send a single burst of packets.
1521  * Used to start communication flows in network loopback test configurations.
1522  */
1523 static int
1524 run_one_txonly_burst_on_core(void *fwd_arg)
1525 {
1526         struct fwd_lcore *fwd_lc;
1527         struct fwd_lcore tmp_lcore;
1528
1529         fwd_lc = (struct fwd_lcore *) fwd_arg;
1530         tmp_lcore = *fwd_lc;
1531         tmp_lcore.stopped = 1;
1532         run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
1533         return 0;
1534 }
1535
1536 /*
1537  * Launch packet forwarding:
1538  *     - Setup per-port forwarding context.
1539  *     - launch logical cores with their forwarding configuration.
1540  */
1541 static void
1542 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
1543 {
1544         port_fwd_begin_t port_fwd_begin;
1545         unsigned int i;
1546         unsigned int lc_id;
1547         int diag;
1548
1549         port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
1550         if (port_fwd_begin != NULL) {
1551                 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1552                         (*port_fwd_begin)(fwd_ports_ids[i]);
1553         }
1554         for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1555                 lc_id = fwd_lcores_cpuids[i];
1556                 if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1557                         fwd_lcores[i]->stopped = 0;
1558                         diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1559                                                      fwd_lcores[i], lc_id);
1560                         if (diag != 0)
1561                                 printf("launch lcore %u failed - diag=%d\n",
1562                                        lc_id, diag);
1563                 }
1564         }
1565 }
1566
1567 /*
1568  * Update the forward ports list.
1569  */
1570 void
1571 update_fwd_ports(portid_t new_pid)
1572 {
1573         unsigned int i;
1574         unsigned int new_nb_fwd_ports = 0;
1575         int move = 0;
1576
1577         for (i = 0; i < nb_fwd_ports; ++i) {
1578                 if (port_id_is_invalid(fwd_ports_ids[i], DISABLED_WARN))
1579                         move = 1;
1580                 else if (move)
1581                         fwd_ports_ids[new_nb_fwd_ports++] = fwd_ports_ids[i];
1582                 else
1583                         new_nb_fwd_ports++;
1584         }
1585         if (new_pid < RTE_MAX_ETHPORTS)
1586                 fwd_ports_ids[new_nb_fwd_ports++] = new_pid;
1587
1588         nb_fwd_ports = new_nb_fwd_ports;
1589         nb_cfg_ports = new_nb_fwd_ports;
1590 }
1591
1592 /*
1593  * Launch packet forwarding configuration.
1594  */
1595 void
1596 start_packet_forwarding(int with_tx_first)
1597 {
1598         port_fwd_begin_t port_fwd_begin;
1599         port_fwd_end_t  port_fwd_end;
1600         struct rte_port *port;
1601         unsigned int i;
1602         portid_t   pt_id;
1603         streamid_t sm_id;
1604
1605         if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
1606                 rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
1607
1608         if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
1609                 rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
1610
1611         if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
1612                 strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
1613                 (!nb_rxq || !nb_txq))
1614                 rte_exit(EXIT_FAILURE,
1615                         "Either rxq or txq are 0, cannot use %s fwd mode\n",
1616                         cur_fwd_eng->fwd_mode_name);
1617
1618         if (all_ports_started() == 0) {
1619                 printf("Not all ports were started\n");
1620                 return;
1621         }
1622         if (test_done == 0) {
1623                 printf("Packet forwarding already started\n");
1624                 return;
1625         }
1626
1627
1628         if(dcb_test) {
1629                 for (i = 0; i < nb_fwd_ports; i++) {
1630                         pt_id = fwd_ports_ids[i];
1631                         port = &ports[pt_id];
1632                         if (!port->dcb_flag) {
1633                                 printf("In DCB mode, all forwarding ports must "
1634                                        "be configured in this mode.\n");
1635                                 return;
1636                         }
1637                 }
1638                 if (nb_fwd_lcores == 1) {
1639                         printf("In DCB mode,the nb forwarding cores "
1640                                "should be larger than 1.\n");
1641                         return;
1642                 }
1643         }
1644         test_done = 0;
1645
1646         fwd_config_setup();
1647
1648         if(!no_flush_rx)
1649                 flush_fwd_rx_queues();
1650
1651         pkt_fwd_config_display(&cur_fwd_config);
1652         rxtx_config_display();
1653
1654         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1655                 pt_id = fwd_ports_ids[i];
1656                 port = &ports[pt_id];
1657                 rte_eth_stats_get(pt_id, &port->stats);
1658                 port->tx_dropped = 0;
1659
1660                 map_port_queue_stats_mapping_registers(pt_id, port);
1661         }
1662         for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1663                 fwd_streams[sm_id]->rx_packets = 0;
1664                 fwd_streams[sm_id]->tx_packets = 0;
1665                 fwd_streams[sm_id]->fwd_dropped = 0;
1666                 fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1667                 fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1668                 fwd_streams[sm_id]->rx_bad_outer_l4_csum = 0;
1669
1670 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1671                 memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1672                        sizeof(fwd_streams[sm_id]->rx_burst_stats));
1673                 memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1674                        sizeof(fwd_streams[sm_id]->tx_burst_stats));
1675 #endif
1676 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1677                 fwd_streams[sm_id]->core_cycles = 0;
1678 #endif
1679         }
1680         if (with_tx_first) {
1681                 port_fwd_begin = tx_only_engine.port_fwd_begin;
1682                 if (port_fwd_begin != NULL) {
1683                         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1684                                 (*port_fwd_begin)(fwd_ports_ids[i]);
1685                 }
1686                 while (with_tx_first--) {
1687                         launch_packet_forwarding(
1688                                         run_one_txonly_burst_on_core);
1689                         rte_eal_mp_wait_lcore();
1690                 }
1691                 port_fwd_end = tx_only_engine.port_fwd_end;
1692                 if (port_fwd_end != NULL) {
1693                         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1694                                 (*port_fwd_end)(fwd_ports_ids[i]);
1695                 }
1696         }
1697         launch_packet_forwarding(start_pkt_forward_on_core);
1698 }
1699
1700 void
1701 stop_packet_forwarding(void)
1702 {
1703         struct rte_eth_stats stats;
1704         struct rte_port *port;
1705         port_fwd_end_t  port_fwd_end;
1706         int i;
1707         portid_t   pt_id;
1708         streamid_t sm_id;
1709         lcoreid_t  lc_id;
1710         uint64_t total_recv;
1711         uint64_t total_xmit;
1712         uint64_t total_rx_dropped;
1713         uint64_t total_tx_dropped;
1714         uint64_t total_rx_nombuf;
1715         uint64_t tx_dropped;
1716         uint64_t rx_bad_ip_csum;
1717         uint64_t rx_bad_l4_csum;
1718 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1719         uint64_t fwd_cycles;
1720 #endif
1721
1722         static const char *acc_stats_border = "+++++++++++++++";
1723
1724         if (test_done) {
1725                 printf("Packet forwarding not started\n");
1726                 return;
1727         }
1728         printf("Telling cores to stop...");
1729         for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1730                 fwd_lcores[lc_id]->stopped = 1;
1731         printf("\nWaiting for lcores to finish...\n");
1732         rte_eal_mp_wait_lcore();
1733         port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1734         if (port_fwd_end != NULL) {
1735                 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1736                         pt_id = fwd_ports_ids[i];
1737                         (*port_fwd_end)(pt_id);
1738                 }
1739         }
1740 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1741         fwd_cycles = 0;
1742 #endif
1743         for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1744                 if (cur_fwd_config.nb_fwd_streams >
1745                     cur_fwd_config.nb_fwd_ports) {
1746                         fwd_stream_stats_display(sm_id);
1747                         ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1748                         ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1749                 } else {
1750                         ports[fwd_streams[sm_id]->tx_port].tx_stream =
1751                                 fwd_streams[sm_id];
1752                         ports[fwd_streams[sm_id]->rx_port].rx_stream =
1753                                 fwd_streams[sm_id];
1754                 }
1755                 tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1756                 tx_dropped = (uint64_t) (tx_dropped +
1757                                          fwd_streams[sm_id]->fwd_dropped);
1758                 ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1759
1760                 rx_bad_ip_csum =
1761                         ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1762                 rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1763                                          fwd_streams[sm_id]->rx_bad_ip_csum);
1764                 ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1765                                                         rx_bad_ip_csum;
1766
1767                 rx_bad_l4_csum =
1768                         ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1769                 rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1770                                          fwd_streams[sm_id]->rx_bad_l4_csum);
1771                 ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1772                                                         rx_bad_l4_csum;
1773
1774                 ports[fwd_streams[sm_id]->rx_port].rx_bad_outer_l4_csum +=
1775                                 fwd_streams[sm_id]->rx_bad_outer_l4_csum;
1776
1777 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1778                 fwd_cycles = (uint64_t) (fwd_cycles +
1779                                          fwd_streams[sm_id]->core_cycles);
1780 #endif
1781         }
1782         total_recv = 0;
1783         total_xmit = 0;
1784         total_rx_dropped = 0;
1785         total_tx_dropped = 0;
1786         total_rx_nombuf  = 0;
1787         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1788                 pt_id = fwd_ports_ids[i];
1789
1790                 port = &ports[pt_id];
1791                 rte_eth_stats_get(pt_id, &stats);
1792                 stats.ipackets -= port->stats.ipackets;
1793                 port->stats.ipackets = 0;
1794                 stats.opackets -= port->stats.opackets;
1795                 port->stats.opackets = 0;
1796                 stats.ibytes   -= port->stats.ibytes;
1797                 port->stats.ibytes = 0;
1798                 stats.obytes   -= port->stats.obytes;
1799                 port->stats.obytes = 0;
1800                 stats.imissed  -= port->stats.imissed;
1801                 port->stats.imissed = 0;
1802                 stats.oerrors  -= port->stats.oerrors;
1803                 port->stats.oerrors = 0;
1804                 stats.rx_nombuf -= port->stats.rx_nombuf;
1805                 port->stats.rx_nombuf = 0;
1806
1807                 total_recv += stats.ipackets;
1808                 total_xmit += stats.opackets;
1809                 total_rx_dropped += stats.imissed;
1810                 total_tx_dropped += port->tx_dropped;
1811                 total_rx_nombuf  += stats.rx_nombuf;
1812
1813                 fwd_port_stats_display(pt_id, &stats);
1814         }
1815
1816         printf("\n  %s Accumulated forward statistics for all ports"
1817                "%s\n",
1818                acc_stats_border, acc_stats_border);
1819         printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1820                "%-"PRIu64"\n"
1821                "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1822                "%-"PRIu64"\n",
1823                total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1824                total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1825         if (total_rx_nombuf > 0)
1826                 printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1827         printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1828                "%s\n",
1829                acc_stats_border, acc_stats_border);
1830 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1831         if (total_recv > 0)
1832                 printf("\n  CPU cycles/packet=%u (total cycles="
1833                        "%"PRIu64" / total RX packets=%"PRIu64")\n",
1834                        (unsigned int)(fwd_cycles / total_recv),
1835                        fwd_cycles, total_recv);
1836 #endif
1837         printf("\nDone.\n");
1838         test_done = 1;
1839 }
1840
1841 void
1842 dev_set_link_up(portid_t pid)
1843 {
1844         if (rte_eth_dev_set_link_up(pid) < 0)
1845                 printf("\nSet link up fail.\n");
1846 }
1847
1848 void
1849 dev_set_link_down(portid_t pid)
1850 {
1851         if (rte_eth_dev_set_link_down(pid) < 0)
1852                 printf("\nSet link down fail.\n");
1853 }
1854
1855 static int
1856 all_ports_started(void)
1857 {
1858         portid_t pi;
1859         struct rte_port *port;
1860
1861         RTE_ETH_FOREACH_DEV(pi) {
1862                 port = &ports[pi];
1863                 /* Check if there is a port which is not started */
1864                 if ((port->port_status != RTE_PORT_STARTED) &&
1865                         (port->slave_flag == 0))
1866                         return 0;
1867         }
1868
1869         /* No port is not started */
1870         return 1;
1871 }
1872
1873 int
1874 port_is_stopped(portid_t port_id)
1875 {
1876         struct rte_port *port = &ports[port_id];
1877
1878         if ((port->port_status != RTE_PORT_STOPPED) &&
1879             (port->slave_flag == 0))
1880                 return 0;
1881         return 1;
1882 }
1883
1884 int
1885 all_ports_stopped(void)
1886 {
1887         portid_t pi;
1888
1889         RTE_ETH_FOREACH_DEV(pi) {
1890                 if (!port_is_stopped(pi))
1891                         return 0;
1892         }
1893
1894         return 1;
1895 }
1896
1897 int
1898 port_is_started(portid_t port_id)
1899 {
1900         if (port_id_is_invalid(port_id, ENABLED_WARN))
1901                 return 0;
1902
1903         if (ports[port_id].port_status != RTE_PORT_STARTED)
1904                 return 0;
1905
1906         return 1;
1907 }
1908
1909 static int
1910 port_is_closed(portid_t port_id)
1911 {
1912         if (port_id_is_invalid(port_id, ENABLED_WARN))
1913                 return 0;
1914
1915         if (ports[port_id].port_status != RTE_PORT_CLOSED)
1916                 return 0;
1917
1918         return 1;
1919 }
1920
1921 int
1922 start_port(portid_t pid)
1923 {
1924         int diag, need_check_link_status = -1;
1925         portid_t pi;
1926         queueid_t qi;
1927         struct rte_port *port;
1928         struct ether_addr mac_addr;
1929         enum rte_eth_event_type event_type;
1930
1931         if (port_id_is_invalid(pid, ENABLED_WARN))
1932                 return 0;
1933
1934         if(dcb_config)
1935                 dcb_test = 1;
1936         RTE_ETH_FOREACH_DEV(pi) {
1937                 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1938                         continue;
1939
1940                 need_check_link_status = 0;
1941                 port = &ports[pi];
1942                 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1943                                                  RTE_PORT_HANDLING) == 0) {
1944                         printf("Port %d is now not stopped\n", pi);
1945                         continue;
1946                 }
1947
1948                 if (port->need_reconfig > 0) {
1949                         port->need_reconfig = 0;
1950
1951                         if (flow_isolate_all) {
1952                                 int ret = port_flow_isolate(pi, 1);
1953                                 if (ret) {
1954                                         printf("Failed to apply isolated"
1955                                                " mode on port %d\n", pi);
1956                                         return -1;
1957                                 }
1958                         }
1959
1960                         printf("Configuring Port %d (socket %u)\n", pi,
1961                                         port->socket_id);
1962                         /* configure port */
1963                         diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1964                                                 &(port->dev_conf));
1965                         if (diag != 0) {
1966                                 if (rte_atomic16_cmpset(&(port->port_status),
1967                                 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1968                                         printf("Port %d can not be set back "
1969                                                         "to stopped\n", pi);
1970                                 printf("Fail to configure port %d\n", pi);
1971                                 /* try to reconfigure port next time */
1972                                 port->need_reconfig = 1;
1973                                 return -1;
1974                         }
1975                 }
1976                 if (port->need_reconfig_queues > 0) {
1977                         port->need_reconfig_queues = 0;
1978                         /* setup tx queues */
1979                         for (qi = 0; qi < nb_txq; qi++) {
1980                                 if ((numa_support) &&
1981                                         (txring_numa[pi] != NUMA_NO_CONFIG))
1982                                         diag = rte_eth_tx_queue_setup(pi, qi,
1983                                                 port->nb_tx_desc[qi],
1984                                                 txring_numa[pi],
1985                                                 &(port->tx_conf[qi]));
1986                                 else
1987                                         diag = rte_eth_tx_queue_setup(pi, qi,
1988                                                 port->nb_tx_desc[qi],
1989                                                 port->socket_id,
1990                                                 &(port->tx_conf[qi]));
1991
1992                                 if (diag == 0)
1993                                         continue;
1994
1995                                 /* Fail to setup tx queue, return */
1996                                 if (rte_atomic16_cmpset(&(port->port_status),
1997                                                         RTE_PORT_HANDLING,
1998                                                         RTE_PORT_STOPPED) == 0)
1999                                         printf("Port %d can not be set back "
2000                                                         "to stopped\n", pi);
2001                                 printf("Fail to configure port %d tx queues\n",
2002                                        pi);
2003                                 /* try to reconfigure queues next time */
2004                                 port->need_reconfig_queues = 1;
2005                                 return -1;
2006                         }
2007                         for (qi = 0; qi < nb_rxq; qi++) {
2008                                 /* setup rx queues */
2009                                 if ((numa_support) &&
2010                                         (rxring_numa[pi] != NUMA_NO_CONFIG)) {
2011                                         struct rte_mempool * mp =
2012                                                 mbuf_pool_find(rxring_numa[pi]);
2013                                         if (mp == NULL) {
2014                                                 printf("Failed to setup RX queue:"
2015                                                         "No mempool allocation"
2016                                                         " on the socket %d\n",
2017                                                         rxring_numa[pi]);
2018                                                 return -1;
2019                                         }
2020
2021                                         diag = rte_eth_rx_queue_setup(pi, qi,
2022                                              port->nb_rx_desc[qi],
2023                                              rxring_numa[pi],
2024                                              &(port->rx_conf[qi]),
2025                                              mp);
2026                                 } else {
2027                                         struct rte_mempool *mp =
2028                                                 mbuf_pool_find(port->socket_id);
2029                                         if (mp == NULL) {
2030                                                 printf("Failed to setup RX queue:"
2031                                                         "No mempool allocation"
2032                                                         " on the socket %d\n",
2033                                                         port->socket_id);
2034                                                 return -1;
2035                                         }
2036                                         diag = rte_eth_rx_queue_setup(pi, qi,
2037                                              port->nb_rx_desc[qi],
2038                                              port->socket_id,
2039                                              &(port->rx_conf[qi]),
2040                                              mp);
2041                                 }
2042                                 if (diag == 0)
2043                                         continue;
2044
2045                                 /* Fail to setup rx queue, return */
2046                                 if (rte_atomic16_cmpset(&(port->port_status),
2047                                                         RTE_PORT_HANDLING,
2048                                                         RTE_PORT_STOPPED) == 0)
2049                                         printf("Port %d can not be set back "
2050                                                         "to stopped\n", pi);
2051                                 printf("Fail to configure port %d rx queues\n",
2052                                        pi);
2053                                 /* try to reconfigure queues next time */
2054                                 port->need_reconfig_queues = 1;
2055                                 return -1;
2056                         }
2057                 }
2058
2059                 /* start port */
2060                 if (rte_eth_dev_start(pi) < 0) {
2061                         printf("Fail to start port %d\n", pi);
2062
2063                         /* Fail to setup rx queue, return */
2064                         if (rte_atomic16_cmpset(&(port->port_status),
2065                                 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2066                                 printf("Port %d can not be set back to "
2067                                                         "stopped\n", pi);
2068                         continue;
2069                 }
2070
2071                 if (rte_atomic16_cmpset(&(port->port_status),
2072                         RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
2073                         printf("Port %d can not be set into started\n", pi);
2074
2075                 rte_eth_macaddr_get(pi, &mac_addr);
2076                 printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
2077                                 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
2078                                 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
2079                                 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
2080
2081                 /* at least one port started, need checking link status */
2082                 need_check_link_status = 1;
2083         }
2084
2085         for (event_type = RTE_ETH_EVENT_UNKNOWN;
2086              event_type < RTE_ETH_EVENT_MAX;
2087              event_type++) {
2088                 diag = rte_eth_dev_callback_register(RTE_ETH_ALL,
2089                                                 event_type,
2090                                                 eth_event_callback,
2091                                                 NULL);
2092                 if (diag) {
2093                         printf("Failed to setup even callback for event %d\n",
2094                                 event_type);
2095                         return -1;
2096                 }
2097         }
2098
2099         if (need_check_link_status == 1 && !no_link_check)
2100                 check_all_ports_link_status(RTE_PORT_ALL);
2101         else if (need_check_link_status == 0)
2102                 printf("Please stop the ports first\n");
2103
2104         printf("Done\n");
2105         return 0;
2106 }
2107
2108 void
2109 stop_port(portid_t pid)
2110 {
2111         portid_t pi;
2112         struct rte_port *port;
2113         int need_check_link_status = 0;
2114
2115         if (dcb_test) {
2116                 dcb_test = 0;
2117                 dcb_config = 0;
2118         }
2119
2120         if (port_id_is_invalid(pid, ENABLED_WARN))
2121                 return;
2122
2123         printf("Stopping ports...\n");
2124
2125         RTE_ETH_FOREACH_DEV(pi) {
2126                 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2127                         continue;
2128
2129                 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2130                         printf("Please remove port %d from forwarding configuration.\n", pi);
2131                         continue;
2132                 }
2133
2134                 if (port_is_bonding_slave(pi)) {
2135                         printf("Please remove port %d from bonded device.\n", pi);
2136                         continue;
2137                 }
2138
2139                 port = &ports[pi];
2140                 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
2141                                                 RTE_PORT_HANDLING) == 0)
2142                         continue;
2143
2144                 rte_eth_dev_stop(pi);
2145
2146                 if (rte_atomic16_cmpset(&(port->port_status),
2147                         RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2148                         printf("Port %d can not be set into stopped\n", pi);
2149                 need_check_link_status = 1;
2150         }
2151         if (need_check_link_status && !no_link_check)
2152                 check_all_ports_link_status(RTE_PORT_ALL);
2153
2154         printf("Done\n");
2155 }
2156
2157 void
2158 close_port(portid_t pid)
2159 {
2160         portid_t pi;
2161         struct rte_port *port;
2162
2163         if (port_id_is_invalid(pid, ENABLED_WARN))
2164                 return;
2165
2166         printf("Closing ports...\n");
2167
2168         RTE_ETH_FOREACH_DEV(pi) {
2169                 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2170                         continue;
2171
2172                 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2173                         printf("Please remove port %d from forwarding configuration.\n", pi);
2174                         continue;
2175                 }
2176
2177                 if (port_is_bonding_slave(pi)) {
2178                         printf("Please remove port %d from bonded device.\n", pi);
2179                         continue;
2180                 }
2181
2182                 port = &ports[pi];
2183                 if (rte_atomic16_cmpset(&(port->port_status),
2184                         RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
2185                         printf("Port %d is already closed\n", pi);
2186                         continue;
2187                 }
2188
2189                 if (rte_atomic16_cmpset(&(port->port_status),
2190                         RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
2191                         printf("Port %d is now not stopped\n", pi);
2192                         continue;
2193                 }
2194
2195                 if (port->flow_list)
2196                         port_flow_flush(pi);
2197                 rte_eth_dev_close(pi);
2198
2199                 if (rte_atomic16_cmpset(&(port->port_status),
2200                         RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
2201                         printf("Port %d cannot be set to closed\n", pi);
2202         }
2203
2204         printf("Done\n");
2205 }
2206
2207 void
2208 reset_port(portid_t pid)
2209 {
2210         int diag;
2211         portid_t pi;
2212         struct rte_port *port;
2213
2214         if (port_id_is_invalid(pid, ENABLED_WARN))
2215                 return;
2216
2217         printf("Resetting ports...\n");
2218
2219         RTE_ETH_FOREACH_DEV(pi) {
2220                 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2221                         continue;
2222
2223                 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2224                         printf("Please remove port %d from forwarding "
2225                                "configuration.\n", pi);
2226                         continue;
2227                 }
2228
2229                 if (port_is_bonding_slave(pi)) {
2230                         printf("Please remove port %d from bonded device.\n",
2231                                pi);
2232                         continue;
2233                 }
2234
2235                 diag = rte_eth_dev_reset(pi);
2236                 if (diag == 0) {
2237                         port = &ports[pi];
2238                         port->need_reconfig = 1;
2239                         port->need_reconfig_queues = 1;
2240                 } else {
2241                         printf("Failed to reset port %d. diag=%d\n", pi, diag);
2242                 }
2243         }
2244
2245         printf("Done\n");
2246 }
2247
2248 static int
2249 eth_dev_event_callback_register(void)
2250 {
2251         int ret;
2252
2253         /* register the device event callback */
2254         ret = rte_dev_event_callback_register(NULL,
2255                 eth_dev_event_callback, NULL);
2256         if (ret) {
2257                 printf("Failed to register device event callback\n");
2258                 return -1;
2259         }
2260
2261         return 0;
2262 }
2263
2264
2265 static int
2266 eth_dev_event_callback_unregister(void)
2267 {
2268         int ret;
2269
2270         /* unregister the device event callback */
2271         ret = rte_dev_event_callback_unregister(NULL,
2272                 eth_dev_event_callback, NULL);
2273         if (ret < 0) {
2274                 printf("Failed to unregister device event callback\n");
2275                 return -1;
2276         }
2277
2278         return 0;
2279 }
2280
2281 void
2282 attach_port(char *identifier)
2283 {
2284         portid_t pi = 0;
2285         unsigned int socket_id;
2286
2287         printf("Attaching a new port...\n");
2288
2289         if (identifier == NULL) {
2290                 printf("Invalid parameters are specified\n");
2291                 return;
2292         }
2293
2294         if (rte_eth_dev_attach(identifier, &pi))
2295                 return;
2296
2297         socket_id = (unsigned)rte_eth_dev_socket_id(pi);
2298         /* if socket_id is invalid, set to 0 */
2299         if (check_socket_id(socket_id) < 0)
2300                 socket_id = 0;
2301         reconfig(pi, socket_id);
2302         rte_eth_promiscuous_enable(pi);
2303
2304         ports_ids[nb_ports] = pi;
2305         nb_ports = rte_eth_dev_count_avail();
2306
2307         ports[pi].port_status = RTE_PORT_STOPPED;
2308
2309         update_fwd_ports(pi);
2310
2311         printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
2312         printf("Done\n");
2313 }
2314
2315 void
2316 detach_port(portid_t port_id)
2317 {
2318         char name[RTE_ETH_NAME_MAX_LEN];
2319         uint16_t i;
2320
2321         printf("Detaching a port...\n");
2322
2323         if (!port_is_closed(port_id)) {
2324                 printf("Please close port first\n");
2325                 return;
2326         }
2327
2328         if (ports[port_id].flow_list)
2329                 port_flow_flush(port_id);
2330
2331         if (rte_eth_dev_detach(port_id, name)) {
2332                 TESTPMD_LOG(ERR, "Failed to detach port %u\n", port_id);
2333                 return;
2334         }
2335
2336         for (i = 0; i < nb_ports; i++) {
2337                 if (ports_ids[i] == port_id) {
2338                         ports_ids[i] = ports_ids[nb_ports-1];
2339                         ports_ids[nb_ports-1] = 0;
2340                         break;
2341                 }
2342         }
2343         nb_ports = rte_eth_dev_count_avail();
2344
2345         update_fwd_ports(RTE_MAX_ETHPORTS);
2346
2347         printf("Port %u is detached. Now total ports is %d\n",
2348                         port_id, nb_ports);
2349         printf("Done\n");
2350         return;
2351 }
2352
2353 void
2354 pmd_test_exit(void)
2355 {
2356         struct rte_device *device;
2357         portid_t pt_id;
2358         int ret;
2359
2360         if (test_done == 0)
2361                 stop_packet_forwarding();
2362
2363         if (ports != NULL) {
2364                 no_link_check = 1;
2365                 RTE_ETH_FOREACH_DEV(pt_id) {
2366                         printf("\nShutting down port %d...\n", pt_id);
2367                         fflush(stdout);
2368                         stop_port(pt_id);
2369                         close_port(pt_id);
2370
2371                         /*
2372                          * This is a workaround to fix a virtio-user issue that
2373                          * requires to call clean-up routine to remove existing
2374                          * socket.
2375                          * This workaround valid only for testpmd, needs a fix
2376                          * valid for all applications.
2377                          * TODO: Implement proper resource cleanup
2378                          */
2379                         device = rte_eth_devices[pt_id].device;
2380                         if (device && !strcmp(device->driver->name, "net_virtio_user"))
2381                                 detach_port(pt_id);
2382                 }
2383         }
2384
2385         if (hot_plug) {
2386                 ret = rte_dev_event_monitor_stop();
2387                 if (ret)
2388                         RTE_LOG(ERR, EAL,
2389                                 "fail to stop device event monitor.");
2390
2391                 ret = eth_dev_event_callback_unregister();
2392                 if (ret)
2393                         RTE_LOG(ERR, EAL,
2394                                 "fail to unregister all event callbacks.");
2395         }
2396
2397         printf("\nBye...\n");
2398 }
2399
2400 typedef void (*cmd_func_t)(void);
2401 struct pmd_test_command {
2402         const char *cmd_name;
2403         cmd_func_t cmd_func;
2404 };
2405
2406 #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
2407
2408 /* Check the link status of all ports in up to 9s, and print them finally */
2409 static void
2410 check_all_ports_link_status(uint32_t port_mask)
2411 {
2412 #define CHECK_INTERVAL 100 /* 100ms */
2413 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
2414         portid_t portid;
2415         uint8_t count, all_ports_up, print_flag = 0;
2416         struct rte_eth_link link;
2417
2418         printf("Checking link statuses...\n");
2419         fflush(stdout);
2420         for (count = 0; count <= MAX_CHECK_TIME; count++) {
2421                 all_ports_up = 1;
2422                 RTE_ETH_FOREACH_DEV(portid) {
2423                         if ((port_mask & (1 << portid)) == 0)
2424                                 continue;
2425                         memset(&link, 0, sizeof(link));
2426                         rte_eth_link_get_nowait(portid, &link);
2427                         /* print link status if flag set */
2428                         if (print_flag == 1) {
2429                                 if (link.link_status)
2430                                         printf(
2431                                         "Port%d Link Up. speed %u Mbps- %s\n",
2432                                         portid, link.link_speed,
2433                                 (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
2434                                         ("full-duplex") : ("half-duplex\n"));
2435                                 else
2436                                         printf("Port %d Link Down\n", portid);
2437                                 continue;
2438                         }
2439                         /* clear all_ports_up flag if any link down */
2440                         if (link.link_status == ETH_LINK_DOWN) {
2441                                 all_ports_up = 0;
2442                                 break;
2443                         }
2444                 }
2445                 /* after finally printing all link status, get out */
2446                 if (print_flag == 1)
2447                         break;
2448
2449                 if (all_ports_up == 0) {
2450                         fflush(stdout);
2451                         rte_delay_ms(CHECK_INTERVAL);
2452                 }
2453
2454                 /* set the print_flag if all ports up or timeout */
2455                 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
2456                         print_flag = 1;
2457                 }
2458
2459                 if (lsc_interrupt)
2460                         break;
2461         }
2462 }
2463
2464 static void
2465 rmv_event_callback(void *arg)
2466 {
2467         int need_to_start = 0;
2468         int org_no_link_check = no_link_check;
2469         portid_t port_id = (intptr_t)arg;
2470
2471         RTE_ETH_VALID_PORTID_OR_RET(port_id);
2472
2473         if (!test_done && port_is_forwarding(port_id)) {
2474                 need_to_start = 1;
2475                 stop_packet_forwarding();
2476         }
2477         no_link_check = 1;
2478         stop_port(port_id);
2479         no_link_check = org_no_link_check;
2480         close_port(port_id);
2481         detach_port(port_id);
2482         if (need_to_start)
2483                 start_packet_forwarding(0);
2484 }
2485
2486 /* This function is used by the interrupt thread */
2487 static int
2488 eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
2489                   void *ret_param)
2490 {
2491         static const char * const event_desc[] = {
2492                 [RTE_ETH_EVENT_UNKNOWN] = "Unknown",
2493                 [RTE_ETH_EVENT_INTR_LSC] = "LSC",
2494                 [RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
2495                 [RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
2496                 [RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
2497                 [RTE_ETH_EVENT_IPSEC] = "IPsec",
2498                 [RTE_ETH_EVENT_MACSEC] = "MACsec",
2499                 [RTE_ETH_EVENT_INTR_RMV] = "device removal",
2500                 [RTE_ETH_EVENT_NEW] = "device probed",
2501                 [RTE_ETH_EVENT_DESTROY] = "device released",
2502                 [RTE_ETH_EVENT_MAX] = NULL,
2503         };
2504
2505         RTE_SET_USED(param);
2506         RTE_SET_USED(ret_param);
2507
2508         if (type >= RTE_ETH_EVENT_MAX) {
2509                 fprintf(stderr, "\nPort %" PRIu16 ": %s called upon invalid event %d\n",
2510                         port_id, __func__, type);
2511                 fflush(stderr);
2512         } else if (event_print_mask & (UINT32_C(1) << type)) {
2513                 printf("\nPort %" PRIu16 ": %s event\n", port_id,
2514                         event_desc[type]);
2515                 fflush(stdout);
2516         }
2517
2518         if (port_id_is_invalid(port_id, DISABLED_WARN))
2519                 return 0;
2520
2521         switch (type) {
2522         case RTE_ETH_EVENT_INTR_RMV:
2523                 if (rte_eal_alarm_set(100000,
2524                                 rmv_event_callback, (void *)(intptr_t)port_id))
2525                         fprintf(stderr, "Could not set up deferred device removal\n");
2526                 break;
2527         default:
2528                 break;
2529         }
2530         return 0;
2531 }
2532
2533 /* This function is used by the interrupt thread */
2534 static void
2535 eth_dev_event_callback(char *device_name, enum rte_dev_event_type type,
2536                              __rte_unused void *arg)
2537 {
2538         if (type >= RTE_DEV_EVENT_MAX) {
2539                 fprintf(stderr, "%s called upon invalid event %d\n",
2540                         __func__, type);
2541                 fflush(stderr);
2542         }
2543
2544         switch (type) {
2545         case RTE_DEV_EVENT_REMOVE:
2546                 RTE_LOG(ERR, EAL, "The device: %s has been removed!\n",
2547                         device_name);
2548                 /* TODO: After finish failure handle, begin to stop
2549                  * packet forward, stop port, close port, detach port.
2550                  */
2551                 break;
2552         case RTE_DEV_EVENT_ADD:
2553                 RTE_LOG(ERR, EAL, "The device: %s has been added!\n",
2554                         device_name);
2555                 /* TODO: After finish kernel driver binding,
2556                  * begin to attach port.
2557                  */
2558                 break;
2559         default:
2560                 break;
2561         }
2562 }
2563
2564 static int
2565 set_tx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
2566 {
2567         uint16_t i;
2568         int diag;
2569         uint8_t mapping_found = 0;
2570
2571         for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
2572                 if ((tx_queue_stats_mappings[i].port_id == port_id) &&
2573                                 (tx_queue_stats_mappings[i].queue_id < nb_txq )) {
2574                         diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
2575                                         tx_queue_stats_mappings[i].queue_id,
2576                                         tx_queue_stats_mappings[i].stats_counter_id);
2577                         if (diag != 0)
2578                                 return diag;
2579                         mapping_found = 1;
2580                 }
2581         }
2582         if (mapping_found)
2583                 port->tx_queue_stats_mapping_enabled = 1;
2584         return 0;
2585 }
2586
2587 static int
2588 set_rx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
2589 {
2590         uint16_t i;
2591         int diag;
2592         uint8_t mapping_found = 0;
2593
2594         for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
2595                 if ((rx_queue_stats_mappings[i].port_id == port_id) &&
2596                                 (rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
2597                         diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
2598                                         rx_queue_stats_mappings[i].queue_id,
2599                                         rx_queue_stats_mappings[i].stats_counter_id);
2600                         if (diag != 0)
2601                                 return diag;
2602                         mapping_found = 1;
2603                 }
2604         }
2605         if (mapping_found)
2606                 port->rx_queue_stats_mapping_enabled = 1;
2607         return 0;
2608 }
2609
2610 static void
2611 map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port)
2612 {
2613         int diag = 0;
2614
2615         diag = set_tx_queue_stats_mapping_registers(pi, port);
2616         if (diag != 0) {
2617                 if (diag == -ENOTSUP) {
2618                         port->tx_queue_stats_mapping_enabled = 0;
2619                         printf("TX queue stats mapping not supported port id=%d\n", pi);
2620                 }
2621                 else
2622                         rte_exit(EXIT_FAILURE,
2623                                         "set_tx_queue_stats_mapping_registers "
2624                                         "failed for port id=%d diag=%d\n",
2625                                         pi, diag);
2626         }
2627
2628         diag = set_rx_queue_stats_mapping_registers(pi, port);
2629         if (diag != 0) {
2630                 if (diag == -ENOTSUP) {
2631                         port->rx_queue_stats_mapping_enabled = 0;
2632                         printf("RX queue stats mapping not supported port id=%d\n", pi);
2633                 }
2634                 else
2635                         rte_exit(EXIT_FAILURE,
2636                                         "set_rx_queue_stats_mapping_registers "
2637                                         "failed for port id=%d diag=%d\n",
2638                                         pi, diag);
2639         }
2640 }
2641
2642 static void
2643 rxtx_port_config(struct rte_port *port)
2644 {
2645         uint16_t qid;
2646
2647         for (qid = 0; qid < nb_rxq; qid++) {
2648                 port->rx_conf[qid] = port->dev_info.default_rxconf;
2649
2650                 /* Check if any Rx parameters have been passed */
2651                 if (rx_pthresh != RTE_PMD_PARAM_UNSET)
2652                         port->rx_conf[qid].rx_thresh.pthresh = rx_pthresh;
2653
2654                 if (rx_hthresh != RTE_PMD_PARAM_UNSET)
2655                         port->rx_conf[qid].rx_thresh.hthresh = rx_hthresh;
2656
2657                 if (rx_wthresh != RTE_PMD_PARAM_UNSET)
2658                         port->rx_conf[qid].rx_thresh.wthresh = rx_wthresh;
2659
2660                 if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
2661                         port->rx_conf[qid].rx_free_thresh = rx_free_thresh;
2662
2663                 if (rx_drop_en != RTE_PMD_PARAM_UNSET)
2664                         port->rx_conf[qid].rx_drop_en = rx_drop_en;
2665
2666                 port->nb_rx_desc[qid] = nb_rxd;
2667         }
2668
2669         for (qid = 0; qid < nb_txq; qid++) {
2670                 port->tx_conf[qid] = port->dev_info.default_txconf;
2671
2672                 /* Check if any Tx parameters have been passed */
2673                 if (tx_pthresh != RTE_PMD_PARAM_UNSET)
2674                         port->tx_conf[qid].tx_thresh.pthresh = tx_pthresh;
2675
2676                 if (tx_hthresh != RTE_PMD_PARAM_UNSET)
2677                         port->tx_conf[qid].tx_thresh.hthresh = tx_hthresh;
2678
2679                 if (tx_wthresh != RTE_PMD_PARAM_UNSET)
2680                         port->tx_conf[qid].tx_thresh.wthresh = tx_wthresh;
2681
2682                 if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
2683                         port->tx_conf[qid].tx_rs_thresh = tx_rs_thresh;
2684
2685                 if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
2686                         port->tx_conf[qid].tx_free_thresh = tx_free_thresh;
2687
2688                 port->nb_tx_desc[qid] = nb_txd;
2689         }
2690 }
2691
2692 void
2693 init_port_config(void)
2694 {
2695         portid_t pid;
2696         struct rte_port *port;
2697
2698         RTE_ETH_FOREACH_DEV(pid) {
2699                 port = &ports[pid];
2700                 port->dev_conf.fdir_conf = fdir_conf;
2701                 rte_eth_dev_info_get(pid, &port->dev_info);
2702                 if (nb_rxq > 1) {
2703                         port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2704                         port->dev_conf.rx_adv_conf.rss_conf.rss_hf =
2705                                 rss_hf & port->dev_info.flow_type_rss_offloads;
2706                 } else {
2707                         port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2708                         port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
2709                 }
2710
2711                 if (port->dcb_flag == 0) {
2712                         if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
2713                                 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
2714                         else
2715                                 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
2716                 }
2717
2718                 rxtx_port_config(port);
2719
2720                 rte_eth_macaddr_get(pid, &port->eth_addr);
2721
2722                 map_port_queue_stats_mapping_registers(pid, port);
2723 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
2724                 rte_pmd_ixgbe_bypass_init(pid);
2725 #endif
2726
2727                 if (lsc_interrupt &&
2728                     (rte_eth_devices[pid].data->dev_flags &
2729                      RTE_ETH_DEV_INTR_LSC))
2730                         port->dev_conf.intr_conf.lsc = 1;
2731                 if (rmv_interrupt &&
2732                     (rte_eth_devices[pid].data->dev_flags &
2733                      RTE_ETH_DEV_INTR_RMV))
2734                         port->dev_conf.intr_conf.rmv = 1;
2735         }
2736 }
2737
2738 void set_port_slave_flag(portid_t slave_pid)
2739 {
2740         struct rte_port *port;
2741
2742         port = &ports[slave_pid];
2743         port->slave_flag = 1;
2744 }
2745
2746 void clear_port_slave_flag(portid_t slave_pid)
2747 {
2748         struct rte_port *port;
2749
2750         port = &ports[slave_pid];
2751         port->slave_flag = 0;
2752 }
2753
2754 uint8_t port_is_bonding_slave(portid_t slave_pid)
2755 {
2756         struct rte_port *port;
2757
2758         port = &ports[slave_pid];
2759         if ((rte_eth_devices[slave_pid].data->dev_flags &
2760             RTE_ETH_DEV_BONDED_SLAVE) || (port->slave_flag == 1))
2761                 return 1;
2762         return 0;
2763 }
2764
2765 const uint16_t vlan_tags[] = {
2766                 0,  1,  2,  3,  4,  5,  6,  7,
2767                 8,  9, 10, 11,  12, 13, 14, 15,
2768                 16, 17, 18, 19, 20, 21, 22, 23,
2769                 24, 25, 26, 27, 28, 29, 30, 31
2770 };
2771
2772 static  int
2773 get_eth_dcb_conf(portid_t pid, struct rte_eth_conf *eth_conf,
2774                  enum dcb_mode_enable dcb_mode,
2775                  enum rte_eth_nb_tcs num_tcs,
2776                  uint8_t pfc_en)
2777 {
2778         uint8_t i;
2779         int32_t rc;
2780         struct rte_eth_rss_conf rss_conf;
2781
2782         /*
2783          * Builds up the correct configuration for dcb+vt based on the vlan tags array
2784          * given above, and the number of traffic classes available for use.
2785          */
2786         if (dcb_mode == DCB_VT_ENABLED) {
2787                 struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
2788                                 &eth_conf->rx_adv_conf.vmdq_dcb_conf;
2789                 struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
2790                                 &eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
2791
2792                 /* VMDQ+DCB RX and TX configurations */
2793                 vmdq_rx_conf->enable_default_pool = 0;
2794                 vmdq_rx_conf->default_pool = 0;
2795                 vmdq_rx_conf->nb_queue_pools =
2796                         (num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2797                 vmdq_tx_conf->nb_queue_pools =
2798                         (num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2799
2800                 vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
2801                 for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
2802                         vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
2803                         vmdq_rx_conf->pool_map[i].pools =
2804                                 1 << (i % vmdq_rx_conf->nb_queue_pools);
2805                 }
2806                 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2807                         vmdq_rx_conf->dcb_tc[i] = i % num_tcs;
2808                         vmdq_tx_conf->dcb_tc[i] = i % num_tcs;
2809                 }
2810
2811                 /* set DCB mode of RX and TX of multiple queues */
2812                 eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
2813                 eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
2814         } else {
2815                 struct rte_eth_dcb_rx_conf *rx_conf =
2816                                 &eth_conf->rx_adv_conf.dcb_rx_conf;
2817                 struct rte_eth_dcb_tx_conf *tx_conf =
2818                                 &eth_conf->tx_adv_conf.dcb_tx_conf;
2819
2820                 rc = rte_eth_dev_rss_hash_conf_get(pid, &rss_conf);
2821                 if (rc != 0)
2822                         return rc;
2823
2824                 rx_conf->nb_tcs = num_tcs;
2825                 tx_conf->nb_tcs = num_tcs;
2826
2827                 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2828                         rx_conf->dcb_tc[i] = i % num_tcs;
2829                         tx_conf->dcb_tc[i] = i % num_tcs;
2830                 }
2831
2832                 eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
2833                 eth_conf->rx_adv_conf.rss_conf = rss_conf;
2834                 eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
2835         }
2836
2837         if (pfc_en)
2838                 eth_conf->dcb_capability_en =
2839                                 ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
2840         else
2841                 eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
2842
2843         return 0;
2844 }
2845
2846 int
2847 init_port_dcb_config(portid_t pid,
2848                      enum dcb_mode_enable dcb_mode,
2849                      enum rte_eth_nb_tcs num_tcs,
2850                      uint8_t pfc_en)
2851 {
2852         struct rte_eth_conf port_conf;
2853         struct rte_port *rte_port;
2854         int retval;
2855         uint16_t i;
2856
2857         rte_port = &ports[pid];
2858
2859         memset(&port_conf, 0, sizeof(struct rte_eth_conf));
2860         /* Enter DCB configuration status */
2861         dcb_config = 1;
2862
2863         port_conf.rxmode = rte_port->dev_conf.rxmode;
2864         port_conf.txmode = rte_port->dev_conf.txmode;
2865
2866         /*set configuration of DCB in vt mode and DCB in non-vt mode*/
2867         retval = get_eth_dcb_conf(pid, &port_conf, dcb_mode, num_tcs, pfc_en);
2868         if (retval < 0)
2869                 return retval;
2870         port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
2871
2872         /* re-configure the device . */
2873         rte_eth_dev_configure(pid, nb_rxq, nb_rxq, &port_conf);
2874
2875         rte_eth_dev_info_get(pid, &rte_port->dev_info);
2876
2877         /* If dev_info.vmdq_pool_base is greater than 0,
2878          * the queue id of vmdq pools is started after pf queues.
2879          */
2880         if (dcb_mode == DCB_VT_ENABLED &&
2881             rte_port->dev_info.vmdq_pool_base > 0) {
2882                 printf("VMDQ_DCB multi-queue mode is nonsensical"
2883                         " for port %d.", pid);
2884                 return -1;
2885         }
2886
2887         /* Assume the ports in testpmd have the same dcb capability
2888          * and has the same number of rxq and txq in dcb mode
2889          */
2890         if (dcb_mode == DCB_VT_ENABLED) {
2891                 if (rte_port->dev_info.max_vfs > 0) {
2892                         nb_rxq = rte_port->dev_info.nb_rx_queues;
2893                         nb_txq = rte_port->dev_info.nb_tx_queues;
2894                 } else {
2895                         nb_rxq = rte_port->dev_info.max_rx_queues;
2896                         nb_txq = rte_port->dev_info.max_tx_queues;
2897                 }
2898         } else {
2899                 /*if vt is disabled, use all pf queues */
2900                 if (rte_port->dev_info.vmdq_pool_base == 0) {
2901                         nb_rxq = rte_port->dev_info.max_rx_queues;
2902                         nb_txq = rte_port->dev_info.max_tx_queues;
2903                 } else {
2904                         nb_rxq = (queueid_t)num_tcs;
2905                         nb_txq = (queueid_t)num_tcs;
2906
2907                 }
2908         }
2909         rx_free_thresh = 64;
2910
2911         memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2912
2913         rxtx_port_config(rte_port);
2914         /* VLAN filter */
2915         rte_port->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
2916         for (i = 0; i < RTE_DIM(vlan_tags); i++)
2917                 rx_vft_set(pid, vlan_tags[i], 1);
2918
2919         rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2920         map_port_queue_stats_mapping_registers(pid, rte_port);
2921
2922         rte_port->dcb_flag = 1;
2923
2924         return 0;
2925 }
2926
2927 static void
2928 init_port(void)
2929 {
2930         /* Configuration of Ethernet ports. */
2931         ports = rte_zmalloc("testpmd: ports",
2932                             sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2933                             RTE_CACHE_LINE_SIZE);
2934         if (ports == NULL) {
2935                 rte_exit(EXIT_FAILURE,
2936                                 "rte_zmalloc(%d struct rte_port) failed\n",
2937                                 RTE_MAX_ETHPORTS);
2938         }
2939 }
2940
2941 static void
2942 force_quit(void)
2943 {
2944         pmd_test_exit();
2945         prompt_exit();
2946 }
2947
2948 static void
2949 print_stats(void)
2950 {
2951         uint8_t i;
2952         const char clr[] = { 27, '[', '2', 'J', '\0' };
2953         const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
2954
2955         /* Clear screen and move to top left */
2956         printf("%s%s", clr, top_left);
2957
2958         printf("\nPort statistics ====================================");
2959         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2960                 nic_stats_display(fwd_ports_ids[i]);
2961 }
2962
2963 static void
2964 signal_handler(int signum)
2965 {
2966         if (signum == SIGINT || signum == SIGTERM) {
2967                 printf("\nSignal %d received, preparing to exit...\n",
2968                                 signum);
2969 #ifdef RTE_LIBRTE_PDUMP
2970                 /* uninitialize packet capture framework */
2971                 rte_pdump_uninit();
2972 #endif
2973 #ifdef RTE_LIBRTE_LATENCY_STATS
2974                 rte_latencystats_uninit();
2975 #endif
2976                 force_quit();
2977                 /* Set flag to indicate the force termination. */
2978                 f_quit = 1;
2979                 /* exit with the expected status */
2980                 signal(signum, SIG_DFL);
2981                 kill(getpid(), signum);
2982         }
2983 }
2984
2985 int
2986 main(int argc, char** argv)
2987 {
2988         int diag;
2989         portid_t port_id;
2990         uint16_t count;
2991         int ret;
2992
2993         signal(SIGINT, signal_handler);
2994         signal(SIGTERM, signal_handler);
2995
2996         diag = rte_eal_init(argc, argv);
2997         if (diag < 0)
2998                 rte_panic("Cannot init EAL\n");
2999
3000         testpmd_logtype = rte_log_register("testpmd");
3001         if (testpmd_logtype < 0)
3002                 rte_panic("Cannot register log type");
3003         rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG);
3004
3005 #ifdef RTE_LIBRTE_PDUMP
3006         /* initialize packet capture framework */
3007         rte_pdump_init(NULL);
3008 #endif
3009
3010         count = 0;
3011         RTE_ETH_FOREACH_DEV(port_id) {
3012                 ports_ids[count] = port_id;
3013                 count++;
3014         }
3015         nb_ports = (portid_t) count;
3016         if (nb_ports == 0)
3017                 TESTPMD_LOG(WARNING, "No probed ethernet devices\n");
3018
3019         /* allocate port structures, and init them */
3020         init_port();
3021
3022         set_def_fwd_config();
3023         if (nb_lcores == 0)
3024                 rte_panic("Empty set of forwarding logical cores - check the "
3025                           "core mask supplied in the command parameters\n");
3026
3027         /* Bitrate/latency stats disabled by default */
3028 #ifdef RTE_LIBRTE_BITRATE
3029         bitrate_enabled = 0;
3030 #endif
3031 #ifdef RTE_LIBRTE_LATENCY_STATS
3032         latencystats_enabled = 0;
3033 #endif
3034
3035         /* on FreeBSD, mlockall() is disabled by default */
3036 #ifdef RTE_EXEC_ENV_BSDAPP
3037         do_mlockall = 0;
3038 #else
3039         do_mlockall = 1;
3040 #endif
3041
3042         argc -= diag;
3043         argv += diag;
3044         if (argc > 1)
3045                 launch_args_parse(argc, argv);
3046
3047         if (do_mlockall && mlockall(MCL_CURRENT | MCL_FUTURE)) {
3048                 TESTPMD_LOG(NOTICE, "mlockall() failed with error \"%s\"\n",
3049                         strerror(errno));
3050         }
3051
3052         if (tx_first && interactive)
3053                 rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
3054                                 "interactive mode.\n");
3055
3056         if (tx_first && lsc_interrupt) {
3057                 printf("Warning: lsc_interrupt needs to be off when "
3058                                 " using tx_first. Disabling.\n");
3059                 lsc_interrupt = 0;
3060         }
3061
3062         if (!nb_rxq && !nb_txq)
3063                 printf("Warning: Either rx or tx queues should be non-zero\n");
3064
3065         if (nb_rxq > 1 && nb_rxq > nb_txq)
3066                 printf("Warning: nb_rxq=%d enables RSS configuration, "
3067                        "but nb_txq=%d will prevent to fully test it.\n",
3068                        nb_rxq, nb_txq);
3069
3070         init_config();
3071
3072         if (hot_plug) {
3073                 /* enable hot plug monitoring */
3074                 ret = rte_dev_event_monitor_start();
3075                 if (ret) {
3076                         rte_errno = EINVAL;
3077                         return -1;
3078                 }
3079                 eth_dev_event_callback_register();
3080
3081         }
3082
3083         if (start_port(RTE_PORT_ALL) != 0)
3084                 rte_exit(EXIT_FAILURE, "Start ports failed\n");
3085
3086         /* set all ports to promiscuous mode by default */
3087         RTE_ETH_FOREACH_DEV(port_id)
3088                 rte_eth_promiscuous_enable(port_id);
3089
3090         /* Init metrics library */
3091         rte_metrics_init(rte_socket_id());
3092
3093 #ifdef RTE_LIBRTE_LATENCY_STATS
3094         if (latencystats_enabled != 0) {
3095                 int ret = rte_latencystats_init(1, NULL);
3096                 if (ret)
3097                         printf("Warning: latencystats init()"
3098                                 " returned error %d\n", ret);
3099                 printf("Latencystats running on lcore %d\n",
3100                         latencystats_lcore_id);
3101         }
3102 #endif
3103
3104         /* Setup bitrate stats */
3105 #ifdef RTE_LIBRTE_BITRATE
3106         if (bitrate_enabled != 0) {
3107                 bitrate_data = rte_stats_bitrate_create();
3108                 if (bitrate_data == NULL)
3109                         rte_exit(EXIT_FAILURE,
3110                                 "Could not allocate bitrate data.\n");
3111                 rte_stats_bitrate_reg(bitrate_data);
3112         }
3113 #endif
3114
3115 #ifdef RTE_LIBRTE_CMDLINE
3116         if (strlen(cmdline_filename) != 0)
3117                 cmdline_read_from_file(cmdline_filename);
3118
3119         if (interactive == 1) {
3120                 if (auto_start) {
3121                         printf("Start automatic packet forwarding\n");
3122                         start_packet_forwarding(0);
3123                 }
3124                 prompt();
3125                 pmd_test_exit();
3126         } else
3127 #endif
3128         {
3129                 char c;
3130                 int rc;
3131
3132                 f_quit = 0;
3133
3134                 printf("No commandline core given, start packet forwarding\n");
3135                 start_packet_forwarding(tx_first);
3136                 if (stats_period != 0) {
3137                         uint64_t prev_time = 0, cur_time, diff_time = 0;
3138                         uint64_t timer_period;
3139
3140                         /* Convert to number of cycles */
3141                         timer_period = stats_period * rte_get_timer_hz();
3142
3143                         while (f_quit == 0) {
3144                                 cur_time = rte_get_timer_cycles();
3145                                 diff_time += cur_time - prev_time;
3146
3147                                 if (diff_time >= timer_period) {
3148                                         print_stats();
3149                                         /* Reset the timer */
3150                                         diff_time = 0;
3151                                 }
3152                                 /* Sleep to avoid unnecessary checks */
3153                                 prev_time = cur_time;
3154                                 sleep(1);
3155                         }
3156                 }
3157
3158                 printf("Press enter to exit\n");
3159                 rc = read(0, &c, 1);
3160                 pmd_test_exit();
3161                 if (rc < 0)
3162                         return 1;
3163         }
3164
3165         return 0;
3166 }