summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIntel <intel.com>2012-09-04 13:54:00 +0100
committerThomas Monjalon <thomas.monjalon@6wind.com>2013-03-11 17:19:20 +0100
commitaf75078fece3615088e561357c1e97603e43a5fe (patch)
tree1e41a38f4acfbeaa044fa88b0c4d4e0b910bdc8a
parent0c9a540ed217764aefc5cb645f3cafd4f9e79765 (diff)
downloaddpdk-1.2.3r0.zip
dpdk-1.2.3r0.tar.gz
dpdk-1.2.3r0.tar.xz
first public releasev1.2.3r0
version 1.2.3 Signed-off-by: Intel
-rw-r--r--Makefile47
-rw-r--r--app/Makefile42
-rw-r--r--app/chkincs/Makefile96
-rw-r--r--app/chkincs/test.c50
-rw-r--r--app/chkincs/test.h90
-rw-r--r--app/chkincs/test_alarm.c53
-rw-r--r--app/chkincs/test_atomic.c93
-rw-r--r--app/chkincs/test_branch_prediction.c58
-rw-r--r--app/chkincs/test_byteorder.c84
-rw-r--r--app/chkincs/test_common.c76
-rw-r--r--app/chkincs/test_cpuflags.c53
-rw-r--r--app/chkincs/test_cycles.c63
-rw-r--r--app/chkincs/test_debug.c55
-rw-r--r--app/chkincs/test_eal.c52
-rw-r--r--app/chkincs/test_errno.c54
-rw-r--r--app/chkincs/test_ethdev.c72
-rw-r--r--app/chkincs/test_ether.c52
-rw-r--r--app/chkincs/test_fbk_hash.c53
-rw-r--r--app/chkincs/test_hash.c85
-rw-r--r--app/chkincs/test_hash_crc.c52
-rw-r--r--app/chkincs/test_interrupts.c53
-rw-r--r--app/chkincs/test_ip.c53
-rw-r--r--app/chkincs/test_jhash.c54
-rw-r--r--app/chkincs/test_launch.c68
-rw-r--r--app/chkincs/test_lcore.c66
-rw-r--r--app/chkincs/test_log.c58
-rw-r--r--app/chkincs/test_lpm.c64
-rw-r--r--app/chkincs/test_malloc.c57
-rw-r--r--app/chkincs/test_mbuf.c110
-rw-r--r--app/chkincs/test_memcpy.c58
-rw-r--r--app/chkincs/test_memory.c65
-rw-r--r--app/chkincs/test_mempool.c111
-rw-r--r--app/chkincs/test_memzone.c61
-rw-r--r--app/chkincs/test_pci.c86
-rw-r--r--app/chkincs/test_pci_dev_ids.c60
-rw-r--r--app/chkincs/test_per_lcore.c57
-rw-r--r--app/chkincs/test_prefetch.c58
-rw-r--r--app/chkincs/test_random.c54
-rw-r--r--app/chkincs/test_ring.c97
-rw-r--r--app/chkincs/test_rwlock.c60
-rw-r--r--app/chkincs/test_sctp.c52
-rw-r--r--app/chkincs/test_spinlock.c59
-rw-r--r--app/chkincs/test_string_fns.c52
-rw-r--r--app/chkincs/test_tailq.c55
-rw-r--r--app/chkincs/test_tcp.c52
-rw-r--r--app/chkincs/test_timer.c74
-rw-r--r--app/chkincs/test_udp.c52
-rw-r--r--app/chkincs/test_version.c52
-rw-r--r--app/dump_cfg/Makefile49
-rw-r--r--app/dump_cfg/dump_cfg_main.c229
-rw-r--r--app/test-pmd/Makefile63
-rw-r--r--app/test-pmd/cmdline.c2180
-rw-r--r--app/test-pmd/config.c1142
-rw-r--r--app/test-pmd/csumonly.c449
-rw-r--r--app/test-pmd/ieee1588fwd.c657
-rw-r--r--app/test-pmd/iofwd.c131
-rw-r--r--app/test-pmd/macfwd.c148
-rw-r--r--app/test-pmd/parameters.c646
-rw-r--r--app/test-pmd/rxonly.c194
-rw-r--r--app/test-pmd/testpmd.c1105
-rw-r--r--app/test-pmd/testpmd.h413
-rw-r--r--app/test-pmd/txonly.c317
-rw-r--r--app/test/Makefile82
-rwxr-xr-xapp/test/autotest.py664
-rw-r--r--app/test/commands.c391
-rwxr-xr-xapp/test/graph_mempool.py193
-rwxr-xr-xapp/test/graph_ring.py201
-rw-r--r--app/test/process.h89
-rw-r--r--app/test/test.c153
-rw-r--r--app/test/test.h85
-rw-r--r--app/test/test_alarm.c258
-rw-r--r--app/test/test_atomic.c381
-rw-r--r--app/test/test_byteorder.c97
-rw-r--r--app/test/test_cpuflags.c134
-rw-r--r--app/test/test_cycles.c94
-rw-r--r--app/test/test_debug.c150
-rw-r--r--app/test/test_eal_flags.c303
-rw-r--r--app/test/test_errno.c110
-rw-r--r--app/test/test_hash.c1785
-rw-r--r--app/test/test_interrupts.c419
-rw-r--r--app/test/test_logs.c96
-rw-r--r--app/test/test_lpm.c1365
-rw-r--r--app/test/test_lpm_routes.h28947
-rw-r--r--app/test/test_malloc.c776
-rw-r--r--app/test/test_mbuf.c875
-rw-r--r--app/test/test_memcpy.c429
-rw-r--r--app/test/test_memory.c92
-rw-r--r--app/test/test_mempool.c707
-rw-r--r--app/test/test_memzone.c639
-rw-r--r--app/test/test_mp_secondary.c236
-rw-r--r--app/test/test_pci.c192
-rw-r--r--app/test/test_per_lcore.c142
-rw-r--r--app/test/test_prefetch.c63
-rw-r--r--app/test/test_ring.c987
-rw-r--r--app/test/test_rwlock.c135
-rw-r--r--app/test/test_spinlock.c318
-rw-r--r--app/test/test_string_fns.c305
-rw-r--r--app/test/test_tailq.c125
-rw-r--r--app/test/test_timer.c363
-rw-r--r--app/test/test_version.c59
-rw-r--r--config/defconfig_i686-default-linuxapp-gcc240
-rw-r--r--config/defconfig_i686-default-linuxapp-icc230
-rw-r--r--config/defconfig_x86_64-default-linuxapp-gcc240
-rw-r--r--config/defconfig_x86_64-default-linuxapp-icc230
-rw-r--r--examples/cmdline/482246_CmdLine_Sample_App_Guide_Rev1.1.pdfbin0 -> 53739 bytes
-rw-r--r--examples/cmdline/Makefile52
-rw-r--r--examples/cmdline/commands.c282
-rw-r--r--examples/cmdline/commands.h41
-rw-r--r--examples/cmdline/main.c100
-rw-r--r--examples/cmdline/main.h47
-rw-r--r--examples/cmdline/parse_obj_list.c164
-rw-r--r--examples/cmdline/parse_obj_list.h113
-rw-r--r--examples/dpdk_qat/497691_QuickAssist_in_DPDK_Env_Sample_App_Guide_Rev1.0.pdfbin0 -> 99638 bytes
-rw-r--r--examples/dpdk_qat/Makefile81
-rw-r--r--examples/dpdk_qat/config_files/shumway_B0/dh89xxcc_qa_dev0.conf537
-rw-r--r--examples/dpdk_qat/config_files/shumway_B0/dh89xxcc_qa_dev1.conf537
-rw-r--r--examples/dpdk_qat/config_files/stargo_B0/dh89xxcc_qa_dev0.conf409
-rw-r--r--examples/dpdk_qat/crypto.c921
-rw-r--r--examples/dpdk_qat/crypto.h88
-rw-r--r--examples/dpdk_qat/main.c857
-rw-r--r--examples/dpdk_qat/main.h47
-rw-r--r--examples/exception_path/482248_ExceptionPath_Sample_App_Guide_Rev1.1.pdfbin0 -> 77734 bytes
-rw-r--r--examples/exception_path/Makefile57
-rw-r--r--examples/exception_path/main.c569
-rw-r--r--examples/helloworld/482249_HelloWorld_Sample_App_Guide_Rev1.1.pdfbin0 -> 48353 bytes
-rw-r--r--examples/helloworld/Makefile52
-rw-r--r--examples/helloworld/main.c82
-rw-r--r--examples/helloworld/main.h47
-rw-r--r--examples/ipv4_frag/490761_IPv4_Frag_Sample_App_Guide_Rev1.0.pdfbin0 -> 67178 bytes
-rw-r--r--examples/ipv4_frag/Makefile63
-rw-r--r--examples/ipv4_frag/main.c707
-rw-r--r--examples/ipv4_frag/main.h48
-rw-r--r--examples/ipv4_frag/rte_ipv4_frag.h253
-rw-r--r--examples/ipv4_multicast/496632_IPv4_Multicast_Sample_App_Guide_Rev1.0.pdfbin0 -> 109644 bytes
-rw-r--r--examples/ipv4_multicast/Makefile63
-rw-r--r--examples/ipv4_multicast/main.c834
-rw-r--r--examples/ipv4_multicast/main.h48
-rw-r--r--examples/l2fwd-vf/496039_L2Forwarding_VirtEnv_Sample_App_Guide_Rev1.0.pdfbin0 -> 70953 bytes
-rw-r--r--examples/l2fwd-vf/Makefile53
-rw-r--r--examples/l2fwd-vf/main.c708
-rw-r--r--examples/l2fwd-vf/main.h47
-rw-r--r--examples/l2fwd/482250_L2Forwarding_Sample_App_Guide_Rev1.1.pdfbin0 -> 80691 bytes
-rw-r--r--examples/l2fwd/Makefile52
-rw-r--r--examples/l2fwd/main.c745
-rw-r--r--examples/l2fwd/main.h47
-rw-r--r--examples/l3fwd-vf/496040_L3Forwarding_VirtEnv_Sample_App_Guide_Rev1.0.pdfbin0 -> 52089 bytes
-rw-r--r--examples/l3fwd-vf/Makefile58
-rw-r--r--examples/l3fwd-vf/main.c1079
-rw-r--r--examples/l3fwd-vf/main.h47
-rw-r--r--examples/l3fwd/482251_L3Forwarding_Sample_App_Guide_Rev1.2.pdfbin0 -> 61714 bytes
-rw-r--r--examples/l3fwd/Makefile58
-rw-r--r--examples/l3fwd/main.c1118
-rw-r--r--examples/l3fwd/main.h47
-rw-r--r--examples/link_status_interrupt/495672_Link_Status_Interrupt_Sample_App_Guide_Rev1.0.pdfbin0 -> 70985 bytes
-rw-r--r--examples/link_status_interrupt/Makefile52
-rw-r--r--examples/link_status_interrupt/main.c792
-rw-r--r--examples/link_status_interrupt/main.h47
-rw-r--r--examples/load_balancer/482252_LoadBalancer_Sample_App_Guide_Rev1.1.pdfbin0 -> 62413 bytes
-rw-r--r--examples/load_balancer/Makefile58
-rw-r--r--examples/load_balancer/config.c1058
-rw-r--r--examples/load_balancer/init.c507
-rw-r--r--examples/load_balancer/main.c112
-rw-r--r--examples/load_balancer/main.h377
-rw-r--r--examples/load_balancer/runtime.c669
-rw-r--r--examples/multi_process/482253_Multi_Process_Sample_App_Guide_Rev1.3.pdfbin0 -> 144607 bytes
-rw-r--r--examples/multi_process/Makefile49
-rw-r--r--examples/multi_process/client_server_mp/Makefile49
-rw-r--r--examples/multi_process/client_server_mp/mp_client/Makefile50
-rw-r--r--examples/multi_process/client_server_mp/mp_client/client.c294
-rw-r--r--examples/multi_process/client_server_mp/mp_server/Makefile63
-rw-r--r--examples/multi_process/client_server_mp/mp_server/args.c175
-rw-r--r--examples/multi_process/client_server_mp/mp_server/args.h41
-rw-r--r--examples/multi_process/client_server_mp/mp_server/init.c304
-rw-r--r--examples/multi_process/client_server_mp/mp_server/init.h74
-rw-r--r--examples/multi_process/client_server_mp/mp_server/main.c330
-rw-r--r--examples/multi_process/client_server_mp/mp_server/main.h50
-rw-r--r--examples/multi_process/client_server_mp/shared/common.h89
-rw-r--r--examples/multi_process/client_server_mp/shared/init_drivers.h58
-rw-r--r--examples/multi_process/simple_mp/Makefile52
-rw-r--r--examples/multi_process/simple_mp/main.c160
-rw-r--r--examples/multi_process/simple_mp/mp_commands.c169
-rw-r--r--examples/multi_process/simple_mp/mp_commands.h46
-rw-r--r--examples/multi_process/symmetric_mp/Makefile52
-rw-r--r--examples/multi_process/symmetric_mp/main.c471
-rw-r--r--examples/timer/482254_Timer_Sample_App_Guide_Rev1.1.pdfbin0 -> 52612 bytes
-rw-r--r--examples/timer/Makefile58
-rw-r--r--examples/timer/main.c156
-rw-r--r--examples/timer/main.h47
-rw-r--r--examples/vmdq_dcb/482255_VMDQ_DCB_L2Fwd_Sample_App_Guide_Rev1.1.pdfbin0 -> 71737 bytes
-rw-r--r--examples/vmdq_dcb/Makefile59
-rw-r--r--examples/vmdq_dcb/main.c331
-rw-r--r--examples/vmdq_dcb/main.h48
-rw-r--r--lib/Makefile51
-rw-r--r--lib/librte_cmdline/Makefile65
-rw-r--r--lib/librte_cmdline/cmdline.c240
-rw-r--r--lib/librte_cmdline/cmdline.h94
-rw-r--r--lib/librte_cmdline/cmdline_cirbuf.c434
-rw-r--r--lib/librte_cmdline/cmdline_cirbuf.h248
-rw-r--r--lib/librte_cmdline/cmdline_parse.c544
-rw-r--r--lib/librte_cmdline/cmdline_parse.h188
-rw-r--r--lib/librte_cmdline/cmdline_parse_etheraddr.c172
-rw-r--r--lib/librte_cmdline/cmdline_parse_etheraddr.h102
-rw-r--r--lib/librte_cmdline/cmdline_parse_ipaddr.c383
-rw-r--r--lib/librte_cmdline/cmdline_parse_ipaddr.h194
-rw-r--r--lib/librte_cmdline/cmdline_parse_num.c493
-rw-r--r--lib/librte_cmdline/cmdline_parse_num.h119
-rw-r--r--lib/librte_cmdline/cmdline_parse_portlist.c172
-rw-r--r--lib/librte_cmdline/cmdline_parse_portlist.h113
-rw-r--r--lib/librte_cmdline/cmdline_parse_string.c228
-rw-r--r--lib/librte_cmdline/cmdline_parse_string.h113
-rw-r--r--lib/librte_cmdline/cmdline_rdline.c675
-rw-r--r--lib/librte_cmdline/cmdline_rdline.h260
-rw-r--r--lib/librte_cmdline/cmdline_socket.c120
-rw-r--r--lib/librte_cmdline/cmdline_socket.h78
-rw-r--r--lib/librte_cmdline/cmdline_vt100.c182
-rw-r--r--lib/librte_cmdline/cmdline_vt100.h153
-rw-r--r--lib/librte_eal/Makefile41
-rw-r--r--lib/librte_eal/common/Makefile56
-rw-r--r--lib/librte_eal/common/eal_common_cpuflags.c265
-rw-r--r--lib/librte_eal/common/eal_common_errno.c72
-rw-r--r--lib/librte_eal/common/eal_common_launch.c122
-rw-r--r--lib/librte_eal/common/eal_common_log.c390
-rw-r--r--lib/librte_eal/common/eal_common_memory.c116
-rw-r--r--lib/librte_eal/common/eal_common_memzone.c376
-rw-r--r--lib/librte_eal/common/eal_common_pci.c145
-rw-r--r--lib/librte_eal/common/eal_common_tailqs.c113
-rw-r--r--lib/librte_eal/common/include/eal_private.h176
-rw-r--r--lib/librte_eal/common/include/i686/arch/rte_atomic.h959
-rw-r--r--lib/librte_eal/common/include/rte_alarm.h100
-rw-r--r--lib/librte_eal/common/include/rte_atomic.h657
-rw-r--r--lib/librte_eal/common/include/rte_branch_prediction.h72
-rw-r--r--lib/librte_eal/common/include/rte_byteorder.h244
-rw-r--r--lib/librte_eal/common/include/rte_common.h310
-rw-r--r--lib/librte_eal/common/include/rte_cpuflags.h174
-rw-r--r--lib/librte_eal/common/include/rte_cycles.h120
-rw-r--r--lib/librte_eal/common/include/rte_debug.h96
-rw-r--r--lib/librte_eal/common/include/rte_eal.h174
-rw-r--r--lib/librte_eal/common/include/rte_errno.h98
-rw-r--r--lib/librte_eal/common/include/rte_interrupts.h123
-rw-r--r--lib/librte_eal/common/include/rte_launch.h179
-rw-r--r--lib/librte_eal/common/include/rte_lcore.h191
-rw-r--r--lib/librte_eal/common/include/rte_log.h290
-rw-r--r--lib/librte_eal/common/include/rte_memcpy.h355
-rw-r--r--lib/librte_eal/common/include/rte_memory.h143
-rw-r--r--lib/librte_eal/common/include/rte_memzone.h200
-rw-r--r--lib/librte_eal/common/include/rte_pci.h197
-rw-r--r--lib/librte_eal/common/include/rte_pci_dev_ids.h205
-rw-r--r--lib/librte_eal/common/include/rte_per_lcore.h81
-rw-r--r--lib/librte_eal/common/include/rte_prefetch.h90
-rw-r--r--lib/librte_eal/common/include/rte_random.h93
-rw-r--r--lib/librte_eal/common/include/rte_rwlock.h174
-rw-r--r--lib/librte_eal/common/include/rte_spinlock.h243
-rw-r--r--lib/librte_eal/common/include/rte_string_fns.h165
-rw-r--r--lib/librte_eal/common/include/rte_tailq.h146
-rw-r--r--lib/librte_eal/common/include/rte_version.h85
-rw-r--r--lib/librte_eal/common/include/rte_warnings.h88
-rw-r--r--lib/librte_eal/common/include/x86_64/arch/rte_atomic.h943
-rw-r--r--lib/librte_eal/linuxapp/Makefile39
-rw-r--r--lib/librte_eal/linuxapp/eal/Makefile91
-rw-r--r--lib/librte_eal/linuxapp/eal/eal.c620
-rw-r--r--lib/librte_eal/linuxapp/eal/eal_alarm.c232
-rw-r--r--lib/librte_eal/linuxapp/eal/eal_debug.c114
-rw-r--r--lib/librte_eal/linuxapp/eal/eal_hpet.c232
-rw-r--r--lib/librte_eal/linuxapp/eal/eal_hugepage_info.c229
-rw-r--r--lib/librte_eal/linuxapp/eal/eal_interrupts.c540
-rw-r--r--lib/librte_eal/linuxapp/eal/eal_lcore.c192
-rw-r--r--lib/librte_eal/linuxapp/eal/eal_log.c137
-rw-r--r--lib/librte_eal/linuxapp/eal/eal_memory.c796
-rw-r--r--lib/librte_eal/linuxapp/eal/eal_pci.c770
-rw-r--r--lib/librte_eal/linuxapp/eal/eal_thread.c237
-rw-r--r--lib/librte_eal/linuxapp/eal/include/eal_fs_paths.h96
-rw-r--r--lib/librte_eal/linuxapp/eal/include/eal_hugepages.h62
-rw-r--r--lib/librte_eal/linuxapp/eal/include/eal_internal_cfg.h76
-rw-r--r--lib/librte_eal/linuxapp/eal/include/eal_thread.h55
-rw-r--r--lib/librte_eal/linuxapp/eal/include/exec-env/rte_interrupts.h56
-rw-r--r--lib/librte_eal/linuxapp/eal/include/exec-env/rte_lcore.h92
-rw-r--r--lib/librte_eal/linuxapp/eal/include/exec-env/rte_per_lcore.h69
-rw-r--r--lib/librte_eal/linuxapp/igb_uio/Makefile55
-rw-r--r--lib/librte_eal/linuxapp/igb_uio/igb_uio.c402
-rw-r--r--lib/librte_ether/Makefile55
-rw-r--r--lib/librte_ether/rte_ethdev.c1381
-rw-r--r--lib/librte_ether/rte_ethdev.h1809
-rw-r--r--lib/librte_ether/rte_ether.h256
-rw-r--r--lib/librte_hash/Makefile55
-rw-r--r--lib/librte_hash/rte_fbk_hash.c210
-rw-r--r--lib/librte_hash/rte_fbk_hash.h334
-rw-r--r--lib/librte_hash/rte_hash.c407
-rw-r--r--lib/librte_hash/rte_hash.h236
-rw-r--r--lib/librte_hash/rte_hash_crc.h114
-rw-r--r--lib/librte_hash/rte_jhash.h263
-rw-r--r--lib/librte_lpm/Makefile51
-rw-r--r--lib/librte_lpm/rte_lpm.c971
-rw-r--r--lib/librte_lpm/rte_lpm.h288
-rw-r--r--lib/librte_malloc/Makefile50
-rw-r--r--lib/librte_malloc/malloc_elem.c280
-rw-r--r--lib/librte_malloc/malloc_elem.h177
-rw-r--r--lib/librte_malloc/malloc_heap.c181
-rw-r--r--lib/librte_malloc/malloc_heap.h68
-rw-r--r--lib/librte_malloc/rte_malloc.c166
-rw-r--r--lib/librte_malloc/rte_malloc.h212
-rw-r--r--lib/librte_mbuf/Makefile50
-rw-r--r--lib/librte_mbuf/rte_mbuf.c252
-rw-r--r--lib/librte_mbuf/rte_mbuf.h1019
-rw-r--r--lib/librte_mempool/Makefile50
-rw-r--r--lib/librte_mempool/rte_mempool.c491
-rw-r--r--lib/librte_mempool/rte_mempool.h1087
-rw-r--r--lib/librte_net/Makefile42
-rw-r--r--lib/librte_net/rte_ip.h255
-rw-r--r--lib/librte_net/rte_sctp.h101
-rw-r--r--lib/librte_net/rte_tcp.h106
-rw-r--r--lib/librte_net/rte_udp.h101
-rw-r--r--lib/librte_pmd_igb/Makefile64
-rw-r--r--lib/librte_pmd_igb/e1000_ethdev.c1319
-rw-r--r--lib/librte_pmd_igb/e1000_ethdev.h117
-rw-r--r--lib/librte_pmd_igb/e1000_logs.h74
-rw-r--r--lib/librte_pmd_igb/e1000_rxtx.c1859
-rw-r--r--lib/librte_pmd_igb/igb/README74
-rw-r--r--lib/librte_pmd_igb/igb/e1000_82575.c2429
-rw-r--r--lib/librte_pmd_igb/igb/e1000_82575.h487
-rw-r--r--lib/librte_pmd_igb/igb/e1000_api.c1152
-rw-r--r--lib/librte_pmd_igb/igb/e1000_api.h156
-rw-r--r--lib/librte_pmd_igb/igb/e1000_defines.h1733
-rw-r--r--lib/librte_pmd_igb/igb/e1000_hw.h767
-rw-r--r--lib/librte_pmd_igb/igb/e1000_mac.c2170
-rw-r--r--lib/librte_pmd_igb/igb/e1000_mac.h95
-rw-r--r--lib/librte_pmd_igb/igb/e1000_manage.c472
-rw-r--r--lib/librte_pmd_igb/igb/e1000_manage.h90
-rw-r--r--lib/librte_pmd_igb/igb/e1000_mbx.c764
-rw-r--r--lib/librte_pmd_igb/igb/e1000_mbx.h106
-rw-r--r--lib/librte_pmd_igb/igb/e1000_nvm.c1071
-rw-r--r--lib/librte_pmd_igb/igb/e1000_nvm.h66
-rw-r--r--lib/librte_pmd_igb/igb/e1000_osdep.c72
-rw-r--r--lib/librte_pmd_igb/igb/e1000_osdep.h128
-rw-r--r--lib/librte_pmd_igb/igb/e1000_phy.c2988
-rw-r--r--lib/librte_pmd_igb/igb/e1000_phy.h217
-rw-r--r--lib/librte_pmd_igb/igb/e1000_regs.h574
-rw-r--r--lib/librte_pmd_igb/igb/e1000_vf.c574
-rw-r--r--lib/librte_pmd_igb/igb/e1000_vf.h294
-rw-r--r--lib/librte_pmd_igb/igb/if_igb.c5567
-rw-r--r--lib/librte_pmd_igb/igb/if_igb.h541
-rw-r--r--lib/librte_pmd_ixgbe/Makefile65
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/README70
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe.c5442
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe.h521
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_82598.c1402
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c2281
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c1130
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h168
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c4049
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.h135
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_mbx.c751
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_mbx.h112
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_osdep.h145
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c1843
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.h141
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h3138
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.c524
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.h113
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.c989
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.h42
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixv.c4010
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe/ixv.h430
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe_ethdev.c1609
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe_ethdev.h176
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe_fdir.c891
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe_logs.h76
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe_rxtx.c2445
-rw-r--r--lib/librte_ring/Makefile50
-rw-r--r--lib/librte_ring/rte_ring.c283
-rw-r--r--lib/librte_ring/rte_ring.h830
-rw-r--r--lib/librte_timer/Makefile50
-rw-r--r--lib/librte_timer/rte_timer.c506
-rw-r--r--lib/librte_timer/rte_timer.h332
-rw-r--r--mk/arch/i686/rte.vars.mk59
-rw-r--r--mk/arch/x86_64/rte.vars.mk59
-rw-r--r--mk/exec-env/linuxapp/rte.app.mk38
-rw-r--r--mk/exec-env/linuxapp/rte.vars.mk52
-rw-r--r--mk/internal/rte.build-post.mk64
-rw-r--r--mk/internal/rte.build-pre.mk34
-rw-r--r--mk/internal/rte.clean-post.mk64
-rw-r--r--mk/internal/rte.clean-pre.mk34
-rw-r--r--mk/internal/rte.compile-post.mk35
-rw-r--r--mk/internal/rte.compile-pre.mk178
-rw-r--r--mk/internal/rte.depdirs-post.mk44
-rw-r--r--mk/internal/rte.depdirs-pre.mk34
-rw-r--r--mk/internal/rte.exthelp-post.mk41
-rw-r--r--mk/internal/rte.install-post.mk101
-rw-r--r--mk/internal/rte.install-pre.mk62
-rw-r--r--mk/machine/atm/rte.vars.mk61
-rw-r--r--mk/machine/default/rte.vars.mk61
-rw-r--r--mk/machine/ivb/rte.vars.mk61
-rw-r--r--mk/machine/native/rte.vars.mk111
-rw-r--r--mk/machine/nhm/rte.vars.mk61
-rw-r--r--mk/machine/snb/rte.vars.mk61
-rw-r--r--mk/machine/wsm/rte.vars.mk61
-rw-r--r--mk/rte.app.mk236
-rw-r--r--mk/rte.doc.mk127
-rw-r--r--mk/rte.extapp.mk56
-rw-r--r--mk/rte.extlib.mk56
-rw-r--r--mk/rte.extobj.mk56
-rw-r--r--mk/rte.extvars.mk83
-rw-r--r--mk/rte.gnuconfigure.mk76
-rw-r--r--mk/rte.hostapp.mk125
-rw-r--r--mk/rte.hostlib.mk118
-rw-r--r--mk/rte.install.mk60
-rw-r--r--mk/rte.lib.mk116
-rw-r--r--mk/rte.module.mk117
-rw-r--r--mk/rte.obj.mk114
-rw-r--r--mk/rte.sdkbuild.mk102
-rw-r--r--mk/rte.sdkconfig.mk109
-rw-r--r--mk/rte.sdkdepdirs.mk65
-rw-r--r--mk/rte.sdkdoc.mk73
-rw-r--r--mk/rte.sdkgcov.mk69
-rw-r--r--mk/rte.sdkinstall.mk76
-rw-r--r--mk/rte.sdkroot.mk158
-rw-r--r--mk/rte.sdktest.mk66
-rw-r--r--mk/rte.sdktestall.mk65
-rw-r--r--mk/rte.subdir.mk114
-rw-r--r--mk/rte.vars.mk125
-rw-r--r--mk/target/generic/rte.app.mk43
-rw-r--r--mk/target/generic/rte.vars.mk150
-rw-r--r--mk/toolchain/gcc/rte.toolchain-compat.mk93
-rw-r--r--mk/toolchain/gcc/rte.vars.mk87
-rw-r--r--mk/toolchain/icc/rte.toolchain-compat.mk82
-rw-r--r--mk/toolchain/icc/rte.vars.mk98
-rw-r--r--scripts/Makefile38
-rwxr-xr-xscripts/depdirs-rule.sh97
-rwxr-xr-xscripts/gen-build-mk.sh55
-rwxr-xr-xscripts/gen-config-h.sh41
-rwxr-xr-xscripts/import_autotest.sh87
-rwxr-xr-xscripts/relpath.sh100
-rwxr-xr-xscripts/test-framework.sh133
-rw-r--r--scripts/testhost/Makefile50
-rw-r--r--scripts/testhost/testhost.c57
-rwxr-xr-xtools/setup.sh420
435 files changed, 169022 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..347f7e1
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,47 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# version: DPDK.L.1.2.3-3
+
+#
+# Head Makefile for compiling rte SDK
+#
+
+RTE_SDK := $(CURDIR)
+export RTE_SDK
+
+#
+# directory list
+#
+
+ROOTDIRS-y := scripts lib app
+
+include $(RTE_SDK)/mk/rte.sdkroot.mk
diff --git a/app/Makefile b/app/Makefile
new file mode 100644
index 0000000..7a206e3
--- /dev/null
+++ b/app/Makefile
@@ -0,0 +1,42 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# version: DPDK.L.1.2.3-3
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+DIRS-$(CONFIG_RTE_APP_TEST) += test
+DIRS-$(CONFIG_RTE_TEST_PMD) += test-pmd
+DIRS-$(CONFIG_RTE_APP_CHKINCS) += chkincs
+
+DIRS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += dump_cfg
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/app/chkincs/Makefile b/app/chkincs/Makefile
new file mode 100644
index 0000000..1ec3337
--- /dev/null
+++ b/app/chkincs/Makefile
@@ -0,0 +1,96 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# version: DPDK.L.1.2.3-3
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+APP = chkincs
+
+#
+# all source are stored in SRCS-y
+#
+
+SRCS-$(CONFIG_RTE_APP_CHKINCS) += test.c \
+ test_alarm.c \
+ test_atomic.c \
+ test_branch_prediction.c \
+ test_byteorder.c \
+ test_common.c \
+ test_cpuflags.c \
+ test_cycles.c \
+ test_debug.c \
+ test_eal.c \
+ test_errno.c \
+ test_ethdev.c \
+ test_ether.c \
+ test_fbk_hash.c \
+ test_hash_crc.c \
+ test_hash.c \
+ test_interrupts.c \
+ test_ip.c \
+ test_jhash.c \
+ test_launch.c \
+ test_lcore.c \
+ test_log.c \
+ test_lpm.c \
+ test_malloc.c \
+ test_mbuf.c \
+ test_memcpy.c \
+ test_memory.c \
+ test_mempool.c \
+ test_memzone.c \
+ test_pci_dev_ids.c \
+ test_pci.c \
+ test_per_lcore.c \
+ test_prefetch.c \
+ test_random.c \
+ test_ring.c \
+ test_rwlock.c \
+ test_sctp.c \
+ test_spinlock.c \
+ test_string_fns.c \
+ test_tailq.c \
+ test_tcp.c \
+ test_timer.c \
+ test_udp.c \
+ test_version.c
+
+CFLAGS += -O0 -fno-inline
+CFLAGS += $(WERROR_FLAGS)
+
+# this application needs libraries first
+DEPDIRS-$(CONFIG_RTE_APP_CHKINCS) += lib
+
+include $(RTE_SDK)/mk/rte.app.mk
diff --git a/app/chkincs/test.c b/app/chkincs/test.c
new file mode 100644
index 0000000..cd44fc2
--- /dev/null
+++ b/app/chkincs/test.c
@@ -0,0 +1,50 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+main(__attribute__((unused)) int argc, __attribute__((unused)) char **argv)
+{
+ return 0;
+}
diff --git a/app/chkincs/test.h b/app/chkincs/test.h
new file mode 100644
index 0000000..4d6ec6e
--- /dev/null
+++ b/app/chkincs/test.h
@@ -0,0 +1,90 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#ifndef _TEST_H_
+#define _TEST_H_
+
+/* icc on baremetal gives us troubles with function named 'main' */
+#ifdef RTE_EXEC_ENV_BAREMETAL
+#define main _main
+#endif
+
+int main(int argc, char **argv);
+
+int test_alarm(void);
+int test_atomic(void);
+int test_branch_prediction(void);
+int test_byteorder(void);
+int test_common(void);
+int test_cpuflags(void);
+int test_cycles(void);
+int test_debug(void);
+int test_eal(void);
+int test_errno(void);
+int test_ethdev(void);
+int test_ether(void);
+int test_fbk_hash(void);
+int test_hash_crc(void);
+int test_hash(void);
+int test_interrupts(void);
+int test_ip(void);
+int test_jhash(void);
+int test_launch(void);
+int test_lcore(void);
+int test_log(void);
+int test_lpm(void);
+int test_malloc(void);
+int test_mbuf(void);
+int test_memcpy(void);
+int test_memory(void);
+int test_mempool(void);
+int test_memzone(void);
+int test_pci_dev_ids(void);
+int test_pci(void);
+int test_per_lcore(void);
+int test_prefetch(void);
+int test_random(void);
+int test_ring(void);
+int test_rwlock(void);
+int test_sctp(void);
+int test_spinlock(void);
+int test_string_fns(void);
+int test_tailq(void);
+int test_tcp(void);
+int test_timer(void);
+int test_udp(void);
+int test_version(void);
+
+#endif
diff --git a/app/chkincs/test_alarm.c b/app/chkincs/test_alarm.c
new file mode 100644
index 0000000..233d4f6
--- /dev/null
+++ b/app/chkincs/test_alarm.c
@@ -0,0 +1,53 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_alarm.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_alarm(void)
+{
+ rte_eal_alarm_set(10, 0, 0);
+ return 1;
+}
diff --git a/app/chkincs/test_atomic.c b/app/chkincs/test_atomic.c
new file mode 100644
index 0000000..f490639
--- /dev/null
+++ b/app/chkincs/test_atomic.c
@@ -0,0 +1,93 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_atomic.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_atomic(void)
+{
+ rte_atomic16_t a16 = RTE_ATOMIC16_INIT(1);
+ rte_atomic32_t a32 = RTE_ATOMIC32_INIT(1);
+ rte_atomic64_t a64 = RTE_ATOMIC64_INIT(1);
+ int x;
+
+ rte_mb();
+ rte_wmb();
+ rte_rmb();
+
+ rte_atomic16_init(&a16);
+ rte_atomic16_set(&a16, 1);
+ x = rte_atomic16_read(&a16);
+ rte_atomic16_inc(&a16);
+ rte_atomic16_dec(&a16);
+ rte_atomic16_add(&a16, 5);
+ rte_atomic16_sub(&a16, 5);
+ x = rte_atomic16_test_and_set(&a16);
+ x = rte_atomic16_add_return(&a16, 10);
+
+ rte_atomic32_init(&a32);
+ rte_atomic32_set(&a32, 1);
+ x = rte_atomic32_read(&a32);
+ rte_atomic32_inc(&a32);
+ rte_atomic32_dec(&a32);
+ rte_atomic32_add(&a32, 5);
+ rte_atomic32_sub(&a32, 5);
+ x = rte_atomic32_test_and_set(&a32);
+ x = rte_atomic32_add_return(&a32, 10);
+
+ rte_atomic64_init(&a64);
+ rte_atomic64_set(&a64, 1);
+ x = rte_atomic64_read(&a64);
+ rte_atomic64_inc(&a64);
+ rte_atomic64_dec(&a64);
+ rte_atomic64_add(&a64, 5);
+ rte_atomic64_sub(&a64, 5);
+ x = rte_atomic64_test_and_set(&a64);
+ x = rte_atomic64_add_return(&a64, 10);
+ (void)x;
+
+ return 1;
+}
+
diff --git a/app/chkincs/test_branch_prediction.c b/app/chkincs/test_branch_prediction.c
new file mode 100644
index 0000000..219ddf1
--- /dev/null
+++ b/app/chkincs/test_branch_prediction.c
@@ -0,0 +1,58 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_branch_prediction.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int test_branch_prediction(void)
+{
+ int a = 1;
+ int b = 2;
+
+ if (likely(a < b))
+ return 0;
+ else if (unlikely(a < b))
+ return 1;
+ else return 2;
+}
diff --git a/app/chkincs/test_byteorder.c b/app/chkincs/test_byteorder.c
new file mode 100644
index 0000000..91b0d6e
--- /dev/null
+++ b/app/chkincs/test_byteorder.c
@@ -0,0 +1,84 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_byteorder.h>
+
+#include "test.h"
+
+static volatile uint16_t u16 = 0x1337;
+static volatile uint32_t u32 = 0xdeadbeefUL;
+static volatile uint64_t u64 = 0xdeadcafebabefaceULL;
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_byteorder(void)
+{
+ uint16_t res_u16;
+ uint32_t res_u32;
+ uint64_t res_u64;
+
+ res_u16 = rte_bswap16(u16);
+ res_u32 = rte_bswap32(u32);
+ res_u64 = rte_bswap64(u64);
+
+ res_u16 = rte_cpu_to_le_16(u16);
+ res_u32 = rte_cpu_to_le_32(u32);
+ res_u64 = rte_cpu_to_le_64(u64);
+
+ res_u16 = rte_cpu_to_be_16(u16);
+ res_u32 = rte_cpu_to_be_32(u32);
+ res_u64 = rte_cpu_to_be_64(u64);
+
+ res_u16 = rte_le_to_cpu_16(u16);
+ res_u32 = rte_le_to_cpu_32(u32);
+ res_u64 = rte_le_to_cpu_64(u64);
+
+ res_u16 = rte_be_to_cpu_16(u16);
+ res_u32 = rte_be_to_cpu_32(u32);
+ res_u64 = rte_be_to_cpu_64(u64);
+
+ (void)res_u16;
+ (void)res_u32;
+ (void)res_u64;
+
+ return 1;
+}
diff --git a/app/chkincs/test_common.c b/app/chkincs/test_common.c
new file mode 100644
index 0000000..3f86d5c
--- /dev/null
+++ b/app/chkincs/test_common.c
@@ -0,0 +1,76 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_common.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+static int
+test_func(__rte_unused int var1, int var2)
+{
+ RTE_SET_USED(var2);
+ return 1;
+}
+
+static int static_var1 = 3;
+static int static_var2 = 6;
+
+int
+test_common(void)
+{
+ int *ptr1 = &static_var1, *ptr2 = &static_var2;
+ int var;
+
+ ptr2 = RTE_PTR_ADD(ptr1, 10);
+ ptr2 = RTE_PTR_SUB(ptr1, 5);
+ var = RTE_PTR_DIFF(ptr1, ptr2);
+
+ var = RTE_ALIGN(var, 16);
+
+ RTE_BUILD_BUG_ON(0);
+
+ var = RTE_MIN(10, 5);
+ var = RTE_MAX(10, 5);
+
+ return test_func(10, 5);
+}
diff --git a/app/chkincs/test_cpuflags.c b/app/chkincs/test_cpuflags.c
new file mode 100644
index 0000000..017bb66
--- /dev/null
+++ b/app/chkincs/test_cpuflags.c
@@ -0,0 +1,53 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_cpuflags.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_cpuflags(void)
+{
+ rte_cpu_get_flag_enabled(RTE_CPUFLAG_SSE3);
+ return 1;
+}
diff --git a/app/chkincs/test_cycles.c b/app/chkincs/test_cycles.c
new file mode 100644
index 0000000..c85a35a
--- /dev/null
+++ b/app/chkincs/test_cycles.c
@@ -0,0 +1,63 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_cycles.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_cycles(void)
+{
+ uint64_t hz, c;
+
+ hz = rte_get_hpet_hz();
+ c = rte_get_hpet_cycles();
+ rte_delay_us(10);
+ rte_delay_ms(10);
+ c = rte_rdtsc();
+
+ (void)hz;
+ (void)c;
+
+ return 1;
+}
diff --git a/app/chkincs/test_debug.c b/app/chkincs/test_debug.c
new file mode 100644
index 0000000..58ecdad
--- /dev/null
+++ b/app/chkincs/test_debug.c
@@ -0,0 +1,55 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_debug.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_debug(void)
+{
+ rte_dump_stack();
+ rte_dump_registers();
+ rte_panic("oops %d", 10);
+ return 1;
+}
diff --git a/app/chkincs/test_eal.c b/app/chkincs/test_eal.c
new file mode 100644
index 0000000..2b77e62
--- /dev/null
+++ b/app/chkincs/test_eal.c
@@ -0,0 +1,52 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_eal.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_eal(void)
+{
+ return 1;
+}
diff --git a/app/chkincs/test_errno.c b/app/chkincs/test_errno.c
new file mode 100644
index 0000000..d02ec94
--- /dev/null
+++ b/app/chkincs/test_errno.c
@@ -0,0 +1,54 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_errno.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_errno(void)
+{
+ if (rte_errno != 0)
+ return -1;
+ return 1;
+}
diff --git a/app/chkincs/test_ethdev.c b/app/chkincs/test_ethdev.c
new file mode 100644
index 0000000..180a796
--- /dev/null
+++ b/app/chkincs/test_ethdev.c
@@ -0,0 +1,72 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+
+#include <rte_ethdev.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+static struct rte_eth_conf port_conf;
+static struct rte_eth_rxconf rx_conf;
+static struct rte_eth_txconf tx_conf;
+static struct rte_mempool *mp;
+
+int
+test_ethdev(void)
+{
+ struct rte_eth_link link;
+ int x;
+ struct ether_addr ea;
+
+ x = rte_eth_dev_count();
+ x = rte_eth_dev_configure(0, 1, 1, &port_conf);
+ rte_eth_macaddr_get(0, &ea);
+ x = rte_eth_rx_queue_setup(0, 0, 128, 0, &rx_conf, mp);
+ x = rte_eth_tx_queue_setup(0, 0, 128, 0, &tx_conf);
+ rte_eth_link_get(0, &link);
+ x = rte_eth_dev_start(0);
+
+ (void)x;
+
+ return 1;
+}
diff --git a/app/chkincs/test_ether.c b/app/chkincs/test_ether.c
new file mode 100644
index 0000000..b089aaf
--- /dev/null
+++ b/app/chkincs/test_ether.c
@@ -0,0 +1,52 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_ether.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_ether(void)
+{
+ return 1;
+}
diff --git a/app/chkincs/test_fbk_hash.c b/app/chkincs/test_fbk_hash.c
new file mode 100644
index 0000000..e1e62a0
--- /dev/null
+++ b/app/chkincs/test_fbk_hash.c
@@ -0,0 +1,53 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_fbk_hash.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_fbk_hash(void)
+{
+ void * ptr = (void *)RTE_FBK_HASH_FUNC_DEFAULT;
+ return ptr == ptr;
+}
diff --git a/app/chkincs/test_hash.c b/app/chkincs/test_hash.c
new file mode 100644
index 0000000..c989070
--- /dev/null
+++ b/app/chkincs/test_hash.c
@@ -0,0 +1,85 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_hash.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+/* Parameters used for hash table in unit test functions. */
+static struct rte_hash_parameters ut_params = {
+ "name", /* name */
+ 64, /* entries */
+ 4, /* bucket_entries */
+ 8, /* key_len */
+ 0, /* hash_func */
+ 0, /* hash_func_init_val */
+ 0, /* socket_id */
+};
+
+struct key {
+ char key[8];
+};
+
+/* Keys used by unit test functions */
+static struct key keys[1] = {
+ {
+ { 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, },
+ }
+};
+
+int test_hash(void)
+{
+ struct rte_hash *handle;
+ int32_t pos0;
+
+ handle = rte_hash_create(&ut_params);
+ if (handle == 0) {
+ return -1;
+ }
+ pos0 = rte_hash_add_key(handle, &keys[0]);
+ pos0 = rte_hash_lookup(handle, &keys[0]);
+ pos0 = rte_hash_del_key(handle, &keys[0]);
+ rte_hash_free(handle);
+ (void)pos0; /* remove compiler warning */
+ return 0;
+}
diff --git a/app/chkincs/test_hash_crc.c b/app/chkincs/test_hash_crc.c
new file mode 100644
index 0000000..f996a09
--- /dev/null
+++ b/app/chkincs/test_hash_crc.c
@@ -0,0 +1,52 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_hash_crc.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_hash_crc(void)
+{
+ return 1;
+}
diff --git a/app/chkincs/test_interrupts.c b/app/chkincs/test_interrupts.c
new file mode 100644
index 0000000..9d55160
--- /dev/null
+++ b/app/chkincs/test_interrupts.c
@@ -0,0 +1,53 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_interrupts.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_interrupts(void)
+{
+ rte_intr_callback_register(0, 0, 0);
+ return 1;
+}
diff --git a/app/chkincs/test_ip.c b/app/chkincs/test_ip.c
new file mode 100644
index 0000000..4da405c
--- /dev/null
+++ b/app/chkincs/test_ip.c
@@ -0,0 +1,53 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_ip.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_ip(void)
+{
+ uint64_t var = IPv4(1,1,1,1);
+ return IS_IPV4_MCAST(var);
+}
diff --git a/app/chkincs/test_jhash.c b/app/chkincs/test_jhash.c
new file mode 100644
index 0000000..f63a68d
--- /dev/null
+++ b/app/chkincs/test_jhash.c
@@ -0,0 +1,54 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_jhash.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_jhash(void)
+{
+ uint32_t a = 1, b = 2, c = 3;
+ __rte_jhash_mix(a,b,c);
+ return 1;
+}
diff --git a/app/chkincs/test_launch.c b/app/chkincs/test_launch.c
new file mode 100644
index 0000000..6395147
--- /dev/null
+++ b/app/chkincs/test_launch.c
@@ -0,0 +1,68 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_launch.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+static int
+test_launch_per_core(__attribute__((unused)) void *arg)
+{
+ return 0;
+}
+
+int
+test_launch(void)
+{
+ enum rte_lcore_state_t s;
+
+ rte_eal_remote_launch(test_launch_per_core, (void *)0, 0);
+ rte_eal_wait_lcore(0);
+ rte_eal_mp_remote_launch(test_launch_per_core, (void *)0, CALL_MASTER);
+ rte_eal_mp_wait_lcore();
+ s = rte_eal_get_lcore_state(0);
+
+ (void)s;
+
+ return 0;
+}
diff --git a/app/chkincs/test_lcore.c b/app/chkincs/test_lcore.c
new file mode 100644
index 0000000..221b122
--- /dev/null
+++ b/app/chkincs/test_lcore.c
@@ -0,0 +1,66 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_lcore.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_lcore(void)
+{
+ unsigned x;
+
+ x = rte_socket_id();
+ x = rte_lcore_id();
+ x = rte_lcore_to_socket_id(x);
+ x = rte_lcore_count();
+ x = rte_lcore_is_enabled(x);
+
+ RTE_LCORE_FOREACH(x)
+ (void)x;
+
+ RTE_LCORE_FOREACH_SLAVE(x)
+ (void)x;
+
+ return 0;
+}
diff --git a/app/chkincs/test_log.c b/app/chkincs/test_log.c
new file mode 100644
index 0000000..c640966
--- /dev/null
+++ b/app/chkincs/test_log.c
@@ -0,0 +1,58 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_log.h>
+
+#include "test.h"
+
+#define RTE_LOGTYPE_TESTAPP1 RTE_LOGTYPE_USER1
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_log(void)
+{
+ rte_set_log_type(RTE_LOGTYPE_TESTAPP1, 1);
+ rte_set_log_level(RTE_LOG_DEBUG);
+ RTE_LOG(DEBUG, TESTAPP1, "this is a debug level message %d\n", 1);
+ rte_log_dump_history();
+ return 0;
+}
diff --git a/app/chkincs/test_lpm.c b/app/chkincs/test_lpm.c
new file mode 100644
index 0000000..989676e
--- /dev/null
+++ b/app/chkincs/test_lpm.c
@@ -0,0 +1,64 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_lpm.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_lpm(void)
+{
+ struct rte_lpm *lpm = 0;
+ uint32_t ip = 0;
+ uint8_t depth = 24, next_hop_add = 100, next_hop_return = 0;
+
+ lpm = rte_lpm_create(__func__, -1, 256, RTE_LPM_HEAP);
+ if (lpm == 0)
+ return -1;
+ rte_lpm_add(lpm, ip, depth, next_hop_add);
+ rte_lpm_lookup(lpm, ip, &next_hop_return);
+ rte_lpm_delete(lpm, ip, depth);
+ rte_lpm_lookup(lpm, ip, &next_hop_return);
+ rte_lpm_free(lpm);
+ return 0;
+}
diff --git a/app/chkincs/test_malloc.c b/app/chkincs/test_malloc.c
new file mode 100644
index 0000000..885b356
--- /dev/null
+++ b/app/chkincs/test_malloc.c
@@ -0,0 +1,57 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_malloc.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_malloc(void)
+{
+ void *p1;
+
+ p1 = rte_malloc("dummy", 1000, 8);
+ rte_free(p1);
+
+ return 0;
+}
diff --git a/app/chkincs/test_mbuf.c b/app/chkincs/test_mbuf.c
new file mode 100644
index 0000000..1d3ff9c
--- /dev/null
+++ b/app/chkincs/test_mbuf.c
@@ -0,0 +1,110 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+
+#include <rte_mbuf.h>
+
+#include "test.h"
+
+#define MBUF_SIZE 2048
+#define NB_MBUF 128
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_mbuf(void)
+{
+ struct rte_mempool *mbuf_pool;
+ struct rte_mbuf *m, *m1;
+ char *hdr;
+ int x;
+ int* ptr;
+
+ mbuf_pool = rte_mempool_create("test_mbuf_pool", NB_MBUF,
+ MBUF_SIZE, 32, 0,
+ (void (*)(struct rte_mempool*, void*)) 0, (void *)0,
+ rte_pktmbuf_init, (void *)0,
+ SOCKET_ID_ANY, 0);
+ if (mbuf_pool == NULL) {
+ return -1;
+ }
+
+ m = rte_pktmbuf_alloc(mbuf_pool);
+ if(m == NULL) {
+ return -1;
+ }
+
+ m1 = RTE_MBUF_FROM_BADDR(RTE_MBUF_TO_BADDR(m));
+ (void)m1;
+
+ x = rte_pktmbuf_pkt_len(m);
+ x = rte_pktmbuf_data_len(m);
+ x = rte_pktmbuf_headroom(m);
+ x = rte_pktmbuf_tailroom(m);
+ x = rte_pktmbuf_is_contiguous(m);
+
+ m = rte_pktmbuf_lastseg(m);
+
+ hdr = rte_pktmbuf_mtod(m, char *);
+ rte_pktmbuf_dump(m, 0);
+
+ hdr = rte_pktmbuf_append(m, 10);
+ x = rte_pktmbuf_trim(m, 10);
+ hdr = rte_pktmbuf_prepend(m, 10);
+ hdr = rte_pktmbuf_adj(m, 10);
+
+ ptr = (int*) rte_ctrlmbuf_data(m);
+ *ptr = rte_ctrlmbuf_len(m);
+ *ptr = rte_pktmbuf_pkt_len(m);
+ *ptr = rte_pktmbuf_data_len(m);
+
+ rte_pktmbuf_free_seg(m);
+ rte_pktmbuf_free(m);
+
+ RTE_MBUF_PREFETCH_TO_FREE(m);
+
+ rte_mbuf_sanity_check(m, RTE_MBUF_CTRL, 1);
+
+ (void)x;
+ (void)hdr;
+
+ return 0;
+}
diff --git a/app/chkincs/test_memcpy.c b/app/chkincs/test_memcpy.c
new file mode 100644
index 0000000..19db8d2
--- /dev/null
+++ b/app/chkincs/test_memcpy.c
@@ -0,0 +1,58 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_memcpy.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_memcpy(void)
+{
+ char buf[16];
+ const char s[] = "hello\n";
+ volatile int a = 10;
+
+ rte_memcpy(buf, s, sizeof(s));
+ rte_memcpy(buf, s, a);
+ return 0;
+}
diff --git a/app/chkincs/test_memory.c b/app/chkincs/test_memory.c
new file mode 100644
index 0000000..c17db89
--- /dev/null
+++ b/app/chkincs/test_memory.c
@@ -0,0 +1,65 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_memory.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+static int a __rte_cache_aligned;
+
+int
+test_memory(void)
+{
+ const struct rte_memseg *mem;
+ int s = CACHE_LINE_ROUNDUP(10);
+
+ rte_dump_physmem_layout();
+ s = rte_eal_get_physmem_size();
+ mem = rte_eal_get_physmem_layout();
+
+ (void)a;
+ (void)s;
+ (void)mem;
+
+ return 0;
+}
diff --git a/app/chkincs/test_mempool.c b/app/chkincs/test_mempool.c
new file mode 100644
index 0000000..9c669d6
--- /dev/null
+++ b/app/chkincs/test_mempool.c
@@ -0,0 +1,111 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_mempool.h>
+
+#include "test.h"
+
+#define MAX_BULK 16
+#define MEMPOOL_ELT_SIZE 2048
+#define MEMPOOL_SIZE 2047
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_mempool(void)
+{
+ struct rte_mempool *mp;
+ void *ptrs[MAX_BULK];
+ int x;
+ phys_addr_t addr;
+
+ mp = rte_mempool_create("test_nocache", MEMPOOL_SIZE,
+ MEMPOOL_ELT_SIZE, 0, 0,
+ (void (*)(struct rte_mempool*, void*)) 0,
+ (void *)0,
+ (void (*)(struct rte_mempool*, void*, void*, unsigned int)) 0,
+ (void *)0,
+ SOCKET_ID_ANY, 0);
+
+ if (mp == NULL) {
+ return -1;
+ }
+
+ rte_mempool_set_bulk_count(mp, MAX_BULK);
+ rte_mempool_dump(mp);
+
+ rte_mempool_mc_get_bulk(mp, ptrs, 1);
+ rte_mempool_mc_get_bulk(mp, ptrs, MAX_BULK);
+ rte_mempool_sc_get_bulk(mp, ptrs, 1);
+ rte_mempool_sc_get_bulk(mp, ptrs, MAX_BULK);
+ rte_mempool_get_bulk(mp, ptrs, 1);
+ rte_mempool_get_bulk(mp, ptrs, MAX_BULK);
+ rte_mempool_mc_get(mp, ptrs);
+ rte_mempool_sc_get(mp, ptrs);
+ rte_mempool_get(mp, ptrs);
+
+ rte_mempool_mp_put_bulk(mp, ptrs, 1);
+ rte_mempool_mp_put_bulk(mp, ptrs, MAX_BULK);
+ rte_mempool_sp_put_bulk(mp, ptrs, 1);
+ rte_mempool_sp_put_bulk(mp, ptrs, MAX_BULK);
+ rte_mempool_put_bulk(mp, ptrs, 1);
+ rte_mempool_put_bulk(mp, ptrs, MAX_BULK);
+ rte_mempool_mp_put(mp, ptrs);
+ rte_mempool_sp_put(mp, ptrs);
+ rte_mempool_put(mp, ptrs);
+
+ __MEMPOOL_STAT_ADD(mp, put, 1);
+ __mempool_check_cookies(mp, 0, 0, 0);
+
+ x = rte_mempool_count(mp);
+ x = rte_mempool_free_count(mp);
+ x = rte_mempool_full(mp);
+ x = rte_mempool_empty(mp);
+
+ addr = rte_mempool_virt2phy(mp, ptrs[0]);
+ rte_mempool_audit(mp);
+ ptrs[0] = rte_mempool_get_priv(mp);
+
+ (void)x;
+ (void)addr;
+
+ return 0;
+}
diff --git a/app/chkincs/test_memzone.c b/app/chkincs/test_memzone.c
new file mode 100644
index 0000000..31c9af6
--- /dev/null
+++ b/app/chkincs/test_memzone.c
@@ -0,0 +1,61 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_memzone.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_memzone(void)
+{
+ const struct rte_memzone *memzone1;
+
+ memzone1 = rte_memzone_lookup("testzone1");
+ memzone1 = rte_memzone_reserve("testzone1", 100,
+ 0, 0);
+ rte_memzone_dump();
+
+ (void)memzone1;
+
+ return 0;
+}
diff --git a/app/chkincs/test_pci.c b/app/chkincs/test_pci.c
new file mode 100644
index 0000000..7af0894
--- /dev/null
+++ b/app/chkincs/test_pci.c
@@ -0,0 +1,86 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_pci.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+static int my_driver_init(struct rte_pci_driver *dr,
+ struct rte_pci_device *dev);
+
+struct rte_pci_id my_driver_id[] = {
+ {
+ 0x8086,
+ 0x10E8,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ },
+ {
+ 0, 0, 0, 0 /* sentinel */
+ },
+};
+struct rte_pci_driver my_driver = {
+ {0, 0},
+ "test_driver",
+ my_driver_init,
+ my_driver_id,
+ RTE_PCI_DRV_NEED_IGB_UIO,
+};
+
+static int
+my_driver_init(__attribute__((unused)) struct rte_pci_driver *dr,
+ __attribute__((unused)) struct rte_pci_device *dev)
+{
+ return 0;
+}
+
+int
+test_pci(void)
+{
+ struct rte_pci_id id = {RTE_PCI_DEVICE(0, 0)};
+ rte_eal_pci_dump();
+ rte_eal_pci_register(&my_driver);
+ rte_eal_pci_probe();
+ (void)id;
+ return 0;
+}
diff --git a/app/chkincs/test_pci_dev_ids.c b/app/chkincs/test_pci_dev_ids.c
new file mode 100644
index 0000000..290105c
--- /dev/null
+++ b/app/chkincs/test_pci_dev_ids.c
@@ -0,0 +1,60 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include "test.h"
+
+struct A {
+ int x;
+ int y;
+};
+
+static struct A a[] = {
+#define RTE_PCI_DEV_ID_DECL(vend, dev) {vend, dev},
+#include <rte_pci_dev_ids.h>
+};
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_pci_dev_ids(void)
+{
+ return a[0].x;
+}
diff --git a/app/chkincs/test_per_lcore.c b/app/chkincs/test_per_lcore.c
new file mode 100644
index 0000000..d2fc666
--- /dev/null
+++ b/app/chkincs/test_per_lcore.c
@@ -0,0 +1,57 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_per_lcore.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+static RTE_DEFINE_PER_LCORE(unsigned, test) = 0x12345678;
+
+int
+test_per_lcore(void)
+{
+ if (RTE_PER_LCORE(test) != 0x12345678)
+ return -1;
+
+ return 0;
+}
diff --git a/app/chkincs/test_prefetch.c b/app/chkincs/test_prefetch.c
new file mode 100644
index 0000000..df81f0e
--- /dev/null
+++ b/app/chkincs/test_prefetch.c
@@ -0,0 +1,58 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_prefetch.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_prefetch(void)
+{
+ int a;
+
+ rte_prefetch0(&a);
+ rte_prefetch1(&a);
+ rte_prefetch2(&a);
+
+ return 0;
+}
diff --git a/app/chkincs/test_random.c b/app/chkincs/test_random.c
new file mode 100644
index 0000000..9e10176
--- /dev/null
+++ b/app/chkincs/test_random.c
@@ -0,0 +1,54 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_random.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_random(void)
+{
+ rte_srand(1);
+ rte_rand();
+ return 0;
+}
diff --git a/app/chkincs/test_ring.c b/app/chkincs/test_ring.c
new file mode 100644
index 0000000..5e37a6a
--- /dev/null
+++ b/app/chkincs/test_ring.c
@@ -0,0 +1,97 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_ring.h>
+
+#include "test.h"
+
+#define MAX_BULK 16
+#define RING_SIZE 4096
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_ring(void)
+{
+ struct rte_ring *r;
+ void *ptrs[MAX_BULK];
+ int x;
+
+ r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
+ if (r == 0) {
+ return -1;
+ }
+ rte_ring_dump(r);
+
+ rte_ring_set_bulk_count(r, MAX_BULK);
+ rte_ring_set_water_mark(r, 50);
+
+ rte_ring_sp_enqueue_bulk(r, &ptrs[0], 1);
+ rte_ring_mp_enqueue_bulk(r, &ptrs[0], 1);
+ rte_ring_sp_enqueue_bulk(r, &ptrs[0], MAX_BULK);
+ rte_ring_mp_enqueue_bulk(r, &ptrs[0], MAX_BULK);
+ rte_ring_enqueue_bulk(r, &ptrs[0], MAX_BULK);
+ rte_ring_enqueue_bulk(r, &ptrs[0], MAX_BULK);
+ rte_ring_sp_enqueue(r, &ptrs[0]);
+ rte_ring_mp_enqueue(r, &ptrs[0]);
+ rte_ring_enqueue(r, &ptrs[0]);
+
+ rte_ring_sc_dequeue_bulk(r, &ptrs[0], 1);
+ rte_ring_sc_dequeue_bulk(r, &ptrs[0], MAX_BULK);
+ rte_ring_mc_dequeue_bulk(r, &ptrs[0], 1);
+ rte_ring_mc_dequeue_bulk(r, &ptrs[0], MAX_BULK);
+ rte_ring_dequeue_bulk(r, &ptrs[0], 1);
+ rte_ring_dequeue_bulk(r, &ptrs[0], MAX_BULK);
+ rte_ring_sc_dequeue(r, &ptrs[0]);
+ rte_ring_mc_dequeue(r, &ptrs[0]);
+ rte_ring_dequeue(r, &ptrs[0]);
+
+ __RING_STAT_ADD(r, enq_fail, 10);
+
+ x = rte_ring_full(r);
+ x = rte_ring_empty(r);
+ x = rte_ring_count(r);
+ x = rte_ring_free_count(r);
+
+ (void)x;
+
+ return 0;
+}
diff --git a/app/chkincs/test_rwlock.c b/app/chkincs/test_rwlock.c
new file mode 100644
index 0000000..20ab519
--- /dev/null
+++ b/app/chkincs/test_rwlock.c
@@ -0,0 +1,60 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_rwlock.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_rwlock(void)
+{
+ rte_rwlock_t rwl = RTE_RWLOCK_INITIALIZER;
+
+ rte_rwlock_init(&rwl);
+ rte_rwlock_write_lock(&rwl);
+ rte_rwlock_write_unlock(&rwl);
+ rte_rwlock_read_lock(&rwl);
+ rte_rwlock_read_unlock(&rwl);
+
+ return 0;
+}
diff --git a/app/chkincs/test_sctp.c b/app/chkincs/test_sctp.c
new file mode 100644
index 0000000..11b6b78
--- /dev/null
+++ b/app/chkincs/test_sctp.c
@@ -0,0 +1,52 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_sctp.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_sctp(void)
+{
+ return 0;
+}
diff --git a/app/chkincs/test_spinlock.c b/app/chkincs/test_spinlock.c
new file mode 100644
index 0000000..eb538df
--- /dev/null
+++ b/app/chkincs/test_spinlock.c
@@ -0,0 +1,59 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_spinlock.h>
+
+#include "test.h"
+
+static rte_spinlock_t sl = RTE_SPINLOCK_INITIALIZER;
+static rte_spinlock_recursive_t slr = RTE_SPINLOCK_RECURSIVE_INITIALIZER;
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_spinlock(void)
+{
+ rte_spinlock_init(&sl);
+ rte_spinlock_lock(&sl);
+ rte_spinlock_unlock(&sl);
+ rte_spinlock_recursive_lock(&slr);
+ return 0;
+}
diff --git a/app/chkincs/test_string_fns.c b/app/chkincs/test_string_fns.c
new file mode 100644
index 0000000..09a24de
--- /dev/null
+++ b/app/chkincs/test_string_fns.c
@@ -0,0 +1,52 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_string_fns.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_string_fns(void)
+{
+ return 0;
+}
diff --git a/app/chkincs/test_tailq.c b/app/chkincs/test_tailq.c
new file mode 100644
index 0000000..4730e1c
--- /dev/null
+++ b/app/chkincs/test_tailq.c
@@ -0,0 +1,55 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_tailq.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_tailq(void)
+{
+ struct rte_dummy *t1, *t2;
+ t1 = RTE_TAILQ_RESERVE("dummy", rte_dummy);
+ t2 = RTE_TAILQ_LOOKUP("dummy", rte_dummy);
+ return (t1 == t2) ? 0 : -1;
+}
diff --git a/app/chkincs/test_tcp.c b/app/chkincs/test_tcp.c
new file mode 100644
index 0000000..96e54a6
--- /dev/null
+++ b/app/chkincs/test_tcp.c
@@ -0,0 +1,52 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_tcp.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_tcp(void)
+{
+ return 0;
+}
diff --git a/app/chkincs/test_timer.c b/app/chkincs/test_timer.c
new file mode 100644
index 0000000..ea63b42
--- /dev/null
+++ b/app/chkincs/test_timer.c
@@ -0,0 +1,74 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+
+#include <rte_timer.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+/* timer callback for basic tests */
+static void
+timer_cb(__attribute__((unused)) struct rte_timer *tim,
+ __attribute__((unused)) void *arg)
+{
+ return;
+}
+
+int
+test_timer(void)
+{
+ int x;
+ struct rte_timer tim = RTE_TIMER_INITIALIZER;
+
+ rte_timer_subsystem_init();
+ rte_timer_init(&tim);
+ rte_timer_reset(&tim, 1234, SINGLE, 0, timer_cb, &x);
+ rte_timer_stop(&tim);
+ rte_timer_reset_sync(&tim, 1234, SINGLE, 0, timer_cb, &x);
+ rte_timer_stop_sync(&tim);
+ x = rte_timer_pending(&tim);
+ rte_timer_manage();
+ rte_timer_dump_stats();
+
+ return 0;
+}
diff --git a/app/chkincs/test_udp.c b/app/chkincs/test_udp.c
new file mode 100644
index 0000000..9ccb5ba
--- /dev/null
+++ b/app/chkincs/test_udp.c
@@ -0,0 +1,52 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include "test.h"
+
+#include <rte_udp.h>
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_udp(void)
+{
+ return 0;
+}
diff --git a/app/chkincs/test_version.c b/app/chkincs/test_version.c
new file mode 100644
index 0000000..e518a67
--- /dev/null
+++ b/app/chkincs/test_version.c
@@ -0,0 +1,52 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <rte_version.h>
+
+#include "test.h"
+
+/*
+ * ^
+ * / \
+ * / | \ WARNING: this test program does *not* show how to use the
+ * / . \ API. Its only goal is to check dependencies of include files.
+ * /_______\
+ */
+
+int
+test_version(void)
+{
+ return 1;
+}
diff --git a/app/dump_cfg/Makefile b/app/dump_cfg/Makefile
new file mode 100644
index 0000000..916166a
--- /dev/null
+++ b/app/dump_cfg/Makefile
@@ -0,0 +1,49 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# version: DPDK.L.1.2.3-3
+#
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+APP = dump_cfg
+
+CFLAGS += $(WERROR_FLAGS)
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-y := dump_cfg_main.c
+
+# this application needs libraries first
+DEPDIRS-y += lib
+
+include $(RTE_SDK)/mk/rte.app.mk
diff --git a/app/dump_cfg/dump_cfg_main.c b/app/dump_cfg/dump_cfg_main.c
new file mode 100644
index 0000000..9227f35
--- /dev/null
+++ b/app/dump_cfg/dump_cfg_main.c
@@ -0,0 +1,229 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/queue.h>
+#include <limits.h>
+
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+
+
+/* some functions used for printing out the memory segments and memory zones information */
+
+#define PRINT_STR_FIELD(structname, field) do{ \
+ count+= rte_snprintf(buf + count, len-count, " %s='%s',", \
+ #field, (const char *)structname->field);\
+} while(0)
+
+#define PRINT_PTR_FIELD(structname, field) do{ \
+ count+= rte_snprintf(buf + count, len-count, " %s=%p,", \
+ #field, (void *)structname->field);\
+} while(0)
+
+#define PRINT_UINT_FIELD(structname, field) do{ \
+ count+= rte_snprintf(buf + count, len-count, " %s=%llu,", \
+ #field, (unsigned long long)structname->field);\
+} while(0)
+
+#define PRINT_INT_FIELD(structname, field) do{ \
+ count+= rte_snprintf(buf + count, len-count, " %s=%lld,", \
+ #field, (long long)structname->field);\
+} while(0)
+
+#define PRINT_CUSTOM_FIELD(structname, field, print_fn) do{ \
+ char buf2[1024]; \
+ count+= rte_snprintf(buf + count, len-count, " %s=%s,", \
+ #field, print_fn(structname->field, buf2, sizeof(buf2)));\
+} while(0)
+
+static inline const char *
+memseg_to_str(const struct rte_memseg *seg, char *buf, size_t len)
+{
+ int count = 0;
+ count += rte_snprintf(buf + count, len - count, "{");
+ PRINT_UINT_FIELD(seg, phys_addr);
+ PRINT_PTR_FIELD(seg, addr);
+ PRINT_UINT_FIELD(seg, len);
+ PRINT_INT_FIELD(seg, socket_id);
+ PRINT_UINT_FIELD(seg, hugepage_sz);
+ PRINT_UINT_FIELD(seg, nchannel);
+ PRINT_UINT_FIELD(seg, nrank);
+ rte_snprintf(buf + count - 1, len - count + 1, " }");
+ return buf;
+}
+
+static inline const char *
+memzone_to_str(const struct rte_memzone *zone, char *buf, size_t len)
+{
+ int count = 0;
+ count += rte_snprintf(buf + count, len - count, "{");
+ PRINT_STR_FIELD(zone, name);
+ PRINT_UINT_FIELD(zone, phys_addr);
+ PRINT_PTR_FIELD(zone, addr);
+ PRINT_UINT_FIELD(zone, len);
+ PRINT_INT_FIELD(zone, socket_id);
+ PRINT_UINT_FIELD(zone, flags);
+ rte_snprintf(buf + count - 1, len - count + 1, " }");
+ return buf;
+}
+
+static inline const char *
+tailq_to_str(const struct rte_tailq_head *tailq, char *buf, size_t len)
+{
+ int count = 0;
+ count += rte_snprintf(buf + count, len - count, "{");
+ PRINT_STR_FIELD(tailq, qname);
+ const struct rte_dummy_head *head = &tailq->tailq_head;
+ PRINT_PTR_FIELD(head, tqh_first);
+ PRINT_PTR_FIELD(head, tqh_last);
+ rte_snprintf(buf + count - 1, len - count + 1, " }");
+ return buf;
+}
+
+#define PREFIX "prefix"
+static const char *directory = "/var/run";
+static const char *pre = "rte";
+
+static void
+usage(const char *prgname)
+{
+ printf("%s --prefix <prefix>\n\n"
+ "dump_config option list:\n"
+ "\t--"PREFIX": filename prefix\n",
+ prgname);
+}
+
+static int
+dmp_cfg_parse_args(int argc, char **argv)
+{
+ const char *prgname = argv[0];
+ const char *home_dir = getenv("HOME");
+ int opt;
+ int option_index;
+ static struct option lgopts[] = {
+ {PREFIX, 1, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+ if (getuid() != 0 && home_dir != NULL)
+ directory = home_dir;
+
+ while ((opt = getopt_long(argc, argv, "",
+ lgopts, &option_index)) != EOF) {
+ switch (opt) {
+ case 0:
+ if (!strcmp(lgopts[option_index].name, PREFIX))
+ pre = optarg;
+ else{
+ usage(prgname);
+ return -1;
+ }
+ break;
+
+ default:
+ usage(prgname);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ char buffer[1024];
+ char path[PATH_MAX];
+ int i;
+ int fd = 0;
+
+ dmp_cfg_parse_args(argc, argv);
+ rte_snprintf(path, sizeof(path), "%s/.%s_config", directory, pre);
+ printf("Path to mem_config: %s\n\n", path);
+
+ fd = open(path, O_RDWR);
+ if (fd < 0){
+ printf("Error with config open\n");
+ return 1;
+ }
+ struct rte_mem_config *cfg = mmap(NULL, sizeof(*cfg), PROT_READ, \
+ MAP_SHARED, fd, 0);
+ if (cfg == NULL){
+ printf("Error with config mmap\n");
+ close(fd);
+ return 1;
+ }
+ close(fd);
+
+ printf("----------- MEMORY_SEGMENTS -------------\n");
+ for (i = 0; i < RTE_MAX_MEMSEG; i++){
+ if (cfg->memseg[i].addr == NULL) break;
+ printf("Segment %d: ", i);
+ printf("%s\n", memseg_to_str(&cfg->memseg[i], buffer, sizeof(buffer)));
+ }
+ printf("--------- END_MEMORY_SEGMENTS -----------\n");
+
+ printf("------------ MEMORY_ZONES ---------------\n");
+ for (i = 0; i < RTE_MAX_MEMZONE; i++){
+ if (cfg->memzone[i].addr == NULL) break;
+ printf("Zone %d: ", i);
+ printf("%s\n", memzone_to_str(&cfg->memzone[i], buffer, sizeof(buffer)));
+
+ }
+ printf("---------- END_MEMORY_ZONES -------------\n");
+
+ printf("------------- TAIL_QUEUES ---------------\n");
+ for (i = 0; i < RTE_MAX_TAILQ; i++){
+ if (cfg->tailq_head[i].qname[0] == '\0') break;
+ printf("Tailq %d: ", i);
+ printf("%s\n", tailq_to_str(&cfg->tailq_head[i], buffer, sizeof(buffer)));
+
+ }
+ printf("----------- END_TAIL_QUEUES -------------\n");
+
+ return 0;
+}
+
diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
new file mode 100644
index 0000000..bad337a
--- /dev/null
+++ b/app/test-pmd/Makefile
@@ -0,0 +1,63 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# version: DPDK.L.1.2.3-3
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+APP = testpmd
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_TEST_PMD) := testpmd.c
+SRCS-$(CONFIG_RTE_TEST_PMD) += parameters.c
+SRCS-$(CONFIG_RTE_TEST_PMD) += cmdline.c
+SRCS-$(CONFIG_RTE_TEST_PMD) += config.c
+SRCS-$(CONFIG_RTE_TEST_PMD) += iofwd.c
+SRCS-$(CONFIG_RTE_TEST_PMD) += macfwd.c
+SRCS-$(CONFIG_RTE_TEST_PMD) += rxonly.c
+SRCS-$(CONFIG_RTE_TEST_PMD) += txonly.c
+SRCS-$(CONFIG_RTE_TEST_PMD) += csumonly.c
+ifeq ($(CONFIG_RTE_LIBRTE_IEEE1588),y)
+SRCS-$(CONFIG_RTE_TEST_PMD) += ieee1588fwd.c
+endif
+
+# this application needs libraries first
+DEPDIRS-$(CONFIG_RTE_TEST_PMD) += lib
+
+include $(RTE_SDK)/mk/rte.app.mk
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
new file mode 100644
index 0000000..28233a6
--- /dev/null
+++ b/app/test-pmd/cmdline.c
@@ -0,0 +1,2180 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdarg.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <inttypes.h>
+#ifndef __linux__
+#include <net/socket.h>
+#endif
+#include <netinet/in.h>
+
+#include <sys/queue.h>
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_string_fns.h>
+
+#include <cmdline_rdline.h>
+#include <cmdline_parse.h>
+#include <cmdline_parse_num.h>
+#include <cmdline_parse_string.h>
+#include <cmdline_parse_ipaddr.h>
+#include <cmdline_parse_etheraddr.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+
+#include "testpmd.h"
+
+/* *** HELP *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(cl,
+ "\n"
+ "TEST PMD\n"
+ "--------\n"
+ "\n"
+ "This commandline can be used to configure forwarding\n"
+ "\n");
+ cmdline_printf(cl,
+ "Display informations:\n"
+ "---------------------\n"
+ "- show port info|stats|fdir X|all\n"
+ " Diplays information or stats on port X, or all\n"
+ "- clear port stats X|all\n"
+ " Clear stats for port X, or all\n"
+ "- show config rxtx|cores|fwd\n"
+ " Displays the given configuration\n"
+ "- read reg port_id reg_off\n"
+ " Displays value of a port register\n"
+ "- read regfield port_id reg_off bit_x bit_y\n"
+ " Displays value of a port register bit field\n"
+ "- read regbit port_id reg_off bit_x\n"
+ " Displays value of a port register bit\n"
+ "- read rxd port_id queue_id rxd_id\n"
+ " Displays a RX descriptor of a port RX queue\n"
+ "- read txd port_id queue_id txd_id\n"
+ " Displays a TX descriptor of a port TX queue\n"
+ "\n");
+ cmdline_printf(cl,
+ "Configure:\n"
+ "----------\n"
+ "Modifications are taken into account once "
+ "forwarding is restarted.\n"
+ "- set default\n"
+ " Set forwarding to default configuration\n"
+ "- set nbport|nbcore|burst|verbose X\n"
+ " Set number of ports, number of cores, number "
+ "of packets per burst,\n or verbose level to X\n"
+ "- set txpkts x[,y]*\n"
+ " Set the length of each segment of TXONLY packets\n"
+ "- set coremask|portmask X\n"
+ " Set the hexadecimal mask of forwarding cores / "
+ "forwarding ports\n"
+ "- set corelist|portlist x[,y]*\n"
+ " Set the list of forwarding cores / forwarding "
+ "ports\n"
+ "- rx_vlan add/rm vlan_id|all port_id\n"
+ " Add/remove vlan_id, or all identifiers, to/from "
+ "the set of VLAN Identifiers\n filtered by port_id\n"
+ "- tx_vlan set vlan_id port_id\n"
+ " Enable hardware insertion of a VLAN header with "
+ "the Tag Identifier vlan_id\n in packets sent on"
+ "port_id\n"
+ "- tx_vlan reset port_id\n"
+ " Disable hardware insertion of a VLAN header in "
+ "packets sent on port_id\n"
+ "- tx_checksum set mask port_id\n"
+ " Enable hardware insertion of checksum offload with "
+ "the 4-bit mask (0~0xf)\n in packets sent on port_id\n"
+ " Please check the NIC datasheet for HW limits\n"
+ " bit 0 - insert ip checksum offload if set \n"
+ " bit 1 - insert udp checksum offload if set \n"
+ " bit 2 - insert tcp checksum offload if set\n"
+ " bit 3 - insert sctp checksum offload if set\n"
+#ifdef RTE_LIBRTE_IEEE1588
+ "- set fwd io|mac|rxonly|txonly|csum|ieee1588\n"
+ " Set IO, MAC, RXONLY, TXONLY, CSUM or IEEE1588 "
+ "packet forwarding mode\n"
+#else
+ "- set fwd io|mac|rxonly|txonly|csum\n"
+ " Set IO, MAC, RXONLY, CSUM or TXONLY packet "
+ "forwarding mode\n"
+#endif
+ "- mac_addr add|remove X <xx:xx:xx:xx:xx:xx>\n"
+ " Add/Remove the MAC address <xx:xx:xx:xx:xx:xx> on port X\n"
+ "- set promisc|allmulti [all|X] on|off\n"
+ " Set/unset promisc|allmulti mode on port X, or all\n"
+ "- set flow_ctrl rx on|off tx on|off high_water low_water "
+ "pause_time send_xon port_id \n"
+ " Set the link flow control parameter on the port \n"
+ "- write reg port_id reg_off value\n"
+ " Set value of a port register\n"
+ "- write regfield port_id reg_off bit_x bit_y value\n"
+ " Set bit field value of a port register\n"
+ "- write regbit port_id reg_off bit_x value\n"
+ " Set bit value of a port register\n"
+ "\n");
+ cmdline_printf(cl,
+ "Control forwarding:\n"
+ "-------------------\n"
+ "- start\n"
+ " Start packet forwarding with current config\n"
+ "- start tx_first\n"
+ " Start packet forwarding with current config"
+ " after sending one burst\n of packets\n"
+ "- stop\n"
+ " Stop packet forwarding, and displays accumulated"
+ " stats\n"
+ "\n");
+ cmdline_printf(cl,
+ "Flow director mode:\n"
+ "-------------------\n"
+ "- add_signature_filter port_id ip|udp|tcp|sctp src\n"
+ " ip_src_address port_src dst ip_dst_address port_dst\n"
+ " flexbytes flexbytes_values vlan vlan_id queue queue_id\n"
+ "- upd_signature_filter port_id ip|udp|tcp|sctp src \n"
+ " ip_src_address port_src dst ip_dst_address port_dst\n"
+ " flexbytes flexbytes_values vlan vlan_id queue queue_id\n"
+ "- rm_signature_filter port_id ip|udp|tcp|sctp src\n"
+ " ip_src_address port_src dst ip_dst_address port_dst\n"
+ " flexbytes flexbytes_values vlan vlan_id\n"
+ "- add_perfect_filter port_id ip|udp|tcp|sctp src\n"
+ " ip_src_address port_src dst ip_dst_address port_dst\n"
+ " flexbytes flexbytes_values vlan vlan_id queue \n"
+ " queue_id soft soft_id\n"
+ "- upd_perfect_filter port_id ip|udp|tcp|sctp src\n"
+ " ip_src_address port_src dst ip_dst_address port_dst\n"
+ " flexbytes flexbytes_values vlan vlan_id queue queue_id\n"
+ "- rm_perfect_filter port_id ip|udp|tcp|sctp src\n"
+ " ip_src_address port_src dst ip_dst_address port_dst\n"
+ " flexbytes flexbytes_values vlan vlan_id soft soft_id\n"
+ "- set_masks_filter port_id only_ip_flow 0|1 src_mask\n"
+ " ip_src_mask port_src_mask dst_mask ip_dst_mask\n"
+ " port_dst_mask flexbytes 0|1 vlan_id 0|1 vlan_prio 0|1\n"
+ "\n");
+ cmdline_printf(cl,
+ "Misc:\n"
+ "-----\n"
+ "- quit\n"
+ " Quit to prompt in linux, and reboot on baremetal\n"
+ "\n");
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** stop *** */
+struct cmd_stop_result {
+ cmdline_fixed_string_t stop;
+};
+
+static void cmd_stop_parsed(__attribute__((unused)) void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ stop_packet_forwarding();
+}
+
+cmdline_parse_token_string_t cmd_stop_stop =
+ TOKEN_STRING_INITIALIZER(struct cmd_stop_result, stop, "stop");
+
+cmdline_parse_inst_t cmd_stop = {
+ .f = cmd_stop_parsed,
+ .data = NULL,
+ .help_str = "stop - stop packet forwarding",
+ .tokens = {
+ (void *)&cmd_stop_stop,
+ NULL,
+ },
+};
+
+/* *** SET CORELIST and PORTLIST CONFIGURATION *** */
+
+static unsigned int
+parse_item_list(char* str, const char* item_name, unsigned int max_items,
+ unsigned int *parsed_items, int check_unique_values)
+{
+ unsigned int nb_item;
+ unsigned int value;
+ unsigned int i;
+ unsigned int j;
+ int value_ok;
+ char c;
+
+ /*
+ * First parse all items in the list and store their value.
+ */
+ value = 0;
+ nb_item = 0;
+ value_ok = 0;
+ for (i = 0; i < strnlen(str, STR_TOKEN_SIZE); i++) {
+ c = str[i];
+ if ((c >= '0') && (c <= '9')) {
+ value = (unsigned int) (value * 10 + (c - '0'));
+ value_ok = 1;
+ continue;
+ }
+ if (c != ',') {
+ printf("character %c is not a decimal digit\n", c);
+ return (0);
+ }
+ if (! value_ok) {
+ printf("No valid value before comma\n");
+ return (0);
+ }
+ if (nb_item < max_items) {
+ parsed_items[nb_item] = value;
+ value_ok = 0;
+ value = 0;
+ }
+ nb_item++;
+ }
+ if (nb_item >= max_items) {
+ printf("Number of %s = %u > %u (maximum items)\n",
+ item_name, nb_item + 1, max_items);
+ return (0);
+ }
+ parsed_items[nb_item++] = value;
+ if (! check_unique_values)
+ return (nb_item);
+
+ /*
+ * Then, check that all values in the list are differents.
+ * No optimization here...
+ */
+ for (i = 0; i < nb_item; i++) {
+ for (j = i + 1; j < nb_item; j++) {
+ if (parsed_items[j] == parsed_items[i]) {
+ printf("duplicated %s %u at index %u and %u\n",
+ item_name, parsed_items[i], i, j);
+ return (0);
+ }
+ }
+ }
+ return (nb_item);
+}
+
+struct cmd_set_list_result {
+ cmdline_fixed_string_t cmd_keyword;
+ cmdline_fixed_string_t list_name;
+ cmdline_fixed_string_t list_of_items;
+};
+
+static void cmd_set_list_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_list_result *res;
+ union {
+ unsigned int lcorelist[RTE_MAX_LCORE];
+ unsigned int portlist[RTE_MAX_ETHPORTS];
+ } parsed_items;
+ unsigned int nb_item;
+
+ res = parsed_result;
+ if (!strcmp(res->list_name, "corelist")) {
+ nb_item = parse_item_list(res->list_of_items, "core",
+ RTE_MAX_LCORE,
+ parsed_items.lcorelist, 1);
+ if (nb_item > 0)
+ set_fwd_lcores_list(parsed_items.lcorelist, nb_item);
+ return;
+ }
+ if (!strcmp(res->list_name, "portlist")) {
+ nb_item = parse_item_list(res->list_of_items, "port",
+ RTE_MAX_ETHPORTS,
+ parsed_items.portlist, 1);
+ if (nb_item > 0)
+ set_fwd_ports_list(parsed_items.portlist, nb_item);
+ }
+}
+
+cmdline_parse_token_string_t cmd_set_list_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, cmd_keyword,
+ "set");
+cmdline_parse_token_string_t cmd_set_list_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_name,
+ "corelist#portlist");
+cmdline_parse_token_string_t cmd_set_list_of_items =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_of_items,
+ NULL);
+
+cmdline_parse_inst_t cmd_set_fwd_list = {
+ .f = cmd_set_list_parsed,
+ .data = NULL,
+ .help_str = "set corelist|portlist x[,y]*",
+ .tokens = {
+ (void *)&cmd_set_list_keyword,
+ (void *)&cmd_set_list_name,
+ (void *)&cmd_set_list_of_items,
+ NULL,
+ },
+};
+
+/* *** SET COREMASK and PORTMASK CONFIGURATION *** */
+
+struct cmd_setmask_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t mask;
+ uint64_t hexavalue;
+};
+
+static void cmd_set_mask_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_setmask_result *res = parsed_result;
+
+ if (!strcmp(res->mask, "coremask"))
+ set_fwd_lcores_mask(res->hexavalue);
+ else if (!strcmp(res->mask, "portmask"))
+ set_fwd_ports_mask(res->hexavalue);
+}
+
+cmdline_parse_token_string_t cmd_setmask_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, set, "set");
+cmdline_parse_token_string_t cmd_setmask_mask =
+ TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, mask,
+ "coremask#portmask");
+cmdline_parse_token_num_t cmd_setmask_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_setmask_result, hexavalue, UINT64);
+
+cmdline_parse_inst_t cmd_set_fwd_mask = {
+ .f = cmd_set_mask_parsed,
+ .data = NULL,
+ .help_str = "set coremask|portmask hexadecimal value",
+ .tokens = {
+ (void *)&cmd_setmask_set,
+ (void *)&cmd_setmask_mask,
+ (void *)&cmd_setmask_value,
+ NULL,
+ },
+};
+
+/*
+ * SET NBPORT, NBCORE, PACKET BURST, and VERBOSE LEVEL CONFIGURATION
+ */
+struct cmd_set_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t what;
+ uint16_t value;
+};
+
+static void cmd_set_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_result *res = parsed_result;
+ if (!strcmp(res->what, "nbport"))
+ set_fwd_ports_number(res->value);
+ else if (!strcmp(res->what, "nbcore"))
+ set_fwd_lcores_number(res->value);
+ else if (!strcmp(res->what, "burst"))
+ set_nb_pkt_per_burst(res->value);
+ else if (!strcmp(res->what, "verbose"))
+ set_verbose_level(res->value);
+}
+
+cmdline_parse_token_string_t cmd_set_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_result, set, "set");
+cmdline_parse_token_string_t cmd_set_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_result, what,
+ "nbport#nbcore#burst#verbose");
+cmdline_parse_token_num_t cmd_set_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_result, value, UINT16);
+
+cmdline_parse_inst_t cmd_set_numbers = {
+ .f = cmd_set_parsed,
+ .data = NULL,
+ .help_str = "set nbport|nbcore|burst|verbose value",
+ .tokens = {
+ (void *)&cmd_set_set,
+ (void *)&cmd_set_what,
+ (void *)&cmd_set_value,
+ NULL,
+ },
+};
+
+/* *** SET SEGMENT LENGTHS OF TXONLY PACKETS *** */
+
+struct cmd_set_txpkts_result {
+ cmdline_fixed_string_t cmd_keyword;
+ cmdline_fixed_string_t txpkts;
+ cmdline_fixed_string_t seg_lengths;
+};
+
+static void
+cmd_set_txpkts_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_txpkts_result *res;
+ unsigned seg_lengths[RTE_MAX_SEGS_PER_PKT];
+ unsigned int nb_segs;
+
+ res = parsed_result;
+ nb_segs = parse_item_list(res->seg_lengths, "segment lengths",
+ RTE_MAX_SEGS_PER_PKT, seg_lengths, 0);
+ if (nb_segs > 0)
+ set_tx_pkt_segments(seg_lengths, nb_segs);
+}
+
+cmdline_parse_token_string_t cmd_set_txpkts_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
+ cmd_keyword, "set");
+cmdline_parse_token_string_t cmd_set_txpkts_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
+ txpkts, "txpkts");
+cmdline_parse_token_string_t cmd_set_txpkts_lengths =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
+ seg_lengths, NULL);
+
+cmdline_parse_inst_t cmd_set_txpkts = {
+ .f = cmd_set_txpkts_parsed,
+ .data = NULL,
+ .help_str = "set txpkts x[,y]*",
+ .tokens = {
+ (void *)&cmd_set_txpkts_keyword,
+ (void *)&cmd_set_txpkts_name,
+ (void *)&cmd_set_txpkts_lengths,
+ NULL,
+ },
+};
+
+/* *** ADD/REMOVE ALL VLAN IDENTIFIERS TO/FROM A PORT VLAN RX FILTER *** */
+struct cmd_rx_vlan_filter_all_result {
+ cmdline_fixed_string_t rx_vlan;
+ cmdline_fixed_string_t what;
+ cmdline_fixed_string_t all;
+ uint8_t port_id;
+};
+
+static void
+cmd_rx_vlan_filter_all_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_rx_vlan_filter_all_result *res = parsed_result;
+
+ if (!strcmp(res->what, "add"))
+ rx_vlan_all_filter_set(res->port_id, 1);
+ else
+ rx_vlan_all_filter_set(res->port_id, 0);
+}
+
+cmdline_parse_token_string_t cmd_rx_vlan_filter_all_rx_vlan =
+ TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
+ rx_vlan, "rx_vlan");
+cmdline_parse_token_string_t cmd_rx_vlan_filter_all_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
+ what, "add#rm");
+cmdline_parse_token_string_t cmd_rx_vlan_filter_all_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
+ all, "all");
+cmdline_parse_token_num_t cmd_rx_vlan_filter_all_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_rx_vlan_filter_all = {
+ .f = cmd_rx_vlan_filter_all_parsed,
+ .data = NULL,
+ .help_str = "add/remove all identifiers to/from the set of VLAN "
+ "Identifiers filtered by a port",
+ .tokens = {
+ (void *)&cmd_rx_vlan_filter_all_rx_vlan,
+ (void *)&cmd_rx_vlan_filter_all_what,
+ (void *)&cmd_rx_vlan_filter_all_all,
+ (void *)&cmd_rx_vlan_filter_all_portid,
+ NULL,
+ },
+};
+
+/* *** ADD/REMOVE A VLAN IDENTIFIER TO/FROM A PORT VLAN RX FILTER *** */
+struct cmd_rx_vlan_filter_result {
+ cmdline_fixed_string_t rx_vlan;
+ cmdline_fixed_string_t what;
+ uint16_t vlan_id;
+ uint8_t port_id;
+};
+
+static void
+cmd_rx_vlan_filter_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_rx_vlan_filter_result *res = parsed_result;
+
+ if (!strcmp(res->what, "add"))
+ rx_vlan_filter_set(res->port_id, res->vlan_id, 1);
+ else
+ rx_vlan_filter_set(res->port_id, res->vlan_id, 0);
+}
+
+cmdline_parse_token_string_t cmd_rx_vlan_filter_rx_vlan =
+ TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
+ rx_vlan, "rx_vlan");
+cmdline_parse_token_string_t cmd_rx_vlan_filter_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
+ what, "add#rm");
+cmdline_parse_token_num_t cmd_rx_vlan_filter_vlanid =
+ TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
+ vlan_id, UINT16);
+cmdline_parse_token_num_t cmd_rx_vlan_filter_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_rx_vlan_filter = {
+ .f = cmd_rx_vlan_filter_parsed,
+ .data = NULL,
+ .help_str = "add/remove a VLAN identifier to/from the set of VLAN "
+ "Identifiers filtered by a port",
+ .tokens = {
+ (void *)&cmd_rx_vlan_filter_rx_vlan,
+ (void *)&cmd_rx_vlan_filter_what,
+ (void *)&cmd_rx_vlan_filter_vlanid,
+ (void *)&cmd_rx_vlan_filter_portid,
+ NULL,
+ },
+};
+
+/* *** ENABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
+struct cmd_tx_vlan_set_result {
+ cmdline_fixed_string_t tx_vlan;
+ cmdline_fixed_string_t set;
+ uint16_t vlan_id;
+ uint8_t port_id;
+};
+
+static void
+cmd_tx_vlan_set_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_tx_vlan_set_result *res = parsed_result;
+
+ tx_vlan_set(res->port_id, res->vlan_id);
+}
+
+cmdline_parse_token_string_t cmd_tx_vlan_set_tx_vlan =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
+ tx_vlan, "tx_vlan");
+cmdline_parse_token_string_t cmd_tx_vlan_set_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
+ set, "set");
+cmdline_parse_token_num_t cmd_tx_vlan_set_vlanid =
+ TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
+ vlan_id, UINT16);
+cmdline_parse_token_num_t cmd_tx_vlan_set_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_tx_vlan_set = {
+ .f = cmd_tx_vlan_set_parsed,
+ .data = NULL,
+ .help_str = "enable hardware insertion of a VLAN header with a given "
+ "TAG Identifier in packets sent on a port",
+ .tokens = {
+ (void *)&cmd_tx_vlan_set_tx_vlan,
+ (void *)&cmd_tx_vlan_set_set,
+ (void *)&cmd_tx_vlan_set_vlanid,
+ (void *)&cmd_tx_vlan_set_portid,
+ NULL,
+ },
+};
+
+/* *** DISABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
+struct cmd_tx_vlan_reset_result {
+ cmdline_fixed_string_t tx_vlan;
+ cmdline_fixed_string_t reset;
+ uint8_t port_id;
+};
+
+static void
+cmd_tx_vlan_reset_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_tx_vlan_reset_result *res = parsed_result;
+
+ tx_vlan_reset(res->port_id);
+}
+
+cmdline_parse_token_string_t cmd_tx_vlan_reset_tx_vlan =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
+ tx_vlan, "tx_vlan");
+cmdline_parse_token_string_t cmd_tx_vlan_reset_reset =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
+ reset, "reset");
+cmdline_parse_token_num_t cmd_tx_vlan_reset_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_reset_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_tx_vlan_reset = {
+ .f = cmd_tx_vlan_reset_parsed,
+ .data = NULL,
+ .help_str = "disable hardware insertion of a VLAN header in packets "
+ "sent on a port",
+ .tokens = {
+ (void *)&cmd_tx_vlan_reset_tx_vlan,
+ (void *)&cmd_tx_vlan_reset_reset,
+ (void *)&cmd_tx_vlan_reset_portid,
+ NULL,
+ },
+};
+
+
+/* *** ENABLE HARDWARE INSERTION OF CHECKSUM IN TX PACKETS *** */
+struct cmd_tx_cksum_set_result {
+ cmdline_fixed_string_t tx_cksum;
+ cmdline_fixed_string_t set;
+ uint8_t cksum_mask;
+ uint8_t port_id;
+};
+
+static void
+cmd_tx_cksum_set_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_tx_cksum_set_result *res = parsed_result;
+
+ tx_cksum_set(res->port_id, res->cksum_mask);
+}
+
+cmdline_parse_token_string_t cmd_tx_cksum_set_tx_cksum =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_set_result,
+ tx_cksum, "tx_checksum");
+cmdline_parse_token_string_t cmd_tx_cksum_set_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_set_result,
+ set, "set");
+cmdline_parse_token_num_t cmd_tx_cksum_set_cksum_mask =
+ TOKEN_NUM_INITIALIZER(struct cmd_tx_cksum_set_result,
+ cksum_mask, UINT8);
+cmdline_parse_token_num_t cmd_tx_cksum_set_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_tx_cksum_set_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_tx_cksum_set = {
+ .f = cmd_tx_cksum_set_parsed,
+ .data = NULL,
+ .help_str = "enable hardware insertion of L3/L4checksum with a given "
+ "mask in packets sent on a port, the bit mapping is given as, Bit 0 for ip"
+ "Bit 1 for UDP, Bit 2 for TCP, Bit 3 for SCTP",
+ .tokens = {
+ (void *)&cmd_tx_cksum_set_tx_cksum,
+ (void *)&cmd_tx_cksum_set_set,
+ (void *)&cmd_tx_cksum_set_cksum_mask,
+ (void *)&cmd_tx_cksum_set_portid,
+ NULL,
+ },
+};
+
+/* *** SET FORWARDING MODE *** */
+struct cmd_set_fwd_mode_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t fwd;
+ cmdline_fixed_string_t mode;
+};
+
+static void cmd_set_fwd_mode_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_fwd_mode_result *res = parsed_result;
+
+ set_pkt_forwarding_mode(res->mode);
+}
+
+cmdline_parse_token_string_t cmd_setfwd_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, set, "set");
+cmdline_parse_token_string_t cmd_setfwd_fwd =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, fwd, "fwd");
+cmdline_parse_token_string_t cmd_setfwd_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, mode,
+#ifdef RTE_LIBRTE_IEEE1588
+ "io#mac#rxonly#txonly#csum#ieee1588");
+#else
+ "io#mac#rxonly#txonly#csum");
+#endif
+
+cmdline_parse_inst_t cmd_set_fwd_mode = {
+ .f = cmd_set_fwd_mode_parsed,
+ .data = NULL,
+#ifdef RTE_LIBRTE_IEEE1588
+ .help_str = "set fwd io|mac|rxonly|txonly|csum|ieee1588 - set IO, MAC,"
+ " RXONLY, TXONLY, CSUM or IEEE1588 packet forwarding mode",
+#else
+ .help_str = "set fwd io|mac|rxonly|txonly|csum - set IO, MAC,"
+ " RXONLY, CSUM or TXONLY packet forwarding mode",
+#endif
+ .tokens = {
+ (void *)&cmd_setfwd_set,
+ (void *)&cmd_setfwd_fwd,
+ (void *)&cmd_setfwd_mode,
+ NULL,
+ },
+};
+
+/* *** SET PROMISC MODE *** */
+struct cmd_set_promisc_mode_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t promisc;
+ cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
+ uint8_t port_num; /* valid if "allports" argument == 0 */
+ cmdline_fixed_string_t mode;
+};
+
+static void cmd_set_promisc_mode_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ void *allports)
+{
+ struct cmd_set_promisc_mode_result *res = parsed_result;
+ int enable;
+ portid_t i;
+
+ if (!strcmp(res->mode, "on"))
+ enable = 1;
+ else
+ enable = 0;
+
+ /* all ports */
+ if (allports) {
+ for (i = 0; i < nb_ports; i++) {
+ if (enable)
+ rte_eth_promiscuous_enable(i);
+ else
+ rte_eth_promiscuous_disable(i);
+ }
+ }
+ else {
+ if (enable)
+ rte_eth_promiscuous_enable(res->port_num);
+ else
+ rte_eth_promiscuous_disable(res->port_num);
+ }
+}
+
+cmdline_parse_token_string_t cmd_setpromisc_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, set, "set");
+cmdline_parse_token_string_t cmd_setpromisc_promisc =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, promisc,
+ "promisc");
+cmdline_parse_token_string_t cmd_setpromisc_portall =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, port_all,
+ "all");
+cmdline_parse_token_num_t cmd_setpromisc_portnum =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_promisc_mode_result, port_num,
+ UINT8);
+cmdline_parse_token_string_t cmd_setpromisc_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, mode,
+ "on#off");
+
+cmdline_parse_inst_t cmd_set_promisc_mode_all = {
+ .f = cmd_set_promisc_mode_parsed,
+ .data = (void *)1,
+ .help_str = "set promisc all on|off: set promisc mode for all ports",
+ .tokens = {
+ (void *)&cmd_setpromisc_set,
+ (void *)&cmd_setpromisc_promisc,
+ (void *)&cmd_setpromisc_portall,
+ (void *)&cmd_setpromisc_mode,
+ NULL,
+ },
+};
+
+cmdline_parse_inst_t cmd_set_promisc_mode_one = {
+ .f = cmd_set_promisc_mode_parsed,
+ .data = (void *)0,
+ .help_str = "set promisc X on|off: set promisc mode on port X",
+ .tokens = {
+ (void *)&cmd_setpromisc_set,
+ (void *)&cmd_setpromisc_promisc,
+ (void *)&cmd_setpromisc_portnum,
+ (void *)&cmd_setpromisc_mode,
+ NULL,
+ },
+};
+
+/* *** SET ALLMULTI MODE *** */
+struct cmd_set_allmulti_mode_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t allmulti;
+ cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
+ uint8_t port_num; /* valid if "allports" argument == 0 */
+ cmdline_fixed_string_t mode;
+};
+
+static void cmd_set_allmulti_mode_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ void *allports)
+{
+ struct cmd_set_allmulti_mode_result *res = parsed_result;
+ int enable;
+ portid_t i;
+
+ if (!strcmp(res->mode, "on"))
+ enable = 1;
+ else
+ enable = 0;
+
+ /* all ports */
+ if (allports) {
+ for (i = 0; i < nb_ports; i++) {
+ if (enable)
+ rte_eth_allmulticast_enable(i);
+ else
+ rte_eth_allmulticast_disable(i);
+ }
+ }
+ else {
+ if (enable)
+ rte_eth_allmulticast_enable(res->port_num);
+ else
+ rte_eth_allmulticast_disable(res->port_num);
+ }
+}
+
+cmdline_parse_token_string_t cmd_setallmulti_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, set, "set");
+cmdline_parse_token_string_t cmd_setallmulti_allmulti =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, allmulti,
+ "allmulti");
+cmdline_parse_token_string_t cmd_setallmulti_portall =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, port_all,
+ "all");
+cmdline_parse_token_num_t cmd_setallmulti_portnum =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_allmulti_mode_result, port_num,
+ UINT8);
+cmdline_parse_token_string_t cmd_setallmulti_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, mode,
+ "on#off");
+
+cmdline_parse_inst_t cmd_set_allmulti_mode_all = {
+ .f = cmd_set_allmulti_mode_parsed,
+ .data = (void *)1,
+ .help_str = "set allmulti all on|off: set allmulti mode for all ports",
+ .tokens = {
+ (void *)&cmd_setallmulti_set,
+ (void *)&cmd_setallmulti_allmulti,
+ (void *)&cmd_setallmulti_portall,
+ (void *)&cmd_setallmulti_mode,
+ NULL,
+ },
+};
+
+cmdline_parse_inst_t cmd_set_allmulti_mode_one = {
+ .f = cmd_set_allmulti_mode_parsed,
+ .data = (void *)0,
+ .help_str = "set allmulti X on|off: set allmulti mode on port X",
+ .tokens = {
+ (void *)&cmd_setallmulti_set,
+ (void *)&cmd_setallmulti_allmulti,
+ (void *)&cmd_setallmulti_portnum,
+ (void *)&cmd_setallmulti_mode,
+ NULL,
+ },
+};
+
+/* *** ADD/REMOVE A PKT FILTER *** */
+struct cmd_pkt_filter_result {
+ cmdline_fixed_string_t pkt_filter;
+ uint8_t port_id;
+ cmdline_fixed_string_t protocol;
+ cmdline_fixed_string_t src;
+ cmdline_ipaddr_t ip_src;
+ uint16_t port_src;
+ cmdline_fixed_string_t dst;
+ cmdline_ipaddr_t ip_dst;
+ uint16_t port_dst;
+ cmdline_fixed_string_t flexbytes;
+ uint16_t flexbytes_value;
+ cmdline_fixed_string_t vlan;
+ uint16_t vlan_id;
+ cmdline_fixed_string_t queue;
+ int8_t queue_id;
+ cmdline_fixed_string_t soft;
+ uint8_t soft_id;
+};
+
+static void
+cmd_pkt_filter_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct rte_fdir_filter fdir_filter;
+ struct cmd_pkt_filter_result *res = parsed_result;
+
+ memset(&fdir_filter, 0, sizeof(struct rte_fdir_filter));
+
+ if (res->ip_src.family == AF_INET)
+ fdir_filter.ip_src.ipv4_addr = res->ip_src.addr.ipv4.s_addr;
+ else
+ memcpy(&(fdir_filter.ip_src.ipv6_addr),
+ &(res->ip_src.addr.ipv6),
+ sizeof(struct in6_addr));
+
+ if (res->ip_dst.family == AF_INET)
+ fdir_filter.ip_dst.ipv4_addr = res->ip_dst.addr.ipv4.s_addr;
+ else
+ memcpy(&(fdir_filter.ip_dst.ipv6_addr),
+ &(res->ip_dst.addr.ipv6),
+ sizeof(struct in6_addr));
+
+ fdir_filter.port_dst = rte_cpu_to_be_16(res->port_dst);
+ fdir_filter.port_src = rte_cpu_to_be_16(res->port_src);
+
+ if (!strcmp(res->protocol, "udp"))
+ fdir_filter.l4type = RTE_FDIR_L4TYPE_UDP;
+ else if (!strcmp(res->protocol, "tcp"))
+ fdir_filter.l4type = RTE_FDIR_L4TYPE_TCP;
+ else if (!strcmp(res->protocol, "sctp"))
+ fdir_filter.l4type = RTE_FDIR_L4TYPE_SCTP;
+ else /* default only IP */
+ fdir_filter.l4type = RTE_FDIR_L4TYPE_NONE;
+
+ if (res->ip_dst.family == AF_INET6)
+ fdir_filter.iptype = RTE_FDIR_IPTYPE_IPV6;
+ else
+ fdir_filter.iptype = RTE_FDIR_IPTYPE_IPV4;
+
+ fdir_filter.vlan_id = rte_cpu_to_be_16(res->vlan_id);
+ fdir_filter.flex_bytes = rte_cpu_to_be_16(res->flexbytes_value);
+
+ if (!strcmp(res->pkt_filter, "add_signature_filter"))
+ fdir_add_signature_filter(res->port_id, res->queue_id,
+ &fdir_filter);
+ else if (!strcmp(res->pkt_filter, "upd_signature_filter"))
+ fdir_update_signature_filter(res->port_id, res->queue_id,
+ &fdir_filter);
+ else if (!strcmp(res->pkt_filter, "rm_signature_filter"))
+ fdir_remove_signature_filter(res->port_id, &fdir_filter);
+ else if (!strcmp(res->pkt_filter, "add_perfect_filter"))
+ fdir_add_perfect_filter(res->port_id, res->soft_id,
+ res->queue_id,
+ (uint8_t) (res->queue_id < 0),
+ &fdir_filter);
+ else if (!strcmp(res->pkt_filter, "upd_perfect_filter"))
+ fdir_update_perfect_filter(res->port_id, res->soft_id,
+ res->queue_id,
+ (uint8_t) (res->queue_id < 0),
+ &fdir_filter);
+ else if (!strcmp(res->pkt_filter, "rm_perfect_filter"))
+ fdir_remove_perfect_filter(res->port_id, res->soft_id,
+ &fdir_filter);
+
+}
+
+
+cmdline_parse_token_num_t cmd_pkt_filter_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_pkt_filter_protocol =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
+ protocol, "ip#tcp#udp#sctp");
+cmdline_parse_token_string_t cmd_pkt_filter_src =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
+ src, "src");
+cmdline_parse_token_ipaddr_t cmd_pkt_filter_ip_src =
+ TOKEN_IPADDR_INITIALIZER(struct cmd_pkt_filter_result,
+ ip_src);
+cmdline_parse_token_num_t cmd_pkt_filter_port_src =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
+ port_src, UINT16);
+cmdline_parse_token_string_t cmd_pkt_filter_dst =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
+ dst, "dst");
+cmdline_parse_token_ipaddr_t cmd_pkt_filter_ip_dst =
+ TOKEN_IPADDR_INITIALIZER(struct cmd_pkt_filter_result,
+ ip_dst);
+cmdline_parse_token_num_t cmd_pkt_filter_port_dst =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
+ port_dst, UINT16);
+cmdline_parse_token_string_t cmd_pkt_filter_flexbytes =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
+ flexbytes, "flexbytes");
+cmdline_parse_token_num_t cmd_pkt_filter_flexbytes_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
+ flexbytes_value, UINT16);
+cmdline_parse_token_string_t cmd_pkt_filter_vlan =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
+ vlan, "vlan");
+cmdline_parse_token_num_t cmd_pkt_filter_vlan_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
+ vlan_id, UINT16);
+cmdline_parse_token_string_t cmd_pkt_filter_queue =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
+ queue, "queue");
+cmdline_parse_token_num_t cmd_pkt_filter_queue_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
+ queue_id, INT8);
+cmdline_parse_token_string_t cmd_pkt_filter_soft =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
+ soft, "soft");
+cmdline_parse_token_num_t cmd_pkt_filter_soft_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
+ soft_id, UINT16);
+
+
+cmdline_parse_token_string_t cmd_pkt_filter_add_signature_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
+ pkt_filter, "add_signature_filter");
+cmdline_parse_inst_t cmd_add_signature_filter = {
+ .f = cmd_pkt_filter_parsed,
+ .data = NULL,
+ .help_str = "add a signature filter",
+ .tokens = {
+ (void *)&cmd_pkt_filter_add_signature_filter,
+ (void *)&cmd_pkt_filter_port_id,
+ (void *)&cmd_pkt_filter_protocol,
+ (void *)&cmd_pkt_filter_src,
+ (void *)&cmd_pkt_filter_ip_src,
+ (void *)&cmd_pkt_filter_port_src,
+ (void *)&cmd_pkt_filter_dst,
+ (void *)&cmd_pkt_filter_ip_dst,
+ (void *)&cmd_pkt_filter_port_dst,
+ (void *)&cmd_pkt_filter_flexbytes,
+ (void *)&cmd_pkt_filter_flexbytes_value,
+ (void *)&cmd_pkt_filter_vlan,
+ (void *)&cmd_pkt_filter_vlan_id,
+ (void *)&cmd_pkt_filter_queue,
+ (void *)&cmd_pkt_filter_queue_id,
+ NULL,
+ },
+};
+
+
+cmdline_parse_token_string_t cmd_pkt_filter_upd_signature_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
+ pkt_filter, "upd_signature_filter");
+cmdline_parse_inst_t cmd_upd_signature_filter = {
+ .f = cmd_pkt_filter_parsed,
+ .data = NULL,
+ .help_str = "update a signature filter",
+ .tokens = {
+ (void *)&cmd_pkt_filter_upd_signature_filter,
+ (void *)&cmd_pkt_filter_port_id,
+ (void *)&cmd_pkt_filter_protocol,
+ (void *)&cmd_pkt_filter_src,
+ (void *)&cmd_pkt_filter_ip_src,
+ (void *)&cmd_pkt_filter_port_src,
+ (void *)&cmd_pkt_filter_dst,
+ (void *)&cmd_pkt_filter_ip_dst,
+ (void *)&cmd_pkt_filter_port_dst,
+ (void *)&cmd_pkt_filter_flexbytes,
+ (void *)&cmd_pkt_filter_flexbytes_value,
+ (void *)&cmd_pkt_filter_vlan,
+ (void *)&cmd_pkt_filter_vlan_id,
+ (void *)&cmd_pkt_filter_queue,
+ (void *)&cmd_pkt_filter_queue_id,
+ NULL,
+ },
+};
+
+
+cmdline_parse_token_string_t cmd_pkt_filter_rm_signature_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
+ pkt_filter, "rm_signature_filter");
+cmdline_parse_inst_t cmd_rm_signature_filter = {
+ .f = cmd_pkt_filter_parsed,
+ .data = NULL,
+ .help_str = "remove a signature filter",
+ .tokens = {
+ (void *)&cmd_pkt_filter_rm_signature_filter,
+ (void *)&cmd_pkt_filter_port_id,
+ (void *)&cmd_pkt_filter_protocol,
+ (void *)&cmd_pkt_filter_src,
+ (void *)&cmd_pkt_filter_ip_src,
+ (void *)&cmd_pkt_filter_port_src,
+ (void *)&cmd_pkt_filter_dst,
+ (void *)&cmd_pkt_filter_ip_dst,
+ (void *)&cmd_pkt_filter_port_dst,
+ (void *)&cmd_pkt_filter_flexbytes,
+ (void *)&cmd_pkt_filter_flexbytes_value,
+ (void *)&cmd_pkt_filter_vlan,
+ (void *)&cmd_pkt_filter_vlan_id,
+ NULL
+ },
+};
+
+
+cmdline_parse_token_string_t cmd_pkt_filter_add_perfect_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
+ pkt_filter, "add_perfect_filter");
+cmdline_parse_inst_t cmd_add_perfect_filter = {
+ .f = cmd_pkt_filter_parsed,
+ .data = NULL,
+ .help_str = "add a perfect filter",
+ .tokens = {
+ (void *)&cmd_pkt_filter_add_perfect_filter,
+ (void *)&cmd_pkt_filter_port_id,
+ (void *)&cmd_pkt_filter_protocol,
+ (void *)&cmd_pkt_filter_src,
+ (void *)&cmd_pkt_filter_ip_src,
+ (void *)&cmd_pkt_filter_port_src,
+ (void *)&cmd_pkt_filter_dst,
+ (void *)&cmd_pkt_filter_ip_dst,
+ (void *)&cmd_pkt_filter_port_dst,
+ (void *)&cmd_pkt_filter_flexbytes,
+ (void *)&cmd_pkt_filter_flexbytes_value,
+ (void *)&cmd_pkt_filter_vlan,
+ (void *)&cmd_pkt_filter_vlan_id,
+ (void *)&cmd_pkt_filter_queue,
+ (void *)&cmd_pkt_filter_queue_id,
+ (void *)&cmd_pkt_filter_soft,
+ (void *)&cmd_pkt_filter_soft_id,
+ NULL,
+ },
+};
+
+
+cmdline_parse_token_string_t cmd_pkt_filter_upd_perfect_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
+ pkt_filter, "upd_perfect_filter");
+cmdline_parse_inst_t cmd_upd_perfect_filter = {
+ .f = cmd_pkt_filter_parsed,
+ .data = NULL,
+ .help_str = "update a perfect filter",
+ .tokens = {
+ (void *)&cmd_pkt_filter_upd_perfect_filter,
+ (void *)&cmd_pkt_filter_port_id,
+ (void *)&cmd_pkt_filter_protocol,
+ (void *)&cmd_pkt_filter_src,
+ (void *)&cmd_pkt_filter_ip_src,
+ (void *)&cmd_pkt_filter_port_src,
+ (void *)&cmd_pkt_filter_dst,
+ (void *)&cmd_pkt_filter_ip_dst,
+ (void *)&cmd_pkt_filter_port_dst,
+ (void *)&cmd_pkt_filter_flexbytes,
+ (void *)&cmd_pkt_filter_flexbytes_value,
+ (void *)&cmd_pkt_filter_vlan,
+ (void *)&cmd_pkt_filter_vlan_id,
+ (void *)&cmd_pkt_filter_queue,
+ (void *)&cmd_pkt_filter_queue_id,
+ (void *)&cmd_pkt_filter_soft,
+ (void *)&cmd_pkt_filter_soft_id,
+ NULL,
+ },
+};
+
+
+cmdline_parse_token_string_t cmd_pkt_filter_rm_perfect_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
+ pkt_filter, "rm_perfect_filter");
+cmdline_parse_inst_t cmd_rm_perfect_filter = {
+ .f = cmd_pkt_filter_parsed,
+ .data = NULL,
+ .help_str = "remove a perfect filter",
+ .tokens = {
+ (void *)&cmd_pkt_filter_rm_perfect_filter,
+ (void *)&cmd_pkt_filter_port_id,
+ (void *)&cmd_pkt_filter_protocol,
+ (void *)&cmd_pkt_filter_src,
+ (void *)&cmd_pkt_filter_ip_src,
+ (void *)&cmd_pkt_filter_port_src,
+ (void *)&cmd_pkt_filter_dst,
+ (void *)&cmd_pkt_filter_ip_dst,
+ (void *)&cmd_pkt_filter_port_dst,
+ (void *)&cmd_pkt_filter_flexbytes,
+ (void *)&cmd_pkt_filter_flexbytes_value,
+ (void *)&cmd_pkt_filter_vlan,
+ (void *)&cmd_pkt_filter_vlan_id,
+ (void *)&cmd_pkt_filter_soft,
+ (void *)&cmd_pkt_filter_soft_id,
+ NULL,
+ },
+};
+
+/* *** SETUP MASKS FILTER *** */
+struct cmd_pkt_filter_masks_result {
+ cmdline_fixed_string_t filter_mask;
+ uint8_t port_id;
+ cmdline_fixed_string_t src_mask;
+ uint32_t ip_src_mask;
+ uint16_t port_src_mask;
+ cmdline_fixed_string_t dst_mask;
+ uint32_t ip_dst_mask;
+ uint16_t port_dst_mask;
+ cmdline_fixed_string_t flexbytes;
+ uint8_t flexbytes_value;
+ cmdline_fixed_string_t vlan_id;
+ uint8_t vlan_id_value;
+ cmdline_fixed_string_t vlan_prio;
+ uint8_t vlan_prio_value;
+ cmdline_fixed_string_t only_ip_flow;
+ uint8_t only_ip_flow_value;
+};
+
+static void
+cmd_pkt_filter_masks_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct rte_fdir_masks fdir_masks;
+ struct cmd_pkt_filter_masks_result *res = parsed_result;
+
+ memset(&fdir_masks, 0, sizeof(struct rte_fdir_masks));
+
+ fdir_masks.only_ip_flow = res->only_ip_flow_value;
+ fdir_masks.vlan_id = res->vlan_id_value;
+ fdir_masks.vlan_prio = res->vlan_prio_value;
+ fdir_masks.dst_ipv4_mask = res->ip_dst_mask;
+ fdir_masks.src_ipv4_mask = res->ip_src_mask;
+ fdir_masks.src_port_mask = res->port_src_mask;
+ fdir_masks.dst_port_mask = res->port_dst_mask;
+ fdir_masks.flexbytes = res->flexbytes_value;
+
+ fdir_set_masks(res->port_id, &fdir_masks);
+}
+
+cmdline_parse_token_string_t cmd_pkt_filter_masks_filter_mask =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ filter_mask, "set_masks_filter");
+cmdline_parse_token_num_t cmd_pkt_filter_masks_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_pkt_filter_masks_only_ip_flow =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ only_ip_flow, "only_ip_flow");
+cmdline_parse_token_num_t cmd_pkt_filter_masks_only_ip_flow_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ only_ip_flow_value, UINT8);
+cmdline_parse_token_string_t cmd_pkt_filter_masks_src_mask =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ src_mask, "src_mask");
+cmdline_parse_token_num_t cmd_pkt_filter_masks_ip_src_mask =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ ip_src_mask, UINT32);
+cmdline_parse_token_num_t cmd_pkt_filter_masks_port_src_mask =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ port_src_mask, UINT16);
+cmdline_parse_token_string_t cmd_pkt_filter_masks_dst_mask =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ src_mask, "dst_mask");
+cmdline_parse_token_num_t cmd_pkt_filter_masks_ip_dst_mask =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ ip_dst_mask, UINT32);
+cmdline_parse_token_num_t cmd_pkt_filter_masks_port_dst_mask =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ port_dst_mask, UINT16);
+cmdline_parse_token_string_t cmd_pkt_filter_masks_flexbytes =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ flexbytes, "flexbytes");
+cmdline_parse_token_num_t cmd_pkt_filter_masks_flexbytes_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ flexbytes_value, UINT8);
+cmdline_parse_token_string_t cmd_pkt_filter_masks_vlan_id =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ vlan_id, "vlan_id");
+cmdline_parse_token_num_t cmd_pkt_filter_masks_vlan_id_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ vlan_id_value, UINT8);
+cmdline_parse_token_string_t cmd_pkt_filter_masks_vlan_prio =
+ TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ vlan_prio, "vlan_prio");
+cmdline_parse_token_num_t cmd_pkt_filter_masks_vlan_prio_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
+ vlan_prio_value, UINT8);
+
+cmdline_parse_inst_t cmd_set_masks_filter = {
+ .f = cmd_pkt_filter_masks_parsed,
+ .data = NULL,
+ .help_str = "setup masks filter",
+ .tokens = {
+ (void *)&cmd_pkt_filter_masks_filter_mask,
+ (void *)&cmd_pkt_filter_masks_port_id,
+ (void *)&cmd_pkt_filter_masks_only_ip_flow,
+ (void *)&cmd_pkt_filter_masks_only_ip_flow_value,
+ (void *)&cmd_pkt_filter_masks_src_mask,
+ (void *)&cmd_pkt_filter_masks_ip_src_mask,
+ (void *)&cmd_pkt_filter_masks_port_src_mask,
+ (void *)&cmd_pkt_filter_masks_dst_mask,
+ (void *)&cmd_pkt_filter_masks_ip_dst_mask,
+ (void *)&cmd_pkt_filter_masks_port_dst_mask,
+ (void *)&cmd_pkt_filter_masks_flexbytes,
+ (void *)&cmd_pkt_filter_masks_flexbytes_value,
+ (void *)&cmd_pkt_filter_masks_vlan_id,
+ (void *)&cmd_pkt_filter_masks_vlan_id_value,
+ (void *)&cmd_pkt_filter_masks_vlan_prio,
+ (void *)&cmd_pkt_filter_masks_vlan_prio_value,
+ NULL,
+ },
+};
+
+/* *** SETUP ETHERNET LINK FLOW CONTROL *** */
+struct cmd_link_flow_ctrl_set_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t flow_ctrl;
+ cmdline_fixed_string_t rx;
+ cmdline_fixed_string_t rx_lfc_mode;
+ cmdline_fixed_string_t tx;
+ cmdline_fixed_string_t tx_lfc_mode;
+ uint32_t high_water;
+ uint32_t low_water;
+ uint16_t pause_time;
+ uint16_t send_xon;
+ uint8_t port_id;
+};
+
+static void
+cmd_link_flow_ctrl_set_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_link_flow_ctrl_set_result *res = parsed_result;
+ struct rte_eth_fc_conf fc_conf;
+ int rx_fc_enable, tx_fc_enable;
+ int ret;
+
+ /*
+ * Rx on/off, flow control is enabled/disabled on RX side. This can indicate
+ * the RTE_FC_TX_PAUSE, Transmit pause frame at the Rx side.
+ * Tx on/off, flow control is enabled/disabled on TX side. This can indicate
+ * the RTE_FC_RX_PAUSE, Respond to the pause frame at the Tx side.
+ */
+ static enum rte_eth_fc_mode rx_tx_onoff_2_lfc_mode[2][2] = {
+ {RTE_FC_NONE, RTE_FC_RX_PAUSE}, {RTE_FC_TX_PAUSE, RTE_FC_FULL}
+ };
+
+ rx_fc_enable = (!strcmp(res->rx_lfc_mode, "on")) ? 1 : 0;
+ tx_fc_enable = (!strcmp(res->tx_lfc_mode, "on")) ? 1 : 0;
+
+ fc_conf.mode = rx_tx_onoff_2_lfc_mode[rx_fc_enable][tx_fc_enable];
+ fc_conf.high_water = res->high_water;
+ fc_conf.low_water = res->low_water;
+ fc_conf.pause_time = res->pause_time;
+ fc_conf.send_xon = res->send_xon;
+
+ ret = rte_eth_dev_flow_ctrl_set(res->port_id, &fc_conf);
+ if (ret != 0)
+ printf("bad flow contrl parameter, return code = %d \n", ret);
+}
+
+cmdline_parse_token_string_t cmd_lfc_set_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_lfc_set_flow_ctrl =
+ TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
+ flow_ctrl, "flow_ctrl");
+cmdline_parse_token_string_t cmd_lfc_set_rx =
+ TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
+ rx, "rx");
+cmdline_parse_token_string_t cmd_lfc_set_rx_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
+ rx_lfc_mode, "on#off");
+cmdline_parse_token_string_t cmd_lfc_set_tx =
+ TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
+ tx, "tx");
+cmdline_parse_token_string_t cmd_lfc_set_tx_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
+ tx_lfc_mode, "on#off");
+cmdline_parse_token_num_t cmd_lfc_set_high_water =
+ TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
+ high_water, UINT32);
+cmdline_parse_token_num_t cmd_lfc_set_low_water =
+ TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
+ low_water, UINT32);
+cmdline_parse_token_num_t cmd_lfc_set_pause_time =
+ TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
+ pause_time, UINT16);
+cmdline_parse_token_num_t cmd_lfc_set_send_xon =
+ TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
+ send_xon, UINT16);
+cmdline_parse_token_num_t cmd_lfc_set_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_link_flow_control_set = {
+ .f = cmd_link_flow_ctrl_set_parsed,
+ .data = NULL,
+ .help_str = "Configure the Ethernet link flow control...",
+ .tokens = {
+ (void *)&cmd_lfc_set_set,
+ (void *)&cmd_lfc_set_flow_ctrl,
+ (void *)&cmd_lfc_set_rx,
+ (void *)&cmd_lfc_set_rx_mode,
+ (void *)&cmd_lfc_set_tx,
+ (void *)&cmd_lfc_set_tx_mode,
+ (void *)&cmd_lfc_set_high_water,
+ (void *)&cmd_lfc_set_low_water,
+ (void *)&cmd_lfc_set_pause_time,
+ (void *)&cmd_lfc_set_send_xon,
+ (void *)&cmd_lfc_set_portid,
+ NULL,
+ },
+};
+
+/* *** RESET CONFIGURATION *** */
+struct cmd_reset_result {
+ cmdline_fixed_string_t reset;
+ cmdline_fixed_string_t def;
+};
+
+static void cmd_reset_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(cl, "Reset to default forwarding configuration...\n");
+ set_def_fwd_config();
+}
+
+cmdline_parse_token_string_t cmd_reset_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_reset_result, reset, "set");
+cmdline_parse_token_string_t cmd_reset_def =
+ TOKEN_STRING_INITIALIZER(struct cmd_reset_result, def,
+ "default");
+
+cmdline_parse_inst_t cmd_reset = {
+ .f = cmd_reset_parsed,
+ .data = NULL,
+ .help_str = "set default: reset default forwarding configuration",
+ .tokens = {
+ (void *)&cmd_reset_set,
+ (void *)&cmd_reset_def,
+ NULL,
+ },
+};
+
+/* *** START FORWARDING *** */
+struct cmd_start_result {
+ cmdline_fixed_string_t start;
+};
+
+cmdline_parse_token_string_t cmd_start_start =
+ TOKEN_STRING_INITIALIZER(struct cmd_start_result, start, "start");
+
+static void cmd_start_parsed(__attribute__((unused)) void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ start_packet_forwarding(0);
+}
+
+cmdline_parse_inst_t cmd_start = {
+ .f = cmd_start_parsed,
+ .data = NULL,
+ .help_str = "start packet forwarding",
+ .tokens = {
+ (void *)&cmd_start_start,
+ NULL,
+ },
+};
+
+/* *** START FORWARDING WITH ONE TX BURST FIRST *** */
+struct cmd_start_tx_first_result {
+ cmdline_fixed_string_t start;
+ cmdline_fixed_string_t tx_first;
+};
+
+static void
+cmd_start_tx_first_parsed(__attribute__((unused)) void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ start_packet_forwarding(1);
+}
+
+cmdline_parse_token_string_t cmd_start_tx_first_start =
+ TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_result, start,
+ "start");
+cmdline_parse_token_string_t cmd_start_tx_first_tx_first =
+ TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_result,
+ tx_first, "tx_first");
+
+cmdline_parse_inst_t cmd_start_tx_first = {
+ .f = cmd_start_tx_first_parsed,
+ .data = NULL,
+ .help_str = "start packet forwarding, after sending 1 burst of packets",
+ .tokens = {
+ (void *)&cmd_start_tx_first_start,
+ (void *)&cmd_start_tx_first_tx_first,
+ NULL,
+ },
+};
+
+/* *** SHOW CFG *** */
+struct cmd_showcfg_result {
+ cmdline_fixed_string_t show;
+ cmdline_fixed_string_t cfg;
+ cmdline_fixed_string_t what;
+};
+
+static void cmd_showcfg_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_showcfg_result *res = parsed_result;
+ if (!strcmp(res->what, "rxtx"))
+ rxtx_config_display();
+ else if (!strcmp(res->what, "cores"))
+ fwd_lcores_config_display();
+ else if (!strcmp(res->what, "fwd"))
+ fwd_config_display();
+}
+
+cmdline_parse_token_string_t cmd_showcfg_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, show, "show");
+cmdline_parse_token_string_t cmd_showcfg_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, cfg, "config");
+cmdline_parse_token_string_t cmd_showcfg_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, what,
+ "rxtx#cores#fwd");
+
+cmdline_parse_inst_t cmd_showcfg = {
+ .f = cmd_showcfg_parsed,
+ .data = NULL,
+ .help_str = "show config rxtx|cores|fwd",
+ .tokens = {
+ (void *)&cmd_showcfg_show,
+ (void *)&cmd_showcfg_port,
+ (void *)&cmd_showcfg_what,
+ NULL,
+ },
+};
+
+/* *** SHOW ALL PORT INFO *** */
+struct cmd_showportall_result {
+ cmdline_fixed_string_t show;
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t what;
+ cmdline_fixed_string_t all;
+};
+
+static void cmd_showportall_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ portid_t i;
+
+ struct cmd_showportall_result *res = parsed_result;
+ if (!strcmp(res->show, "clear")) {
+ if (!strcmp(res->what, "stats"))
+ for (i = 0; i < nb_ports; i++)
+ nic_stats_clear(i);
+ } else if (!strcmp(res->what, "info"))
+ for (i = 0; i < nb_ports; i++)
+ port_infos_display(i);
+ else if (!strcmp(res->what, "stats"))
+ for (i = 0; i < nb_ports; i++)
+ nic_stats_display(i);
+ else if (!strcmp(res->what, "fdir"))
+ for (i = 0; i < nb_ports; i++)
+ fdir_get_infos(i);
+}
+
+cmdline_parse_token_string_t cmd_showportall_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, show,
+ "show#clear");
+cmdline_parse_token_string_t cmd_showportall_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, port, "port");
+cmdline_parse_token_string_t cmd_showportall_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, what,
+ "info#stats#fdir");
+cmdline_parse_token_string_t cmd_showportall_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, all, "all");
+cmdline_parse_inst_t cmd_showportall = {
+ .f = cmd_showportall_parsed,
+ .data = NULL,
+ .help_str = "show|clear port info|stats|fdir all",
+ .tokens = {
+ (void *)&cmd_showportall_show,
+ (void *)&cmd_showportall_port,
+ (void *)&cmd_showportall_what,
+ (void *)&cmd_showportall_all,
+ NULL,
+ },
+};
+
+/* *** SHOW PORT INFO *** */
+struct cmd_showport_result {
+ cmdline_fixed_string_t show;
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t what;
+ uint8_t portnum;
+};
+
+static void cmd_showport_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_showport_result *res = parsed_result;
+ if (!strcmp(res->show, "clear")) {
+ if (!strcmp(res->what, "stats"))
+ nic_stats_clear(res->portnum);
+ } else if (!strcmp(res->what, "info"))
+ port_infos_display(res->portnum);
+ else if (!strcmp(res->what, "stats"))
+ nic_stats_display(res->portnum);
+ else if (!strcmp(res->what, "fdir"))
+ fdir_get_infos(res->portnum);
+}
+
+cmdline_parse_token_string_t cmd_showport_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_result, show,
+ "show#clear");
+cmdline_parse_token_string_t cmd_showport_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_result, port, "port");
+cmdline_parse_token_string_t cmd_showport_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_result, what,
+ "info#stats#fdir");
+cmdline_parse_token_num_t cmd_showport_portnum =
+ TOKEN_NUM_INITIALIZER(struct cmd_showport_result, portnum, INT32);
+
+cmdline_parse_inst_t cmd_showport = {
+ .f = cmd_showport_parsed,
+ .data = NULL,
+ .help_str = "show|clear port info|stats|fdir X (X = port number)",
+ .tokens = {
+ (void *)&cmd_showport_show,
+ (void *)&cmd_showport_port,
+ (void *)&cmd_showport_what,
+ (void *)&cmd_showport_portnum,
+ NULL,
+ },
+};
+
+/* *** READ PORT REGISTER *** */
+struct cmd_read_reg_result {
+ cmdline_fixed_string_t read;
+ cmdline_fixed_string_t reg;
+ uint8_t port_id;
+ uint32_t reg_off;
+};
+
+static void
+cmd_read_reg_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_read_reg_result *res = parsed_result;
+ port_reg_display(res->port_id, res->reg_off);
+}
+
+cmdline_parse_token_string_t cmd_read_reg_read =
+ TOKEN_STRING_INITIALIZER(struct cmd_read_reg_result, read, "read");
+cmdline_parse_token_string_t cmd_read_reg_reg =
+ TOKEN_STRING_INITIALIZER(struct cmd_read_reg_result, reg, "reg");
+cmdline_parse_token_num_t cmd_read_reg_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_read_reg_result, port_id, UINT8);
+cmdline_parse_token_num_t cmd_read_reg_reg_off =
+ TOKEN_NUM_INITIALIZER(struct cmd_read_reg_result, reg_off, UINT32);
+
+cmdline_parse_inst_t cmd_read_reg = {
+ .f = cmd_read_reg_parsed,
+ .data = NULL,
+ .help_str = "read reg port_id reg_off",
+ .tokens = {
+ (void *)&cmd_read_reg_read,
+ (void *)&cmd_read_reg_reg,
+ (void *)&cmd_read_reg_port_id,
+ (void *)&cmd_read_reg_reg_off,
+ NULL,
+ },
+};
+
+/* *** READ PORT REGISTER BIT FIELD *** */
+struct cmd_read_reg_bit_field_result {
+ cmdline_fixed_string_t read;
+ cmdline_fixed_string_t regfield;
+ uint8_t port_id;
+ uint32_t reg_off;
+ uint8_t bit1_pos;
+ uint8_t bit2_pos;
+};
+
+static void
+cmd_read_reg_bit_field_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_read_reg_bit_field_result *res = parsed_result;
+ port_reg_bit_field_display(res->port_id, res->reg_off,
+ res->bit1_pos, res->bit2_pos);
+}
+
+cmdline_parse_token_string_t cmd_read_reg_bit_field_read =
+ TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_field_result, read,
+ "read");
+cmdline_parse_token_string_t cmd_read_reg_bit_field_regfield =
+ TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_field_result,
+ regfield, "regfield");
+cmdline_parse_token_num_t cmd_read_reg_bit_field_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, port_id,
+ UINT8);
+cmdline_parse_token_num_t cmd_read_reg_bit_field_reg_off =
+ TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, reg_off,
+ UINT32);
+cmdline_parse_token_num_t cmd_read_reg_bit_field_bit1_pos =
+ TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, bit1_pos,
+ UINT8);
+cmdline_parse_token_num_t cmd_read_reg_bit_field_bit2_pos =
+ TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, bit2_pos,
+ UINT8);
+
+cmdline_parse_inst_t cmd_read_reg_bit_field = {
+ .f = cmd_read_reg_bit_field_parsed,
+ .data = NULL,
+ .help_str = "read regfield port_id reg_off bit_x bit_y "
+ "(read register bit field between bit_x and bit_y included)",
+ .tokens = {
+ (void *)&cmd_read_reg_bit_field_read,
+ (void *)&cmd_read_reg_bit_field_regfield,
+ (void *)&cmd_read_reg_bit_field_port_id,
+ (void *)&cmd_read_reg_bit_field_reg_off,
+ (void *)&cmd_read_reg_bit_field_bit1_pos,
+ (void *)&cmd_read_reg_bit_field_bit2_pos,
+ NULL,
+ },
+};
+
+/* *** READ PORT REGISTER BIT *** */
+struct cmd_read_reg_bit_result {
+ cmdline_fixed_string_t read;
+ cmdline_fixed_string_t regbit;
+ uint8_t port_id;
+ uint32_t reg_off;
+ uint8_t bit_pos;
+};
+
+static void
+cmd_read_reg_bit_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_read_reg_bit_result *res = parsed_result;
+ port_reg_bit_display(res->port_id, res->reg_off, res->bit_pos);
+}
+
+cmdline_parse_token_string_t cmd_read_reg_bit_read =
+ TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_result, read, "read");
+cmdline_parse_token_string_t cmd_read_reg_bit_regbit =
+ TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_result,
+ regbit, "regbit");
+cmdline_parse_token_num_t cmd_read_reg_bit_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, port_id, UINT8);
+cmdline_parse_token_num_t cmd_read_reg_bit_reg_off =
+ TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, reg_off, UINT32);
+cmdline_parse_token_num_t cmd_read_reg_bit_bit_pos =
+ TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, bit_pos, UINT8);
+
+cmdline_parse_inst_t cmd_read_reg_bit = {
+ .f = cmd_read_reg_bit_parsed,
+ .data = NULL,
+ .help_str = "read regbit port_id reg_off bit_x (0 <= bit_x <= 31)",
+ .tokens = {
+ (void *)&cmd_read_reg_bit_read,
+ (void *)&cmd_read_reg_bit_regbit,
+ (void *)&cmd_read_reg_bit_port_id,
+ (void *)&cmd_read_reg_bit_reg_off,
+ (void *)&cmd_read_reg_bit_bit_pos,
+ NULL,
+ },
+};
+
+/* *** WRITE PORT REGISTER *** */
+struct cmd_write_reg_result {
+ cmdline_fixed_string_t write;
+ cmdline_fixed_string_t reg;
+ uint8_t port_id;
+ uint32_t reg_off;
+ uint32_t value;
+};
+
+static void
+cmd_write_reg_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_write_reg_result *res = parsed_result;
+ port_reg_set(res->port_id, res->reg_off, res->value);
+}
+
+cmdline_parse_token_string_t cmd_write_reg_write =
+ TOKEN_STRING_INITIALIZER(struct cmd_write_reg_result, write, "write");
+cmdline_parse_token_string_t cmd_write_reg_reg =
+ TOKEN_STRING_INITIALIZER(struct cmd_write_reg_result, reg, "reg");
+cmdline_parse_token_num_t cmd_write_reg_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, port_id, UINT8);
+cmdline_parse_token_num_t cmd_write_reg_reg_off =
+ TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, reg_off, UINT32);
+cmdline_parse_token_num_t cmd_write_reg_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, value, UINT32);
+
+cmdline_parse_inst_t cmd_write_reg = {
+ .f = cmd_write_reg_parsed,
+ .data = NULL,
+ .help_str = "write reg port_id reg_off reg_value",
+ .tokens = {
+ (void *)&cmd_write_reg_write,
+ (void *)&cmd_write_reg_reg,
+ (void *)&cmd_write_reg_port_id,
+ (void *)&cmd_write_reg_reg_off,
+ (void *)&cmd_write_reg_value,
+ NULL,
+ },
+};
+
+/* *** WRITE PORT REGISTER BIT FIELD *** */
+struct cmd_write_reg_bit_field_result {
+ cmdline_fixed_string_t write;
+ cmdline_fixed_string_t regfield;
+ uint8_t port_id;
+ uint32_t reg_off;
+ uint8_t bit1_pos;
+ uint8_t bit2_pos;
+ uint32_t value;
+};
+
+static void
+cmd_write_reg_bit_field_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_write_reg_bit_field_result *res = parsed_result;
+ port_reg_bit_field_set(res->port_id, res->reg_off,
+ res->bit1_pos, res->bit2_pos, res->value);
+}
+
+cmdline_parse_token_string_t cmd_write_reg_bit_field_write =
+ TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_field_result, write,
+ "write");
+cmdline_parse_token_string_t cmd_write_reg_bit_field_regfield =
+ TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_field_result,
+ regfield, "regfield");
+cmdline_parse_token_num_t cmd_write_reg_bit_field_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, port_id,
+ UINT8);
+cmdline_parse_token_num_t cmd_write_reg_bit_field_reg_off =
+ TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, reg_off,
+ UINT32);
+cmdline_parse_token_num_t cmd_write_reg_bit_field_bit1_pos =
+ TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, bit1_pos,
+ UINT8);
+cmdline_parse_token_num_t cmd_write_reg_bit_field_bit2_pos =
+ TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, bit2_pos,
+ UINT8);
+cmdline_parse_token_num_t cmd_write_reg_bit_field_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, value,
+ UINT32);
+
+cmdline_parse_inst_t cmd_write_reg_bit_field = {
+ .f = cmd_write_reg_bit_field_parsed,
+ .data = NULL,
+ .help_str = "write regfield port_id reg_off bit_x bit_y reg_value"
+ "(set register bit field between bit_x and bit_y included)",
+ .tokens = {
+ (void *)&cmd_write_reg_bit_field_write,
+ (void *)&cmd_write_reg_bit_field_regfield,
+ (void *)&cmd_write_reg_bit_field_port_id,
+ (void *)&cmd_write_reg_bit_field_reg_off,
+ (void *)&cmd_write_reg_bit_field_bit1_pos,
+ (void *)&cmd_write_reg_bit_field_bit2_pos,
+ (void *)&cmd_write_reg_bit_field_value,
+ NULL,
+ },
+};
+
+/* *** WRITE PORT REGISTER BIT *** */
+struct cmd_write_reg_bit_result {
+ cmdline_fixed_string_t write;
+ cmdline_fixed_string_t regbit;
+ uint8_t port_id;
+ uint32_t reg_off;
+ uint8_t bit_pos;
+ uint8_t value;
+};
+
+static void
+cmd_write_reg_bit_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_write_reg_bit_result *res = parsed_result;
+ port_reg_bit_set(res->port_id, res->reg_off, res->bit_pos, res->value);
+}
+
+cmdline_parse_token_string_t cmd_write_reg_bit_write =
+ TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_result, write,
+ "write");
+cmdline_parse_token_string_t cmd_write_reg_bit_regbit =
+ TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_result,
+ regbit, "regbit");
+cmdline_parse_token_num_t cmd_write_reg_bit_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, port_id, UINT8);
+cmdline_parse_token_num_t cmd_write_reg_bit_reg_off =
+ TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, reg_off, UINT32);
+cmdline_parse_token_num_t cmd_write_reg_bit_bit_pos =
+ TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, bit_pos, UINT8);
+cmdline_parse_token_num_t cmd_write_reg_bit_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, value, UINT8);
+
+cmdline_parse_inst_t cmd_write_reg_bit = {
+ .f = cmd_write_reg_bit_parsed,
+ .data = NULL,
+ .help_str = "write regbit port_id reg_off bit_x 0/1 (0 <= bit_x <= 31)",
+ .tokens = {
+ (void *)&cmd_write_reg_bit_write,
+ (void *)&cmd_write_reg_bit_regbit,
+ (void *)&cmd_write_reg_bit_port_id,
+ (void *)&cmd_write_reg_bit_reg_off,
+ (void *)&cmd_write_reg_bit_bit_pos,
+ (void *)&cmd_write_reg_bit_value,
+ NULL,
+ },
+};
+
+/* *** READ A RING DESCRIPTOR OF A PORT RX/TX QUEUE *** */
+struct cmd_read_rxd_txd_result {
+ cmdline_fixed_string_t read;
+ cmdline_fixed_string_t rxd_txd;
+ uint8_t port_id;
+ uint16_t queue_id;
+ uint16_t desc_id;
+};
+
+static void
+cmd_read_rxd_txd_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_read_rxd_txd_result *res = parsed_result;
+
+ if (!strcmp(res->rxd_txd, "rxd"))
+ rx_ring_desc_display(res->port_id, res->queue_id, res->desc_id);
+ else if (!strcmp(res->rxd_txd, "txd"))
+ tx_ring_desc_display(res->port_id, res->queue_id, res->desc_id);
+}
+
+cmdline_parse_token_string_t cmd_read_rxd_txd_read =
+ TOKEN_STRING_INITIALIZER(struct cmd_read_rxd_txd_result, read, "read");
+cmdline_parse_token_string_t cmd_read_rxd_txd_rxd_txd =
+ TOKEN_STRING_INITIALIZER(struct cmd_read_rxd_txd_result, rxd_txd,
+ "rxd#txd");
+cmdline_parse_token_num_t cmd_read_rxd_txd_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, port_id, UINT8);
+cmdline_parse_token_num_t cmd_read_rxd_txd_queue_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, queue_id, UINT16);
+cmdline_parse_token_num_t cmd_read_rxd_txd_desc_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, desc_id, UINT16);
+
+cmdline_parse_inst_t cmd_read_rxd_txd = {
+ .f = cmd_read_rxd_txd_parsed,
+ .data = NULL,
+ .help_str = "read rxd|txd port_id queue_id rxd_id",
+ .tokens = {
+ (void *)&cmd_read_rxd_txd_read,
+ (void *)&cmd_read_rxd_txd_rxd_txd,
+ (void *)&cmd_read_rxd_txd_port_id,
+ (void *)&cmd_read_rxd_txd_queue_id,
+ (void *)&cmd_read_rxd_txd_desc_id,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ pmd_test_exit();
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** ADD/REMOVE MAC ADDRESS FROM A PORT *** */
+struct cmd_mac_addr_result {
+ cmdline_fixed_string_t mac_addr_cmd;
+ cmdline_fixed_string_t what;
+ uint8_t port_num;
+ struct ether_addr address;
+};
+
+static void cmd_mac_addr_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_mac_addr_result *res = parsed_result;
+ int ret;
+
+ if (strcmp(res->what, "add") == 0)
+ ret = rte_eth_dev_mac_addr_add(res->port_num, &res->address, 0);
+ else
+ ret = rte_eth_dev_mac_addr_remove(res->port_num, &res->address);
+
+ /* check the return value and print it if is < 0 */
+ if(ret < 0)
+ printf("mac_addr_cmd error: (%s)\n", strerror(-ret));
+
+}
+
+cmdline_parse_token_string_t cmd_mac_addr_cmd =
+ TOKEN_STRING_INITIALIZER(struct cmd_mac_addr_result, mac_addr_cmd,
+ "mac_addr");
+cmdline_parse_token_string_t cmd_mac_addr_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_mac_addr_result, what,
+ "add#remove");
+cmdline_parse_token_num_t cmd_mac_addr_portnum =
+ TOKEN_NUM_INITIALIZER(struct cmd_mac_addr_result, port_num, UINT8);
+cmdline_parse_token_string_t cmd_mac_addr_addr =
+ TOKEN_ETHERADDR_INITIALIZER(struct cmd_mac_addr_result, address);
+
+cmdline_parse_inst_t cmd_mac_addr = {
+ .f = cmd_mac_addr_parsed,
+ .data = (void *)0,
+ .help_str = "mac_addr add|remove X <address>: "
+ "add/remove MAC address on port X",
+ .tokens = {
+ (void *)&cmd_mac_addr_cmd,
+ (void *)&cmd_mac_addr_what,
+ (void *)&cmd_mac_addr_portnum,
+ (void *)&cmd_mac_addr_addr,
+ NULL,
+ },
+};
+
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ (cmdline_parse_inst_t *)&cmd_showport,
+ (cmdline_parse_inst_t *)&cmd_showportall,
+ (cmdline_parse_inst_t *)&cmd_showcfg,
+ (cmdline_parse_inst_t *)&cmd_start,
+ (cmdline_parse_inst_t *)&cmd_start_tx_first,
+ (cmdline_parse_inst_t *)&cmd_reset,
+ (cmdline_parse_inst_t *)&cmd_set_numbers,
+ (cmdline_parse_inst_t *)&cmd_set_txpkts,
+ (cmdline_parse_inst_t *)&cmd_set_fwd_list,
+ (cmdline_parse_inst_t *)&cmd_set_fwd_mask,
+ (cmdline_parse_inst_t *)&cmd_set_fwd_mode,
+ (cmdline_parse_inst_t *)&cmd_set_promisc_mode_one,
+ (cmdline_parse_inst_t *)&cmd_set_promisc_mode_all,
+ (cmdline_parse_inst_t *)&cmd_set_allmulti_mode_one,
+ (cmdline_parse_inst_t *)&cmd_set_allmulti_mode_all,
+ (cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
+ (cmdline_parse_inst_t *)&cmd_rx_vlan_filter,
+ (cmdline_parse_inst_t *)&cmd_tx_vlan_set,
+ (cmdline_parse_inst_t *)&cmd_tx_vlan_reset,
+ (cmdline_parse_inst_t *)&cmd_tx_cksum_set,
+ (cmdline_parse_inst_t *)&cmd_link_flow_control_set,
+ (cmdline_parse_inst_t *)&cmd_read_reg,
+ (cmdline_parse_inst_t *)&cmd_read_reg_bit_field,
+ (cmdline_parse_inst_t *)&cmd_read_reg_bit,
+ (cmdline_parse_inst_t *)&cmd_write_reg,
+ (cmdline_parse_inst_t *)&cmd_write_reg_bit_field,
+ (cmdline_parse_inst_t *)&cmd_write_reg_bit,
+ (cmdline_parse_inst_t *)&cmd_read_rxd_txd,
+ (cmdline_parse_inst_t *)&cmd_add_signature_filter,
+ (cmdline_parse_inst_t *)&cmd_upd_signature_filter,
+ (cmdline_parse_inst_t *)&cmd_rm_signature_filter,
+ (cmdline_parse_inst_t *)&cmd_add_perfect_filter,
+ (cmdline_parse_inst_t *)&cmd_upd_perfect_filter,
+ (cmdline_parse_inst_t *)&cmd_rm_perfect_filter,
+ (cmdline_parse_inst_t *)&cmd_set_masks_filter,
+ (cmdline_parse_inst_t *)&cmd_stop,
+ (cmdline_parse_inst_t *)&cmd_mac_addr,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "testpmd> ");
+ if (cl == NULL) {
+ return;
+ }
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
new file mode 100644
index 0000000..fd62235
--- /dev/null
+++ b/app/test-pmd/config.c
@@ -0,0 +1,1142 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdarg.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <sys/queue.h>
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_debug.h>
+#include <rte_log.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_string_fns.h>
+
+#include "testpmd.h"
+
+static void
+print_ethaddr(const char *name, struct ether_addr *eth_addr)
+{
+ printf("%s%02X:%02X:%02X:%02X:%02X:%02X", name,
+ eth_addr->addr_bytes[0],
+ eth_addr->addr_bytes[1],
+ eth_addr->addr_bytes[2],
+ eth_addr->addr_bytes[3],
+ eth_addr->addr_bytes[4],
+ eth_addr->addr_bytes[5]);
+}
+
+void
+nic_stats_display(portid_t port_id)
+{
+ struct rte_eth_stats stats;
+
+ static const char *nic_stats_border = "########################";
+
+ if (port_id >= nb_ports) {
+ printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+ return;
+ }
+ rte_eth_stats_get(port_id, &stats);
+ printf("\n %s NIC statistics for port %-2d %s\n",
+ nic_stats_border, port_id, nic_stats_border);
+ printf(" RX-packets: %-10"PRIu64" RX-errors: %-10"PRIu64"RX-bytes: "
+ "%-"PRIu64"\n"
+ " TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64"TX-bytes: "
+ "%-"PRIu64"\n",
+ stats.ipackets, stats.ierrors, stats.ibytes,
+ stats.opackets, stats.oerrors, stats.obytes);
+
+ /* stats fdir */
+ if (fdir_conf.mode != RTE_FDIR_MODE_NONE)
+ printf(" Fdirmiss: %-10"PRIu64" Fdirmatch: %-10"PRIu64"\n",
+ stats.fdirmiss,
+ stats.fdirmatch);
+
+ printf(" %s############################%s\n",
+ nic_stats_border, nic_stats_border);
+}
+
+void
+nic_stats_clear(portid_t port_id)
+{
+ if (port_id >= nb_ports) {
+ printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+ return;
+ }
+ rte_eth_stats_reset(port_id);
+ printf("\n NIC statistics for port %d cleared\n", port_id);
+}
+
+void
+port_infos_display(portid_t port_id)
+{
+ struct rte_port *port;
+ struct rte_eth_link link;
+ static const char *info_border = "*********************";
+
+ if (port_id >= nb_ports) {
+ printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+ return;
+ }
+ port = &ports[port_id];
+ rte_eth_link_get(port_id, &link);
+ printf("\n%s Infos for port %-2d %s\n",
+ info_border, port_id, info_border);
+ print_ethaddr("MAC address: ", &port->eth_addr);
+ printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down"));
+ printf("Link speed: %u Mbps\n", (unsigned) link.link_speed);
+ printf("Link duplex: %s\n", (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
+ ("full-duplex") : ("half-duplex"));
+ printf("Promiscuous mode: %s\n",
+ rte_eth_promiscuous_get(port_id) ? "enabled" : "disabled");
+ printf("Allmulticast mode: %s\n",
+ rte_eth_allmulticast_get(port_id) ? "enabled" : "disabled");
+ printf("Maximum number of MAC addresses: %u\n",
+ (unsigned int)(port->dev_info.max_mac_addrs));
+}
+
+static int
+port_id_is_invalid(portid_t port_id)
+{
+ if (port_id < nb_ports)
+ return 0;
+ printf("Invalid port %d (must be < nb_ports=%d)\n", port_id, nb_ports);
+ return 1;
+}
+
+static int
+vlan_id_is_invalid(uint16_t vlan_id)
+{
+ if (vlan_id < 4096)
+ return 0;
+ printf("Invalid vlan_id %d (must be < 4096)\n", vlan_id);
+ return 1;
+}
+
+static int
+port_reg_off_is_invalid(portid_t port_id, uint32_t reg_off)
+{
+ uint64_t pci_len;
+
+ if (reg_off & 0x3) {
+ printf("Port register offset 0x%X not aligned on a 4-byte "
+ "boundary\n",
+ (unsigned)reg_off);
+ return 1;
+ }
+ pci_len = ports[port_id].dev_info.pci_dev->mem_resource.len;
+ if (reg_off >= pci_len) {
+ printf("Port %d: register offset %u (0x%X) out of port PCI "
+ "resource (length=%"PRIu64")\n",
+ port_id, (unsigned)reg_off, (unsigned)reg_off, pci_len);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+reg_bit_pos_is_invalid(uint8_t bit_pos)
+{
+ if (bit_pos <= 31)
+ return 0;
+ printf("Invalid bit position %d (must be <= 31)\n", bit_pos);
+ return 1;
+}
+
+#define display_port_and_reg_off(port_id, reg_off) \
+ printf("port %d PCI register at offset 0x%X: ", (port_id), (reg_off))
+
+static inline void
+display_port_reg_value(portid_t port_id, uint32_t reg_off, uint32_t reg_v)
+{
+ display_port_and_reg_off(port_id, (unsigned)reg_off);
+ printf("0x%08X (%u)\n", (unsigned)reg_v, (unsigned)reg_v);
+}
+
+void
+port_reg_bit_display(portid_t port_id, uint32_t reg_off, uint8_t bit_x)
+{
+ uint32_t reg_v;
+
+
+ if (port_id_is_invalid(port_id))
+ return;
+ if (port_reg_off_is_invalid(port_id, reg_off))
+ return;
+ if (reg_bit_pos_is_invalid(bit_x))
+ return;
+ reg_v = port_id_pci_reg_read(port_id, reg_off);
+ display_port_and_reg_off(port_id, (unsigned)reg_off);
+ printf("bit %d=%d\n", bit_x, (int) ((reg_v & (1 << bit_x)) >> bit_x));
+}
+
+void
+port_reg_bit_field_display(portid_t port_id, uint32_t reg_off,
+ uint8_t bit1_pos, uint8_t bit2_pos)
+{
+ uint32_t reg_v;
+ uint8_t l_bit;
+ uint8_t h_bit;
+
+ if (port_id_is_invalid(port_id))
+ return;
+ if (port_reg_off_is_invalid(port_id, reg_off))
+ return;
+ if (reg_bit_pos_is_invalid(bit1_pos))
+ return;
+ if (reg_bit_pos_is_invalid(bit2_pos))
+ return;
+ if (bit1_pos > bit2_pos)
+ l_bit = bit2_pos, h_bit = bit1_pos;
+ else
+ l_bit = bit1_pos, h_bit = bit2_pos;
+
+ reg_v = port_id_pci_reg_read(port_id, reg_off);
+ reg_v >>= l_bit;
+ if (h_bit < 31)
+ reg_v &= ((1 << (h_bit - l_bit + 1)) - 1);
+ display_port_and_reg_off(port_id, (unsigned)reg_off);
+ printf("bits[%d, %d]=0x%0*X (%u)\n", l_bit, h_bit,
+ ((h_bit - l_bit) / 4) + 1, (unsigned)reg_v, (unsigned)reg_v);
+}
+
+void
+port_reg_display(portid_t port_id, uint32_t reg_off)
+{
+ uint32_t reg_v;
+
+ if (port_id_is_invalid(port_id))
+ return;
+ if (port_reg_off_is_invalid(port_id, reg_off))
+ return;
+ reg_v = port_id_pci_reg_read(port_id, reg_off);
+ display_port_reg_value(port_id, reg_off, reg_v);
+}
+
+void
+port_reg_bit_set(portid_t port_id, uint32_t reg_off, uint8_t bit_pos,
+ uint8_t bit_v)
+{
+ uint32_t reg_v;
+
+ if (port_id_is_invalid(port_id))
+ return;
+ if (port_reg_off_is_invalid(port_id, reg_off))
+ return;
+ if (reg_bit_pos_is_invalid(bit_pos))
+ return;
+ if (bit_v > 1) {
+ printf("Invalid bit value %d (must be 0 or 1)\n", (int) bit_v);
+ return;
+ }
+ reg_v = port_id_pci_reg_read(port_id, reg_off);
+ if (bit_v == 0)
+ reg_v &= ~(1 << bit_pos);
+ else
+ reg_v |= (1 << bit_pos);
+ port_id_pci_reg_write(port_id, reg_off, reg_v);
+ display_port_reg_value(port_id, reg_off, reg_v);
+}
+
+void
+port_reg_bit_field_set(portid_t port_id, uint32_t reg_off,
+ uint8_t bit1_pos, uint8_t bit2_pos, uint32_t value)
+{
+ uint32_t max_v;
+ uint32_t reg_v;
+ uint8_t l_bit;
+ uint8_t h_bit;
+
+ if (port_id_is_invalid(port_id))
+ return;
+ if (port_reg_off_is_invalid(port_id, reg_off))
+ return;
+ if (reg_bit_pos_is_invalid(bit1_pos))
+ return;
+ if (reg_bit_pos_is_invalid(bit2_pos))
+ return;
+ if (bit1_pos > bit2_pos)
+ l_bit = bit2_pos, h_bit = bit1_pos;
+ else
+ l_bit = bit1_pos, h_bit = bit2_pos;
+
+ if ((h_bit - l_bit) < 31)
+ max_v = (1 << (h_bit - l_bit + 1)) - 1;
+ else
+ max_v = 0xFFFFFFFF;
+
+ if (value > max_v) {
+ printf("Invalid value %u (0x%x) must be < %u (0x%x)\n",
+ (unsigned)value, (unsigned)value,
+ (unsigned)max_v, (unsigned)max_v);
+ return;
+ }
+ reg_v = port_id_pci_reg_read(port_id, reg_off);
+ reg_v &= ~(max_v << l_bit); /* Keep unchanged bits */
+ reg_v |= (value << l_bit); /* Set changed bits */
+ port_id_pci_reg_write(port_id, reg_off, reg_v);
+ display_port_reg_value(port_id, reg_off, reg_v);
+}
+
+void
+port_reg_set(portid_t port_id, uint32_t reg_off, uint32_t reg_v)
+{
+ if (port_id_is_invalid(port_id))
+ return;
+ if (port_reg_off_is_invalid(port_id, reg_off))
+ return;
+ port_id_pci_reg_write(port_id, reg_off, reg_v);
+ display_port_reg_value(port_id, reg_off, reg_v);
+}
+
+/*
+ * RX/TX ring descriptors display functions.
+ */
+static int
+rx_queue_id_is_invalid(queueid_t rxq_id)
+{
+ if (rxq_id < nb_rxq)
+ return 0;
+ printf("Invalid RX queue %d (must be < nb_rxq=%d)\n", rxq_id, nb_rxq);
+ return 1;
+}
+
+static int
+tx_queue_id_is_invalid(queueid_t txq_id)
+{
+ if (txq_id < nb_txq)
+ return 0;
+ printf("Invalid TX queue %d (must be < nb_rxq=%d)\n", txq_id, nb_txq);
+ return 1;
+}
+
+static int
+rx_desc_id_is_invalid(uint16_t rxdesc_id)
+{
+ if (rxdesc_id < nb_rxd)
+ return 0;
+ printf("Invalid RX descriptor %d (must be < nb_rxd=%d)\n",
+ rxdesc_id, nb_rxd);
+ return 1;
+}
+
+static int
+tx_desc_id_is_invalid(uint16_t txdesc_id)
+{
+ if (txdesc_id < nb_txd)
+ return 0;
+ printf("Invalid TX descriptor %d (must be < nb_txd=%d)\n",
+ txdesc_id, nb_txd);
+ return 1;
+}
+
+static const struct rte_memzone *
+ring_dma_zone_lookup(const char *ring_name, uint8_t port_id, uint16_t q_id)
+{
+ char mz_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+
+ rte_snprintf(mz_name, sizeof(mz_name), "%s_%s_%d_%d",
+ ports[port_id].dev_info.driver_name, ring_name, port_id, q_id);
+ mz = rte_memzone_lookup(mz_name);
+ if (mz == NULL)
+ printf("%s ring memory zoneof (port %d, queue %d) not"
+ "found (zone name = %s\n",
+ ring_name, port_id, q_id, mz_name);
+ return (mz);
+}
+
+union igb_ring_dword {
+ uint64_t dword;
+ struct {
+ uint32_t hi;
+ uint32_t lo;
+ } words;
+};
+
+struct igb_ring_desc {
+ union igb_ring_dword lo_dword;
+ union igb_ring_dword hi_dword;
+};
+
+static void
+ring_descriptor_display(const struct rte_memzone *ring_mz, uint16_t desc_id)
+{
+ struct igb_ring_desc *ring;
+ struct igb_ring_desc rd;
+
+ ring = (struct igb_ring_desc *) ring_mz->addr;
+ rd.lo_dword = rte_le_to_cpu_64(ring[desc_id].lo_dword);
+ rd.hi_dword = rte_le_to_cpu_64(ring[desc_id].hi_dword);
+ printf(" 0x%08X - 0x%08X / 0x%08X - 0x%08X\n",
+ (unsigned)rd.lo_dword.words.lo, (unsigned)rd.lo_dword.words.hi,
+ (unsigned)rd.hi_dword.words.lo, (unsigned)rd.hi_dword.words.hi);
+}
+
+void
+rx_ring_desc_display(portid_t port_id, queueid_t rxq_id, uint16_t rxd_id)
+{
+ const struct rte_memzone *rx_mz;
+
+ if (port_id_is_invalid(port_id))
+ return;
+ if (rx_queue_id_is_invalid(rxq_id))
+ return;
+ if (rx_desc_id_is_invalid(rxd_id))
+ return;
+ rx_mz = ring_dma_zone_lookup("rx_ring", port_id, rxq_id);
+ if (rx_mz == NULL)
+ return;
+ ring_descriptor_display(rx_mz, rxd_id);
+}
+
+void
+tx_ring_desc_display(portid_t port_id, queueid_t txq_id, uint16_t txd_id)
+{
+ const struct rte_memzone *tx_mz;
+
+ if (port_id_is_invalid(port_id))
+ return;
+ if (tx_queue_id_is_invalid(txq_id))
+ return;
+ if (tx_desc_id_is_invalid(txd_id))
+ return;
+ tx_mz = ring_dma_zone_lookup("tx_ring", port_id, txq_id);
+ if (tx_mz == NULL)
+ return;
+ ring_descriptor_display(tx_mz, txd_id);
+}
+
+void
+fwd_lcores_config_display(void)
+{
+ lcoreid_t lc_id;
+
+ printf("List of forwarding lcores:");
+ for (lc_id = 0; lc_id < nb_cfg_lcores; lc_id++)
+ printf(" %2u", fwd_lcores_cpuids[lc_id]);
+ printf("\n");
+}
+void
+rxtx_config_display(void)
+{
+ printf(" %s packet forwarding - CRC stripping %s - "
+ "packets/burst=%d\n", cur_fwd_eng->fwd_mode_name,
+ rx_mode.hw_strip_crc ? "enabled" : "disabled",
+ nb_pkt_per_burst);
+
+ if (cur_fwd_eng == &tx_only_engine)
+ printf(" packet len=%u - nb packet segments=%d\n",
+ (unsigned)tx_pkt_length, (int) tx_pkt_nb_segs);
+
+ printf(" nb forwarding cores=%d - nb forwarding ports=%d\n",
+ nb_fwd_lcores, nb_fwd_ports);
+ printf(" RX queues=%d - RX desc=%d - RX free threshold=%d\n",
+ nb_rxq, nb_rxd, rx_free_thresh);
+ printf(" RX threshold registers: pthresh=%d hthresh=%d wthresh=%d\n",
+ rx_thresh.pthresh, rx_thresh.hthresh, rx_thresh.wthresh);
+ printf(" TX queues=%d - TX desc=%d - TX free threshold=%d\n",
+ nb_txq, nb_txd, tx_free_thresh);
+ printf(" TX threshold registers: pthresh=%d hthresh=%d wthresh=%d\n",
+ tx_thresh.pthresh, tx_thresh.hthresh, tx_thresh.wthresh);
+ printf(" TX RS bit threshold=%d\n", tx_rs_thresh);
+}
+
+/*
+ * Setup forwarding configuration for each logical core.
+ */
+static void
+setup_fwd_config_of_each_lcore(struct fwd_config *cfg)
+{
+ streamid_t nb_fs_per_lcore;
+ streamid_t nb_fs;
+ streamid_t sm_id;
+ lcoreid_t nb_extra;
+ lcoreid_t nb_fc;
+ lcoreid_t nb_lc;
+ lcoreid_t lc_id;
+
+ nb_fs = cfg->nb_fwd_streams;
+ nb_fc = cfg->nb_fwd_lcores;
+ if (nb_fs <= nb_fc) {
+ nb_fs_per_lcore = 1;
+ nb_extra = 0;
+ } else {
+ nb_fs_per_lcore = (streamid_t) (nb_fs / nb_fc);
+ nb_extra = (lcoreid_t) (nb_fs % nb_fc);
+ }
+ nb_extra = (lcoreid_t) (nb_fs % nb_fc);
+
+ nb_lc = (lcoreid_t) (nb_fc - nb_extra);
+ sm_id = 0;
+ for (lc_id = 0; lc_id < nb_lc; lc_id++) {
+ fwd_lcores[lc_id]->stream_idx = sm_id;
+ fwd_lcores[lc_id]->stream_nb = nb_fs_per_lcore;
+ sm_id = (streamid_t) (sm_id + nb_fs_per_lcore);
+ }
+
+ /*
+ * Assign extra remaining streams, if any.
+ */
+ nb_fs_per_lcore = (streamid_t) (nb_fs_per_lcore + 1);
+ for (lc_id = 0; lc_id < nb_extra; lc_id++) {
+ fwd_lcores[nb_lc + lc_id]->stream_idx = sm_id;
+ fwd_lcores[nb_lc + lc_id]->stream_nb = nb_fs_per_lcore;
+ sm_id = (streamid_t) (sm_id + nb_fs_per_lcore);
+ }
+}
+
+static void
+simple_fwd_config_setup(void)
+{
+ portid_t i;
+ portid_t j;
+ portid_t inc = 2;
+
+ if (nb_fwd_ports % 2) {
+ if (port_topology == PORT_TOPOLOGY_CHAINED) {
+ inc = 1;
+ }
+ else {
+ printf("\nWarning! Cannot handle an odd number of ports "
+ "with the current port topology. Configuration "
+ "must be changed to have an even number of ports, "
+ "or relaunch application with "
+ "--port-topology=chained\n\n");
+ }
+ }
+
+ cur_fwd_config.nb_fwd_ports = (portid_t) nb_fwd_ports;
+ cur_fwd_config.nb_fwd_streams =
+ (streamid_t) cur_fwd_config.nb_fwd_ports;
+
+ /*
+ * In the simple forwarding test, the number of forwarding cores
+ * must be lower or equal to the number of forwarding ports.
+ */
+ cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores;
+ if (cur_fwd_config.nb_fwd_lcores > cur_fwd_config.nb_fwd_ports)
+ cur_fwd_config.nb_fwd_lcores =
+ (lcoreid_t) cur_fwd_config.nb_fwd_ports;
+ setup_fwd_config_of_each_lcore(&cur_fwd_config);
+
+ for (i = 0; i < cur_fwd_config.nb_fwd_ports; i = (portid_t) (i + inc)) {
+ j = (portid_t) ((i + 1) % cur_fwd_config.nb_fwd_ports);
+ fwd_streams[i]->rx_port = fwd_ports_ids[i];
+ fwd_streams[i]->rx_queue = 0;
+ fwd_streams[i]->tx_port = fwd_ports_ids[j];
+ fwd_streams[i]->tx_queue = 0;
+ fwd_streams[i]->peer_addr = j;
+
+ if (port_topology == PORT_TOPOLOGY_PAIRED) {
+ fwd_streams[j]->rx_port = fwd_ports_ids[j];
+ fwd_streams[j]->rx_queue = 0;
+ fwd_streams[j]->tx_port = fwd_ports_ids[i];
+ fwd_streams[j]->tx_queue = 0;
+ fwd_streams[j]->peer_addr = i;
+ }
+ }
+}
+
+/**
+ * For the RSS forwarding test, each core is assigned on every port a transmit
+ * queue whose index is the index of the core itself. This approach limits the
+ * maximumm number of processing cores of the RSS test to the maximum number of
+ * TX queues supported by the devices.
+ *
+ * Each core is assigned a single stream, each stream being composed of
+ * a RX queue to poll on a RX port for input messages, associated with
+ * a TX queue of a TX port where to send forwarded packets.
+ * All packets received on the RX queue of index "RxQj" of the RX port "RxPi"
+ * are sent on the TX queue "TxQl" of the TX port "TxPk" according to the two
+ * following rules:
+ * - TxPk = (RxPi + 1) if RxPi is even, (RxPi - 1) if RxPi is odd
+ * - TxQl = RxQj
+ */
+static void
+rss_fwd_config_setup(void)
+{
+ portid_t rxp;
+ portid_t txp;
+ queueid_t rxq;
+ queueid_t nb_q;
+ lcoreid_t lc_id;
+
+ nb_q = nb_rxq;
+ if (nb_q > nb_txq)
+ nb_q = nb_txq;
+ cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores;
+ cur_fwd_config.nb_fwd_ports = nb_fwd_ports;
+ cur_fwd_config.nb_fwd_streams =
+ (streamid_t) (nb_q * cur_fwd_config.nb_fwd_ports);
+ if (cur_fwd_config.nb_fwd_streams > cur_fwd_config.nb_fwd_lcores)
+ cur_fwd_config.nb_fwd_streams =
+ (streamid_t)cur_fwd_config.nb_fwd_lcores;
+ else
+ cur_fwd_config.nb_fwd_lcores =
+ (lcoreid_t)cur_fwd_config.nb_fwd_streams;
+ setup_fwd_config_of_each_lcore(&cur_fwd_config);
+ rxp = 0; rxq = 0;
+ for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) {
+ struct fwd_stream *fs;
+
+ fs = fwd_streams[lc_id];
+ if ((rxp & 0x1) == 0)
+ txp = (portid_t) (rxp + 1);
+ else
+ txp = (portid_t) (rxp - 1);
+ fs->rx_port = fwd_ports_ids[rxp];
+ fs->rx_queue = rxq;
+ fs->tx_port = fwd_ports_ids[txp];
+ fs->tx_queue = rxq;
+ fs->peer_addr = fs->tx_port;
+ rxq = (queueid_t) (rxq + 1);
+ if (rxq < nb_q)
+ continue;
+ /*
+ * rxq == nb_q
+ * Restart from RX queue 0 on next RX port
+ */
+ rxq = 0;
+ if (numa_support && (nb_fwd_ports <= (nb_ports >> 1)))
+ rxp = (portid_t)
+ (rxp + ((nb_ports >> 1) / nb_fwd_ports));
+ else
+ rxp = (portid_t) (rxp + 1);
+ }
+}
+
+void
+fwd_config_setup(void)
+{
+ cur_fwd_config.fwd_eng = cur_fwd_eng;
+ if ((nb_rxq > 1) && (nb_txq > 1))
+ rss_fwd_config_setup();
+ else
+ simple_fwd_config_setup();
+}
+
+static void
+pkt_fwd_config_display(struct fwd_config *cfg)
+{
+ struct fwd_stream *fs;
+ lcoreid_t lc_id;
+ streamid_t sm_id;
+
+ printf("%s packet forwarding - ports=%d - cores=%d - streams=%d - "
+ "NUMA support %s\n",
+ cfg->fwd_eng->fwd_mode_name,
+ cfg->nb_fwd_ports, cfg->nb_fwd_lcores, cfg->nb_fwd_streams,
+ numa_support == 1 ? "enabled" : "disabled");
+ for (lc_id = 0; lc_id < cfg->nb_fwd_lcores; lc_id++) {
+ printf("Logical Core %u (socket %u) forwards packets on "
+ "%d streams:",
+ fwd_lcores_cpuids[lc_id],
+ rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]),
+ fwd_lcores[lc_id]->stream_nb);
+ for (sm_id = 0; sm_id < fwd_lcores[lc_id]->stream_nb; sm_id++) {
+ fs = fwd_streams[fwd_lcores[lc_id]->stream_idx + sm_id];
+ printf("\n RX P=%d/Q=%d (socket %u) -> TX "
+ "P=%d/Q=%d (socket %u) ",
+ fs->rx_port, fs->rx_queue,
+ ports[fs->rx_port].socket_id,
+ fs->tx_port, fs->tx_queue,
+ ports[fs->tx_port].socket_id);
+ print_ethaddr("peer=",
+ &peer_eth_addrs[fs->peer_addr]);
+ }
+ printf("\n");
+ }
+ printf("\n");
+}
+
+
+void
+fwd_config_display(void)
+{
+ fwd_config_setup();
+ pkt_fwd_config_display(&cur_fwd_config);
+}
+
+void
+set_fwd_lcores_list(unsigned int *lcorelist, unsigned int nb_lc)
+{
+ unsigned int i;
+ unsigned int lcore_cpuid;
+ int record_now;
+
+ record_now = 0;
+ again:
+ for (i = 0; i < nb_lc; i++) {
+ lcore_cpuid = lcorelist[i];
+ if (! rte_lcore_is_enabled(lcore_cpuid)) {
+ printf("Logical core %u not enabled\n", lcore_cpuid);
+ return;
+ }
+ if (lcore_cpuid == rte_get_master_lcore()) {
+ printf("Master core %u cannot forward packets\n",
+ lcore_cpuid);
+ return;
+ }
+ if (record_now)
+ fwd_lcores_cpuids[i] = lcore_cpuid;
+ }
+ if (record_now == 0) {
+ record_now = 1;
+ goto again;
+ }
+ nb_cfg_lcores = (lcoreid_t) nb_lc;
+ if (nb_fwd_lcores != (lcoreid_t) nb_lc) {
+ printf("previous number of forwarding cores %u - changed to "
+ "number of configured cores %u\n",
+ (unsigned int) nb_fwd_lcores, nb_lc);
+ nb_fwd_lcores = (lcoreid_t) nb_lc;
+ }
+}
+
+void
+set_fwd_lcores_mask(uint64_t lcoremask)
+{
+ unsigned int lcorelist[64];
+ unsigned int nb_lc;
+ unsigned int i;
+
+ if (lcoremask == 0) {
+ printf("Invalid NULL mask of cores\n");
+ return;
+ }
+ nb_lc = 0;
+ for (i = 0; i < 64; i++) {
+ if (! ((uint64_t)(1ULL << i) & lcoremask))
+ continue;
+ lcorelist[nb_lc++] = i;
+ }
+ set_fwd_lcores_list(lcorelist, nb_lc);
+}
+
+void
+set_fwd_lcores_number(uint16_t nb_lc)
+{
+ if (nb_lc > nb_cfg_lcores) {
+ printf("nb fwd cores %u > %u (max. number of configured "
+ "lcores) - ignored\n",
+ (unsigned int) nb_lc, (unsigned int) nb_cfg_lcores);
+ return;
+ }
+ nb_fwd_lcores = (lcoreid_t) nb_lc;
+ printf("Number of forwarding cores set to %u\n",
+ (unsigned int) nb_fwd_lcores);
+}
+
+void
+set_fwd_ports_list(unsigned int *portlist, unsigned int nb_pt)
+{
+ unsigned int i;
+ portid_t port_id;
+ int record_now;
+
+ record_now = 0;
+ again:
+ for (i = 0; i < nb_pt; i++) {
+ port_id = (portid_t) portlist[i];
+ if (port_id >= nb_ports) {
+ printf("Invalid port id %u > %u\n",
+ (unsigned int) port_id,
+ (unsigned int) nb_ports);
+ return;
+ }
+ if (record_now)
+ fwd_ports_ids[i] = port_id;
+ }
+ if (record_now == 0) {
+ record_now = 1;
+ goto again;
+ }
+ nb_cfg_ports = (portid_t) nb_pt;
+ if (nb_fwd_ports != (portid_t) nb_pt) {
+ printf("previous number of forwarding ports %u - changed to "
+ "number of configured ports %u\n",
+ (unsigned int) nb_fwd_ports, nb_pt);
+ nb_fwd_ports = (portid_t) nb_pt;
+ }
+}
+
+void
+set_fwd_ports_mask(uint64_t portmask)
+{
+ unsigned int portlist[64];
+ unsigned int nb_pt;
+ unsigned int i;
+
+ if (portmask == 0) {
+ printf("Invalid NULL mask of ports\n");
+ return;
+ }
+ nb_pt = 0;
+ for (i = 0; i < 64; i++) {
+ if (! ((uint64_t)(1ULL << i) & portmask))
+ continue;
+ portlist[nb_pt++] = i;
+ }
+ set_fwd_ports_list(portlist, nb_pt);
+}
+
+void
+set_fwd_ports_number(uint16_t nb_pt)
+{
+ if (nb_pt > nb_cfg_ports) {
+ printf("nb fwd ports %u > %u (number of configured "
+ "ports) - ignored\n",
+ (unsigned int) nb_pt, (unsigned int) nb_cfg_ports);
+ return;
+ }
+ nb_fwd_ports = (portid_t) nb_pt;
+ printf("Number of forwarding ports set to %u\n",
+ (unsigned int) nb_fwd_ports);
+}
+
+void
+set_nb_pkt_per_burst(uint16_t nb)
+{
+ if (nb > MAX_PKT_BURST) {
+ printf("nb pkt per burst: %u > %u (maximum packet per burst) "
+ " ignored\n",
+ (unsigned int) nb, (unsigned int) MAX_PKT_BURST);
+ return;
+ }
+ nb_pkt_per_burst = nb;
+ printf("Number of packets per burst set to %u\n",
+ (unsigned int) nb_pkt_per_burst);
+}
+
+void
+set_tx_pkt_segments(unsigned *seg_lengths, unsigned nb_segs)
+{
+ uint16_t tx_pkt_len;
+ unsigned i;
+
+ if (nb_segs >= (unsigned) nb_txd) {
+ printf("nb segments per TX packets=%u >= nb_txd=%u - ignored\n",
+ nb_segs, (unsigned int) nb_txd);
+ return;
+ }
+
+ /*
+ * Check that each segment length is greater or equal than
+ * the mbuf data sise.
+ * Check also that the total packet length is greater or equal than the
+ * size of an empty UDP/IP packet (sizeof(struct ether_hdr) + 20 + 8).
+ */
+ tx_pkt_len = 0;
+ for (i = 0; i < nb_segs; i++) {
+ if (seg_lengths[i] > (unsigned) mbuf_data_size) {
+ printf("length[%u]=%u > mbuf_data_size=%u - give up\n",
+ i, seg_lengths[i], (unsigned) mbuf_data_size);
+ return;
+ }
+ tx_pkt_len = (uint16_t)(tx_pkt_len + seg_lengths[i]);
+ }
+ if (tx_pkt_len < (sizeof(struct ether_hdr) + 20 + 8)) {
+ printf("total packet length=%u < %d - give up\n",
+ (unsigned) tx_pkt_len,
+ (int)(sizeof(struct ether_hdr) + 20 + 8));
+ return;
+ }
+
+ for (i = 0; i < nb_segs; i++)
+ tx_pkt_seg_lengths[i] = (uint16_t) seg_lengths[i];
+
+ tx_pkt_length = tx_pkt_len;
+ tx_pkt_nb_segs = (uint8_t) nb_segs;
+}
+
+void
+set_pkt_forwarding_mode(const char *fwd_mode_name)
+{
+ struct fwd_engine *fwd_eng;
+ unsigned i;
+
+ i = 0;
+ while ((fwd_eng = fwd_engines[i]) != NULL) {
+ if (! strcmp(fwd_eng->fwd_mode_name, fwd_mode_name)) {
+ printf("Set %s packet forwarding mode\n",
+ fwd_mode_name);
+ cur_fwd_eng = fwd_eng;
+ return;
+ }
+ i++;
+ }
+ printf("Invalid %s packet forwarding mode\n", fwd_mode_name);
+}
+
+void
+set_verbose_level(uint16_t vb_level)
+{
+ printf("Change verbose level from %u to %u\n",
+ (unsigned int) verbose_level, (unsigned int) vb_level);
+ verbose_level = vb_level;
+}
+
+void
+rx_vlan_filter_set(portid_t port_id, uint16_t vlan_id, int on)
+{
+ int diag;
+
+ if (port_id_is_invalid(port_id))
+ return;
+ if (vlan_id_is_invalid(vlan_id))
+ return;
+ diag = rte_eth_dev_vlan_filter(port_id, vlan_id, on);
+ if (diag == 0)
+ return;
+ printf("rte_eth_dev_vlan_filter(port_pi=%d, vlan_id=%d, on=%d) failed "
+ "diag=%d\n",
+ port_id, vlan_id, on, diag);
+}
+
+void
+rx_vlan_all_filter_set(portid_t port_id, int on)
+{
+ uint16_t vlan_id;
+
+ if (port_id_is_invalid(port_id))
+ return;
+ for (vlan_id = 0; vlan_id < 4096; vlan_id++)
+ rx_vlan_filter_set(port_id, vlan_id, on);
+}
+
+void
+tx_vlan_set(portid_t port_id, uint16_t vlan_id)
+{
+ if (port_id_is_invalid(port_id))
+ return;
+ if (vlan_id_is_invalid(vlan_id))
+ return;
+ ports[port_id].tx_ol_flags |= PKT_TX_VLAN_PKT;
+ ports[port_id].tx_vlan_id = vlan_id;
+}
+
+void
+tx_vlan_reset(portid_t port_id)
+{
+ if (port_id_is_invalid(port_id))
+ return;
+ ports[port_id].tx_ol_flags &= ~PKT_TX_VLAN_PKT;
+}
+
+void
+tx_cksum_set(portid_t port_id, uint8_t cksum_mask)
+{
+ uint16_t tx_ol_flags;
+ if (port_id_is_invalid(port_id))
+ return;
+ /* Clear last 4 bits and then set L3/4 checksum mask again */
+ tx_ol_flags = (uint16_t) (ports[port_id].tx_ol_flags & 0xFFF0);
+ ports[port_id].tx_ol_flags = (uint16_t) ((cksum_mask & 0xf) | tx_ol_flags);
+}
+
+void
+fdir_add_signature_filter(portid_t port_id, uint8_t queue_id,
+ struct rte_fdir_filter *fdir_filter)
+{
+ int diag;
+
+ if (port_id_is_invalid(port_id))
+ return;
+
+ diag = rte_eth_dev_fdir_add_signature_filter(port_id, fdir_filter,
+ queue_id);
+ if (diag == 0)
+ return;
+
+ printf("rte_eth_dev_fdir_add_signature_filter for port_id=%d failed "
+ "diag=%d\n", port_id, diag);
+}
+
+void
+fdir_update_signature_filter(portid_t port_id, uint8_t queue_id,
+ struct rte_fdir_filter *fdir_filter)
+{
+ int diag;
+
+ if (port_id_is_invalid(port_id))
+ return;
+
+ diag = rte_eth_dev_fdir_update_signature_filter(port_id, fdir_filter,
+ queue_id);
+ if (diag == 0)
+ return;
+
+ printf("rte_eth_dev_fdir_update_signature_filter for port_id=%d failed "
+ "diag=%d\n", port_id, diag);
+}
+
+void
+fdir_remove_signature_filter(portid_t port_id,
+ struct rte_fdir_filter *fdir_filter)
+{
+ int diag;
+
+ if (port_id_is_invalid(port_id))
+ return;
+
+ diag = rte_eth_dev_fdir_remove_signature_filter(port_id, fdir_filter);
+ if (diag == 0)
+ return;
+
+ printf("rte_eth_dev_fdir_add_signature_filter for port_id=%d failed "
+ "diag=%d\n", port_id, diag);
+
+}
+
+void
+fdir_get_infos(portid_t port_id)
+{
+ struct rte_eth_fdir fdir_infos;
+
+ static const char *fdir_stats_border = "########################";
+
+ if (port_id_is_invalid(port_id))
+ return;
+
+ rte_eth_dev_fdir_get_infos(port_id, &fdir_infos);
+
+ printf("\n %s FDIR infos for port %-2d %s\n",
+ fdir_stats_border, port_id, fdir_stats_border);
+
+ printf(" collision: %-10"PRIu64" free: %-10"PRIu64"\n"
+ " maxhash: %-10"PRIu64" maxlen: %-10"PRIu64"\n"
+ " add : %-10"PRIu64" remove : %-10"PRIu64"\n"
+ " f_add: %-10"PRIu64" f_remove: %-10"PRIu64"\n",
+ (uint64_t)(fdir_infos.collision), (uint64_t)(fdir_infos.free),
+ (uint64_t)(fdir_infos.maxhash), (uint64_t)(fdir_infos.maxlen),
+ fdir_infos.add, fdir_infos.remove,
+ fdir_infos.f_add, fdir_infos.f_remove);
+ printf(" %s############################%s\n",
+ fdir_stats_border, fdir_stats_border);
+}
+
+void
+fdir_add_perfect_filter(portid_t port_id, uint16_t soft_id, uint8_t queue_id,
+ uint8_t drop, struct rte_fdir_filter *fdir_filter)
+{
+ int diag;
+
+ if (port_id_is_invalid(port_id))
+ return;
+
+ diag = rte_eth_dev_fdir_add_perfect_filter(port_id, fdir_filter,
+ soft_id, queue_id, drop);
+ if (diag == 0)
+ return;
+
+ printf("rte_eth_dev_fdir_add_perfect_filter for port_id=%d failed "
+ "diag=%d\n", port_id, diag);
+}
+
+void
+fdir_update_perfect_filter(portid_t port_id, uint16_t soft_id, uint8_t queue_id,
+ uint8_t drop, struct rte_fdir_filter *fdir_filter)
+{
+ int diag;
+
+ if (port_id_is_invalid(port_id))
+ return;
+
+ diag = rte_eth_dev_fdir_update_perfect_filter(port_id, fdir_filter,
+ soft_id, queue_id, drop);
+ if (diag == 0)
+ return;
+
+ printf("rte_eth_dev_fdir_update_perfect_filter for port_id=%d failed "
+ "diag=%d\n", port_id, diag);
+}
+
+void
+fdir_remove_perfect_filter(portid_t port_id, uint16_t soft_id,
+ struct rte_fdir_filter *fdir_filter)
+{
+ int diag;
+
+ if (port_id_is_invalid(port_id))
+ return;
+
+ diag = rte_eth_dev_fdir_remove_perfect_filter(port_id, fdir_filter,
+ soft_id);
+ if (diag == 0)
+ return;
+
+ printf("rte_eth_dev_fdir_update_perfect_filter for port_id=%d failed "
+ "diag=%d\n", port_id, diag);
+}
+
+void
+fdir_set_masks(portid_t port_id, struct rte_fdir_masks *fdir_masks)
+{
+ int diag;
+
+ if (port_id_is_invalid(port_id))
+ return;
+
+ diag = rte_eth_dev_fdir_set_masks(port_id, fdir_masks);
+ if (diag == 0)
+ return;
+
+ printf("rte_eth_dev_set_masks_filter for port_id=%d failed "
+ "diag=%d\n", port_id, diag);
+}
diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
new file mode 100644
index 0000000..7aabcde
--- /dev/null
+++ b/app/test-pmd/csumonly.c
@@ -0,0 +1,449 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <sys/queue.h>
+#include <sys/stat.h>
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_ring.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_memcpy.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_ip.h>
+#include <rte_tcp.h>
+#include <rte_udp.h>
+#include <rte_sctp.h>
+#include <rte_prefetch.h>
+#include <rte_string_fns.h>
+#include "testpmd.h"
+
+
+
+#define IP_DEFTTL 64 /* from RFC 1340. */
+#define IP_VERSION 0x40
+#define IP_HDRLEN 0x05 /* default IP header length == five 32-bits words. */
+#define IP_VHL_DEF (IP_VERSION | IP_HDRLEN)
+
+/* Pseudo Header for IPv4/UDP/TCP checksum */
+struct psd_header {
+ uint32_t src_addr; /* IP address of source host. */
+ uint32_t dst_addr; /* IP address of destination host(s). */
+ uint8_t zero; /* zero. */
+ uint8_t proto; /* L4 protocol type. */
+ uint16_t len; /* L4 length. */
+} __attribute__((__packed__));
+
+
+/* Pseudo Header for IPv6/UDP/TCP checksum */
+struct ipv6_psd_header {
+ uint8_t src_addr[16]; /* IP address of source host. */
+ uint8_t dst_addr[16]; /* IP address of destination host(s). */
+ uint32_t len; /* L4 length. */
+ uint8_t zero[3]; /* zero. */
+ uint8_t proto; /* L4 protocol. */
+} __attribute__((__packed__));
+
+
+static inline uint16_t
+get_16b_sum(uint16_t *ptr16, uint32_t nr)
+{
+ uint32_t sum = 0;
+ while (nr > 1)
+ {
+ sum +=*ptr16;
+ nr -= sizeof(uint16_t);
+ ptr16++;
+ if (sum > UINT16_MAX)
+ sum -= UINT16_MAX;
+ }
+
+ /* If length is in odd bytes */
+ if (nr)
+ sum += *((uint8_t*)ptr16);
+
+ sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff);
+ sum &= 0x0ffff;
+ return (uint16_t)sum;
+}
+
+static inline uint16_t
+get_ipv4_cksum(struct ipv4_hdr *ipv4_hdr)
+{
+ uint16_t cksum;
+ cksum = get_16b_sum((uint16_t*)ipv4_hdr, sizeof(struct ipv4_hdr));
+ return (uint16_t)((cksum == 0xffff)?cksum:~cksum);
+}
+
+
+static inline
+uint16_t get_ipv4_psd_sum (struct ipv4_hdr * ip_hdr)
+{
+ struct psd_header psd_hdr;
+ psd_hdr.src_addr = ip_hdr->src_addr;
+ psd_hdr.dst_addr = ip_hdr->dst_addr;
+ psd_hdr.zero = 0;
+ psd_hdr.proto = ip_hdr->next_proto_id;
+ psd_hdr.len = rte_cpu_to_be_16((uint16_t)(rte_be_to_cpu_16(ip_hdr->total_length)
+ - sizeof(struct ipv4_hdr)));
+ return get_16b_sum((uint16_t*)&psd_hdr, sizeof(struct psd_header));
+}
+
+static inline
+uint16_t get_ipv6_psd_sum (struct ipv6_hdr * ip_hdr)
+{
+ struct ipv6_psd_header psd_hdr;
+ rte_memcpy(psd_hdr.src_addr, ip_hdr->src_addr, sizeof(ip_hdr->src_addr)
+ + sizeof(ip_hdr->dst_addr));
+
+ psd_hdr.zero[0] = 0;
+ psd_hdr.zero[1] = 0;
+ psd_hdr.zero[2] = 0;
+ psd_hdr.proto = ip_hdr->proto;
+ psd_hdr.len = ip_hdr->payload_len;
+
+ return get_16b_sum((uint16_t*)&psd_hdr, sizeof(struct ipv6_psd_header));
+}
+
+static inline uint16_t
+get_ipv4_udptcp_checksum(struct ipv4_hdr *ipv4_hdr, uint16_t *l4_hdr)
+{
+ uint32_t cksum;
+ uint32_t l4_len;
+
+ l4_len = rte_be_to_cpu_16(ipv4_hdr->total_length) - sizeof(struct ipv4_hdr);
+
+ cksum = get_16b_sum(l4_hdr, l4_len);
+ cksum += get_ipv4_psd_sum(ipv4_hdr);
+
+ cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
+ cksum = (~cksum) & 0xffff;
+ if (cksum == 0)
+ cksum = 0xffff;
+ return (uint16_t)cksum;
+
+}
+
+static inline uint16_t
+get_ipv6_udptcp_checksum(struct ipv6_hdr *ipv6_hdr, uint16_t *l4_hdr)
+{
+ uint32_t cksum;
+ uint32_t l4_len;
+
+ l4_len = rte_be_to_cpu_16(ipv6_hdr->payload_len);
+
+ cksum = get_16b_sum(l4_hdr, l4_len);
+ cksum += get_ipv6_psd_sum(ipv6_hdr);
+
+ cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
+ cksum = (~cksum) & 0xffff;
+ if (cksum == 0)
+ cksum = 0xffff;
+
+ return (uint16_t)cksum;
+}
+
+
+/*
+ * Forwarding of packets. Change the checksum field with HW or SW methods
+ * The HW/SW method selection depends on the ol_flags on every packet
+ */
+static void
+pkt_burst_checksum_forward(struct fwd_stream *fs)
+{
+ struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+ struct rte_port *txp;
+ struct rte_mbuf *mb;
+ struct ether_hdr *eth_hdr;
+ struct ipv4_hdr *ipv4_hdr;
+ struct ipv6_hdr *ipv6_hdr;
+ struct udp_hdr *udp_hdr;
+ struct tcp_hdr *tcp_hdr;
+ struct sctp_hdr *sctp_hdr;
+
+ uint16_t nb_rx;
+ uint16_t nb_tx;
+ uint16_t i;
+ uint16_t ol_flags;
+ uint16_t pkt_ol_flags;
+ uint16_t tx_ol_flags;
+ uint16_t l4_proto;
+ uint8_t l2_len;
+ uint8_t l3_len;
+
+ uint32_t rx_bad_ip_csum;
+ uint32_t rx_bad_l4_csum;
+
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ uint64_t start_tsc;
+ uint64_t end_tsc;
+ uint64_t core_cycles;
+#endif
+
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ start_tsc = rte_rdtsc();
+#endif
+
+ /*
+ * Receive a burst of packets and forward them.
+ */
+ nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
+ nb_pkt_per_burst);
+ if (unlikely(nb_rx == 0))
+ return;
+
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
+#endif
+ fs->rx_packets += nb_rx;
+ rx_bad_ip_csum = 0;
+ rx_bad_l4_csum = 0;
+
+ txp = &ports[fs->tx_port];
+ tx_ol_flags = txp->tx_ol_flags;
+
+ for (i = 0; i < nb_rx; i++) {
+
+ mb = pkts_burst[i];
+ l2_len = sizeof(struct ether_hdr);
+ pkt_ol_flags = mb->ol_flags;
+ ol_flags = (uint16_t) (pkt_ol_flags & (~PKT_TX_L4_MASK));
+
+ eth_hdr = (struct ether_hdr *) mb->pkt.data;
+ if (rte_be_to_cpu_16(eth_hdr->ether_type) == ETHER_TYPE_VLAN) {
+ /* Only allow single VLAN label here */
+ l2_len += sizeof(struct vlan_hdr);
+ }
+
+ /* Update the L3/L4 checksum error packet count */
+ rx_bad_ip_csum += (uint16_t) ((pkt_ol_flags & PKT_RX_IP_CKSUM_BAD) != 0);
+ rx_bad_l4_csum += (uint16_t) ((pkt_ol_flags & PKT_RX_L4_CKSUM_BAD) != 0);
+
+ /*
+ * Simplify the protocol parsing
+ * Assuming the incoming packets format as
+ * Ethernet2 + optional single VLAN
+ * + ipv4 or ipv6
+ * + udp or tcp or sctp or others
+ */
+ if (pkt_ol_flags & PKT_RX_IPV4_HDR) {
+
+ /* Do not support ipv4 option field */
+ l3_len = sizeof(struct ipv4_hdr) ;
+
+ ipv4_hdr = (struct ipv4_hdr *) (rte_pktmbuf_mtod(mb,
+ unsigned char *) + l2_len);
+
+ l4_proto = ipv4_hdr->next_proto_id;
+
+ /* Do not delete, this is required by HW*/
+ ipv4_hdr->hdr_checksum = 0;
+
+ if (tx_ol_flags & 0x1) {
+ /* HW checksum */
+ ol_flags |= PKT_TX_IP_CKSUM;
+ }
+ else {
+ /* SW checksum calculation */
+ ipv4_hdr->src_addr++;
+ ipv4_hdr->hdr_checksum = get_ipv4_cksum(ipv4_hdr);
+ }
+
+ if (l4_proto == IPPROTO_UDP) {
+ udp_hdr = (struct udp_hdr*) (rte_pktmbuf_mtod(mb,
+ unsigned char *) + l2_len + l3_len);
+ if (tx_ol_flags & 0x2) {
+ /* HW Offload */
+ ol_flags |= PKT_TX_UDP_CKSUM;
+ /* Pseudo header sum need be set properly */
+ udp_hdr->dgram_cksum = get_ipv4_psd_sum(ipv4_hdr);
+ }
+ else {
+ /* SW Implementation, clear checksum field first */
+ udp_hdr->dgram_cksum = 0;
+ udp_hdr->dgram_cksum = get_ipv4_udptcp_checksum(ipv4_hdr,
+ (uint16_t*)udp_hdr);
+ }
+ }
+ else if (l4_proto == IPPROTO_TCP){
+ tcp_hdr = (struct tcp_hdr*) (rte_pktmbuf_mtod(mb,
+ unsigned char *) + l2_len + l3_len);
+ if (tx_ol_flags & 0x4) {
+ ol_flags |= PKT_TX_TCP_CKSUM;
+ tcp_hdr->cksum = get_ipv4_psd_sum(ipv4_hdr);
+ }
+ else {
+ tcp_hdr->cksum = 0;
+ tcp_hdr->cksum = get_ipv4_udptcp_checksum(ipv4_hdr,
+ (uint16_t*)tcp_hdr);
+ }
+ }
+ else if (l4_proto == IPPROTO_SCTP) {
+ sctp_hdr = (struct sctp_hdr*) (rte_pktmbuf_mtod(mb,
+ unsigned char *) + l2_len + l3_len);
+
+ if (tx_ol_flags & 0x8) {
+ ol_flags |= PKT_TX_SCTP_CKSUM;
+ sctp_hdr->cksum = 0;
+
+ /* Sanity check, only number of 4 bytes supported */
+ if ((rte_be_to_cpu_16(ipv4_hdr->total_length) % 4) != 0)
+ printf("sctp payload must be a multiple "
+ "of 4 bytes for checksum offload");
+ }
+ else {
+ sctp_hdr->cksum = 0;
+ /* CRC32c sample code available in RFC3309 */
+ }
+ }
+ /* End of L4 Handling*/
+ }
+
+ else {
+ ipv6_hdr = (struct ipv6_hdr *) (rte_pktmbuf_mtod(mb,
+ unsigned char *) + l2_len);
+ l3_len = sizeof(struct ipv6_hdr) ;
+ l4_proto = ipv6_hdr->proto;
+
+ if (l4_proto == IPPROTO_UDP) {
+ udp_hdr = (struct udp_hdr*) (rte_pktmbuf_mtod(mb,
+ unsigned char *) + l2_len + l3_len);
+ if (tx_ol_flags & 0x2) {
+ /* HW Offload */
+ ol_flags |= PKT_TX_UDP_CKSUM;
+ udp_hdr->dgram_cksum = get_ipv6_psd_sum(ipv6_hdr);
+ }
+ else {
+ /* SW Implementation */
+ /* checksum field need be clear first */
+ udp_hdr->dgram_cksum = 0;
+ udp_hdr->dgram_cksum = get_ipv6_udptcp_checksum(ipv6_hdr,
+ (uint16_t*)udp_hdr);
+ }
+ }
+ else if (l4_proto == IPPROTO_TCP) {
+ tcp_hdr = (struct tcp_hdr*) (rte_pktmbuf_mtod(mb,
+ unsigned char *) + l2_len + l3_len);
+ if (tx_ol_flags & 0x4) {
+ ol_flags |= PKT_TX_TCP_CKSUM;
+ tcp_hdr->cksum = get_ipv6_psd_sum(ipv6_hdr);
+ }
+ else {
+ tcp_hdr->cksum = 0;
+ tcp_hdr->cksum = get_ipv6_udptcp_checksum(ipv6_hdr,
+ (uint16_t*)tcp_hdr);
+ }
+ }
+ else if (l4_proto == IPPROTO_SCTP) {
+ sctp_hdr = (struct sctp_hdr*) (rte_pktmbuf_mtod(mb,
+ unsigned char *) + l2_len + l3_len);
+
+ if (tx_ol_flags & 0x8) {
+ ol_flags |= PKT_TX_SCTP_CKSUM;
+ sctp_hdr->cksum = 0;
+ /* Sanity check, only number of 4 bytes supported by HW */
+ if ((rte_be_to_cpu_16(ipv6_hdr->payload_len) % 4) != 0)
+ printf("sctp payload must be a multiple "
+ "of 4 bytes for checksum offload");
+ }
+ else {
+ /* CRC32c sample code available in RFC3309 */
+ sctp_hdr->cksum = 0;
+ }
+ } else {
+ printf("Test flow control for 1G PMD \n");
+ }
+ /* End of L4 Handling*/
+ }
+
+ /* Combine the packet header write. VLAN is not consider here */
+ mb->pkt.l2_len = l2_len;
+ mb->pkt.l3_len = l3_len;
+ mb->ol_flags = ol_flags;
+ }
+ nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx);
+ fs->tx_packets += nb_tx;
+ fs->rx_bad_ip_csum += rx_bad_ip_csum;
+ fs->rx_bad_l4_csum += rx_bad_l4_csum;
+
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ fs->tx_burst_stats.pkt_burst_spread[nb_tx]++;
+#endif
+ if (unlikely(nb_tx < nb_rx)) {
+ fs->fwd_dropped += (nb_rx - nb_tx);
+ do {
+ rte_pktmbuf_free(pkts_burst[nb_tx]);
+ } while (++nb_tx < nb_rx);
+ }
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ end_tsc = rte_rdtsc();
+ core_cycles = (end_tsc - start_tsc);
+ fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
+#endif
+}
+
+
+struct fwd_engine csum_fwd_engine = {
+ .fwd_mode_name = "csum",
+ .port_fwd_begin = NULL,
+ .port_fwd_end = NULL,
+ .packet_fwd = pkt_burst_checksum_forward,
+};
+
diff --git a/app/test-pmd/ieee1588fwd.c b/app/test-pmd/ieee1588fwd.c
new file mode 100644
index 0000000..1fbc554
--- /dev/null
+++ b/app/test-pmd/ieee1588fwd.c
@@ -0,0 +1,657 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <sys/queue.h>
+#include <sys/stat.h>
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_ring.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_string_fns.h>
+
+#include "testpmd.h"
+
+/**
+ * The structure of a PTP V2 packet.
+ *
+ * Only the minimum fields used by the ieee1588 test are represented.
+ */
+struct ptpv2_msg {
+ uint8_t msg_id;
+ uint8_t version; /**< must be 0x02 */
+ uint8_t unused[34];
+};
+#define PTP_SYNC_MESSAGE 0x0
+#define PTP_DELAY_REQ_MESSAGE 0x1
+#define PTP_PATH_DELAY_REQ_MESSAGE 0x2
+#define PTP_PATH_DELAY_RESP_MESSAGE 0x3
+#define PTP_FOLLOWUP_MESSAGE 0x8
+#define PTP_DELAY_RESP_MESSAGE 0x9
+#define PTP_PATH_DELAY_FOLLOWUP_MESSAGE 0xA
+#define PTP_ANNOUNCE_MESSAGE 0xB
+#define PTP_SIGNALLING_MESSAGE 0xC
+#define PTP_MANAGEMENT_MESSAGE 0xD
+
+/*
+ * Forwarding of IEEE1588 Precise Time Protocol (PTP) packets.
+ *
+ * In this mode, packets are received one by one and are expected to be
+ * PTP V2 L2 Ethernet frames (with the specific Ethernet type "0x88F7")
+ * containing PTP "sync" messages (version 2 at offset 1, and message ID
+ * 0 at offset 0).
+ *
+ * Check that each received packet is a IEEE1588 PTP V2 packet of type
+ * PTP_SYNC_MESSAGE, and that it has been identified and timestamped
+ * by the hardware.
+ * Check that the value of the last RX timestamp recorded by the controller
+ * is greater than the previous one.
+ *
+ * If everything is OK, send the received packet back on the same port,
+ * requesting for it to be timestamped by the hardware.
+ * Check that the value of the last TX timestamp recorded by the controller
+ * is greater than the previous one.
+ */
+
+/*
+ * 1GbE 82576 Kawela registers used for IEEE1588 hardware support
+ */
+#define IGBE_82576_ETQF(n) (0x05CB0 + (4 * (n)))
+#define IGBE_82576_ETQF_FILTER_ENABLE (1 << 26)
+#define IGBE_82576_ETQF_1588_TIMESTAMP (1 << 30)
+
+#define IGBE_82576_TSYNCRXCTL 0x0B620
+#define IGBE_82576_TSYNCRXCTL_RXTS_ENABLE (1 << 4)
+
+#define IGBE_82576_RXSTMPL 0x0B624
+#define IGBE_82576_RXSTMPH 0x0B628
+#define IGBE_82576_RXSATRL 0x0B62C
+#define IGBE_82576_RXSATRH 0x0B630
+#define IGBE_82576_TSYNCTXCTL 0x0B614
+#define IGBE_82576_TSYNCTXCTL_TXTS_ENABLE (1 << 4)
+
+#define IGBE_82576_TXSTMPL 0x0B618
+#define IGBE_82576_TXSTMPH 0x0B61C
+#define IGBE_82576_SYSTIML 0x0B600
+#define IGBE_82576_SYSTIMH 0x0B604
+#define IGBE_82576_TIMINCA 0x0B608
+#define IGBE_82576_TIMADJL 0x0B60C
+#define IGBE_82576_TIMADJH 0x0B610
+#define IGBE_82576_TSAUXC 0x0B640
+#define IGBE_82576_TRGTTIML0 0x0B644
+#define IGBE_82576_TRGTTIMH0 0x0B648
+#define IGBE_82576_TRGTTIML1 0x0B64C
+#define IGBE_82576_TRGTTIMH1 0x0B650
+#define IGBE_82576_AUXSTMPL0 0x0B65C
+#define IGBE_82576_AUXSTMPH0 0x0B660
+#define IGBE_82576_AUXSTMPL1 0x0B664
+#define IGBE_82576_AUXSTMPH1 0x0B668
+#define IGBE_82576_TSYNCRXCFG 0x05F50
+#define IGBE_82576_TSSDP 0x0003C
+
+/*
+ * 10GbE 82599 Niantic registers used for IEEE1588 hardware support
+ */
+#define IXGBE_82599_ETQF(n) (0x05128 + (4 * (n)))
+#define IXGBE_82599_ETQF_FILTER_ENABLE (1 << 31)
+#define IXGBE_82599_ETQF_1588_TIMESTAMP (1 << 30)
+
+#define IXGBE_82599_TSYNCRXCTL 0x05188
+#define IXGBE_82599_TSYNCRXCTL_RXTS_ENABLE (1 << 4)
+
+#define IXGBE_82599_RXSTMPL 0x051E8
+#define IXGBE_82599_RXSTMPH 0x051A4
+#define IXGBE_82599_RXSATRL 0x051A0
+#define IXGBE_82599_RXSATRH 0x051A8
+#define IXGBE_82599_RXMTRL 0x05120
+#define IXGBE_82599_TSYNCTXCTL 0x08C00
+#define IXGBE_82599_TSYNCTXCTL_TXTS_ENABLE (1 << 4)
+
+#define IXGBE_82599_TXSTMPL 0x08C04
+#define IXGBE_82599_TXSTMPH 0x08C08
+#define IXGBE_82599_SYSTIML 0x08C0C
+#define IXGBE_82599_SYSTIMH 0x08C10
+#define IXGBE_82599_TIMINCA 0x08C14
+#define IXGBE_82599_TIMADJL 0x08C18
+#define IXGBE_82599_TIMADJH 0x08C1C
+#define IXGBE_82599_TSAUXC 0x08C20
+#define IXGBE_82599_TRGTTIML0 0x08C24
+#define IXGBE_82599_TRGTTIMH0 0x08C28
+#define IXGBE_82599_TRGTTIML1 0x08C2C
+#define IXGBE_82599_TRGTTIMH1 0x08C30
+#define IXGBE_82599_AUXSTMPL0 0x08C3C
+#define IXGBE_82599_AUXSTMPH0 0x08C40
+#define IXGBE_82599_AUXSTMPL1 0x08C44
+#define IXGBE_82599_AUXSTMPH1 0x08C48
+
+/**
+ * Mandatory ETQF register for IEEE1588 packets filter.
+ */
+#define ETQF_FILTER_1588_REG 3
+
+/**
+ * Recommended value for increment and period of
+ * the Increment Attribute Register.
+ */
+#define IEEE1588_TIMINCA_INIT ((0x02 << 24) | 0x00F42400)
+
+/**
+ * Data structure with pointers to port-specific functions.
+ */
+typedef void (*ieee1588_start_t)(portid_t pi); /**< Start IEEE1588 feature. */
+typedef void (*ieee1588_stop_t)(portid_t pi); /**< Stop IEEE1588 feature. */
+typedef int (*tmst_read_t)(portid_t pi, uint64_t *tmst); /**< Read TMST regs */
+
+struct port_ieee1588_ops {
+ ieee1588_start_t ieee1588_start;
+ ieee1588_stop_t ieee1588_stop;
+ tmst_read_t rx_tmst_read;
+ tmst_read_t tx_tmst_read;
+};
+
+/**
+ * 1GbE 82576 IEEE1588 operations.
+ */
+static void
+igbe_82576_ieee1588_start(portid_t pi)
+{
+ uint32_t tsync_ctl;
+
+ /*
+ * Start incrementation of the System Time registers used to
+ * timestamp PTP packets.
+ */
+ port_id_pci_reg_write(pi, IGBE_82576_TIMINCA, IEEE1588_TIMINCA_INIT);
+ port_id_pci_reg_write(pi, IGBE_82576_TSAUXC, 0);
+
+ /*
+ * Enable L2 filtering of IEEE1588 Ethernet frame types.
+ */
+ port_id_pci_reg_write(pi, IGBE_82576_ETQF(ETQF_FILTER_1588_REG),
+ (ETHER_TYPE_1588 |
+ IGBE_82576_ETQF_FILTER_ENABLE |
+ IGBE_82576_ETQF_1588_TIMESTAMP));
+
+ /*
+ * Enable timestamping of received PTP packets.
+ */
+ tsync_ctl = port_id_pci_reg_read(pi, IGBE_82576_TSYNCRXCTL);
+ tsync_ctl |= IGBE_82576_TSYNCRXCTL_RXTS_ENABLE;
+ port_id_pci_reg_write(pi, IGBE_82576_TSYNCRXCTL, tsync_ctl);
+
+ /*
+ * Enable Timestamping of transmitted PTP packets.
+ */
+ tsync_ctl = port_id_pci_reg_read(pi, IGBE_82576_TSYNCTXCTL);
+ tsync_ctl |= IGBE_82576_TSYNCTXCTL_TXTS_ENABLE;
+ port_id_pci_reg_write(pi, IGBE_82576_TSYNCTXCTL, tsync_ctl);
+}
+
+static void
+igbe_82576_ieee1588_stop(portid_t pi)
+{
+ uint32_t tsync_ctl;
+
+ /*
+ * Disable Timestamping of transmitted PTP packets.
+ */
+ tsync_ctl = port_id_pci_reg_read(pi, IGBE_82576_TSYNCTXCTL);
+ tsync_ctl &= ~IGBE_82576_TSYNCTXCTL_TXTS_ENABLE;
+ port_id_pci_reg_write(pi, IGBE_82576_TSYNCTXCTL, tsync_ctl);
+
+ /*
+ * Disable timestamping of received PTP packets.
+ */
+ tsync_ctl = port_id_pci_reg_read(pi, IGBE_82576_TSYNCRXCTL);
+ tsync_ctl &= ~IGBE_82576_TSYNCRXCTL_RXTS_ENABLE;
+ port_id_pci_reg_write(pi, IGBE_82576_TSYNCRXCTL, tsync_ctl);
+
+ /*
+ * Disable L2 filtering of IEEE1588 Ethernet types.
+ */
+ port_id_pci_reg_write(pi, IGBE_82576_ETQF(ETQF_FILTER_1588_REG), 0);
+
+ /*
+ * Stop incrementation of the System Time registers.
+ */
+ port_id_pci_reg_write(pi, IGBE_82576_TIMINCA, 0);
+}
+
+/**
+ * Return the 64-bit value contained in the RX IEEE1588 timestamp registers
+ * of a 1GbE 82576 port.
+ *
+ * @param pi
+ * The port identifier.
+ *
+ * @param tmst
+ * The address of a 64-bit variable to return the value of the RX timestamp.
+ *
+ * @return
+ * -1: the RXSTMPL and RXSTMPH registers of the port are not valid.
+ * 0: the variable pointed to by the "tmst" parameter contains the value
+ * of the RXSTMPL and RXSTMPH registers of the port.
+ */
+static int
+igbe_82576_rx_timestamp_read(portid_t pi, uint64_t *tmst)
+{
+ uint32_t tsync_rxctl;
+ uint32_t rx_stmpl;
+ uint32_t rx_stmph;
+
+ tsync_rxctl = port_id_pci_reg_read(pi, IGBE_82576_TSYNCRXCTL);
+ if ((tsync_rxctl & 0x01) == 0)
+ return (-1);
+
+ rx_stmpl = port_id_pci_reg_read(pi, IGBE_82576_RXSTMPL);
+ rx_stmph = port_id_pci_reg_read(pi, IGBE_82576_RXSTMPH);
+ *tmst = (uint64_t)(((uint64_t) rx_stmph << 32) | rx_stmpl);
+ return (0);
+}
+
+/**
+ * Return the 64-bit value contained in the TX IEEE1588 timestamp registers
+ * of a 1GbE 82576 port.
+ *
+ * @param pi
+ * The port identifier.
+ *
+ * @param tmst
+ * The address of a 64-bit variable to return the value of the TX timestamp.
+ *
+ * @return
+ * -1: the TXSTMPL and TXSTMPH registers of the port are not valid.
+ * 0: the variable pointed to by the "tmst" parameter contains the value
+ * of the TXSTMPL and TXSTMPH registers of the port.
+ */
+static int
+igbe_82576_tx_timestamp_read(portid_t pi, uint64_t *tmst)
+{
+ uint32_t tsync_txctl;
+ uint32_t tx_stmpl;
+ uint32_t tx_stmph;
+
+ tsync_txctl = port_id_pci_reg_read(pi, IGBE_82576_TSYNCTXCTL);
+ if ((tsync_txctl & 0x01) == 0)
+ return (-1);
+
+ tx_stmpl = port_id_pci_reg_read(pi, IGBE_82576_TXSTMPL);
+ tx_stmph = port_id_pci_reg_read(pi, IGBE_82576_TXSTMPH);
+ *tmst = (uint64_t)(((uint64_t) tx_stmph << 32) | tx_stmpl);
+ return (0);
+}
+
+static struct port_ieee1588_ops igbe_82576_ieee1588_ops = {
+ .ieee1588_start = igbe_82576_ieee1588_start,
+ .ieee1588_stop = igbe_82576_ieee1588_stop,
+ .rx_tmst_read = igbe_82576_rx_timestamp_read,
+ .tx_tmst_read = igbe_82576_tx_timestamp_read,
+};
+
+/**
+ * 10GbE 82599 IEEE1588 operations.
+ */
+static void
+ixgbe_82599_ieee1588_start(portid_t pi)
+{
+ uint32_t tsync_ctl;
+
+ /*
+ * Start incrementation of the System Time registers used to
+ * timestamp PTP packets.
+ */
+ port_id_pci_reg_write(pi, IXGBE_82599_TIMINCA, IEEE1588_TIMINCA_INIT);
+
+ /*
+ * Enable L2 filtering of IEEE1588 Ethernet frame types.
+ */
+ port_id_pci_reg_write(pi, IXGBE_82599_ETQF(ETQF_FILTER_1588_REG),
+ (ETHER_TYPE_1588 |
+ IXGBE_82599_ETQF_FILTER_ENABLE |
+ IXGBE_82599_ETQF_1588_TIMESTAMP));
+
+ /*
+ * Enable timestamping of received PTP packets.
+ */
+ tsync_ctl = port_id_pci_reg_read(pi, IXGBE_82599_TSYNCRXCTL);
+ tsync_ctl |= IXGBE_82599_TSYNCRXCTL_RXTS_ENABLE;
+ port_id_pci_reg_write(pi, IXGBE_82599_TSYNCRXCTL, tsync_ctl);
+
+ /*
+ * Enable Timestamping of transmitted PTP packets.
+ */
+ tsync_ctl = port_id_pci_reg_read(pi, IXGBE_82599_TSYNCTXCTL);
+ tsync_ctl |= IXGBE_82599_TSYNCTXCTL_TXTS_ENABLE;
+ port_id_pci_reg_write(pi, IXGBE_82599_TSYNCTXCTL, tsync_ctl);
+}
+
+static void
+ixgbe_82599_ieee1588_stop(portid_t pi)
+{
+ uint32_t tsync_ctl;
+
+ /*
+ * Disable Timestamping of transmitted PTP packets.
+ */
+ tsync_ctl = port_id_pci_reg_read(pi, IXGBE_82599_TSYNCTXCTL);
+ tsync_ctl &= ~IXGBE_82599_TSYNCTXCTL_TXTS_ENABLE;
+ port_id_pci_reg_write(pi, IXGBE_82599_TSYNCTXCTL, tsync_ctl);
+
+ /*
+ * Disable timestamping of received PTP packets.
+ */
+ tsync_ctl = port_id_pci_reg_read(pi, IXGBE_82599_TSYNCRXCTL);
+ tsync_ctl &= ~IXGBE_82599_TSYNCRXCTL_RXTS_ENABLE;
+ port_id_pci_reg_write(pi, IXGBE_82599_TSYNCRXCTL, tsync_ctl);
+
+ /*
+ * Disable L2 filtering of IEEE1588 Ethernet frame types.
+ */
+ port_id_pci_reg_write(pi, IXGBE_82599_ETQF(ETQF_FILTER_1588_REG), 0);
+
+ /*
+ * Stop incrementation of the System Time registers.
+ */
+ port_id_pci_reg_write(pi, IXGBE_82599_TIMINCA, 0);
+}
+
+/**
+ * Return the 64-bit value contained in the RX IEEE1588 timestamp registers
+ * of a 10GbE 82599 port.
+ *
+ * @param pi
+ * The port identifier.
+ *
+ * @param tmst
+ * The address of a 64-bit variable to return the value of the TX timestamp.
+ *
+ * @return
+ * -1: the RX timestamp registers of the port are not valid.
+ * 0: the variable pointed to by the "tmst" parameter contains the value
+ * of the RXSTMPL and RXSTMPH registers of the port.
+ */
+static int
+ixgbe_82599_rx_timestamp_read(portid_t pi, uint64_t *tmst)
+{
+ uint32_t tsync_rxctl;
+ uint32_t rx_stmpl;
+ uint32_t rx_stmph;
+
+ tsync_rxctl = port_id_pci_reg_read(pi, IXGBE_82599_TSYNCRXCTL);
+ if ((tsync_rxctl & 0x01) == 0)
+ return (-1);
+
+ rx_stmpl = port_id_pci_reg_read(pi, IXGBE_82599_RXSTMPL);
+ rx_stmph = port_id_pci_reg_read(pi, IXGBE_82599_RXSTMPH);
+ *tmst = (uint64_t)(((uint64_t) rx_stmph << 32) | rx_stmpl);
+ return (0);
+}
+
+/**
+ * Return the 64-bit value contained in the TX IEEE1588 timestamp registers
+ * of a 10GbE 82599 port.
+ *
+ * @param pi
+ * The port identifier.
+ *
+ * @param tmst
+ * The address of a 64-bit variable to return the value of the TX timestamp.
+ *
+ * @return
+ * -1: the TXSTMPL and TXSTMPH registers of the port are not valid.
+ * 0: the variable pointed to by the "tmst" parameter contains the value
+ * of the TXSTMPL and TXSTMPH registers of the port.
+ */
+static int
+ixgbe_82599_tx_timestamp_read(portid_t pi, uint64_t *tmst)
+{
+ uint32_t tsync_txctl;
+ uint32_t tx_stmpl;
+ uint32_t tx_stmph;
+
+ tsync_txctl = port_id_pci_reg_read(pi, IXGBE_82599_TSYNCTXCTL);
+ if ((tsync_txctl & 0x01) == 0)
+ return (-1);
+
+ tx_stmpl = port_id_pci_reg_read(pi, IXGBE_82599_TXSTMPL);
+ tx_stmph = port_id_pci_reg_read(pi, IXGBE_82599_TXSTMPH);
+ *tmst = (uint64_t)(((uint64_t) tx_stmph << 32) | tx_stmpl);
+ return (0);
+}
+
+static struct port_ieee1588_ops ixgbe_82599_ieee1588_ops = {
+ .ieee1588_start = ixgbe_82599_ieee1588_start,
+ .ieee1588_stop = ixgbe_82599_ieee1588_stop,
+ .rx_tmst_read = ixgbe_82599_rx_timestamp_read,
+ .tx_tmst_read = ixgbe_82599_tx_timestamp_read,
+};
+
+static void
+port_ieee1588_rx_timestamp_check(portid_t pi)
+{
+ struct port_ieee1588_ops *ieee_ops;
+ uint64_t rx_tmst;
+
+ ieee_ops = (struct port_ieee1588_ops *)ports[pi].fwd_ctx;
+ if (ieee_ops->rx_tmst_read(pi, &rx_tmst) < 0) {
+ printf("Port %u: RX timestamp registers not valid\n",
+ (unsigned) pi);
+ return;
+ }
+ printf("Port %u RX timestamp value 0x%"PRIu64"\n",
+ (unsigned) pi, rx_tmst);
+}
+
+#define MAX_TX_TMST_WAIT_MICROSECS 1000 /**< 1 milli-second */
+
+static void
+port_ieee1588_tx_timestamp_check(portid_t pi)
+{
+ struct port_ieee1588_ops *ieee_ops;
+ uint64_t tx_tmst;
+ unsigned wait_us;
+
+ ieee_ops = (struct port_ieee1588_ops *)ports[pi].fwd_ctx;
+ wait_us = 0;
+ while ((ieee_ops->tx_tmst_read(pi, &tx_tmst) < 0) &&
+ (wait_us < MAX_TX_TMST_WAIT_MICROSECS)) {
+ rte_delay_us(1);
+ wait_us++;
+ }
+ if (wait_us >= MAX_TX_TMST_WAIT_MICROSECS) {
+ printf("Port %u: TX timestamp registers not valid after"
+ "%u micro-seconds\n",
+ (unsigned) pi, (unsigned) MAX_TX_TMST_WAIT_MICROSECS);
+ return;
+ }
+ printf("Port %u TX timestamp value 0x%"PRIu64" validated after "
+ "%u micro-second%s\n",
+ (unsigned) pi, tx_tmst, wait_us,
+ (wait_us == 1) ? "" : "s");
+}
+
+static void
+ieee1588_packet_fwd(struct fwd_stream *fs)
+{
+ struct rte_mbuf *mb;
+ struct ether_hdr *eth_hdr;
+ struct ptpv2_msg *ptp_hdr;
+ uint16_t eth_type;
+
+ /*
+ * Receive 1 packet at a time.
+ */
+ if (rte_eth_rx_burst(fs->rx_port, fs->rx_queue, &mb, 1) == 0)
+ return;
+
+ fs->rx_packets += 1;
+
+ /*
+ * Check that the received packet is a PTP packet that was detected
+ * by the hardware.
+ */
+ eth_hdr = (struct ether_hdr *)mb->pkt.data;
+ eth_type = rte_be_to_cpu_16(eth_hdr->ether_type);
+ if (! (mb->ol_flags & PKT_RX_IEEE1588_PTP)) {
+ if (eth_type == ETHER_TYPE_1588) {
+ printf("Port %u Received PTP packet not filtered"
+ " by hardware\n",
+ (unsigned) fs->rx_port);
+ } else {
+ printf("Port %u Received non PTP packet type=0x%4x "
+ "len=%u\n",
+ (unsigned) fs->rx_port, eth_type,
+ (unsigned) mb->pkt.pkt_len);
+ }
+ rte_pktmbuf_free(mb);
+ return;
+ }
+ if (eth_type != ETHER_TYPE_1588) {
+ printf("Port %u Received NON PTP packet wrongly"
+ " detected by hardware\n",
+ (unsigned) fs->rx_port);
+ rte_pktmbuf_free(mb);
+ return;
+ }
+
+ /*
+ * Check that the received PTP packet is a PTP V2 packet of type
+ * PTP_SYNC_MESSAGE.
+ */
+ ptp_hdr = (struct ptpv2_msg *) ((char *) mb->pkt.data +
+ sizeof(struct ether_hdr));
+ if (ptp_hdr->version != 0x02) {
+ printf("Port %u Received PTP V2 Ethernet frame with wrong PTP"
+ " protocol version 0x%x (should be 0x02)\n",
+ (unsigned) fs->rx_port, ptp_hdr->version);
+ rte_pktmbuf_free(mb);
+ return;
+ }
+ if (ptp_hdr->msg_id != PTP_SYNC_MESSAGE) {
+ printf("Port %u Received PTP V2 Ethernet frame with unexpected"
+ " messageID 0x%x (expected 0x0 - PTP_SYNC_MESSAGE)\n",
+ (unsigned) fs->rx_port, ptp_hdr->msg_id);
+ rte_pktmbuf_free(mb);
+ return;
+ }
+ printf("Port %u IEEE1588 PTP V2 SYNC Message filtered by hardware\n",
+ (unsigned) fs->rx_port);
+
+ /*
+ * Check that the received PTP packet has been timestamped by the
+ * hardware.
+ */
+ if (! (mb->ol_flags & PKT_RX_IEEE1588_TMST)) {
+ printf("Port %u Received PTP packet not timestamped"
+ " by hardware\n",
+ (unsigned) fs->rx_port);
+ rte_pktmbuf_free(mb);
+ return;
+ }
+
+ /* Check the RX timestamp */
+ port_ieee1588_rx_timestamp_check(fs->rx_port);
+
+ /* Forward PTP packet with hardware TX timestamp */
+ mb->ol_flags |= PKT_TX_IEEE1588_TMST;
+ fs->tx_packets += 1;
+ if (rte_eth_tx_burst(fs->rx_port, fs->tx_queue, &mb, 1) == 0) {
+ printf("Port %u sent PTP packet dropped\n",
+ (unsigned) fs->rx_port);
+ fs->fwd_dropped += 1;
+ rte_pktmbuf_free(mb);
+ return;
+ }
+
+ /*
+ * Check the TX timestamp.
+ */
+ port_ieee1588_tx_timestamp_check(fs->rx_port);
+}
+
+static void
+port_ieee1588_fwd_begin(portid_t pi)
+{
+ struct port_ieee1588_ops *ieee_ops;
+
+ if (strcmp(ports[pi].dev_info.driver_name, "rte_igb_pmd") == 0)
+ ieee_ops = &igbe_82576_ieee1588_ops;
+ else
+ ieee_ops = &ixgbe_82599_ieee1588_ops;
+ ports[pi].fwd_ctx = ieee_ops;
+ (ieee_ops->ieee1588_start)(pi);
+}
+
+static void
+port_ieee1588_fwd_end(portid_t pi)
+{
+ struct port_ieee1588_ops *ieee_ops;
+
+ ieee_ops = (struct port_ieee1588_ops *)ports[pi].fwd_ctx;
+ (ieee_ops->ieee1588_stop)(pi);
+}
+
+struct fwd_engine ieee1588_fwd_engine = {
+ .fwd_mode_name = "ieee1588",
+ .port_fwd_begin = port_ieee1588_fwd_begin,
+ .port_fwd_end = port_ieee1588_fwd_end,
+ .packet_fwd = ieee1588_packet_fwd,
+};
diff --git a/app/test-pmd/iofwd.c b/app/test-pmd/iofwd.c
new file mode 100644
index 0000000..3f29f6d
--- /dev/null
+++ b/app/test-pmd/iofwd.c
@@ -0,0 +1,131 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <sys/queue.h>
+#include <sys/stat.h>
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_ring.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_string_fns.h>
+
+#include "testpmd.h"
+
+/*
+ * Forwarding of packets in I/O mode.
+ * Forward packets "as-is".
+ * This is the fastest possible forwarding operation, as it does not access
+ * to packets data.
+ */
+static void
+pkt_burst_io_forward(struct fwd_stream *fs)
+{
+ struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+ uint16_t nb_rx;
+ uint16_t nb_tx;
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ uint64_t start_tsc;
+ uint64_t end_tsc;
+ uint64_t core_cycles;
+#endif
+
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ start_tsc = rte_rdtsc();
+#endif
+
+ /*
+ * Receive a burst of packets and forward them.
+ */
+ nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
+ nb_pkt_per_burst);
+ if (unlikely(nb_rx == 0))
+ return;
+
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
+#endif
+ fs->rx_packets += nb_rx;
+ nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx);
+ fs->tx_packets += nb_tx;
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ fs->tx_burst_stats.pkt_burst_spread[nb_tx]++;
+#endif
+ if (unlikely(nb_tx < nb_rx)) {
+ fs->fwd_dropped += (nb_rx - nb_tx);
+ do {
+ rte_pktmbuf_free(pkts_burst[nb_tx]);
+ } while (++nb_tx < nb_rx);
+ }
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ end_tsc = rte_rdtsc();
+ core_cycles = (end_tsc - start_tsc);
+ fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
+#endif
+}
+
+struct fwd_engine io_fwd_engine = {
+ .fwd_mode_name = "io",
+ .port_fwd_begin = NULL,
+ .port_fwd_end = NULL,
+ .packet_fwd = pkt_burst_io_forward,
+};
diff --git a/app/test-pmd/macfwd.c b/app/test-pmd/macfwd.c
new file mode 100644
index 0000000..8f31e05
--- /dev/null
+++ b/app/test-pmd/macfwd.c
@@ -0,0 +1,148 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <sys/queue.h>
+#include <sys/stat.h>
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_ring.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_ip.h>
+#include <rte_string_fns.h>
+
+#include "testpmd.h"
+
+/*
+ * Forwarding of packets in MAC mode.
+ * Change the source and the destination Ethernet addressed of packets
+ * before forwarding them.
+ */
+static void
+pkt_burst_mac_forward(struct fwd_stream *fs)
+{
+ struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+ struct rte_port *txp;
+ struct rte_mbuf *mb;
+ struct ether_hdr *eth_hdr;
+ uint16_t nb_rx;
+ uint16_t nb_tx;
+ uint16_t i;
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ uint64_t start_tsc;
+ uint64_t end_tsc;
+ uint64_t core_cycles;
+#endif
+
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ start_tsc = rte_rdtsc();
+#endif
+
+ /*
+ * Receive a burst of packets and forward them.
+ */
+ nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
+ nb_pkt_per_burst);
+ if (unlikely(nb_rx == 0))
+ return;
+
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
+#endif
+ fs->rx_packets += nb_rx;
+ txp = &ports[fs->tx_port];
+ for (i = 0; i < nb_rx; i++) {
+ mb = pkts_burst[i];
+ eth_hdr = (struct ether_hdr *) mb->pkt.data;
+ ether_addr_copy(&peer_eth_addrs[fs->peer_addr],
+ &eth_hdr->d_addr);
+ ether_addr_copy(&ports[fs->tx_port].eth_addr,
+ &eth_hdr->s_addr);
+ mb->ol_flags = txp->tx_ol_flags;
+ mb->pkt.l2_len = sizeof(struct ether_hdr);
+ mb->pkt.l3_len = sizeof(struct ipv4_hdr);
+ mb->pkt.vlan_tci = txp->tx_vlan_id;
+ }
+ nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx);
+ fs->tx_packets += nb_tx;
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ fs->tx_burst_stats.pkt_burst_spread[nb_tx]++;
+#endif
+ if (unlikely(nb_tx < nb_rx)) {
+ fs->fwd_dropped += (nb_rx - nb_tx);
+ do {
+ rte_pktmbuf_free(pkts_burst[nb_tx]);
+ } while (++nb_tx < nb_rx);
+ }
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ end_tsc = rte_rdtsc();
+ core_cycles = (end_tsc - start_tsc);
+ fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
+#endif
+}
+
+struct fwd_engine mac_fwd_engine = {
+ .fwd_mode_name = "mac",
+ .port_fwd_begin = NULL,
+ .port_fwd_end = NULL,
+ .packet_fwd = pkt_burst_mac_forward,
+};
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
new file mode 100644
index 0000000..4c559ef
--- /dev/null
+++ b/app/test-pmd/parameters.c
@@ -0,0 +1,646 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <errno.h>
+#include <getopt.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#include <sys/queue.h>
+#include <sys/stat.h>
+
+#include <stdint.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_string_fns.h>
+#include <cmdline_parse.h>
+#include <cmdline_parse_etheraddr.h>
+
+#include "testpmd.h"
+
+static void
+usage(char* progname)
+{
+ printf("usage: %s [--interactive|-i] [--help|-h] | ["
+ "--coremask=COREMASK --portmask=PORTMASK --numa "
+ "--eth-peers-configfile= | "
+ "--eth-peer=X,M:M:M:M:M:M | --nb-cores= | --nb-ports= | "
+ "--pkt-filter-mode= |"
+ "--rss-ip | --rss-udp | "
+ "--rxpt= | --rxht= | --rxwt= | --rxfreet= | "
+ "--txpt= | --txht= | --txwt= | --txfreet= | "
+ "--txrst= ]\n",
+ progname);
+ printf(" --interactive: run in interactive mode\n");
+ printf(" --help: display this message and quit\n");
+ printf(" --eth-peers-configfile=name of file with ethernet addresses "
+ "of peer ports\n");
+ printf(" --eth-peer=X,M:M:M:M:M:M set the mac address of the X peer "
+ "port (0 <= X < %d)\n", RTE_MAX_ETHPORTS);
+ printf(" --nb-cores=N set the number of forwarding cores"
+ " (1 <= N <= %d)\n", nb_lcores);
+ printf(" --nb-ports=N set the number of forwarding ports"
+ " (1 <= N <= %d)\n", nb_ports);
+ printf(" --coremask=COREMASK: hexadecimal bitmask of cores running "
+ "the packet forwarding test\n");
+ printf(" --portmask=PORTMASK: hexadecimal bitmask of ports used "
+ "by the packet forwarding test\n");
+ printf(" --numa: enable NUMA-aware allocation of RX/TX rings and of "
+ " RX memory buffers (mbufs)\n");
+ printf(" --mbuf-size=N set the data size of mbuf to N bytes\n");
+ printf(" --max-pkt-len=N set the maximum size of packet to N bytes\n");
+ printf(" --pkt-filter-mode=N: set Flow director mode "
+ "( N: none (default mode) or signature or perfect)\n");
+ printf(" --pkt-filter-report-hash=N: set Flow director report mode "
+ "( N: none or match (default) or always)\n");
+ printf(" --pkt-filter-size=N: set Flow director mode "
+ "( N: 64K (default mode) or 128K or 256K)\n");
+ printf(" --pkt-filter-flexbytes-offset=N: set flexbytes-offset."
+ " The offset is defined in word units counted from the"
+ " first byte of the destination Ethernet MAC address."
+ " 0 <= N <= 32\n");
+ printf(" --pkt-filter-drop-queue=N: set drop-queue."
+ " In perfect mode, when you add a rule with queue -1"
+ " the packet will be enqueued into the rx drop-queue."
+ " If the drop-queue doesn't exist, the packet is dropped."
+ " By default drop-queue=127\n");
+ printf(" --crc-strip: enable CRC stripping by hardware\n");
+ printf(" --enable-rx-cksum: enable rx hardware checksum offload\n");
+ printf(" --disable-hw-vlan: disable hardware vlan\n");
+ printf(" --disable-rss: disable rss\n");
+ printf(" --port-topology=N: set port topology (N: paired (default) or "
+ "chained)\n");
+ printf(" --rss-ip: set RSS functions to IPv4/IPv6 only \n");
+ printf(" --rss-udp: set RSS functions to IPv4/IPv6 + UDP\n");
+ printf(" --rxq=N set the number of RX queues per port to N\n");
+ printf(" --rxd=N set the number of descriptors in RX rings to N\n");
+ printf(" --txq=N set the number of TX queues per port to N\n");
+ printf(" --txd=N set the number of descriptors in TX rings to N\n");
+ printf(" --burst=N set the number of packets per burst to N\n");
+ printf(" --mbcache=N set the cache of mbuf memory pool to N\n");
+ printf(" --rxpt=N set prefetch threshold register of RX rings to N"
+ " (0 <= N <= 16)\n");
+ printf(" --rxht=N set the host threshold register of RX rings to N"
+ " (0 <= N <= 16)\n");
+ printf(" --rxfreet=N set the free threshold of RX descriptors to N"
+ " (0 <= N < value of rxd)\n");
+ printf(" --rxwt=N set the write-back threshold register of RX rings"
+ " to N (0 <= N <= 16)\n");
+ printf(" --txpt=N set the prefetch threshold register of TX rings"
+ " to N (0 <= N <= 16)\n");
+ printf(" --txht=N set the nhost threshold register of TX rings to N"
+ " (0 <= N <= 16)\n");
+ printf(" --txwt=N set the write-back threshold register of TX rings"
+ " to N (0 <= N <= 16)\n");
+ printf(" --txfreet=N set the transmit free threshold of TX rings to N"
+ " (0 <= N <= value of txd)\n");
+ printf(" --txrst=N set the transmit RS bit threshold of TX rings to N"
+ " (0 <= N <= value of txd)\n");
+}
+
+static int
+init_peer_eth_addrs(char *config_filename)
+{
+ FILE *config_file;
+ portid_t i;
+ char buf[50];
+
+ config_file = fopen(config_filename, "r");
+ if (config_file == NULL) {
+ perror("open log file failed\n");
+ return -1;
+ }
+
+ for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+
+ if (fgets(buf, sizeof(buf), config_file) == NULL)
+ break;
+
+ if (cmdline_parse_etheraddr(NULL, buf, &peer_eth_addrs[i]) < 0 ){
+ printf("bad format of mac address on line %d\n", i);
+ fclose(config_file);
+ return -1;
+ }
+ }
+ fclose(config_file);
+ nb_peer_eth_addrs = (portid_t) i;
+ return 0;
+}
+
+/*
+ * Parse the coremask given as argument (hexadecimal string) and set
+ * the global configuration of forwarding cores.
+ */
+static void
+parse_fwd_coremask(const char *coremask)
+{
+ char *end;
+ unsigned long long int cm;
+
+ /* parse hexadecimal string */
+ end = NULL;
+ cm = strtoull(coremask, &end, 16);
+ if ((coremask[0] == '\0') || (end == NULL) || (*end != '\0'))
+ rte_exit(EXIT_FAILURE, "Invalid fwd core mask\n");
+ else
+ set_fwd_lcores_mask((uint64_t) cm);
+}
+
+/*
+ * Parse the coremask given as argument (hexadecimal string) and set
+ * the global configuration of forwarding cores.
+ */
+static void
+parse_fwd_portmask(const char *portmask)
+{
+ char *end;
+ unsigned long long int pm;
+
+ /* parse hexadecimal string */
+ end = NULL;
+ pm = strtoull(portmask, &end, 16);
+ if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
+ rte_exit(EXIT_FAILURE, "Invalid fwd port mask\n");
+ else
+ set_fwd_ports_mask((uint64_t) pm);
+}
+
+void
+launch_args_parse(int argc, char** argv)
+{
+ int n, opt;
+ char **argvopt;
+ int opt_idx;
+ static struct option lgopts[] = {
+ { "help", 0, 0, 0 },
+ { "interactive", 0, 0, 0 },
+ { "eth-peers-configfile", 1, 0, 0 },
+ { "eth-peer", 1, 0, 0 },
+ { "ports", 1, 0, 0 },
+ { "nb-cores", 1, 0, 0 },
+ { "nb-ports", 1, 0, 0 },
+ { "coremask", 1, 0, 0 },
+ { "portmask", 1, 0, 0 },
+ { "numa", 0, 0, 0 },
+ { "mbuf-size", 1, 0, 0 },
+ { "max-pkt-len", 1, 0, 0 },
+ { "pkt-filter-mode", 1, 0, 0 },
+ { "pkt-filter-report-hash", 1, 0, 0 },
+ { "pkt-filter-size", 1, 0, 0 },
+ { "pkt-filter-flexbytes-offset",1, 0, 0 },
+ { "pkt-filter-drop-queue", 1, 0, 0 },
+ { "crc-strip", 0, 0, 0 },
+ { "disable-hw-vlan", 0, 0, 0 },
+ { "disable-rss", 0, 0, 0 },
+ { "port-topology", 1, 0, 0 },
+ { "rss-ip", 0, 0, 0 },
+ { "rss-udp", 0, 0, 0 },
+ { "rxq", 1, 0, 0 },
+ { "txq", 1, 0, 0 },
+ { "rxd", 1, 0, 0 },
+ { "txd", 1, 0, 0 },
+ { "burst", 1, 0, 0 },
+ { "mbcache", 1, 0, 0 },
+ { "txpt", 1, 0, 0 },
+ { "txht", 1, 0, 0 },
+ { "txwt", 1, 0, 0 },
+ { "txfreet", 1, 0, 0 },
+ { "txrst", 1, 0, 0 },
+ { "rxpt", 1, 0, 0 },
+ { "rxht", 1, 0, 0 },
+ { "rxwt", 1, 0, 0 },
+ { "rxfreet", 1, 0, 0 },
+ { 0, 0, 0, 0 },
+ };
+
+ argvopt = argv;
+
+ while ((opt = getopt_long(argc, argvopt, "ih",
+ lgopts, &opt_idx)) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+ case 0: /*long options */
+ if (!strcmp(lgopts[opt_idx].name, "help")) {
+ usage(argv[0]);
+ rte_exit(EXIT_SUCCESS, "Displayed help\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "interactive")) {
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ }
+ if (!strcmp(lgopts[opt_idx].name,
+ "eth-peers-configfile")) {
+ if (init_peer_eth_addrs(optarg) != 0)
+ rte_exit(EXIT_FAILURE,
+ "Cannot open logfile\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
+ char *port_end;
+ uint8_t c, peer_addr[6];
+
+ errno = 0;
+ n = strtoul(optarg, &port_end, 10);
+ if (errno != 0 || port_end == optarg || *port_end++ != ',')
+ rte_exit(EXIT_FAILURE,
+ "Invalid eth-peer: %s", optarg);
+ if (n >= RTE_MAX_ETHPORTS)
+ rte_exit(EXIT_FAILURE,
+ "eth-peer: port %d >= RTE_MAX_ETHPORTS(%d)\n",
+ n, RTE_MAX_ETHPORTS);
+
+ if (cmdline_parse_etheraddr(NULL, port_end, &peer_addr) < 0 )
+ rte_exit(EXIT_FAILURE,
+ "Invalid ethernet address: %s\n",
+ port_end);
+ for (c = 0; c < 6; c++)
+ peer_eth_addrs[n].addr_bytes[c] =
+ peer_addr[c];
+ nb_peer_eth_addrs++;
+ }
+ if (!strcmp(lgopts[opt_idx].name, "nb-ports")) {
+ n = atoi(optarg);
+ if (n > 0 && n <= nb_ports)
+ nb_fwd_ports = (uint8_t) n;
+ else
+ rte_exit(EXIT_FAILURE,
+ "nb-ports should be > 0 and <= %d\n",
+ nb_ports);
+ }
+ if (!strcmp(lgopts[opt_idx].name, "nb-cores")) {
+ n = atoi(optarg);
+ if (n > 0 && n <= nb_lcores)
+ nb_fwd_lcores = (uint8_t) n;
+ else
+ rte_exit(EXIT_FAILURE,
+ "nb-cores should be > 0 and <= %d\n",
+ nb_lcores);
+ }
+ if (!strcmp(lgopts[opt_idx].name, "coremask"))
+ parse_fwd_coremask(optarg);
+ if (!strcmp(lgopts[opt_idx].name, "portmask"))
+ parse_fwd_portmask(optarg);
+ if (!strcmp(lgopts[opt_idx].name, "numa"))
+ numa_support = 1;
+ if (!strcmp(lgopts[opt_idx].name, "mbuf-size")) {
+ n = atoi(optarg);
+ if (n > 0 && n <= 0xFFFF)
+ mbuf_data_size = (uint16_t) n;
+ else
+ rte_exit(EXIT_FAILURE,
+ "mbuf-size should be > 0 and < 65536\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "max-pkt-len")) {
+ n = atoi(optarg);
+ if (n >= ETHER_MIN_LEN) {
+ rx_mode.max_rx_pkt_len = (uint32_t) n;
+ if (n > ETHER_MAX_LEN)
+ rx_mode.jumbo_frame = 1;
+ } else
+ rte_exit(EXIT_FAILURE,
+ "Invalid max-pkt-len=%d - should be > %d\n",
+ n, ETHER_MIN_LEN);
+ }
+ if (!strcmp(lgopts[opt_idx].name, "pkt-filter-mode")) {
+ if (!strcmp(optarg, "signature"))
+ fdir_conf.mode =
+ RTE_FDIR_MODE_SIGNATURE;
+ else if (!strcmp(optarg, "perfect"))
+ fdir_conf.mode = RTE_FDIR_MODE_PERFECT;
+ else if (!strcmp(optarg, "none"))
+ fdir_conf.mode = RTE_FDIR_MODE_NONE;
+ else
+ rte_exit(EXIT_FAILURE,
+ "pkt-mode-invalid %s invalid - must be: "
+ "none, signature or perfect\n",
+ optarg);
+ }
+ if (!strcmp(lgopts[opt_idx].name,
+ "pkt-filter-report-hash")) {
+ if (!strcmp(optarg, "none"))
+ fdir_conf.status =
+ RTE_FDIR_NO_REPORT_STATUS;
+ else if (!strcmp(optarg, "match"))
+ fdir_conf.status =
+ RTE_FDIR_REPORT_STATUS;
+ else if (!strcmp(optarg, "always"))
+ fdir_conf.status =
+ RTE_FDIR_REPORT_STATUS_ALWAYS;
+ else
+ rte_exit(EXIT_FAILURE,
+ "pkt-filter-report-hash %s invalid "
+ "- must be: none or match or always\n",
+ optarg);
+ }
+ if (!strcmp(lgopts[opt_idx].name, "pkt-filter-size")) {
+ if (!strcmp(optarg, "64K"))
+ fdir_conf.pballoc =
+ RTE_FDIR_PBALLOC_64K;
+ else if (!strcmp(optarg, "128K"))
+ fdir_conf.pballoc =
+ RTE_FDIR_PBALLOC_128K;
+ else if (!strcmp(optarg, "256K"))
+ fdir_conf.pballoc =
+ RTE_FDIR_PBALLOC_256K;
+ else
+ rte_exit(EXIT_FAILURE, "pkt-filter-size %s invalid -"
+ " must be: 64K or 128K or 256K\n",
+ optarg);
+ }
+ if (!strcmp(lgopts[opt_idx].name,
+ "pkt-filter-flexbytes-offset")) {
+ n = atoi(optarg);
+ if ( n >= 0 && n <= (int) 32)
+ fdir_conf.flexbytes_offset =
+ (uint8_t) n;
+ else
+ rte_exit(EXIT_FAILURE,
+ "flexbytes %d invalid - must"
+ "be >= 0 && <= 32\n", n);
+ }
+ if (!strcmp(lgopts[opt_idx].name,
+ "pkt-filter-drop-queue")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ fdir_conf.drop_queue = (uint8_t) n;
+ else
+ rte_exit(EXIT_FAILURE,
+ "drop queue %d invalid - must"
+ "be >= 0 \n", n);
+ }
+ if (!strcmp(lgopts[opt_idx].name, "crc-strip"))
+ rx_mode.hw_strip_crc = 1;
+ if (!strcmp(lgopts[opt_idx].name, "enable-rx-cksum"))
+ rx_mode.hw_ip_checksum = 1;
+ if (!strcmp(lgopts[opt_idx].name, "disable-hw-vlan"))
+ rx_mode.hw_vlan_filter = 0;
+ if (!strcmp(lgopts[opt_idx].name, "disable-rss"))
+ rss_hf = 0;
+ if (!strcmp(lgopts[opt_idx].name, "port-topology")) {
+ if (!strcmp(optarg, "paired"))
+ port_topology = PORT_TOPOLOGY_PAIRED;
+ else if (!strcmp(optarg, "chained"))
+ port_topology = PORT_TOPOLOGY_CHAINED;
+ else
+ rte_exit(EXIT_FAILURE, "port-topology %s invalid -"
+ " must be: paired or chained \n",
+ optarg);
+ }
+ if (!strcmp(lgopts[opt_idx].name, "rss-ip"))
+ rss_hf = ETH_RSS_IPV4 | ETH_RSS_IPV6;
+ if (!strcmp(lgopts[opt_idx].name, "rss-udp"))
+ rss_hf = ETH_RSS_IPV4 | ETH_RSS_IPV6 |
+ ETH_RSS_IPV4_UDP;
+ if (!strcmp(lgopts[opt_idx].name, "rxq")) {
+ n = atoi(optarg);
+ if (n >= 1 && n <= (int) MAX_QUEUE_ID)
+ nb_rxq = (queueid_t) n;
+ else
+ rte_exit(EXIT_FAILURE, "rxq %d invalid - must be"
+ " >= 1 && <= %d\n", n,
+ (int) MAX_QUEUE_ID);
+ }
+ if (!strcmp(lgopts[opt_idx].name, "txq")) {
+ n = atoi(optarg);
+ if (n >= 1 && n <= (int) MAX_QUEUE_ID)
+ nb_txq = (queueid_t) n;
+ else
+ rte_exit(EXIT_FAILURE, "txq %d invalid - must be"
+ " >= 1 && <= %d\n", n,
+ (int) MAX_QUEUE_ID);
+ }
+ if (!strcmp(lgopts[opt_idx].name, "rxd")) {
+ n = atoi(optarg);
+ if (n > 0)
+ nb_rxd = (uint16_t) n;
+ else
+ rte_exit(EXIT_FAILURE, "rxd must be > 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "txd")) {
+ n = atoi(optarg);
+ if (n > 0)
+ nb_txd = (uint16_t) n;
+ else
+ rte_exit(EXIT_FAILURE, "txd must be in > 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "burst")) {
+ n = atoi(optarg);
+ if ((n >= 1) && (n <= MAX_PKT_BURST))
+ nb_pkt_per_burst = (uint16_t) n;
+ else
+ rte_exit(EXIT_FAILURE,
+ "burst must >= 1 and <= %d]",
+ MAX_PKT_BURST);
+ }
+ if (!strcmp(lgopts[opt_idx].name, "mbcache")) {
+ n = atoi(optarg);
+ if ((n >= 0) &&
+ (n <= RTE_MEMPOOL_CACHE_MAX_SIZE))
+ mb_mempool_cache = (uint16_t) n;
+ else
+ rte_exit(EXIT_FAILURE,
+ "mbcache must be >= 0 and <= %d\n",
+ RTE_MEMPOOL_CACHE_MAX_SIZE);
+ }
+ if (!strcmp(lgopts[opt_idx].name, "txpt")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ tx_thresh.pthresh = (uint8_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "txpt must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "txht")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ tx_thresh.hthresh = (uint8_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "txht must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "txwt")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ tx_thresh.wthresh = (uint8_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "txwt must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "txfreet")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ tx_free_thresh = (uint16_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "txfreet must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "txrst")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ tx_rs_thresh = (uint16_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "txrst must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "rxpt")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ rx_thresh.pthresh = (uint8_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "rxpt must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "rxht")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ rx_thresh.hthresh = (uint8_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "rxht must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "rxwt")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ rx_thresh.wthresh = (uint8_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "rxwt must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "rxd")) {
+ n = atoi(optarg);
+ if (n > 0) {
+ if (rx_free_thresh >= n)
+ rte_exit(EXIT_FAILURE,
+ "rxd must be > "
+ "rx_free_thresh(%d)\n",
+ (int)rx_free_thresh);
+ else
+ nb_rxd = (uint16_t) n;
+ } else
+ rte_exit(EXIT_FAILURE,
+ "rxd(%d) invalid - must be > 0\n",
+ n);
+ }
+ if (!strcmp(lgopts[opt_idx].name, "txd")) {
+ n = atoi(optarg);
+ if (n > 0)
+ nb_txd = (uint16_t) n;
+ else
+ rte_exit(EXIT_FAILURE, "txd must be in > 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "txpt")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ tx_thresh.pthresh = (uint8_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "txpt must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "txht")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ tx_thresh.hthresh = (uint8_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "txht must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "txwt")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ tx_thresh.wthresh = (uint8_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "txwt must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "rxpt")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ rx_thresh.pthresh = (uint8_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "rxpt must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "rxht")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ rx_thresh.hthresh = (uint8_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "rxht must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "rxwt")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ rx_thresh.wthresh = (uint8_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "rxwt must be >= 0\n");
+ }
+ if (!strcmp(lgopts[opt_idx].name, "rxfreet")) {
+ n = atoi(optarg);
+ if (n >= 0)
+ rx_free_thresh = (uint16_t)n;
+ else
+ rte_exit(EXIT_FAILURE, "rxfreet must be >= 0\n");
+ }
+ break;
+ case 'h':
+ usage(argv[0]);
+ rte_exit(EXIT_SUCCESS, "Displayed help\n");
+ break;
+ default:
+ usage(argv[0]);
+ rte_exit(EXIT_FAILURE,
+ "Command line is incomplete or incorrect\n");
+ break;
+ }
+ }
+}
diff --git a/app/test-pmd/rxonly.c b/app/test-pmd/rxonly.c
new file mode 100644
index 0000000..d1b1289
--- /dev/null
+++ b/app/test-pmd/rxonly.c
@@ -0,0 +1,194 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <sys/queue.h>
+#include <sys/stat.h>
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_ring.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_string_fns.h>
+
+#include "testpmd.h"
+
+#define MAX_PKT_RX_FLAGS 11
+static const char *pkt_rx_flag_names[MAX_PKT_RX_FLAGS] = {
+ "VLAN_PKT",
+ "RSS_HASH",
+ "PKT_RX_FDIR",
+ "IP_CKSUM",
+ "IP_CKSUM_BAD",
+
+ "IPV4_HDR",
+ "IPV4_HDR_EXT",
+ "IPV6_HDR",
+ "IPV6_HDR_EXT",
+
+ "IEEE1588_PTP",
+ "IEEE1588_TMST",
+};
+
+static inline void
+print_ether_addr(const char *what, struct ether_addr *eth_addr)
+{
+ printf("%s%02X:%02X:%02X:%02X:%02X:%02X",
+ what,
+ eth_addr->addr_bytes[0],
+ eth_addr->addr_bytes[1],
+ eth_addr->addr_bytes[2],
+ eth_addr->addr_bytes[3],
+ eth_addr->addr_bytes[4],
+ eth_addr->addr_bytes[5]);
+}
+
+/*
+ * Received a burst of packets.
+ */
+static void
+pkt_burst_receive(struct fwd_stream *fs)
+{
+ struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+ struct rte_mbuf *mb;
+ struct ether_hdr *eth_hdr;
+ uint16_t eth_type;
+ uint16_t ol_flags;
+ uint16_t nb_rx;
+ uint16_t i;
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ uint64_t start_tsc;
+ uint64_t end_tsc;
+ uint64_t core_cycles;
+#endif
+
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ start_tsc = rte_rdtsc();
+#endif
+
+ /*
+ * Receive a burst of packets.
+ */
+ nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
+ nb_pkt_per_burst);
+ if (unlikely(nb_rx == 0))
+ return;
+
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
+#endif
+ fs->rx_packets += nb_rx;
+
+ /*
+ * Dump each received packet if verbose_level > 0.
+ */
+ if (verbose_level > 0)
+ printf("port %u/queue %u: received %u packets\n",
+ (unsigned) fs->rx_port,
+ (unsigned) fs->rx_queue,
+ (unsigned) nb_rx);
+ for (i = 0; i < nb_rx; i++) {
+ mb = pkts_burst[i];
+ if (verbose_level == 0) {
+ rte_pktmbuf_free(mb);
+ continue;
+ }
+ eth_hdr = (struct ether_hdr *) mb->pkt.data;
+ eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type);
+ ol_flags = mb->ol_flags;
+ print_ether_addr(" src=", &eth_hdr->s_addr);
+ print_ether_addr(" - dst=", &eth_hdr->d_addr);
+ printf(" - type=0x%04x - length=%u - nb_segs=%d",
+ eth_type, (unsigned) mb->pkt.pkt_len,
+ (int)mb->pkt.nb_segs);
+ if (ol_flags & PKT_RX_RSS_HASH)
+ printf(" - RSS hash=0x%x", (unsigned) mb->pkt.hash.rss);
+ else if (ol_flags & PKT_RX_FDIR)
+ printf(" - FDIR hash=0x%x - FDIR id=0x%x ",
+ mb->pkt.hash.fdir.hash, mb->pkt.hash.fdir.id);
+ if (ol_flags & PKT_RX_VLAN_PKT)
+ printf(" - VLAN tci=0x%x", mb->pkt.vlan_tci);
+ printf("\n");
+ if (ol_flags != 0) {
+ int rxf;
+
+ for (rxf = 0; rxf < MAX_PKT_RX_FLAGS; rxf++) {
+ if (ol_flags & (1 << rxf))
+ printf(" PKT_RX_%s\n",
+ pkt_rx_flag_names[rxf]);
+ }
+ }
+ rte_pktmbuf_free(mb);
+ }
+
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ end_tsc = rte_rdtsc();
+ core_cycles = (end_tsc - start_tsc);
+ fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
+#endif
+}
+
+struct fwd_engine rx_only_engine = {
+ .fwd_mode_name = "rxonly",
+ .port_fwd_begin = NULL,
+ .port_fwd_end = NULL,
+ .packet_fwd = pkt_burst_receive,
+};
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
new file mode 100644
index 0000000..6813b66
--- /dev/null
+++ b/app/test-pmd/testpmd.c
@@ -0,0 +1,1105 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#include <sys/queue.h>
+#include <sys/stat.h>
+
+#include <stdint.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+#include <rte_malloc.h>
+#include <rte_mbuf.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_string_fns.h>
+
+#include "testpmd.h"
+
+uint16_t verbose_level = 0; /**< Silent by default. */
+
+/* use master core for command line ? */
+uint8_t interactive = 0;
+
+/*
+ * NUMA support configuration.
+ * When set, the NUMA support attempts to dispatch the allocation of the
+ * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
+ * probed ports among the CPU sockets 0 and 1.
+ * Otherwise, all memory is allocated from CPU socket 0.
+ */
+uint8_t numa_support = 0; /**< No numa support by default */
+
+/*
+ * Record the Ethernet address of peer target ports to which packets are
+ * forwarded.
+ * Must be instanciated with the ethernet addresses of peer traffic generator
+ * ports.
+ */
+struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
+portid_t nb_peer_eth_addrs = 0;
+
+/*
+ * Probed Target Environment.
+ */
+struct rte_port *ports; /**< For all probed ethernet ports. */
+portid_t nb_ports; /**< Number of probed ethernet ports. */
+struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
+lcoreid_t nb_lcores; /**< Number of probed logical cores. */
+
+/*
+ * Test Forwarding Configuration.
+ * nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
+ * nb_fwd_ports <= nb_cfg_ports <= nb_ports
+ */
+lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
+lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
+portid_t nb_cfg_ports; /**< Number of configured ports. */
+portid_t nb_fwd_ports; /**< Number of forwarding ports. */
+
+unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
+portid_t fwd_ports_ids[RTE_MAX_ETHPORTS]; /**< Port ids configuration. */
+
+struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
+streamid_t nb_fwd_streams; /**< Is equal to (nb_ports * nb_rxq). */
+
+/*
+ * Forwarding engines.
+ */
+struct fwd_engine * fwd_engines[] = {
+ &io_fwd_engine,
+ &mac_fwd_engine,
+ &rx_only_engine,
+ &tx_only_engine,
+ &csum_fwd_engine,
+#ifdef RTE_LIBRTE_IEEE1588
+ &ieee1588_fwd_engine,
+#endif
+ NULL,
+};
+
+struct fwd_config cur_fwd_config;
+struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
+
+uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
+
+/*
+ * Configuration of packet segments used by the "txonly" processing engine.
+ */
+uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
+uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
+ TXONLY_DEF_PACKET_LEN,
+};
+uint8_t tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
+
+uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
+uint16_t mb_mempool_cache = DEF_PKT_BURST; /**< Size of mbuf mempool cache. */
+
+/*
+ * Ethernet Ports Configuration.
+ */
+int promiscuous_on = 1; /**< Ports set in promiscuous mode by default. */
+
+/*
+ * Configurable number of RX/TX queues.
+ */
+queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
+queueid_t nb_txq = 1; /**< Number of TX queues per port. */
+
+/*
+ * Configurable number of RX/TX ring descriptors.
+ */
+#define RTE_TEST_RX_DESC_DEFAULT 128
+#define RTE_TEST_TX_DESC_DEFAULT 512
+uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
+uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
+
+/*
+ * Configurable values of RX and TX ring threshold registers.
+ */
+#define RX_PTHRESH 8 /**< Default value of RX prefetch threshold register. */
+#define RX_HTHRESH 8 /**< Default value of RX host threshold register. */
+#define RX_WTHRESH 4 /**< Default value of RX write-back threshold register. */
+
+#define TX_PTHRESH 36 /**< Default value of TX prefetch threshold register. */
+#define TX_HTHRESH 0 /**< Default value of TX host threshold register. */
+#define TX_WTHRESH 0 /**< Default value of TX write-back threshold register. */
+
+struct rte_eth_thresh rx_thresh = {
+ .pthresh = RX_PTHRESH,
+ .hthresh = RX_HTHRESH,
+ .wthresh = RX_WTHRESH,
+};
+
+struct rte_eth_thresh tx_thresh = {
+ .pthresh = TX_PTHRESH,
+ .hthresh = TX_HTHRESH,
+ .wthresh = TX_WTHRESH,
+};
+
+/*
+ * Configurable value of RX free threshold.
+ */
+uint16_t rx_free_thresh = 0; /* Immediately free RX descriptors by default. */
+
+/*
+ * Configurable value of TX free threshold.
+ */
+uint16_t tx_free_thresh = 0; /* Use default values. */
+
+/*
+ * Configurable value of TX RS bit threshold.
+ */
+uint16_t tx_rs_thresh = 0; /* Use default values. */
+
+/*
+ * Receive Side Scaling (RSS) configuration.
+ */
+uint16_t rss_hf = ETH_RSS_IPV4 | ETH_RSS_IPV6; /* RSS IP by default. */
+
+/*
+ * Port topology configuration
+ */
+uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
+
+/*
+ * Ethernet device configuration.
+ */
+struct rte_eth_rxmode rx_mode = {
+ .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
+ .split_hdr_size = 0,
+ .header_split = 0, /**< Header Split disabled. */
+ .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
+ .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
+ .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
+ .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */
+};
+
+struct rte_fdir_conf fdir_conf = {
+ .mode = RTE_FDIR_MODE_NONE,
+ .pballoc = RTE_FDIR_PBALLOC_64K,
+ .status = RTE_FDIR_REPORT_STATUS,
+ .flexbytes_offset = 0x6,
+ .drop_queue = 127,
+};
+
+static volatile int test_done = 1; /* stop packet forwarding when set to 1. */
+
+/*
+ * Setup default configuration.
+ */
+static void
+set_default_fwd_lcores_config(void)
+{
+ unsigned int i;
+ unsigned int nb_lc;
+
+ nb_lc = 0;
+ for (i = 0; i < RTE_MAX_LCORE; i++) {
+ if (! rte_lcore_is_enabled(i))
+ continue;
+ if (i == rte_get_master_lcore())
+ continue;
+ fwd_lcores_cpuids[nb_lc++] = i;
+ }
+ nb_lcores = (lcoreid_t) nb_lc;
+ nb_cfg_lcores = nb_lcores;
+ nb_fwd_lcores = 1;
+}
+
+static void
+set_def_peer_eth_addrs(void)
+{
+ portid_t i;
+
+ for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+ peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
+ peer_eth_addrs[i].addr_bytes[5] = i;
+ }
+}
+
+static void
+set_default_fwd_ports_config(void)
+{
+ portid_t pt_id;
+
+ for (pt_id = 0; pt_id < nb_ports; pt_id++)
+ fwd_ports_ids[pt_id] = pt_id;
+
+ nb_cfg_ports = nb_ports;
+ nb_fwd_ports = nb_ports;
+}
+
+void
+set_def_fwd_config(void)
+{
+ set_default_fwd_lcores_config();
+ set_def_peer_eth_addrs();
+ set_default_fwd_ports_config();
+}
+
+/*
+ * Configuration initialisation done once at init time.
+ */
+struct mbuf_ctor_arg {
+ uint16_t seg_buf_offset; /**< offset of data in data segment of mbuf. */
+ uint16_t seg_buf_size; /**< size of data segment in mbuf. */
+};
+
+struct mbuf_pool_ctor_arg {
+ uint16_t seg_buf_size; /**< size of data segment in mbuf. */
+};
+
+static void
+testpmd_mbuf_ctor(struct rte_mempool *mp,
+ void *opaque_arg,
+ void *raw_mbuf,
+ __attribute__((unused)) unsigned i)
+{
+ struct mbuf_ctor_arg *mb_ctor_arg;
+ struct rte_mbuf *mb;
+
+ mb_ctor_arg = (struct mbuf_ctor_arg *) opaque_arg;
+ mb = (struct rte_mbuf *) raw_mbuf;
+
+ mb->pool = mp;
+ mb->buf_addr = (void *) ((char *)mb + mb_ctor_arg->seg_buf_offset);
+ mb->buf_physaddr = (uint64_t) (rte_mempool_virt2phy(mp, mb) +
+ mb_ctor_arg->seg_buf_offset);
+ mb->buf_len = mb_ctor_arg->seg_buf_size;
+ mb->type = RTE_MBUF_PKT;
+ mb->ol_flags = 0;
+ mb->pkt.data = (char *) mb->buf_addr + RTE_PKTMBUF_HEADROOM;
+ mb->pkt.nb_segs = 1;
+ mb->pkt.l2_len = 0;
+ mb->pkt.l3_len = 0;
+ mb->pkt.vlan_tci = 0;
+ mb->pkt.hash.rss = 0;
+}
+
+static void
+testpmd_mbuf_pool_ctor(struct rte_mempool *mp,
+ void *opaque_arg)
+{
+ struct mbuf_pool_ctor_arg *mbp_ctor_arg;
+ struct rte_pktmbuf_pool_private *mbp_priv;
+
+ if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
+ printf("%s(%s) private_data_size %d < %d\n",
+ __func__, mp->name, (int) mp->private_data_size,
+ (int) sizeof(struct rte_pktmbuf_pool_private));
+ return;
+ }
+ mbp_ctor_arg = (struct mbuf_pool_ctor_arg *) opaque_arg;
+ mbp_priv = (struct rte_pktmbuf_pool_private *)
+ ((char *)mp + sizeof(struct rte_mempool));
+ mbp_priv->mbuf_data_room_size = mbp_ctor_arg->seg_buf_size;
+}
+
+static void
+mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
+ unsigned int socket_id)
+{
+ char pool_name[RTE_MEMPOOL_NAMESIZE];
+ struct rte_mempool *rte_mp;
+ struct mbuf_pool_ctor_arg mbp_ctor_arg;
+ struct mbuf_ctor_arg mb_ctor_arg;
+ uint32_t mb_size;
+
+ mbp_ctor_arg.seg_buf_size = (uint16_t) (RTE_PKTMBUF_HEADROOM +
+ mbuf_seg_size);
+ mb_ctor_arg.seg_buf_offset =
+ (uint16_t) CACHE_LINE_ROUNDUP(sizeof(struct rte_mbuf));
+ mb_ctor_arg.seg_buf_size = mbp_ctor_arg.seg_buf_size;
+ mb_size = mb_ctor_arg.seg_buf_offset + mb_ctor_arg.seg_buf_size;
+ mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
+ rte_mp = rte_mempool_create(pool_name, nb_mbuf, (unsigned) mb_size,
+ (unsigned) mb_mempool_cache,
+ sizeof(struct rte_pktmbuf_pool_private),
+ testpmd_mbuf_pool_ctor, &mbp_ctor_arg,
+ testpmd_mbuf_ctor, &mb_ctor_arg,
+ socket_id, 0);
+ if (rte_mp == NULL) {
+ rte_exit(EXIT_FAILURE, "Creation of mbuf pool for socket %u failed\n",
+ socket_id);
+ }
+}
+
+static void
+init_config(void)
+{
+ struct rte_port *port;
+ struct rte_mempool *mbp;
+ unsigned int nb_mbuf_per_pool;
+ streamid_t sm_id;
+ lcoreid_t lc_id;
+ portid_t pt_id;
+
+ /* Configuration of logical cores. */
+ fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
+ sizeof(struct fwd_lcore *) * nb_lcores,
+ CACHE_LINE_SIZE);
+ if (fwd_lcores == NULL) {
+ rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) failed\n",
+ nb_lcores);
+ }
+ for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
+ fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
+ sizeof(struct fwd_lcore),
+ CACHE_LINE_SIZE);
+ if (fwd_lcores[lc_id] == NULL) {
+ rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) failed\n");
+ }
+ fwd_lcores[lc_id]->cpuid_idx = lc_id;
+ }
+
+ /*
+ * Create pools of mbuf.
+ * If NUMA support is disabled, create a single pool of mbuf in
+ * socket 0 memory.
+ * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
+ */
+ nb_mbuf_per_pool = nb_rxd + (nb_lcores * mb_mempool_cache) +
+ nb_txd + MAX_PKT_BURST;
+ if (numa_support) {
+ nb_mbuf_per_pool = nb_mbuf_per_pool * (nb_ports >> 1);
+ mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
+ mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 1);
+ } else {
+ nb_mbuf_per_pool = (nb_mbuf_per_pool * nb_ports);
+ mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
+ }
+
+ /*
+ * Records which Mbuf pool to use by each logical core, if needed.
+ */
+ for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
+ mbp = mbuf_pool_find(rte_lcore_to_socket_id(lc_id));
+ if (mbp == NULL)
+ mbp = mbuf_pool_find(0);
+ fwd_lcores[lc_id]->mbp = mbp;
+ }
+
+ /* Configuration of Ethernet ports. */
+ ports = rte_zmalloc("testpmd: ports",
+ sizeof(struct rte_port) * nb_ports,
+ CACHE_LINE_SIZE);
+ if (ports == NULL) {
+ rte_exit(EXIT_FAILURE, "rte_zmalloc(%d struct rte_port) failed\n",
+ nb_ports);
+ }
+ port = ports;
+ for (pt_id = 0; pt_id < nb_ports; pt_id++, port++) {
+ rte_eth_dev_info_get(pt_id, &port->dev_info);
+ if (nb_rxq > port->dev_info.max_rx_queues) {
+ rte_exit(EXIT_FAILURE, "Port %d: max RX queues %d < nb_rxq %d\n",
+ (int) pt_id,
+ (int) port->dev_info.max_rx_queues,
+ (int) nb_rxq);
+ }
+ if (nb_txq > port->dev_info.max_tx_queues) {
+ rte_exit(EXIT_FAILURE, "Port %d: max TX queues %d < nb_txq %d\n",
+ (int) pt_id,
+ (int) port->dev_info.max_tx_queues,
+ (int) nb_txq);
+ }
+
+ if (numa_support)
+ port->socket_id = (pt_id < (nb_ports >> 1)) ? 0 : 1;
+ else
+ port->socket_id = 0;
+ }
+
+ /* Configuration of packet forwarding streams. */
+ nb_fwd_streams = (streamid_t) (nb_ports * nb_rxq);
+ fwd_streams = rte_zmalloc("testpmd: fwd_streams",
+ sizeof(struct fwd_stream *) * nb_fwd_streams,
+ CACHE_LINE_SIZE);
+ if (fwd_streams == NULL) {
+ rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) failed\n",
+ nb_fwd_streams);
+ }
+ for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
+ fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream",
+ sizeof(struct fwd_stream),
+ CACHE_LINE_SIZE);
+ if (fwd_streams[sm_id] == NULL) {
+ rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream) failed\n");
+ }
+ }
+}
+
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+static void
+pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
+{
+ unsigned int total_burst;
+ unsigned int nb_burst;
+ unsigned int burst_stats[3];
+ uint16_t pktnb_stats[3];
+ uint16_t nb_pkt;
+ int burst_percent[3];
+
+ /*
+ * First compute the total number of packet bursts and the
+ * two highest numbers of bursts of the same number of packets.
+ */
+ total_burst = 0;
+ burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
+ pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
+ for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
+ nb_burst = pbs->pkt_burst_spread[nb_pkt];
+ if (nb_burst == 0)
+ continue;
+ total_burst += nb_burst;
+ if (nb_burst > burst_stats[0]) {
+ burst_stats[1] = burst_stats[0];
+ pktnb_stats[1] = pktnb_stats[0];
+ burst_stats[0] = nb_burst;
+ pktnb_stats[0] = nb_pkt;
+ }
+ }
+ if (total_burst == 0)
+ return;
+ burst_percent[0] = (burst_stats[0] * 100) / total_burst;
+ printf(" %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
+ burst_percent[0], (int) pktnb_stats[0]);
+ if (burst_stats[0] == total_burst) {
+ printf("]\n");
+ return;
+ }
+ if (burst_stats[0] + burst_stats[1] == total_burst) {
+ printf(" + %d%% of %d pkts]\n",
+ 100 - burst_percent[0], pktnb_stats[1]);
+ return;
+ }
+ burst_percent[1] = (burst_stats[1] * 100) / total_burst;
+ burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
+ if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
+ printf(" + %d%% of others]\n", 100 - burst_percent[0]);
+ return;
+ }
+ printf(" + %d%% of %d pkts + %d%% of others]\n",
+ burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
+}
+#endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
+
+static void
+fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
+{
+ struct rte_port *port;
+
+ static const char *fwd_stats_border = "----------------------";
+
+ port = &ports[port_id];
+ printf("\n %s Forward statistics for port %-2d %s\n",
+ fwd_stats_border, port_id, fwd_stats_border);
+ printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
+ "%-"PRIu64"\n",
+ stats->ipackets, stats->ierrors,
+ (uint64_t) (stats->ipackets + stats->ierrors));
+
+ if (cur_fwd_eng == &csum_fwd_engine)
+ printf(" Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
+ port->rx_bad_ip_csum, port->rx_bad_l4_csum);
+
+ printf(" TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
+ "%-"PRIu64"\n",
+ stats->opackets, port->tx_dropped,
+ (uint64_t) (stats->opackets + port->tx_dropped));
+
+ if (stats->rx_nombuf > 0)
+ printf(" RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ if (port->rx_stream)
+ pkt_burst_stats_display("RX", &port->rx_stream->rx_burst_stats);
+ if (port->tx_stream)
+ pkt_burst_stats_display("TX", &port->tx_stream->tx_burst_stats);
+#endif
+ /* stats fdir */
+ if (fdir_conf.mode != RTE_FDIR_MODE_NONE)
+ printf(" Fdirmiss: %-14"PRIu64" Fdirmatch: %-14"PRIu64"\n",
+ stats->fdirmiss,
+ stats->fdirmatch);
+
+ printf(" %s--------------------------------%s\n",
+ fwd_stats_border, fwd_stats_border);
+}
+
+static void
+fwd_stream_stats_display(streamid_t stream_id)
+{
+ struct fwd_stream *fs;
+ static const char *fwd_top_stats_border = "-------";
+
+ fs = fwd_streams[stream_id];
+ if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
+ (fs->fwd_dropped == 0))
+ return;
+ printf("\n %s Forward Stats for RX Port=%2d/Queue=%2d -> "
+ "TX Port=%2d/Queue=%2d %s\n",
+ fwd_top_stats_border, fs->rx_port, fs->rx_queue,
+ fs->tx_port, fs->tx_queue, fwd_top_stats_border);
+ printf(" RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
+ fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
+
+ /* if checksum mode */
+ if (cur_fwd_eng == &csum_fwd_engine) {
+ printf(" RX- bad IP checksum: %-14u Rx- bad L4 checksum: %-14u\n",
+ fs->rx_bad_ip_csum, fs->rx_bad_l4_csum);
+ }
+
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ pkt_burst_stats_display("RX", &fs->rx_burst_stats);
+ pkt_burst_stats_display("TX", &fs->tx_burst_stats);
+#endif
+}
+
+static void
+flush_all_rx_queues(void)
+{
+ struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+ portid_t rxp;
+ queueid_t rxq;
+ uint16_t nb_rx;
+ uint16_t i;
+ uint8_t j;
+
+ for (j = 0; j < 2; j++) {
+ for (rxp = 0; rxp < nb_ports; rxp++) {
+ for (rxq = 0; rxq < nb_rxq; rxq++) {
+ do {
+ nb_rx = rte_eth_rx_burst(rxp, rxq,
+ pkts_burst,
+ MAX_PKT_BURST);
+ for (i = 0; i < nb_rx; i++)
+ rte_pktmbuf_free(pkts_burst[i]);
+ } while (nb_rx > 0);
+ }
+ }
+ rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
+ }
+}
+
+static void
+run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
+{
+ struct fwd_stream **fsm;
+ streamid_t nb_fs;
+ streamid_t sm_id;
+
+ fsm = &fwd_streams[fc->stream_idx];
+ nb_fs = fc->stream_nb;
+ do {
+ for (sm_id = 0; sm_id < nb_fs; sm_id++)
+ (*pkt_fwd)(fsm[sm_id]);
+ } while (! fc->stopped);
+}
+
+static int
+start_pkt_forward_on_core(void *fwd_arg)
+{
+ run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
+ cur_fwd_config.fwd_eng->packet_fwd);
+ return 0;
+}
+
+/*
+ * Run the TXONLY packet forwarding engine to send a single burst of packets.
+ * Used to start communication flows in network loopback test configurations.
+ */
+static int
+run_one_txonly_burst_on_core(void *fwd_arg)
+{
+ struct fwd_lcore *fwd_lc;
+ struct fwd_lcore tmp_lcore;
+
+ fwd_lc = (struct fwd_lcore *) fwd_arg;
+ tmp_lcore = *fwd_lc;
+ tmp_lcore.stopped = 1;
+ run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
+ return 0;
+}
+
+/*
+ * Launch packet forwarding:
+ * - Setup per-port forwarding context.
+ * - launch logical cores with their forwarding configuration.
+ */
+static void
+launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
+{
+ port_fwd_begin_t port_fwd_begin;
+ unsigned int i;
+ unsigned int lc_id;
+ int diag;
+
+ port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
+ if (port_fwd_begin != NULL) {
+ for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
+ (*port_fwd_begin)(fwd_ports_ids[i]);
+ }
+ for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
+ lc_id = fwd_lcores_cpuids[i];
+ if ((interactive == 0) || (lc_id != rte_lcore_id())) {
+ fwd_lcores[i]->stopped = 0;
+ diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
+ fwd_lcores[i], lc_id);
+ if (diag != 0)
+ printf("launch lcore %u failed - diag=%d\n",
+ lc_id, diag);
+ }
+ }
+}
+
+/*
+ * Launch packet forwarding configuration.
+ */
+void
+start_packet_forwarding(int with_tx_first)
+{
+ port_fwd_begin_t port_fwd_begin;
+ port_fwd_end_t port_fwd_end;
+ struct rte_port *port;
+ unsigned int i;
+ portid_t pt_id;
+ streamid_t sm_id;
+
+ if (test_done == 0) {
+ printf("Packet forwarding already started\n");
+ return;
+ }
+ test_done = 0;
+ flush_all_rx_queues();
+ fwd_config_setup();
+ rxtx_config_display();
+
+ for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
+ pt_id = fwd_ports_ids[i];
+ port = &ports[pt_id];
+ rte_eth_stats_get(pt_id, &port->stats);
+ port->tx_dropped = 0;
+ }
+ for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
+ fwd_streams[sm_id]->rx_packets = 0;
+ fwd_streams[sm_id]->tx_packets = 0;
+ fwd_streams[sm_id]->fwd_dropped = 0;
+ fwd_streams[sm_id]->rx_bad_ip_csum = 0;
+ fwd_streams[sm_id]->rx_bad_l4_csum = 0;
+
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
+ sizeof(fwd_streams[sm_id]->rx_burst_stats));
+ memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
+ sizeof(fwd_streams[sm_id]->tx_burst_stats));
+#endif
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ fwd_streams[sm_id]->core_cycles = 0;
+#endif
+ }
+ if (with_tx_first) {
+ port_fwd_begin = tx_only_engine.port_fwd_begin;
+ if (port_fwd_begin != NULL) {
+ for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
+ (*port_fwd_begin)(fwd_ports_ids[i]);
+ }
+ launch_packet_forwarding(run_one_txonly_burst_on_core);
+ rte_eal_mp_wait_lcore();
+ port_fwd_end = tx_only_engine.port_fwd_end;
+ if (port_fwd_end != NULL) {
+ for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
+ (*port_fwd_end)(fwd_ports_ids[i]);
+ }
+ }
+ launch_packet_forwarding(start_pkt_forward_on_core);
+}
+
+void
+stop_packet_forwarding(void)
+{
+ struct rte_eth_stats stats;
+ struct rte_port *port;
+ port_fwd_end_t port_fwd_end;
+ int i;
+ portid_t pt_id;
+ streamid_t sm_id;
+ lcoreid_t lc_id;
+ uint64_t total_recv;
+ uint64_t total_xmit;
+ uint64_t total_rx_dropped;
+ uint64_t total_tx_dropped;
+ uint64_t total_rx_nombuf;
+ uint64_t tx_dropped;
+ uint64_t rx_bad_ip_csum;
+ uint64_t rx_bad_l4_csum;
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ uint64_t fwd_cycles;
+#endif
+ static const char *acc_stats_border = "+++++++++++++++";
+
+ if (test_done) {
+ printf("Packet forwarding not started\n");
+ return;
+ }
+ printf("Telling cores to stop...");
+ for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
+ fwd_lcores[lc_id]->stopped = 1;
+ printf("\nWaiting for lcores to finish...\n");
+ rte_eal_mp_wait_lcore();
+ port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
+ if (port_fwd_end != NULL) {
+ for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
+ pt_id = fwd_ports_ids[i];
+ (*port_fwd_end)(pt_id);
+ }
+ }
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ fwd_cycles = 0;
+#endif
+ for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
+ if (cur_fwd_config.nb_fwd_streams >
+ cur_fwd_config.nb_fwd_ports) {
+ fwd_stream_stats_display(sm_id);
+ ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
+ ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
+ } else {
+ ports[fwd_streams[sm_id]->tx_port].tx_stream =
+ fwd_streams[sm_id];
+ ports[fwd_streams[sm_id]->rx_port].rx_stream =
+ fwd_streams[sm_id];
+ }
+ tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
+ tx_dropped = (uint64_t) (tx_dropped +
+ fwd_streams[sm_id]->fwd_dropped);
+ ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
+
+ rx_bad_ip_csum = ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
+ rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
+ fwd_streams[sm_id]->rx_bad_ip_csum);
+ ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum = rx_bad_ip_csum;
+
+ rx_bad_l4_csum = ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
+ rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
+ fwd_streams[sm_id]->rx_bad_l4_csum);
+ ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum = rx_bad_l4_csum;
+
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ fwd_cycles = (uint64_t) (fwd_cycles +
+ fwd_streams[sm_id]->core_cycles);
+#endif
+ }
+ total_recv = 0;
+ total_xmit = 0;
+ total_rx_dropped = 0;
+ total_tx_dropped = 0;
+ total_rx_nombuf = 0;
+ for (i = 0; i < ((cur_fwd_config.nb_fwd_ports + 1) & ~0x1); i++) {
+ pt_id = fwd_ports_ids[i];
+
+ port = &ports[pt_id];
+ rte_eth_stats_get(pt_id, &stats);
+ stats.ipackets -= port->stats.ipackets;
+ port->stats.ipackets = 0;
+ stats.opackets -= port->stats.opackets;
+ port->stats.opackets = 0;
+ stats.ibytes -= port->stats.ibytes;
+ port->stats.ibytes = 0;
+ stats.obytes -= port->stats.obytes;
+ port->stats.obytes = 0;
+ stats.ierrors -= port->stats.ierrors;
+ port->stats.ierrors = 0;
+ stats.oerrors -= port->stats.oerrors;
+ port->stats.oerrors = 0;
+ stats.rx_nombuf -= port->stats.rx_nombuf;
+ port->stats.rx_nombuf = 0;
+ stats.fdirmatch -= port->stats.fdirmatch;
+ port->stats.rx_nombuf = 0;
+ stats.fdirmiss -= port->stats.fdirmiss;
+ port->stats.rx_nombuf = 0;
+
+ total_recv += stats.ipackets;
+ total_xmit += stats.opackets;
+ total_rx_dropped += stats.ierrors;
+ total_tx_dropped += port->tx_dropped;
+ total_rx_nombuf += stats.rx_nombuf;
+
+ fwd_port_stats_display(pt_id, &stats);
+ }
+ printf("\n %s Accumulated forward statistics for all ports"
+ "%s\n",
+ acc_stats_border, acc_stats_border);
+ printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
+ "%-"PRIu64"\n"
+ " TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
+ "%-"PRIu64"\n",
+ total_recv, total_rx_dropped, total_recv + total_rx_dropped,
+ total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
+ if (total_rx_nombuf > 0)
+ printf(" RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
+ printf(" %s++++++++++++++++++++++++++++++++++++++++++++++"
+ "%s\n",
+ acc_stats_border, acc_stats_border);
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ if (total_recv > 0)
+ printf("\n CPU cycles/packet=%u (total cycles="
+ "%"PRIu64" / total RX packets=%"PRIu64")\n",
+ (unsigned int)(fwd_cycles / total_recv),
+ fwd_cycles, total_recv);
+#endif
+ printf("\nDone.\n");
+ test_done = 1;
+}
+
+void
+pmd_test_exit(void)
+{
+ portid_t pt_id;
+
+ for (pt_id = 0; pt_id < nb_ports; pt_id++) {
+ printf("Stopping port %d...", pt_id);
+ fflush(stdout);
+ rte_eth_dev_close(pt_id);
+ printf("done\n");
+ }
+ printf("bye...\n");
+}
+
+typedef void (*cmd_func_t)(void);
+struct pmd_test_command {
+ const char *cmd_name;
+ cmd_func_t cmd_func;
+};
+
+#define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
+
+static void
+fatal_init_error(const char *func_name, uint8_t port_id, int diag)
+{
+ rte_panic("%s(port_id=%d) failed - diag=%d\n",
+ func_name, port_id, diag);
+}
+
+static void
+init_ports(void)
+{
+ struct rte_eth_link link;
+ struct rte_eth_conf port_conf = {
+ .intr_conf = {
+ .lsc = 0,
+ },
+ };
+ struct rte_eth_rxconf rx_conf;
+ struct rte_eth_txconf tx_conf;
+ struct rte_port *port;
+ unsigned int sock_id;
+ portid_t pi;
+ queueid_t qi;
+ int diag;
+
+ port_conf.rxmode = rx_mode;
+ port_conf.fdir_conf = fdir_conf;
+
+ if (nb_rxq > 0) { /* configure RSS */
+ port_conf.rx_adv_conf.rss_conf.rss_key = NULL;
+ /* use default hash key */
+ port_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf;
+ } else
+ port_conf.rx_adv_conf.rss_conf.rss_hf = 0;
+ rx_conf.rx_thresh = rx_thresh;
+ rx_conf.rx_free_thresh = rx_free_thresh;
+ tx_conf.tx_thresh = tx_thresh;
+ tx_conf.tx_rs_thresh = tx_rs_thresh;
+ tx_conf.tx_free_thresh = tx_free_thresh;
+
+ for (pi = 0; pi < nb_ports; pi++) {
+ port = &ports[pi];
+ memcpy(&port->dev_conf, &port_conf, sizeof(port_conf));
+ sock_id = port->socket_id;
+ printf("Initializing port %d... ", pi);
+ fflush(stdout);
+ diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq, &port_conf);
+ if (diag != 0) {
+ fatal_init_error("rte_eth_dev_configure", pi, diag);
+ /* NOT REACHED */
+ }
+ rte_eth_macaddr_get(pi, &port->eth_addr);
+ for (qi = 0; qi < nb_txq; qi++) {
+ diag = rte_eth_tx_queue_setup(pi, qi, nb_txd,
+ sock_id,
+ &tx_conf);
+ if (diag != 0) {
+ fatal_init_error("rte_eth_tx_queue_setup",
+ pi, diag);
+ /* NOT REACHED */
+ }
+ }
+ for (qi = 0; qi < nb_rxq; qi++) {
+ diag = rte_eth_rx_queue_setup(pi, qi, nb_rxd, sock_id,
+ &rx_conf,
+ mbuf_pool_find(sock_id));
+ if (diag != 0) {
+ fatal_init_error("rte_eth_rx_queue_setup",
+ pi , diag);
+ /* NOT REACHED */
+ }
+ }
+
+ /* Start device */
+ diag = rte_eth_dev_start(pi);
+ if (diag != 0) {
+ fatal_init_error("rte_eth_dev_start", pi, diag);
+ /* NOT REACHED */
+ }
+ printf("done: ");
+ rte_eth_link_get(pi, &link);
+ if (link.link_status) {
+ printf(" Link Up - speed %u Mbps - %s\n",
+ (unsigned) link.link_speed,
+ (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
+ ("full-duplex") : ("half-duplex\n"));
+ } else {
+ printf(" Link Down\n");
+ }
+
+ /*
+ * If enabled, put device in promiscuous mode.
+ * This allows the PMD test in IO forwarding mode to forward
+ * packets to itself through 2 cross-connected ports of the
+ * target machine.
+ */
+ if (promiscuous_on)
+ rte_eth_promiscuous_enable(pi);
+ }
+}
+
+#ifdef RTE_EXEC_ENV_BAREMETAL
+#define main _main
+#endif
+
+int
+main(int argc, char** argv)
+{
+ int diag;
+
+ diag = rte_eal_init(argc, argv);
+ if (diag < 0)
+ rte_panic("Cannot init EAL\n");
+
+#ifdef RTE_LIBRTE_IGB_PMD
+ if (rte_igb_pmd_init())
+ rte_panic("Cannot init igb PMD\n");
+#endif
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ if (rte_ixgbe_pmd_init())
+ rte_panic("Cannot init ixgbe PMD\n");
+
+ if (rte_ixgbevf_pmd_init())
+ rte_panic("Cannot init ixgbevf PMD\n");
+#endif
+
+ if (rte_eal_pci_probe())
+ rte_panic("Cannot probe PCI\n");
+
+ nb_ports = (portid_t) rte_eth_dev_count();
+ if (nb_ports == 0)
+ rte_exit(EXIT_FAILURE, "No probed ethernet devices - check that "
+ "CONFIG_RTE_LIBRTE_IGB_PMD=y and that "
+ "CONFIG_RTE_LIBRTE_IXGBE_PMD=y in your "
+ "configuration file\n");
+
+ set_def_fwd_config();
+ if (nb_lcores == 0)
+ rte_panic("Empty set of forwarding logical cores - check the "
+ "core mask supplied in the command parameters\n");
+
+ argc -= diag;
+ argv += diag;
+ if (argc > 1)
+ launch_args_parse(argc, argv);
+
+ if (nb_rxq > nb_txq)
+ printf("Warning: nb_rxq=%d enables RSS configuration, "
+ "but nb_txq=%d will prevent to fully test it.\n",
+ nb_rxq, nb_txq);
+
+ init_config();
+
+ init_ports();
+
+ if (interactive == 1)
+ prompt();
+ else {
+ char c;
+ int rc;
+
+ printf("No commandline core given, start packet forwarding\n");
+ start_packet_forwarding(0);
+ printf("Press enter to exit\n");
+ rc = read(0, &c, 1);
+ if (rc < 0)
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
new file mode 100644
index 0000000..cc4a0fd
--- /dev/null
+++ b/app/test-pmd/testpmd.h
@@ -0,0 +1,413 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#ifndef _TESTPMD_H_
+#define _TESTPMD_H_
+
+/* icc on baremetal gives us troubles with function named 'main' */
+#ifdef RTE_EXEC_ENV_BAREMETAL
+#define main _main
+int main(int argc, char **argv);
+#endif
+
+/*
+ * Default size of the mbuf data buffer to receive standard 1518-byte
+ * Ethernet frames in a mono-segment memory buffer.
+ */
+#define DEFAULT_MBUF_DATA_SIZE 2048 /**< Default size of mbuf data buffer. */
+
+/*
+ * The maximum number of segments per packet is used when creating
+ * scattered transmit packets composed of a list of mbufs.
+ */
+#define RTE_MAX_SEGS_PER_PKT 255 /**< pkt.nb_segs is a 8-bit unsigned char. */
+
+#define MAX_PKT_BURST 512
+#define DEF_PKT_BURST 16
+
+#define CACHE_LINE_SIZE_ROUNDUP(size) \
+ (CACHE_LINE_SIZE * ((size + CACHE_LINE_SIZE - 1) / CACHE_LINE_SIZE))
+
+typedef uint8_t lcoreid_t;
+typedef uint8_t portid_t;
+typedef uint16_t queueid_t;
+typedef uint16_t streamid_t;
+
+#define MAX_QUEUE_ID ((1 << (sizeof(queueid_t) * 8)) - 1)
+
+enum {
+ PORT_TOPOLOGY_PAIRED,
+ PORT_TOPOLOGY_CHAINED
+};
+
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+/**
+ * The data structure associated with RX and TX packet burst statistics
+ * that are recorded for each forwarding stream.
+ */
+struct pkt_burst_stats {
+ unsigned int pkt_burst_spread[MAX_PKT_BURST];
+};
+#endif
+
+/**
+ * The data structure associated with a forwarding stream between a receive
+ * port/queue and a transmit port/queue.
+ */
+struct fwd_stream {
+ /* "read-only" data */
+ portid_t rx_port; /**< port to poll for received packets */
+ queueid_t rx_queue; /**< RX queue to poll on "rx_port" */
+ portid_t tx_port; /**< forwarding port of received packets */
+ queueid_t tx_queue; /**< TX queue to send forwarded packets */
+ streamid_t peer_addr; /**< index of peer ethernet address of packets */
+
+ /* "read-write" results */
+ unsigned int rx_packets; /**< received packets */
+ unsigned int tx_packets; /**< received packets transmitted */
+ unsigned int fwd_dropped; /**< received packets not forwarded */
+ unsigned int rx_bad_ip_csum ; /**< received packets has bad ip checksum */
+ unsigned int rx_bad_l4_csum ; /**< received packets has bad l4 checksum */
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ uint64_t core_cycles; /**< used for RX and TX processing */
+#endif
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ struct pkt_burst_stats rx_burst_stats;
+ struct pkt_burst_stats tx_burst_stats;
+#endif
+};
+
+/**
+ * The data structure associated with each port.
+ * tx_ol_flags is slightly different from ol_flags of rte_mbuf.
+ * Bit 0: Insert IP checksum
+ * Bit 1: Insert UDP checksum
+ * Bit 2: Insert TCP checksum
+ * Bit 3: Insert SCTP checksum
+ * Bit 11: Insert VLAN Label
+ */
+struct rte_port {
+ struct rte_eth_dev_info dev_info; /**< PCI info + driver name */
+ struct rte_eth_conf dev_conf; /**< Port configuration. */
+ struct ether_addr eth_addr; /**< Port ethernet address */
+ struct rte_eth_stats stats; /**< Last port statistics */
+ uint64_t tx_dropped; /**< If no descriptor in TX ring */
+ struct fwd_stream *rx_stream; /**< Port RX stream, if unique */
+ struct fwd_stream *tx_stream; /**< Port TX stream, if unique */
+ unsigned int socket_id; /**< For NUMA support */
+ uint16_t tx_ol_flags;/**< Offload Flags of TX packets. */
+ uint16_t tx_vlan_id; /**< Tag Id. in TX VLAN packets. */
+ void *fwd_ctx; /**< Forwarding mode context */
+ uint64_t rx_bad_ip_csum; /**< rx pkts with bad ip checksum */
+ uint64_t rx_bad_l4_csum; /**< rx pkts with bad l4 checksum */
+};
+
+/**
+ * The data structure associated with each forwarding logical core.
+ * The logical cores are internally numbered by a core index from 0 to
+ * the maximum number of logical cores - 1.
+ * The system CPU identifier of all logical cores are setup in a global
+ * CPU id. configuration table.
+ */
+struct fwd_lcore {
+ struct rte_mempool *mbp; /**< The mbuf pool to use by this core */
+ streamid_t stream_idx; /**< index of 1st stream in "fwd_streams" */
+ streamid_t stream_nb; /**< number of streams in "fwd_streams" */
+ lcoreid_t cpuid_idx; /**< index of logical core in CPU id table */
+ queueid_t tx_queue; /**< TX queue to send forwarded packets */
+ volatile char stopped; /**< stop forwarding when set */
+};
+
+/*
+ * Forwarding mode operations:
+ * - IO forwarding mode (default mode)
+ * Forwards packets unchanged.
+ *
+ * - MAC forwarding mode
+ * Set the source and the destination Ethernet addresses of packets
+ * before forwarding them.
+ *
+ * - IEEE1588 forwarding mode
+ * Check that received IEEE1588 Precise Time Protocol (PTP) packets are
+ * filtered and timestamped by the hardware.
+ * Forwards packets unchanged on the same port.
+ * Check that sent IEEE1588 PTP packets are timestamped by the hardware.
+ */
+typedef void (*port_fwd_begin_t)(portid_t pi);
+typedef void (*port_fwd_end_t)(portid_t pi);
+typedef void (*packet_fwd_t)(struct fwd_stream *fs);
+
+struct fwd_engine {
+ const char *fwd_mode_name; /**< Forwarding mode name. */
+ port_fwd_begin_t port_fwd_begin; /**< NULL if nothing special to do. */
+ port_fwd_end_t port_fwd_end; /**< NULL if nothing special to do. */
+ packet_fwd_t packet_fwd; /**< Mandatory. */
+};
+
+extern struct fwd_engine io_fwd_engine;
+extern struct fwd_engine mac_fwd_engine;
+extern struct fwd_engine rx_only_engine;
+extern struct fwd_engine tx_only_engine;
+extern struct fwd_engine csum_fwd_engine;
+#ifdef RTE_LIBRTE_IEEE1588
+extern struct fwd_engine ieee1588_fwd_engine;
+#endif
+
+extern struct fwd_engine * fwd_engines[]; /**< NULL terminated array. */
+
+/**
+ * Forwarding Configuration
+ *
+ */
+struct fwd_config {
+ struct fwd_engine *fwd_eng; /**< Packet forwarding mode. */
+ streamid_t nb_fwd_streams; /**< Nb. of forward streams to process. */
+ lcoreid_t nb_fwd_lcores; /**< Nb. of logical cores to launch. */
+ portid_t nb_fwd_ports; /**< Nb. of ports involved. */
+};
+
+/* globals used for configuration */
+extern uint16_t verbose_level; /**< Drives messages being displayed, if any. */
+extern uint8_t interactive;
+extern uint8_t numa_support; /**< set by "--numa" parameter */
+extern uint16_t port_topology; /**< set by "--port-topology" parameter */
+
+/*
+ * Configuration of logical cores:
+ * nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
+ */
+extern lcoreid_t nb_lcores; /**< Number of logical cores probed at init time. */
+extern lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
+extern lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
+extern unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE];
+
+/*
+ * Configuration of Ethernet ports:
+ * nb_fwd_ports <= nb_cfg_ports <= nb_ports
+ */
+extern portid_t nb_ports; /**< Number of ethernet ports probed at init time. */
+extern portid_t nb_cfg_ports; /**< Number of configured ports. */
+extern portid_t nb_fwd_ports; /**< Number of forwarding ports. */
+extern portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];
+extern struct rte_port *ports;
+
+extern struct rte_eth_rxmode rx_mode;
+extern uint16_t rss_hf;
+
+extern queueid_t nb_rxq;
+extern queueid_t nb_txq;
+
+extern uint16_t nb_rxd;
+extern uint16_t nb_txd;
+
+extern uint16_t rx_free_thresh;
+extern uint16_t tx_free_thresh;
+extern uint16_t tx_rs_thresh;
+
+extern uint16_t mbuf_data_size; /**< Mbuf data space size. */
+
+extern struct rte_fdir_conf fdir_conf;
+
+/*
+ * Configuration of packet segments used by the "txonly" processing engine.
+ */
+#define TXONLY_DEF_PACKET_LEN 64
+extern uint16_t tx_pkt_length; /**< Length of TXONLY packet */
+extern uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT]; /**< Seg. lengths */
+extern uint8_t tx_pkt_nb_segs; /**< Number of segments in TX packets */
+
+extern uint16_t nb_pkt_per_burst;
+extern uint16_t mb_mempool_cache;
+extern struct rte_eth_thresh rx_thresh;
+extern struct rte_eth_thresh tx_thresh;
+
+extern struct fwd_config cur_fwd_config;
+extern struct fwd_engine *cur_fwd_eng;
+extern struct fwd_lcore **fwd_lcores;
+extern struct fwd_stream **fwd_streams;
+
+extern portid_t nb_peer_eth_addrs; /**< Number of peer ethernet addresses. */
+extern struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
+
+static inline unsigned int
+lcore_num(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < RTE_MAX_LCORE; ++i)
+ if (fwd_lcores_cpuids[i] == rte_lcore_id())
+ return i;
+
+ rte_panic("lcore_id of current thread not found in fwd_lcores_cpuids\n");
+}
+
+static inline struct fwd_lcore *
+current_fwd_lcore(void)
+{
+ return fwd_lcores[lcore_num()];
+}
+
+/* Mbuf Pools */
+static inline void
+mbuf_poolname_build(unsigned int sock_id, char* mp_name, int name_size)
+{
+ rte_snprintf(mp_name, name_size, "mbuf_pool_socket_%u", sock_id);
+}
+
+static inline struct rte_mempool *
+mbuf_pool_find(unsigned int sock_id)
+{
+ char pool_name[RTE_MEMPOOL_NAMESIZE];
+
+ mbuf_poolname_build(sock_id, pool_name, sizeof(pool_name));
+ return (rte_mempool_lookup((const char *)pool_name));
+}
+
+/**
+ * Read/Write operations on a PCI register of a port.
+ */
+static inline uint32_t
+port_pci_reg_read(struct rte_port *port, uint32_t reg_off)
+{
+ void *reg_addr;
+ uint32_t reg_v;
+
+ reg_addr = (void *)((char *)port->dev_info.pci_dev->mem_resource.addr +
+ reg_off);
+ reg_v = *((volatile uint32_t *)reg_addr);
+ return rte_le_to_cpu_32(reg_v);
+}
+
+#define port_id_pci_reg_read(pt_id, reg_off) \
+ port_pci_reg_read(&ports[(pt_id)], (reg_off))
+
+static inline void
+port_pci_reg_write(struct rte_port *port, uint32_t reg_off, uint32_t reg_v)
+{
+ void *reg_addr;
+
+ reg_addr = (void *)((char *)port->dev_info.pci_dev->mem_resource.addr +
+ reg_off);
+ *((volatile uint32_t *)reg_addr) = rte_cpu_to_le_32(reg_v);
+}
+
+#define port_id_pci_reg_write(pt_id, reg_off, reg_value) \
+ port_pci_reg_write(&ports[(pt_id)], (reg_off), (reg_value))
+
+/* Prototypes */
+void launch_args_parse(int argc, char** argv);
+void prompt(void);
+void nic_stats_display(portid_t port_id);
+void nic_stats_clear(portid_t port_id);
+void port_infos_display(portid_t port_id);
+void fwd_lcores_config_display(void);
+void fwd_config_display(void);
+void rxtx_config_display(void);
+void fwd_config_setup(void);
+void set_def_fwd_config(void);
+
+void port_reg_bit_display(portid_t port_id, uint32_t reg_off, uint8_t bit_pos);
+void port_reg_bit_set(portid_t port_id, uint32_t reg_off, uint8_t bit_pos,
+ uint8_t bit_v);
+void port_reg_bit_field_display(portid_t port_id, uint32_t reg_off,
+ uint8_t bit1_pos, uint8_t bit2_pos);
+void port_reg_bit_field_set(portid_t port_id, uint32_t reg_off,
+ uint8_t bit1_pos, uint8_t bit2_pos, uint32_t value);
+void port_reg_display(portid_t port_id, uint32_t reg_off);
+void port_reg_set(portid_t port_id, uint32_t reg_off, uint32_t value);
+
+void rx_ring_desc_display(portid_t port_id, queueid_t rxq_id, uint16_t rxd_id);
+void tx_ring_desc_display(portid_t port_id, queueid_t txq_id, uint16_t txd_id);
+
+void set_fwd_lcores_list(unsigned int *lcorelist, unsigned int nb_lc);
+void set_fwd_lcores_mask(uint64_t lcoremask);
+void set_fwd_lcores_number(uint16_t nb_lc);
+
+void set_fwd_ports_list(unsigned int *portlist, unsigned int nb_pt);
+void set_fwd_ports_mask(uint64_t portmask);
+void set_fwd_ports_number(uint16_t nb_pt);
+
+void rx_vlan_filter_set(portid_t port_id, uint16_t vlan_id, int on);
+void rx_vlan_all_filter_set(portid_t port_id, int on);
+void tx_vlan_set(portid_t port_id, uint16_t vlan_id);
+void tx_vlan_reset(portid_t port_id);
+
+void tx_cksum_set(portid_t port_id, uint8_t cksum_mask);
+
+void set_verbose_level(uint16_t vb_level);
+void set_tx_pkt_segments(unsigned *seg_lengths, unsigned nb_segs);
+void set_nb_pkt_per_burst(uint16_t pkt_burst);
+void set_pkt_forwarding_mode(const char *fwd_mode);
+void start_packet_forwarding(int with_tx_first);
+void stop_packet_forwarding(void);
+void pmd_test_exit(void);
+
+void fdir_add_signature_filter(portid_t port_id, uint8_t queue_id,
+ struct rte_fdir_filter *fdir_filter);
+void fdir_update_signature_filter(portid_t port_id, uint8_t queue_id,
+ struct rte_fdir_filter *fdir_filter);
+void fdir_remove_signature_filter(portid_t port_id,
+ struct rte_fdir_filter *fdir_filter);
+void fdir_get_infos(portid_t port_id);
+void fdir_add_perfect_filter(portid_t port_id, uint16_t soft_id,
+ uint8_t queue_id, uint8_t drop,
+ struct rte_fdir_filter *fdir_filter);
+void fdir_update_perfect_filter(portid_t port_id, uint16_t soft_id,
+ uint8_t queue_id, uint8_t drop,
+ struct rte_fdir_filter *fdir_filter);
+void fdir_remove_perfect_filter(portid_t port_id, uint16_t soft_id,
+ struct rte_fdir_filter *fdir_filter);
+void fdir_set_masks(portid_t port_id, struct rte_fdir_masks *fdir_masks);
+
+/*
+ * Work-around of a compilation error with ICC on invocations of the
+ * rte_be_to_cpu_16() function.
+ */
+#ifdef __GCC__
+#define RTE_BE_TO_CPU_16(be_16_v) rte_be_to_cpu_16((be_16_v))
+#define RTE_CPU_TO_BE_16(cpu_16_v) rte_cpu_to_be_16((cpu_16_v))
+#else
+#ifdef __big_endian__
+#define RTE_BE_TO_CPU_16(be_16_v) (be_16_v)
+#define RTE_CPU_TO_BE_16(cpu_16_v) (cpu_16_v)
+#else
+#define RTE_BE_TO_CPU_16(be_16_v) \
+ (uint16_t) ((((be_16_v) & 0xFF) << 8) | ((be_16_v) >> 8))
+#define RTE_CPU_TO_BE_16(cpu_16_v) \
+ (uint16_t) ((((cpu_16_v) & 0xFF) << 8) | ((cpu_16_v) >> 8))
+#endif
+#endif /* __GCC__ */
+
+#endif /* _TESTPMD_H_ */
diff --git a/app/test-pmd/txonly.c b/app/test-pmd/txonly.c
new file mode 100644
index 0000000..bf0a3e2
--- /dev/null
+++ b/app/test-pmd/txonly.c
@@ -0,0 +1,317 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <sys/queue.h>
+#include <sys/stat.h>
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_ring.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_memcpy.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_ip.h>
+#include <rte_tcp.h>
+#include <rte_udp.h>
+#include <rte_string_fns.h>
+
+#include "testpmd.h"
+
+#define UDP_SRC_PORT 1024
+#define UDP_DST_PORT 1024
+
+#define IP_SRC_ADDR ((192 << 24) | (168 << 16) | (0 << 8) | 1)
+#define IP_DST_ADDR ((192 << 24) | (168 << 16) | (0 << 8) | 2)
+
+#define IP_DEFTTL 64 /* from RFC 1340. */
+#define IP_VERSION 0x40
+#define IP_HDRLEN 0x05 /* default IP header length == five 32-bits words. */
+#define IP_VHL_DEF (IP_VERSION | IP_HDRLEN)
+
+static struct ipv4_hdr pkt_ip_hdr; /**< IP header of transmitted packets. */
+static struct udp_hdr pkt_udp_hdr; /**< UDP header of transmitted packets. */
+
+static inline struct rte_mbuf *
+tx_mbuf_alloc(struct rte_mempool *mp)
+{
+ struct rte_mbuf *m;
+ void *mb;
+
+ if (rte_mempool_get(mp, &mb) < 0)
+ return NULL;
+ m = (struct rte_mbuf *)mb;
+ __rte_mbuf_sanity_check(m, RTE_MBUF_PKT, 1);
+ return m;
+}
+
+static void
+copy_buf_to_pkt_segs(void* buf, unsigned len, struct rte_mbuf *pkt,
+ unsigned offset)
+{
+ struct rte_mbuf *seg;
+ void *seg_buf;
+ unsigned copy_len;
+
+ seg = pkt;
+ while (offset >= seg->pkt.data_len) {
+ offset -= seg->pkt.data_len;
+ seg = seg->pkt.next;
+ }
+ copy_len = seg->pkt.data_len - offset;
+ seg_buf = ((char *) seg->pkt.data + offset);
+ while (len > copy_len) {
+ rte_memcpy(seg_buf, buf, (size_t) copy_len);
+ len -= copy_len;
+ buf = ((char*) buf + copy_len);
+ seg = seg->pkt.next;
+ seg_buf = seg->pkt.data;
+ }
+ rte_memcpy(seg_buf, buf, (size_t) len);
+}
+
+static inline void
+copy_buf_to_pkt(void* buf, unsigned len, struct rte_mbuf *pkt, unsigned offset)
+{
+ if (offset + len <= pkt->pkt.data_len) {
+ rte_memcpy(((char *) pkt->pkt.data + offset), buf, (size_t) len);
+ return;
+ }
+ copy_buf_to_pkt_segs(buf, len, pkt, offset);
+}
+
+static void
+setup_pkt_udp_ip_headers(struct ipv4_hdr *ip_hdr,
+ struct udp_hdr *udp_hdr,
+ uint16_t pkt_data_len)
+{
+ uint16_t *ptr16;
+ uint32_t ip_cksum;
+ uint16_t pkt_len;
+
+ /*
+ * Initialize UDP header.
+ */
+ pkt_len = (uint16_t) (pkt_data_len + sizeof(struct udp_hdr));
+ udp_hdr->src_port = rte_cpu_to_be_16(UDP_SRC_PORT);
+ udp_hdr->dst_port = rte_cpu_to_be_16(UDP_DST_PORT);
+ udp_hdr->dgram_len = RTE_CPU_TO_BE_16(pkt_len);
+ udp_hdr->dgram_cksum = 0; /* No UDP checksum. */
+
+ /*
+ * Initialize IP header.
+ */
+ pkt_len = (uint16_t) (pkt_len + sizeof(struct ipv4_hdr));
+ ip_hdr->version_ihl = IP_VHL_DEF;
+ ip_hdr->type_of_service = 0;
+ ip_hdr->fragment_offset = 0;
+ ip_hdr->time_to_live = IP_DEFTTL;
+ ip_hdr->next_proto_id = IPPROTO_UDP;
+ ip_hdr->packet_id = 0;
+ ip_hdr->total_length = RTE_CPU_TO_BE_16(pkt_len);
+ ip_hdr->src_addr = rte_cpu_to_be_32(IP_SRC_ADDR);
+ ip_hdr->dst_addr = rte_cpu_to_be_32(IP_DST_ADDR);
+
+ /*
+ * Compute IP header checksum.
+ */
+ ptr16 = (uint16_t*) ip_hdr;
+ ip_cksum = 0;
+ ip_cksum += ptr16[0]; ip_cksum += ptr16[1];
+ ip_cksum += ptr16[2]; ip_cksum += ptr16[3];
+ ip_cksum += ptr16[4];
+ ip_cksum += ptr16[6]; ip_cksum += ptr16[7];
+ ip_cksum += ptr16[8]; ip_cksum += ptr16[9];
+
+ /*
+ * Reduce 32 bit checksum to 16 bits and complement it.
+ */
+ ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) +
+ (ip_cksum & 0x0000FFFF);
+ if (ip_cksum > 65535)
+ ip_cksum -= 65535;
+ ip_cksum = (~ip_cksum) & 0x0000FFFF;
+ if (ip_cksum == 0)
+ ip_cksum = 0xFFFF;
+ ip_hdr->hdr_checksum = (uint16_t) ip_cksum;
+}
+
+/*
+ * Transmit a burst of multi-segments packets.
+ */
+static void
+pkt_burst_transmit(struct fwd_stream *fs)
+{
+ struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+ struct rte_mbuf *pkt;
+ struct rte_mbuf *pkt_seg;
+ struct rte_mempool *mbp;
+ struct ether_hdr eth_hdr;
+ uint16_t nb_tx;
+ uint16_t nb_pkt;
+ uint16_t vlan_tci;
+ uint16_t ol_flags;
+ uint8_t i;
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ uint64_t start_tsc;
+ uint64_t end_tsc;
+ uint64_t core_cycles;
+#endif
+
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ start_tsc = rte_rdtsc();
+#endif
+
+ mbp = current_fwd_lcore()->mbp;
+ vlan_tci = ports[fs->tx_port].tx_vlan_id;
+ ol_flags = ports[fs->tx_port].tx_ol_flags;
+ for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) {
+ pkt = tx_mbuf_alloc(mbp);
+ if (pkt == NULL) {
+ nomore_mbuf:
+ if (nb_pkt == 0)
+ return;
+ break;
+ }
+ pkt->pkt.data_len = tx_pkt_seg_lengths[0];
+ pkt_seg = pkt;
+ for (i = 1; i < tx_pkt_nb_segs; i++) {
+ pkt_seg->pkt.next = tx_mbuf_alloc(mbp);
+ if (pkt_seg->pkt.next == NULL) {
+ rte_pktmbuf_free(pkt);
+ goto nomore_mbuf;
+ }
+ pkt_seg = pkt_seg->pkt.next;
+ pkt_seg->pkt.data_len = tx_pkt_seg_lengths[i];
+ }
+ pkt_seg->pkt.next = NULL; /* Last segment of packet. */
+
+ /*
+ * Initialize Ethernet header.
+ */
+ ether_addr_copy(&peer_eth_addrs[fs->peer_addr],&eth_hdr.d_addr);
+ ether_addr_copy(&ports[fs->tx_port].eth_addr, &eth_hdr.s_addr);
+ eth_hdr.ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+
+ /*
+ * Copy headers in first packet segment(s).
+ */
+ copy_buf_to_pkt(&eth_hdr, sizeof(eth_hdr), pkt, 0);
+ copy_buf_to_pkt(&pkt_ip_hdr, sizeof(pkt_ip_hdr), pkt,
+ sizeof(struct ether_hdr));
+ copy_buf_to_pkt(&pkt_udp_hdr, sizeof(pkt_udp_hdr), pkt,
+ sizeof(struct ether_hdr) +
+ sizeof(struct ipv4_hdr));
+
+ /*
+ * Complete first mbuf of packet and append it to the
+ * burst of packets to be transmitted.
+ */
+ pkt->pkt.nb_segs = tx_pkt_nb_segs;
+ pkt->pkt.pkt_len = tx_pkt_length;
+ pkt->ol_flags = ol_flags;
+ pkt->pkt.vlan_tci = vlan_tci;
+ pkt->pkt.l2_len = sizeof(struct ether_hdr);
+ pkt->pkt.l3_len = sizeof(struct ipv4_hdr);
+ pkts_burst[nb_pkt] = pkt;
+ }
+ nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_pkt);
+ fs->tx_packets += nb_tx;
+
+#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
+ fs->tx_burst_stats.pkt_burst_spread[nb_tx]++;
+#endif
+ if (unlikely(nb_tx < nb_pkt)) {
+ if (verbose_level > 0 && fs->fwd_dropped == 0)
+ printf("port %d tx_queue %d - drop "
+ "(nb_pkt:%u - nb_tx:%u)=%u packets\n",
+ fs->tx_port, fs->tx_queue,
+ (unsigned) nb_pkt, (unsigned) nb_tx,
+ (unsigned) (nb_pkt - nb_tx));
+ fs->fwd_dropped += (nb_pkt - nb_tx);
+ do {
+ rte_pktmbuf_free(pkts_burst[nb_tx]);
+ } while (++nb_tx < nb_pkt);
+ }
+
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ end_tsc = rte_rdtsc();
+ core_cycles = (end_tsc - start_tsc);
+ fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
+#endif
+}
+
+static void
+tx_only_begin(__attribute__((unused)) portid_t pi)
+{
+ uint16_t pkt_data_len;
+
+ pkt_data_len = (uint16_t) (tx_pkt_length - (sizeof(struct ether_hdr) +
+ sizeof(struct ipv4_hdr) +
+ sizeof(struct udp_hdr)));
+ setup_pkt_udp_ip_headers(&pkt_ip_hdr, &pkt_udp_hdr, pkt_data_len);
+}
+
+struct fwd_engine tx_only_engine = {
+ .fwd_mode_name = "txonly",
+ .port_fwd_begin = tx_only_begin,
+ .port_fwd_end = NULL,
+ .packet_fwd = pkt_burst_transmit,
+};
diff --git a/app/test/Makefile b/app/test/Makefile
new file mode 100644
index 0000000..80d210d
--- /dev/null
+++ b/app/test/Makefile
@@ -0,0 +1,82 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# version: DPDK.L.1.2.3-3
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+APP = test
+
+#
+# all sources are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_APP_TEST) := commands.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_pci.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_prefetch.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_byteorder.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_per_lcore.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_atomic.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_malloc.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_cycles.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_spinlock.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_memory.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_memzone.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_ring.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_rwlock.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_timer.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_mempool.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_mbuf.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_logs.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_memcpy.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_hash.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_lpm.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_debug.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_errno.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_tailq.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_string_fns.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_mp_secondary.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_cpuflags.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_eal_flags.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_alarm.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_interrupts.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_version.c
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# this application needs libraries first
+DEPDIRS-$(CONFIG_RTE_APP_TEST) += lib
+
+include $(RTE_SDK)/mk/rte.app.mk
diff --git a/app/test/autotest.py b/app/test/autotest.py
new file mode 100755
index 0000000..2609142
--- /dev/null
+++ b/app/test/autotest.py
@@ -0,0 +1,664 @@
+#!/usr/bin/python
+
+# BSD LICENSE
+#
+# Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# version: DPDK.L.1.2.3-3
+
+# Script that uses qemu controlled by python-pexpect to check that
+# all autotests are working in the baremetal environment.
+
+import sys, pexpect, time, os, re
+
+directory = sys.argv[2]
+target = sys.argv[3]
+log_file = "%s.txt"%(target)
+
+if "baremetal" in target:
+ cmdline = "qemu-system-x86_64 -cdrom %s.iso -boot d "%(sys.argv[1])
+ cmdline += "-m 2000 -smp 4 -nographic -net nic,model=e1000"
+ platform = "QEMU x86_64"
+else:
+ cmdline = "%s -c f -n 4"%(sys.argv[1])
+ try:
+ platform = open("/root/rte_platform_model.txt").read()
+ except:
+ platform = "unknown"
+
+print cmdline
+
+report_hdr=""".. <COPYRIGHT_TAG>
+
+"""
+
+test_whitelist=None
+test_blacklist=None
+
+class SubTest:
+ "Defines a subtest"
+ def __init__(self, title, function, command=None, timeout=10, genreport=None):
+ self.title = title
+ self.function = function
+ self.command = command
+ self.timeout = timeout
+ self.genreport = genreport
+
+class AutoTest:
+ """This class contains all methods needed to launch several
+ automatic tests, archive test results, log, and generate a nice
+ test report in restructured text"""
+
+ title = "new"
+ mainlog = None
+ logbuf = None
+ literal = 0
+ test_list = []
+ report_list = []
+ child = None
+
+ def __init__(self, pexpectchild, filename, mode):
+ "Init the Autotest class"
+ self.mainlog = file(filename, mode)
+ self.child = pexpectchild
+ pexpectchild.logfile = self
+ def register(self, filename, title, subtest_list):
+ "Register a test with a list of subtests"
+ test = {}
+ test["filename"] = filename
+ test["title"] = title
+ test["subtest_list"] = subtest_list
+ self.test_list.append(test)
+
+ def start(self):
+ "start the tests, and fill the internal report_list field"
+ for t in self.test_list:
+ report = {}
+ report["date"] = time.asctime()
+ report["title"] = t["title"]
+ report["filename"] = t["filename"]
+ report["subreport_list"] = []
+ report["fails"] = 0
+ report["success"] = 0
+ report["subreport_list"] = []
+ for st in t["subtest_list"]:
+ if test_whitelist is not None and st.title not in test_whitelist:
+ continue
+ if test_blacklist is not None and st.title in test_blacklist:
+ continue
+ subreport = {}
+ self.reportbuf = ""
+ subreport["title"] = st.title
+ subreport["func"] = st.function
+ subreport["command"] = st.command
+ subreport["timeout"] = st.timeout
+ subreport["genreport"] = st.genreport
+
+ # launch subtest
+ print "%s (%s): "%(subreport["title"], subreport["command"]),
+ sys.stdout.flush()
+ start = time.time()
+ res = subreport["func"](self.child,
+ command = subreport["command"],
+ timeout = subreport["timeout"])
+ t = int(time.time() - start)
+
+ subreport["time"] = "%dmn%d"%(t/60, t%60)
+ subreport["result"] = res[0] # 0 or -1
+ subreport["result_str"] = res[1] # cause of fail
+ subreport["logs"] = self.reportbuf
+ print "%s [%s]"%(subreport["result_str"], subreport["time"])
+ if subreport["result"] == 0:
+ report["success"] += 1
+ else:
+ report["fails"] += 1
+ report["subreport_list"].append(subreport)
+ self.report_list.append(report)
+
+ def gen_report(self):
+ for report in self.report_list:
+ # main report header and stats
+ self.literal = 0
+ reportlog = file(report["filename"], "w")
+ reportlog.write(report_hdr)
+ reportlog.write(report["title"] + "\n")
+ reportlog.write(re.sub(".", "=", report["title"]) + "\n\n")
+ reportlog.write("Autogenerated test report:\n\n" )
+ reportlog.write("- date: **%s**\n"%(report["date"]))
+ reportlog.write("- target: **%s**\n"%(target))
+ reportlog.write("- success: **%d**\n"%(report["success"]))
+ reportlog.write("- fails: **%d**\n"%(report["fails"]))
+ reportlog.write("- platform: **%s**\n\n"%(platform))
+
+ # summary
+ reportlog.write(".. csv-table:: Test results summary\n")
+ reportlog.write(' :header: "Name", "Result"\n\n')
+ for subreport in report["subreport_list"]:
+ if subreport["result"] == 0:
+ res_str = "Success"
+ else:
+ res_str = "Failure"
+ reportlog.write(' "%s", "%s"\n'%(subreport["title"], res_str))
+ reportlog.write('\n')
+
+ # subreports
+ for subreport in report["subreport_list"]:
+ # print subtitle
+ reportlog.write(subreport["title"] + "\n")
+ reportlog.write(re.sub(".", "-", subreport["title"]) + "\n\n")
+ # print logs
+ reportlog.write("::\n \n ")
+ s = subreport["logs"].replace("\n", "\n ")
+ reportlog.write(s)
+ # print result
+ reportlog.write("\n\n")
+ reportlog.write("**" + subreport["result_str"] + "**\n\n")
+ # custom genreport
+ if subreport["genreport"] != None:
+ s = subreport["genreport"]()
+ reportlog.write(s)
+
+ reportlog.close()
+
+ # displayed on console
+ print
+ print "-------------------------"
+ print
+ if report["fails"] == 0:
+ print "All test OK"
+ else:
+ print "%s test(s) failed"%(report["fails"])
+
+ # file API, to store logs from pexpect
+ def write(self, buf):
+ s = buf[:]
+ s = s.replace("\r", "")
+ self.mainlog.write(s)
+ self.reportbuf += s
+ def flush(self):
+ self.mainlog.flush()
+ def close(self):
+ self.mainlog.close()
+
+
+# Try to match prompt: return 0 on success, else return -1
+def wait_prompt(child):
+ for i in range(3):
+ index = child.expect(["RTE>>", pexpect.TIMEOUT], timeout = 1)
+ child.sendline("")
+ if index == 0:
+ return 0
+ print "Cannot find prompt"
+ return -1
+
+# Try to match prompt after boot: return 0 on success, else return -1
+def wait_boot(child):
+ index = child.expect(["RTE>>", pexpect.TIMEOUT],
+ timeout = 120)
+ if index == 0:
+ return 0
+ if (wait_prompt(child) == -1):
+ print "Target did not boot, failed"
+ return -1
+ return 0
+
+# quit RTE
+def quit(child):
+ if wait_boot(child) != 0:
+ return -1, "Cannot find prompt"
+ child.sendline("quit")
+ return 0, "Success"
+
+# Default function to launch an autotest that does not need to
+# interact with the user. Basically, this function calls the autotest
+# function through command line interface, then check that it displays
+# "Test OK" or "Test Failed".
+def default_autotest(child, command, timeout=10):
+ if wait_prompt(child) != 0:
+ return -1, "Failed: cannot find prompt"
+ child.sendline(command)
+ index = child.expect(["Test OK", "Test Failed",
+ pexpect.TIMEOUT], timeout = timeout)
+ if index == 1:
+ return -1, "Failed"
+ elif index == 2:
+ return -1, "Failed [Timeout]"
+ return 0, "Success"
+
+# wait boot
+def boot_autotest(child, **kargs):
+ if wait_boot(child) != 0:
+ return -1, "Cannot find prompt"
+ return 0, "Success"
+
+# Test memory dump. We need to check that at least one memory zone is
+# displayed.
+def memory_autotest(child, command, **kargs):
+ if wait_prompt(child) != 0:
+ return -1, "Failed: cannot find prompt"
+ child.sendline(command)
+ regexp = "phys:0x[0-9a-f]*, len:0x([0-9a-f]*), virt:0x[0-9a-f]*, socket_id:[0-9]*"
+ index = child.expect([regexp, pexpect.TIMEOUT], timeout = 180)
+ if index != 0:
+ return -1, "Failed: timeout"
+ size = int(child.match.groups()[0], 16)
+ if size <= 0:
+ return -1, "Failed: bad size"
+ index = child.expect(["Test OK", "Test Failed",
+ pexpect.TIMEOUT], timeout = 10)
+ if index == 1:
+ return -1, "Failed: C code returned an error"
+ elif index == 2:
+ return -1, "Failed: timeout"
+ return 0, "Success"
+
+# Test some libc functions including scanf. This requires a
+# interaction with the user (simulated in expect), so we cannot use
+# default_autotest() here.
+def string_autotest(child, command, **kargs):
+ if wait_prompt(child) != 0:
+ return -1, "Failed: cannot find prompt"
+ child.sendline(command)
+ index = child.expect(["Now, test scanf, enter this number",
+ pexpect.TIMEOUT], timeout = 10)
+ if index != 0:
+ return -1, "Failed: timeout"
+ child.sendline("123456")
+ index = child.expect(["number=123456", pexpect.TIMEOUT], timeout = 10)
+ if index != 0:
+ return -1, "Failed: timeout (2)"
+ index = child.expect(["Test OK", "Test Failed",
+ pexpect.TIMEOUT], timeout = 10)
+ if index != 0:
+ return -1, "Failed: C code returned an error"
+ return 0, "Success"
+
+# Test spinlock. This requires to check the order of displayed lines:
+# we cannot use default_autotest() here.
+def spinlock_autotest(child, command, **kargs):
+ i = 0
+ ir = 0
+ if wait_prompt(child) != 0:
+ return -1, "Failed: cannot find prompt"
+ child.sendline(command)
+ while True:
+ index = child.expect(["Test OK",
+ "Test Failed",
+ "Hello from core ([0-9]*) !",
+ "Hello from within recursive locks from ([0-9]*) !",
+ pexpect.TIMEOUT], timeout = 20)
+ # ok
+ if index == 0:
+ break
+
+ # message, check ordering
+ elif index == 2:
+ if int(child.match.groups()[0]) < i:
+ return -1, "Failed: bad order"
+ i = int(child.match.groups()[0])
+ elif index == 3:
+ if int(child.match.groups()[0]) < ir:
+ return -1, "Failed: bad order"
+ ir = int(child.match.groups()[0])
+
+ # fail
+ else:
+ return -1, "Failed: timeout or error"
+
+ return 0, "Success"
+
+
+# Test rwlock. This requires to check the order of displayed lines:
+# we cannot use default_autotest() here.
+def rwlock_autotest(child, command, **kargs):
+ i = 0
+ if wait_prompt(child) != 0:
+ return -1, "Failed: cannot find prompt"
+ child.sendline(command)
+ while True:
+ index = child.expect(["Test OK",
+ "Test Failed",
+ "Hello from core ([0-9]*) !",
+ "Global write lock taken on master core ([0-9]*)",
+ pexpect.TIMEOUT], timeout = 10)
+ # ok
+ if index == 0:
+ if i != 0xffff:
+ return -1, "Failed: a message is missing"
+ break
+
+ # message, check ordering
+ elif index == 2:
+ if int(child.match.groups()[0]) < i:
+ return -1, "Failed: bad order"
+ i = int(child.match.groups()[0])
+
+ # must be the last message, check ordering
+ elif index == 3:
+ i = 0xffff
+
+ # fail
+ else:
+ return -1, "Failed: timeout or error"
+
+ return 0, "Success"
+
+# Test logs. This requires to check the order of displayed lines:
+# we cannot use default_autotest() here.
+def logs_autotest(child, command, **kargs):
+ i = 0
+ if wait_prompt(child) != 0:
+ return -1, "Failed: cannot find prompt"
+ child.sendline(command)
+
+ log_list = [
+ "TESTAPP1: this is a debug level message",
+ "TESTAPP1: this is a info level message",
+ "TESTAPP1: this is a warning level message",
+ "TESTAPP2: this is a info level message",
+ "TESTAPP2: this is a warning level message",
+ "TESTAPP1: this is a debug level message",
+ "TESTAPP1: this is a debug level message",
+ "TESTAPP1: this is a info level message",
+ "TESTAPP1: this is a warning level message",
+ "TESTAPP2: this is a info level message",
+ "TESTAPP2: this is a warning level message",
+ "TESTAPP1: this is a debug level message",
+ ]
+
+ for log_msg in log_list:
+ index = child.expect([log_msg,
+ "Test OK",
+ "Test Failed",
+ pexpect.TIMEOUT], timeout = 10)
+
+ # not ok
+ if index != 0:
+ return -1, "Failed: timeout or error"
+
+ index = child.expect(["Test OK",
+ "Test Failed",
+ pexpect.TIMEOUT], timeout = 10)
+
+ return 0, "Success"
+
+# Test timers. This requires to check the order of displayed lines:
+# we cannot use default_autotest() here.
+def timer_autotest(child, command, **kargs):
+ i = 0
+ if wait_prompt(child) != 0:
+ return -1, "Failed: cannot find prompt"
+ child.sendline(command)
+
+ index = child.expect(["Start timer stress tests \(30 seconds\)",
+ "Test Failed",
+ pexpect.TIMEOUT], timeout = 10)
+
+ # not ok
+ if index != 0:
+ return -1, "Failed: timeout or error"
+
+ index = child.expect(["Start timer basic tests \(30 seconds\)",
+ "Test Failed",
+ pexpect.TIMEOUT], timeout = 40)
+
+ # not ok
+ if index != 0:
+ return -1, "Failed: timeout or error (2)"
+
+ prev_lcore_timer1 = -1
+
+ lcore_tim0 = -1
+ lcore_tim1 = -1
+ lcore_tim2 = -1
+ lcore_tim3 = -1
+
+ while True:
+ index = child.expect(["TESTTIMER: ([0-9]*): callback id=([0-9]*) count=([0-9]*) on core ([0-9]*)",
+ "Test OK",
+ "Test Failed",
+ pexpect.TIMEOUT], timeout = 10)
+
+ if index == 1:
+ break
+
+ if index != 0:
+ return -1, "Failed: timeout or error (3)"
+
+ try:
+ t = int(child.match.groups()[0])
+ id = int(child.match.groups()[1])
+ cnt = int(child.match.groups()[2])
+ lcore = int(child.match.groups()[3])
+ except:
+ return -1, "Failed: cannot parse output"
+
+ # timer0 always expires on the same core when cnt < 20
+ if id == 0:
+ if lcore_tim0 == -1:
+ lcore_tim0 = lcore
+ elif lcore != lcore_tim0 and cnt < 20:
+ return -1, "Failed: lcore != lcore_tim0 (%d, %d)"%(lcore, lcore_tim0)
+ if cnt > 21:
+ return -1, "Failed: tim0 cnt > 21"
+
+ # timer1 each time expires on a different core
+ if id == 1:
+ if lcore == lcore_tim1:
+ return -1, "Failed: lcore == lcore_tim1 (%d, %d)"%(lcore, lcore_tim1)
+ lcore_tim1 = lcore
+ if cnt > 10:
+ return -1, "Failed: tim1 cnt > 30"
+
+ # timer0 always expires on the same core
+ if id == 2:
+ if lcore_tim2 == -1:
+ lcore_tim2 = lcore
+ elif lcore != lcore_tim2:
+ return -1, "Failed: lcore != lcore_tim2 (%d, %d)"%(lcore, lcore_tim2)
+ if cnt > 30:
+ return -1, "Failed: tim2 cnt > 30"
+
+ # timer0 always expires on the same core
+ if id == 3:
+ if lcore_tim3 == -1:
+ lcore_tim3 = lcore
+ elif lcore != lcore_tim3:
+ return -1, "Failed: lcore_tim3 changed (%d -> %d)"%(lcore, lcore_tim3)
+ if cnt > 30:
+ return -1, "Failed: tim3 cnt > 30"
+
+ # must be 2 different cores
+ if lcore_tim0 == lcore_tim3:
+ return -1, "Failed: lcore_tim0 (%d) == lcore_tim3 (%d)"%(lcore_tim0, lcore_tim3)
+
+ return 0, "Success"
+
+# Ring autotest
+def ring_autotest(child, command, timeout=10):
+ if wait_prompt(child) != 0:
+ return -1, "Failed: cannot find prompt"
+ child.sendline(command)
+ index = child.expect(["Test OK", "Test Failed",
+ pexpect.TIMEOUT], timeout = timeout)
+ if index != 0:
+ return -1, "Failed"
+
+ child.sendline("set_watermark test 100")
+ child.sendline("set_quota test 16")
+ child.sendline("dump_ring test")
+ index = child.expect([" watermark=100",
+ pexpect.TIMEOUT], timeout = 1)
+ if index != 0:
+ return -1, "Failed: bad watermark"
+
+ index = child.expect([" bulk_default=16",
+ pexpect.TIMEOUT], timeout = 1)
+ if index != 0:
+ return -1, "Failed: bad quota"
+
+ return 0, "Success"
+
+def ring_genreport():
+ s = "Performance curves\n"
+ s += "------------------\n\n"
+ sdk = os.getenv("RTE_SDK")
+ script = os.path.join(sdk, "app/test/graph_ring.py")
+ title ='"Autotest %s %s"'%(target, time.asctime())
+ filename = target + ".txt"
+ os.system("/usr/bin/python %s %s %s"%(script, filename, title))
+ for f in os.listdir("."):
+ if not f.startswith("ring"):
+ continue
+ if not f.endswith(".svg"):
+ continue
+ # skip single producer/consumer
+ if "_sc" in f:
+ continue
+ if "_sp" in f:
+ continue
+ f = f[:-4] + ".png"
+ s += ".. figure:: ../../images/autotests/%s/%s\n"%(target, f)
+ s += " :width: 50%\n\n"
+ s += " %s\n\n"%(f)
+ return s
+
+def mempool_genreport():
+ s = "Performance curves\n"
+ s += "------------------\n\n"
+ sdk = os.getenv("RTE_SDK")
+ script = os.path.join(sdk, "app/test/graph_mempool.py")
+ title ='"Autotest %s %s"'%(target, time.asctime())
+ filename = target + ".txt"
+ os.system("/usr/bin/python %s %s %s"%(script, filename, title))
+ for f in os.listdir("."):
+ if not f.startswith("mempool"):
+ continue
+ if not f.endswith(".svg"):
+ continue
+ # skip when n_keep = 128
+ if "_128." in f:
+ continue
+ f = f[:-4] + ".png"
+ s += ".. figure:: ../../images/autotests/%s/%s\n"%(target, f)
+ s += " :width: 50%\n\n"
+ s += " %s\n\n"%(f)
+ return s
+
+#
+# main
+#
+
+if len(sys.argv) > 4:
+ testlist=sys.argv[4].split(',')
+ if testlist[0].startswith('-'):
+ testlist[0]=testlist[0].lstrip('-')
+ test_blacklist=testlist
+ else:
+ test_whitelist=testlist
+
+child = pexpect.spawn(cmdline)
+autotest = AutoTest(child, log_file,'w')
+
+# timeout for memcpy and hash test
+if "baremetal" in target:
+ timeout = 60*180
+else:
+ timeout = 180
+
+autotest.register("eal_report.rst", "EAL-%s"%(target),
+ [ SubTest("Boot", boot_autotest, "boot_autotest"),
+ SubTest("EAL Flags", default_autotest, "eal_flags_autotest"),
+ SubTest("Version", default_autotest, "version_autotest"),
+ SubTest("PCI", default_autotest, "pci_autotest"),
+ SubTest("Memory", memory_autotest, "memory_autotest"),
+ SubTest("Lcore launch", default_autotest, "per_lcore_autotest"),
+ SubTest("Spinlock", spinlock_autotest, "spinlock_autotest"),
+ SubTest("Rwlock", rwlock_autotest, "rwlock_autotest"),
+ SubTest("Atomic", default_autotest, "atomic_autotest"),
+ SubTest("Byte order", default_autotest, "byteorder_autotest"),
+ SubTest("Prefetch", default_autotest, "prefetch_autotest"),
+ SubTest("Debug", default_autotest, "debug_autotest"),
+ SubTest("Cycles", default_autotest, "cycles_autotest"),
+ SubTest("Logs", logs_autotest, "logs_autotest"),
+ SubTest("Memzone", default_autotest, "memzone_autotest"),
+ SubTest("Cpu flags", default_autotest, "cpuflags_autotest"),
+ SubTest("Memcpy", default_autotest, "memcpy_autotest", timeout),
+ SubTest("String Functions", default_autotest, "string_autotest"),
+ SubTest("Alarm", default_autotest, "alarm_autotest", 30),
+ SubTest("Interrupt", default_autotest, "interrupt_autotest"),
+ ])
+
+autotest.register("ring_report.rst", "Ring-%s"%(target),
+ [ SubTest("Ring", ring_autotest, "ring_autotest", 30*60,
+ ring_genreport)
+ ])
+
+if "baremetal" in target:
+ timeout = 60*60*3
+else:
+ timeout = 60*30
+
+autotest.register("mempool_report.rst", "Mempool-%s"%(target),
+ [ SubTest("Mempool", default_autotest, "mempool_autotest",
+ timeout, mempool_genreport)
+ ])
+autotest.register("mbuf_report.rst", "Mbuf-%s"%(target),
+ [ SubTest("Mbuf", default_autotest, "mbuf_autotest", timeout=120)
+ ])
+autotest.register("timer_report.rst", "Timer-%s"%(target),
+ [ SubTest("Timer", timer_autotest, "timer_autotest")
+ ])
+autotest.register("malloc_report.rst", "Malloc-%s"%(target),
+ [ SubTest("Malloc", default_autotest, "malloc_autotest")
+ ])
+
+# only do the hash autotest if supported by the platform
+if not (platform.startswith("Intel(R) Core(TM)2 Quad CPU") or
+ platform.startswith("QEMU")):
+ autotest.register("hash_report.rst", "Hash-%s"%(target),
+ [ SubTest("Hash", default_autotest, "hash_autotest", timeout)
+ ])
+
+autotest.register("lpm_report.rst", "LPM-%s"%(target),
+ [ SubTest("Lpm", default_autotest, "lpm_autotest", timeout)
+ ])
+autotest.register("eal2_report.rst", "EAL2-%s"%(target),
+ [ SubTest("TailQ", default_autotest, "tailq_autotest"),
+ SubTest("Errno", default_autotest, "errno_autotest"),
+ SubTest("Multiprocess", default_autotest, "multiprocess_autotest")
+ ])
+
+autotest.start()
+autotest.gen_report()
+
+quit(child)
+child.terminate()
+sys.exit(0)
diff --git a/app/test/commands.c b/app/test/commands.c
new file mode 100644
index 0000000..a1d23d8
--- /dev/null
+++ b/app/test/commands.c
@@ -0,0 +1,391 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <termios.h>
+#ifndef __linux__
+#include <net/socket.h>
+#endif
+#include <inttypes.h>
+#include <errno.h>
+#include <sys/queue.h>
+
+#include <rte_common.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_cycles.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_timer.h>
+
+#include <cmdline_rdline.h>
+#include <cmdline_parse.h>
+#include <cmdline_parse_ipaddr.h>
+#include <cmdline_parse_num.h>
+#include <cmdline_parse_string.h>
+#include <cmdline.h>
+
+#include "test.h"
+
+/****************/
+
+struct cmd_autotest_result {
+ cmdline_fixed_string_t autotest;
+};
+
+static void cmd_autotest_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_autotest_result *res = parsed_result;
+ int ret = 0;
+ int all = 0;
+
+ if (!strcmp(res->autotest, "all_autotests"))
+ all = 1;
+
+ if (all || !strcmp(res->autotest, "version_autotest"))
+ ret |= test_version();
+ if (all || !strcmp(res->autotest, "debug_autotest"))
+ ret |= test_debug();
+ if (all || !strcmp(res->autotest, "pci_autotest"))
+ ret |= test_pci();
+ if (all || !strcmp(res->autotest, "prefetch_autotest"))
+ ret |= test_prefetch();
+ if (all || !strcmp(res->autotest, "byteorder_autotest"))
+ ret |= test_byteorder();
+ if (all || !strcmp(res->autotest, "per_lcore_autotest"))
+ ret |= test_per_lcore();
+ if (all || !strcmp(res->autotest, "atomic_autotest"))
+ ret |= test_atomic();
+ if (all || !strcmp(res->autotest, "malloc_autotest"))
+ ret |= test_malloc();
+ if (all || !strcmp(res->autotest, "spinlock_autotest"))
+ ret |= test_spinlock();
+ if (all || !strcmp(res->autotest, "memory_autotest"))
+ ret |= test_memory();
+ if (all || !strcmp(res->autotest, "memzone_autotest"))
+ ret |= test_memzone();
+ if (all || !strcmp(res->autotest, "rwlock_autotest"))
+ ret |= test_rwlock();
+ if (all || !strcmp(res->autotest, "mbuf_autotest"))
+ ret |= test_mbuf();
+ if (all || !strcmp(res->autotest, "logs_autotest"))
+ ret |= test_logs();
+ if (all || !strcmp(res->autotest, "errno_autotest"))
+ ret |= test_errno();
+ if (all || !strcmp(res->autotest, "hash_autotest"))
+ ret |= test_hash();
+ if (all || !strcmp(res->autotest, "lpm_autotest"))
+ ret |= test_lpm();
+ if (all || !strcmp(res->autotest, "cpuflags_autotest"))
+ ret |= test_cpuflags();
+ /* tailq autotest must go after all lpm and hashs tests or any other
+ * tests which need to create tailq objects (ring and mempool are implicitly
+ * created in earlier tests so can go later)
+ */
+ if (all || !strcmp(res->autotest, "tailq_autotest"))
+ ret |= test_tailq();
+ if (all || !strcmp(res->autotest, "multiprocess_autotest"))
+ ret |= test_mp_secondary();
+ if (all || !strcmp(res->autotest, "memcpy_autotest"))
+ ret |= test_memcpy();
+ if (all || !strcmp(res->autotest, "string_autotest"))
+ ret |= test_string_fns();
+ if (all || !strcmp(res->autotest, "eal_flags_autotest"))
+ ret |= test_eal_flags();
+ if (all || !strcmp(res->autotest, "alarm_autotest"))
+ ret |= test_alarm();
+ if (all || !strcmp(res->autotest, "interrupt_autotest"))
+ ret |= test_interrupt();
+ if (all || !strcmp(res->autotest, "cycles_autotest"))
+ ret |= test_cycles();
+ if (all || !strcmp(res->autotest, "ring_autotest"))
+ ret |= test_ring();
+ if (all || !strcmp(res->autotest, "timer_autotest"))
+ ret |= test_timer();
+ if (all || !strcmp(res->autotest, "mempool_autotest"))
+ ret |= test_mempool();
+
+ if (ret == 0)
+ printf("Test OK\n");
+ else
+ printf("Test Failed\n");
+ fflush(stdout);
+}
+
+cmdline_parse_token_string_t cmd_autotest_autotest =
+ TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest,
+ "pci_autotest#memory_autotest#"
+ "per_lcore_autotest#spinlock_autotest#"
+ "rwlock_autotest#atomic_autotest#"
+ "byteorder_autotest#prefetch_autotest#"
+ "cycles_autotest#logs_autotest#"
+ "memzone_autotest#ring_autotest#"
+ "mempool_autotest#mbuf_autotest#"
+ "timer_autotest#malloc_autotest#"
+ "memcpy_autotest#hash_autotest#"
+ "lpm_autotest#debug_autotest#"
+ "errno_autotest#tailq_autotest#"
+ "string_autotest#multiprocess_autotest#"
+ "cpuflags_autotest#eal_flags_autotest#"
+ "alarm_autotest#interrupt_autotest#"
+ "version_autotest#"
+ "all_autotests");
+
+cmdline_parse_inst_t cmd_autotest = {
+ .f = cmd_autotest_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = "launch autotest",
+ .tokens = { /* token list, NULL terminated */
+ (void *)&cmd_autotest_autotest,
+ NULL,
+ },
+};
+
+/****************/
+
+struct cmd_dump_result {
+ cmdline_fixed_string_t dump;
+};
+
+static void
+dump_struct_sizes(void)
+{
+#define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t));
+ DUMP_SIZE(struct rte_mbuf);
+ DUMP_SIZE(struct rte_pktmbuf);
+ DUMP_SIZE(struct rte_ctrlmbuf);
+ DUMP_SIZE(struct rte_mempool);
+ DUMP_SIZE(struct rte_ring);
+#undef DUMP_SIZE
+}
+
+static void cmd_dump_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_dump_result *res = parsed_result;
+
+ if (!strcmp(res->dump, "dump_physmem"))
+ rte_dump_physmem_layout();
+ else if (!strcmp(res->dump, "dump_memzone"))
+ rte_memzone_dump();
+ else if (!strcmp(res->dump, "dump_log_history"))
+ rte_log_dump_history();
+ else if (!strcmp(res->dump, "dump_struct_sizes"))
+ dump_struct_sizes();
+ else if (!strcmp(res->dump, "dump_ring"))
+ rte_ring_list_dump();
+ else if (!strcmp(res->dump, "dump_mempool"))
+ rte_mempool_list_dump();
+}
+
+cmdline_parse_token_string_t cmd_dump_dump =
+ TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
+ "dump_physmem#dump_memzone#dump_log_history#"
+ "dump_struct_sizes#dump_ring#dump_mempool");
+
+cmdline_parse_inst_t cmd_dump = {
+ .f = cmd_dump_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = "dump status",
+ .tokens = { /* token list, NULL terminated */
+ (void *)&cmd_dump_dump,
+ NULL,
+ },
+};
+
+/****************/
+
+struct cmd_dump_one_result {
+ cmdline_fixed_string_t dump;
+ cmdline_fixed_string_t name;
+};
+
+static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_dump_one_result *res = parsed_result;
+
+ if (!strcmp(res->dump, "dump_ring")) {
+ struct rte_ring *r;
+ r = rte_ring_lookup(res->name);
+ if (r == NULL) {
+ cmdline_printf(cl, "Cannot find ring\n");
+ return;
+ }
+ rte_ring_dump(r);
+ }
+ else if (!strcmp(res->dump, "dump_mempool")) {
+ struct rte_mempool *mp;
+ mp = rte_mempool_lookup(res->name);
+ if (mp == NULL) {
+ cmdline_printf(cl, "Cannot find mempool\n");
+ return;
+ }
+ rte_mempool_dump(mp);
+ }
+}
+
+cmdline_parse_token_string_t cmd_dump_one_dump =
+ TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump,
+ "dump_ring#dump_mempool");
+
+cmdline_parse_token_string_t cmd_dump_one_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL);
+
+cmdline_parse_inst_t cmd_dump_one = {
+ .f = cmd_dump_one_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = "dump one ring/mempool: dump_ring|dump_mempool <name>",
+ .tokens = { /* token list, NULL terminated */
+ (void *)&cmd_dump_one_dump,
+ (void *)&cmd_dump_one_name,
+ NULL,
+ },
+};
+
+/****************/
+
+struct cmd_set_ring_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t name;
+ uint32_t value;
+};
+
+static void cmd_set_ring_parsed(void *parsed_result, struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_ring_result *res = parsed_result;
+ struct rte_ring *r;
+ int ret;
+
+ r = rte_ring_lookup(res->name);
+ if (r == NULL) {
+ cmdline_printf(cl, "Cannot find ring\n");
+ return;
+ }
+
+ if (!strcmp(res->set, "set_quota")) {
+ ret = rte_ring_set_bulk_count(r, res->value);
+ if (ret != 0)
+ cmdline_printf(cl, "Cannot set quota\n");
+ }
+ else if (!strcmp(res->set, "set_watermark")) {
+ ret = rte_ring_set_water_mark(r, res->value);
+ if (ret != 0)
+ cmdline_printf(cl, "Cannot set water mark\n");
+ }
+}
+
+cmdline_parse_token_string_t cmd_set_ring_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, set,
+ "set_quota#set_watermark");
+
+cmdline_parse_token_string_t cmd_set_ring_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, name, NULL);
+
+cmdline_parse_token_num_t cmd_set_ring_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_ring_result, value, UINT32);
+
+cmdline_parse_inst_t cmd_set_ring = {
+ .f = cmd_set_ring_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = "set quota/watermark: "
+ "set_quota|set_watermark <ring_name> <value>",
+ .tokens = { /* token list, NULL terminated */
+ (void *)&cmd_set_ring_set,
+ (void *)&cmd_set_ring_name,
+ (void *)&cmd_set_ring_value,
+ NULL,
+ },
+};
+
+/****************/
+
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void
+cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit,
+ "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = "exit application",
+ .tokens = { /* token list, NULL terminated */
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/****************/
+
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_autotest,
+ (cmdline_parse_inst_t *)&cmd_dump,
+ (cmdline_parse_inst_t *)&cmd_dump_one,
+ (cmdline_parse_inst_t *)&cmd_set_ring,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
diff --git a/app/test/graph_mempool.py b/app/test/graph_mempool.py
new file mode 100755
index 0000000..46e3e7b
--- /dev/null
+++ b/app/test/graph_mempool.py
@@ -0,0 +1,193 @@
+#!/usr/bin/env python
+
+# BSD LICENSE
+#
+# Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# version: DPDK.L.1.2.3-3
+
+import sys, re
+import numpy as np
+import matplotlib
+matplotlib.use('Agg') # we don't want to use X11
+import matplotlib.pyplot as plt
+from matplotlib.ticker import FuncFormatter
+
+INT = "([-+]?[0-9][0-9]*)"
+
+class MempoolTest:
+ l = []
+
+ def __init__(self):
+ pass
+
+ # sort a test case list
+ def sort(self, x, y):
+ for t in [ "cache", "cores", "n_get_bulk", "n_put_bulk",
+ "n_keep", "rate" ]:
+ if x[t] > y[t]:
+ return 1
+ if x[t] < y[t]:
+ return -1
+ return 0
+
+ # add a test case
+ def add(self, **args):
+ self.l.append(args)
+
+ # get an ordered list matching parameters
+ # ex: r.get(enq_core=1, deq_core=1)
+ def get(self, **args):
+ retlist = []
+ for t in self.l:
+ add_it = 1
+ for a in args:
+ if args[a] != t[a]:
+ add_it = 0
+ break
+ if add_it:
+ retlist.append(t)
+ retlist.sort(cmp=self.sort)
+ return retlist
+
+ # return an ordered list of all values for this param or param list
+ # ex: r.get_value_list("enq_core")
+ def get_value_list(self, param):
+ retlist = []
+ if type(param) is not list:
+ param = [param]
+ for t in self.l:
+ entry = []
+ for p in param:
+ entry.append(t[p])
+ if len(entry) == 1:
+ entry = entry[0]
+ else:
+ entry = tuple(entry)
+ if not entry in retlist:
+ retlist.append(entry)
+ retlist.sort()
+ return retlist
+
+# read the file and return a MempoolTest object containing all data
+def read_data_from_file(filename):
+
+ mempool_test = MempoolTest()
+
+ # parse the file: it produces a list of dict containing the data for
+ # each test case (each dict in the list corresponds to a line)
+ f = open(filename)
+ while True:
+ l = f.readline()
+
+ if l == "":
+ break
+
+ regexp = "mempool_autotest "
+ regexp += "cache=%s cores=%s "%(INT, INT)
+ regexp += "n_get_bulk=%s n_put_bulk=%s "%(INT, INT)
+ regexp += "n_keep=%s rate_persec=%s"%(INT, INT)
+ m = re.match(regexp, l)
+ if m == None:
+ continue
+
+ mempool_test.add(cache = int(m.groups()[0]),
+ cores = int(m.groups()[1]),
+ n_get_bulk = int(m.groups()[2]),
+ n_put_bulk = int(m.groups()[3]),
+ n_keep = int(m.groups()[4]),
+ rate = int(m.groups()[5]))
+
+ f.close()
+ return mempool_test
+
+def millions(x, pos):
+ return '%1.1fM' % (x*1e-6)
+
+# graph one, with specific parameters -> generate a .svg file
+def graph_one(str, mempool_test, cache, cores, n_keep):
+ filename = "mempool_%d_%d_%d.svg"%(cache, cores, n_keep)
+
+ n_get_bulk_list = mempool_test.get_value_list("n_get_bulk")
+ N_n_get_bulk = len(n_get_bulk_list)
+ get_names = map(lambda x:"get=%d"%x, n_get_bulk_list)
+
+ n_put_bulk_list = mempool_test.get_value_list("n_put_bulk")
+ N_n_put_bulk = len(n_put_bulk_list)
+ put_names = map(lambda x:"put=%d"%x, n_put_bulk_list)
+
+ N = N_n_get_bulk * (N_n_put_bulk + 1)
+ rates = []
+
+ colors = []
+ for n_get_bulk in mempool_test.get_value_list("n_get_bulk"):
+ col = 0.
+ for n_put_bulk in mempool_test.get_value_list("n_put_bulk"):
+ col += 0.9 / len(mempool_test.get_value_list("n_put_bulk"))
+ r = mempool_test.get(cache=cache, cores=cores,
+ n_get_bulk=n_get_bulk,
+ n_put_bulk=n_put_bulk, n_keep=n_keep)
+ if len(r) != 0:
+ r = r[0]["rate"]
+ rates.append(r)
+ colors.append((1. - col, 0.2, col, 1.)) # rgba
+
+ rates.append(0)
+ colors.append((0.,0.,0.,0.))
+
+ ind = np.arange(N) # the x locations for the groups
+ width = 1 # the width of the bars: can also be len(x) sequence
+
+
+ formatter = FuncFormatter(millions)
+ fig = plt.figure()
+ p = plt.bar(ind, tuple(rates), width, color=tuple(colors))
+ fig.axes[0].yaxis.set_major_formatter(formatter)
+
+ plt.ylabel('Obj/sec')
+ #plt.ylim(0, 400000000.)
+ title = "Mempool autotest \"%s\"\n"%(str)
+ title += "cache=%d, core(s)=%d, n_keep=%d"%(cache, cores, n_keep)
+ plt.title(title)
+ ind_names = np.arange(N_n_get_bulk) * (N_n_put_bulk+1) + (N_n_put_bulk+1) / 2
+ plt.xticks(ind_names, tuple(get_names))
+ plt.legend(tuple([p[i] for i in range(N_n_put_bulk)]), tuple(put_names),
+ loc="upper left")
+ plt.savefig(filename)
+
+if len(sys.argv) != 3:
+ print "usage: graph_mempool.py file title"
+ sys.exit(1)
+
+mempool_test = read_data_from_file(sys.argv[1])
+
+for cache, cores, n_keep in mempool_test.get_value_list(["cache", "cores",
+ "n_keep"]):
+ graph_one(sys.argv[2], mempool_test, cache, cores, n_keep)
diff --git a/app/test/graph_ring.py b/app/test/graph_ring.py
new file mode 100755
index 0000000..02c4228
--- /dev/null
+++ b/app/test/graph_ring.py
@@ -0,0 +1,201 @@
+#!/usr/bin/env python
+
+# BSD LICENSE
+#
+# Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# version: DPDK.L.1.2.3-3
+
+import sys, re
+import numpy as np
+import matplotlib
+matplotlib.use('Agg') # we don't want to use X11
+import matplotlib.pyplot as plt
+from matplotlib.ticker import FuncFormatter
+
+INT = "([-+]?[0-9][0-9]*)"
+
+class RingTest:
+ l = []
+
+ def __init__(self):
+ pass
+
+ # sort a test case list
+ def sort(self, x, y):
+ for t in [ "enq_core", "deq_core", "enq_bulk", "deq_bulk", "rate" ]:
+ if x[t] > y[t]:
+ return 1
+ if x[t] < y[t]:
+ return -1
+ return 0
+
+ # add a test case
+ def add(self, **args):
+ self.l.append(args)
+
+ # get an ordered list matching parameters
+ # ex: r.get(enq_core=1, deq_core=1)
+ def get(self, **args):
+ retlist = []
+ for t in self.l:
+ add_it = 1
+ for a in args:
+ if args[a] != t[a]:
+ add_it = 0
+ break
+ if add_it:
+ retlist.append(t)
+ retlist.sort(cmp=self.sort)
+ return retlist
+
+ # return an ordered list of all values for this param or param list
+ # ex: r.get_value_list("enq_core")
+ def get_value_list(self, param):
+ retlist = []
+ if type(param) is not list:
+ param = [param]
+ for t in self.l:
+ entry = []
+ for p in param:
+ entry.append(t[p])
+ if len(entry) == 1:
+ entry = entry[0]
+ else:
+ entry = tuple(entry)
+ if not entry in retlist:
+ retlist.append(entry)
+ retlist.sort()
+ return retlist
+
+# read the file and return a RingTest object containing all data
+def read_data_from_file(filename):
+
+ ring_test = RingTest()
+
+ # parse the file: it produces a list of dict containing the data for
+ # each test case (each dict in the list corresponds to a line)
+ f = open(filename)
+ while True:
+ l = f.readline()
+
+ if l == "":
+ break
+
+ regexp = "ring_autotest "
+ regexp += "e/d_core=%s,%s e/d_bulk=%s,%s "%(INT, INT, INT, INT)
+ regexp += "sp=%s sc=%s "%(INT, INT)
+ regexp += "rate_persec=%s"%(INT)
+ m = re.match(regexp, l)
+ if m == None:
+ continue
+
+ ring_test.add(enq_core = int(m.groups()[0]),
+ deq_core = int(m.groups()[1]),
+ enq_bulk = int(m.groups()[2]),
+ deq_bulk = int(m.groups()[3]),
+ sp = int(m.groups()[4]),
+ sc = int(m.groups()[5]),
+ rate = int(m.groups()[6]))
+
+ f.close()
+ return ring_test
+
+def millions(x, pos):
+ return '%1.1fM' % (x*1e-6)
+
+# graph one, with specific parameters -> generate a .svg file
+def graph_one(str, ring_test, enq_core, deq_core, sp, sc):
+ filename = "ring_%d_%d"%(enq_core, deq_core)
+ if sp:
+ sp_str = "sp"
+ else:
+ sp_str = "mp"
+ if sc:
+ sc_str = "sc"
+ else:
+ sc_str = "mc"
+ filename += "_%s_%s.svg"%(sp_str, sc_str)
+
+
+ enq_bulk_list = ring_test.get_value_list("enq_bulk")
+ N_enq_bulk = len(enq_bulk_list)
+ enq_names = map(lambda x:"enq=%d"%x, enq_bulk_list)
+
+ deq_bulk_list = ring_test.get_value_list("deq_bulk")
+ N_deq_bulk = len(deq_bulk_list)
+ deq_names = map(lambda x:"deq=%d"%x, deq_bulk_list)
+
+ N = N_enq_bulk * (N_deq_bulk + 1)
+ rates = []
+
+ colors = []
+ for enq_bulk in ring_test.get_value_list("enq_bulk"):
+ col = 0.
+ for deq_bulk in ring_test.get_value_list("deq_bulk"):
+ col += 0.9 / len(ring_test.get_value_list("deq_bulk"))
+ r = ring_test.get(enq_core=enq_core, deq_core=deq_core,
+ enq_bulk=enq_bulk, deq_bulk=deq_bulk,
+ sp=sp, sc=sc)
+ r = r[0]["rate"]
+ rates.append(r)
+ colors.append((1. - col, 0.2, col, 1.)) # rgba
+
+ rates.append(0)
+ colors.append((0.,0.,0.,0.))
+
+ ind = np.arange(N) # the x locations for the groups
+ width = 1 # the width of the bars: can also be len(x) sequence
+
+
+ formatter = FuncFormatter(millions)
+ fig = plt.figure()
+ p = plt.bar(ind, tuple(rates), width, color=tuple(colors))
+ fig.axes[0].yaxis.set_major_formatter(formatter)
+
+ plt.ylabel('Obj/sec')
+ #plt.ylim(0, 400000000.)
+ plt.title("Ring autotest \"%s\"\nenq core(s)=%d, deq core(s)=%d, %s, %s"\
+ %(str, enq_core, deq_core, sp_str, sc_str))
+ ind_names = np.arange(N_enq_bulk) * (N_deq_bulk+1) + (N_deq_bulk+1) / 2
+ plt.xticks(ind_names, tuple(enq_names))
+ plt.legend(tuple([p[i] for i in range(N_deq_bulk)]), tuple(deq_names),
+ loc="upper left")
+ plt.savefig(filename)
+
+if len(sys.argv) != 3:
+ print "usage: graph_ring.py file title"
+ sys.exit(1)
+
+ring_test = read_data_from_file(sys.argv[1])
+
+for enq_core, deq_core, sp, sc in \
+ ring_test.get_value_list(["enq_core", "deq_core", "sp", "sc"]):
+ graph_one(sys.argv[2], ring_test, enq_core, deq_core, sp, sc)
diff --git a/app/test/process.h b/app/test/process.h
new file mode 100644
index 0000000..0dbc898
--- /dev/null
+++ b/app/test/process.h
@@ -0,0 +1,89 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#ifndef _PROCESS_H_
+#define _PROCESS_H_
+
+#ifndef RTE_EXEC_ENV_BAREMETAL
+
+/*
+ * launches a second copy of the test process using the given argv parameters,
+ * which should include argv[0] as the process name. To identify in the
+ * subprocess the source of the call, the env_value parameter is set in the
+ * environment as $RTE_TEST
+ */
+static inline int
+process_dup(const char *const argv[], int numargs, const char *env_value)
+{
+ char *argv_cpy[numargs + 1];
+ int i, fd, status;
+ char path[32];
+
+ pid_t pid = fork();
+ if (pid < 0)
+ return -1;
+ else if (pid == 0) {
+ /* make a copy of the arguments to be passed to exec */
+ for (i = 0; i < numargs; i++)
+ argv_cpy[i] = strdup(argv[i]);
+ argv_cpy[i] = NULL;
+
+ /* close all open file descriptors, check /proc/self/fd to only
+ * call close on open fds. Exclude fds 0, 1 and 2*/
+ for (fd = getdtablesize(); fd > 2; fd-- ) {
+ rte_snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
+ if (access(path, F_OK) == 0)
+ close(fd);
+ }
+ printf("Running binary with argv[]:");
+ for (i = 0; i < numargs; i++)
+ printf("'%s' ", argv_cpy[i]);
+ printf("\n");
+
+ /* set the environment variable */
+ if (setenv(RECURSIVE_ENV_VAR, env_value, 1) != 0)
+ rte_panic("Cannot export environment variable\n");
+ if (execv("/proc/self/exe", argv_cpy) < 0)
+ rte_panic("Cannot exec\n");
+ }
+ /* parent process does a wait */
+ while (wait(&status) != pid)
+ ;
+ return status;
+}
+
+#endif /* not baremetal */
+
+#endif /* _PROCESS_H_ */
diff --git a/app/test/test.c b/app/test/test.c
new file mode 100644
index 0000000..f98656c
--- /dev/null
+++ b/app/test/test.c
@@ -0,0 +1,153 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <termios.h>
+#include <ctype.h>
+#include <sys/queue.h>
+
+#include <cmdline_rdline.h>
+#include <cmdline_parse.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_timer.h>
+#include <rte_string_fns.h>
+
+#include "test.h"
+
+const char *prgname; /* to be set to argv[0] */
+
+#ifndef RTE_EXEC_ENV_BAREMETAL
+static const char *recursive_call; /* used in linuxapp for MP and other tests */
+
+static int
+no_action(void){ return 0; }
+
+static int
+do_recursive_call(void)
+{
+ unsigned i;
+ struct {
+ const char *env_var;
+ int (*action_fn)(void);
+ } actions[] = {
+ { "run_secondary_instances", test_mp_secondary },
+ { "test_missing_c_flag", no_action },
+ { "test_missing_n_flag", no_action },
+ { "test_no_hpet_flag", no_action },
+ { "test_invalid_b_flag", no_action },
+ { "test_invalid_r_flag", no_action },
+ { "test_misc_flags", no_action },
+ };
+
+ if (recursive_call == NULL)
+ return -1;
+ for (i = 0; i < sizeof(actions)/sizeof(actions[0]); i++) {
+ if (strcmp(actions[i].env_var, recursive_call) == 0)
+ return (actions[i].action_fn)();
+ }
+ return -1;
+}
+#endif
+
+void
+test_hexdump(const char *title, const void *buf, unsigned int len)
+{
+ unsigned int i, out, ofs;
+ const unsigned char *data = buf;
+#define LINE_LEN 80
+ char line[LINE_LEN]; /* space needed 8+16*3+3+16 == 75 */
+
+ printf("%s at [%p], len=%u\n", title, data, len);
+ ofs = 0;
+ while (ofs < len) {
+ /* format 1 line in the buffer, then use printf to print them */
+ out = rte_snprintf(line, LINE_LEN, "%08X", ofs);
+ for (i = 0; ofs+i < len && i < 16; i++)
+ out += rte_snprintf(line+out, LINE_LEN - out, " %02X",
+ data[ofs+i]&0xff);
+ for(; i <= 16; i++)
+ out += rte_snprintf(line+out, LINE_LEN - out, " ");
+ for(i = 0; ofs < len && i < 16; i++, ofs++) {
+ unsigned char c = data[ofs];
+ if (!isascii(c) || !isprint(c))
+ c = '.';
+ out += rte_snprintf(line+out, LINE_LEN - out, "%c", c);
+ }
+ printf("%s\n", line);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ struct cmdline *cl;
+ int ret;
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ return -1;
+
+ rte_timer_subsystem_init();
+
+ argc -= ret;
+ argv += ret;
+
+ prgname = argv[0];
+
+#ifndef RTE_EXEC_ENV_BAREMETAL
+ if ((recursive_call = getenv(RECURSIVE_ENV_VAR)) != NULL)
+ return do_recursive_call();
+#endif
+
+ cl = cmdline_stdin_new(main_ctx, "RTE>>");
+ if (cl == NULL) {
+ return -1;
+ }
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+
+ return 0;
+}
diff --git a/app/test/test.h b/app/test/test.h
new file mode 100644
index 0000000..3c927d2
--- /dev/null
+++ b/app/test/test.h
@@ -0,0 +1,85 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#ifndef _TEST_H_
+#define _TEST_H_
+
+/* icc on baremetal gives us troubles with function named 'main' */
+#ifdef RTE_EXEC_ENV_BAREMETAL
+#define main _main
+#endif
+
+#define RECURSIVE_ENV_VAR "RTE_TEST_RECURSIVE"
+
+extern const char *prgname;
+
+extern cmdline_parse_ctx_t main_ctx[];
+
+void test_hexdump(const char *title, const void *buf, unsigned int len);
+
+int main(int argc, char **argv);
+
+int test_pci(void);
+int test_memory(void);
+int test_per_lcore(void);
+int test_spinlock(void);
+int test_rwlock(void);
+int test_atomic(void);
+int test_byteorder(void);
+int test_prefetch(void);
+int test_cycles(void);
+int test_logs(void);
+int test_memzone(void);
+int test_ring(void);
+int test_mempool(void);
+int test_mbuf(void);
+int test_timer(void);
+int test_malloc(void);
+int test_memcpy(void);
+int test_hash(void);
+int test_lpm(void);
+int test_debug(void);
+int test_errno(void);
+int test_tailq(void);
+int test_string_fns(void);
+int test_mp_secondary(void);
+int test_cpuflags(void);
+int test_eal_flags(void);
+int test_alarm(void);
+int test_interrupt(void);
+int test_version(void);
+int test_pci_run;
+
+#endif
diff --git a/app/test/test_alarm.c b/app/test/test_alarm.c
new file mode 100644
index 0000000..5e36a3d
--- /dev/null
+++ b/app/test/test_alarm.c
@@ -0,0 +1,258 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+
+#include <cmdline_parse.h>
+
+#include <rte_common.h>
+#include <rte_cycles.h>
+#include <rte_interrupts.h>
+#include <rte_common.h>
+#include <rte_atomic.h>
+#include <rte_alarm.h>
+
+#include "test.h"
+
+#define US_PER_MS 1000
+
+#define RTE_TEST_ALARM_TIMEOUT 3000 /* ms */
+#define RTE_TEST_CHECK_PERIOD 1000 /* ms */
+
+static volatile int flag;
+
+static void
+test_alarm_callback(void *cb_arg)
+{
+ flag = 1;
+ printf("Callback setting flag - OK. [cb_arg = %p]\n", cb_arg);
+}
+
+static rte_atomic32_t cb_count;
+
+static void
+test_multi_cb(void *arg)
+{
+ rte_atomic32_inc(&cb_count);
+ printf("In %s - arg = %p\n", __func__, arg);
+}
+
+static volatile int recursive_error = 0;
+
+static void
+test_remove_in_callback(void *arg)
+{
+ printf("In %s - arg = %p\n", __func__, arg);
+ if (rte_eal_alarm_cancel(test_remove_in_callback, arg) ||
+ rte_eal_alarm_cancel(test_remove_in_callback, (void *)-1)) {
+ printf("Error - cancelling callback from within function succeeded!\n");
+ recursive_error = 1;
+ }
+ flag = (int)((uintptr_t)arg);
+}
+
+static volatile int flag_2;
+
+static void
+test_remove_in_callback_2(void *arg)
+{
+ if (rte_eal_alarm_cancel(test_remove_in_callback_2, arg) || rte_eal_alarm_cancel(test_remove_in_callback_2, (void *)-1)) {
+ printf("Error - cancelling callback of test_remove_in_callback_2\n");
+ return;
+ }
+ flag_2 = 1;
+}
+
+static int
+test_multi_alarms(void)
+{
+ int rm_count = 0;
+ cb_count.cnt = 0;
+
+ printf("Expect 6 callbacks in order...\n");
+ /* add two alarms in order */
+ rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)1);
+ rte_eal_alarm_set(2000 * US_PER_MS, test_multi_cb, (void *)2);
+
+ /* now add in reverse order */
+ rte_eal_alarm_set(6000 * US_PER_MS, test_multi_cb, (void *)6);
+ rte_eal_alarm_set(5000 * US_PER_MS, test_multi_cb, (void *)5);
+ rte_eal_alarm_set(4000 * US_PER_MS, test_multi_cb, (void *)4);
+ rte_eal_alarm_set(3000 * US_PER_MS, test_multi_cb, (void *)3);
+
+ /* wait for expiry */
+ rte_delay_ms(6500);
+ if (cb_count.cnt != 6) {
+ printf("Missing callbacks\n");
+ /* remove any callbacks that might remain */
+ rte_eal_alarm_cancel(test_multi_cb, (void *)-1);
+ return -1;
+ }
+
+ cb_count.cnt = 0;
+ printf("Expect only callbacks with args 1 and 3...\n");
+ /* Add 3 flags, then delete one */
+ rte_eal_alarm_set(3000 * US_PER_MS, test_multi_cb, (void *)3);
+ rte_eal_alarm_set(2000 * US_PER_MS, test_multi_cb, (void *)2);
+ rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)1);
+ rm_count = rte_eal_alarm_cancel(test_multi_cb, (void *)2);
+
+ rte_delay_ms(3500);
+ if (cb_count.cnt != 2 || rm_count != 1) {
+ printf("Error: invalid flags count or alarm removal failure"
+ " - flags value = %d, expected = %d\n", cb_count.cnt, 2);
+ /* remove any callbacks that might remain */
+ rte_eal_alarm_cancel(test_multi_cb, (void *)-1);
+ return -1;
+ }
+
+ printf("Testing adding and then removing multiple alarms\n");
+ /* finally test that no callbacks are called if we delete them all*/
+ rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)1);
+ rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)2);
+ rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)3);
+ rm_count = rte_eal_alarm_cancel(test_alarm_callback, (void *)-1);
+ if (rm_count != 0) {
+ printf("Error removing non-existant alarm succeeded\n");
+ rte_eal_alarm_cancel(test_multi_cb, (void *) -1);
+ return -1;
+ }
+ rm_count = rte_eal_alarm_cancel(test_multi_cb, (void *) -1);
+ if (rm_count != 3) {
+ printf("Error removing all pending alarm callbacks\n");
+ return -1;
+ }
+
+ /* Test that we cannot cancel an alarm from within the callback itself
+ * Also test that we can cancel head-of-line callbacks ok.*/
+ flag = 0;
+ recursive_error = 0;
+ rte_eal_alarm_set(1000 * US_PER_MS, test_remove_in_callback, (void *)1);
+ rte_eal_alarm_set(2000 * US_PER_MS, test_remove_in_callback, (void *)2);
+ rm_count = rte_eal_alarm_cancel(test_remove_in_callback, (void *)1);
+ if (rm_count != 1) {
+ printf("Error cancelling head-of-list callback\n");
+ return -1;
+ }
+ rte_delay_ms(1500);
+ if (flag != 0) {
+ printf("Error, cancelling head-of-list leads to premature callback\n");
+ return -1;
+ }
+ rte_delay_ms(1000);
+ if (flag != 2) {
+ printf("Error - expected callback not called\n");
+ rte_eal_alarm_cancel(test_remove_in_callback, (void *)-1);
+ return -1;
+ }
+ if (recursive_error == 1)
+ return -1;
+
+ /* Check if it can cancel all for the same callback */
+ printf("Testing canceling all for the same callback\n");
+ flag_2 = 0;
+ rte_eal_alarm_set(1000 * US_PER_MS, test_remove_in_callback, (void *)1);
+ rte_eal_alarm_set(2000 * US_PER_MS, test_remove_in_callback_2, (void *)2);
+ rte_eal_alarm_set(3000 * US_PER_MS, test_remove_in_callback_2, (void *)3);
+ rte_eal_alarm_set(4000 * US_PER_MS, test_remove_in_callback, (void *)4);
+ rm_count = rte_eal_alarm_cancel(test_remove_in_callback_2, (void *)-1);
+ if (rm_count != 2) {
+ printf("Error, cannot cancel all for the same callback\n");
+ return -1;
+ }
+ rm_count = rte_eal_alarm_cancel(test_remove_in_callback, (void *)-1);
+ if (rm_count != 2) {
+ printf("Error, cannot cancel all for the same callback\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+test_alarm(void)
+{
+ int count = 0;
+
+ /* check if the callback will be called */
+ printf("check if the callback will be called\n");
+ flag = 0;
+ if (rte_eal_alarm_set(RTE_TEST_ALARM_TIMEOUT * US_PER_MS,
+ test_alarm_callback, NULL) < 0) {
+ printf("fail to set alarm callback\n");
+ return -1;
+ }
+ while (flag == 0 && count ++ < 6)
+ rte_delay_ms(RTE_TEST_CHECK_PERIOD);
+
+ if (flag == 0){
+ printf("Callback not called\n");
+ return -1;
+ }
+
+ /* check if it will fail to set alarm with wrong us value */
+ printf("check if it will fail to set alarm with wrong ms values\n");
+ if (rte_eal_alarm_set(0, test_alarm_callback,
+ NULL) >= 0) {
+ printf("should not be successful with 0 us value\n");
+ return -1;
+ }
+ if (rte_eal_alarm_set(UINT64_MAX - 1, test_alarm_callback,
+ NULL) >= 0) {
+ printf("should not be successful with (UINT64_MAX-1) us value\n");
+ return -1;
+ }
+
+ /* check if it will fail to set alarm with null callback parameter */
+ printf("check if it will fail to set alarm with null callback parameter\n");
+ if (rte_eal_alarm_set(RTE_TEST_ALARM_TIMEOUT, NULL, NULL) >= 0) {
+ printf("should not be successful to set alarm with null callback parameter\n");
+ return -1;
+ }
+
+ /* check if it will fail to remove alarm with null callback parameter */
+ printf("check if it will fail to remove alarm with null callback parameter\n");
+ if (rte_eal_alarm_cancel(NULL, NULL) == 0) {
+ printf("should not be successful to remove alarm with null callback parameter");
+ return -1;
+ }
+
+ if (test_multi_alarms() != 0)
+ return -1;
+
+ return 0;
+}
+
diff --git a/app/test/test_atomic.c b/app/test/test_atomic.c
new file mode 100644
index 0000000..b64f361
--- /dev/null
+++ b/app/test/test_atomic.c
@@ -0,0 +1,381 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/queue.h>
+
+#include <cmdline_parse.h>
+
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_per_lcore.h>
+#include <rte_launch.h>
+#include <rte_atomic.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+
+#include "test.h"
+
+/*
+ * Atomic Variables
+ * ================
+ *
+ * - The main test function performs three subtests. The first test
+ * checks that the usual inc/dec/add/sub functions are working
+ * correctly:
+ *
+ * - Initialize 16-bit, 32-bit and 64-bit atomic variables to specific
+ * values.
+ *
+ * - These variables are incremented and decremented on each core at
+ * the same time in ``test_atomic_usual()``.
+ *
+ * - The function checks that once all lcores finish their function,
+ * the value of the atomic variables are still the same.
+ *
+ * - The second test verifies the behavior of "test and set" functions.
+ *
+ * - Initialize 16-bit, 32-bit and 64-bit atomic variables to zero.
+ *
+ * - Invoke ``test_atomic_tas()`` on each lcore: before doing anything
+ * else. The cores are waiting a synchro using ``while
+ * (rte_atomic32_read(&val) == 0)`` which is triggered by the main test
+ * function. Then all cores do a
+ * ``rte_atomicXX_test_and_set()`` at the same time. If it is successful,
+ * it increments another atomic counter.
+ *
+ * - The main function checks that the atomic counter was incremented
+ * twice only (one for 16-bit, one for 32-bit and one for 64-bit values).
+ *
+ * - Test "add/sub and return"
+ *
+ * - Initialize 16-bit, 32-bit and 64-bit atomic variables to zero.
+ *
+ * - Invoke ``test_atomic_addsub_return()`` on each lcore. Before doing
+ * anything else, the cores are waiting a synchro. Each lcore does
+ * this operation several times::
+ *
+ * tmp = rte_atomicXX_add_return(&a, 1);
+ * atomic_add(&count, tmp);
+ * tmp = rte_atomicXX_sub_return(&a, 1);
+ * atomic_sub(&count, tmp+1);
+ *
+ * - At the end of the test, the *count* value must be 0.
+ */
+
+#define NUM_ATOMIC_TYPES 3
+
+#define N 10000
+
+static rte_atomic16_t a16;
+static rte_atomic32_t a32;
+static rte_atomic64_t a64;
+static rte_atomic32_t count;
+static rte_atomic32_t synchro;
+
+static int
+test_atomic_usual(__attribute__((unused)) void *arg)
+{
+ unsigned i;
+
+ while (rte_atomic32_read(&synchro) == 0)
+ ;
+
+ for (i = 0; i < N; i++)
+ rte_atomic16_inc(&a16);
+ for (i = 0; i < N; i++)
+ rte_atomic16_dec(&a16);
+ for (i = 0; i < (N / 5); i++)
+ rte_atomic16_add(&a16, 5);
+ for (i = 0; i < (N / 5); i++)
+ rte_atomic16_sub(&a16, 5);
+
+ for (i = 0; i < N; i++)
+ rte_atomic32_inc(&a32);
+ for (i = 0; i < N; i++)
+ rte_atomic32_dec(&a32);
+ for (i = 0; i < (N / 5); i++)
+ rte_atomic32_add(&a32, 5);
+ for (i = 0; i < (N / 5); i++)
+ rte_atomic32_sub(&a32, 5);
+
+ for (i = 0; i < N; i++)
+ rte_atomic64_inc(&a64);
+ for (i = 0; i < N; i++)
+ rte_atomic64_dec(&a64);
+ for (i = 0; i < (N / 5); i++)
+ rte_atomic64_add(&a64, 5);
+ for (i = 0; i < (N / 5); i++)
+ rte_atomic64_sub(&a64, 5);
+
+ return 0;
+}
+
+static int
+test_atomic_tas(__attribute__((unused)) void *arg)
+{
+ while (rte_atomic32_read(&synchro) == 0)
+ ;
+
+ if (rte_atomic16_test_and_set(&a16))
+ rte_atomic32_inc(&count);
+ if (rte_atomic32_test_and_set(&a32))
+ rte_atomic32_inc(&count);
+ if (rte_atomic64_test_and_set(&a64))
+ rte_atomic32_inc(&count);
+
+ return 0;
+}
+
+static int
+test_atomic_addsub_and_return(__attribute__((unused)) void *arg)
+{
+ uint32_t tmp16;
+ uint32_t tmp32;
+ uint64_t tmp64;
+ unsigned i;
+
+ while (rte_atomic32_read(&synchro) == 0)
+ ;
+
+ for (i = 0; i < N; i++) {
+ tmp16 = rte_atomic16_add_return(&a16, 1);
+ rte_atomic32_add(&count, tmp16);
+
+ tmp16 = rte_atomic16_sub_return(&a16, 1);
+ rte_atomic32_sub(&count, tmp16+1);
+
+ tmp32 = rte_atomic32_add_return(&a32, 1);
+ rte_atomic32_add(&count, tmp32);
+
+ tmp32 = rte_atomic32_sub_return(&a32, 1);
+ rte_atomic32_sub(&count, tmp32+1);
+
+ tmp64 = rte_atomic64_add_return(&a64, 1);
+ rte_atomic32_add(&count, tmp64);
+
+ tmp64 = rte_atomic64_sub_return(&a64, 1);
+ rte_atomic32_sub(&count, tmp64+1);
+ }
+
+ return 0;
+}
+
+/*
+ * rte_atomic32_inc_and_test() would increase a 32 bits counter by one and then
+ * test if that counter is equal to 0. It would return true if the counter is 0
+ * and false if the counter is not 0. rte_atomic64_inc_and_test() could do the
+ * same thing but for a 64 bits counter.
+ * Here checks that if the 32/64 bits counter is equal to 0 after being atomically
+ * increased by one. If it is, increase the variable of "count" by one which would
+ * be checked as the result later.
+ *
+ */
+static int
+test_atomic_inc_and_test(__attribute__((unused)) void *arg)
+{
+ while (rte_atomic32_read(&synchro) == 0)
+ ;
+
+ if (rte_atomic16_inc_and_test(&a16)) {
+ rte_atomic32_inc(&count);
+ }
+ if (rte_atomic32_inc_and_test(&a32)) {
+ rte_atomic32_inc(&count);
+ }
+ if (rte_atomic64_inc_and_test(&a64)) {
+ rte_atomic32_inc(&count);
+ }
+
+ return 0;
+}
+
+/*
+ * rte_atomicXX_dec_and_test() should decrease a 32 bits counter by one and then
+ * test if that counter is equal to 0. It should return true if the counter is 0
+ * and false if the counter is not 0.
+ * This test checks if the counter is equal to 0 after being atomically
+ * decreased by one. If it is, increase the value of "count" by one which is to
+ * be checked as the result later.
+ */
+static int
+test_atomic_dec_and_test(__attribute__((unused)) void *arg)
+{
+ while (rte_atomic32_read(&synchro) == 0)
+ ;
+
+ if (rte_atomic16_dec_and_test(&a16))
+ rte_atomic32_inc(&count);
+
+ if (rte_atomic32_dec_and_test(&a32))
+ rte_atomic32_inc(&count);
+
+ if (rte_atomic64_dec_and_test(&a64))
+ rte_atomic32_inc(&count);
+
+ return 0;
+}
+
+int
+test_atomic(void)
+{
+ rte_atomic16_init(&a16);
+ rte_atomic32_init(&a32);
+ rte_atomic64_init(&a64);
+ rte_atomic32_init(&count);
+ rte_atomic32_init(&synchro);
+
+ rte_atomic16_set(&a16, 1UL << 10);
+ rte_atomic32_set(&a32, 1UL << 10);
+ rte_atomic64_set(&a64, 1ULL << 33);
+
+ printf("usual inc/dec/add/sub functions\n");
+
+ rte_eal_mp_remote_launch(test_atomic_usual, NULL, SKIP_MASTER);
+ rte_atomic32_set(&synchro, 1);
+ rte_eal_mp_wait_lcore();
+ rte_atomic32_set(&synchro, 0);
+
+ if (rte_atomic16_read(&a16) != 1UL << 10) {
+ printf("Atomic16 usual functions failed\n");
+ return -1;
+ }
+
+ if (rte_atomic32_read(&a32) != 1UL << 10) {
+ printf("Atomic32 usual functions failed\n");
+ return -1;
+ }
+
+ if (rte_atomic64_read(&a64) != 1ULL << 33) {
+ printf("Atomic64 usual functions failed\n");
+ return -1;
+ }
+
+ printf("test and set\n");
+
+ rte_atomic64_set(&a64, 0);
+ rte_atomic32_set(&a32, 0);
+ rte_atomic16_set(&a16, 0);
+ rte_atomic32_set(&count, 0);
+ rte_eal_mp_remote_launch(test_atomic_tas, NULL, SKIP_MASTER);
+ rte_atomic32_set(&synchro, 1);
+ rte_eal_mp_wait_lcore();
+ rte_atomic32_set(&synchro, 0);
+
+ if (rte_atomic32_read(&count) != NUM_ATOMIC_TYPES) {
+ printf("Atomic test and set failed\n");
+ return -1;
+ }
+
+ printf("add/sub and return\n");
+
+ rte_atomic64_set(&a64, 0);
+ rte_atomic32_set(&a32, 0);
+ rte_atomic16_set(&a16, 0);
+ rte_atomic32_set(&count, 0);
+ rte_eal_mp_remote_launch(test_atomic_addsub_and_return, NULL,
+ SKIP_MASTER);
+ rte_atomic32_set(&synchro, 1);
+ rte_eal_mp_wait_lcore();
+ rte_atomic32_set(&synchro, 0);
+
+ if (rte_atomic32_read(&count) != 0) {
+ printf("Atomic add/sub+return failed\n");
+ return -1;
+ }
+
+ /*
+ * Set a64, a32 and a16 with the same value of minus "number of slave
+ * lcores", launch all slave lcores to atomically increase by one and
+ * test them respectively.
+ * Each lcore should have only one chance to increase a64 by one and
+ * then check if it is equal to 0, but there should be only one lcore
+ * that finds that it is 0. It is similar for a32 and a16.
+ * Then a variable of "count", initialized to zero, is increased by
+ * one if a64, a32 or a16 is 0 after being increased and tested
+ * atomically.
+ * We can check if "count" is finally equal to 3 to see if all slave
+ * lcores performed "atomic inc and test" right.
+ */
+ printf("inc and test\n");
+
+ rte_atomic64_clear(&a64);
+ rte_atomic32_clear(&a32);
+ rte_atomic16_clear(&a16);
+ rte_atomic32_clear(&synchro);
+ rte_atomic32_clear(&count);
+
+ rte_atomic64_set(&a64, (int64_t)(1 - (int64_t)rte_lcore_count()));
+ rte_atomic32_set(&a32, (int32_t)(1 - (int32_t)rte_lcore_count()));
+ rte_atomic16_set(&a16, (int16_t)(1 - (int16_t)rte_lcore_count()));
+ rte_eal_mp_remote_launch(test_atomic_inc_and_test, NULL, SKIP_MASTER);
+ rte_atomic32_set(&synchro, 1);
+ rte_eal_mp_wait_lcore();
+ rte_atomic32_clear(&synchro);
+
+ if (rte_atomic32_read(&count) != NUM_ATOMIC_TYPES) {
+ printf("Atomic inc and test failed %d\n", count.cnt);
+ return -1;
+ }
+
+ /*
+ * Same as above, but this time we set the values to "number of slave
+ * lcores", and decrement instead of increment.
+ */
+ printf("dec and test\n");
+
+ rte_atomic32_clear(&synchro);
+ rte_atomic32_clear(&count);
+
+ rte_atomic64_set(&a64, (int64_t)(rte_lcore_count() - 1));
+ rte_atomic32_set(&a32, (int32_t)(rte_lcore_count() - 1));
+ rte_atomic16_set(&a16, (int16_t)(rte_lcore_count() - 1));
+ rte_eal_mp_remote_launch(test_atomic_dec_and_test, NULL, SKIP_MASTER);
+ rte_atomic32_set(&synchro, 1);
+ rte_eal_mp_wait_lcore();
+ rte_atomic32_clear(&synchro);
+
+ if (rte_atomic32_read(&count) != NUM_ATOMIC_TYPES) {
+ printf("Atomic dec and test failed\n");
+ return -1;
+ }
+
+ return 0;
+}
+
diff --git a/app/test/test_byteorder.c b/app/test/test_byteorder.c
new file mode 100644
index 0000000..593e26f
--- /dev/null
+++ b/app/test/test_byteorder.c
@@ -0,0 +1,97 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <cmdline_parse.h>
+
+#include <rte_byteorder.h>
+
+#include "test.h"
+
+static volatile uint16_t u16 = 0x1337;
+static volatile uint32_t u32 = 0xdeadbeefUL;
+static volatile uint64_t u64 = 0xdeadcafebabefaceULL;
+
+/*
+ * Byteorder functions
+ * ===================
+ *
+ * - check that optimized byte swap functions are working for each
+ * size (16, 32, 64 bits)
+ */
+
+int
+test_byteorder(void)
+{
+ uint16_t res_u16;
+ uint32_t res_u32;
+ uint64_t res_u64;
+
+ res_u16 = rte_bswap16(u16);
+ printf("%"PRIx16" -> %"PRIx16"\n", u16, res_u16);
+ if (res_u16 != 0x3713)
+ return -1;
+
+ res_u32 = rte_bswap32(u32);
+ printf("%"PRIx32" -> %"PRIx32"\n", u32, res_u32);
+ if (res_u32 != 0xefbeaddeUL)
+ return -1;
+
+ res_u64 = rte_bswap64(u64);
+ printf("%"PRIx64" -> %"PRIx64"\n", u64, res_u64);
+ if (res_u64 != 0xcefabebafecaaddeULL)
+ return -1;
+
+ res_u16 = rte_bswap16(0x1337);
+ printf("const %"PRIx16" -> %"PRIx16"\n", 0x1337, res_u16);
+ if (res_u16 != 0x3713)
+ return -1;
+
+ res_u32 = rte_bswap32(0xdeadbeefUL);
+ printf("const %"PRIx32" -> %"PRIx32"\n", (uint32_t) 0xdeadbeef, res_u32);
+ if (res_u32 != 0xefbeaddeUL)
+ return -1;
+
+ res_u64 = rte_bswap64(0xdeadcafebabefaceULL);
+ printf("const %"PRIx64" -> %"PRIx64"\n", (uint64_t) 0xdeadcafebabefaceULL, res_u64);
+ if (res_u64 != 0xcefabebafecaaddeULL)
+ return -1;
+
+ return 0;
+}
diff --git a/app/test/test_cpuflags.c b/app/test/test_cpuflags.c
new file mode 100644
index 0000000..d15d6e4
--- /dev/null
+++ b/app/test/test_cpuflags.c
@@ -0,0 +1,134 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdio.h>
+
+#include <cmdline_parse.h>
+#include <errno.h>
+#include <stdint.h>
+#include <rte_cpuflags.h>
+#include <rte_debug.h>
+
+#include "test.h"
+
+
+/* convenience define */
+#define CHECK_FOR_FLAG(x) \
+ result = rte_cpu_get_flag_enabled(x); \
+ printf("%s\n", cpu_flag_result(result)); \
+ if (result == -ENOENT) \
+ return -1;
+
+/*
+ * Helper function to display result
+ */
+static inline const char *
+cpu_flag_result(int result)
+{
+ switch (result) {
+ case 0:
+ return "NOT PRESENT";
+ case 1:
+ return "OK";
+ default:
+ return "ERROR";
+ }
+}
+
+
+
+/*
+ * CPUID test
+ * ===========
+ *
+ * - Check flags from different registers with rte_cpu_get_flag_enabled()
+ * - Check if register and CPUID functions fail properly
+ */
+
+int
+test_cpuflags(void)
+{
+ int result;
+ printf("\nChecking for flags from different registers...\n");
+
+ printf("Check for SSE:\t\t");
+ CHECK_FOR_FLAG(RTE_CPUFLAG_SSE);
+
+ printf("Check for SSE2:\t\t");
+ CHECK_FOR_FLAG(RTE_CPUFLAG_SSE2);
+
+ printf("Check for SSE3:\t\t");
+ CHECK_FOR_FLAG(RTE_CPUFLAG_SSE3);
+
+ printf("Check for SSE4.1:\t");
+ CHECK_FOR_FLAG(RTE_CPUFLAG_SSE4_1);
+
+ printf("Check for SSE4.2:\t");
+ CHECK_FOR_FLAG(RTE_CPUFLAG_SSE4_2);
+
+ printf("Check for AVX:\t\t");
+ CHECK_FOR_FLAG(RTE_CPUFLAG_AVX);
+
+ printf("Check for AVX2:\t\t");
+ CHECK_FOR_FLAG(RTE_CPUFLAG_AVX2);
+
+ printf("Check for TRBOBST:\t");
+ CHECK_FOR_FLAG(RTE_CPUFLAG_TRBOBST);
+
+ printf("Check for ENERGY_EFF:\t");
+ CHECK_FOR_FLAG(RTE_CPUFLAG_ENERGY_EFF);
+
+ printf("Check for LAHF_SAHF:\t");
+ CHECK_FOR_FLAG(RTE_CPUFLAG_LAHF_SAHF);
+
+ printf("Check for 1GB_PG:\t");
+ CHECK_FOR_FLAG(RTE_CPUFLAG_1GB_PG);
+
+ printf("Check for INVTSC:\t");
+ CHECK_FOR_FLAG(RTE_CPUFLAG_INVTSC);
+
+
+
+ /*
+ * Check if invalid data is handled properly
+ */
+ printf("\nCheck for invalid flag:\t");
+ result = rte_cpu_get_flag_enabled(RTE_CPUFLAG_NUMFLAGS);
+ printf("%s\n", cpu_flag_result(result));
+ if (result != -ENOENT)
+ return -1;
+
+ return 0;
+}
diff --git a/app/test/test_cycles.c b/app/test/test_cycles.c
new file mode 100644
index 0000000..f480402
--- /dev/null
+++ b/app/test/test_cycles.c
@@ -0,0 +1,94 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+
+#include <cmdline_parse.h>
+
+#include <rte_common.h>
+#include <rte_cycles.h>
+
+#include "test.h"
+
+#define N 10000
+
+/*
+ * Cycles test
+ * ===========
+ *
+ * - Loop N times and check that the timer alway increments and
+ * never decrements during this loop.
+ *
+ * - Wait one second using rte_usleep() and check that the increment
+ * of cycles is correct with regard to the frequency of the timer.
+ */
+
+int
+test_cycles(void)
+{
+ unsigned i;
+ uint64_t start_cycles, cycles, prev_cycles;
+ uint64_t hz = rte_get_hpet_hz();
+ uint64_t max_inc = (hz / 100); /* 10 ms max between 2 reads */
+
+ /* check that the timer is always incrementing */
+ start_cycles = rte_get_hpet_cycles();
+ prev_cycles = start_cycles;
+ for (i=0; i<N; i++) {
+ cycles = rte_get_hpet_cycles();
+ if ((uint64_t)(cycles - prev_cycles) > max_inc) {
+ printf("increment too high or going backwards\n");
+ return -1;
+ }
+ prev_cycles = cycles;
+ }
+
+ /* check that waiting 1 second is precise */
+ prev_cycles = rte_get_hpet_cycles();
+ rte_delay_us(1000000);
+ cycles = rte_get_hpet_cycles();
+ if ((uint64_t)(cycles - prev_cycles) > (hz + max_inc)) {
+ printf("delay_us is not accurate\n");
+ return -1;
+ }
+ cycles = rte_get_hpet_cycles();
+ if ((uint64_t)(cycles - prev_cycles) < (hz)) {
+ printf("delay_us is not accurate\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/app/test/test_debug.c b/app/test/test_debug.c
new file mode 100644
index 0000000..153c562
--- /dev/null
+++ b/app/test/test_debug.c
@@ -0,0 +1,150 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <cmdline_parse.h>
+
+#include <rte_debug.h>
+#include <rte_common.h>
+
+#include "test.h"
+
+/*
+ * Debug test
+ * ==========
+ *
+ * - Call rte_dump_stack() and rte_dump_registers(). The result is not checked
+ * currently, as the functions are not implemented on baremetal.
+ * - Check that rte_panic() terminates the program using a non-zero error code.
+ * (Only implemented on linux, since it requires the fork() system call)
+ */
+
+#ifdef RTE_EXEC_ENV_BAREMETAL
+
+/* baremetal - don't test rte_panic or rte_exit */
+static int
+test_panic(void)
+{
+ return 0;
+}
+
+static int
+test_exit(void)
+{
+ return 0;
+}
+
+#else
+
+/* linuxapp - use fork() to test rte_panic() */
+static int
+test_panic(void)
+{
+ int pid;
+ int status;
+
+ pid = fork();
+
+ if (pid == 0)
+ rte_panic("Test Debug\n");
+ else if (pid < 0){
+ printf("Fork Failed\n");
+ return -1;
+ }
+ wait(&status);
+ if(status == 0){
+ printf("Child process terminated normally!\n");
+ return -1;
+ } else
+ printf("Child process terminated as expected - Test passed!\n");
+
+ return 0;
+}
+
+/* linuxapp - use fork() to test rte_exit() */
+static int
+test_exit_val(int exit_val)
+{
+ int pid;
+ int status;
+
+ pid = fork();
+
+ if (pid == 0)
+ rte_exit(exit_val, __func__);
+ else if (pid < 0){
+ printf("Fork Failed\n");
+ return -1;
+ }
+ wait(&status);
+ printf("Child process status: %d\n", status);
+ if(!WIFEXITED(status) || WEXITSTATUS(status) != (uint8_t)exit_val){
+ printf("Child process terminated with incorrect return code!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+test_exit(void)
+{
+ int test_vals[] = { 0, 1, 2, 255, -1 };
+ unsigned i;
+ for (i = 0; i < sizeof(test_vals) / sizeof(test_vals[0]); i++){
+ if (test_exit_val(test_vals[i]) < 0)
+ return -1;
+ }
+ printf("%s Passed\n", __func__);
+ return 0;
+}
+
+#endif
+
+int
+test_debug(void)
+{
+ rte_dump_stack();
+ rte_dump_registers();
+ if (test_panic() < 0)
+ return -1;
+ if (test_exit() < 0)
+ return -1;
+ return 0;
+}
diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c
new file mode 100644
index 0000000..37b9aaf
--- /dev/null
+++ b/app/test/test_eal_flags.c
@@ -0,0 +1,303 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+#include <stdio.h>
+
+#include <cmdline_parse.h>
+
+#include "test.h"
+
+#ifndef RTE_EXEC_ENV_BAREMETAL
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include <rte_debug.h>
+#include <rte_string_fns.h>
+
+#include "process.h"
+
+#define mp_flag "--proc-type=secondary"
+#define no_hpet "--no-hpet"
+#define no_huge "--no-huge"
+#define no_shconf "--no-shconf"
+#define launch_proc(ARGV) process_dup(ARGV, \
+ sizeof(ARGV)/(sizeof(ARGV[0])), __func__)
+
+/*
+ * Test that the app doesn't run without invalid blacklist option.
+ * Final test ensures it does run with valid options as sanity check
+ */
+static int
+test_invalid_b_flag(void)
+{
+ const char *blinval[][8] = {
+ {prgname, mp_flag, "-n", "1", "-c", "1", "-b", "error"},
+ {prgname, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0"},
+ {prgname, mp_flag, "-n", "1", "-c", "1", "-b", "0:error:0.1"},
+ {prgname, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1error"},
+ {prgname, mp_flag, "-n", "1", "-c", "1", "-b", "error0:0:0.1"},
+ {prgname, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1.2"},
+ };
+ /* Test with valid blacklist option */
+ const char *blval[] = {prgname, mp_flag, "-n", "1", "-c", "1", "-b", "FF:09:0B.3"};
+
+ int i;
+
+ for (i = 0; i != sizeof (blinval) / sizeof (blinval[0]); i++) {
+ if (launch_proc(blinval[i]) == 0) {
+ printf("Error - process did run ok with invalid "
+ "blacklist parameter\n");
+ return -1;
+ }
+ }
+ if (launch_proc(blval) != 0) {
+ printf("Error - process did not run ok with valid blacklist value\n");
+ return -1;
+ }
+ return 0;
+}
+
+
+/*
+ * Test that the app doesn't run with invalid -r option.
+ */
+static int
+test_invalid_r_flag(void)
+{
+ const char *rinval[][8] = {
+ {prgname, mp_flag, "-n", "1", "-c", "1", "-r", "error"},
+ {prgname, mp_flag, "-n", "1", "-c", "1", "-r", "0"},
+ {prgname, mp_flag, "-n", "1", "-c", "1", "-r", "-1"},
+ {prgname, mp_flag, "-n", "1", "-c", "1", "-r", "17"},
+ };
+ /* Test with valid blacklist option */
+ const char *rval[] = {prgname, mp_flag, "-n", "1", "-c", "1", "-r", "16"};
+
+ int i;
+
+ for (i = 0; i != sizeof (rinval) / sizeof (rinval[0]); i++) {
+ if (launch_proc(rinval[i]) == 0) {
+ printf("Error - process did run ok with invalid "
+ "-r (rank) parameter\n");
+ return -1;
+ }
+ }
+ if (launch_proc(rval) != 0) {
+ printf("Error - process did not run ok with valid -r (rank) value\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Test that the app doesn't run without the coremask flag. In all cases
+ * should give an error and fail to run
+ */
+static int
+test_missing_c_flag(void)
+{
+ /* -c flag but no coremask value */
+ const char *argv1[] = { prgname, mp_flag, "-n", "3", "-c"};
+ /* No -c flag at all */
+ const char *argv2[] = { prgname, mp_flag, "-n", "3"};
+ /* bad coremask value */
+ const char *argv3[] = { prgname, mp_flag, "-n", "3", "-c", "error" };
+ /* sanity check of tests - valid coremask value */
+ const char *argv4[] = { prgname, mp_flag, "-n", "3", "-c", "1" };
+
+ if (launch_proc(argv1) == 0
+ || launch_proc(argv2) == 0
+ || launch_proc(argv3) == 0) {
+ printf("Error - process ran without error when missing -c flag\n");
+ return -1;
+ }
+ if (launch_proc(argv4) != 0) {
+ printf("Error - process did not run ok with valid coremask value\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Test that the app doesn't run without the -n flag. In all cases
+ * should give an error and fail to run.
+ * Since -n is not compulsory for MP, we instead use --no-huge and --no-shconf
+ * flags.
+ */
+static int
+test_missing_n_flag(void)
+{
+ /* -n flag but no value */
+ const char *argv1[] = { prgname, no_huge, no_shconf, "-c", "1", "-n"};
+ /* No -n flag at all */
+ const char *argv2[] = { prgname, no_huge, no_shconf, "-c", "1"};
+ /* bad numeric value */
+ const char *argv3[] = { prgname, no_huge, no_shconf, "-c", "1", "-n", "e" };
+ /* out-of-range value */
+ const char *argv4[] = { prgname, no_huge, no_shconf, "-c", "1", "-n", "9" };
+ /* sanity test - check with good value */
+ const char *argv5[] = { prgname, no_huge, no_shconf, "-c", "1", "-n", "2" };
+
+ if (launch_proc(argv1) == 0
+ || launch_proc(argv2) == 0
+ || launch_proc(argv3) == 0
+ || launch_proc(argv4) == 0) {
+ printf("Error - process ran without error when missing -n flag\n");
+ return -1;
+ }
+ if (launch_proc(argv5) != 0) {
+ printf("Error - process did not run ok with valid num-channel value\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Test that the app runs with HPET, and without HPET
+ */
+static int
+test_no_hpet_flag(void)
+{
+ /* With --no-hpet */
+ const char *argv1[] = {prgname, mp_flag, no_hpet, "-c", "1", "-n", "2"};
+ /* Without --no-hpet */
+ const char *argv2[] = {prgname, mp_flag, "-c", "1", "-n", "2"};
+
+ if (launch_proc(argv1) != 0) {
+ printf("Error - process did not run ok with --no-hpet flag\n");
+ return -1;
+ }
+ if (launch_proc(argv2) != 0) {
+ printf("Error - process did not run ok without --no-hpet flag\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int
+test_misc_flags(void)
+{
+ /* check that some general flags don't prevent things from working.
+ * All cases, apart from the first, app should run.
+ * No futher testing of output done.
+ */
+ /* sanity check - failure with invalid option */
+ const char *argv0[] = {prgname, mp_flag, "-c", "1", "--invalid-opt"};
+
+ /* With --no-pci */
+ const char *argv1[] = {prgname, mp_flag, "-c", "1", "--no-pci"};
+ /* With -v */
+ const char *argv2[] = {prgname, mp_flag, "-c", "1", "-v"};
+ /* With -m - ignored for secondary processes */
+ const char *argv3[] = {prgname, mp_flag, "-c", "1", "-m", "32"};
+
+ if (launch_proc(argv0) == 0) {
+ printf("Error - process ran ok with invalid flag\n");
+ return -1;
+ }
+ if (launch_proc(argv1) != 0) {
+ printf("Error - process did not run ok with --no-pci flag\n");
+ return -1;
+ }
+ if (launch_proc(argv2) != 0) {
+ printf("Error - process did not run ok with -v flag\n");
+ return -1;
+ }
+ if (launch_proc(argv3) != 0) {
+ printf("Error - process did not run ok with -m flag\n");
+ return -1;
+ }
+ return 0;
+}
+
+int
+test_eal_flags(void)
+{
+ int ret = 0;
+
+ ret = test_missing_c_flag();
+ if (ret < 0) {
+ printf("Error in test_missing_c_flag()");
+ return ret;
+ }
+
+ ret = test_missing_n_flag();
+ if (ret < 0) {
+ printf("Error in test_missing_n_flag()");
+ return ret;
+ }
+
+ ret = test_no_hpet_flag();
+ if (ret < 0) {
+ printf("Error in test_no_hpet_flag()");
+ return ret;
+ }
+
+ ret = test_invalid_b_flag();
+ if (ret < 0) {
+ printf("Error in test_invalid_b_flag()");
+ return ret;
+ }
+
+ ret = test_invalid_r_flag();
+ if (ret < 0) {
+ printf("Error in test_invalid_r_flag()");
+ return ret;
+ }
+
+ ret = test_misc_flags();
+ if (ret < 0) {
+ printf("Error in test_misc_flags()");
+ return ret;
+ }
+
+ return ret;
+}
+
+#else
+/* Baremetal version
+ * Multiprocess not applicable, so just return 0 always
+ */
+int
+test_eal_flags(void)
+{
+ printf("Multi-process not possible for baremetal, cannot test EAL flags\n");
+ return 0;
+}
+
+#endif
diff --git a/app/test/test_errno.c b/app/test/test_errno.c
new file mode 100644
index 0000000..4233dc1
--- /dev/null
+++ b/app/test/test_errno.c
@@ -0,0 +1,110 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <string.h>
+#include <rte_per_lcore.h>
+#include <rte_errno.h>
+#include <rte_string_fns.h>
+
+#include <cmdline_parse.h>
+
+#include "test.h"
+
+int
+test_errno(void)
+{
+ const char *rte_retval;
+ const char *libc_retval;
+ const char unknown_code_result[] = "Unknown error %d";
+ char expected_libc_retval[sizeof(unknown_code_result)+3];
+
+ /* use a small selection of standard errors for testing */
+ int std_errs[] = {EAGAIN, EBADF, EACCES, EINTR, EINVAL};
+ /* test ALL registered RTE error codes for overlap */
+ int rte_errs[] = {E_RTE_SECONDARY, E_RTE_NO_CONFIG, E_RTE_NO_TAILQ};
+ unsigned i;
+
+ rte_errno = 0;
+ if (rte_errno != 0)
+ return -1;
+ /* check for standard errors we return the same as libc */
+ for (i = 0; i < sizeof(std_errs)/sizeof(std_errs[0]); i++){
+ rte_retval = rte_strerror(std_errs[i]);
+ libc_retval = strerror(std_errs[i]);
+ printf("rte_strerror: '%s', strerror: '%s'\n",
+ rte_retval, libc_retval);
+ if (strcmp(rte_retval, libc_retval) != 0)
+ return -1;
+ }
+ /* for rte-specific errors ensure we return a different string
+ * and that the string for libc is for an unknown error
+ */
+ for (i = 0; i < sizeof(rte_errs)/sizeof(rte_errs[0]); i++){
+ rte_retval = rte_strerror(rte_errs[i]);
+ libc_retval = strerror(rte_errs[i]);
+ printf("rte_strerror: '%s', strerror: '%s'\n",
+ rte_retval, libc_retval);
+ if (strcmp(rte_retval, libc_retval) == 0)
+ return -1;
+ /* generate appropriate error string for unknown error number
+ * and then check that this is what we got back. If not, we have
+ * a duplicate error number that conflicts with errno.h */
+ rte_snprintf(expected_libc_retval, sizeof(expected_libc_retval),
+ unknown_code_result, rte_errs[i]);
+ if (strcmp(expected_libc_retval, libc_retval) != 0){
+ printf("Error, duplicate error code %d\n", rte_errs[i]);
+ return -1;
+ }
+ }
+
+ /* ensure that beyond RTE_MAX_ERRNO, we always get an unknown code */
+ rte_retval = rte_strerror(RTE_MAX_ERRNO + 1);
+ libc_retval = strerror(RTE_MAX_ERRNO + 1);
+ rte_snprintf(expected_libc_retval, sizeof(expected_libc_retval),
+ unknown_code_result, RTE_MAX_ERRNO + 1);
+ printf("rte_strerror: '%s', strerror: '%s'\n",
+ rte_retval, libc_retval);
+ if ((strcmp(rte_retval, libc_retval) != 0) ||
+ (strcmp(expected_libc_retval, libc_retval) != 0)){
+ printf("Failed test for RTE_MAX_ERRNO + 1 value\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/app/test/test_hash.c b/app/test/test_hash.c
new file mode 100644
index 0000000..5992fa3
--- /dev/null
+++ b/app/test/test_hash.c
@@ -0,0 +1,1785 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * version: DPDK.L.1.2.3-3
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <sys/queue.h>
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_cycles.h>
+#include <rte_random.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_hash.h>
+#include <rte_hash_crc.h>
+#include <rte_jhash.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_fbk_hash.h>
+#include <rte_ip.h>
+#include <rte_string_fns.h>
+
+#include <cmdline_parse.h>
+
+#include "test.h"
+
+#ifdef RTE_LIBRTE_HASH
+
+/* Types of hash table performance test that can be performed */
+enum hash_test_t {
+ ADD_ON_EMPTY, /*< Add keys to empty table */
+ DELETE_ON_EMPTY, /*< Attempt to delete keys from empty table */
+ LOOKUP_ON_EMPTY, /*< Attempt to find keys in an empty table */
+ ADD_UPDATE, /*< Add/update keys in a full table */
+ DELETE, /*< Delete keys from a full table */
+ LOOKUP /*< Find keys in a full table */
+};
+
+/* Function type for hash table operations. */
+typedef int32_t (*hash_operation)(const struct rte_hash *h, const void *key);
+
+/* Structure to hold parameters used to run a hash table performance test */
+struct tbl_perf_test_params {
+ enum hash_test_t test_type;
+ uint32_t num_iterations;
+ uint32_t entries;
+ uint32_t bucket_entries;
+ uint32_t key_len;
+ rte_hash_function hash_func;
+ uint32_t hash_func_init_val;
+};
+
+#define ITERATIONS 10000
+#define LOCAL_FBK_HASH_ENTRIES_MAX (1 << 15)
+
+/*******************************************************************************
+ * Hash table performance test configuration section.
+ */
+struct tbl_perf_test_params tbl_perf_params[] =
+{
+/* Small table, add */
+/* Test type | Iterations | Entries | BucketSize | KeyLen | HashFunc | InitVal */
+{ ADD_ON_EMPTY, 1024, 1024, 1, 16, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 2, 16, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 4, 16, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 8, 16, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 16, 16, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 1, 32, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 2, 32, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 4, 32, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 8, 32, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 16, 32, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 1, 48, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 2, 48, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 4, 48, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 8, 48, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 16, 48, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 1, 64, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 2, 64, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 4, 64, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 8, 64, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 16, 64, rte_jhash, 0},
+/* Small table, update */
+/* Test type | Iterations | Entries | BucketSize | KeyLen | HashFunc | InitVal */
+{ ADD_UPDATE, ITERATIONS, 1024, 1, 16, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 2, 16, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 4, 16, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 8, 16, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 16, 16, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 1, 32, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 2, 32, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 4, 32, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 8, 32, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 16, 32, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 1, 48, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 2, 48, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 4, 48, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 8, 48, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 16, 48, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 1, 64, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 2, 64, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 4, 64, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 8, 64, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 16, 64, rte_jhash, 0},
+/* Small table, lookup */
+/* Test type | Iterations | Entries | BucketSize | KeyLen | HashFunc | InitVal */
+{ LOOKUP, ITERATIONS, 1024, 1, 16, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 2, 16, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 4, 16, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 8, 16, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 16, 16, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 1, 32, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 2, 32, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 4, 32, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 8, 32, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 16, 32, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 1, 48, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 2, 48, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 4, 48, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 8, 48, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 16, 48, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 1, 64, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 2, 64, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 4, 64, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 8, 64, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1024, 16, 64, rte_jhash, 0},
+/* Big table, add */
+/* Test type | Iterations | Entries | BucketSize | KeyLen | HashFunc | InitVal */
+{ ADD_ON_EMPTY, 1048576, 1048576, 1, 16, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 2, 16, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 4, 16, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 8, 16, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 16, 16, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 1, 32, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 2, 32, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 4, 32, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 8, 32, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 16, 32, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 1, 48, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 2, 48, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 4, 48, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 8, 48, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 16, 48, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 1, 64, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 2, 64, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 4, 64, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 8, 64, rte_jhash, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 16, 64, rte_jhash, 0},
+/* Big table, update */
+/* Test type | Iterations | Entries | BucketSize | KeyLen | HashFunc | InitVal */
+{ ADD_UPDATE, ITERATIONS, 1048576, 1, 16, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 2, 16, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 4, 16, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 8, 16, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 16, 16, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 1, 32, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 2, 32, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 4, 32, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 8, 32, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 16, 32, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 1, 48, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 2, 48, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 4, 48, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 8, 48, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 16, 48, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 1, 64, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 2, 64, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 4, 64, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 8, 64, rte_jhash, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 16, 64, rte_jhash, 0},
+/* Big table, lookup */
+/* Test type | Iterations | Entries | BucketSize | KeyLen | HashFunc | InitVal */
+{ LOOKUP, ITERATIONS, 1048576, 1, 16, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 2, 16, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 4, 16, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 8, 16, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 16, 16, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 1, 32, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 2, 32, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 4, 32, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 8, 32, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 16, 32, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 1, 48, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 2, 48, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 4, 48, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 8, 48, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 16, 48, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 1, 64, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 2, 64, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 4, 64, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 8, 64, rte_jhash, 0},
+{ LOOKUP, ITERATIONS, 1048576, 16, 64, rte_jhash, 0},
+
+/* Small table, add */
+/* Test type | Iterations | Entries | BucketSize | KeyLen | HashFunc | InitVal */
+{ ADD_ON_EMPTY, 1024, 1024, 1, 16, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 2, 16, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 4, 16, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 8, 16, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 16, 16, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 1, 32, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 2, 32, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 4, 32, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 8, 32, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 16, 32, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 1, 48, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 2, 48, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 4, 48, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 8, 48, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 16, 48, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 1, 64, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 2, 64, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 4, 64, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 8, 64, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1024, 1024, 16, 64, rte_hash_crc, 0},
+/* Small table, update */
+/* Test type | Iterations | Entries | BucketSize | KeyLen | HashFunc | InitVal */
+{ ADD_UPDATE, ITERATIONS, 1024, 1, 16, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 2, 16, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 4, 16, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 8, 16, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 16, 16, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 1, 32, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 2, 32, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 4, 32, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 8, 32, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 16, 32, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 1, 48, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 2, 48, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 4, 48, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 8, 48, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 16, 48, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 1, 64, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 2, 64, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 4, 64, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 8, 64, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1024, 16, 64, rte_hash_crc, 0},
+/* Small table, lookup */
+/* Test type | Iterations | Entries | BucketSize | KeyLen | HashFunc | InitVal */
+{ LOOKUP, ITERATIONS, 1024, 1, 16, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 2, 16, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 4, 16, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 8, 16, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 16, 16, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 1, 32, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 2, 32, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 4, 32, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 8, 32, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 16, 32, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 1, 48, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 2, 48, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 4, 48, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 8, 48, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 16, 48, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 1, 64, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 2, 64, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 4, 64, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 8, 64, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1024, 16, 64, rte_hash_crc, 0},
+/* Big table, add */
+/* Test type | Iterations | Entries | BucketSize | KeyLen | HashFunc | InitVal */
+{ ADD_ON_EMPTY, 1048576, 1048576, 1, 16, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 2, 16, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 4, 16, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 8, 16, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 16, 16, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 1, 32, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 2, 32, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 4, 32, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 8, 32, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 16, 32, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 1, 48, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 2, 48, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 4, 48, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 8, 48, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 16, 48, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 1, 64, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 2, 64, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 4, 64, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 8, 64, rte_hash_crc, 0},
+{ ADD_ON_EMPTY, 1048576, 1048576, 16, 64, rte_hash_crc, 0},
+/* Big table, update */
+/* Test type | Iterations | Entries | BucketSize | KeyLen | HashFunc | InitVal */
+{ ADD_UPDATE, ITERATIONS, 1048576, 1, 16, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 2, 16, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 4, 16, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 8, 16, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 16, 16, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 1, 32, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 2, 32, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 4, 32, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 8, 32, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 16, 32, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 1, 48, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 2, 48, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 4, 48, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 8, 48, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 16, 48, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 1, 64, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 2, 64, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 4, 64, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 8, 64, rte_hash_crc, 0},
+{ ADD_UPDATE, ITERATIONS, 1048576, 16, 64, rte_hash_crc, 0},
+/* Big table, lookup */
+/* Test type | Iterations | Entries | BucketSize | KeyLen | HashFunc | InitVal */
+{ LOOKUP, ITERATIONS, 1048576, 1, 16, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 2, 16, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 4, 16, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 8, 16, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 16, 16, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 1, 32, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 2, 32, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 4, 32, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 8, 32, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 16, 32, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 1, 48, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 2, 48, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 4, 48, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 8, 48, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 16, 48, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 1, 64, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 2, 64, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 4, 64, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 8, 64, rte_hash_crc, 0},
+{ LOOKUP, ITERATIONS, 1048576, 16, 64, rte_hash_crc, 0},
+};
+
+/******************************************************************************/
+
+/*******************************************************************************
+ * Hash function performance test configuration section. Each performance test
+ * will be performed HASHTEST_ITERATIONS times.
+ *
+ * The five arrays below control what tests are performed. Every combination
+ * from the array entries is tested.
+ */
+#define HASHTEST_ITERATIONS 1000000
+
+#ifdef RTE_MACHINE_CPUFLAG_SSE4_2
+static rte_hash_function hashtest_funcs[] = {rte_jhash, rte_hash_crc};
+#else
+static rte_hash_function hashtest_funcs[] = {rte_jhash};
+#endif
+static uint32_t hashtest_initvals[] = {0};
+static uint32_t hashtest_key_lens[] = {2, 4, 5, 6, 7, 8, 10, 11, 15, 16, 21, 31, 32, 33, 63, 64};
+/******************************************************************************/
+
+/*
+ * Check condition and return an error if true. Assumes that "handle" is the
+ * name of the hash structure pointer to be freed.
+ */
+#define RETURN_IF_ERROR(cond, str, ...) do { \
+ if (cond) { \
+ printf("ERROR line %d: " str "\n", __LINE__, ##__VA_ARGS__); \
+ if (handle) rte_hash_free(handle); \
+ return -1; \
+ } \
+} while(0)
+
+#define RETURN_IF_ERROR_FBK(cond, str, ...) do { \
+ if (cond) { \
+ printf("ERROR line %d: " str "\n", __LINE__, ##__VA_ARGS__); \
+ if (handle) rte_fbk_hash_free(handle); \
+ return -1; \
+ } \
+} while(0)
+
+/* 5-tuple key type */
+struct flow_key {
+ uint32_t ip_src;
+ uint32_t ip_dst;
+ uint16_t port_src;
+ uint16_t port_dst;
+ uint8_t proto;
+} __attribute__((packed));
+
+/*
+ * Hash function that always returns the same value, to easily test what
+ * happens when a bucket is full.
+ */
+static uint32_t pseudo_hash(__attribute__((unused)) const void *keys,
+ __attribute__((unused)) uint32_t key_len,
+ __attribute__((unused)) uint32_t init_val)
+{
+ return 3;
+}
+
+/*
+ * Print out result of unit test hash operation.
+ */
+#if defined(UNIT_TEST_HASH_VERBOSE)
+static void print_key_info(const char *msg, const struct flow_key *key,
+ int32_t pos)
+{
+ uint8_t *p = (uint8_t *)key;
+ unsigned i;
+
+ printf("%s key:0x", msg);
+ for (i = 0; i < sizeof(struct flow_key); i++) {
+ printf("%02X", p[i]);
+ }
+ printf(" @ pos %d\n", pos);
+}
+#else
+static void print_key_info(__attribute__((unused)) const char *msg,
+ __attribute__((unused)) const struct flow_key *key,
+ __attribute__((unused)) int32_t pos)
+{
+}
+#endif
+
+/* Keys used by unit test functions */
+static struct flow_key keys[5] = { {
+ .ip_src = IPv4(0x03, 0x02, 0x01, 0x00),
+ .ip_dst = IPv4(0x07, 0x06, 0x05, 0x04),
+ .port_src = 0x0908,
+ .port_dst = 0x0b0a,
+ .proto = 0x0c,
+}, {
+ .ip_src = IPv4(0x13, 0x12, 0x11, 0x10),
+ .ip_dst = IPv4(0x17, 0x16, 0x15, 0x14),
+ .port_src = 0x1918,
+ .port_dst = 0x1b1a,
+ .proto = 0x1c,
+}, {
+ .ip_src = IPv4(0x23, 0x22, 0x21, 0x20),
+ .ip_dst = IPv4(0x27, 0x26, 0x25, 0x24),
+ .port_src = 0x2928,
+ .port_dst = 0x2b2a,
+ .proto = 0x2c,
+}, {
+ .ip_src = IPv4(0x33, 0x32, 0x31, 0x30),
+ .ip_dst = IPv4(0x37, 0x36, 0x35, 0x34),
+ .port_src = 0x3938,
+ .port_dst = 0x3b3a,
+ .proto = 0x3c,
+}, {
+ .ip_src = IPv4(0x43, 0x42, 0x41, 0x40),
+ .ip_dst = IPv4(0x47, 0x46, 0x45, 0x44),
+ .port_src = 0x4948,
+ .port_dst = 0x4b4a,
+ .proto = 0x4c,
+} };
+
+/* Parameters used for hash table in unit test functions. Name set later. */
+static struct rte_hash_parameters ut_params = {
+ .entries = 64,
+ .bucket_entries = 4,
+ .key_len = sizeof(struct flow_key), /* 13 */
+ .hash_func = rte_jhash,
+ .hash_func_init_val = 0,
+ .socket_id = 0,
+};
+
+/*
+ * Basic sequence of operations for a single key:
+ * - add
+ * - lookup (hit)
+ * - delete
+ * - lookup (miss)
+ */
+static int test_add_delete(void)
+{
+ struct rte_hash *handle;
+ int pos0, expectedPos0;
+
+ ut_params.name = "test1";
+ handle = rte_hash_create(&ut_params);
+ RETURN_IF_ERROR(handle == NULL, "hash creation failed");
+
+ pos0 = rte_hash_add_key(handle, &keys[0]);
+ print_key_info("Add", &keys[0], pos0);
+ RETURN_IF_ERROR(pos0 < 0, "failed to add key (pos0=%d)", pos0);
+ expectedPos0 = pos0;
+
+ pos0 = rte_hash_lookup(handle, &keys[0]);
+ print_key_info("Lkp", &keys[0], pos0);
+ RETURN_IF_ERROR(pos0 != expectedPos0,
+ "failed to find key (pos0=%d)", pos0);
+
+ pos0 = rte_hash_del_key(handle, &keys[0]);
+ print_key_info("Del", &keys[0], pos0);
+ RETURN_IF_ERROR(pos0 != expectedPos0,
+ "failed to delete key (pos0=%d)", pos0);
+
+ pos0 = rte_hash_lookup(handle, &keys[0]);
+ print_key_info("Lkp", &keys[0], pos0);
+ RETURN_IF_ERROR(pos0 != -ENOENT,
+ "fail: found key after deleting! (pos0=%d)", pos0);
+
+ rte_hash_free(handle);
+ return 0;
+}
+
+/*
+ * Sequence of operations for a single key:
+ * - delete: miss
+ * - add
+ * - lookup: hit
+ * - add: update
+ * - lookup: hit (updated data)
+ * - delete: hit
+ * - delete: miss
+ * - lookup: miss
+ */
+static int test_add_update_delete(void)
+{
+ struct rte_hash *handle;
+ int pos0, expectedPos0;
+
+ ut_params.name = "test2";
+ handle = rte_hash_create(&ut_params);
+ RETURN_IF_ERROR(handle == NULL, "hash creation failed");
+
+ pos0 = rte_hash_del_key(handle, &keys[0]);
+ print_key_info("Del", &keys[0], pos0);
+ RETURN_IF_ERROR(pos0 != -ENOENT,
+ "fail: found non-existent key (pos0=%d)", pos0);
+
+ pos0 = rte_hash_add_key(handle, &keys[0]);
+ print_key_info("Add", &keys[0], pos0);
+ RETURN_IF_ERROR(pos0 < 0, "failed to add key (pos0=%d)", pos0);
+ expectedPos0 = pos0;
+
+ pos0 = rte_hash_lookup(handle, &keys[0]);
+ print_key_info("Lkp", &keys[0], pos0);
+ RETURN_IF_ERROR(pos0 != expectedPos0,
+ "failed to find key (pos0=%d)", pos0);
+
+ pos0 = rte_hash_add_key(handle, &keys[0]);
+ print_key_info("Add", &keys[0], pos0);
+ RETURN_IF_ERROR(pos0 != expectedPos0,
+ "failed to re-add key (pos0=%d)", pos0);
+
+ pos0 = rte_hash_lookup(handle, &keys[0]);
+ print_key_info("Lkp", &keys[0], pos0);
+ RETURN_IF_ERROR(pos0 != expectedPos0,
+ "failed to find key (pos0=%d)", pos0);
+
+ pos0 = rte_hash_del_key(handle, &keys[0]);
+ print_key_info("Del", &keys[0], pos0);
+ RETURN_IF_ERROR(pos0 != expectedPos0,
+ "failed to delete key (pos0=%d)", pos0);
+
+ pos0 = rte_hash_del_key(handle, &keys[0]);
+ print_key_info("Del", &keys[0], pos0);
+ RETURN_IF_ERROR(pos0 != -ENOENT,
+ "fail: deleted already deleted key (pos0=%d)", pos0);
+
+ pos0 = rte_hash_lookup(handle, &keys[0]);
+ print_key_info("Lkp", &keys[0], pos0);
+ RETURN_IF_ERROR(pos0 != -ENOENT,
+ "fail: found key after deleting! (pos0=%d)", pos0);
+
+ rte_hash_free(handle);
+ return 0;
+}
+
+/*
+ * Sequence of operations for find existing hash table
+ *
+ * - create table
+ * - find existing table: hit
+ * - find non-existing table: miss
+ *
+ */
+static int test_hash_find_existing(void)
+{
+ struct rte_hash *handle = NULL, *result = NULL;
+
+ /* Create hash table. */
+ ut_params.name = "hash_find_existing";
+ handle = rte_hash_create(&ut_params);
+ RETURN_IF_ERROR(handle == NULL, "hash creation failed");
+
+ /* Try to find existing hash table */
+ result = rte_hash_find_existing("hash_find_existing");
+ RETURN_IF_ERROR(result != handle, "could not find existing hash table");
+
+ /* Try to find non-existing hash table */
+ result = rte_hash_find_existing("hash_find_non_existing");
+ RETURN_IF_ERROR(!(result == NULL), "found table that shouldn't exist");
+
+ /* Cleanup. */
+ rte_hash_free(handle);
+
+ return 0;
+}
+
+/*
+ * Sequence of operations for 5 keys
+ * - add keys
+ * - lookup keys: hit
+ * - add keys (update)
+ * - lookup keys: hit (updated data)
+ * - delete keys : hit
+ * - lookup keys: miss
+ */
+static int test_five_keys(void)
+{
+ struct rte_hash *handle;
+ const void *key_array[5] = {0};
+ int pos[5];
+ int expected_pos[5];
+ unsigned i;
+ int ret;
+
+ ut_params.name = "test3";
+ handle = rte_hash_create(&ut_params);
+ RETURN_IF_ERROR(handle == NULL, "hash creation failed");
+
+ /* Add */
+ for (i = 0; i < 5; i++) {
+ pos[i] = rte_hash_add_key(handle, &keys[i]);
+ print_key_info("Add", &keys[i], pos[i]);
+ RETURN_IF_ERROR(pos[i] < 0,
+ "failed to add key (pos[%u]=%d)", i, pos[i]);
+ expected_pos[i] = pos[i];
+ }
+
+ /* Lookup */
+ for(i = 0; i < 5; i++)
+ key_array[i] = &keys[i];
+
+ ret = rte_hash_lookup_multi(handle, &key_array[0], 5, (int32_t *)pos);
+ if(ret == 0)
+ for(i = 0; i < 5; i++) {
+ print_key_info("Lkp", key_array[i], pos[i]);
+ RETURN_IF_ERROR(pos[i] != expected_pos[i],
+ "failed to find key (pos[%u]=%d)", i, pos[i]);
+ }
+
+ /* Add - update */
+ for (i = 0; i < 5; i++) {
+ pos[i] = rte_hash_add_key(handle, &keys[i]);
+ print_key_info("Add", &keys[i], pos[i]);
+ RETURN_IF_ERROR(pos[i] != expected_pos[i],
+ "failed to add key (pos[%u]=%d)", i, pos[i]);
+ }
+
+ /* Lookup */
+ for (i = 0; i < 5; i++) {
+ pos[i] = rte_hash_lookup(handle, &keys[i]);
+ print_key_info("Lkp", &keys[i], pos[i]);
+ RETURN_IF_ERROR(pos[i] != expected_pos[i],
+ "failed to find key (pos[%u]=%d)", i, pos[i]);
+ }
+
+ /* Delete */
+ for (i = 0; i < 5; i++) {
+ pos[i] = rte_hash_del_key(handle, &keys[i]);
+ print_key_info("Del", &keys[i], pos[i]);
+ RETURN_IF_ERROR(pos[i] != expected_pos[i],
+ "failed to delete key (pos[%u]=%d)", i, pos[i]);
+ }
+
+ /* Lookup */
+ for (i = 0; i < 5; i++) {
+ pos[i] = rte_hash_lookup(handle, &keys[i]);
+ print_key_info("Lkp", &keys[i], pos[i]);
+ RETURN_IF_ERROR(pos[i] != -ENOENT,
+ "failed to find key (pos[%u]=%d)", i, pos[i]);
+ }
+
+ rte_hash_free(handle);
+
+ return 0;
+}
+
+/*
+ * Add keys to the same bucket until bucket full.
+ * - add 5 keys to the same bucket (hash created with 4 keys per bucket):
+ * first 4 successful, 5th unsuccessful
+ * - lookup the 5 keys: 4 hits, 1 miss
+ * - add the 5 keys again: 4 OK, one error as bucket is full
+ * - lookup the 5 keys: 4 hits (updated data), 1 miss
+ * - delete the 5 keys: 5 OK (even if the 5th is not in the table)
+ * - lookup the 5 keys: 5 misses
+ * - add the 5th key: OK
+ * - lookup the 5th key: hit
+ */
+static int test_full_bucket(void)
+{
+ struct rte_hash_parameters params_pseudo_hash = {
+ .name = "test4",
+ .entries = 64,
+ .bucket_entries = 4,
+ .key_len = sizeof(struct flow_key), /* 13 */
+ .hash_func = pseudo_hash,
+ .hash_func_init_val = 0,
+ .socket_id = 0,
+ };
+ struct rte_hash *handle;
+ int pos[5];
+ int expected_pos[5];
+ unsigned i;
+
+ handle = rte_hash_create(&params_pseudo_hash);
+ RETURN_IF_ERROR(handle == NULL, "hash creation failed");
+
+ /* Fill bucket*/
+ for (i = 0; i < 4; i++) {
+ pos[i] = rte_hash_add_key(handle, &keys[i]);
+ print_key_info("Add", &keys[i], pos[i]);
+ RETURN_IF_ERROR(pos[i] < 0,
+ "failed to add key (pos[%u]=%d)", i, pos[i]);
+ expected_pos[i] = pos[i];
+ }
+ /* This shouldn't work because the bucket is full */
+ pos[4] = rte_hash_add_key(handle, &keys[4]);
+ print_key_info("Add", &keys[4], pos[4]);
+ RETURN_IF_ERROR(pos[4] != -ENOSPC,
+ "fail: added key to full bucket (pos[4]=%d)", pos[4]);
+
+ /* Lookup */
+ for (i = 0; i < 4; i++) {
+ pos[i] = rte_hash_lookup(handle, &keys[i]);
+ print_key_info("Lkp", &keys[i], pos[i]);
+ RETURN_IF_ERROR(pos[i] != expected_pos[i],
+ "failed to find key (pos[%u]=%d)", i, pos[i]);
+ }
+ pos[4] = rte_hash_lookup(handle, &keys[4]);
+ print_key_info("Lkp", &keys[4], pos[4]);
+ RETURN_IF_ERROR(pos[4] != -ENOENT,
+ "fail: found non-existent key (pos[4]=%d)", pos[4]);
+
+ /* Add - update */
+ for (i = 0; i < 4; i++) {
+ pos[i] = rte_hash_add_key(handle, &keys[i]);
+ print_key_info("Add", &keys[i], pos[i]);
+ RETURN_IF_ERROR(pos[i] != expected_pos[i],
+ "failed to add key (pos[%u]=%d)", i, pos[i]);
+ }
+ pos[4] = rte_hash_add_key(handle, &keys[4]);
+ print_key_info("Add", &keys[4], pos[4]);
+ RETURN_IF_ERROR(pos[4] != -ENOSPC,
+ "fail: added key to full bucket (pos[4]=%d)", pos[4]);
+
+ /* Lookup */
+ for (i = 0; i < 4; i++) {
+ pos[i] = rte_hash_lookup(handle, &keys[i]);
+ print_key_info("Lkp", &keys[i], pos[i]);
+ RETURN_IF_ERROR(pos[i] != expected_pos[i],
+ "failed to find key (pos[%u]=%d)", i, pos[i]);
+ }
+ pos[4] = rte_hash_lookup(handle, &keys[4]);
+ print_key_info("Lkp", &keys[4], pos[4]);
+ RETURN_IF_ERROR(pos[4] != -ENOENT,
+ "fail: found non-existent key (pos[4]=%d)", pos[4]);
+
+ /* Delete 1 key, check other keys are still found */
+ pos[1] = rte_hash_del_key(handle, &keys[1]);
+ print_key_info("Del", &keys[1], pos[1]);
+ RETURN_IF_ERROR(pos[1] != expected_pos[1],
+ "failed to delete key (pos[1]=%d)", pos[1]);
+ pos[3] = rte_hash_lookup(handle, &keys[3]);
+ print_key_info("Lkp", &keys[3], pos[3]);
+ RETURN_IF_ERROR(pos[3] != expected_pos[3],
+ "failed lookup after deleting key from same bucket "
+ "(pos[3]=%d)", pos[3]);
+
+ /* Go back to previous state */
+ pos[1] = rte_hash_add_key(handle, &keys[1]);
+ print_key_info("Add", &keys[1], pos[1]);
+ expected_pos[1] = pos[1];
+ RETURN_IF_ERROR(pos[1] < 0, "failed to add key (pos[1]=%d)", pos[1]);
+
+ /* Delete */
+ for (i = 0; i < 4; i++) {
+ pos[i] = rte_hash_del_key(handle, &keys[i]);
+ print_key_info("Del", &keys[i], pos[i]);
+ RETURN_IF_ERROR(pos[i] != expected_pos[i],
+ "failed to delete key (pos[%u]=%d)", i, pos[i]);
+ }
+ pos[4] = rte_hash_del_key(handle, &keys[4]);
+ print_key_info("Del", &keys[4], pos[4]);
+ RETURN_IF_ERROR(pos[4] != -ENOENT,
+ "fail: deleted non-existent key (pos[4]=%d)", pos[4]);
+
+ /* Lookup */
+ for (i = 0; i < 4; i++) {
+ pos[i] = rte_hash_lookup(handle, &keys[i]);
+ print_key_info("Lkp", &keys[i], pos[i]);
+ RETURN_IF_ERROR(pos[i] != -ENOENT,
+ "fail: found non-existent key (pos[%u]=%d)", i, pos[i]);
+ }
+
+ /* Add and lookup the 5th key */
+ pos[4] = rte_hash_add_key(handle, &keys[4]);
+ print_key_info("Add", &keys[4], pos[4]);
+ RETURN_IF_ERROR(pos[4] < 0, "failed to add key (pos[4]=%d)", pos[4]);
+ expected_pos[4] = pos[4];
+ pos[4] = rte_hash_lookup(handle, &keys[4]);
+ print_key_info("Lkp", &keys[4], pos[4]);
+ RETURN_IF_ERROR(pos[4] != expected_pos[4],
+ "failed to find key (pos[4]=%d)", pos[4]);
+
+ rte_hash_free(handle);
+
+ /* Cover the NULL case. */
+ rte_hash_free(0);
+ return 0;
+}
+
+/*
+ * To help print out name of hash functions.
+ */
+static const char *get_hash_name(rte_hash_function f)
+{
+ if (f == rte_jhash)
+ return "jhash";
+
+ if (f == rte_hash_crc)
+ return "rte_hash_crc";
+
+ return "UnknownHash";
+}
+
+/*
+ * Find average of array of numbers.
+ */
+static double
+get_avg(const uint32_t *array, uint32_t size)
+{
+ double sum = 0;
+ unsigned i;
+ for (i = 0; i < size; i++)
+ sum += array[i];
+ return sum / (double)size;
+}
+
+/*
+ * Do a single performance test, of one type of operation.
+ *
+ * @param h
+ * hash table to run test on
+ * @param func
+ * function to call (add, delete or lookup function)
+ * @param avg_occupancy
+ * The average number of entries in each bucket of the hash table
+ * @param invalid_pos_count
+ * The amount of errors (e.g. due to a full bucket).
+ * @return
+ * The average number of ticks per hash function call. A negative number
+ * signifies failure.
+ */
+static double
+run_single_tbl_perf_test(const struct rte_hash *h, hash_operation func,
+ const struct tbl_perf_test_params *params, double *avg_occupancy,
+ uint32_t *invalid_pos_count)
+{
+ uint64_t begin, end, ticks = 0;
+ uint8_t *key = NULL;
+ uint32_t *bucket_occupancies = NULL;
+ uint32_t num_buckets, i, j;
+ int32_t pos;
+
+ /* Initialise */
+ num_buckets = params->entries / params->bucket_entries;
+ key = (uint8_t *) rte_zmalloc("hash key",
+ params->key_len * sizeof(uint8_t), 16);
+ if (key == NULL)
+ return -1;
+
+ bucket_occupancies = (uint32_t *) rte_zmalloc("bucket occupancies",<