netlib: integrated e10k device queue including hardware filters
authorRoni Häcki <roni.haecki@inf.ethz.ch>
Tue, 18 Apr 2017 07:35:02 +0000 (09:35 +0200)
committerRoni Häcki <roni.haecki@inf.ethz.ch>
Tue, 18 Apr 2017 07:35:02 +0000 (09:35 +0200)
Signed-off-by: Roni Häcki <roni.haecki@inf.ethz.ch>

if/e10k_vf.if
lib/devif/backends/net/e10k/devif_backend_e10k.c
lib/devif/backends/net/e10k/e10k_queue.h
lib/net/net.c
lib/net/netif.c
lib/net/networking_internal.h
usr/drivers/e10k/Hakefile
usr/drivers/e10k/e10k_cdriver.c

index a75eb8f..84bd919 100644 (file)
@@ -26,8 +26,10 @@ interface e10k_vf "e10k VF/PF interface" {
                        in uint8  msix_intdest,
                        in bool   use_irq,
                        in bool   use_rsc,
+                       out uint64 mac,
                        out int qid,
-                       out cap regs);
+                       out cap regs,
+                       out errval err);
 
       rpc destroy_queue(in int qid, out errval err);
 };
index 4c9aa4e..c812861 100644 (file)
@@ -115,6 +115,7 @@ static errval_t enqueue_tx_buf(struct e10k_queue* q, regionid_t rid,
     bool last = flags & NETIF_TXFLAG_LAST;
     bool first = flags & NETIF_TXFLAG_FIRST;
     // Prepare checksum offload
+
     if (buf_use_ipxsm(flags)) {
         e10k_q_l4_type_t l4t = 0;
         uint8_t l4len = 0;
@@ -134,7 +135,7 @@ static errval_t enqueue_tx_buf(struct e10k_queue* q, regionid_t rid,
             assert(entry != NULL);
 
             lpaddr_t addr = 0;
-            addr = (lpaddr_t) entry->virt + offset;
+            addr = (lpaddr_t) entry->virt + offset + valid_data;
             e10k_queue_add_txbuf_ctx(q, addr, rid, offset, length,
                                      valid_data, valid_length, flags,
                                      first, last, length, 0, true, l4len !=0);
@@ -145,7 +146,7 @@ static errval_t enqueue_tx_buf(struct e10k_queue* q, regionid_t rid,
             assert(entry != NULL);
 
             lpaddr_t addr = 0;
-            addr = (lpaddr_t) entry->phys + offset;
+            addr = (lpaddr_t) entry->phys + offset + valid_data;
             e10k_queue_add_txbuf_ctx(q, addr, rid, offset, length,
                                      valid_data, valid_length, flags,
                                      first, last, length, 0, true, l4len != 0);
@@ -157,7 +158,7 @@ static errval_t enqueue_tx_buf(struct e10k_queue* q, regionid_t rid,
             assert(entry != NULL);
 
             lpaddr_t addr = 0;
-            addr = (lpaddr_t) entry->virt + offset;
+            addr = (lpaddr_t) entry->virt + offset + valid_data;
             e10k_queue_add_txbuf(q, addr, rid, offset, length, valid_data,
                                  valid_length, flags,
                                  first, last, length);
@@ -166,7 +167,7 @@ static errval_t enqueue_tx_buf(struct e10k_queue* q, regionid_t rid,
             assert(entry != NULL);
 
             lpaddr_t addr = 0;
-            addr = (lpaddr_t) entry->phys + offset;
+            addr = (lpaddr_t) entry->phys + offset + valid_data;
             e10k_queue_add_txbuf(q, addr, rid, offset, length, valid_data,
                                  valid_length, flags, first, last, length);
         }
@@ -242,6 +243,7 @@ static errval_t e10k_enqueue(struct devq* q, regionid_t rid, genoffset_t offset,
 
         assert(length <= 2048);
         
+        DEBUG_QUEUE("Enqueuing offset=%lu valid_data=%lu \n", offset, valid_data);
         err = enqueue_tx_buf(queue, rid, offset, length, valid_data,
                              valid_length, flags);
         if (err_is_fail(err)) {
@@ -266,6 +268,7 @@ static errval_t e10k_dequeue(struct devq* q, regionid_t* rid,
                              valid_length, flags, &last)) {
         err = DEVQ_ERR_QUEUE_EMPTY;
     } else {
+        DEBUG_QUEUE("Received offset=%lu valid_data=%lu \n", *offset, *valid_data);
         return SYS_ERR_OK;
     }
      
@@ -273,6 +276,7 @@ static errval_t e10k_dequeue(struct devq* q, regionid_t* rid,
                               valid_length, flags)) {
         err = DEVQ_ERR_QUEUE_EMPTY;
     }  else {
+        DEBUG_QUEUE("Sent offset=%lu valid_data=%lu \n", *offset, *valid_data);
         return SYS_ERR_OK;
     }
 
@@ -341,6 +345,9 @@ static errval_t e10k_deregister(struct devq* q, regionid_t rid)
 
 static errval_t e10k_control(struct devq* q, uint64_t cmd, uint64_t value, uint64_t *result)
 {
+    struct e10k_queue* queue = (struct e10k_queue*) q;
+    *result = queue->mac;
+    DEBUG_QUEUE("Control cmd=%lu value=%lu \n", cmd, value);
     return SYS_ERR_OK;
 }
 
@@ -483,7 +490,7 @@ errval_t e10k_queue_create(struct e10k_queue** queue, e10k_event_cb_t cb,
 
     // allocate memory for RX/TX rings
     struct capref tx_frame;
-    size_t tx_size = e10k_q_tdesc_legacy_size*NUM_TX_DESC;
+    size_t tx_size = e10k_q_tdesc_adv_ctx_size*NUM_TX_DESC;
     void* tx_virt = alloc_map_frame(VREGION_FLAGS_READ_WRITE, tx_size, &tx_frame);
     if (tx_virt == NULL) {
         return DEVQ_ERR_INIT_QUEUE;
@@ -491,7 +498,7 @@ errval_t e10k_queue_create(struct e10k_queue** queue, e10k_event_cb_t cb,
 
 
     struct capref rx_frame;
-    size_t rx_size = e10k_q_tdesc_legacy_size*NUM_TX_DESC;
+    size_t rx_size = e10k_q_tdesc_adv_ctx_size*NUM_RX_DESC;
     void* rx_virt = alloc_map_frame(VREGION_FLAGS_READ_WRITE, rx_size, &rx_frame);
     if (rx_virt == NULL) {
         return DEVQ_ERR_INIT_QUEUE;
@@ -535,13 +542,10 @@ errval_t e10k_queue_create(struct e10k_queue** queue, e10k_event_cb_t cb,
             return err;
         }
     } else {
-        struct capref regs;
 
-        // Inform card driver about new queue and get the registers/queue id
-        err = slot_alloc(&regs);
-        if (err_is_fail(err)) {
-            return err;
-        }
+        int qid;
+        errval_t err2;
+        struct capref regs;
 
         if (q->use_irq) {
             /*
@@ -552,26 +556,35 @@ errval_t e10k_queue_create(struct e10k_queue** queue, e10k_event_cb_t cb,
             // TODO setup MSI-X interrupts
         }
 
-        int q_id;
-        err = q->binding->rpc_tx_vtbl.create_queue(q->binding, tx_frame, txhwb_frame,
-                                            rx_frame, 2048, q->msix_intvec,
-                                            q->msix_intdest, false, false, &q_id,
-                                            &regs);
+        // Inform card driver about new queue and get the registers/queue id
+        err = slot_alloc(&regs);
         if (err_is_fail(err)) {
             return err;
         }
 
-        assert(q_id >= 0);
-        q->id = (uint16_t)q_id;
+        err = q->binding->rpc_tx_vtbl.create_queue(q->binding, tx_frame, txhwb_frame,
+                                            rx_frame, 2048, q->msix_intvec,
+                                            q->msix_intdest, false, false, 
+                                            &q->mac, &qid,
+                                            &regs, &err2);
+        if (err_is_fail(err) || err_is_fail(err2)) {
+            DEBUG_QUEUE("e10k rpc error\n");
+            return err_is_fail(err)? err: err2;
+        }
+
+        assert(qid >= 0);
+        q->id = (uint16_t)qid;
 
         err = map_device_memory(q, regs);
         if (err_is_fail(err)) {
+            DEBUG_QUEUE("e10k map device error\n");
             return err;
         }
     }
 
     err = devq_init(&q->q, false);
     if (err_is_fail(err)) {
+        DEBUG_QUEUE("e10k devq_init error\n");
         return err;
     }
     
@@ -585,6 +598,7 @@ errval_t e10k_queue_create(struct e10k_queue** queue, e10k_event_cb_t cb,
 
     *queue = q;
 
+    DEBUG_QUEUE("e10k queue init done\n");
     return SYS_ERR_OK;
 }
 
index 63b6644..9bf5a49 100644 (file)
@@ -59,6 +59,7 @@ struct e10k_queue {
     bool use_txhwb; 
     size_t rxbufsz;
     uint8_t pci_function; 
+    uint64_t mac;
 
     // registered regions
     struct region_entry* regions;   
@@ -129,6 +130,8 @@ static inline void e10k_queue_init(struct e10k_queue* q, void* tx, size_t tx_siz
     // Initialize ring memory with zero
     memset(tx, 0, tx_size * e10k_q_tdesc_adv_wb_size);
     memset(rx, 0, rx_size * e10k_q_rdesc_adv_wb_size);
+    memset(q->tx_isctx, 0, tx_size*sizeof(bool));
+    memset(q->rx_context, 0, tx_size*sizeof(*q->rx_context));
 }
 
 static inline int e10k_queue_add_txcontext(e10k_queue_t* q, uint8_t idx,
index 729086c..1b98792 100644 (file)
@@ -48,8 +48,10 @@ errval_t networking_get_defaults(uint64_t *queue, const char **cardname, uint32_
     /* TODO: get the values from the SKB */
 
     *queue = NETWORKING_DEFAULT_QUEUE_ID;
+    //*cardname = "e10k";
     *cardname = "sfn5122f";
     *flags = NET_FLAGS_POLLING | NET_FLAGS_BLOCKING_INIT;
+    //*flags = NET_FLAGS_POLLING;
 
     return SYS_ERR_OK;
 }
@@ -88,7 +90,13 @@ static errval_t create_driver_queue (struct net_state *st, uint64_t* queueid,
 static errval_t create_e10k_queue (struct net_state *st, uint64_t* queueid,
                                    struct devq **retqueue)
 {
-    return SYS_ERR_OK;
+    errval_t err;
+    err = e10k_queue_create((struct e10k_queue**)retqueue, int_handler,
+                            false /*virtual functions*/,
+                            !(st->flags & NET_FLAGS_POLLING) /* user interrupts*/);
+    *queueid = 0;
+    //*queueid = e10k_queue_get_id((struct e10k_queue*)*retqueue);
+    return err;
 }
 
 static errval_t create_sfn5122f_queue (struct net_state *st, uint64_t* queueid, 
index af2acf8..1677691 100644 (file)
@@ -74,6 +74,8 @@ static size_t bench_devq_deq_count = 0;
 #endif
 
 
+errval_t net_if_get_hwaddr(struct netif *netif);
+
 static err_t net_if_linkoutput(struct netif *netif, struct pbuf *p)
 {
     errval_t err;
index 7eb3992..2d91207 100644 (file)
@@ -23,6 +23,7 @@
 #include <devif/queue_interface.h>
 #include <devif/backends/loopback_devif.h>
 #include <devif/backends/net/sfn5122f_devif.h>
+#include <devif/backends/net/e10k_devif.h>
 
 #include <lwip/netif.h>
 
index e955ec6..22b0899 100644 (file)
                       cFiles = [ "e10k_cdriver.c", "e10k_phy.c", "sleep.c",
                                  "helper.c"],
                       flounderBindings = [ "net_queue_manager", "net_soft_filters", "e10k", "e10k_vf" ],
-                      flounderDefs = [ "e10k_vf" ],
+                      flounderDefs = [ "e10k_vf" , "net_filter"],
                       --flounderBindings = [ "e10k"],
+                      flounderExtraBindings = [ ("net_filter", ["rpcclient"])],
+                      flounderExtraDefs = [("net_filter",["rpcclient"])],
                       mackerelDevices = [ "e10k" ],
+                      addIncludes  = [ "/lib/lwip-2.0.2/src/include/" ],
+
                       addLibraries = [ "pci", "contmng", "net_device_manager",
-                                       "bench", "trace", "skb" ]
+                                       "bench", "trace", "skb" , "net"]
                     },
 
   build application { target = "e10k_queue_elb",
index 697b6d7..9034722 100644 (file)
 #include <pci/pci.h>
 #include <barrelfish/nameservice_client.h>
 #include <barrelfish/debug.h>
-#include <ipv4/lwip/inet.h>
+#include <barrelfish/deferred.h>
+#include <lwip/ip.h>
+#include <net/net.h>
 #ifdef LIBRARY
 #       include <netif/e1000.h>
 #endif
 
 #include <if/e10k_defs.h>
 #include <if/e10k_vf_defs.h>
+#include <if/net_filter_defs.h>
 #include <dev/e10k_dev.h>
 
 #include "e10k.h"
@@ -161,8 +164,11 @@ static void e10k_flt_ftqf_setup(int index, struct e10k_filter *filter);
 
 static const char *service_name = "e10k";
 static int initialized = 0;
+static bool exported = false;
 static e10k_t *d = NULL;
 static struct capref *regframe;
+
+static bool use_interrupts = false;
 static bool msix = false;
 
 /** Specifies if RX/TX is currently enabled on the device. */
@@ -271,6 +277,96 @@ static errval_t reg_ftfq_filter(struct e10k_filter* f, uint64_t* fid)
 #endif
 
 
+/****************************************************************************/
+/* Net filter interface implementation                                      */
+/****************************************************************************/
+
+
+static errval_t cb_install_filter(struct net_filter_binding *b,
+                                  net_filter_filter_type_t type,
+                                  uint64_t qid,
+                                  uint32_t src_ip,
+                                  uint32_t dst_ip,
+                                  uint16_t src_port,
+                                  uint16_t dst_port,
+                                  uint64_t* fid)
+{
+
+    errval_t err;
+    struct e10k_filter f = {
+        .dst_port = dst_port,
+        .src_port = src_port,
+        .dst_ip = dst_ip,
+        .src_ip = src_ip,
+        .l4_type = (type == net_filter_PORT_TCP ? L4_TCP : L4_UDP),
+        .priority = 1,
+        .queue = qid,
+    };
+
+    if (src_ip == 0) {
+        f.mask = f.mask | MASK_SRCIP;
+    }
+
+    if (dst_ip == 0) {
+        f.mask = f.mask | MASK_DSTIP;
+    }
+
+    if (dst_port == 0) {
+        f.mask = f.mask | MASK_DSTPORT;
+    }
+
+    if (src_port == 0) {
+        f.mask = f.mask | MASK_SRCPORT;
+    }
+
+    *fid = -1ULL;
+
+    err = reg_ftfq_filter(&f, fid);
+    DEBUG("filter registered: err=%s, fid=%"PRIu64"\n", err_getstring(err), *fid);
+    return err;
+}
+
+
+static errval_t cb_remove_filter(struct net_filter_binding *b,
+                                 net_filter_filter_type_t type,
+                                 uint64_t filter_id,
+                                 errval_t* err)
+{
+    if ((type == net_filter_PORT_UDP || type == net_filter_PORT_TCP)){
+        USER_PANIC("NYI");
+        *err = SYS_ERR_OK;
+    } else {
+        *err = NET_FILTER_ERR_NOT_FOUND;
+    }
+
+    DEBUG("unregister_filter: called (%"PRIx64")\n", filter_id);
+    return SYS_ERR_OK;
+}
+
+static struct net_filter_rpc_rx_vtbl net_filter_rpc_rx_vtbl = {
+    .install_filter_ip_call = cb_install_filter,
+    .remove_filter_call = cb_remove_filter,
+    .install_filter_mac_call = NULL,
+};
+
+static void net_filter_export_cb(void *st, errval_t err, iref_t iref)
+{
+
+    printf("exported net filter interface\n");
+    err = nameservice_register("net_filter_e10k", iref);
+    assert(err_is_ok(err));
+    DEBUG("Net filter interface exported\n");
+}
+
+
+static errval_t net_filter_connect_cb(void *st, struct net_filter_binding *b)
+{
+    printf("New connection on net filter interface\n");
+    b->rpc_rx_vtbl = net_filter_rpc_rx_vtbl;
+    return SYS_ERR_OK;
+}
+
+
 #if 0
 static void e10k_flt_etype_setup(int filter, int queue, uint16_t etype)
 {
@@ -758,19 +854,17 @@ static void device_init(void)
     e10k_rtrpcs_rac_wrf(d, 0);
     e10k_rtrpcs_rrm_wrf(d, 0);
 #else
-    e10k_rttdcs_tdpac_wrf(d, 1);
-    e10k_rttdcs_vmpac_wrf(d, 1);
-    e10k_rttdcs_tdrm_wrf(d, 1);
 
+    e10k_rttdcs_tdpac_wrf(d, 0);
+    e10k_rttdcs_vmpac_wrf(d, 0);
+    e10k_rttdcs_tdrm_wrf(d, 0);
     e10k_rttdcs_bdpm_wrf(d, 1);
-    e10k_rttdcs_bpbfsm_wrf(d, 0);
-    e10k_rttpcs_tppac_wrf(d, 1);
-    e10k_rttpcs_tprm_wrf(d, 1);
-    e10k_rttpcs_arbd_wrf(d, 0x004);
-
+    e10k_rttdcs_bpbfsm_wrf(d, 1);
+    e10k_rttpcs_tppac_wrf(d, 0);
+    e10k_rttpcs_tprm_wrf(d, 0);
+    e10k_rttpcs_arbd_wrf(d, 0x224);
     e10k_rtrpcs_rac_wrf(d, 0);
-    e10k_rtrpcs_rrm_wrf(d, 1);
-    e10k_sectxminifg_sectxdcb_wrf(d, 0x1f);
+    e10k_rtrpcs_rrm_wrf(d, 0);
 #endif
 
     // disable relaxed ordering
@@ -959,13 +1053,14 @@ static void queue_hw_init(uint8_t n, bool set_tail)
                 e10k_eiac_rtxq_wrf(d, e10k_eiac_rtxq_rdf(d) | (1 << rxv));
             }
 
-            // Enable interrupt
-            e10k_eimsn_wr(d, rxv / 32, (1 << (rxv % 32)));
         }
         if (rxv < 16) {
             // Make sure interrupt is cleared
             e10k_eicr_wr(d, 1 << rxv);
         }
+
+        // Enable interrupt
+        e10k_eimsn_wr(d, rxv / 32, (1 << (rxv % 32)));
     }
 
     // Enable RX
@@ -1154,6 +1249,7 @@ static void interrupt_handler_msix(void* arg)
 /** Here are the global interrupts handled. */
 static void interrupt_handler(void* arg)
 {
+    DEBUG("e10k: received interrupt\n");
     e10k_eicr_t eicr = e10k_eicr_rd(d);
 
     if (eicr >> 16) {
@@ -1164,6 +1260,9 @@ static void interrupt_handler(void* arg)
         qd_interrupt(!!(eicr & (1 << QUEUE_INTRX)),
                      !!(eicr & (1 << QUEUE_INTTX)));
     }
+
+    // Reenable interrupt
+    e10k_eimsn_cause_wrf(d, 0, 0x1);
 }
 
 /******************************************************************************/
@@ -1456,24 +1555,20 @@ static void request_vf_number(struct e10k_vf_binding *b)
 }
 
 
-/** Request from queue driver to initialize hardware queue. */
-static void create_queue(struct e10k_vf_binding *b,
-                         struct capref tx_frame,
-                         struct capref txhwb_frame,
-                         struct capref rx_frame,
-                         uint32_t rxbufsz,
-                         int16_t msix_intvec,
-                         uint8_t msix_intdest,
-                         bool use_irq,
-                         bool use_rsc)
+static errval_t cd_create_queue_rpc(struct e10k_vf_binding *b, 
+                                    struct capref tx_frame, struct capref txhwb_frame, 
+                                    struct capref rx_frame, uint32_t rxbufsz, 
+                                    int16_t msix_intvec, uint8_t msix_intdest, 
+                                    bool use_irq, bool use_rsc, uint64_t *mac, 
+                                    int32_t *qid, struct capref *regs, errval_t *ret_err)
 {
-    errval_t err;
     // TODO: Make sure that rxbufsz is a power of 2 >= 1024
 
     if (use_irq && msix_intvec != 0 && !msix) {
         printf("e10k: Queue requests MSI-X, but MSI-X is not enabled "
                 " card driver. Ignoring queue\n");
-        return;
+        *ret_err = NIC_ERR_ALLOC_QUEUE;
+        return NIC_ERR_ALLOC_QUEUE;
     }
 
     // allocate a queue
@@ -1488,9 +1583,9 @@ static void create_queue(struct e10k_vf_binding *b,
     
     DEBUG("create queue(%"PRIu8")\n", n);
 
-    if (n == -1) {
-       err = b->tx_vtbl.create_queue_response(b, NOP_CONT, n, NULL_CAP);
-       assert(err_is_ok(err));
+    if (n == -1) {  
+        *ret_err = NIC_ERR_ALLOC_QUEUE;
+        return NIC_ERR_ALLOC_QUEUE;
     }
 
     // Save state so we can restore the configuration in case we need to do a
@@ -1510,19 +1605,39 @@ static void create_queue(struct e10k_vf_binding *b,
 
     queue_hw_init(n, false);
 
-    err = b->tx_vtbl.create_queue_response(b, NOP_CONT, n, *regframe);
-    assert(err_is_ok(err));
-    
+    // TODO for now vfn = 0
+    uint64_t d_mac = e10k_ral_ral_rdf(d, 0) | ((uint64_t) e10k_rah_rah_rdf(d, 0) << 32);
+
+    *regs = *regframe;
+    *qid = n;
+    *mac = d_mac;    
+
     DEBUG("[%d] Queue int done\n", n);
+    *ret_err = SYS_ERR_OK;
+    return SYS_ERR_OK;
 }
 
+static void cd_create_queue(struct e10k_vf_binding *b, 
+                            struct capref tx_frame, struct capref txhwb_frame, 
+                            struct capref rx_frame, uint32_t rxbufsz, 
+                            int16_t msix_intvec, uint8_t msix_intdest, 
+                            bool use_irq, bool use_rsc)
+{
 
-static struct e10k_vf_rx_vtbl vf_rx_vtbl = {
-    .get_mac_address_call = get_mac_address_vf,
-    .request_vf_number_call = request_vf_number,
-    .create_queue_call = create_queue,
-    .init_done_call = init_done_vf,
-};
+    uint64_t mac;
+    int queueid;
+    errval_t err;
+
+    struct capref regs;
+
+    err = cd_create_queue_rpc(b, tx_frame, txhwb_frame, rx_frame, 
+                              rxbufsz, msix_intvec, msix_intdest, use_irq, use_rsc, 
+                              &mac, &queueid, &regs, &err);
+
+    err = b->tx_vtbl.create_queue_response(b, NOP_CONT, mac, queueid, regs, err);
+    assert(err_is_ok(err));
+    DEBUG("cd_create_queue end\n");
+}
 
 static void vf_export_cb(void *st, errval_t err, iref_t iref)
 {
@@ -1537,12 +1652,21 @@ static void vf_export_cb(void *st, errval_t err, iref_t iref)
     err = nameservice_register(name, iref);
     assert(err_is_ok(err));
     DEBUG("VF/PF interface [%s] exported\n", name);
+    exported = true;
 }
 
 static errval_t vf_connect_cb(void *st, struct e10k_vf_binding *b)
 {
     DEBUG("New connection on VF/PF interface\n");
-    b->rx_vtbl = vf_rx_vtbl;
+
+    b->rx_vtbl.create_queue_call = cd_create_queue;
+    b->rx_vtbl.request_vf_number_call = request_vf_number;
+    b->rx_vtbl.init_done_call = init_done_vf;
+    b->rx_vtbl.get_mac_address_call = get_mac_address_vf;
+
+    b->rpc_rx_vtbl.create_queue_call = cd_create_queue_rpc;
+
+
     return SYS_ERR_OK;
 }
 
@@ -1557,6 +1681,10 @@ static void initialize_vfif(void)
     r = e10k_vf_export(NULL, vf_export_cb, vf_connect_cb, get_default_waitset(),
                       IDC_BIND_FLAGS_DEFAULT);
     assert(err_is_ok(r));
+
+    r = net_filter_export(NULL, net_filter_export_cb, net_filter_connect_cb, 
+                          get_default_waitset(), IDC_BIND_FLAGS_DEFAULT);
+    assert(err_is_ok(r));
 }
 
 /******************************************************************************/
@@ -1713,10 +1841,15 @@ static void parse_cmdline(int argc, char **argv)
 static void eventloop(void)
 {
     struct waitset *ws;
-
+    
+    printf("Entering polling loop\n");
     ws = get_default_waitset();
     while (1) {
-        event_dispatch(ws);
+        if (use_interrupts) {
+            event_dispatch(ws);
+        } else {
+            networking_poll();
+        }
     }
 }
 
@@ -1749,9 +1882,17 @@ int e1000n_driver_init(int argc, char *argv[])
     parse_cmdline(argc, argv);
     pci_register();
 
-    while (!initialized) {
+    while (!initialized || !exported) {
         event_dispatch(get_default_waitset());
     }
+
+    DEBUG("e10k driver networking init \n");
+    errval_t err;
+    err = networking_init("e10k", NET_FLAGS_DO_DHCP | NET_FLAGS_POLLING |
+                          NET_FLAGS_DEFAULT_QUEUE);
+    DEBUG("e10k driver networking init done with error: %s \n", err_getstring(err));
+    assert(err_is_ok(err));
+
     qd_main();
     return 1;
 }