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