e10k: fixed adding filter bug
[barrelfish] / usr / drivers / e10k / e10k_cdriver.c
1 /*
2  * Copyright (c) 2007-2011, 2013, 2014, 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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdarg.h>
14
15 #include <net_device_manager/net_device_manager.h>
16 #include <pci/pci.h>
17 #include <barrelfish/nameservice_client.h>
18 #include <barrelfish/debug.h>
19 #include <barrelfish/deferred.h>
20 #include <lwip/ip.h>
21 #include <net/net.h>
22 #ifdef LIBRARY
23 #       include <netif/e1000.h>
24 #endif
25
26 #include <if/e10k_defs.h>
27 #include <if/e10k_vf_defs.h>
28 #include <if/net_filter_defs.h>
29 #include <dev/e10k_dev.h>
30
31 #include "e10k.h"
32 #include "sleep.h"
33 #include "helper.h"
34
35 //#define VTON_DCBOFF TODO use if VFs are enabled
36 //#define DCA_ENABLED
37
38 //#define DEBUG(x...) printf("e10k: " x)
39 #define DEBUG(x...) do {} while (0)
40
41 #define QUEUE_INTRX 0
42 #define QUEUE_INTTX 1
43
44 struct queue_state {
45     bool enabled;
46     struct e10k_binding *binding;
47
48     struct capref tx_frame;
49     struct capref txhwb_frame;
50     struct capref rx_frame;
51     uint32_t rxbufsz;
52     uint32_t rxhdrsz;
53
54     size_t msix_index;
55     int16_t msix_intvec;
56     uint8_t msix_intdest;
57     bool use_irq;
58     bool use_rsc;
59
60     uint64_t rx_head;
61     uint64_t tx_head;
62     lvaddr_t tx_va;
63     lvaddr_t rx_va;
64     lvaddr_t txhwb_va;
65 };
66
67 enum filter_l4type {
68     L4_OTHER,
69     L4_UDP,
70     L4_TCP,
71     L4_SCTP
72 };
73
74 enum filter_mask {
75     MASK_L4PROTO    = (1 << 0),
76     MASK_SRCIP      = (1 << 1),
77     MASK_DSTIP      = (1 << 2),
78     MASK_SRCPORT    = (1 << 3),
79     MASK_DSTPORT    = (1 << 4),
80 };
81
82 struct e10k_filter {
83     bool enabled;
84     uint8_t priority;
85     uint8_t queue;
86
87     uint32_t src_ip;
88     uint32_t dst_ip;
89     uint16_t src_port;
90     uint16_t dst_port;
91
92     uint16_t mask;
93     uint16_t l4_type;
94 };
95
96 union macentry {
97     uint8_t as8[6];
98     uint64_t as64;
99 };
100
101 static union macentry mactable[128] = {
102     { .as8 = "\x0\x0\x0\x0\x0\x0" },      // First MAC is never set (loaded from card EEPROM)
103
104     { .as8 = "\x22\xc9\xfc\x96\x83\xfc" },
105     { .as8 = "\xce\x43\x5b\xf7\x3e\x60" },
106     { .as8 = "\x6a\xb0\x62\xf6\xa7\x21" },
107     { .as8 = "\xb2\xdf\xf9\x39\xc6\x10" },
108     { .as8 = "\x92\x77\xe7\x3f\x80\x30" },
109     { .as8 = "\xd6\x88\xd6\x86\x4a\x22" },
110     { .as8 = "\x7e\x64\xe9\x2e\xbe\x4b" },
111     { .as8 = "\xba\xac\x49\xd6\x3c\x77" },
112
113     // We set the rest to all zeroes
114
115     // Last MAC (127) never set (loaded from card EEPROM ... at least, it's already there)
116 };
117
118 static uint16_t credit_refill[128];
119 static uint32_t tx_rate[128];
120
121 // Hack for monolithic driver
122 void qd_main(void) __attribute__((weak));
123 void qd_argument(const char *arg) __attribute__((weak));
124 void qd_interrupt(bool is_rx, bool is_tx) __attribute__((weak));
125 void qd_queue_init_data(struct e10k_binding *b, struct capref registers,
126         uint64_t macaddr) __attribute__((weak));
127 void qd_queue_memory_registered(struct e10k_binding *b) __attribute__((weak));
128 void qd_write_queue_tails(struct e10k_binding *b) __attribute__((weak));
129
130
131 void cd_request_device_info(struct e10k_binding *b);
132 void cd_register_queue_memory(struct e10k_binding *b,
133                               uint8_t n,
134                               struct capref tx_frame,
135                               struct capref txhwb_frame,
136                               struct capref rx_frame,
137                               uint32_t rxbufsz,
138                               uint32_t rxhdrsz,
139                               int16_t msix_intvec,
140                               uint8_t msix_intdest,
141                               bool use_irq,
142                               bool use_rsc,
143                               lvaddr_t tx_va,
144                               lvaddr_t rx_va,
145                               lvaddr_t txhwb_va);
146 void cd_set_interrupt_rate(struct e10k_binding *b,
147                            uint8_t queue,
148                            uint16_t rate);
149
150
151 static void idc_write_queue_tails(struct e10k_binding *b);
152 static void stop_device(void);
153
154 static void device_init(void);
155 static void queue_hw_init(uint8_t n, bool set_tail);
156 //static void queue_hw_stop(uint8_t n);
157 static void interrupt_handler_msix(void* arg);
158 //static void interrupt_handler_msix_b(void* arg);
159
160 static void e10k_flt_ftqf_setup(int index, struct e10k_filter *filter);
161 //static void e10k_flt_etype_setup(int filter, int queue, uint16_t etype);
162
163
164
165 static const char *service_name = "e10k";
166 static int initialized = 0;
167 static bool exported = false;
168 static e10k_t *d = NULL;
169 static struct capref *regframe;
170
171 static bool use_interrupts = false;
172 static bool msix = false;
173
174 /** Specifies if RX/TX is currently enabled on the device. */
175 static bool rxtx_enabled = false;
176
177 // Management of MSI-X vectors
178 static struct bmallocator msix_alloc;
179 /** MSI-X vector used by cdriver */
180 static size_t cdriver_msix = -1;
181 static uint8_t cdriver_vector;
182
183
184 // State of queues and filters
185 static struct queue_state queues[128];
186 static struct e10k_filter filters[128];
187
188 static char buf[4096];
189
190 /* PCI device address passed on command line */
191 static uint32_t pci_bus = PCI_DONT_CARE;
192 static uint32_t pci_device = PCI_DONT_CARE;
193 static uint32_t pci_function = 0;
194 static uint32_t pci_deviceid = E10K_PCI_DEVID;
195
196 /* VFs alloacation data*/
197 static bool vf_used[63];
198
199 static void e10k_flt_ftqf_setup(int idx, struct e10k_filter* filter)
200 {
201     uint16_t m = filter->mask;
202     e10k_l4_proto_t p;
203     e10k_ftqf_t ftqf = 0;
204     e10k_l34timir_t timir = 0;
205     e10k_sdpqf_t sdpqf = 0;
206
207
208     // Write filter data
209     if (!(m & MASK_SRCIP)) {
210         DEBUG("src_ip=%"PRIx32" ", filter->src_ip);
211         e10k_saqf_wr(d, idx, htonl(filter->src_ip));
212     }
213
214     if (!(m & MASK_DSTIP)) {
215         DEBUG("dst_ip=%"PRIx32" ", filter->dst_ip);
216         e10k_daqf_wr(d, idx, htonl(filter->dst_ip));
217     }
218
219     if (!(m & MASK_SRCPORT)) {
220         DEBUG("src_port=%d ", filter->src_port);
221         sdpqf = e10k_sdpqf_src_port_insert(sdpqf, htons(filter->src_port));
222     }
223
224     if (!(m & MASK_DSTPORT)) {
225         DEBUG("dst_port=%d ", filter->dst_port);
226         sdpqf = e10k_sdpqf_dst_port_insert(sdpqf, htons(filter->dst_port));
227     }
228     e10k_sdpqf_wr(d, idx, sdpqf);
229     DEBUG("queue_id=%d \n", filter->queue);
230
231     if (!(m & MASK_L4PROTO)) {
232         switch (filter->l4_type) {
233             case L4_OTHER:  p = e10k_l4other; break;
234             case L4_UDP:    p = e10k_l4udp; break;
235             case L4_TCP:    p = e10k_l4tcp; break;
236             case L4_SCTP:   p = e10k_l4sctp; break;
237             default: assert(0); return;
238         }
239         ftqf = e10k_ftqf_protocol_insert(ftqf, p);
240     }
241
242     // Write mask bits
243     ftqf = e10k_ftqf_m_srcaddr_insert(ftqf, !!(m & MASK_SRCIP));
244     ftqf = e10k_ftqf_m_dstaddr_insert(ftqf, !!(m & MASK_DSTIP));
245     ftqf = e10k_ftqf_m_srcport_insert(ftqf, !!(m & MASK_SRCPORT));
246     ftqf = e10k_ftqf_m_dstport_insert(ftqf, !!(m & MASK_DSTPORT));
247     ftqf = e10k_ftqf_m_protocol_insert(ftqf, !!(m & MASK_L4PROTO));
248
249
250     // Configure destination queue and enable filter
251     timir = e10k_l34timir_rx_queue_insert(timir, filter->queue);
252     e10k_l34timir_wr(d, idx, timir);
253
254     ftqf = e10k_ftqf_priority_insert(ftqf, filter->priority);
255     ftqf = e10k_ftqf_pool_mask_insert(ftqf, 1);
256     ftqf = e10k_ftqf_queue_en_insert(ftqf, 1);
257     e10k_ftqf_wr(d, idx, ftqf);
258 }
259
260 #ifndef LIBRARY
261 static int ftqf_index = 0;
262 static int ftqf_alloc(void)
263 {
264     // FIXME: Do this reasonably
265     return ftqf_index++;
266 }
267
268 static errval_t reg_ftfq_filter(struct e10k_filter* f, uint64_t* fid)
269 {
270     int i;
271
272     DEBUG("reg_ftfq_filter: called\n");
273
274     if ((i = ftqf_alloc()) < 0) {
275         return FILTER_ERR_NOT_ENOUGH_MEMORY;
276     }
277
278
279     filters[i] = *f;
280     filters[i].enabled = true;
281
282     e10k_flt_ftqf_setup(i, f);
283
284     *fid = i + 1;
285
286     return SYS_ERR_OK;
287 }
288 #endif
289
290
291 /****************************************************************************/
292 /* Net filter interface implementation                                      */
293 /****************************************************************************/
294
295
296 static errval_t cb_install_filter(struct net_filter_binding *b,
297                                   net_filter_filter_type_t type,
298                                   uint64_t qid,
299                                   uint32_t src_ip,
300                                   uint32_t dst_ip,
301                                   uint16_t src_port,
302                                   uint16_t dst_port,
303                                   uint64_t* fid)
304 {
305
306     errval_t err;
307     struct e10k_filter f = {
308         .dst_port = dst_port,
309         .src_port = src_port,
310         .dst_ip = dst_ip,
311         .src_ip = src_ip,
312         .l4_type = (type == net_filter_PORT_TCP ? L4_TCP : L4_UDP),
313         .priority = 1,
314         .queue = qid,
315     };
316
317     if (src_ip == 0) {
318         f.mask = f.mask | MASK_SRCIP;
319     }
320
321     // ignore dst ip
322     f.mask = f.mask | MASK_DSTIP;
323
324     if (dst_port == 0) {
325         f.mask = f.mask | MASK_DSTPORT;
326     }
327
328     if (src_port == 0) {
329         f.mask = f.mask | MASK_SRCPORT;
330     }
331
332     *fid = -1ULL;
333
334     err = reg_ftfq_filter(&f, fid);
335     DEBUG("filter registered: err=%s, fid=%"PRIu64"\n", err_getstring(err), *fid);
336     return err;
337 }
338
339
340 static errval_t cb_remove_filter(struct net_filter_binding *b,
341                                  net_filter_filter_type_t type,
342                                  uint64_t filter_id,
343                                  errval_t* err)
344 {
345     if ((type == net_filter_PORT_UDP || type == net_filter_PORT_TCP)){
346         USER_PANIC("NYI");
347         *err = SYS_ERR_OK;
348     } else {
349         *err = NET_FILTER_ERR_NOT_FOUND;
350     }
351
352     DEBUG("unregister_filter: called (%"PRIx64")\n", filter_id);
353     return SYS_ERR_OK;
354 }
355
356 static struct net_filter_rpc_rx_vtbl net_filter_rpc_rx_vtbl = {
357     .install_filter_ip_call = cb_install_filter,
358     .remove_filter_call = cb_remove_filter,
359     .install_filter_mac_call = NULL,
360 };
361
362 static void net_filter_export_cb(void *st, errval_t err, iref_t iref)
363 {
364
365     printf("exported net filter interface\n");
366     err = nameservice_register("net_filter_e10k", iref);
367     assert(err_is_ok(err));
368     DEBUG("Net filter interface exported\n");
369 }
370
371
372 static errval_t net_filter_connect_cb(void *st, struct net_filter_binding *b)
373 {
374     printf("New connection on net filter interface\n");
375     b->rpc_rx_vtbl = net_filter_rpc_rx_vtbl;
376     return SYS_ERR_OK;
377 }
378
379
380 #if 0
381 static void e10k_flt_etype_setup(int filter, int queue, uint16_t etype)
382 {
383     // Clear existing values
384     e10k_etqf_wr(d, filter, 0x0);
385     e10k_etqs_wr(d, filter, 0x0);
386
387     e10k_etqs_rx_queue_wrf(d, filter, queue);
388     e10k_etqs_queue_en_wrf(d, filter, 1);
389
390     e10k_etqf_etype_wrf(d, filter, etype);
391     e10k_etqf_filter_en_wrf(d, filter, 1);
392 }
393
394
395 static errval_t arp_filter(uint64_t qid, uint64_t* fid)
396 {
397     e10k_flt_etype_setup(0, (int) qid, 0x0806);
398     *fid = 0;
399     DEBUG("reg_arp_filter: called\n");
400     return SYS_ERR_OK;
401 }
402
403 static errval_t reg_ftfq_filter(struct e10k_filter* f, uint64_t* fid)
404 {
405     int i;
406
407     DEBUG("reg_ftfq_filter: called\n");
408
409     if ((i = ftqf_alloc()) < 0) {
410         return ETHERSRV_ERR_NOT_ENOUGH_MEM;
411     }
412
413
414     filters[i] = *f;
415     filters[i].enabled = true;
416
417     e10k_flt_ftqf_setup(i, f);
418
419     *fid = i + 1;
420
421     return SYS_ERR_OK;
422 }
423
424 static errval_t ipv4_tcp_port(uint64_t qid, uint16_t port, uint64_t* fid)
425 {
426     struct e10k_filter f = {
427         .dst_port = port,
428         .mask = MASK_SRCIP | MASK_DSTIP | MASK_SRCPORT,
429         .l4_type = L4_TCP,
430         .priority = 1,
431         .queue = qid,
432     };
433
434     DEBUG("ipv4_tcp_port: called\n");
435     return reg_ftfq_filter(&f, fid);
436 }
437
438 static errval_t ipv4_udp_port(uint64_t qid, uint16_t port, uint64_t* fid)
439 {
440     struct e10k_filter f = {
441         .dst_port = port,
442         .mask = MASK_SRCIP | MASK_DSTIP | MASK_SRCPORT,
443         .l4_type = L4_UDP,
444         .priority = 1,
445         .queue = qid,
446     };
447
448     DEBUG("ipv4_udp_port: called\n");
449     return reg_ftfq_filter( &f, fid);
450 }
451
452 static errval_t ipv4_tcp_conn(uint64_t qid,
453                               uint32_t l_ip, uint16_t l_port,
454                               uint32_t r_ip, uint16_t r_port,
455                               uint64_t* fid)
456 {
457     struct e10k_filter f = {
458         .dst_ip = l_ip,
459         .dst_port = l_port,
460         .src_ip = r_ip,
461         .src_port = r_port,
462         .mask = 0,
463         .l4_type = L4_TCP,
464         .priority = 0,
465         .queue = qid,
466     };
467
468     DEBUG("ipv4_tcp_conn: called\n");
469     return reg_ftfq_filter(&f, fid);
470 }
471
472 static errval_t deregister_filter(uint64_t fid)
473 {
474     DEBUG("deregister_filter: called\n");
475     return LIB_ERR_NOT_IMPLEMENTED;
476 }
477
478 #endif
479
480
481 /** Enable RX operation for whole card. */
482 static void rx_enable(void)
483 {
484     e10k_secrxctrl_rx_dis_wrf(d, 1);
485     while (e10k_secrxstat_sr_rdy_rdf(d) == 0); // TODO: Timeout
486     e10k_rxctrl_rxen_wrf(d, 1);
487     e10k_secrxctrl_rx_dis_wrf(d, 0);
488 }
489
490 /** Disable RX operation for whole card. */
491 static void rx_disable(void)
492 {
493     e10k_secrxctrl_rx_dis_wrf(d, 1);
494     while (e10k_secrxstat_sr_rdy_rdf(d) == 0); // TODO: Timeout
495     e10k_rxctrl_rxen_wrf(d, 0);
496     e10k_secrxctrl_rx_dis_wrf(d, 0);
497 }
498
499 /** Enable TX operation for whole card. */
500 static void tx_enable(void)
501 {
502     e10k_dmatxctl_txen_wrf(d, 1);
503 }
504
505 /** Disable TX operation for whole card. */
506 static void tx_disable(void)
507 {
508     e10k_dmatxctl_txen_wrf(d, 0);
509     while (e10k_dmatxctl_txen_rdf(d) != 0); // TODO: timeout
510 }
511
512
513 static void setup_interrupt(size_t *msix_index, uint8_t core, uint8_t vector)
514 {
515     bool res;
516     errval_t err;
517     uint8_t dest;
518
519     res = bmallocator_alloc(&msix_alloc, msix_index);
520     assert(res);
521
522     err = get_apicid_from_core(core, &dest);
523     assert(err_is_ok(err));
524
525     err = pci_msix_vector_init(*msix_index, dest, vector);
526     assert(err_is_ok(err));
527
528     DEBUG("e10k: MSI-X vector setup index=%"PRIx64", core=%d apic=%d swvec=%x\n",
529             *msix_index, core, dest, vector);
530 }
531
532 /**
533  * Initialize hardware registers.
534  * Is also called after a reset of the device.
535  */
536 static void device_init(void)
537 {
538     int i;
539     e10k_ctrl_t ctrl;
540     e10k_pfqde_t pfqde;
541     errval_t err;
542     bool initialized_before = initialized;
543
544     initialized = 0;
545
546     stop_device();
547
548     if (initialized_before) {
549         // Save queue heads and tails
550         for (i = 0; i < 128; i++) {
551             if (queues[i].enabled) {
552                 queues[i].tx_head = e10k_tdh_rd(d, i);
553                 if (i < 64) {
554                     queues[i].rx_head = e10k_rdh_1_rd(d, i);
555                 } else {
556                     queues[i].rx_head = e10k_rdh_2_rd(d, i - 64);
557                 }
558             }
559         }
560     }
561
562     // Make a double reset to be sure
563     for (i = 0; i < 2; i++) {
564         // Issue Global reset
565         ctrl = e10k_ctrl_rd(d);
566         ctrl = e10k_ctrl_lrst_insert(ctrl, 1);
567         ctrl = e10k_ctrl_rst_insert(ctrl, 1);
568         e10k_ctrl_wr(d, ctrl);
569         while ((e10k_ctrl_rst_rdf(d) != 0) ||
570                (e10k_ctrl_lrst_rdf(d) != 0)); // TODO: Timeout
571
572         // Spec says 10, fbsd driver 50
573         milli_sleep(50);
574     }
575     DEBUG("Global reset done\n");
576
577     // Disable interrupts
578     e10k_eimc_cause_wrf(d, 0x7FFFFFFF);
579     e10k_eicr_rd(d);
580
581     // Let firmware know that we have taken over
582     e10k_ctrl_ext_drv_load_wrf(d, 1);
583
584     // NO Snoop disable (from FBSD)
585     // Without this, the driver only works on sbrinz1 if the receive buffers are
586     // mapped non cacheable. If the buffers are mapped cacheable, sometimes we
587     // seem to read old buffer contents, not sure exactly why, as far as
588     // understood this, No snoop should only be enabled by the device if it is
589     // save...
590     // TODO: Also check performance implications of this on gottardo and other
591     // machnies where it works without this.
592     e10k_ctrl_ext_ns_dis_wrf(d, 1);
593
594     // Initialize flow-control registers
595     for (i = 0; i < 8; i++) {
596         if (i < 4) e10k_fcttv_wr(d, i, 0x0);
597         e10k_fcrtl_wr(d, i, 0x0);
598         e10k_fcrth_wr(d, i, 0x0);
599     }
600     e10k_fcrtv_wr(d, 0x0);
601     e10k_fccfg_wr(d, 0x0);
602
603     // Initialize Phy
604     e10k_phy_init(d);
605
606     // Wait for EEPROM auto read
607     while (e10k_eec_auto_rd_rdf(d) == 0); // TODO: Timeout
608     DEBUG("EEPROM auto read done\n");
609
610     // Wait for DMA initialization
611     while (e10k_rdrxctl_dma_initok_rdf(d) == 0); // TODO: Timeout
612
613     // Wait for link to come up
614     while (e10k_links_lnk_up_rdf(d) == 0); // TODO: Timeout
615     DEBUG("Link Up\n");
616     milli_sleep(50);
617
618     // Initialize interrupts
619     e10k_eicr_wr(d, 0xffffffff);
620     if (msix) {
621         // Switch to MSI-X mode
622         e10k_gpie_msix_wrf(d, 1);
623         e10k_gpie_pba_sup_wrf(d, 1);
624         e10k_gpie_ocd_wrf(d, 1);
625
626         // Allocate msix vector for cdriver and set up handler
627         if (cdriver_msix == -1) {
628             err = pci_setup_inthandler(interrupt_handler_msix, NULL, &cdriver_vector);
629             assert(err_is_ok(err));
630
631             setup_interrupt(&cdriver_msix, disp_get_core_id(), cdriver_vector);
632         }
633
634         // Map management interrupts to our vector
635         e10k_ivar_misc_i_alloc0_wrf(d, cdriver_msix);
636         e10k_ivar_misc_i_alloc1_wrf(d, cdriver_msix);
637         e10k_ivar_misc_i_allocval0_wrf(d, 1);
638         e10k_ivar_misc_i_allocval1_wrf(d, 1);
639
640         // Enable auto masking of interrupt
641         e10k_gpie_eiame_wrf(d, 1);
642         e10k_eiamn_wr(d, cdriver_msix / 32, (1 << (cdriver_msix % 32)));
643
644         // Set no interrupt delay
645         e10k_eitr_l_wr(d, cdriver_msix, 0);
646         e10k_gpie_eimen_wrf(d, 1);
647
648         // Enable interrupt
649         e10k_eimsn_wr(d, cdriver_msix / 32, (1 << (cdriver_msix % 32)));
650     } else {
651         // Set no Interrupt delay
652         e10k_eitr_l_wr(d, 0, 0);
653         e10k_gpie_eimen_wrf(d, 1);
654
655         // Enable all interrupts
656         e10k_eimc_wr(d, e10k_eims_rd(d));
657         e10k_eims_cause_wrf(d, 0x7fffffff);
658     }
659
660     // Just a guess for RSC delay
661     e10k_gpie_rsc_delay_wrf(d, 2);
662
663     // Initialize multiple register tables (MAC 0 and 127 are not set)
664     for (i = 0; i < 128; i++) {
665         /* uint64_t mac = e10k_ral_ral_rdf(d, i) | ((uint64_t) e10k_rah_rah_rdf(d, i) << 32); */
666         /* uint8_t *m = (uint8_t *)&mac; */
667         /* DEBUG("Old MAC %d: %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx ... mac valid = %x\n", */
668         /*       i, m[0], m[1], m[2], m[3], m[4], m[5], e10k_rah_av_rdf(d, 0)); */
669
670         if(i > 0 && i < 127) {
671             e10k_ral_wr(d, i, mactable[i].as64 & 0xffffffff);
672             e10k_rah_wr(d, i, mactable[i].as64 >> 32);
673             e10k_rah_av_wrf(d, i, 1);
674
675             /* mac = e10k_ral_ral_rdf(d, i) | ((uint64_t) e10k_rah_rah_rdf(d, i) << 32); */
676             /* m = (uint8_t *)&mac; */
677             /* DEBUG("New MAC %d: %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx ... mac valid = %x\n", */
678             /*       i, m[0], m[1], m[2], m[3], m[4], m[5], e10k_rah_av_rdf(d, 0)); */
679         }
680     }
681     for (i = 0; i < 128; i++)
682         e10k_mta_bit_vec_wrf(d, i, 0);
683     for (i = 0; i < 128; i++)
684         e10k_vfta_vlan_flt_wrf(d, i, 0);
685     for (i = 0; i < 128; i++)
686         e10k_pfvlvfb_wr(d, i, 0);
687
688     for (i = 0; i < 64; i++) {
689 #ifdef VTON_DCBOFF
690         e10k_pfvlvf_vi_en_wrf(d, i, 1);
691 #else
692         e10k_pfvlvf_vi_en_wrf(d, i, 0);
693 #endif
694         e10k_psrtype_wr(d, i, 0);
695     }
696     for (i = 0; i < 128; i++)
697         e10k_pfuta_wr(d, i, 0);
698     for (i = 0; i < 256; i++)
699         e10k_mpsar_pool_ena_wrf(d, i, 0);
700
701     // Program direct match MAC forwarding rules
702     // This setup will assign the first 64 MAC addresses each to a different
703     // RX pool. This assumes we have 64 VFs. The rest is set to filtered.
704     for(i = 0; i < 128; i++) {
705         if(i < 32) {
706             // Pools < 32 (low bits)
707             e10k_mpsar_pool_ena_wrf(d, 2 * i, 1 << i);
708             e10k_mpsar_pool_ena_wrf(d, 2 * i + 1, 0);
709         } else if(i < 64) {
710             // Pools >= 32 and < 64 (high bits)
711             e10k_mpsar_pool_ena_wrf(d, 2 * i, 0);
712             e10k_mpsar_pool_ena_wrf(d, 2 * i + 1, 1 << (i - 32));
713         } else {
714             // Pools >= 64 -> DROP
715             e10k_mpsar_pool_ena_wrf(d, 2 * i, 0);
716             e10k_mpsar_pool_ena_wrf(d, 2 * i + 1, 0);
717         }
718     }
719
720     for (i = 0; i < 128; i++) {
721         e10k_fhft_1_wr(d, i, 0);
722         if (i < 64) {
723             e10k_fhft_2_wr(d, i, 0);
724         }
725     }
726
727 #ifdef VTON_DCBOFF
728     // Disallow per-queue RSC (not supported in SR-IOV mode)
729     e10k_rfctl_rsc_dis_wrf(d, 1);
730 #else
731     // Allow for per-queue RSC
732     e10k_rfctl_rsc_dis_wrf(d, 0);
733 #endif
734
735     // Initialize RX filters
736     for (i = 0; i < 128; i++) {
737         e10k_ftqf_wr(d, i, 0);
738         e10k_saqf_wr(d, i, 0);
739         e10k_daqf_wr(d, i, 0);
740         e10k_sdpqf_wr(d, i, 0);
741     }
742     for (i = 0; i < 32; i++)
743         e10k_reta_wr(d, i, 0);
744     e10k_mcstctrl_mfe_wrf(d, 0);
745
746     // Accept broadcasts
747     e10k_fctrl_bam_wrf(d, 1);
748
749     // Enable Jumbo frames
750     e10k_hlreg0_jumboen_wrf(d, 1);
751     e10k_maxfrs_mfs_wrf(d, 15872);
752
753     // Make sure Rx CRC strip is consistently enabled in HLREG0 and RDRXCTL
754     e10k_hlreg0_rxcrcstrp_wrf(d, 1);
755     // Note: rscfrstsz has to be set to 0 (is mbz)
756     e10k_rdrxctl_t rdrxctl = e10k_rdrxctl_rd(d);
757     rdrxctl = e10k_rdrxctl_crcstrip_insert(rdrxctl, 1);
758     e10k_rdrxctl_wr(d, rdrxctl);
759
760
761     // Configure buffers etc. according to specification
762     // Section 4.6.11.3.4 (DCB, virtualization, no RSS)
763     // 1:1 from spec, though not sure if everything is necessary, but since
764     // initialization is still buggy, I'd rather be conservative and set some
765     // additional flags, even if they aren't strictly necessary.
766     e10k_rttdcs_arbdis_wrf(d, 1);
767
768 #ifdef VTON_DCBOFF
769     e10k_rxpbsize_size_wrf(d, 0, 0x200);
770     e10k_txpbsize_size_wrf(d, 0, 0xA0);
771     e10k_txpbthresh_thresh_wrf(d, 0, 0xA0);
772     for (i = 1; i < 8; i++) {
773         e10k_rxpbsize_size_wrf(d, i, 0x0);
774         e10k_txpbsize_size_wrf(d, i, 0x0);
775         e10k_txpbthresh_thresh_wrf(d, i, 0x0);
776     }
777
778     e10k_mrqc_mrque_wrf(d, e10k_vrt_only);
779     e10k_mtqc_rt_en_wrf(d, 0);
780     e10k_mtqc_vt_en_wrf(d, 1);
781     e10k_mtqc_num_tc_wrf(d, 1);
782     e10k_pfvtctl_vt_en_wrf(d, 1);
783 #else
784     e10k_rxpbsize_size_wrf(d, 0, 0x200);
785     e10k_txpbsize_size_wrf(d, 0, 0xA0);
786     e10k_txpbthresh_thresh_wrf(d, 0, 0xA0);
787     for (i = 1; i < 8; i++) {
788         e10k_rxpbsize_size_wrf(d, i, 0x0);
789         e10k_txpbsize_size_wrf(d, i, 0x0);
790         e10k_txpbthresh_thresh_wrf(d, i, 0x0);
791     }
792
793     e10k_mrqc_mrque_wrf(d, e10k_no_rss);
794     e10k_mtqc_rt_en_wrf(d, 0);
795     e10k_mtqc_vt_en_wrf(d, 0);
796     e10k_mtqc_num_tc_wrf(d, 0);
797     e10k_pfvtctl_vt_en_wrf(d, 0);
798 #endif
799     e10k_rtrup2tc_wr(d, 0);
800     e10k_rttup2tc_wr(d, 0);
801
802 #ifdef VTON_DCBOFF
803     e10k_dtxmxszrq_max_bytes_wrf(d, 0xFFF);
804 #else
805     e10k_dtxmxszrq_max_bytes_wrf(d, 0x010);
806 #endif
807
808     e10k_rttdcs_arbdis_wrf(d, 0);
809
810     for (i = 0; i < 128; i++) {
811         pfqde = e10k_pfqde_queue_idx_insert(0x0, i);
812         pfqde = e10k_pfqde_we_insert(pfqde, 1);
813         // XXX: Might want to set drop enable here
814         /* pfqde = e10k_pfqde_qde_insert(pfqde, 1); */
815         e10k_pfqde_wr(d, pfqde);
816     }
817
818 #ifdef VTON_DCBOFF
819     e10k_mflcn_rpfce_wrf(d, 0);
820     e10k_mflcn_rfce_wrf(d, 0);
821     e10k_fccfg_tfce_wrf(d, e10k_lfc_en);
822 #else
823     e10k_mflcn_rpfce_wrf(d, 1);
824     e10k_mflcn_rfce_wrf(d, 0);
825     e10k_fccfg_tfce_wrf(d, e10k_pfc_en);
826 #endif
827
828     /* Causes ECC error (could be same problem as with l34timir (see e10k.dev) */
829     for (i = 0; i < 128; i++) {
830         e10k_rttdqsel_txdq_idx_wrf(d, i);
831         e10k_rttdt1c_wr(d, credit_refill[i]);   // Credit refill x 64 bytes
832         e10k_rttbcnrc_wr(d, 0);
833         if(tx_rate[i] != 0) {
834             // Turn on rate scheduler for this queue and set rate factor
835             e10k_rttbcnrc_t rttbcnrc = 0;
836             // XXX: Assuming 10Gb/s link speed. Change if that's not correct.
837             uint32_t tx_factor = (10000 << 14) / tx_rate[i];
838
839             rttbcnrc = e10k_rttbcnrc_rf_dec_insert(rttbcnrc, tx_factor & 0x3fff);
840             rttbcnrc = e10k_rttbcnrc_rf_int_insert(rttbcnrc, tx_factor >> 14);
841             rttbcnrc = e10k_rttbcnrc_rs_ena_insert(rttbcnrc, 1);
842             e10k_rttbcnrc_wr(d, rttbcnrc);
843
844             printf("Setting rate for queue %d to %u\n", i, tx_rate[i]);
845         }
846     }
847
848     for (i = 0; i < 8; i++) {
849         e10k_rttdt2c_wr(d, i, 0);
850         e10k_rttpt2c_wr(d, i, 0);
851         e10k_rtrpt4c_wr(d, i, 0);
852     }
853
854 #ifdef VTON_DCBOFF
855     e10k_rttdcs_tdpac_wrf(d, 0);
856     e10k_rttdcs_vmpac_wrf(d, 1);        // Remember to set RTTDT1C >= MTU when this is 1
857
858     e10k_rttdcs_tdrm_wrf(d, 0);
859     e10k_rttdcs_bdpm_wrf(d, 1);
860     e10k_rttdcs_bpbfsm_wrf(d, 0);
861     e10k_rttpcs_tppac_wrf(d, 0);
862     e10k_rttpcs_tprm_wrf(d, 0);
863     e10k_rttpcs_arbd_wrf(d, 0x224);
864     e10k_rtrpcs_rac_wrf(d, 0);
865     e10k_rtrpcs_rrm_wrf(d, 0);
866 #else
867
868     e10k_rttdcs_tdpac_wrf(d, 0);
869     e10k_rttdcs_vmpac_wrf(d, 0);
870     e10k_rttdcs_tdrm_wrf(d, 0);
871     e10k_rttdcs_bdpm_wrf(d, 1);
872     e10k_rttdcs_bpbfsm_wrf(d, 1);
873     e10k_rttpcs_tppac_wrf(d, 0);
874     e10k_rttpcs_tprm_wrf(d, 0);
875     e10k_rttpcs_arbd_wrf(d, 0x224);
876     e10k_rtrpcs_rac_wrf(d, 0);
877     e10k_rtrpcs_rrm_wrf(d, 0);
878 #endif
879
880     // disable relaxed ordering
881     for (i = 0; i < 128; i++) {
882         e10k_dca_txctrl_txdesc_wbro_wrf(d, i, 0);
883         if (i < 64) {
884             e10k_dca_rxctrl_1_rxhdr_ro_wrf(d, i, 0);
885             e10k_dca_rxctrl_1_rxdata_wrro_wrf(d, i, 0);
886         } else {
887             e10k_dca_rxctrl_2_rxhdr_ro_wrf(d, i - 64, 0);
888             e10k_dca_rxctrl_2_rxdata_wrro_wrf(d, i - 64, 0);
889         }
890     }
891
892     // disable all queues
893     for (i = 0; i < 128; i++) {
894         e10k_txdctl_enable_wrf(d, i, 0);
895         if (i < 64) {
896             e10k_rxdctl_1_enable_wrf(d, i, 0);
897         } else {
898             e10k_rxdctl_2_enable_wrf(d, i - 64, 0);
899         }
900     }
901
902     for(i = 0; i < 64; i++) {
903         e10k_pfvml2flt_mpe_wrf(d, i, 1);
904         e10k_pfvml2flt_bam_wrf(d, i, 1);
905         e10k_pfvml2flt_aupe_wrf(d, i, 1);
906     }
907
908 #ifdef DCA_ENABLED
909     // Enable DCA (Direct Cache Access)
910     {
911         e10k_dca_ctrl_t dca_ctrl = 0;
912         dca_ctrl = e10k_dca_ctrl_dca_mode_insert(dca_ctrl, e10k_dca10);
913         e10k_dca_ctrl_wr(d, dca_ctrl);
914     }
915
916     printf("DCA globally enabled\n");
917 #endif
918
919     DEBUG("Card initialized (%d)\n", initialized_before);
920
921
922     // Restore configuration
923     if (initialized_before) {
924         // Restoring filters
925         for (i = 0; i < 128; i++) {
926             if (filters[i].enabled) {
927                 e10k_flt_ftqf_setup(i, filters + i);
928             }
929         }
930
931         // Restoring queues
932         for (i = 0; i < 128; i++) {
933             if (queues[i].enabled) {
934                 queue_hw_init(i, true);
935             }
936         }
937
938         DEBUG("Configuration restored\n");
939     }
940
941     initialized = 1;
942 }
943
944 /** Initialize hardware queue n. */
945 static void queue_hw_init(uint8_t n, bool set_tail)
946 {
947     errval_t r;
948     struct frame_identity frameid = { .base = 0, .bytes = 0 };
949     uint64_t tx_phys, txhwb_phys, rx_phys;
950     size_t tx_size, rx_size;
951     bool enable_global = !rxtx_enabled;
952
953     // Get physical addresses for rx/tx rings
954     r = invoke_frame_identify(queues[n].tx_frame, &frameid);
955     assert(err_is_ok(r));
956     tx_phys = frameid.base;
957     tx_size = frameid.bytes;
958
959     r = invoke_frame_identify(queues[n].rx_frame, &frameid);
960     assert(err_is_ok(r));
961     rx_phys = frameid.base;
962     rx_size = frameid.bytes;
963
964     DEBUG("tx.phys=%"PRIx64" tx.size=%"PRIu64"\n", tx_phys, tx_size);
965     DEBUG("rx.phys=%"PRIx64" rx.size=%"PRIu64"\n", rx_phys, rx_size);
966
967
968     // Initialize RX queue in HW
969     if (queues[n].rx_va) {
970         e10k_rdbal_1_wr(d, n, queues[n].rx_va);
971         e10k_rdbah_1_wr(d, n, (queues[n].rx_va) >> 32);
972     } else {
973         e10k_rdbal_1_wr(d, n, rx_phys);
974         e10k_rdbah_1_wr(d, n, rx_phys >> 32);
975     }
976     e10k_rdlen_1_wr(d, n, rx_size);
977
978     e10k_srrctl_1_bsz_pkt_wrf(d, n, queues[n].rxbufsz / 1024);
979     uint32_t hdrsz = queues[n].rxhdrsz;
980     if (hdrsz == 0) {
981         hdrsz = 128;
982     }
983     assert(hdrsz % 64 == 0);
984     assert(hdrsz >= 128 && hdrsz <= 1024);
985
986     e10k_srrctl_1_bsz_hdr_wrf(d, n, hdrsz / 64);
987     // Enable header split if desired
988     if (queues[n].rxhdrsz != 0) {
989         e10k_srrctl_1_desctype_wrf(d, n, e10k_adv_hdrsp);
990         // Split packets after TCP, UDP, IP4, IP6 and L2 headers if we enable
991         // header split
992         e10k_psrtype_split_tcp_wrf(d, n, 1);
993         e10k_psrtype_split_udp_wrf(d, n, 1);
994         e10k_psrtype_split_ip4_wrf(d, n, 1);
995         e10k_psrtype_split_ip6_wrf(d, n, 1);
996         e10k_psrtype_split_l2_wrf(d, n, 1);
997     } else {
998         //e10k_srrctl_1_desctype_wrf(d, n, e10k_adv_1buf);
999         e10k_srrctl_1_desctype_wrf(d, n, e10k_legacy);
1000     }
1001     e10k_srrctl_1_bsz_hdr_wrf(d, n, 128 / 64); // TODO: Do 128 bytes suffice in
1002                                                //       all cases?
1003     e10k_srrctl_1_drop_en_wrf(d, n, 1);
1004
1005     // Set RSC status
1006     if (queues[n].use_rsc) {
1007         USER_PANIC("RSC not supported in SR-IOV mode!\n");
1008         e10k_rscctl_1_maxdesc_wrf(d, n, 3);
1009         e10k_rscctl_1_rsc_en_wrf(d, n, 1);
1010         // TODO: (how) does this work for queues >=64?
1011         e10k_psrtype_split_tcp_wrf(d, n, 1); // needed for RSC
1012     } else {
1013         e10k_rscctl_1_maxdesc_wrf(d, n, 0);
1014         e10k_rscctl_1_rsc_en_wrf(d, n, 0);
1015     }
1016
1017     // Initialize queue pointers (empty)
1018     e10k_rdt_1_wr(d, n, queues[n].rx_head);
1019     e10k_rdh_1_wr(d, n, queues[n].rx_head);
1020
1021 #ifdef VTON_DCBOFF
1022     // Open virtualization pool gate (assumes 64 VF mapping)
1023     e10k_pfvfre_wr(d, n / 64, e10k_pfvfre_rd(d, n / 64) | (1 << ((n / 2) % 32)));
1024 #endif
1025
1026     e10k_rxdctl_1_enable_wrf(d, n, 1);
1027     while (e10k_rxdctl_1_enable_rdf(d, n) == 0); // TODO: Timeout
1028     DEBUG("[%x] RX queue enabled\n", n);
1029
1030     // Setup Interrupts for this queue
1031     if (queues[n].use_irq) {
1032         uint8_t rxv, txv;
1033         // Look for interrupt vector
1034         if (queues[n].msix_intvec != 0) {
1035             if (queues[n].msix_index == -1) {
1036                 setup_interrupt(&queues[n].msix_index, queues[n].msix_intdest,
1037                                 queues[n].msix_intvec);
1038             }
1039             rxv = txv = queues[n].msix_index;
1040         } else {
1041             rxv = QUEUE_INTRX;
1042             txv = QUEUE_INTTX;
1043         }
1044         DEBUG("rxv=%d txv=%d\n", rxv, txv);
1045
1046         // Setup mapping queue Rx/Tx -> interrupt
1047         uint8_t i = n / 2;
1048         if ((n % 2) == 0) {
1049             e10k_ivar_i_alloc0_wrf(d, i, rxv);
1050             e10k_ivar_i_allocval0_wrf(d, i, 1);
1051             e10k_ivar_i_alloc1_wrf(d, i, txv);
1052             e10k_ivar_i_allocval1_wrf(d, i, 1);
1053         } else {
1054             e10k_ivar_i_alloc2_wrf(d, i, rxv);
1055             e10k_ivar_i_allocval2_wrf(d, i, 1);
1056             e10k_ivar_i_alloc3_wrf(d, i, txv);
1057             e10k_ivar_i_allocval3_wrf(d, i, 1);
1058         }
1059         if (queues[n].msix_intvec != 0) {
1060             e10k_eitr_l_wr(d, rxv, 0);
1061
1062             // Enable autoclear (higher ones are always auto cleared)
1063             if (rxv < 16) {
1064                 e10k_eiac_rtxq_wrf(d, e10k_eiac_rtxq_rdf(d) | (1 << rxv));
1065             }
1066
1067         }
1068         if (rxv < 16) {
1069             // Make sure interrupt is cleared
1070             e10k_eicr_wr(d, 1 << rxv);
1071         }
1072
1073         // Enable interrupt
1074         e10k_eimsn_wr(d, rxv / 32, (1 << (rxv % 32)));
1075     }
1076
1077     // Enable RX
1078     if (enable_global) {
1079         DEBUG("[%x] Enabling RX globally...\n", n);
1080         rx_enable();
1081         DEBUG("[%x] RX globally enabled\n", n);
1082     }
1083
1084 #ifdef DCA_ENABLED
1085     {
1086         // Enable DCA for this queue
1087         e10k_dca_rxctrl_t dca_rxctrl = 0;
1088
1089         dca_rxctrl = e10k_dca_rxctrl_rxdca_desc_insert(dca_rxctrl, 1);
1090         dca_rxctrl = e10k_dca_rxctrl_rxdca_hdr_insert(dca_rxctrl, 1);
1091         dca_rxctrl = e10k_dca_rxctrl_rxdca_payl_insert(dca_rxctrl, 1);
1092
1093         uint8_t my_apic_id;
1094         errval_t err = sys_debug_get_apic_id(&my_apic_id);
1095         assert(err_is_ok(err));
1096
1097         dca_rxctrl = e10k_dca_rxctrl_cpuid_insert(dca_rxctrl, my_apic_id);
1098
1099         if(n < 64) {
1100             e10k_dca_rxctrl_1_wr(d, n, dca_rxctrl);
1101         } else {
1102             e10k_dca_rxctrl_2_wr(d, n - 64, dca_rxctrl);
1103         }
1104
1105         printf("DCA enabled on queue %d with APIC ID %d\n", n, my_apic_id);
1106     }
1107 #endif
1108
1109     // Initialize TX queue in HW
1110     if (queues[n].rx_va) {
1111         e10k_tdbal_wr(d, n, queues[n].tx_va);
1112         e10k_tdbah_wr(d, n, (queues[n].tx_va) >> 32);
1113     } else {
1114         e10k_tdbal_wr(d, n, tx_phys);
1115         e10k_tdbah_wr(d, n, tx_phys >> 32);
1116     }
1117     e10k_tdlen_wr(d, n, tx_size);
1118
1119     // Initialize TX head index write back
1120     if (!capref_is_null(queues[n].txhwb_frame)) {
1121         r = invoke_frame_identify(queues[n].txhwb_frame, &frameid);
1122         assert(err_is_ok(r));
1123         txhwb_phys = frameid.base;
1124         if (queues[n].rx_va) {
1125             e10k_tdwbal_headwb_low_wrf(d, n, (queues[n].txhwb_va) >> 2);
1126             e10k_tdwbah_headwb_high_wrf(d, n, (queues[n].txhwb_va) >> 32);
1127         } else {
1128             e10k_tdwbal_headwb_low_wrf(d, n, txhwb_phys >> 2);
1129             e10k_tdwbah_headwb_high_wrf(d, n, txhwb_phys >> 32);
1130         }
1131         e10k_tdwbal_headwb_en_wrf(d, n, 1);
1132     }
1133
1134     // Initialized by queue driver to avoid race conditions
1135     // Initialize queue pointers
1136     e10k_tdh_wr(d, n, queues[n].tx_head);
1137     e10k_tdt_wr(d, n, queues[n].tx_head);
1138
1139     // Configure prefetch and writeback threshhold
1140     e10k_txdctl_pthresh_wrf(d, n, 8); // FIXME: Figure out what the right number
1141                                       //        is here.
1142     e10k_txdctl_hthresh_wrf(d, n, 0);
1143     e10k_txdctl_wthresh_wrf(d, n, 0);
1144
1145     if (enable_global) {
1146         DEBUG("[%x] Enabling TX globally...\n", n);
1147         tx_enable();
1148         rxtx_enabled = true;
1149         DEBUG("[%x] TX globally enabled\n", n);
1150     }
1151
1152 #ifdef VTON_DCBOFF
1153     // Open virtualization pool gate (assumes 64 VF mapping)
1154     e10k_pfvfte_wr(d, n / 64, e10k_pfvfte_rd(d, n / 64) | (1 << ((n / 2) % 32)));
1155 #endif
1156
1157     e10k_txdctl_enable_wrf(d, n, 1);
1158     while (e10k_txdctl_enable_rdf(d, n) == 0); // TODO: Timeout
1159     DEBUG("[%x] TX queue enabled\n", n);
1160
1161     // Some initialization stuff from BSD driver
1162     e10k_dca_txctrl_txdesc_wbro_wrf(d, n, 0);
1163
1164     if (set_tail) {
1165         idc_write_queue_tails(queues[n].binding);
1166     }
1167 }
1168
1169 #ifndef LIBRARY
1170 /** Stop queue. */
1171 static void queue_hw_stop(uint8_t n)
1172 {
1173     // This process is described in 4.6.7.1.2
1174
1175     // Disable TX for this queue
1176     e10k_txdctl_enable_wrf(d, n, 0);
1177
1178     // TODO: Flush packet buffers
1179     // TODO: Remove all filters
1180     // TODO: With RSC we have to wait here (see spec), not used atm
1181
1182     // Disable RX for this queue
1183     e10k_rxdctl_1_enable_wrf(d, n, 0);
1184     while (e10k_rxdctl_1_enable_rdf(d, n) != 0); // TODO: Timeout
1185
1186     // A bit too much, but make sure memory is not used anymore
1187     milli_sleep(1);
1188 }
1189 #endif
1190
1191
1192 /** Stop whole device. */
1193 static void stop_device(void)
1194 {
1195     int i = 0;
1196
1197     DEBUG("Stopping device\n");
1198
1199     // Disable RX and TX
1200     rx_disable();
1201     tx_disable();
1202     rxtx_enabled = false;
1203
1204     // Disable interrupts
1205     e10k_eimc_cause_wrf(d, 0x7FFFFFFF);
1206     e10k_eicr_rd(d);
1207
1208     // Disable each RX and TX queue
1209     for (i = 0; i < 128; i++) {
1210         e10k_txdctl_wr(d, i, e10k_txdctl_swflsh_insert(0x0, 1));
1211
1212         if (i < 64) {
1213             e10k_rxdctl_1_wr(d, i, 0x0);
1214         } else {
1215             e10k_rxdctl_2_wr(d, i - 64, 0x0);
1216         }
1217
1218     }
1219
1220     // From BSD driver (not in spec)
1221     milli_sleep(2);
1222
1223     // Master disable procedure
1224     e10k_ctrl_pcie_md_wrf(d, 1);
1225     while (e10k_status_pcie_mes_rdf(d) != 0); // TODO: Timeout
1226     DEBUG("Stopping device done\n");
1227 }
1228
1229 static void management_interrupt(e10k_eicr_t eicr)
1230 {
1231     if (e10k_eicr_ecc_extract(eicr)) {
1232         DEBUG("##########################################\n");
1233         DEBUG("ECC Error, resetting device :-/\n");
1234         DEBUG("##########################################\n");
1235         device_init();
1236     } else if (eicr >> 16) {
1237         DEBUG("Interrupt: %x\n", eicr);
1238         e10k_eicr_prtval(buf, sizeof(buf), eicr);
1239         puts(buf);
1240     } else if (msix) {
1241         DEBUG("Weird management interrupt without cause: eicr=%x\n", eicr);
1242     }
1243 }
1244
1245 static void interrupt_handler_msix(void* arg)
1246 {
1247     DEBUG("e10k: MSI-X management interrupt\n");
1248     e10k_eicr_t eicr = e10k_eicr_rd(d);
1249
1250     eicr &= ~(1 << cdriver_msix);
1251     management_interrupt(eicr);
1252
1253     // Ensure management MSI-X vector is cleared
1254     e10k_eicr_wr(d, (1 << cdriver_msix));
1255
1256     // Reenable interrupt
1257     e10k_eimsn_cause_wrf(d, cdriver_msix / 32, (1 << (cdriver_msix % 32)));
1258 }
1259
1260 /** Here are the global interrupts handled. */
1261 static void interrupt_handler(void* arg)
1262 {
1263     DEBUG("e10k: received interrupt\n");
1264     e10k_eicr_t eicr = e10k_eicr_rd(d);
1265
1266     if (eicr >> 16) {
1267         management_interrupt(eicr);
1268     }
1269     if (eicr & ((1 << QUEUE_INTRX) | (1 << QUEUE_INTTX))) {
1270         e10k_eicr_wr(d, eicr);
1271         qd_interrupt(!!(eicr & (1 << QUEUE_INTRX)),
1272                      !!(eicr & (1 << QUEUE_INTTX)));
1273     }
1274
1275     // Reenable interrupt
1276     e10k_eimsn_cause_wrf(d, 0, 0x1);
1277 }
1278
1279 /******************************************************************************/
1280 /* Management interface implemetation */
1281
1282 /** Send register cap and mac address to queue driver. */
1283 static void idc_queue_init_data(struct e10k_binding *b,
1284                                 struct capref registers,
1285                                 uint64_t macaddr)
1286 {
1287     errval_t r;
1288     r = e10k_queue_init_data__tx(b, NOP_CONT, registers, macaddr);
1289     // TODO: handle busy
1290     assert(err_is_ok(r));
1291 }
1292
1293 /** Tell queue driver that we are done initializing the queue. */
1294 static void idc_queue_memory_registered(struct e10k_binding *b)
1295 {
1296     errval_t r;
1297     r = e10k_queue_memory_registered__tx(b, NOP_CONT);
1298     // TODO: handle busy
1299     assert(err_is_ok(r));
1300 }
1301
1302 /** Send request to queue driver to rewrite the tail pointers of its queues. */
1303 static void idc_write_queue_tails(struct e10k_binding *b)
1304 {
1305     errval_t r;
1306     if (b == NULL) {
1307         qd_write_queue_tails(b);
1308         return;
1309     }
1310
1311     r = e10k_write_queue_tails__tx(b, NOP_CONT);
1312     // TODO: handle busy
1313     assert(err_is_ok(r));
1314 }
1315
1316 /** Request from queue driver for register memory cap */
1317 void cd_request_device_info(struct e10k_binding *b)
1318 {
1319     assert(initialized);
1320 #ifdef LIBRARY
1321     uint64_t d_mac = e10k_ral_ral_rdf(d, qi) | ((uint64_t) e10k_rah_rah_rdf(d, qi) << 32);
1322     DEBUG("mac valid = %x\n", e10k_rah_av_rdf(d, qi));
1323 #else
1324     uint64_t d_mac = e10k_ral_ral_rdf(d, 0) | ((uint64_t) e10k_rah_rah_rdf(d, 0) << 32);
1325     DEBUG("mac valid = %x\n", e10k_rah_av_rdf(d, 0));
1326 #endif
1327
1328     if (b == NULL) {
1329         struct capref cr;
1330         errval_t err = slot_alloc(&cr);
1331         assert(err_is_ok(err));
1332         err = cap_copy(cr, *regframe);
1333         assert(err_is_ok(err));
1334         qd_queue_init_data(b, cr, d_mac);
1335         return;
1336     }
1337     idc_queue_init_data(b, *regframe, d_mac);
1338 }
1339
1340 /** Request from queue driver to initialize hardware queue. */
1341 void cd_register_queue_memory(struct e10k_binding *b,
1342                               uint8_t n,
1343                               struct capref tx_frame,
1344                               struct capref txhwb_frame,
1345                               struct capref rx_frame,
1346                               uint32_t rxbufsz,
1347                               uint32_t rxhdrsz,
1348                               int16_t msix_intvec,
1349                               uint8_t msix_intdest,
1350                               bool use_irq,
1351                               bool use_rsc,
1352                               lvaddr_t tx_va,
1353                               lvaddr_t rx_va,
1354                               lvaddr_t txhwb_va)
1355 {
1356     DEBUG("register_queue_memory(%"PRIu8")\n", n);
1357     // TODO: Make sure that rxbufsz is a power of 2 >= 1024
1358
1359     if (use_irq && msix_intvec != 0 && !msix) {
1360         printf("e10k: Queue %d requests MSI-X, but MSI-X is not enabled "
1361                 " card driver. Ignoring queue\n", n);
1362         return;
1363     }
1364     // Save state so we can restore the configuration in case we need to do a
1365     // reset
1366     queues[n].enabled = true;
1367     queues[n].tx_frame = tx_frame;
1368     queues[n].txhwb_frame = txhwb_frame;
1369     queues[n].rx_frame = rx_frame;
1370     queues[n].tx_head = 0;
1371     queues[n].rx_head = 0;
1372     queues[n].rxbufsz = rxbufsz;
1373     queues[n].rxhdrsz = rxhdrsz;
1374     queues[n].msix_index = -1;
1375     queues[n].msix_intvec = msix_intvec;
1376     queues[n].msix_intdest = msix_intdest;
1377     queues[n].binding = b;
1378     queues[n].use_irq = use_irq;
1379     queues[n].use_rsc = use_rsc;
1380     queues[n].tx_va = tx_va;
1381     queues[n].rx_va = rx_va;
1382     queues[n].txhwb_va = txhwb_va;
1383
1384     queue_hw_init(n, true);
1385
1386     if (b == NULL) {
1387         qd_queue_memory_registered(b);
1388         return;
1389     }
1390     idc_queue_memory_registered(b);
1391 }
1392
1393
1394 /** Request from queue driver to initialize hardware queue. */
1395 void cd_set_interrupt_rate(struct e10k_binding *b,
1396                            uint8_t n,
1397                            uint16_t rate)
1398 {
1399     DEBUG("set_interrupt_rate(%"PRIu8")\n", n);
1400
1401     uint8_t i;
1402     e10k_eitrn_t eitr = 0;
1403     eitr = e10k_eitrn_itr_int_insert(eitr, rate);
1404
1405     i = (queues[n].msix_index == -1 ? 0 : queues[n].msix_index);
1406     if (i < 24) {
1407         e10k_eitr_l_wr(d, i, eitr);
1408     } else {
1409         e10k_eitr_h_wr(d, i - 24, eitr);
1410     }
1411 }
1412
1413 #ifndef LIBRARY
1414 /**
1415  * Request from queue driver to stop hardware queue and free everything
1416  * associated with that queue.
1417  */
1418 static errval_t idc_terminate_queue(struct e10k_binding *b, uint8_t n)
1419 {
1420     DEBUG("idc_terminate_queue(q=%d)\n", n);
1421
1422     queue_hw_stop(n);
1423
1424     queues[n].enabled = false;
1425     queues[n].binding = NULL;
1426
1427     // TODO: Do we have to free the frame caps, or destroy the binding?
1428     return SYS_ERR_OK;
1429 }
1430
1431 static errval_t idc_register_port_filter(struct e10k_binding *b,
1432                                      uint64_t buf_id_rx,
1433                                      uint64_t buf_id_tx,
1434                                      uint8_t queue,
1435                                      e10k_port_type_t type,
1436                                      uint16_t port,
1437                                      errval_t *err,
1438                                      uint64_t *filter)
1439 {
1440     struct e10k_filter f = {
1441         .dst_port = port,
1442         .mask = MASK_SRCIP | MASK_DSTIP | MASK_SRCPORT,
1443         .l4_type = (type == e10k_PORT_TCP ? L4_TCP : L4_UDP),
1444         .priority = 1,
1445         .queue = queue,
1446     };
1447     *filter = -1ULL;
1448
1449     DEBUG("idc_register_port_filter: called (q=%d t=%d p=%d)\n",
1450             queue, type, port);
1451
1452     *err = reg_ftfq_filter(&f, filter);
1453     DEBUG("filter registered: err=%"PRIu64", fid=%"PRIu64"\n", *err, *filter);
1454     return SYS_ERR_OK;
1455 }
1456
1457 static errval_t idc_unregister_filter(struct e10k_binding *b,
1458                                   uint64_t filter, errval_t *err)
1459 {
1460     DEBUG("unregister_filter: called (%"PRIx64")\n", filter);
1461     *err = LIB_ERR_NOT_IMPLEMENTED;
1462     return SYS_ERR_OK;
1463 }
1464
1465 static struct e10k_rx_vtbl rx_vtbl = {
1466     .request_device_info = cd_request_device_info,
1467     .register_queue_memory = cd_register_queue_memory,
1468     .set_interrupt_rate = cd_set_interrupt_rate,
1469 };
1470
1471 static struct e10k_rpc_rx_vtbl rpc_rx_vtbl = {
1472     .terminate_queue_call = idc_terminate_queue,
1473     .register_port_filter_call = idc_register_port_filter,
1474     .unregister_filter_call = idc_unregister_filter,
1475 };
1476
1477
1478 static void export_cb(void *st, errval_t err, iref_t iref)
1479 {
1480     const char *suffix = "_e10kmng";
1481     char name[strlen(service_name) + strlen(suffix) + 1];
1482
1483     assert(err_is_ok(err));
1484
1485     // Build label for interal management service
1486     sprintf(name, "%s%s", service_name, suffix);
1487
1488     err = nameservice_register(name, iref);
1489     assert(err_is_ok(err));
1490     DEBUG("Management interface exported\n");
1491 }
1492
1493 static errval_t connect_cb(void *st, struct e10k_binding *b)
1494 {
1495     DEBUG("New connection on management interface\n");
1496     b->rx_vtbl = rx_vtbl;
1497     b->rpc_rx_vtbl = rpc_rx_vtbl;
1498     return SYS_ERR_OK;
1499 }
1500
1501 /**
1502  * Initialize management interface for queue drivers.
1503  * This has to be done _after_ the hardware is initialized.
1504  */
1505 static void initialize_mngif(void)
1506 {
1507     errval_t r;
1508
1509     r = e10k_export(NULL, export_cb, connect_cb, get_default_waitset(),
1510                     IDC_BIND_FLAGS_DEFAULT);
1511     assert(err_is_ok(r));
1512 }
1513 #endif
1514
1515 /****** VF/PF server interface *******/
1516
1517 static void init_done_vf(struct e10k_vf_binding *b, uint8_t vfn)
1518 {
1519     assert(vfn < 64);
1520
1521     DEBUG("VF %d init done\n", vfn);
1522
1523     // Enable correct pool for VF
1524     e10k_pfvfre_wr(d, vfn / 32, e10k_pfvfre_rd(d, vfn / 32) | (1 << (vfn % 32)));
1525     e10k_pfvfte_wr(d, vfn / 32, e10k_pfvfte_rd(d, vfn / 32) | (1 << (vfn % 32)));
1526
1527     if(vfn < 32) {
1528         e10k_pfvflrec_wr(d, 0, 1 << vfn);
1529     } else {
1530         e10k_pfvflrec_wr(d, 1, 1 << (vfn - 32));
1531     }
1532
1533     errval_t err = b->tx_vtbl.init_done_response(b, NOP_CONT);
1534     assert(err_is_ok(err));
1535 }
1536
1537 static void get_mac_address_vf(struct e10k_vf_binding *b, uint8_t vfn)
1538 {
1539     assert(initialized);
1540     uint64_t d_mac = e10k_ral_ral_rdf(d, vfn) | ((uint64_t) e10k_rah_rah_rdf(d, vfn) << 32);
1541     errval_t err = b->tx_vtbl.get_mac_address_response(b, NOP_CONT, d_mac);
1542     assert(err_is_ok(err));
1543 }
1544
1545 static void request_vf_number(struct e10k_vf_binding *b)
1546 {
1547     DEBUG("VF allocated\n");
1548     errval_t err;
1549     uint8_t vf_num = 255;
1550     for (int i = 0; i < 64; i++) {
1551         if (!vf_used[i]) {
1552             vf_num = i;
1553             break;
1554         }
1555     }
1556
1557     if (vf_num == 255){
1558         //TODO better error
1559         err = NIC_ERR_ALLOC_QUEUE;
1560     } else {
1561         err = SYS_ERR_OK;
1562     }
1563
1564     err = b->tx_vtbl.request_vf_number_response(b, NOP_CONT, vf_num, err);
1565     assert(err_is_ok(err));
1566 }
1567
1568
1569 static errval_t cd_create_queue_rpc(struct e10k_vf_binding *b, 
1570                                     struct capref tx_frame, struct capref txhwb_frame, 
1571                                     struct capref rx_frame, uint32_t rxbufsz, 
1572                                     int16_t msix_intvec, uint8_t msix_intdest, 
1573                                     bool use_irq, bool use_rsc, bool default_q,
1574                                     uint64_t *mac, int32_t *qid, struct capref *regs, 
1575                                     errval_t *ret_err)
1576 {
1577     // TODO: Make sure that rxbufsz is a power of 2 >= 1024
1578
1579     if (use_irq && msix_intvec != 0 && !msix) {
1580         printf("e10k: Queue requests MSI-X, but MSI-X is not enabled "
1581                 " card driver. Ignoring queue\n");
1582         *ret_err = NIC_ERR_ALLOC_QUEUE;
1583         return NIC_ERR_ALLOC_QUEUE;
1584     }
1585
1586     // allocate a queue
1587     int n = -1;
1588     for (int i = 1; i < 128; i++) {
1589         if (!queues[i].enabled) {
1590             n = i;
1591             break;
1592         }
1593     }
1594
1595     if (default_q) {
1596         if (queues[0].enabled == false) {
1597             n = 0;
1598         } else {
1599             printf("Default queue already initalized \n");
1600             return NIC_ERR_ALLOC_QUEUE;
1601         }
1602     }
1603
1604     DEBUG("create queue(%"PRIu8")\n", n);
1605
1606     if (n == -1) {  
1607         *ret_err = NIC_ERR_ALLOC_QUEUE;
1608         return NIC_ERR_ALLOC_QUEUE;
1609     }
1610
1611     // Save state so we can restore the configuration in case we need to do a
1612     // reset
1613     
1614     queues[n].tx_frame = tx_frame;
1615     queues[n].txhwb_frame = txhwb_frame;
1616     queues[n].rx_frame = rx_frame;
1617     queues[n].tx_head = 0;
1618     queues[n].rx_head = 0;
1619     queues[n].rxbufsz = rxbufsz;
1620     queues[n].msix_index = -1;
1621     queues[n].msix_intvec = msix_intvec;
1622     queues[n].msix_intdest = msix_intdest;
1623     queues[n].use_irq = use_irq;
1624     queues[n].use_rsc = use_rsc;
1625     queues[n].enabled = true;
1626
1627     queue_hw_init(n, false);
1628
1629     // TODO for now vfn = 0
1630     uint64_t d_mac = e10k_ral_ral_rdf(d, 0) | ((uint64_t) e10k_rah_rah_rdf(d, 0) << 32);
1631
1632     *regs = *regframe;
1633     *qid = n;
1634     *mac = d_mac;    
1635
1636     DEBUG("[%d] Queue int done\n", n);
1637     *ret_err = SYS_ERR_OK;
1638     return SYS_ERR_OK;
1639 }
1640
1641 static void cd_create_queue(struct e10k_vf_binding *b, 
1642                             struct capref tx_frame, struct capref txhwb_frame, 
1643                             struct capref rx_frame, uint32_t rxbufsz, 
1644                             int16_t msix_intvec, uint8_t msix_intdest, 
1645                             bool use_irq, bool use_rsc, bool default_q)
1646 {
1647
1648     uint64_t mac;
1649     int queueid;
1650     errval_t err;
1651
1652     struct capref regs;
1653
1654     err = cd_create_queue_rpc(b, tx_frame, txhwb_frame, rx_frame, 
1655                               rxbufsz, msix_intvec, msix_intdest, use_irq, use_rsc, 
1656                               default_q, &mac, &queueid, &regs, &err);
1657
1658     err = b->tx_vtbl.create_queue_response(b, NOP_CONT, mac, queueid, regs, err);
1659     assert(err_is_ok(err));
1660     DEBUG("cd_create_queue end\n");
1661 }
1662
1663 static void vf_export_cb(void *st, errval_t err, iref_t iref)
1664 {
1665     const char *suffix = "_vf";
1666     char name[strlen(service_name) + strlen(suffix) + 100];
1667
1668     assert(err_is_ok(err));
1669
1670     // Build label for interal management service
1671     sprintf(name, "%s%s%u", service_name, suffix, pci_function);
1672
1673     err = nameservice_register(name, iref);
1674     assert(err_is_ok(err));
1675     DEBUG("VF/PF interface [%s] exported\n", name);
1676     exported = true;
1677 }
1678
1679 static errval_t vf_connect_cb(void *st, struct e10k_vf_binding *b)
1680 {
1681     DEBUG("New connection on VF/PF interface\n");
1682
1683     b->rx_vtbl.create_queue_call = cd_create_queue;
1684     b->rx_vtbl.request_vf_number_call = request_vf_number;
1685     b->rx_vtbl.init_done_call = init_done_vf;
1686     b->rx_vtbl.get_mac_address_call = get_mac_address_vf;
1687
1688     b->rpc_rx_vtbl.create_queue_call = cd_create_queue_rpc;
1689
1690
1691     return SYS_ERR_OK;
1692 }
1693
1694 /**
1695  * Initialize management interface for queue drivers.
1696  * This has to be done _after_ the hardware is initialized.
1697  */
1698 static void initialize_vfif(void)
1699 {
1700     errval_t r;
1701
1702     r = e10k_vf_export(NULL, vf_export_cb, vf_connect_cb, get_default_waitset(),
1703                        IDC_BIND_FLAGS_DEFAULT);
1704     assert(err_is_ok(r));
1705
1706     r = net_filter_export(NULL, net_filter_export_cb, net_filter_connect_cb, 
1707                           get_default_waitset(), IDC_BIND_FLAGS_DEFAULT);
1708     assert(err_is_ok(r));
1709 }
1710
1711 /******************************************************************************/
1712 /* Initialization code for driver */
1713
1714 /** Callback from pci to initialize a specific PCI device. */
1715 static void pci_init_card(struct device_mem* bar_info, int bar_count)
1716 {
1717     errval_t err;
1718     bool res;
1719
1720     assert(!initialized);
1721
1722     d = malloc(sizeof(*d));
1723
1724     // Map first BAR for register access
1725     assert(bar_count >= 1);
1726     map_device(&bar_info[0]);
1727     regframe = bar_info[0].frame_cap;
1728     DEBUG("BAR[0] mapped (v=%llx p=%llx l=%llx)\n",
1729             (unsigned long long) bar_info[0].vaddr,
1730             (unsigned long long) bar_info[0].paddr,
1731             (unsigned long long) bar_info[0].bytes);
1732
1733     // Initialize Mackerel binding
1734     e10k_initialize(d, (void*) bar_info[0].vaddr);
1735
1736     DEBUG("STATUS = %x\n", e10k_status_rd(d));
1737
1738     // Initialize manager for MSI-X vectors
1739     if (msix) {
1740         DEBUG("Enabling MSI-X interrupts\n");
1741         uint16_t msix_count = 0;
1742         err = pci_msix_enable(&msix_count);
1743         assert(err_is_ok(err));
1744         assert(msix_count > 0);
1745         DEBUG("MSI-X #vecs=%d\n", msix_count);
1746
1747         res = bmallocator_init(&msix_alloc, msix_count);
1748         assert(res);
1749     } else {
1750         DEBUG("Using legacy interrupts\n");
1751     }
1752
1753     // Initialize hardware registers etc.
1754     DEBUG("Initializing hardware\n");
1755     device_init();
1756
1757     assert(initialized);
1758
1759 #ifdef VTON_DCBOFF
1760     DEBUG("SR-IOV device up routine\n");
1761
1762     // Setup support for 64 VFs
1763     e10k_gcr_ext_vtmode_wrf(d, e10k_vt_64);
1764     e10k_gpie_vtmode_wrf(d, e10k_vt_64);
1765
1766     // Enable virtualization, disable default pool, replication enable
1767     e10k_pfvtctl_t pfvtctl = e10k_pfvtctl_rd(d);
1768     pfvtctl = e10k_pfvtctl_vt_en_insert(pfvtctl, 1);
1769     pfvtctl = e10k_pfvtctl_def_pl_insert(pfvtctl, 0);
1770     pfvtctl = e10k_pfvtctl_dis_def_pl_insert(pfvtctl, 1);
1771     pfvtctl = e10k_pfvtctl_rpl_en_insert(pfvtctl, 1);
1772     e10k_pfvtctl_wr(d, pfvtctl);
1773
1774     // Enable L2 loopback
1775     e10k_pfdtxgswc_lbe_wrf(d, 1);
1776
1777     // TODO: Accept untagged packets in all VMDQ pools
1778     // TODO: Broadcast accept mode
1779     // TODO: Accept packets matching PFUTA table
1780     // TODO: Accept packets matching MTA table
1781     // TODO: Accept untagged packets enable
1782     // TODO: Strip VLAN tag for incoming packets
1783
1784     DEBUG("STATUS = %x\n", e10k_status_rd(d));
1785
1786     e10k_ctrl_ext_pfrstd_wrf(d, 1);
1787 #endif
1788
1789 #ifndef LIBRARY
1790     // Now we initialize the management interface
1791     DEBUG("Initializing management interface\n");
1792     initialize_mngif();
1793 #endif
1794
1795     DEBUG("Initializing VF/PF interface\n");
1796     initialize_vfif();
1797     DEBUG("Done with initialization\n");
1798 }
1799
1800
1801 /** Register with PCI */
1802 static void pci_register(void)
1803 {
1804     errval_t r;
1805
1806     r = pci_client_connect();
1807     assert(err_is_ok(r));
1808     DEBUG("connected to pci\n");
1809
1810     r = pci_register_driver_irq(pci_init_card, PCI_CLASS_ETHERNET,
1811                                 PCI_DONT_CARE, PCI_DONT_CARE,
1812                                 PCI_VENDOR_INTEL, pci_deviceid,
1813                                 pci_bus, pci_device, pci_function,
1814                                 interrupt_handler, NULL);
1815     assert(err_is_ok(r));
1816 }
1817
1818 static void parse_cmdline(int argc, char **argv)
1819 {
1820     int i;
1821
1822     for (i = 1; i < argc; i++) {
1823         if (strncmp(argv[i], "cardname=", strlen("cardname=")) == 0) {
1824             service_name = argv[i] + strlen("cardname=");
1825         } else if (strncmp(argv[i], "bus=", strlen("bus=")) == 0) {
1826             pci_bus = atol(argv[i] + strlen("bus="));
1827         } else if (strncmp(argv[i], "device=", strlen("device=")) == 0) {
1828             pci_device = atol(argv[i] + strlen("device="));
1829         } else if (strncmp(argv[i], "function=", strlen("function=")) == 0) {
1830             pci_function = atol(argv[i] + strlen("function="));
1831         } else if (strncmp(argv[i], "deviceid=", strlen("deviceid=")) == 0) {
1832             pci_deviceid = strtoul(argv[i] + strlen("deviceid="), NULL, 0);
1833         } else if (strncmp(argv[i], "msix=", strlen("msix=")) == 0) {
1834             msix = !!atol(argv[i] + strlen("msix="));
1835             // also pass this to queue driver
1836             qd_argument(argv[i]);
1837         } else if (strncmp(argv[i], "credit_refill[", strlen("credit_refill[") - 1) == 0) {
1838             // Controls the WRR (weighted round-robin) scheduler's credit refill rate
1839             // This seems to be per VM pool
1840             unsigned int entry, val;
1841             int r = sscanf(argv[i], "credit_refill[%u]=%u", &entry, &val);
1842             assert(r == 2);
1843             assert(entry < 128);
1844             assert(val < 0x3fff);
1845             credit_refill[entry] = val;
1846         } else if (strncmp(argv[i], "tx_rate[", strlen("tx_rate[") - 1) == 0) {
1847             // This is specified in Mbits/s and must be >= 10 and <= link speed (typically 10,000)
1848             // This seems to be per Tx queue
1849             unsigned int entry, val;
1850             int r = sscanf(argv[i], "tx_rate[%u]=%u", &entry, &val);
1851             assert(r == 2);
1852             assert(entry < 128);
1853             assert(val >= 10 && val <= 10000);
1854             tx_rate[entry] = val;
1855         } else {
1856             qd_argument(argv[i]);
1857         }
1858     }
1859 }
1860
1861 #ifndef LIBRARY
1862 static void eventloop(void)
1863 {
1864     struct waitset *ws;
1865     
1866     printf("Entering polling loop\n");
1867     ws = get_default_waitset();
1868     while (1) {
1869         if (use_interrupts) {
1870             event_dispatch(ws);
1871         } else {
1872             networking_poll();
1873         }
1874     }
1875 }
1876
1877 void qd_main(void)
1878 {
1879     eventloop();
1880 }
1881
1882 void qd_argument(const char *arg) { }
1883 void qd_interrupt(bool is_rx, bool is_tx) { }
1884 void qd_queue_init_data(struct e10k_binding *b, struct capref registers,
1885         uint64_t macaddr) { }
1886 void qd_queue_memory_registered(struct e10k_binding *b) { }
1887 void qd_write_queue_tails(struct e10k_binding *b) { }
1888
1889 int main(int argc, char **argv)
1890 #else
1891 int e1000n_driver_init(int argc, char *argv[])
1892 #endif
1893 {
1894     //barrelfish_usleep(10*1000*1000);
1895     DEBUG("PF driver started\n");
1896     // credit_refill value must be >= 1 for a queue to be able to send.
1897     // Set them all to 1 here. May be overridden via commandline.
1898     for(int i = 0; i < 128; i++) {
1899         credit_refill[i] = 1;
1900     }
1901
1902     memset(tx_rate, 0, sizeof(tx_rate));
1903
1904     parse_cmdline(argc, argv);
1905     pci_register();
1906
1907     while (!initialized || !exported) {
1908         event_dispatch(get_default_waitset());
1909     }
1910
1911     DEBUG("e10k driver networking init \n");
1912     errval_t err;
1913     err = networking_init("e10k", NET_FLAGS_DO_DHCP | NET_FLAGS_POLLING |
1914                           NET_FLAGS_DEFAULT_QUEUE);
1915     DEBUG("e10k driver networking init done with error: %s \n", err_getstring(err));
1916     assert(err_is_ok(err));
1917
1918     qd_main();
1919     return 1;
1920 }