2 * Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, ETH Zurich.
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 #include <barrelfish/barrelfish.h>
14 #include <barrelfish/waitset.h>
15 #include <barrelfish/waitset_chan.h>
16 #include <barrelfish/deferred.h>
17 #include <devif/queue_interface.h>
18 #include <devif/backends/net/udp.h>
19 #include <bench/bench.h>
20 #include <net_interfaces/flags.h>
21 #include <net/net_filter.h>
23 //#define DEBUG(x...) printf("devif_test: " x)
24 #define DEBUG(x...) do {} while (0)
28 #define MEMORY_SIZE BASE_PAGE_SIZE*NUM_ENQ
29 #define TX_BUF_SIZE 2048
30 #define RX_BUF_SIZE 2048
32 static uint32_t ip_dst;
33 static uint64_t mac_dst;
34 static uint16_t port_src;
35 static uint16_t port_dst;
37 static struct capref memory_rx;
38 static struct capref memory_tx;
39 static regionid_t regid_rx;
40 static regionid_t regid_tx;
41 static struct frame_identity id;
45 static uint32_t num_tx = 0;
46 static uint32_t num_rx = 0;
47 static struct udp_q* udp_q;
48 static const char* cardname;
51 static void wait_for_interrupt(void)
56 errval_t err = event_dispatch(get_default_waitset());
57 if (err_is_fail(err)) {
58 USER_PANIC_ERR(err, "error in event_dispatch for wait_for_interrupt");
64 static uint64_t total_rx = 0;
65 static bool reg_done = false;
67 static bool use_interrupts = false;
70 static void event_cb(void* queue)
72 struct devq* q = (struct devq*) udp_q;
79 genoffset_t valid_data;
80 genoffset_t valid_length;
85 uint64_t start = 0, end = 0;
91 while (err == SYS_ERR_OK) {
93 err = devq_dequeue(q, &rid, &offset, &length, &valid_data,
94 &valid_length, &flags);
95 if (err_is_fail(err)) {
99 if (flags & NETIF_TXFLAG) {
100 DEBUG("Received TX buffer back \n");
102 } else if (flags & NETIF_RXFLAG) {
104 DEBUG("Received RX buffer \n");
105 err = devq_enqueue(q, rid, offset, length, 0,
108 total_rx += end - start;
110 printf("Unknown flags %lx \n", flags);
115 static void test_udp(void)
120 // create queue with interrupts
121 udp_create(&udp_q, cardname, port_src, port_dst,
122 ip_dst, event_cb, !use_interrupts);
124 q = (struct devq*) udp_q;
130 err = devq_register(q, memory_rx, ®id_rx);
131 if (err_is_fail(err)){
132 USER_PANIC("Registering memory to devq failed \n");
136 for (int i = 0; i < NUM_ENQ; i++) {
137 err = devq_enqueue(q, regid_rx, i*(RX_BUF_SIZE), RX_BUF_SIZE,
140 if (err_is_fail(err)){
141 USER_PANIC("Devq enqueue RX buffer failed \n");
146 err = devq_register(q, memory_tx, ®id_tx);
147 if (err_is_fail(err)){
148 USER_PANIC("Registering memory to devq failed \n");
152 // write something into the buffers
153 char* data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
154 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
155 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
156 printf("Data length %zu \n", strlen(data));
158 for (int i = 0; i < NUM_ENQ; i++) {
159 udp_write_buffer(udp_q, regid_tx, i*(TX_BUF_SIZE),
163 uint64_t total = 0, start = 0, end = 0;
164 for (int z = 0; z < NUM_ENQ; z++) {
167 for (int i = 0; i < NUM_ENQ; i++) {
168 err = devq_enqueue(q, regid_tx, i*(TX_BUF_SIZE), TX_BUF_SIZE,
169 0, strlen(data), NETIF_TXFLAG | NETIF_TXFLAG_LAST);
170 if (err_is_fail(err)){
171 USER_PANIC("Devq enqueue failed \n");
175 while (num_tx < NUM_ENQ*z) {
176 if (use_interrupts) {
177 event_dispatch(get_default_waitset());
184 total += end - start;
186 printf("Average %f cycles TX\n", (double)total/(NUM_ENQ*NUM_ENQ));
187 barrelfish_usleep(1000*1000);
188 printf("Testing receiving UDP packets \n");
190 for (int z = 0; z < NUM_ENQ; z++) {
191 while(num_rx < NUM_ENQ*z) {
192 if (use_interrupts) {
193 event_dispatch(get_default_waitset());
200 printf("Average %f cycles RX\n", (double)total_rx/(NUM_ENQ*NUM_ENQ));
202 err = devq_deregister(q, regid_rx, &memory_rx);
203 if (err_is_fail(err)){
204 printf("%s \n", err_getstring(err));
205 USER_PANIC("Devq deregister tx failed \n");
208 err = devq_deregister(q, regid_tx, &memory_tx);
209 if (err_is_fail(err)){
210 printf("%s \n", err_getstring(err));
211 USER_PANIC("Devq deregister tx failed \n");
214 printf("Receiving UDP packets done \n");
215 printf("SUCCESS: udp test ended \n");
218 int main(int argc, char *argv[])
222 err = frame_alloc(&memory_tx, MEMORY_SIZE, NULL);
223 if (err_is_fail(err)){
224 USER_PANIC("Allocating cap failed \n");
227 err = frame_alloc(&memory_rx, MEMORY_SIZE, NULL);
228 if (err_is_fail(err)){
229 USER_PANIC("Allocating cap failed \n");
233 err = invoke_frame_identify(memory_rx, &id);
234 if (err_is_fail(err)) {
235 USER_PANIC("Frame identify failed \n");
238 err = vspace_map_one_frame_attr(&va_rx, id.bytes, memory_rx,
239 VREGION_FLAGS_READ, NULL, NULL);
240 if (err_is_fail(err)) {
241 USER_PANIC("Frame mapping failed \n");
245 err = invoke_frame_identify(memory_tx, &id);
246 if (err_is_fail(err)) {
247 USER_PANIC("Frame identify failed \n");
250 err = vspace_map_one_frame_attr(&va_tx, id.bytes, memory_tx,
251 VREGION_FLAGS_READ_WRITE, NULL, NULL);
252 if (err_is_fail(err)) {
253 USER_PANIC("Frame mapping failed \n");
258 ip_dst = atoi(argv[1]);
259 mac_dst = strtoull(argv[2], &end, 10);
260 port_src = atoi(argv[3]);
261 port_dst = atoi(argv[4]);
264 USER_PANIC("NO src or dst IP given \n");
267 barrelfish_usleep(1000*1000*15);