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