libnet: HW filter disable/enable on queue creation
[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 #include "net_queue_internal.h"
14
15 static errval_t create_loopback_queue(const char* cardname, inthandler_t interrupt, uint64_t *queueid,
16                                       bool default_q, bool poll, struct devq **retqueue)
17 {
18     errval_t err;
19
20     debug_printf("net: creating loopback queue.\n");
21
22     *queueid = 0;
23     err = loopback_queue_create((struct loopback_queue **)retqueue);
24     if (err_is_fail(err)) {
25         return err;
26     }
27
28     return SYS_ERR_OK;
29 }
30
31 static errval_t create_driver_queue(const char* cardname, inthandler_t interrupt, uint64_t *queueid,
32                                     bool default_q, bool poll, struct devq **retqueue)
33 {
34     *queueid = 0;
35     return SYS_ERR_OK;
36 }
37
38 // cardname - "e1000:vendor:deviceid:bus:device:function"
39 static errval_t create_e1000_queue(const char* cardname, inthandler_t interrupt, uint64_t *queueid,
40                                    bool default_q, bool poll, struct devq **retqueue)
41 {
42     if (cardname[5] != ':') {
43         return SYS_ERR_OK;
44     }
45     uint32_t vendor, deviceid, bus, device, function;
46     unsigned parsed = sscanf(cardname + 6, "%x:%x:%x:%x:%x", &vendor,
47                              &deviceid, &bus, &device, &function);
48     if (parsed != 5) {
49         return SYS_ERR_OK;
50     }
51
52     struct net_state* st = get_default_net_state();
53     // disable HW filter since the card does not have them
54     st->hw_filter = false;
55
56     return e1000_queue_create((struct e1000_queue**)retqueue, vendor, deviceid,
57                               bus, device, function, 1, interrupt);
58 }
59
60 static errval_t create_e10k_queue(const char* cardname, inthandler_t interrupt, uint64_t *queueid,
61                                   bool default_q, bool poll, struct devq **retqueue)
62 {
63     errval_t err;
64     struct net_state* st = get_default_net_state();
65     // enable HW filter since they are enabled by default by the driver
66     st->hw_filter = true;
67     err = e10k_queue_create((struct e10k_queue**)retqueue, interrupt,
68                             false /*virtual functions*/,
69                             !poll, /* user interrupts*/
70                             default_q);
71     *queueid = e10k_queue_get_id((struct e10k_queue*)*retqueue);
72     assert(retqueue != NULL);
73     return err;
74 }
75
76 static errval_t create_sfn5122f_queue(const char* cardname, inthandler_t interrupt, uint64_t *queueid,
77                                       bool default_q, bool poll, struct devq **retqueue)
78 {
79     errval_t err;
80     struct net_state* st = get_default_net_state();
81     // enable HW filter since they are enabled by default by the driver
82     st->hw_filter = true;
83     err = sfn5122f_queue_create((struct sfn5122f_queue**)retqueue, interrupt,
84                                 false /*userlevel network feature*/,
85                                 !poll /* user interrupts*/,
86                                 default_q);
87     *queueid = sfn5122f_queue_get_id((struct sfn5122f_queue*)*retqueue);
88     return err;
89 }
90
91
92 typedef errval_t (*queue_create_fn)(const char*, inthandler_t, uint64_t*, bool, bool, struct devq **);
93 struct networking_card
94 {
95     char *cardname;
96     queue_create_fn createfn;
97 } networking_cards [] = {
98     { "loopback", create_loopback_queue},
99     { "driver", create_driver_queue},
100     { "e1000", create_e1000_queue},
101     { "e10k", create_e10k_queue},
102     { "sfn5122f", create_sfn5122f_queue},
103     { NULL, NULL}
104 };
105
106
107 /**
108  * @brief creates a queue to the given card and the queueid
109  *
110  * @param interrupt interrupt handler 
111  * @param cardname  network card to create the queue for
112  * @param queueid   queueid of the network card
113  * @param default_q get the default queue (most of the time queue 0)
114  * @param poll      Is the queue polled or are interrupts used
115  * @param retqueue  returns the pointer to the queue
116  *
117  * @return SYS_ERR_OK on success, errval on failure
118  */
119 errval_t net_queue_internal_create(inthandler_t interrupt, const char *cardname,
120                                    uint64_t* queueid, bool default_q, bool poll, 
121                                    struct devq **retqueue)
122 {
123     struct networking_card *nc = networking_cards;
124     while(nc->cardname != NULL) {
125         if (strncmp(cardname, nc->cardname, strlen(nc->cardname)) == 0) {
126             return nc->createfn(cardname, interrupt, queueid, default_q, 
127                                 poll, retqueue);
128         }
129         nc++;
130     }
131
132     debug_printf("net: ERROR unknown queue. card='%s', queueid=%" PRIu64 "\n",
133                   cardname, *queueid);
134
135     return -1;
136 }
137
138
139 /**
140  * @brief creates a queue to the given card and the queueid
141  *
142  * @param interrupt interrupt handler 
143  * @param cardname  network card to create the queue for
144  * @param queueid   queueid of the network card
145  * @param poll      Is the queue polled or are interrupts used
146  * @param retqueue  returns the pointer to the queue
147  *
148  * @return SYS_ERR_OK on success, errval on failure
149  */
150 errval_t net_queue_create(inthandler_t interrupt, const char *cardname,
151                           uint64_t* queueid, bool poll, struct devq **retqueue)
152 {
153     return net_queue_internal_create(interrupt, cardname, queueid, false, poll, retqueue);
154 }