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