app/testpmd: add latency statistics calculation
[dpdk.git] / app / test-pmd / testpmd.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <signal.h>
38 #include <string.h>
39 #include <time.h>
40 #include <fcntl.h>
41 #include <sys/types.h>
42 #include <errno.h>
43
44 #include <sys/queue.h>
45 #include <sys/stat.h>
46
47 #include <stdint.h>
48 #include <unistd.h>
49 #include <inttypes.h>
50
51 #include <rte_common.h>
52 #include <rte_errno.h>
53 #include <rte_byteorder.h>
54 #include <rte_log.h>
55 #include <rte_debug.h>
56 #include <rte_cycles.h>
57 #include <rte_memory.h>
58 #include <rte_memcpy.h>
59 #include <rte_memzone.h>
60 #include <rte_launch.h>
61 #include <rte_eal.h>
62 #include <rte_per_lcore.h>
63 #include <rte_lcore.h>
64 #include <rte_atomic.h>
65 #include <rte_branch_prediction.h>
66 #include <rte_mempool.h>
67 #include <rte_malloc.h>
68 #include <rte_mbuf.h>
69 #include <rte_interrupts.h>
70 #include <rte_pci.h>
71 #include <rte_ether.h>
72 #include <rte_ethdev.h>
73 #include <rte_dev.h>
74 #include <rte_string_fns.h>
75 #ifdef RTE_LIBRTE_PMD_XENVIRT
76 #include <rte_eth_xenvirt.h>
77 #endif
78 #ifdef RTE_LIBRTE_PDUMP
79 #include <rte_pdump.h>
80 #endif
81 #include <rte_flow.h>
82 #include <rte_metrics.h>
83 #ifdef RTE_LIBRTE_BITRATE
84 #include <rte_bitrate.h>
85 #endif
86 #include <rte_metrics.h>
87 #ifdef RTE_LIBRTE_LATENCY_STATS
88 #include <rte_latencystats.h>
89 #endif
90
91 #include "testpmd.h"
92
93 uint16_t verbose_level = 0; /**< Silent by default. */
94
95 /* use master core for command line ? */
96 uint8_t interactive = 0;
97 uint8_t auto_start = 0;
98
99 /*
100  * NUMA support configuration.
101  * When set, the NUMA support attempts to dispatch the allocation of the
102  * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
103  * probed ports among the CPU sockets 0 and 1.
104  * Otherwise, all memory is allocated from CPU socket 0.
105  */
106 uint8_t numa_support = 0; /**< No numa support by default */
107
108 /*
109  * In UMA mode,all memory is allocated from socket 0 if --socket-num is
110  * not configured.
111  */
112 uint8_t socket_num = UMA_NO_CONFIG;
113
114 /*
115  * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs.
116  */
117 uint8_t mp_anon = 0;
118
119 /*
120  * Record the Ethernet address of peer target ports to which packets are
121  * forwarded.
122  * Must be instantiated with the ethernet addresses of peer traffic generator
123  * ports.
124  */
125 struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
126 portid_t nb_peer_eth_addrs = 0;
127
128 /*
129  * Probed Target Environment.
130  */
131 struct rte_port *ports;        /**< For all probed ethernet ports. */
132 portid_t nb_ports;             /**< Number of probed ethernet ports. */
133 struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
134 lcoreid_t nb_lcores;           /**< Number of probed logical cores. */
135
136 /*
137  * Test Forwarding Configuration.
138  *    nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
139  *    nb_fwd_ports  <= nb_cfg_ports  <= nb_ports
140  */
141 lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
142 lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
143 portid_t  nb_cfg_ports;  /**< Number of configured ports. */
144 portid_t  nb_fwd_ports;  /**< Number of forwarding ports. */
145
146 unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
147 portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];      /**< Port ids configuration. */
148
149 struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
150 streamid_t nb_fwd_streams;       /**< Is equal to (nb_ports * nb_rxq). */
151
152 /*
153  * Forwarding engines.
154  */
155 struct fwd_engine * fwd_engines[] = {
156         &io_fwd_engine,
157         &mac_fwd_engine,
158         &mac_swap_engine,
159         &flow_gen_engine,
160         &rx_only_engine,
161         &tx_only_engine,
162         &csum_fwd_engine,
163         &icmp_echo_engine,
164 #ifdef RTE_LIBRTE_IEEE1588
165         &ieee1588_fwd_engine,
166 #endif
167         NULL,
168 };
169
170 struct fwd_config cur_fwd_config;
171 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
172 uint32_t retry_enabled;
173 uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
174 uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
175
176 uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
177 uint32_t param_total_num_mbufs = 0;  /**< number of mbufs in all pools - if
178                                       * specified on command-line. */
179
180 /*
181  * Configuration of packet segments used by the "txonly" processing engine.
182  */
183 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
184 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
185         TXONLY_DEF_PACKET_LEN,
186 };
187 uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
188
189 enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
190 /**< Split policy for packets to TX. */
191
192 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
193 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
194
195 /* current configuration is in DCB or not,0 means it is not in DCB mode */
196 uint8_t dcb_config = 0;
197
198 /* Whether the dcb is in testing status */
199 uint8_t dcb_test = 0;
200
201 /*
202  * Configurable number of RX/TX queues.
203  */
204 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
205 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
206
207 /*
208  * Configurable number of RX/TX ring descriptors.
209  */
210 #define RTE_TEST_RX_DESC_DEFAULT 128
211 #define RTE_TEST_TX_DESC_DEFAULT 512
212 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
213 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
214
215 #define RTE_PMD_PARAM_UNSET -1
216 /*
217  * Configurable values of RX and TX ring threshold registers.
218  */
219
220 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
221 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
222 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
223
224 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
225 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
226 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
227
228 /*
229  * Configurable value of RX free threshold.
230  */
231 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
232
233 /*
234  * Configurable value of RX drop enable.
235  */
236 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
237
238 /*
239  * Configurable value of TX free threshold.
240  */
241 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
242
243 /*
244  * Configurable value of TX RS bit threshold.
245  */
246 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
247
248 /*
249  * Configurable value of TX queue flags.
250  */
251 int32_t txq_flags = RTE_PMD_PARAM_UNSET;
252
253 /*
254  * Receive Side Scaling (RSS) configuration.
255  */
256 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
257
258 /*
259  * Port topology configuration
260  */
261 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
262
263 /*
264  * Avoids to flush all the RX streams before starts forwarding.
265  */
266 uint8_t no_flush_rx = 0; /* flush by default */
267
268 /*
269  * Avoids to check link status when starting/stopping a port.
270  */
271 uint8_t no_link_check = 0; /* check by default */
272
273 /*
274  * NIC bypass mode configuration options.
275  */
276 #ifdef RTE_NIC_BYPASS
277
278 /* The NIC bypass watchdog timeout. */
279 uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF;
280
281 #endif
282
283 #ifdef RTE_LIBRTE_LATENCY_STATS
284
285 /*
286  * Set when latency stats is enabled in the commandline
287  */
288 uint8_t latencystats_enabled;
289
290 /*
291  * Lcore ID to serive latency statistics.
292  */
293 lcoreid_t latencystats_lcore_id = -1;
294
295 #endif
296
297 /*
298  * Ethernet device configuration.
299  */
300 struct rte_eth_rxmode rx_mode = {
301         .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
302         .split_hdr_size = 0,
303         .header_split   = 0, /**< Header Split disabled. */
304         .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
305         .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
306         .hw_vlan_strip  = 1, /**< VLAN strip enabled. */
307         .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
308         .jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
309         .hw_strip_crc   = 0, /**< CRC stripping by hardware disabled. */
310 };
311
312 struct rte_fdir_conf fdir_conf = {
313         .mode = RTE_FDIR_MODE_NONE,
314         .pballoc = RTE_FDIR_PBALLOC_64K,
315         .status = RTE_FDIR_REPORT_STATUS,
316         .mask = {
317                 .vlan_tci_mask = 0x0,
318                 .ipv4_mask     = {
319                         .src_ip = 0xFFFFFFFF,
320                         .dst_ip = 0xFFFFFFFF,
321                 },
322                 .ipv6_mask     = {
323                         .src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
324                         .dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
325                 },
326                 .src_port_mask = 0xFFFF,
327                 .dst_port_mask = 0xFFFF,
328                 .mac_addr_byte_mask = 0xFF,
329                 .tunnel_type_mask = 1,
330                 .tunnel_id_mask = 0xFFFFFFFF,
331         },
332         .drop_queue = 127,
333 };
334
335 volatile int test_done = 1; /* stop packet forwarding when set to 1. */
336
337 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
338 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
339
340 struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
341 struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
342
343 uint16_t nb_tx_queue_stats_mappings = 0;
344 uint16_t nb_rx_queue_stats_mappings = 0;
345
346 unsigned max_socket = 0;
347
348 /* Bitrate statistics */
349 struct rte_stats_bitrates *bitrate_data;
350
351 /* Forward function declarations */
352 static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
353 static void check_all_ports_link_status(uint32_t port_mask);
354
355 /*
356  * Check if all the ports are started.
357  * If yes, return positive value. If not, return zero.
358  */
359 static int all_ports_started(void);
360
361 /*
362  * Find next enabled port
363  */
364 portid_t
365 find_next_port(portid_t p, struct rte_port *ports, int size)
366 {
367         if (ports == NULL)
368                 rte_exit(-EINVAL, "failed to find a next port id\n");
369
370         while ((p < size) && (ports[p].enabled == 0))
371                 p++;
372         return p;
373 }
374
375 /*
376  * Setup default configuration.
377  */
378 static void
379 set_default_fwd_lcores_config(void)
380 {
381         unsigned int i;
382         unsigned int nb_lc;
383         unsigned int sock_num;
384
385         nb_lc = 0;
386         for (i = 0; i < RTE_MAX_LCORE; i++) {
387                 sock_num = rte_lcore_to_socket_id(i) + 1;
388                 if (sock_num > max_socket) {
389                         if (sock_num > RTE_MAX_NUMA_NODES)
390                                 rte_exit(EXIT_FAILURE, "Total sockets greater than %u\n", RTE_MAX_NUMA_NODES);
391                         max_socket = sock_num;
392                 }
393                 if (!rte_lcore_is_enabled(i))
394                         continue;
395                 if (i == rte_get_master_lcore())
396                         continue;
397                 fwd_lcores_cpuids[nb_lc++] = i;
398         }
399         nb_lcores = (lcoreid_t) nb_lc;
400         nb_cfg_lcores = nb_lcores;
401         nb_fwd_lcores = 1;
402 }
403
404 static void
405 set_def_peer_eth_addrs(void)
406 {
407         portid_t i;
408
409         for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
410                 peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
411                 peer_eth_addrs[i].addr_bytes[5] = i;
412         }
413 }
414
415 static void
416 set_default_fwd_ports_config(void)
417 {
418         portid_t pt_id;
419
420         for (pt_id = 0; pt_id < nb_ports; pt_id++)
421                 fwd_ports_ids[pt_id] = pt_id;
422
423         nb_cfg_ports = nb_ports;
424         nb_fwd_ports = nb_ports;
425 }
426
427 void
428 set_def_fwd_config(void)
429 {
430         set_default_fwd_lcores_config();
431         set_def_peer_eth_addrs();
432         set_default_fwd_ports_config();
433 }
434
435 /*
436  * Configuration initialisation done once at init time.
437  */
438 static void
439 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
440                  unsigned int socket_id)
441 {
442         char pool_name[RTE_MEMPOOL_NAMESIZE];
443         struct rte_mempool *rte_mp = NULL;
444         uint32_t mb_size;
445
446         mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
447         mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
448
449         RTE_LOG(INFO, USER1,
450                 "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
451                 pool_name, nb_mbuf, mbuf_seg_size, socket_id);
452
453 #ifdef RTE_LIBRTE_PMD_XENVIRT
454         rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
455                 (unsigned) mb_mempool_cache,
456                 sizeof(struct rte_pktmbuf_pool_private),
457                 rte_pktmbuf_pool_init, NULL,
458                 rte_pktmbuf_init, NULL,
459                 socket_id, 0);
460 #endif
461
462         /* if the former XEN allocation failed fall back to normal allocation */
463         if (rte_mp == NULL) {
464                 if (mp_anon != 0) {
465                         rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
466                                 mb_size, (unsigned) mb_mempool_cache,
467                                 sizeof(struct rte_pktmbuf_pool_private),
468                                 socket_id, 0);
469                         if (rte_mp == NULL)
470                                 goto err;
471
472                         if (rte_mempool_populate_anon(rte_mp) == 0) {
473                                 rte_mempool_free(rte_mp);
474                                 rte_mp = NULL;
475                                 goto err;
476                         }
477                         rte_pktmbuf_pool_init(rte_mp, NULL);
478                         rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
479                 } else {
480                         /* wrapper to rte_mempool_create() */
481                         rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
482                                 mb_mempool_cache, 0, mbuf_seg_size, socket_id);
483                 }
484         }
485
486 err:
487         if (rte_mp == NULL) {
488                 rte_exit(EXIT_FAILURE,
489                         "Creation of mbuf pool for socket %u failed: %s\n",
490                         socket_id, rte_strerror(rte_errno));
491         } else if (verbose_level > 0) {
492                 rte_mempool_dump(stdout, rte_mp);
493         }
494 }
495
496 /*
497  * Check given socket id is valid or not with NUMA mode,
498  * if valid, return 0, else return -1
499  */
500 static int
501 check_socket_id(const unsigned int socket_id)
502 {
503         static int warning_once = 0;
504
505         if (socket_id >= max_socket) {
506                 if (!warning_once && numa_support)
507                         printf("Warning: NUMA should be configured manually by"
508                                " using --port-numa-config and"
509                                " --ring-numa-config parameters along with"
510                                " --numa.\n");
511                 warning_once = 1;
512                 return -1;
513         }
514         return 0;
515 }
516
517 static void
518 init_config(void)
519 {
520         portid_t pid;
521         struct rte_port *port;
522         struct rte_mempool *mbp;
523         unsigned int nb_mbuf_per_pool;
524         lcoreid_t  lc_id;
525         uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
526
527         memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
528         /* Configuration of logical cores. */
529         fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
530                                 sizeof(struct fwd_lcore *) * nb_lcores,
531                                 RTE_CACHE_LINE_SIZE);
532         if (fwd_lcores == NULL) {
533                 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
534                                                         "failed\n", nb_lcores);
535         }
536         for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
537                 fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
538                                                sizeof(struct fwd_lcore),
539                                                RTE_CACHE_LINE_SIZE);
540                 if (fwd_lcores[lc_id] == NULL) {
541                         rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
542                                                                 "failed\n");
543                 }
544                 fwd_lcores[lc_id]->cpuid_idx = lc_id;
545         }
546
547         /*
548          * Create pools of mbuf.
549          * If NUMA support is disabled, create a single pool of mbuf in
550          * socket 0 memory by default.
551          * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
552          *
553          * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
554          * nb_txd can be configured at run time.
555          */
556         if (param_total_num_mbufs)
557                 nb_mbuf_per_pool = param_total_num_mbufs;
558         else {
559                 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache)
560                                 + RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
561
562                 if (!numa_support)
563                         nb_mbuf_per_pool =
564                                 (nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
565         }
566
567         if (!numa_support) {
568                 if (socket_num == UMA_NO_CONFIG)
569                         mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
570                 else
571                         mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
572                                                  socket_num);
573         }
574
575         FOREACH_PORT(pid, ports) {
576                 port = &ports[pid];
577                 rte_eth_dev_info_get(pid, &port->dev_info);
578
579                 if (numa_support) {
580                         if (port_numa[pid] != NUMA_NO_CONFIG)
581                                 port_per_socket[port_numa[pid]]++;
582                         else {
583                                 uint32_t socket_id = rte_eth_dev_socket_id(pid);
584
585                                 /* if socket_id is invalid, set to 0 */
586                                 if (check_socket_id(socket_id) < 0)
587                                         socket_id = 0;
588                                 port_per_socket[socket_id]++;
589                         }
590                 }
591
592                 /* set flag to initialize port/queue */
593                 port->need_reconfig = 1;
594                 port->need_reconfig_queues = 1;
595         }
596
597         if (numa_support) {
598                 uint8_t i;
599                 unsigned int nb_mbuf;
600
601                 if (param_total_num_mbufs)
602                         nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports;
603
604                 for (i = 0; i < max_socket; i++) {
605                         nb_mbuf = (nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
606                         if (nb_mbuf)
607                                 mbuf_pool_create(mbuf_data_size,
608                                                 nb_mbuf,i);
609                 }
610         }
611         init_port_config();
612
613         /*
614          * Records which Mbuf pool to use by each logical core, if needed.
615          */
616         for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
617                 mbp = mbuf_pool_find(
618                         rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
619
620                 if (mbp == NULL)
621                         mbp = mbuf_pool_find(0);
622                 fwd_lcores[lc_id]->mbp = mbp;
623         }
624
625         /* Configuration of packet forwarding streams. */
626         if (init_fwd_streams() < 0)
627                 rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
628
629         fwd_config_setup();
630 }
631
632
633 void
634 reconfig(portid_t new_port_id, unsigned socket_id)
635 {
636         struct rte_port *port;
637
638         /* Reconfiguration of Ethernet ports. */
639         port = &ports[new_port_id];
640         rte_eth_dev_info_get(new_port_id, &port->dev_info);
641
642         /* set flag to initialize port/queue */
643         port->need_reconfig = 1;
644         port->need_reconfig_queues = 1;
645         port->socket_id = socket_id;
646
647         init_port_config();
648 }
649
650
651 int
652 init_fwd_streams(void)
653 {
654         portid_t pid;
655         struct rte_port *port;
656         streamid_t sm_id, nb_fwd_streams_new;
657         queueid_t q;
658
659         /* set socket id according to numa or not */
660         FOREACH_PORT(pid, ports) {
661                 port = &ports[pid];
662                 if (nb_rxq > port->dev_info.max_rx_queues) {
663                         printf("Fail: nb_rxq(%d) is greater than "
664                                 "max_rx_queues(%d)\n", nb_rxq,
665                                 port->dev_info.max_rx_queues);
666                         return -1;
667                 }
668                 if (nb_txq > port->dev_info.max_tx_queues) {
669                         printf("Fail: nb_txq(%d) is greater than "
670                                 "max_tx_queues(%d)\n", nb_txq,
671                                 port->dev_info.max_tx_queues);
672                         return -1;
673                 }
674                 if (numa_support) {
675                         if (port_numa[pid] != NUMA_NO_CONFIG)
676                                 port->socket_id = port_numa[pid];
677                         else {
678                                 port->socket_id = rte_eth_dev_socket_id(pid);
679
680                                 /* if socket_id is invalid, set to 0 */
681                                 if (check_socket_id(port->socket_id) < 0)
682                                         port->socket_id = 0;
683                         }
684                 }
685                 else {
686                         if (socket_num == UMA_NO_CONFIG)
687                                 port->socket_id = 0;
688                         else
689                                 port->socket_id = socket_num;
690                 }
691         }
692
693         q = RTE_MAX(nb_rxq, nb_txq);
694         if (q == 0) {
695                 printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
696                 return -1;
697         }
698         nb_fwd_streams_new = (streamid_t)(nb_ports * q);
699         if (nb_fwd_streams_new == nb_fwd_streams)
700                 return 0;
701         /* clear the old */
702         if (fwd_streams != NULL) {
703                 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
704                         if (fwd_streams[sm_id] == NULL)
705                                 continue;
706                         rte_free(fwd_streams[sm_id]);
707                         fwd_streams[sm_id] = NULL;
708                 }
709                 rte_free(fwd_streams);
710                 fwd_streams = NULL;
711         }
712
713         /* init new */
714         nb_fwd_streams = nb_fwd_streams_new;
715         fwd_streams = rte_zmalloc("testpmd: fwd_streams",
716                 sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE);
717         if (fwd_streams == NULL)
718                 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) "
719                                                 "failed\n", nb_fwd_streams);
720
721         for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
722                 fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
723                                 sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE);
724                 if (fwd_streams[sm_id] == NULL)
725                         rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)"
726                                                                 " failed\n");
727         }
728
729         return 0;
730 }
731
732 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
733 static void
734 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
735 {
736         unsigned int total_burst;
737         unsigned int nb_burst;
738         unsigned int burst_stats[3];
739         uint16_t pktnb_stats[3];
740         uint16_t nb_pkt;
741         int burst_percent[3];
742
743         /*
744          * First compute the total number of packet bursts and the
745          * two highest numbers of bursts of the same number of packets.
746          */
747         total_burst = 0;
748         burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
749         pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
750         for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
751                 nb_burst = pbs->pkt_burst_spread[nb_pkt];
752                 if (nb_burst == 0)
753                         continue;
754                 total_burst += nb_burst;
755                 if (nb_burst > burst_stats[0]) {
756                         burst_stats[1] = burst_stats[0];
757                         pktnb_stats[1] = pktnb_stats[0];
758                         burst_stats[0] = nb_burst;
759                         pktnb_stats[0] = nb_pkt;
760                 }
761         }
762         if (total_burst == 0)
763                 return;
764         burst_percent[0] = (burst_stats[0] * 100) / total_burst;
765         printf("  %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
766                burst_percent[0], (int) pktnb_stats[0]);
767         if (burst_stats[0] == total_burst) {
768                 printf("]\n");
769                 return;
770         }
771         if (burst_stats[0] + burst_stats[1] == total_burst) {
772                 printf(" + %d%% of %d pkts]\n",
773                        100 - burst_percent[0], pktnb_stats[1]);
774                 return;
775         }
776         burst_percent[1] = (burst_stats[1] * 100) / total_burst;
777         burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
778         if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
779                 printf(" + %d%% of others]\n", 100 - burst_percent[0]);
780                 return;
781         }
782         printf(" + %d%% of %d pkts + %d%% of others]\n",
783                burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
784 }
785 #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
786
787 static void
788 fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
789 {
790         struct rte_port *port;
791         uint8_t i;
792
793         static const char *fwd_stats_border = "----------------------";
794
795         port = &ports[port_id];
796         printf("\n  %s Forward statistics for port %-2d %s\n",
797                fwd_stats_border, port_id, fwd_stats_border);
798
799         if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
800                 printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
801                        "%-"PRIu64"\n",
802                        stats->ipackets, stats->imissed,
803                        (uint64_t) (stats->ipackets + stats->imissed));
804
805                 if (cur_fwd_eng == &csum_fwd_engine)
806                         printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
807                                port->rx_bad_ip_csum, port->rx_bad_l4_csum);
808                 if ((stats->ierrors + stats->rx_nombuf) > 0) {
809                         printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
810                         printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
811                 }
812
813                 printf("  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
814                        "%-"PRIu64"\n",
815                        stats->opackets, port->tx_dropped,
816                        (uint64_t) (stats->opackets + port->tx_dropped));
817         }
818         else {
819                 printf("  RX-packets:             %14"PRIu64"    RX-dropped:%14"PRIu64"    RX-total:"
820                        "%14"PRIu64"\n",
821                        stats->ipackets, stats->imissed,
822                        (uint64_t) (stats->ipackets + stats->imissed));
823
824                 if (cur_fwd_eng == &csum_fwd_engine)
825                         printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
826                                port->rx_bad_ip_csum, port->rx_bad_l4_csum);
827                 if ((stats->ierrors + stats->rx_nombuf) > 0) {
828                         printf("  RX-error:%"PRIu64"\n", stats->ierrors);
829                         printf("  RX-nombufs:             %14"PRIu64"\n",
830                                stats->rx_nombuf);
831                 }
832
833                 printf("  TX-packets:             %14"PRIu64"    TX-dropped:%14"PRIu64"    TX-total:"
834                        "%14"PRIu64"\n",
835                        stats->opackets, port->tx_dropped,
836                        (uint64_t) (stats->opackets + port->tx_dropped));
837         }
838
839 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
840         if (port->rx_stream)
841                 pkt_burst_stats_display("RX",
842                         &port->rx_stream->rx_burst_stats);
843         if (port->tx_stream)
844                 pkt_burst_stats_display("TX",
845                         &port->tx_stream->tx_burst_stats);
846 #endif
847
848         if (port->rx_queue_stats_mapping_enabled) {
849                 printf("\n");
850                 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
851                         printf("  Stats reg %2d RX-packets:%14"PRIu64
852                                "     RX-errors:%14"PRIu64
853                                "    RX-bytes:%14"PRIu64"\n",
854                                i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
855                 }
856                 printf("\n");
857         }
858         if (port->tx_queue_stats_mapping_enabled) {
859                 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
860                         printf("  Stats reg %2d TX-packets:%14"PRIu64
861                                "                                 TX-bytes:%14"PRIu64"\n",
862                                i, stats->q_opackets[i], stats->q_obytes[i]);
863                 }
864         }
865
866         printf("  %s--------------------------------%s\n",
867                fwd_stats_border, fwd_stats_border);
868 }
869
870 static void
871 fwd_stream_stats_display(streamid_t stream_id)
872 {
873         struct fwd_stream *fs;
874         static const char *fwd_top_stats_border = "-------";
875
876         fs = fwd_streams[stream_id];
877         if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
878             (fs->fwd_dropped == 0))
879                 return;
880         printf("\n  %s Forward Stats for RX Port=%2d/Queue=%2d -> "
881                "TX Port=%2d/Queue=%2d %s\n",
882                fwd_top_stats_border, fs->rx_port, fs->rx_queue,
883                fs->tx_port, fs->tx_queue, fwd_top_stats_border);
884         printf("  RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
885                fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
886
887         /* if checksum mode */
888         if (cur_fwd_eng == &csum_fwd_engine) {
889                printf("  RX- bad IP checksum: %-14u  Rx- bad L4 checksum: "
890                         "%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
891         }
892
893 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
894         pkt_burst_stats_display("RX", &fs->rx_burst_stats);
895         pkt_burst_stats_display("TX", &fs->tx_burst_stats);
896 #endif
897 }
898
899 static void
900 flush_fwd_rx_queues(void)
901 {
902         struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
903         portid_t  rxp;
904         portid_t port_id;
905         queueid_t rxq;
906         uint16_t  nb_rx;
907         uint16_t  i;
908         uint8_t   j;
909         uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
910         uint64_t timer_period;
911
912         /* convert to number of cycles */
913         timer_period = rte_get_timer_hz(); /* 1 second timeout */
914
915         for (j = 0; j < 2; j++) {
916                 for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
917                         for (rxq = 0; rxq < nb_rxq; rxq++) {
918                                 port_id = fwd_ports_ids[rxp];
919                                 /**
920                                 * testpmd can stuck in the below do while loop
921                                 * if rte_eth_rx_burst() always returns nonzero
922                                 * packets. So timer is added to exit this loop
923                                 * after 1sec timer expiry.
924                                 */
925                                 prev_tsc = rte_rdtsc();
926                                 do {
927                                         nb_rx = rte_eth_rx_burst(port_id, rxq,
928                                                 pkts_burst, MAX_PKT_BURST);
929                                         for (i = 0; i < nb_rx; i++)
930                                                 rte_pktmbuf_free(pkts_burst[i]);
931
932                                         cur_tsc = rte_rdtsc();
933                                         diff_tsc = cur_tsc - prev_tsc;
934                                         timer_tsc += diff_tsc;
935                                 } while ((nb_rx > 0) &&
936                                         (timer_tsc < timer_period));
937                                 timer_tsc = 0;
938                         }
939                 }
940                 rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
941         }
942 }
943
944 static void
945 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
946 {
947         struct fwd_stream **fsm;
948         streamid_t nb_fs;
949         streamid_t sm_id;
950 #ifdef RTE_LIBRTE_BITRATE
951         uint64_t tics_per_1sec;
952         uint64_t tics_datum;
953         uint64_t tics_current;
954         uint8_t idx_port, cnt_ports;
955
956         cnt_ports = rte_eth_dev_count();
957         tics_datum = rte_rdtsc();
958         tics_per_1sec = rte_get_timer_hz();
959 #endif
960         fsm = &fwd_streams[fc->stream_idx];
961         nb_fs = fc->stream_nb;
962         do {
963                 for (sm_id = 0; sm_id < nb_fs; sm_id++)
964                         (*pkt_fwd)(fsm[sm_id]);
965 #ifdef RTE_LIBRTE_BITRATE
966                 tics_current = rte_rdtsc();
967                 if (tics_current - tics_datum >= tics_per_1sec) {
968                         /* Periodic bitrate calculation */
969                         for (idx_port = 0; idx_port < cnt_ports; idx_port++)
970                                 rte_stats_bitrate_calc(bitrate_data, idx_port);
971                         tics_datum = tics_current;
972                 }
973 #endif
974 #ifdef RTE_LIBRTE_LATENCY_STATS
975                 if (latencystats_lcore_id == rte_lcore_id())
976                         rte_latencystats_update();
977 #endif
978
979         } while (! fc->stopped);
980 }
981
982 static int
983 start_pkt_forward_on_core(void *fwd_arg)
984 {
985         run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
986                              cur_fwd_config.fwd_eng->packet_fwd);
987         return 0;
988 }
989
990 /*
991  * Run the TXONLY packet forwarding engine to send a single burst of packets.
992  * Used to start communication flows in network loopback test configurations.
993  */
994 static int
995 run_one_txonly_burst_on_core(void *fwd_arg)
996 {
997         struct fwd_lcore *fwd_lc;
998         struct fwd_lcore tmp_lcore;
999
1000         fwd_lc = (struct fwd_lcore *) fwd_arg;
1001         tmp_lcore = *fwd_lc;
1002         tmp_lcore.stopped = 1;
1003         run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
1004         return 0;
1005 }
1006
1007 /*
1008  * Launch packet forwarding:
1009  *     - Setup per-port forwarding context.
1010  *     - launch logical cores with their forwarding configuration.
1011  */
1012 static void
1013 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
1014 {
1015         port_fwd_begin_t port_fwd_begin;
1016         unsigned int i;
1017         unsigned int lc_id;
1018         int diag;
1019
1020         port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
1021         if (port_fwd_begin != NULL) {
1022                 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1023                         (*port_fwd_begin)(fwd_ports_ids[i]);
1024         }
1025         for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1026                 lc_id = fwd_lcores_cpuids[i];
1027                 if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1028                         fwd_lcores[i]->stopped = 0;
1029                         diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1030                                                      fwd_lcores[i], lc_id);
1031                         if (diag != 0)
1032                                 printf("launch lcore %u failed - diag=%d\n",
1033                                        lc_id, diag);
1034                 }
1035         }
1036 }
1037
1038 /*
1039  * Launch packet forwarding configuration.
1040  */
1041 void
1042 start_packet_forwarding(int with_tx_first)
1043 {
1044         port_fwd_begin_t port_fwd_begin;
1045         port_fwd_end_t  port_fwd_end;
1046         struct rte_port *port;
1047         unsigned int i;
1048         portid_t   pt_id;
1049         streamid_t sm_id;
1050
1051         if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
1052                 rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
1053
1054         if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
1055                 rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
1056
1057         if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
1058                 strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
1059                 (!nb_rxq || !nb_txq))
1060                 rte_exit(EXIT_FAILURE,
1061                         "Either rxq or txq are 0, cannot use %s fwd mode\n",
1062                         cur_fwd_eng->fwd_mode_name);
1063
1064         if (all_ports_started() == 0) {
1065                 printf("Not all ports were started\n");
1066                 return;
1067         }
1068         if (test_done == 0) {
1069                 printf("Packet forwarding already started\n");
1070                 return;
1071         }
1072
1073         if (init_fwd_streams() < 0) {
1074                 printf("Fail from init_fwd_streams()\n");
1075                 return;
1076         }
1077
1078         if(dcb_test) {
1079                 for (i = 0; i < nb_fwd_ports; i++) {
1080                         pt_id = fwd_ports_ids[i];
1081                         port = &ports[pt_id];
1082                         if (!port->dcb_flag) {
1083                                 printf("In DCB mode, all forwarding ports must "
1084                                        "be configured in this mode.\n");
1085                                 return;
1086                         }
1087                 }
1088                 if (nb_fwd_lcores == 1) {
1089                         printf("In DCB mode,the nb forwarding cores "
1090                                "should be larger than 1.\n");
1091                         return;
1092                 }
1093         }
1094         test_done = 0;
1095
1096         if(!no_flush_rx)
1097                 flush_fwd_rx_queues();
1098
1099         fwd_config_setup();
1100         pkt_fwd_config_display(&cur_fwd_config);
1101         rxtx_config_display();
1102
1103         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1104                 pt_id = fwd_ports_ids[i];
1105                 port = &ports[pt_id];
1106                 rte_eth_stats_get(pt_id, &port->stats);
1107                 port->tx_dropped = 0;
1108
1109                 map_port_queue_stats_mapping_registers(pt_id, port);
1110         }
1111         for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1112                 fwd_streams[sm_id]->rx_packets = 0;
1113                 fwd_streams[sm_id]->tx_packets = 0;
1114                 fwd_streams[sm_id]->fwd_dropped = 0;
1115                 fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1116                 fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1117
1118 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1119                 memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1120                        sizeof(fwd_streams[sm_id]->rx_burst_stats));
1121                 memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1122                        sizeof(fwd_streams[sm_id]->tx_burst_stats));
1123 #endif
1124 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1125                 fwd_streams[sm_id]->core_cycles = 0;
1126 #endif
1127         }
1128         if (with_tx_first) {
1129                 port_fwd_begin = tx_only_engine.port_fwd_begin;
1130                 if (port_fwd_begin != NULL) {
1131                         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1132                                 (*port_fwd_begin)(fwd_ports_ids[i]);
1133                 }
1134                 while (with_tx_first--) {
1135                         launch_packet_forwarding(
1136                                         run_one_txonly_burst_on_core);
1137                         rte_eal_mp_wait_lcore();
1138                 }
1139                 port_fwd_end = tx_only_engine.port_fwd_end;
1140                 if (port_fwd_end != NULL) {
1141                         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1142                                 (*port_fwd_end)(fwd_ports_ids[i]);
1143                 }
1144         }
1145         launch_packet_forwarding(start_pkt_forward_on_core);
1146 }
1147
1148 void
1149 stop_packet_forwarding(void)
1150 {
1151         struct rte_eth_stats stats;
1152         struct rte_port *port;
1153         port_fwd_end_t  port_fwd_end;
1154         int i;
1155         portid_t   pt_id;
1156         streamid_t sm_id;
1157         lcoreid_t  lc_id;
1158         uint64_t total_recv;
1159         uint64_t total_xmit;
1160         uint64_t total_rx_dropped;
1161         uint64_t total_tx_dropped;
1162         uint64_t total_rx_nombuf;
1163         uint64_t tx_dropped;
1164         uint64_t rx_bad_ip_csum;
1165         uint64_t rx_bad_l4_csum;
1166 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1167         uint64_t fwd_cycles;
1168 #endif
1169         static const char *acc_stats_border = "+++++++++++++++";
1170
1171         if (test_done) {
1172                 printf("Packet forwarding not started\n");
1173                 return;
1174         }
1175         printf("Telling cores to stop...");
1176         for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1177                 fwd_lcores[lc_id]->stopped = 1;
1178         printf("\nWaiting for lcores to finish...\n");
1179         rte_eal_mp_wait_lcore();
1180         port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1181         if (port_fwd_end != NULL) {
1182                 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1183                         pt_id = fwd_ports_ids[i];
1184                         (*port_fwd_end)(pt_id);
1185                 }
1186         }
1187 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1188         fwd_cycles = 0;
1189 #endif
1190         for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1191                 if (cur_fwd_config.nb_fwd_streams >
1192                     cur_fwd_config.nb_fwd_ports) {
1193                         fwd_stream_stats_display(sm_id);
1194                         ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1195                         ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1196                 } else {
1197                         ports[fwd_streams[sm_id]->tx_port].tx_stream =
1198                                 fwd_streams[sm_id];
1199                         ports[fwd_streams[sm_id]->rx_port].rx_stream =
1200                                 fwd_streams[sm_id];
1201                 }
1202                 tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1203                 tx_dropped = (uint64_t) (tx_dropped +
1204                                          fwd_streams[sm_id]->fwd_dropped);
1205                 ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1206
1207                 rx_bad_ip_csum =
1208                         ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1209                 rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1210                                          fwd_streams[sm_id]->rx_bad_ip_csum);
1211                 ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1212                                                         rx_bad_ip_csum;
1213
1214                 rx_bad_l4_csum =
1215                         ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1216                 rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1217                                          fwd_streams[sm_id]->rx_bad_l4_csum);
1218                 ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1219                                                         rx_bad_l4_csum;
1220
1221 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1222                 fwd_cycles = (uint64_t) (fwd_cycles +
1223                                          fwd_streams[sm_id]->core_cycles);
1224 #endif
1225         }
1226         total_recv = 0;
1227         total_xmit = 0;
1228         total_rx_dropped = 0;
1229         total_tx_dropped = 0;
1230         total_rx_nombuf  = 0;
1231         for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1232                 pt_id = fwd_ports_ids[i];
1233
1234                 port = &ports[pt_id];
1235                 rte_eth_stats_get(pt_id, &stats);
1236                 stats.ipackets -= port->stats.ipackets;
1237                 port->stats.ipackets = 0;
1238                 stats.opackets -= port->stats.opackets;
1239                 port->stats.opackets = 0;
1240                 stats.ibytes   -= port->stats.ibytes;
1241                 port->stats.ibytes = 0;
1242                 stats.obytes   -= port->stats.obytes;
1243                 port->stats.obytes = 0;
1244                 stats.imissed  -= port->stats.imissed;
1245                 port->stats.imissed = 0;
1246                 stats.oerrors  -= port->stats.oerrors;
1247                 port->stats.oerrors = 0;
1248                 stats.rx_nombuf -= port->stats.rx_nombuf;
1249                 port->stats.rx_nombuf = 0;
1250
1251                 total_recv += stats.ipackets;
1252                 total_xmit += stats.opackets;
1253                 total_rx_dropped += stats.imissed;
1254                 total_tx_dropped += port->tx_dropped;
1255                 total_rx_nombuf  += stats.rx_nombuf;
1256
1257                 fwd_port_stats_display(pt_id, &stats);
1258         }
1259         printf("\n  %s Accumulated forward statistics for all ports"
1260                "%s\n",
1261                acc_stats_border, acc_stats_border);
1262         printf("  RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1263                "%-"PRIu64"\n"
1264                "  TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1265                "%-"PRIu64"\n",
1266                total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1267                total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1268         if (total_rx_nombuf > 0)
1269                 printf("  RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1270         printf("  %s++++++++++++++++++++++++++++++++++++++++++++++"
1271                "%s\n",
1272                acc_stats_border, acc_stats_border);
1273 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1274         if (total_recv > 0)
1275                 printf("\n  CPU cycles/packet=%u (total cycles="
1276                        "%"PRIu64" / total RX packets=%"PRIu64")\n",
1277                        (unsigned int)(fwd_cycles / total_recv),
1278                        fwd_cycles, total_recv);
1279 #endif
1280         printf("\nDone.\n");
1281         test_done = 1;
1282 }
1283
1284 void
1285 dev_set_link_up(portid_t pid)
1286 {
1287         if (rte_eth_dev_set_link_up((uint8_t)pid) < 0)
1288                 printf("\nSet link up fail.\n");
1289 }
1290
1291 void
1292 dev_set_link_down(portid_t pid)
1293 {
1294         if (rte_eth_dev_set_link_down((uint8_t)pid) < 0)
1295                 printf("\nSet link down fail.\n");
1296 }
1297
1298 static int
1299 all_ports_started(void)
1300 {
1301         portid_t pi;
1302         struct rte_port *port;
1303
1304         FOREACH_PORT(pi, ports) {
1305                 port = &ports[pi];
1306                 /* Check if there is a port which is not started */
1307                 if ((port->port_status != RTE_PORT_STARTED) &&
1308                         (port->slave_flag == 0))
1309                         return 0;
1310         }
1311
1312         /* No port is not started */
1313         return 1;
1314 }
1315
1316 int
1317 all_ports_stopped(void)
1318 {
1319         portid_t pi;
1320         struct rte_port *port;
1321
1322         FOREACH_PORT(pi, ports) {
1323                 port = &ports[pi];
1324                 if ((port->port_status != RTE_PORT_STOPPED) &&
1325                         (port->slave_flag == 0))
1326                         return 0;
1327         }
1328
1329         return 1;
1330 }
1331
1332 int
1333 port_is_started(portid_t port_id)
1334 {
1335         if (port_id_is_invalid(port_id, ENABLED_WARN))
1336                 return 0;
1337
1338         if (ports[port_id].port_status != RTE_PORT_STARTED)
1339                 return 0;
1340
1341         return 1;
1342 }
1343
1344 static int
1345 port_is_closed(portid_t port_id)
1346 {
1347         if (port_id_is_invalid(port_id, ENABLED_WARN))
1348                 return 0;
1349
1350         if (ports[port_id].port_status != RTE_PORT_CLOSED)
1351                 return 0;
1352
1353         return 1;
1354 }
1355
1356 int
1357 start_port(portid_t pid)
1358 {
1359         int diag, need_check_link_status = -1;
1360         portid_t pi;
1361         queueid_t qi;
1362         struct rte_port *port;
1363         struct ether_addr mac_addr;
1364
1365         if (port_id_is_invalid(pid, ENABLED_WARN))
1366                 return 0;
1367
1368         if(dcb_config)
1369                 dcb_test = 1;
1370         FOREACH_PORT(pi, ports) {
1371                 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1372                         continue;
1373
1374                 need_check_link_status = 0;
1375                 port = &ports[pi];
1376                 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1377                                                  RTE_PORT_HANDLING) == 0) {
1378                         printf("Port %d is now not stopped\n", pi);
1379                         continue;
1380                 }
1381
1382                 if (port->need_reconfig > 0) {
1383                         port->need_reconfig = 0;
1384
1385                         printf("Configuring Port %d (socket %u)\n", pi,
1386                                         port->socket_id);
1387                         /* configure port */
1388                         diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1389                                                 &(port->dev_conf));
1390                         if (diag != 0) {
1391                                 if (rte_atomic16_cmpset(&(port->port_status),
1392                                 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1393                                         printf("Port %d can not be set back "
1394                                                         "to stopped\n", pi);
1395                                 printf("Fail to configure port %d\n", pi);
1396                                 /* try to reconfigure port next time */
1397                                 port->need_reconfig = 1;
1398                                 return -1;
1399                         }
1400                 }
1401                 if (port->need_reconfig_queues > 0) {
1402                         port->need_reconfig_queues = 0;
1403                         /* setup tx queues */
1404                         for (qi = 0; qi < nb_txq; qi++) {
1405                                 if ((numa_support) &&
1406                                         (txring_numa[pi] != NUMA_NO_CONFIG))
1407                                         diag = rte_eth_tx_queue_setup(pi, qi,
1408                                                 nb_txd,txring_numa[pi],
1409                                                 &(port->tx_conf));
1410                                 else
1411                                         diag = rte_eth_tx_queue_setup(pi, qi,
1412                                                 nb_txd,port->socket_id,
1413                                                 &(port->tx_conf));
1414
1415                                 if (diag == 0)
1416                                         continue;
1417
1418                                 /* Fail to setup tx queue, return */
1419                                 if (rte_atomic16_cmpset(&(port->port_status),
1420                                                         RTE_PORT_HANDLING,
1421                                                         RTE_PORT_STOPPED) == 0)
1422                                         printf("Port %d can not be set back "
1423                                                         "to stopped\n", pi);
1424                                 printf("Fail to configure port %d tx queues\n", pi);
1425                                 /* try to reconfigure queues next time */
1426                                 port->need_reconfig_queues = 1;
1427                                 return -1;
1428                         }
1429                         /* setup rx queues */
1430                         for (qi = 0; qi < nb_rxq; qi++) {
1431                                 if ((numa_support) &&
1432                                         (rxring_numa[pi] != NUMA_NO_CONFIG)) {
1433                                         struct rte_mempool * mp =
1434                                                 mbuf_pool_find(rxring_numa[pi]);
1435                                         if (mp == NULL) {
1436                                                 printf("Failed to setup RX queue:"
1437                                                         "No mempool allocation"
1438                                                         " on the socket %d\n",
1439                                                         rxring_numa[pi]);
1440                                                 return -1;
1441                                         }
1442
1443                                         diag = rte_eth_rx_queue_setup(pi, qi,
1444                                              nb_rxd,rxring_numa[pi],
1445                                              &(port->rx_conf),mp);
1446                                 } else {
1447                                         struct rte_mempool *mp =
1448                                                 mbuf_pool_find(port->socket_id);
1449                                         if (mp == NULL) {
1450                                                 printf("Failed to setup RX queue:"
1451                                                         "No mempool allocation"
1452                                                         " on the socket %d\n",
1453                                                         port->socket_id);
1454                                                 return -1;
1455                                         }
1456                                         diag = rte_eth_rx_queue_setup(pi, qi,
1457                                              nb_rxd,port->socket_id,
1458                                              &(port->rx_conf), mp);
1459                                 }
1460                                 if (diag == 0)
1461                                         continue;
1462
1463                                 /* Fail to setup rx queue, return */
1464                                 if (rte_atomic16_cmpset(&(port->port_status),
1465                                                         RTE_PORT_HANDLING,
1466                                                         RTE_PORT_STOPPED) == 0)
1467                                         printf("Port %d can not be set back "
1468                                                         "to stopped\n", pi);
1469                                 printf("Fail to configure port %d rx queues\n", pi);
1470                                 /* try to reconfigure queues next time */
1471                                 port->need_reconfig_queues = 1;
1472                                 return -1;
1473                         }
1474                 }
1475                 /* start port */
1476                 if (rte_eth_dev_start(pi) < 0) {
1477                         printf("Fail to start port %d\n", pi);
1478
1479                         /* Fail to setup rx queue, return */
1480                         if (rte_atomic16_cmpset(&(port->port_status),
1481                                 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1482                                 printf("Port %d can not be set back to "
1483                                                         "stopped\n", pi);
1484                         continue;
1485                 }
1486
1487                 if (rte_atomic16_cmpset(&(port->port_status),
1488                         RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
1489                         printf("Port %d can not be set into started\n", pi);
1490
1491                 rte_eth_macaddr_get(pi, &mac_addr);
1492                 printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
1493                                 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
1494                                 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
1495                                 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
1496
1497                 /* at least one port started, need checking link status */
1498                 need_check_link_status = 1;
1499         }
1500
1501         if (need_check_link_status == 1 && !no_link_check)
1502                 check_all_ports_link_status(RTE_PORT_ALL);
1503         else if (need_check_link_status == 0)
1504                 printf("Please stop the ports first\n");
1505
1506         printf("Done\n");
1507         return 0;
1508 }
1509
1510 void
1511 stop_port(portid_t pid)
1512 {
1513         portid_t pi;
1514         struct rte_port *port;
1515         int need_check_link_status = 0;
1516
1517         if (dcb_test) {
1518                 dcb_test = 0;
1519                 dcb_config = 0;
1520         }
1521
1522         if (port_id_is_invalid(pid, ENABLED_WARN))
1523                 return;
1524
1525         printf("Stopping ports...\n");
1526
1527         FOREACH_PORT(pi, ports) {
1528                 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1529                         continue;
1530
1531                 if (port_is_forwarding(pi) != 0 && test_done == 0) {
1532                         printf("Please remove port %d from forwarding configuration.\n", pi);
1533                         continue;
1534                 }
1535
1536                 if (port_is_bonding_slave(pi)) {
1537                         printf("Please remove port %d from bonded device.\n", pi);
1538                         continue;
1539                 }
1540
1541                 port = &ports[pi];
1542                 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
1543                                                 RTE_PORT_HANDLING) == 0)
1544                         continue;
1545
1546                 rte_eth_dev_stop(pi);
1547
1548                 if (rte_atomic16_cmpset(&(port->port_status),
1549                         RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1550                         printf("Port %d can not be set into stopped\n", pi);
1551                 need_check_link_status = 1;
1552         }
1553         if (need_check_link_status && !no_link_check)
1554                 check_all_ports_link_status(RTE_PORT_ALL);
1555
1556         printf("Done\n");
1557 }
1558
1559 void
1560 close_port(portid_t pid)
1561 {
1562         portid_t pi;
1563         struct rte_port *port;
1564
1565         if (port_id_is_invalid(pid, ENABLED_WARN))
1566                 return;
1567
1568         printf("Closing ports...\n");
1569
1570         FOREACH_PORT(pi, ports) {
1571                 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1572                         continue;
1573
1574                 if (port_is_forwarding(pi) != 0 && test_done == 0) {
1575                         printf("Please remove port %d from forwarding configuration.\n", pi);
1576                         continue;
1577                 }
1578
1579                 if (port_is_bonding_slave(pi)) {
1580                         printf("Please remove port %d from bonded device.\n", pi);
1581                         continue;
1582                 }
1583
1584                 port = &ports[pi];
1585                 if (rte_atomic16_cmpset(&(port->port_status),
1586                         RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
1587                         printf("Port %d is already closed\n", pi);
1588                         continue;
1589                 }
1590
1591                 if (rte_atomic16_cmpset(&(port->port_status),
1592                         RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
1593                         printf("Port %d is now not stopped\n", pi);
1594                         continue;
1595                 }
1596
1597                 if (port->flow_list)
1598                         port_flow_flush(pi);
1599                 rte_eth_dev_close(pi);
1600
1601                 if (rte_atomic16_cmpset(&(port->port_status),
1602                         RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
1603                         printf("Port %d cannot be set to closed\n", pi);
1604         }
1605
1606         printf("Done\n");
1607 }
1608
1609 void
1610 attach_port(char *identifier)
1611 {
1612         portid_t pi = 0;
1613         unsigned int socket_id;
1614
1615         printf("Attaching a new port...\n");
1616
1617         if (identifier == NULL) {
1618                 printf("Invalid parameters are specified\n");
1619                 return;
1620         }
1621
1622         if (rte_eth_dev_attach(identifier, &pi))
1623                 return;
1624
1625         ports[pi].enabled = 1;
1626         socket_id = (unsigned)rte_eth_dev_socket_id(pi);
1627         /* if socket_id is invalid, set to 0 */
1628         if (check_socket_id(socket_id) < 0)
1629                 socket_id = 0;
1630         reconfig(pi, socket_id);
1631         rte_eth_promiscuous_enable(pi);
1632
1633         nb_ports = rte_eth_dev_count();
1634
1635         ports[pi].port_status = RTE_PORT_STOPPED;
1636
1637         printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
1638         printf("Done\n");
1639 }
1640
1641 void
1642 detach_port(uint8_t port_id)
1643 {
1644         char name[RTE_ETH_NAME_MAX_LEN];
1645
1646         printf("Detaching a port...\n");
1647
1648         if (!port_is_closed(port_id)) {
1649                 printf("Please close port first\n");
1650                 return;
1651         }
1652
1653         if (ports[port_id].flow_list)
1654                 port_flow_flush(port_id);
1655
1656         if (rte_eth_dev_detach(port_id, name))
1657                 return;
1658
1659         ports[port_id].enabled = 0;
1660         nb_ports = rte_eth_dev_count();
1661
1662         printf("Port '%s' is detached. Now total ports is %d\n",
1663                         name, nb_ports);
1664         printf("Done\n");
1665         return;
1666 }
1667
1668 void
1669 pmd_test_exit(void)
1670 {
1671         portid_t pt_id;
1672
1673         if (test_done == 0)
1674                 stop_packet_forwarding();
1675
1676         if (ports != NULL) {
1677                 no_link_check = 1;
1678                 FOREACH_PORT(pt_id, ports) {
1679                         printf("\nShutting down port %d...\n", pt_id);
1680                         fflush(stdout);
1681                         stop_port(pt_id);
1682                         close_port(pt_id);
1683                 }
1684         }
1685         printf("\nBye...\n");
1686 }
1687
1688 typedef void (*cmd_func_t)(void);
1689 struct pmd_test_command {
1690         const char *cmd_name;
1691         cmd_func_t cmd_func;
1692 };
1693
1694 #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
1695
1696 /* Check the link status of all ports in up to 9s, and print them finally */
1697 static void
1698 check_all_ports_link_status(uint32_t port_mask)
1699 {
1700 #define CHECK_INTERVAL 100 /* 100ms */
1701 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
1702         uint8_t portid, count, all_ports_up, print_flag = 0;
1703         struct rte_eth_link link;
1704
1705         printf("Checking link statuses...\n");
1706         fflush(stdout);
1707         for (count = 0; count <= MAX_CHECK_TIME; count++) {
1708                 all_ports_up = 1;
1709                 FOREACH_PORT(portid, ports) {
1710                         if ((port_mask & (1 << portid)) == 0)
1711                                 continue;
1712                         memset(&link, 0, sizeof(link));
1713                         rte_eth_link_get_nowait(portid, &link);
1714                         /* print link status if flag set */
1715                         if (print_flag == 1) {
1716                                 if (link.link_status)
1717                                         printf("Port %d Link Up - speed %u "
1718                                                 "Mbps - %s\n", (uint8_t)portid,
1719                                                 (unsigned)link.link_speed,
1720                                 (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
1721                                         ("full-duplex") : ("half-duplex\n"));
1722                                 else
1723                                         printf("Port %d Link Down\n",
1724                                                 (uint8_t)portid);
1725                                 continue;
1726                         }
1727                         /* clear all_ports_up flag if any link down */
1728                         if (link.link_status == ETH_LINK_DOWN) {
1729                                 all_ports_up = 0;
1730                                 break;
1731                         }
1732                 }
1733                 /* after finally printing all link status, get out */
1734                 if (print_flag == 1)
1735                         break;
1736
1737                 if (all_ports_up == 0) {
1738                         fflush(stdout);
1739                         rte_delay_ms(CHECK_INTERVAL);
1740                 }
1741
1742                 /* set the print_flag if all ports up or timeout */
1743                 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
1744                         print_flag = 1;
1745                 }
1746         }
1747 }
1748
1749 static int
1750 set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1751 {
1752         uint16_t i;
1753         int diag;
1754         uint8_t mapping_found = 0;
1755
1756         for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
1757                 if ((tx_queue_stats_mappings[i].port_id == port_id) &&
1758                                 (tx_queue_stats_mappings[i].queue_id < nb_txq )) {
1759                         diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
1760                                         tx_queue_stats_mappings[i].queue_id,
1761                                         tx_queue_stats_mappings[i].stats_counter_id);
1762                         if (diag != 0)
1763                                 return diag;
1764                         mapping_found = 1;
1765                 }
1766         }
1767         if (mapping_found)
1768                 port->tx_queue_stats_mapping_enabled = 1;
1769         return 0;
1770 }
1771
1772 static int
1773 set_rx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port)
1774 {
1775         uint16_t i;
1776         int diag;
1777         uint8_t mapping_found = 0;
1778
1779         for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
1780                 if ((rx_queue_stats_mappings[i].port_id == port_id) &&
1781                                 (rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
1782                         diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
1783                                         rx_queue_stats_mappings[i].queue_id,
1784                                         rx_queue_stats_mappings[i].stats_counter_id);
1785                         if (diag != 0)
1786                                 return diag;
1787                         mapping_found = 1;
1788                 }
1789         }
1790         if (mapping_found)
1791                 port->rx_queue_stats_mapping_enabled = 1;
1792         return 0;
1793 }
1794
1795 static void
1796 map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port)
1797 {
1798         int diag = 0;
1799
1800         diag = set_tx_queue_stats_mapping_registers(pi, port);
1801         if (diag != 0) {
1802                 if (diag == -ENOTSUP) {
1803                         port->tx_queue_stats_mapping_enabled = 0;
1804                         printf("TX queue stats mapping not supported port id=%d\n", pi);
1805                 }
1806                 else
1807                         rte_exit(EXIT_FAILURE,
1808                                         "set_tx_queue_stats_mapping_registers "
1809                                         "failed for port id=%d diag=%d\n",
1810                                         pi, diag);
1811         }
1812
1813         diag = set_rx_queue_stats_mapping_registers(pi, port);
1814         if (diag != 0) {
1815                 if (diag == -ENOTSUP) {
1816                         port->rx_queue_stats_mapping_enabled = 0;
1817                         printf("RX queue stats mapping not supported port id=%d\n", pi);
1818                 }
1819                 else
1820                         rte_exit(EXIT_FAILURE,
1821                                         "set_rx_queue_stats_mapping_registers "
1822                                         "failed for port id=%d diag=%d\n",
1823                                         pi, diag);
1824         }
1825 }
1826
1827 static void
1828 rxtx_port_config(struct rte_port *port)
1829 {
1830         port->rx_conf = port->dev_info.default_rxconf;
1831         port->tx_conf = port->dev_info.default_txconf;
1832
1833         /* Check if any RX/TX parameters have been passed */
1834         if (rx_pthresh != RTE_PMD_PARAM_UNSET)
1835                 port->rx_conf.rx_thresh.pthresh = rx_pthresh;
1836
1837         if (rx_hthresh != RTE_PMD_PARAM_UNSET)
1838                 port->rx_conf.rx_thresh.hthresh = rx_hthresh;
1839
1840         if (rx_wthresh != RTE_PMD_PARAM_UNSET)
1841                 port->rx_conf.rx_thresh.wthresh = rx_wthresh;
1842
1843         if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
1844                 port->rx_conf.rx_free_thresh = rx_free_thresh;
1845
1846         if (rx_drop_en != RTE_PMD_PARAM_UNSET)
1847                 port->rx_conf.rx_drop_en = rx_drop_en;
1848
1849         if (tx_pthresh != RTE_PMD_PARAM_UNSET)
1850                 port->tx_conf.tx_thresh.pthresh = tx_pthresh;
1851
1852         if (tx_hthresh != RTE_PMD_PARAM_UNSET)
1853                 port->tx_conf.tx_thresh.hthresh = tx_hthresh;
1854
1855         if (tx_wthresh != RTE_PMD_PARAM_UNSET)
1856                 port->tx_conf.tx_thresh.wthresh = tx_wthresh;
1857
1858         if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
1859                 port->tx_conf.tx_rs_thresh = tx_rs_thresh;
1860
1861         if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
1862                 port->tx_conf.tx_free_thresh = tx_free_thresh;
1863
1864         if (txq_flags != RTE_PMD_PARAM_UNSET)
1865                 port->tx_conf.txq_flags = txq_flags;
1866 }
1867
1868 void
1869 init_port_config(void)
1870 {
1871         portid_t pid;
1872         struct rte_port *port;
1873
1874         FOREACH_PORT(pid, ports) {
1875                 port = &ports[pid];
1876                 port->dev_conf.rxmode = rx_mode;
1877                 port->dev_conf.fdir_conf = fdir_conf;
1878                 if (nb_rxq > 1) {
1879                         port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1880                         port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
1881                 } else {
1882                         port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
1883                         port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
1884                 }
1885
1886                 if (port->dcb_flag == 0) {
1887                         if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
1888                                 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
1889                         else
1890                                 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
1891                 }
1892
1893                 rxtx_port_config(port);
1894
1895                 rte_eth_macaddr_get(pid, &port->eth_addr);
1896
1897                 map_port_queue_stats_mapping_registers(pid, port);
1898 #ifdef RTE_NIC_BYPASS
1899                 rte_eth_dev_bypass_init(pid);
1900 #endif
1901         }
1902 }
1903
1904 void set_port_slave_flag(portid_t slave_pid)
1905 {
1906         struct rte_port *port;
1907
1908         port = &ports[slave_pid];
1909         port->slave_flag = 1;
1910 }
1911
1912 void clear_port_slave_flag(portid_t slave_pid)
1913 {
1914         struct rte_port *port;
1915
1916         port = &ports[slave_pid];
1917         port->slave_flag = 0;
1918 }
1919
1920 uint8_t port_is_bonding_slave(portid_t slave_pid)
1921 {
1922         struct rte_port *port;
1923
1924         port = &ports[slave_pid];
1925         return port->slave_flag;
1926 }
1927
1928 const uint16_t vlan_tags[] = {
1929                 0,  1,  2,  3,  4,  5,  6,  7,
1930                 8,  9, 10, 11,  12, 13, 14, 15,
1931                 16, 17, 18, 19, 20, 21, 22, 23,
1932                 24, 25, 26, 27, 28, 29, 30, 31
1933 };
1934
1935 static  int
1936 get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
1937                  enum dcb_mode_enable dcb_mode,
1938                  enum rte_eth_nb_tcs num_tcs,
1939                  uint8_t pfc_en)
1940 {
1941         uint8_t i;
1942
1943         /*
1944          * Builds up the correct configuration for dcb+vt based on the vlan tags array
1945          * given above, and the number of traffic classes available for use.
1946          */
1947         if (dcb_mode == DCB_VT_ENABLED) {
1948                 struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
1949                                 &eth_conf->rx_adv_conf.vmdq_dcb_conf;
1950                 struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
1951                                 &eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
1952
1953                 /* VMDQ+DCB RX and TX configurations */
1954                 vmdq_rx_conf->enable_default_pool = 0;
1955                 vmdq_rx_conf->default_pool = 0;
1956                 vmdq_rx_conf->nb_queue_pools =
1957                         (num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1958                 vmdq_tx_conf->nb_queue_pools =
1959                         (num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
1960
1961                 vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
1962                 for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
1963                         vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
1964                         vmdq_rx_conf->pool_map[i].pools =
1965                                 1 << (i % vmdq_rx_conf->nb_queue_pools);
1966                 }
1967                 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
1968                         vmdq_rx_conf->dcb_tc[i] = i;
1969                         vmdq_tx_conf->dcb_tc[i] = i;
1970                 }
1971
1972                 /* set DCB mode of RX and TX of multiple queues */
1973                 eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
1974                 eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
1975         } else {
1976                 struct rte_eth_dcb_rx_conf *rx_conf =
1977                                 &eth_conf->rx_adv_conf.dcb_rx_conf;
1978                 struct rte_eth_dcb_tx_conf *tx_conf =
1979                                 &eth_conf->tx_adv_conf.dcb_tx_conf;
1980
1981                 rx_conf->nb_tcs = num_tcs;
1982                 tx_conf->nb_tcs = num_tcs;
1983
1984                 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
1985                         rx_conf->dcb_tc[i] = i % num_tcs;
1986                         tx_conf->dcb_tc[i] = i % num_tcs;
1987                 }
1988                 eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
1989                 eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
1990                 eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
1991         }
1992
1993         if (pfc_en)
1994                 eth_conf->dcb_capability_en =
1995                                 ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
1996         else
1997                 eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
1998
1999         return 0;
2000 }
2001
2002 int
2003 init_port_dcb_config(portid_t pid,
2004                      enum dcb_mode_enable dcb_mode,
2005                      enum rte_eth_nb_tcs num_tcs,
2006                      uint8_t pfc_en)
2007 {
2008         struct rte_eth_conf port_conf;
2009         struct rte_port *rte_port;
2010         int retval;
2011         uint16_t i;
2012
2013         rte_port = &ports[pid];
2014
2015         memset(&port_conf, 0, sizeof(struct rte_eth_conf));
2016         /* Enter DCB configuration status */
2017         dcb_config = 1;
2018
2019         /*set configuration of DCB in vt mode and DCB in non-vt mode*/
2020         retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
2021         if (retval < 0)
2022                 return retval;
2023         port_conf.rxmode.hw_vlan_filter = 1;
2024
2025         /**
2026          * Write the configuration into the device.
2027          * Set the numbers of RX & TX queues to 0, so
2028          * the RX & TX queues will not be setup.
2029          */
2030         (void)rte_eth_dev_configure(pid, 0, 0, &port_conf);
2031
2032         rte_eth_dev_info_get(pid, &rte_port->dev_info);
2033
2034         /* If dev_info.vmdq_pool_base is greater than 0,
2035          * the queue id of vmdq pools is started after pf queues.
2036          */
2037         if (dcb_mode == DCB_VT_ENABLED &&
2038             rte_port->dev_info.vmdq_pool_base > 0) {
2039                 printf("VMDQ_DCB multi-queue mode is nonsensical"
2040                         " for port %d.", pid);
2041                 return -1;
2042         }
2043
2044         /* Assume the ports in testpmd have the same dcb capability
2045          * and has the same number of rxq and txq in dcb mode
2046          */
2047         if (dcb_mode == DCB_VT_ENABLED) {
2048                 if (rte_port->dev_info.max_vfs > 0) {
2049                         nb_rxq = rte_port->dev_info.nb_rx_queues;
2050                         nb_txq = rte_port->dev_info.nb_tx_queues;
2051                 } else {
2052                         nb_rxq = rte_port->dev_info.max_rx_queues;
2053                         nb_txq = rte_port->dev_info.max_tx_queues;
2054                 }
2055         } else {
2056                 /*if vt is disabled, use all pf queues */
2057                 if (rte_port->dev_info.vmdq_pool_base == 0) {
2058                         nb_rxq = rte_port->dev_info.max_rx_queues;
2059                         nb_txq = rte_port->dev_info.max_tx_queues;
2060                 } else {
2061                         nb_rxq = (queueid_t)num_tcs;
2062                         nb_txq = (queueid_t)num_tcs;
2063
2064                 }
2065         }
2066         rx_free_thresh = 64;
2067
2068         memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2069
2070         rxtx_port_config(rte_port);
2071         /* VLAN filter */
2072         rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
2073         for (i = 0; i < RTE_DIM(vlan_tags); i++)
2074                 rx_vft_set(pid, vlan_tags[i], 1);
2075
2076         rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2077         map_port_queue_stats_mapping_registers(pid, rte_port);
2078
2079         rte_port->dcb_flag = 1;
2080
2081         return 0;
2082 }
2083
2084 static void
2085 init_port(void)
2086 {
2087         portid_t pid;
2088
2089         /* Configuration of Ethernet ports. */
2090         ports = rte_zmalloc("testpmd: ports",
2091                             sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2092                             RTE_CACHE_LINE_SIZE);
2093         if (ports == NULL) {
2094                 rte_exit(EXIT_FAILURE,
2095                                 "rte_zmalloc(%d struct rte_port) failed\n",
2096                                 RTE_MAX_ETHPORTS);
2097         }
2098
2099         /* enabled allocated ports */
2100         for (pid = 0; pid < nb_ports; pid++)
2101                 ports[pid].enabled = 1;
2102 }
2103
2104 static void
2105 force_quit(void)
2106 {
2107         pmd_test_exit();
2108         prompt_exit();
2109 }
2110
2111 static void
2112 signal_handler(int signum)
2113 {
2114         if (signum == SIGINT || signum == SIGTERM) {
2115                 printf("\nSignal %d received, preparing to exit...\n",
2116                                 signum);
2117 #ifdef RTE_LIBRTE_PDUMP
2118                 /* uninitialize packet capture framework */
2119                 rte_pdump_uninit();
2120 #endif
2121 #ifdef RTE_LIBRTE_LATENCY_STATS
2122                 rte_latencystats_uninit();
2123 #endif
2124                 force_quit();
2125                 /* exit with the expected status */
2126                 signal(signum, SIG_DFL);
2127                 kill(getpid(), signum);
2128         }
2129 }
2130
2131 int
2132 main(int argc, char** argv)
2133 {
2134         int  diag;
2135         uint8_t port_id;
2136
2137         signal(SIGINT, signal_handler);
2138         signal(SIGTERM, signal_handler);
2139
2140         diag = rte_eal_init(argc, argv);
2141         if (diag < 0)
2142                 rte_panic("Cannot init EAL\n");
2143
2144 #ifdef RTE_LIBRTE_PDUMP
2145         /* initialize packet capture framework */
2146         rte_pdump_init(NULL);
2147 #endif
2148
2149         nb_ports = (portid_t) rte_eth_dev_count();
2150         if (nb_ports == 0)
2151                 RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
2152
2153         /* allocate port structures, and init them */
2154         init_port();
2155
2156         set_def_fwd_config();
2157         if (nb_lcores == 0)
2158                 rte_panic("Empty set of forwarding logical cores - check the "
2159                           "core mask supplied in the command parameters\n");
2160
2161         argc -= diag;
2162         argv += diag;
2163         if (argc > 1)
2164                 launch_args_parse(argc, argv);
2165
2166         if (!nb_rxq && !nb_txq)
2167                 printf("Warning: Either rx or tx queues should be non-zero\n");
2168
2169         if (nb_rxq > 1 && nb_rxq > nb_txq)
2170                 printf("Warning: nb_rxq=%d enables RSS configuration, "
2171                        "but nb_txq=%d will prevent to fully test it.\n",
2172                        nb_rxq, nb_txq);
2173
2174         init_config();
2175         if (start_port(RTE_PORT_ALL) != 0)
2176                 rte_exit(EXIT_FAILURE, "Start ports failed\n");
2177
2178         /* set all ports to promiscuous mode by default */
2179         FOREACH_PORT(port_id, ports)
2180                 rte_eth_promiscuous_enable(port_id);
2181
2182         /* Init metrics library */
2183         rte_metrics_init(rte_socket_id());
2184
2185 #ifdef RTE_LIBRTE_LATENCY_STATS
2186         if (latencystats_enabled != 0) {
2187                 int ret = rte_latencystats_init(1, NULL);
2188                 if (ret)
2189                         printf("Warning: latencystats init()"
2190                                 " returned error %d\n", ret);
2191                 printf("Latencystats running on lcore %d\n",
2192                         latencystats_lcore_id);
2193         }
2194 #endif
2195
2196         /* Setup bitrate stats */
2197 #ifdef RTE_LIBRTE_BITRATE
2198         bitrate_data = rte_stats_bitrate_create();
2199         if (bitrate_data == NULL)
2200                 rte_exit(EXIT_FAILURE, "Could not allocate bitrate data.\n");
2201         rte_stats_bitrate_reg(bitrate_data);
2202 #endif
2203
2204
2205 #ifdef RTE_LIBRTE_CMDLINE
2206         if (interactive == 1) {
2207                 if (auto_start) {
2208                         printf("Start automatic packet forwarding\n");
2209                         start_packet_forwarding(0);
2210                 }
2211                 prompt();
2212         } else
2213 #endif
2214         {
2215                 char c;
2216                 int rc;
2217
2218                 printf("No commandline core given, start packet forwarding\n");
2219                 start_packet_forwarding(0);
2220                 printf("Press enter to exit\n");
2221                 rc = read(0, &c, 1);
2222                 pmd_test_exit();
2223                 if (rc < 0)
2224                         return 1;
2225         }
2226
2227         return 0;
2228 }