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