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 <barrelfish/sys_debug.h>
18 #include <devif/queue_interface.h>
19 #include <devif/backends/net/udp.h>
20 #include <bench/bench.h>
21 #include <net_interfaces/flags.h>
25 //#define DEBUG(x...) printf("devif_test: " x)
26 #define DEBUG(x...) do {} while (0)
28 #define TX_BUF_SIZE 2048
29 #define RX_BUF_SIZE 2048
31 #define MEMORY_SIZE RX_BUF_SIZE*NUM_BUF
35 static struct devq* udp_q;
36 static struct capref memory_rx;
37 static regionid_t regid_rx;
38 static struct frame_identity id;
39 static lpaddr_t phys_rx;
42 static uint32_t ip_dst;
43 static uint64_t mac_dst;
44 static uint16_t port_src;
45 static uint16_t port_dst;
46 static const char* cardname;
49 static uint64_t bytes = 0;
51 static uint64_t num_dequeue_tx = 0;
52 static uint64_t num_dequeue_rx = 0;
53 static uint64_t num_enqueue_tx = 0;
54 static uint64_t num_enqueue_rx = 0;
55 static uint64_t enq_s, enq_e;
56 static uint64_t deq_s, deq_e;
57 static uint64_t tot_enq_rx, tot_deq_rx;
58 static uint64_t tot_enq_tx, tot_deq_tx;
60 static uint64_t num_rx = 0;
61 static uint64_t start;
63 static uint64_t tsc_per_ms;
65 static bool use_irq = false;
67 static void convert_mac(uint64_t int_mac, struct eth_addr* mac)
69 // Also convert to network byte order
70 mac->addr[5] = int_mac & 0xFF;
71 mac->addr[4] = (int_mac & 0xFF00) >> 8;
72 mac->addr[3] = (int_mac & 0xFF0000) >> 16;
73 mac->addr[2] = (int_mac & 0xFF000000) >> 24;
74 mac->addr[1] = (int_mac & 0xFF00000000) >> 32;
75 mac->addr[0] = (int_mac & 0xFF0000000000) >> 40;
78 static void event_cb(void* queue)
80 struct devq* q = (struct devq*) udp_q;
87 genoffset_t valid_data;
88 genoffset_t valid_length;
93 while (err == SYS_ERR_OK) {
97 err = devq_dequeue(q, &rid, &offset, &length, &valid_data,
98 &valid_length, &flags);
100 if (err_is_fail(err)) {
104 if (flags & NETIF_TXFLAG) {
108 tot_deq_tx += deq_e - deq_s;
110 DEBUG("Received TX buffer back \n");
114 err = devq_enqueue(q, rid, offset, length, 0,
116 if (err_is_fail(err)) {
122 tot_enq_rx += enq_e - enq_s;
124 } else if (flags & NETIF_RXFLAG) {
128 tot_deq_rx += deq_e - deq_s;
131 bytes += valid_length;
132 DEBUG("Received RX buffer \n");
136 // TODO change to TX flag
137 //printf("offset %lu lenght %lu valid_length %lu \n", offset, length, valid_length);
138 err = devq_enqueue(q, rid, offset, length, 0,
139 valid_length, NETIF_TXFLAG | NETIF_TXFLAG_LAST);
140 if (err_is_fail(err)) {
145 tot_enq_tx += enq_e - enq_s;
148 if ((num_rx % 1000000) == 0) {
150 double time = ((double) end-start)/(tsc_per_ms*1000);
151 printf("Mbit/s %f during %f seconds \n",
152 ((double)bytes*8)/(1000*1000*time), time);
153 printf("Num packets/s %f \n", (double) 1000000/time);
155 printf("AVG deq_rx %f micro seconds\n", ((double) (tot_deq_rx/num_dequeue_rx)/(tsc_per_ms/1000)));
156 printf("AVG enq_rx %f micro seconds\n", ((double) (tot_enq_rx/num_enqueue_rx)/(tsc_per_ms/1000)));
157 printf("AVG deq_tx %f micro seconds\n", ((double) (tot_deq_tx/num_dequeue_tx)/(tsc_per_ms/1000)));
158 printf("AVG enq_tx %f micro seconds\n", ((double) (tot_enq_tx/num_enqueue_tx)/(tsc_per_ms/1000)));
174 printf("Unknown flags %lx \n", flags);
180 int main(int argc, char *argv[])
184 ip_dst = atoi(argv[1]);
185 mac_dst = strtoull(argv[2], &stop, 10);
187 port_src = atoi(argv[3]);
188 port_dst = atoi(argv[4]);
191 USER_PANIC("NO src or dst IP given \n");
196 err = frame_alloc(&memory_rx, MEMORY_SIZE, NULL);
197 if (err_is_fail(err)){
198 USER_PANIC("Allocating cap failed \n");
202 err = invoke_frame_identify(memory_rx, &id);
203 if (err_is_fail(err)) {
204 USER_PANIC("Frame identify failed \n");
207 err = vspace_map_one_frame_attr(&va_rx, id.bytes, memory_rx,
208 VREGION_FLAGS_READ_WRITE, NULL, NULL);
209 if (err_is_fail(err)) {
210 USER_PANIC("Frame mapping failed \n");
215 struct eth_addr dst_mac;
217 convert_mac(mac_dst, &dst_mac);
219 err = udp_create((struct udp_q**) &udp_q, cardname, port_src, port_dst,
220 ip_dst, dst_mac, event_cb, true);
221 if (err_is_fail(err)) {
222 USER_PANIC("Queue creation failed \n");
225 err = devq_register(udp_q, memory_rx, ®id_rx);
226 if (err_is_fail(err)) {
227 USER_PANIC("Register failed \n");
230 for (int j = 0; j < NUM_BUF; j++) {
231 err = devq_enqueue(udp_q, regid_rx, j*RX_BUF_SIZE, RX_BUF_SIZE, 0, RX_BUF_SIZE,
233 if (err_is_fail(err)) {
234 USER_PANIC("Err %s \n", err_getstring(err));
238 err = sys_debug_get_tsc_per_ms(&tsc_per_ms);
239 assert(err_is_ok(err));
241 barrelfish_usleep(1000*1000*15);
245 event_dispatch(get_default_waitset());
248 printf("Testing receiving UDP packets \n");