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