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/descq.h>
20 #include <bench/bench.h>
25 #define NUM_RX_BUF 1024
26 #define NUM_ROUNDS_TX 16384
27 #define NUM_ROUNDS_RX 128
28 #define MEMORY_SIZE BASE_PAGE_SIZE*512
30 static struct capref memory_rx;
31 static struct capref memory_tx;
32 static regionid_t regid_rx;
33 static regionid_t regid_tx;
34 static struct frame_identity id;
35 static lpaddr_t phys_rx;
36 static lpaddr_t phys_tx;
38 static volatile uint32_t num_tx = 0;
39 static volatile uint32_t num_rx = 0;
45 struct list_ele* first;
46 struct list_ele* last;
56 struct list_ele* next;
60 static struct waitset_chanstate *chan = NULL;
61 static struct waitset card_ws;
64 static uint8_t udp_header[8] = {
65 0x07, 0xD0, 0x07, 0xD0,
66 0x00, 0x80, 0x00, 0x00,
70 static void print_buffer(size_t len, bufferid_t bid)
72 uint8_t* buf = (uint8_t*) va_rx+bid;
73 printf("Packet in region %p at address %p len %zu \n",
75 for (int i = 0; i < len; i++) {
76 if (((i % 10) == 0) && i > 0) {
79 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)) {
114 case DEVQ_BUF_FLAG_TX:
117 case DEVQ_BUF_FLAG_RX:
119 //print_buffer(len, bid);
121 case DEVQ_BUF_FLAG_TX + DEVQ_BUF_FLAG_TX_LAST:
125 printf("Unknown flags \n");
129 // MSIX is not working on sfn5122f yet so we have to "simulate interrupts"
130 err = waitset_chan_register(&card_ws, chan,
131 MKCLOSURE(sfn5122f_event_cb, queue));
132 if (err_is_fail(err) && err_no(err) == LIB_ERR_CHAN_ALREADY_REGISTERED) {
133 printf("Got actual interrupt?\n");
135 else if (err_is_fail(err)) {
136 USER_PANIC_ERR(err, "Can't register our dummy channel.");
138 err = waitset_chan_trigger(chan);
139 if (err_is_fail(err)) {
140 USER_PANIC_ERR(err, "trigger failed.");
144 static void test_sfn5122f_tx(void)
151 struct sfn5122f_queue* queue;
153 printf("SFN5122F direct device test started \n");
154 err = sfn5122f_queue_create(&queue, sfn5122f_event_cb, true, false);
155 if (err_is_fail(err)){
156 USER_PANIC("Allocating devq failed \n");
159 q = (struct devq*) queue;
162 waitset_init(&card_ws);
164 // MSIX is not working on sfn5122f yet so we have to "simulate interrupts"
165 chan = malloc(sizeof(struct waitset_chanstate));
166 waitset_chanstate_init(chan, CHANTYPE_AHCI);
168 err = waitset_chan_register(&card_ws, chan, MKCLOSURE(sfn5122f_event_cb, q));
169 if (err_is_fail(err)) {
170 USER_PANIC_ERR(err, "waitset_chan_regster failed.");
173 err = waitset_chan_trigger(chan);
174 if (err_is_fail(err)) {
175 USER_PANIC_ERR(err, "trigger failed.");
178 err = devq_register(q, memory_tx, ®id_tx);
179 if (err_is_fail(err)){
180 USER_PANIC("Registering memory to devq failed \n");
186 // write something into the buffers
188 uint16_t rest = 4096 -BUF_SIZE;
190 for (int i = 0; i < NUM_ENQ; i++) {
191 write = va_tx + i*(BUF_SIZE+rest);
192 for (int j = 0; j < 8; j++) {
193 write[j] = udp_header[j];
195 for (int j = 8; j < BUF_SIZE; j++) {
201 cycles_t t1 = bench_tsc();
203 for (int z = 0; z < NUM_ROUNDS_TX; z++) {
204 for (int i = 0; i < NUM_ENQ; i++) {
205 addr = phys_tx+(i*(BUF_SIZE));
207 err = devq_enqueue(q, regid_tx, addr, BUF_SIZE,
208 DEVQ_BUF_FLAG_TX | DEVQ_BUF_FLAG_TX_LAST, &bid);
209 if (err_is_fail(err)){
210 USER_PANIC("Devq enqueue failed \n");
215 if ((num_tx < NUM_ENQ)) {
216 wait_for_interrupt();
224 cycles_t t2 = bench_tsc();
225 cycles_t result = (t2 -t1 - bench_tscoverhead());
227 uint64_t sent_bytes = (uint64_t) BUF_SIZE*NUM_ENQ*NUM_ROUNDS_TX;
228 double result_ms = (double) bench_tsc_to_ms(result);
229 double bw = sent_bytes / result_ms / 1000;
231 printf("Write throughput %.2f [MB/s] for %.2f ms \n", bw, result_ms);
233 err = devq_control(q, 1, 1);
234 if (err_is_fail(err)){
235 printf("%s \n", err_getstring(err));
236 USER_PANIC("Devq control failed \n");
239 err = devq_deregister(q, regid_tx, &memory_tx);
240 if (err_is_fail(err)){
241 printf("%s \n", err_getstring(err));
242 USER_PANIC("Devq deregister tx failed \n");
245 err = sfn5122f_queue_destroy((struct sfn5122f_queue*) q);
247 printf("SUCCESS: SFN5122F tx test ended\n");
251 static void test_sfn5122f_rx(void)
258 struct sfn5122f_queue* queue;
260 printf("SFN5122F direct device test started \n");
261 err = sfn5122f_queue_create(&queue, sfn5122f_event_cb, /* userlevel*/ true,
262 /*MSIX interrupts*/ false);
263 if (err_is_fail(err)){
264 USER_PANIC("Allocating devq failed \n");
267 q = (struct devq*) queue;
270 waitset_init(&card_ws);
272 // MSIX is not working on sfn5122f yet so we have to "simulate interrupts"
273 chan = malloc(sizeof(struct waitset_chanstate));
274 waitset_chanstate_init(chan, CHANTYPE_AHCI);
276 err = waitset_chan_register(&card_ws, chan, MKCLOSURE(sfn5122f_event_cb, q));
277 if (err_is_fail(err)) {
278 USER_PANIC_ERR(err, "waitset_chan_regster failed.");
281 err = waitset_chan_trigger(chan);
282 if (err_is_fail(err)) {
283 USER_PANIC_ERR(err, "trigger failed.");
286 err = devq_register(q, memory_rx, ®id_rx);
287 if (err_is_fail(err)){
288 USER_PANIC("Registering memory to devq failed \n");
294 // Enqueue RX buffers to receive into
295 for (int i = 0; i < NUM_ROUNDS_RX; i++){
296 addr = phys_rx+(i*2048);
297 err = devq_enqueue(q, regid_rx, addr, 2048,
298 DEVQ_BUF_FLAG_RX, &bid);
299 if (err_is_fail(err)){
300 USER_PANIC("Devq enqueue failed: %s\n", err_getstring(err));
306 if ((num_rx < NUM_ROUNDS_RX)) {
307 wait_for_interrupt();
314 err = devq_control(q, 1, 1);
315 if (err_is_fail(err)){
316 printf("%s \n", err_getstring(err));
317 USER_PANIC("Devq control failed \n");
320 err = devq_deregister(q, regid_rx, &memory_rx);
321 if (err_is_fail(err)){
322 printf("%s \n", err_getstring(err));
323 USER_PANIC("Devq deregister rx failed \n");
326 err = sfn5122f_queue_destroy((struct sfn5122f_queue*) q);
328 printf("SUCCESS: SFN5122F rx test ended\n");
332 static errval_t descq_notify(struct descq* q)
334 errval_t err = SYS_ERR_OK;
335 struct devq* queue = (struct devq*) q;
343 while(err_is_ok(err)) {
344 err = devq_dequeue(queue, &rid, &addr, &len, &bid, &flags);
352 static void test_idc_queue(void)
360 struct descq_func_pointer* f;
361 f = malloc(sizeof(struct descq_func_pointer));
362 f->notify = descq_notify;
364 printf("Descriptor queue test started \n");
365 err = descq_create(&queue, DESCQ_DEFAULT_SIZE, "test_queue",
367 if (err_is_fail(err)){
368 USER_PANIC("Allocating devq failed \n");
371 q = (struct devq*) queue;
373 err = devq_register(q, memory_rx, ®id_rx);
374 if (err_is_fail(err)){
375 USER_PANIC("Registering memory to devq failed \n");
378 err = devq_register(q, memory_tx, ®id_tx);
379 if (err_is_fail(err)){
380 USER_PANIC("Registering memory to devq failed \n");
385 // Enqueue RX buffers to receive into
386 for (int j = 0; j < 1000000; j++){
387 for (int i = 0; i < 32; i++){
388 addr = phys_rx+(i*2048);
389 err = devq_enqueue(q, regid_rx, addr, 2048,
391 if (err_is_fail(err)){
399 err = devq_notify(q);
400 if (err_is_fail(err)) {
401 USER_PANIC("Devq notify failed: %s\n", err_getstring(err));
403 event_dispatch(get_default_waitset());
406 while(num_tx != num_rx) {
407 event_dispatch(get_default_waitset());
410 err = devq_control(q, 1, 1);
411 if (err_is_fail(err)){
412 printf("%s \n", err_getstring(err));
413 USER_PANIC("Devq control failed \n");
416 err = devq_deregister(q, regid_rx, &memory_rx);
417 if (err_is_fail(err)){
418 printf("%s \n", err_getstring(err));
419 USER_PANIC("Devq deregister rx failed \n");
422 err = devq_deregister(q, regid_tx, &memory_tx);
423 if (err_is_fail(err)){
424 printf("%s \n", err_getstring(err));
425 USER_PANIC("Devq deregister tx failed \n");
428 printf("SUCCESS: IDC queue\n");
431 int main(int argc, char *argv[])
435 err = frame_alloc(&memory_rx, MEMORY_SIZE, NULL);
436 if (err_is_fail(err)){
437 USER_PANIC("Allocating cap failed \n");
440 err = frame_alloc(&memory_tx, MEMORY_SIZE, NULL);
441 if (err_is_fail(err)){
442 USER_PANIC("Allocating cap failed \n");
446 err = invoke_frame_identify(memory_rx, &id);
447 if (err_is_fail(err)) {
448 USER_PANIC("Frame identify failed \n");
451 err = vspace_map_one_frame_attr(&va_rx, MEMORY_SIZE, memory_rx,
452 VREGION_FLAGS_READ, NULL, NULL);
453 if (err_is_fail(err)) {
454 USER_PANIC("Frame mapping failed \n");
460 err = invoke_frame_identify(memory_tx, &id);
461 if (err_is_fail(err)) {
462 USER_PANIC("Frame identify failed \n");
465 err = vspace_map_one_frame_attr(&va_tx, MEMORY_SIZE, memory_tx,
466 VREGION_FLAGS_WRITE, NULL, NULL);
467 if (err_is_fail(err)) {
468 USER_PANIC("Frame mapping failed \n");
473 if (strcmp(argv[1], "net_tx") == 0) {
477 if (strcmp(argv[1], "net_rx") == 0) {
481 if (strcmp(argv[1], "idc") == 0) {
486 barrelfish_usleep(1000*1000*5);