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