]> git.proxmox.com Git - ceph.git/blob - ceph/src/dpdk/app/test-pmd/testpmd.c
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / dpdk / 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 }