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/sfn5122f_devif.h>
19 //#include <devif/backends/net/e10k_devif.h>
20 #include <devif/backends/descq.h>
21 #include <bench/bench.h>
22 #include <net_interfaces/flags.h>
26 #define NUM_RX_BUF 1024
27 #define NUM_ROUNDS_TX 16384
28 #define NUM_ROUNDS_RX 128
29 #define MEMORY_SIZE BASE_PAGE_SIZE*512
31 static struct capref memory_rx;
32 static struct capref memory_tx;
33 static regionid_t regid_rx;
34 static regionid_t regid_tx;
35 static struct frame_identity id;
36 static lpaddr_t phys_rx;
37 static lpaddr_t phys_tx;
39 static volatile uint32_t num_tx = 0;
40 static volatile uint32_t num_rx = 0;
46 struct list_ele* first;
47 struct list_ele* last;
57 struct list_ele* next;
61 static struct waitset_chanstate *chan = NULL;
62 static struct waitset card_ws;
65 static uint8_t udp_header[8] = {
66 0x07, 0xD0, 0x07, 0xD0,
67 0x00, 0x80, 0x00, 0x00,
71 static void print_buffer(size_t len, bufferid_t bid)
73 uint8_t* buf = (uint8_t*) va_rx+bid;
74 printf("Packet in region %p at address %p len %zu \n",
76 for (int i = 0; i < len; i++) {
77 if (((i % 10) == 0) && i > 0) {
80 printf("%2X ", buf[i]);
85 static void wait_for_interrupt(void)
87 errval_t err = event_dispatch(&card_ws);
88 if (err_is_fail(err)) {
89 USER_PANIC_ERR(err, "error in event_dispatch for wait_for_interrupt");
93 static void sfn5122f_event_cb(void* queue)
95 struct devq* q = (struct devq*) queue;
107 while (err == SYS_ERR_OK) {
108 err = devq_dequeue(q, &rid, &addr, &len, &bid, &flags);
109 if (err_is_fail(err)) {
113 if (flags & NETIF_TXFLAG) {
115 } else if (flags & NETIF_RXFLAG) {
117 //print_buffer(len, bid);
119 printf("Unknown flags \n");
123 // MSIX is not working on sfn5122f yet so we have to "simulate interrupts"
124 err = waitset_chan_register(&card_ws, chan,
125 MKCLOSURE(sfn5122f_event_cb, queue));
126 if (err_is_fail(err) && err_no(err) == LIB_ERR_CHAN_ALREADY_REGISTERED) {
127 printf("Got actual interrupt?\n");
129 else if (err_is_fail(err)) {
130 USER_PANIC_ERR(err, "Can't register our dummy channel.");
132 err = waitset_chan_trigger(chan);
133 if (err_is_fail(err)) {
134 USER_PANIC_ERR(err, "trigger failed.");
138 static void test_sfn5122f_tx(void)
145 struct sfn5122f_queue* queue;
147 printf("SFN5122F direct device test started \n");
148 err = sfn5122f_queue_create(&queue, sfn5122f_event_cb, true, false);
149 if (err_is_fail(err)){
150 USER_PANIC("Allocating devq failed \n");
153 q = (struct devq*) queue;
156 waitset_init(&card_ws);
158 // MSIX is not working on sfn5122f yet so we have to "simulate interrupts"
159 chan = malloc(sizeof(struct waitset_chanstate));
160 waitset_chanstate_init(chan, CHANTYPE_AHCI);
162 err = waitset_chan_register(&card_ws, chan, MKCLOSURE(sfn5122f_event_cb, q));
163 if (err_is_fail(err)) {
164 USER_PANIC_ERR(err, "waitset_chan_regster failed.");
167 err = waitset_chan_trigger(chan);
168 if (err_is_fail(err)) {
169 USER_PANIC_ERR(err, "trigger failed.");
172 err = devq_register(q, memory_tx, ®id_tx);
173 if (err_is_fail(err)){
174 USER_PANIC("Registering memory to devq failed \n");
180 // write something into the buffers
182 uint16_t rest = 4096 -BUF_SIZE;
184 for (int i = 0; i < NUM_ENQ; i++) {
185 write = va_tx + i*(BUF_SIZE+rest);
186 for (int j = 0; j < 8; j++) {
187 write[j] = udp_header[j];
189 for (int j = 8; j < BUF_SIZE; j++) {
195 cycles_t t1 = bench_tsc();
197 for (int z = 0; z < NUM_ROUNDS_TX; z++) {
198 for (int i = 0; i < NUM_ENQ; i++) {
199 addr = phys_tx+(i*(BUF_SIZE));
201 err = devq_enqueue(q, regid_tx, addr, BUF_SIZE,
202 NETIF_TXFLAG | NETIF_TXFLAG_LAST, &bid);
203 if (err_is_fail(err)){
204 USER_PANIC("Devq enqueue failed \n");
209 if ((num_tx < NUM_ENQ)) {
210 wait_for_interrupt();
218 cycles_t t2 = bench_tsc();
219 cycles_t result = (t2 -t1 - bench_tscoverhead());
221 uint64_t sent_bytes = (uint64_t) BUF_SIZE*NUM_ENQ*NUM_ROUNDS_TX;
222 double result_ms = (double) bench_tsc_to_ms(result);
223 double bw = sent_bytes / result_ms / 1000;
225 printf("Write throughput %.2f [MB/s] for %.2f ms \n", bw, result_ms);
227 err = devq_control(q, 1, 1);
228 if (err_is_fail(err)){
229 printf("%s \n", err_getstring(err));
230 USER_PANIC("Devq control failed \n");
233 err = devq_deregister(q, regid_tx, &memory_tx);
234 if (err_is_fail(err)){
235 printf("%s \n", err_getstring(err));
236 USER_PANIC("Devq deregister tx failed \n");
239 err = sfn5122f_queue_destroy((struct sfn5122f_queue*) q);
241 printf("SUCCESS: SFN5122F tx test ended\n");
245 static void test_sfn5122f_rx(void)
252 struct sfn5122f_queue* queue;
254 printf("SFN5122F direct device test started \n");
255 err = sfn5122f_queue_create(&queue, sfn5122f_event_cb, /* userlevel*/ true,
256 /*MSIX interrupts*/ false);
257 if (err_is_fail(err)){
258 USER_PANIC("Allocating devq failed \n");
261 q = (struct devq*) queue;
264 waitset_init(&card_ws);
266 // MSIX is not working on sfn5122f yet so we have to "simulate interrupts"
267 chan = malloc(sizeof(struct waitset_chanstate));
268 waitset_chanstate_init(chan, CHANTYPE_AHCI);
270 err = waitset_chan_register(&card_ws, chan, MKCLOSURE(sfn5122f_event_cb, q));
271 if (err_is_fail(err)) {
272 USER_PANIC_ERR(err, "waitset_chan_regster failed.");
275 err = waitset_chan_trigger(chan);
276 if (err_is_fail(err)) {
277 USER_PANIC_ERR(err, "trigger failed.");
280 err = devq_register(q, memory_rx, ®id_rx);
281 if (err_is_fail(err)){
282 USER_PANIC("Registering memory to devq failed \n");
288 // Enqueue RX buffers to receive into
289 for (int i = 0; i < NUM_ROUNDS_RX; i++){
290 addr = phys_rx+(i*2048);
291 err = devq_enqueue(q, regid_rx, addr, 2048,
293 if (err_is_fail(err)){
294 USER_PANIC("Devq enqueue failed: %s\n", err_getstring(err));
300 if ((num_rx < NUM_ROUNDS_RX)) {
301 wait_for_interrupt();
308 err = devq_control(q, 1, 1);
309 if (err_is_fail(err)){
310 printf("%s \n", err_getstring(err));
311 USER_PANIC("Devq control failed \n");
314 err = devq_deregister(q, regid_rx, &memory_rx);
315 if (err_is_fail(err)){
316 printf("%s \n", err_getstring(err));
317 USER_PANIC("Devq deregister rx failed \n");
320 err = sfn5122f_queue_destroy((struct sfn5122f_queue*) q);
322 printf("SUCCESS: SFN5122F rx test ended\n");
326 static errval_t descq_notify(struct descq* q)
328 errval_t err = SYS_ERR_OK;
329 struct devq* queue = (struct devq*) q;
337 while(err_is_ok(err)) {
338 err = devq_dequeue(queue, &rid, &addr, &len, &bid, &flags);
346 static void test_idc_queue(void)
354 struct descq_func_pointer* f;
355 f = malloc(sizeof(struct descq_func_pointer));
356 f->notify = descq_notify;
358 printf("Descriptor queue test started \n");
359 err = descq_create(&queue, DESCQ_DEFAULT_SIZE, "test_queue",
361 if (err_is_fail(err)){
362 USER_PANIC("Allocating devq failed \n");
365 q = (struct devq*) queue;
367 err = devq_register(q, memory_rx, ®id_rx);
368 if (err_is_fail(err)){
369 USER_PANIC("Registering memory to devq failed \n");
372 err = devq_register(q, memory_tx, ®id_tx);
373 if (err_is_fail(err)){
374 USER_PANIC("Registering memory to devq failed \n");
379 // Enqueue RX buffers to receive into
380 for (int j = 0; j < 1000000; j++){
381 for (int i = 0; i < 32; i++){
382 addr = phys_rx+(i*2048);
383 err = devq_enqueue(q, regid_rx, addr, 2048,
385 if (err_is_fail(err)){
393 err = devq_notify(q);
394 if (err_is_fail(err)) {
395 USER_PANIC("Devq notify failed: %s\n", err_getstring(err));
397 event_dispatch(get_default_waitset());
400 while(num_tx != num_rx) {
401 event_dispatch(get_default_waitset());
404 err = devq_control(q, 1, 1);
405 if (err_is_fail(err)){
406 printf("%s \n", err_getstring(err));
407 USER_PANIC("Devq control failed \n");
410 err = devq_deregister(q, regid_rx, &memory_rx);
411 if (err_is_fail(err)){
412 printf("%s \n", err_getstring(err));
413 USER_PANIC("Devq deregister rx failed \n");
416 err = devq_deregister(q, regid_tx, &memory_tx);
417 if (err_is_fail(err)){
418 printf("%s \n", err_getstring(err));
419 USER_PANIC("Devq deregister tx failed \n");
422 printf("SUCCESS: IDC queue\n");
427 static void e10k_event_cb(void* queue)
432 static void test_e10k_queue(void)
439 struct e10k_queue* queue;
441 printf("e10k test started \n");
442 err = e10k_queue_create(&queue, e10k_event_cb, /* interrupts*/ false,
444 if (err_is_fail(err)){
445 USER_PANIC("Allocating devq failed \n");
448 q = (struct devq*) queue;
451 printf("e10k test endned \n");
455 int main(int argc, char *argv[])
459 err = frame_alloc(&memory_rx, MEMORY_SIZE, NULL);
460 if (err_is_fail(err)){
461 USER_PANIC("Allocating cap failed \n");
464 err = frame_alloc(&memory_tx, MEMORY_SIZE, NULL);
465 if (err_is_fail(err)){
466 USER_PANIC("Allocating cap failed \n");
470 err = invoke_frame_identify(memory_rx, &id);
471 if (err_is_fail(err)) {
472 USER_PANIC("Frame identify failed \n");
475 err = vspace_map_one_frame_attr(&va_rx, MEMORY_SIZE, memory_rx,
476 VREGION_FLAGS_READ, NULL, NULL);
477 if (err_is_fail(err)) {
478 USER_PANIC("Frame mapping failed \n");
484 err = invoke_frame_identify(memory_tx, &id);
485 if (err_is_fail(err)) {
486 USER_PANIC("Frame identify failed \n");
489 err = vspace_map_one_frame_attr(&va_tx, MEMORY_SIZE, memory_tx,
490 VREGION_FLAGS_WRITE, NULL, NULL);
491 if (err_is_fail(err)) {
492 USER_PANIC("Frame mapping failed \n");
497 if (strcmp(argv[1], "net_tx") == 0) {
501 if (strcmp(argv[1], "net_rx") == 0) {
505 if (strcmp(argv[1], "idc") == 0) {
510 if (strcmp(argv[1], "e10k") == 0) {
514 barrelfish_usleep(1000*1000*5);