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