libnet: added small library to get a hardware queue
[barrelfish] / lib / net / net_queue.c
1 /*
2  * Copyright (c) 2017, ETH Zurich.
3  * All rights reserved.
4  *
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, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8  */
9
10 #include <barrelfish/barrelfish.h>
11 #include <net/net_queue.h>
12 #include "networking_internal.h"
13
14 // cardname - "e1000:vendor:deviceid:bus:device:function"
15 static errval_t create_e1000_queue(char* cardname, inthandler_t interrupt, uint64_t *queueid,
16                                    bool poll, struct devq **retqueue)
17 {
18     if (cardname[5] != ':') {
19         return SYS_ERR_OK;
20     }
21     uint32_t vendor, deviceid, bus, device, function;
22     unsigned parsed = sscanf(cardname + 6, "%x:%x:%x:%x:%x", &vendor,
23                              &deviceid, &bus, &device, &function);
24     if (parsed != 5) {
25         return SYS_ERR_OK;
26     }
27
28     return e1000_queue_create((struct e1000_queue**)retqueue, vendor, deviceid,
29                               bus, device, function, 1, interrupt);
30 }
31
32 static errval_t create_e10k_queue(char* cardname, inthandler_t interrupt, uint64_t *queueid,
33                                   bool poll, struct devq **retqueue)
34 {
35     errval_t err;
36     err = e10k_queue_create((struct e10k_queue**)retqueue, interrupt,
37                             false /*virtual functions*/,
38                             poll, /* user interrupts*/
39                             false);
40     *queueid = e10k_queue_get_id((struct e10k_queue*)*retqueue);
41     return err;
42 }
43
44 static errval_t create_sfn5122f_queue(char* cardname, inthandler_t interrupt, uint64_t *queueid,
45                                       bool poll, struct devq **retqueue)
46 {
47     errval_t err;
48     err = sfn5122f_queue_create((struct sfn5122f_queue**)retqueue, interrupt,
49                                 false /*userlevel network feature*/,
50                                 poll /* user interrupts*/,
51                                 false);
52     *queueid = sfn5122f_queue_get_id((struct sfn5122f_queue*)*retqueue);
53     return err;
54 }
55
56
57 typedef errval_t (*queue_create_fn)(char*, inthandler_t, uint64_t*, bool, struct devq **);
58 struct networking_card
59 {
60     char *cardname;
61     queue_create_fn createfn;
62 } networking_cards [] = {
63     { "e1000", create_e1000_queue},
64     { "e10k", create_e10k_queue},
65     { "sfn5122f", create_sfn5122f_queue},
66     { NULL, NULL}
67 };
68
69
70 /**
71  * @brief creates a queue to the given card and the queueid
72  *
73  * @param interrupt interrupt handler 
74  * @param cardname  network card to create the queue for
75  * @param queueid   queueid of the network card
76  * @param poll      Is the queue polled or are interrupts used
77  * @param retqueue  returns the pointer to the queue
78  *
79  * @return SYS_ERR_OK on success, errval on failure
80  */
81 errval_t net_queue_create(inthandler_t interrupt, const char *cardname,
82                           uint64_t* queueid, bool poll, struct devq **retqueue)
83 {
84     struct networking_card *nc = networking_cards;
85     while(nc->cardname != NULL) {
86         if (strncmp(cardname, nc->cardname, strlen(nc->cardname)) == 0) {
87             return nc->createfn(nc->cardname, interrupt, queueid, poll, retqueue);
88         }
89         nc++;
90     }
91
92     debug_printf("net: ERROR unknown queue. card='%s', queueid=%" PRIu64 "\n",
93                   cardname, *queueid);
94
95     return -1;
96 }