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