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