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