solarflare: changed card driver to start shared queue 0
authorRoni Häcki <roni.haecki@inf.ethz.ch>
Wed, 29 Mar 2017 12:31:36 +0000 (14:31 +0200)
committerRoni Häcki <roni.haecki@inf.ethz.ch>
Wed, 29 Mar 2017 12:31:36 +0000 (14:31 +0200)
Signed-off-by: Roni Häcki <roni.haecki@inf.ethz.ch>

if/sfn5122f_devif.if
usr/drivers/solarflare/sfn5122f.h
usr/drivers/solarflare/sfn5122f_cdriver.c
usr/drivers/solarflare/sfn5122f_debug.h
usr/drivers/solarflare/sfn5122f_qdriver.c
usr/drivers/solarflare/sfn5122f_qdriver.h [new file with mode: 0644]
usr/drivers/solarflare/sfn5122f_queue.h

index ea28736..57c65eb 100644 (file)
@@ -26,4 +26,5 @@ interface sfn5122f_devif "sfn5122f devif communication interface" {
     rpc register_region(in uint16 qid, in cap reg, out uint64 buftbl_id, out errval err);
     rpc deregister_region(in uint64 buftbl_id, in uint64 size, out errval err);
 
+    message interrupt(uint16 qid);
 };
index e0a2622..af5a6d4 100644 (file)
@@ -27,7 +27,7 @@
 #define DEVICE_ID 0x803
 // TX Queue
 #define TX_DESC_CACHE_SIZE 16
-#define TX_ENTRIES 2048
+#define TX_ENTRIES 4096
 #define TX_DC_BASE 0x11000
 // Event Queue
 #define EV_CODE_RX 0
 
 /* for each TX/RX entry one entry plus an additonal 2 for mcdi completion
 and link state events */
-#define EV_ENTRIES 4096
+#define EV_ENTRIES 32768
 
 // RX Queue
 #define RX_DESC_CACHE_SIZE 64
-#define RX_ENTRIES 2048
+#define RX_ENTRIES 4096
 #define RX_DC_BASE 0xD000
 // calculcat max frame length
 #define MTU 1500
index cac498f..8fa0944 100644 (file)
@@ -15,6 +15,8 @@
 #include <barrelfish/nameservice_client.h>
 #include <barrelfish/spawn_client.h>
 #include <barrelfish/deferred.h>
+#include <netd/netd.h>
+#include <net_device_manager/net_device_manager.h>
 #include <pci/pci.h>
 #include <ipv4/lwip/inet.h>
 #include <barrelfish/debug.h>
 #include <if/net_ARP_defs.h>
 #include <if/net_ARP_defs.h>
 
-
 #include "sfn5122f.h"
 #include "sfn5122f_debug.h"
 #include "buffer_tbl.h"
+#include "sfn5122f_qdriver.h"
 
 struct queue_state {
     bool enabled;
@@ -60,6 +62,7 @@ struct queue_state {
 static bool use_msix = false;
 static const char *service_name = "sfn5122f";
 static sfn5122f_t *d = NULL;
+static void* d_virt;
 //static sfn5122f_msix_t *d_msix = NULL;
 static uint64_t d_mac[2];
 static int initialized = 0;
@@ -107,7 +110,7 @@ static struct bmallocator msix_alloc;
 static size_t cdriver_msix = -1;
 static uint8_t cdriver_vector;
 
-static bool use_interrupt = false;
+static bool use_interrupt = true;
 
 // first to start everything
 static bool first = 1;
@@ -117,7 +120,7 @@ uint8_t rx_hash_key[40];
 uint8_t mc_hash[32];
 
 // Filters
-//static uint32_t ip = 175178791;
+//static uint32_t ip = 0x2704710A;
 static uint32_t ip = 0;
 
 enum filter_type_ip {
@@ -212,7 +215,7 @@ static void start_all(void);
 static void probe_all(void);
 static uint32_t init_txq(uint16_t n, lpaddr_t phys, bool csum, bool userspace);
 static uint32_t init_rxq(uint16_t n, lpaddr_t phys, bool userspace);
-static uint32_t init_evq(uint16_t n, lpaddr_t phys);
+static uint32_t init_evq(uint16_t n, lpaddr_t phys, bool interrupt);
 static void queue_hw_stop(uint16_t n);
 
 static void setup_interrupt(size_t *msix_index, uint8_t core, uint8_t vector);
@@ -669,7 +672,6 @@ static void init_rx_filter_config(void)
     reg_hi = sfn5122f_rx_filter_ctl_reg_hi_ethernet_full_search_limit_insert(reg_hi, 1);
     reg_hi = sfn5122f_rx_filter_ctl_reg_hi_ethernet_wildcard_search_limit_insert(reg_hi, 3);
 
-    // TODO set to 0
     reg_lo = sfn5122f_rx_filter_ctl_reg_lo_multicast_nomatch_q_id_lo_insert(reg_lo, 0);
     reg_lo = sfn5122f_rx_filter_ctl_reg_lo_unicast_nomatch_q_id_insert(reg_lo, 0);
     reg_lo = sfn5122f_rx_filter_ctl_reg_lo_unicast_nomatch_rss_enabled_insert(reg_lo, 0);
@@ -715,8 +717,8 @@ static void device_init(void)
     // unset bit and set other bit which are not in documentation (43 and 47)
     reg = sfn5122f_rx_cfg_reg_lo_rx_desc_push_en_insert(reg, 0) ;
     reg = sfn5122f_rx_cfg_reg_lo_rx_ingr_en_insert(reg, 1);
-    reg = sfn5122f_rx_cfg_reg_lo_rx_usr_buf_size_insert(reg, (MTU_MAX-256) >> 5);
-    //reg = sfn5122f_rx_cfg_reg_lo_rx_usr_buf_size_insert(reg, 4096 >> 5);
+    //reg = sfn5122f_rx_cfg_reg_lo_rx_usr_buf_size_insert(reg, (MTU_MAX-256) >> 5);
+    reg = sfn5122f_rx_cfg_reg_lo_rx_usr_buf_size_insert(reg, 4096 >> 5);
     //reg = sfn5122f_rx_cfg_reg_lo_rx_ownerr_ctl_insert(reg, 1);
     reg = sfn5122f_rx_cfg_reg_lo_rx_ip_hash_insert(reg, 1);
     //reg = sfn5122f_rx_cfg_reg_lo_rx_hash_insrt_hdr_insert(reg, 1);
@@ -803,7 +805,7 @@ static void device_init(void)
       (from linux driver) */
     reg = sfn5122f_tx_reserved_reg_lo_rd(d);
     reg = sfn5122f_tx_reserved_reg_lo_tx_rx_spacer_en_insert(reg, 1);
-    reg = sfn5122f_tx_reserved_reg_lo_tx_one_pkt_per_q_insert(reg, 1);
+    reg = sfn5122f_tx_reserved_reg_lo_tx_one_pkt_per_q_insert(reg, 0);
     reg = sfn5122f_tx_reserved_reg_lo_tx_dis_non_ip_ev_insert(reg, 1);
 
     /* Enable software events */
@@ -818,7 +820,8 @@ static void device_init(void)
     reg2 = sfn5122f_tx_reserved_reg_hi_rd(d);
     reg2 = sfn5122f_tx_reserved_reg_hi_tx_push_en_insert(reg2, 0);
     reg2 = sfn5122f_tx_reserved_reg_hi_tx_push_chk_dis_insert(reg2, 0);
-    reg2 = sfn5122f_tx_reserved_reg_hi_tx_rx_spacer_insert(reg2, 0xfe);
+    //reg2 = sfn5122f_tx_reserved_reg_hi_tx_rx_spacer_insert(reg2, 0xfe);
+    reg2 = sfn5122f_tx_reserved_reg_hi_tx_rx_spacer_insert(reg2, 0x1);
     sfn5122f_tx_reserved_reg_lo_wr(d, reg);
     sfn5122f_tx_reserved_reg_hi_wr(d, reg2);
 
@@ -830,9 +833,6 @@ static void device_init(void)
 static void start_all(void)
 {
     uint64_t reg;
-    uint8_t in[CMD_MAC_STATS_IN_LEN];
-    unsigned long long* stats = (unsigned long long *) mac_virt;
-    uint8_t* pointer;
  
     start_port(pci_function);
 
@@ -854,6 +854,11 @@ static void start_all(void)
     sfn5122f_int_en_reg_ker_hi_wr(d, sfn5122f_int_en_reg_ker_hi_rd(d));
 
     /* Start MAC stats            */
+    /*
+    uint8_t in[CMD_MAC_STATS_IN_LEN];
+    unsigned long long* stats = (unsigned long long *) mac_virt;
+    uint8_t* pointer;
+
     memset(in, 0, sizeof(in));
     stats[0x60] = (unsigned long long) (-1);
     memcpy(in, &mac_phys, 8);
@@ -866,6 +871,7 @@ static void start_all(void)
     errval_t err = mcdi_rpc(CMD_MAC_STATS, in, CMD_MAC_STATS_IN_LEN,
                             NULL, 0, NULL, pci_function, d);
     assert(err_is_ok(err));
+    */
 }
 
 /**************************************************************************
@@ -930,7 +936,7 @@ static void queue_hw_stop(uint16_t n)
 
 
 
-static uint32_t init_evq(uint16_t n, lpaddr_t phys)
+static uint32_t init_evq(uint16_t n, lpaddr_t phys, bool interrupt)
 {
 
     //errval_t r;
@@ -945,7 +951,7 @@ static uint32_t init_evq(uint16_t n, lpaddr_t phys)
     } else {
         reg = sfn5122f_timer_tbl_lo_int_pend_insert(reg, 0);
         reg = sfn5122f_timer_tbl_lo_int_armd_insert(reg, 0);
-        if (use_interrupt) {
+        if (use_interrupt && interrupt) {
             reg = sfn5122f_timer_tbl_lo_host_notify_mode_insert(reg, 0);
         } else {
             reg = sfn5122f_timer_tbl_lo_host_notify_mode_insert(reg, 1);
@@ -971,7 +977,7 @@ static uint32_t init_evq(uint16_t n, lpaddr_t phys)
     //  setup EV queue
     reg = sfn5122f_evq_ptr_tbl_lo_rd(d, n);
     reg = sfn5122f_evq_ptr_tbl_lo_evq_en_insert(reg, 1);
-    reg = sfn5122f_evq_ptr_tbl_lo_evq_size_insert(reg, 3);
+    reg = sfn5122f_evq_ptr_tbl_lo_evq_size_insert(reg, 6);
     reg = sfn5122f_evq_ptr_tbl_lo_evq_buf_base_id_insert(reg,
            buffer_offset);
 
@@ -989,7 +995,6 @@ static uint32_t init_evq(uint16_t n, lpaddr_t phys)
 
     sfn5122f_timer_command_reg_lo_wr(d, n, reg);
 
-
     sfn5122f_evq_rptr_reg_wr(d, n, queues[n].ev_head);
 
     return buffer_offset;
@@ -998,7 +1003,6 @@ static uint32_t init_evq(uint16_t n, lpaddr_t phys)
 static uint32_t init_rxq(uint16_t n, lpaddr_t phys, bool userspace)
 {
     //errval_t r;
-    size_t num_ent_rx;
     //struct frame_identity frameid = { .base = 0, .bytes = 0 };
     uint64_t reg_lo, reg_hi,  buffer_offset;
    /*
@@ -1012,15 +1016,14 @@ static uint32_t init_rxq(uint16_t n, lpaddr_t phys, bool userspace)
     rx_phys = frameid.base;
     rx_size = frameid.bytes;
     */
+
+    /* RX   */
     if (userspace) {
-        num_ent_rx = NUM_ENT_RX_USR;
+        buffer_offset = alloc_buf_tbl_entries(phys, NUM_ENT_RX_USR, 0, false, d);
     } else {
-        num_ent_rx = NUM_ENT_RX;
+        buffer_offset = alloc_buf_tbl_entries(phys, NUM_ENT_RX, 0, false, d);
     }
 
-    /* RX   */
-    buffer_offset = alloc_buf_tbl_entries(phys, num_ent_rx, 0, 0, d);
-
     if (buffer_offset == -1) {
        return -1;
     }
@@ -1044,7 +1047,7 @@ static uint32_t init_rxq(uint16_t n, lpaddr_t phys, bool userspace)
     reg_lo = sfn5122f_rx_desc_ptr_tbl_lo_rx_descq_label_insert(reg_lo, n);
 
     /*  1024 entries = 1   (512 = 0; 2048 = 2 ; 4096 = 3)   */
-    reg_lo = sfn5122f_rx_desc_ptr_tbl_lo_rx_descq_size_insert(reg_lo, 1);
+    reg_lo = sfn5122f_rx_desc_ptr_tbl_lo_rx_descq_size_insert(reg_lo, 3);
 
     if (!userspace) {
         reg_lo = sfn5122f_rx_desc_ptr_tbl_lo_rx_descq_type_insert(reg_lo, 0);
@@ -1057,8 +1060,8 @@ static uint32_t init_rxq(uint16_t n, lpaddr_t phys, bool userspace)
     reg_lo = sfn5122f_rx_desc_ptr_tbl_lo_rx_descq_en_insert(reg_lo, 1);
    
     /*   Hardware verifies data digest  */
-    reg_hi = sfn5122f_rx_desc_ptr_tbl_hi_rx_iscsi_ddig_en_insert(reg_hi, 1);
-    reg_hi = sfn5122f_rx_desc_ptr_tbl_hi_rx_iscsi_hdig_en_insert(reg_hi, 1);
+    reg_hi = sfn5122f_rx_desc_ptr_tbl_hi_rx_iscsi_ddig_en_insert(reg_hi, 0);
+    reg_hi = sfn5122f_rx_desc_ptr_tbl_hi_rx_iscsi_hdig_en_insert(reg_hi, 0);
 
     sfn5122f_rx_desc_ptr_tbl_lo_wr(d, n, reg_lo);
     sfn5122f_rx_desc_ptr_tbl_hi_wr(d, n, reg_hi);
@@ -1097,7 +1100,7 @@ static uint32_t init_txq(uint16_t n, uint64_t phys,
     }
     reg = sfn5122f_tx_desc_ptr_tbl_lo_tx_descq_label_insert(reg , n);
     /*  1024 entries = 1   (512 = 0; 2048 = 2 ; 4096 = 3)   */
-    reg = sfn5122f_tx_desc_ptr_tbl_lo_tx_descq_size_insert(reg , 2);
+    reg = sfn5122f_tx_desc_ptr_tbl_lo_tx_descq_size_insert(reg , 3);
 
     /*  No user lvl networking   */
     if (!userspace) {
@@ -1143,11 +1146,23 @@ static void setup_interrupt(size_t *msix_index, uint8_t core, uint8_t vector)
             *msix_index, core, dest, vector);
 }
 
+static void resend_interrupt(void* arg)
+{
+    errval_t err;
+    uint64_t i = (uint64_t) arg;
+    err = queues[i].devif->tx_vtbl.interrupt(queues[i].devif, NOP_CONT, i);
+    // If the queue is busy, there is already an oustanding message
+    if (err_is_fail(err) && err != FLOUNDER_ERR_TX_BUSY) {
+        USER_PANIC("Error when sending interrupt %s \n", err_getstring(err));
+    } 
+}
+
 /** Here are the global interrupts handled. */
 static void global_interrupt_handler(void* arg)
 {
     //uint64_t reg;
-    uint32_t queue;
+    errval_t err;
+    uint32_t q_to_check;
     errval_t syserr;
     uint8_t* net_ivec_fatal = (uint8_t *) int_ker_virt;
 
@@ -1160,12 +1175,29 @@ static void global_interrupt_handler(void* arg)
 
     }
 
-    queue = sfn5122f_int_isr0_reg_lo_rd(d);
-    DEBUG("AN INTERRUPT OCCURED %d \n", queue);
+    q_to_check = sfn5122f_int_isr0_reg_lo_rd(d);
+
+    for (uint64_t i = 1; i < 32; i++) {
+        if ((q_to_check >> i) & 0x1) {
+            if (queues[i].use_irq && queues[i].devif != NULL) {
+                DEBUG("Interrupt to queue %lu \n", i);
+                err = queues[i].devif->tx_vtbl.interrupt(queues[i].devif, NOP_CONT, i);
+                if (err_is_fail(err)) {
+                    err = queues[i].devif->register_send(queues[i].devif, 
+                                                         get_default_waitset(),
+                                                         MKCONT(resend_interrupt, (void*)i));
+                }
+            }
+        }
+    }
+
+    if (q_to_check & 0x1) {
+        DEBUG("Interrupt to queue 0 \n");
+        check_queue_0();
+    }
 
-    
-    
 
+   
     // Don't need to start event queues because we're already polling
 
 }
@@ -1251,7 +1283,7 @@ void cd_register_queue_memory(struct sfn5122f_binding *b,
     struct frame_identity id;
     err = invoke_frame_identify(ev_frame, &id);
     assert(err_is_ok(err));
-    queues[n].ev_buf_tbl = init_evq(n, id.base);
+    queues[n].ev_buf_tbl = init_evq(n, id.base, use_irq);
 
 
     // enable checksums
@@ -1321,16 +1353,18 @@ static errval_t idc_register_port_filter(struct sfn5122f_binding *b,
                                      errval_t *err,
                                      uint64_t *fid)
 {
-    DEBUG("idc_register_port_filter: called (q=%d t=%d p=%d)\n",
-            queue, type, port);
 
     if (ip == 0) {
         /* Get cards IP */
         waitset_init(&rpc_ws);
         bind_arp(&rpc_ws);
         arp_ip_info();
+        printf("IP %d \n", ip);
     }
 
+    DEBUG("idc_register_port_filter: called (q=%d t=%d p=%d)\n",
+            queue, type, port);
+
     struct sfn5122f_filter_ip f = {
             .dst_port = port,
             .dst_ip = htonl(ip),
@@ -1375,7 +1409,7 @@ static void cd_create_queue(struct sfn5122f_devif_binding *b, struct capref fram
     struct frame_identity id;
 
     int n = -1;
-    for (int i = 0; i < NUM_QUEUES; i++) {
+    for (int i = 1; i < NUM_QUEUES; i++) {
         if (queues[i].enabled == false) {
             n = i;
             break;
@@ -1402,7 +1436,7 @@ static void cd_create_queue(struct sfn5122f_devif_binding *b, struct capref fram
     queues[n].msix_intdest = core;
     queues[n].msix_intvec = msix_vector;
 
-    if (queues[n].use_irq) {
+    if (queues[n].use_irq && use_msix) {
         if (queues[n].msix_intvec != 0) {
             if (queues[n].msix_index == -1) {
                 setup_interrupt(&queues[n].msix_index, queues[n].msix_intdest,
@@ -1413,11 +1447,12 @@ static void cd_create_queue(struct sfn5122f_devif_binding *b, struct capref fram
 
     err = invoke_frame_identify(frame, &id);
     assert(err_is_ok(err));
-    queues[n].ev_buf_tbl = init_evq(n, id.base+sizeof(uint64_t)*(TX_ENTRIES+RX_ENTRIES));
     // enable checksums
     queues[n].tx_buf_tbl = init_txq(n, id.base, csum_offload, user);
     queues[n].rx_buf_tbl = init_rxq(n, id.base+ sizeof(uint64_t)*TX_ENTRIES, user);
 
+    queues[n].ev_buf_tbl = init_evq(n, id.base+sizeof(uint64_t)*(TX_ENTRIES+RX_ENTRIES), 
+                                    interrupt);
     if(queues[n].ev_buf_tbl == -1 ||
        queues[n].tx_buf_tbl == -1 ||
        queues[n].rx_buf_tbl == -1){
@@ -1458,7 +1493,7 @@ static void cd_register_region(struct sfn5122f_devif_binding *b, uint16_t qid,
     size_t size = id.bytes;
     lpaddr_t addr = id.base;
 
-    // TODO unsigned/signed not nice ...
+    // TODO unsigned/signed 
     buffer_offset = alloc_buf_tbl_entries(addr, size/BUF_SIZE, qid, true, d);
     if (buffer_offset == -1) {
         err = b->tx_vtbl.register_region_response(b, NOP_CONT, 0, NIC_ERR_REGISTER_REGION);
@@ -1466,7 +1501,9 @@ static void cd_register_region(struct sfn5122f_devif_binding *b, uint16_t qid,
     }
     
     err = b->tx_vtbl.register_region_response(b, NOP_CONT, buffer_offset, SYS_ERR_OK);
-    assert(err_is_ok(err));
+    if (err_is_fail(err)) {
+       
+    }
 }
 
 
@@ -1635,6 +1672,7 @@ static void pci_init_card(struct device_mem* bar_info, int bar_count)
 
     /* Initialize Mackerel binding */
     sfn5122f_initialize(d, (void*) bar_info[0].vaddr);
+    d_virt = bar_info[0].vaddr;
 
     // Initialize manager for MSI-X vectors
     if (use_msix) {
@@ -1713,16 +1751,48 @@ static void cd_main(void)
     eventloop();
 }
 
+
+
+/*
+static errval_t init_stack(void)
+{
+
+    struct netd_state *state;
+    char* card_name = "sfn5122f";
+    uint32_t allocated_queue = 0;   
+    uint32_t total_queues = 16;
+    uint8_t filter_type = 2;
+    bool do_dhcp = false;
+    char* ip_addr_str = "10.113.4.39";
+    char* netmask_str = "255.255.252.0";
+    char* gateway_str = "10.113.4.4";
+    errval_t err;
+
+    err = init_device_manager(card_name, total_queues, filter_type);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    err = netd_init(&state, card_name, allocated_queue, do_dhcp, 
+                    ip_addr_str, netmask_str, gateway_str);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    return SYS_ERR_OK;
+}
+*/
+
 int main(int argc, char** argv)
 {
     DEBUG("SFN5122F driver started \n");
-    errval_t r;
+    errval_t err;
 
     parse_cmdline(argc, argv);
     /* Register our device driver */
-    r = pci_client_connect();
-    assert(err_is_ok(r));
-    r = pci_register_driver_irq(pci_init_card, PCI_CLASS_ETHERNET,
+    err = pci_client_connect();
+    assert(err_is_ok(err));
+    err = pci_register_driver_irq(pci_init_card, PCI_CLASS_ETHERNET,
                                 PCI_DONT_CARE, PCI_DONT_CARE,
                                 PCI_VENDOR_SOLARFLARE, DEVICE_ID,
                                 pci_bus, pci_device, pci_function,
@@ -1732,6 +1802,62 @@ int main(int argc, char** argv)
         event_dispatch(get_default_waitset());
     }
 
+    init_queue_0("sfn5122f", d_mac[pci_function], d_virt,
+                 use_interrupt, false, &queues[0].ev_frame, 
+                 &queues[0].tx_frame, &queues[0].rx_frame);
+
+    queues[0].enabled = false;
+    queues[0].tx_head = 0;
+    queues[0].rx_head = 0;
+    queues[0].ev_head = 0;
+    queues[0].rxbufsz = MTU_MAX;
+    queues[0].binding = NULL;
+    queues[0].use_irq = true;
+    queues[0].userspace = false;
+
+    struct frame_identity id;
+    err = invoke_frame_identify(queues[0].ev_frame, &id);
+    assert(err_is_ok(err));
+    queues[0].ev_buf_tbl = init_evq(0, id.base, queues[0].use_irq);
+    // enable checksums
+    err = invoke_frame_identify(queues[0].tx_frame, &id);
+    assert(err_is_ok(err));
+    queues[0].tx_buf_tbl = init_txq(0, id.base, csum_offload, false);
+
+    err = invoke_frame_identify(queues[0].rx_frame, &id);
+    assert(err_is_ok(err));
+    queues[0].rx_buf_tbl = init_rxq(0, id.base, false);
+
+    write_queue_tails();
+
+    start_all();    
+    
+    /*
+    err = init_stack();
+    if (err_is_fail(err)) {
+        USER_PANIC("Failed initalizing netd etc %s \n", err_getstring(err));
+    } 
+    */   
+
+    /*
+    struct sfn5122f_filter_ip f = {
+            .dst_port = 7,
+            .dst_ip = htonl(0x2704710A),
+            .src_ip = 0,
+            .src_port = 0,
+            .type_ip = sfn5122f_PORT_UDP,
+            .queue = 1,
+    };
+
+    uint64_t fid;   
+    for (int i = 0; i < 10; i++) {
+        f.dst_port = 7+i;
+        f.queue = i+1;
+        err = reg_port_filter(&f, &fid);
+        assert(err_is_ok(err));
+
+    }
+    */
     /* loop myself */
     cd_main();
 }
index 44b97f1..6f5daa6 100644 (file)
@@ -33,7 +33,7 @@
 #endif
 
 
-#ifdef DEBUG_buftbl
+#ifdef DEBUG_BUFTBL
     #define DEBUG_BUF(x...) printf("buftbl: " x)
 #else
     #define DEBUG_BUF(x...) do {} while (0)
index 4796b63..f9e8945 100644 (file)
@@ -1,23 +1,16 @@
-/* Copyright (c) 2007-2011, ETH Zurich.
+/* Copyright (c) 2017, ETH Zurich.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
  * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ * ETH Zurich D-INFK, Universitätstrasse 6, CH-8092 Zurich. Attn: Systems Group.
  */
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
 
 #include <net_queue_manager/net_queue_manager.h>
-#include <barrelfish/nameservice_client.h>
-#include <barrelfish/spawn_client.h>
-#include <barrelfish/debug.h>
-#include <barrelfish/deferred.h>
-#include <pci/pci.h>
 
-
-#include <if/sfn5122f_defs.h>
 #include <dev/sfn5122f_dev.h>
 #include <dev/sfn5122f_q_dev.h>
 
 #include "sfn5122f_queue.h"
 #include "sfn5122f_debug.h"
 #include "buffer_tbl.h"
-
-/******************************************************************************/
-/* Prototypes */
-
-static void idc_register_queue_memory(uint8_t queue,
-                                      struct capref tx_frame,
-                                      struct capref ev_frame,
-                                      struct capref rx_frame,
-                                      uint32_t rxbufsz,
-                                      uint8_t vector,
-                                      coreid_t core);
-
-static void idc_terminate_queue(void);
-
-void qd_queue_init_data(struct sfn5122f_binding *b, struct capref registers,
-        uint64_t macaddr);
-void qd_queue_memory_registered(struct sfn5122f_binding *b);
-void qd_write_queue_tails(struct sfn5122f_binding *b);
-
-void qd_argument(const char *arg);
-void qd_main(void);
-int main(int argc, char **argv) __attribute__((weak));
-
-/* Global state */
-static const char* service_name = "sfn5122f";
-
-/** Binding to the internal sfn5122f management service */
-static struct sfn5122f_binding *binding = NULL;
+#include "sfn5122f_qdriver.h"
 
 /** Queue index for this manager instance */
-static int qi = -1;
+static int qi = 0;
 
 /** Mackerel handle for device */
 static sfn5122f_t *d = NULL;
@@ -68,7 +34,7 @@ static sfn5122f_queue_t *q;
 static uint64_t mac_address = 0;
 
 /** Indicates if the initialization is done */
-static int initialized = 0;
+static bool initialized = false;
 
 /**
  * Indicates whether we should rely on cache coherence for the descriptor
@@ -77,10 +43,7 @@ static int initialized = 0;
 static bool cache_coherence = true;
 
 /** Indicates whether Interrupts should be used */
-static bool use_interrupts = false;
-static bool use_msix = false;
-static coreid_t core = 0;
-static uint8_t vector = 0;
+static bool use_interrupts = true;
 
 /** Capability for hardware TX ring */
 static struct capref tx_frame;
@@ -94,8 +57,6 @@ static struct capref ev_frame;
 //static void* mac_virt;
 uint64_t mac_stats_array[NUM_MAC_STATS];
 
-/**  Userspace networking enable  */
-static bool userspace = 0;
 
 /******************************************************************************/
 /* Transmit path */
@@ -105,7 +66,7 @@ static uint64_t find_tx_free_slot_count_fn(void)
 }
 
 static errval_t transmit_pbuf_list_fn(struct driver_buffer *buffers,
-                                      size_t                count)
+                               size_t                count)
 {
     size_t i;
     
@@ -165,7 +126,7 @@ static size_t check_for_new_events(void)
 
     // need to block until initalized
     if (!initialized) {
-        return 0;
+        return NIC_ERR_QDRIVER;
     }
  
     ev_code = sfn5122f_get_event_code(q);
@@ -181,6 +142,7 @@ static size_t check_for_new_events(void)
                         buf[0].opaque = op;
                         process_received_packet(buf, 1, 0);
                    } else {
+                        DEBUG_QUEUE("Failed receiveing \n");
                         // TODO how to tell the the upper layer that it can reuse
                         // the rx buffer
                    }
@@ -189,16 +151,21 @@ static size_t check_for_new_events(void)
                    sfn5122f_queue_bump_evhead(q);
                    break;
               case EV_CODE_TX:
-                   if (sfn5122f_queue_handle_tx_ev(q, &op) == SYS_ERR_OK) {
+                   if (sfn5122f_queue_handle_tx_ev(q) == SYS_ERR_OK) {
                         DEBUG_QUEUE("TX EVENT OK %d \n", qi);
-                        handle_tx_done(op); 
+                        uint8_t index = 0;
+                        while (q->num_left > 0) {
+                            handle_tx_done(q->bufs[0]);
+                            index++;
+                            q->num_left--;
+                        }
                    } else {
                         DEBUG_QUEUE("TX EVENT ERR %d \n", qi);
                    }
                    sfn5122f_queue_bump_evhead(q);
                    break;
               case EV_CODE_DRV:
-                   //DEBUG_QUEUE("DRIVER EVENT %d\n", qi);
+                   DEBUG_QUEUE("DRIVER EVENT %d\n", qi);
                    sfn5122f_handle_drv_ev(q, qi);
                    sfn5122f_queue_bump_evhead(q);
                    break;
@@ -211,7 +178,7 @@ static size_t check_for_new_events(void)
                    sfn5122f_queue_bump_evhead(q);
                    break;
               case EV_CODE_MCDI:
-                   //DEBUG_QUEUE("MCDI EVENT \n");
+                   DEBUG_QUEUE("MCDI EVENT \n");
                    sfn5122f_queue_handle_mcdi_event(q);
                    sfn5122f_queue_bump_evhead(q);
                    break;
@@ -266,34 +233,13 @@ static void get_mac_address_fn(uint8_t* mac)
 {
     memcpy(mac, &mac_address, 6);
 }
-/******************************************************************************/
-/* Interrupts */
-
-static void qd_interrupt(void)
-{
-    size_t count;
-    
-    count = check_for_new_events();
-    if (count <= 0) {
-        DEBUG_QUEUE("qd_int_%d: qid=%d no events \n", disp_get_core_id(), qi);
-    } else {
-        DEBUG_QUEUE("qd_int_%d: qid=%d events processed=%ld \n", disp_get_core_id(), 
-                    qi, count);
-    }
-
-}
-
-static void interrupt_handler(void *data)
-{
-    qd_interrupt();
-}
 
 /******************************************************************************/
 /* Device/queue initialization */
 
 /** Allocate queue n and return handle for queue manager */
 
-static void setup_queue(void)
+static void setup_queue(struct capref* ev, struct capref* tx, struct capref* rx)
 {
     size_t tx_size, rx_size, ev_size;
     void *tx_virt, *rx_virt, *ev_virt;
@@ -312,154 +258,49 @@ static void setup_queue(void)
     /* Allocate memory for descriptor rings  
        No difference for userspace networking*/
     tx_size = sfn5122f_q_tx_ker_desc_size * TX_ENTRIES;
-    tx_virt = alloc_map_frame(flags_vreg, tx_size, &tx_frame);
+    tx_virt = alloc_map_frame(flags_vreg, tx_size, tx);
 
     assert(tx_virt != NULL);
 
-    if (!userspace) {
-         rx_size = sfn5122f_q_rx_ker_desc_size * RX_ENTRIES;
-    } else {
-         rx_size = sfn5122f_q_rx_user_desc_size * RX_ENTRIES;
-    }
+    rx_size = sfn5122f_q_rx_ker_desc_size * RX_ENTRIES;
 
-    rx_virt = alloc_map_frame(flags_vreg, rx_size, &rx_frame);
+    rx_virt = alloc_map_frame(flags_vreg, rx_size, rx);
     assert(rx_virt != NULL);
 
     ev_size = sfn5122f_q_event_entry_size * EV_ENTRIES;
-    ev_virt = alloc_map_frame(flags_vreg, ev_size, &ev_frame);
+    ev_virt = alloc_map_frame(flags_vreg, ev_size, ev);
     assert(ev_virt != NULL);
 
-    if (use_interrupts && use_msix) {
-        DEBUG_QUEUE("Enabling MSI-X interrupts\n");
-        errval_t err = pci_setup_inthandler(interrupt_handler, NULL, &vector);
-        assert(err_is_ok(err));
-        core = disp_get_core_id();
-    } else {
-        if (use_interrupts) {
-            DEBUG_QUEUE("Enabling legacy interrupts\n");
-        }
-        vector = 0;
-        core = 0;
-    }
-
-
     // Initialize queue manager
     q = sfn5122f_queue_init(tx_virt, TX_ENTRIES, rx_virt, RX_ENTRIES,
-                            ev_virt, EV_ENTRIES, &ops,  NULL, userspace);
-    idc_register_queue_memory(qi, tx_frame, rx_frame,
-                              ev_frame, MTU_MAX, vector, core);
-
-}
-
-/** Terminate this queue driver */
-static void terminate_queue_fn(void)
-{
-    idc_terminate_queue();
+                            ev_virt, EV_ENTRIES, &ops,  NULL, false);
 }
 
-/******************************************************************************/
-/* Management interface implemetation */
 
-/** Request device register cap from card driver */
 
-static void idc_request_device_info(void)
+void write_queue_tails(void)
 {
+    DEBUG_QUEUE("idc_write_queue_tails()\n");
 
-    errval_t r;
-    DEBUG_QUEUE("idc_request_device_info()\n");
-
-    r = sfn5122f_request_device_info__tx(binding, NOP_CONT);
-    // TODO: handle busy
-    assert(err_is_ok(r));
+    sfn5122f_queue_bump_rxtail(q);
+    sfn5122f_queue_bump_txtail(q);
 }
 
-/** Send memory caps to card driver */
-static void idc_register_queue_memory(uint8_t queue,
-                                      struct capref tx,
-                                      struct capref rx,
-                                      struct capref ev,
-                                      uint32_t rxbufsz,
-                                      uint8_t vec,
-                                      coreid_t cid)
+size_t check_queue_0(void) 
 {
-
-    errval_t r;
-    DEBUG_QUEUE("idc_register_queue_memory()\n");
-
-    r = sfn5122f_register_queue_memory__tx(binding, NOP_CONT, queue,
-                                           tx, rx, ev, rxbufsz, 
-                                           use_interrupts, userspace,
-                                           vec, cid);
-    // TODO: handle busy
-    assert(err_is_ok(r));
+        do_pending_work_for_all();
+        return check_for_new_events();
 }
 
-// Callback from device manager
-void qd_queue_init_data(struct sfn5122f_binding *b, struct capref registers,
-                        uint64_t macaddr)
+static void terminate_queue_fn(void) 
 {
-    struct frame_identity frameid = { .base = 0, .bytes = 0 };
     errval_t err;
-    void *virt;
-
-    DEBUG_QUEUE("idc_queue_init_data\n");
-
-    mac_address = macaddr;
-
-    // Map device registers
-    invoke_frame_identify(registers, &frameid);
-    err = vspace_map_one_frame_attr(&virt, frameid.bytes, registers,
-            VREGION_FLAGS_READ_WRITE_NOCACHE, NULL, NULL);
-
+    err = terminate_queue_0();
     assert(err_is_ok(err));
-
-    // Initialize mackerel device
-    d = malloc(sizeof(*d));
-    sfn5122f_initialize(d, virt);
-    // Initialize queue
-    setup_queue();
-}
-
-/** Tell card driver to stop this queue. */
-static void idc_terminate_queue(void)
-{
-    errval_t r;
-    DEBUG_QUEUE("idc_terminate_queue()\n");
-
-    r = sfn5122f_terminate_queue__tx(binding, NOP_CONT, qi);
-    // TODO: handle busy
-    assert(err_is_ok(r));
 }
 
 // Callback from device manager
-void qd_queue_memory_registered(struct sfn5122f_binding *b)
-{
-    initialized = 1;
-    // Register queue with queue_mgr library
-    DEBUG_QUEUE("Called ethersrv_init() \n");
-    ethersrv_init((char*) service_name, qi, 
-                  get_mac_address_fn, 
-                  terminate_queue_fn,
-                  transmit_pbuf_list_fn, 
-                  find_tx_free_slot_count_fn,
-                  handle_free_tx_slot_fn, 
-                  MTU_MAX, 
-                  register_rx_buffer_fn,
-                  find_rx_free_slot_count_fn);
-}
-
-// Callback from device manager
-void qd_write_queue_tails(struct sfn5122f_binding *b)
-{
-    DEBUG_QUEUE("idc_write_queue_tails()\n");
-
-    sfn5122f_queue_bump_rxtail(q);
-    sfn5122f_queue_bump_txtail(q);
-}
-
-
-// Callback from device manager
-static void idc_queue_terminated(struct sfn5122f_binding *b)
+errval_t terminate_queue_0(void)
 {
     errval_t err;
 
@@ -468,156 +309,70 @@ static void idc_queue_terminated(struct sfn5122f_binding *b)
     // Free memory for hardware ring buffers
     if (q->userspace) {
         err = vspace_unmap(q->tx_ring.user);
-        assert(err_is_ok(err));
+        if (err_is_fail(err)) {
+            return err;
+        }
         err = vspace_unmap(q->rx_ring.user);
-        assert(err_is_ok(err));
+        if (err_is_fail(err)) {
+            return err;
+        }
     } else {
         err = vspace_unmap(q->tx_ring.ker);
-        assert(err_is_ok(err));
+        if (err_is_fail(err)) {
+            return err;
+        }
         err = vspace_unmap(q->rx_ring.ker);
-        assert(err_is_ok(err));
+        if (err_is_fail(err)) {
+            return err;
+        }
     }
 
     err = vspace_unmap(q->ev_ring);
-    assert(err_is_ok(err));
+    if (err_is_fail(err)) {
+        return err;
+    }
     err = cap_delete(tx_frame);
-    assert(err_is_ok(err));
-    err = cap_delete(rx_frame);
-    assert(err_is_ok(err));
-    err = cap_delete(ev_frame);
-    assert(err_is_ok(err));
-
-    exit(0);
-}
-
-static struct sfn5122f_rx_vtbl rx_vtbl = {
-    .queue_init_data = qd_queue_init_data,
-    .queue_memory_registered = qd_queue_memory_registered,
-    .write_queue_tails = qd_write_queue_tails,
-    .queue_terminated = idc_queue_terminated,
-};
-
-static void bind_cb(void *st, errval_t err, struct sfn5122f_binding *b)
-{
-    assert(err_is_ok(err));
-
-    DEBUG_QUEUE("Sucessfully connected to management interface\n");
-
-    b->rx_vtbl = rx_vtbl;
-    binding = b;
-
-    idc_request_device_info();
-}
-
-/** Connect to the management interface */
-static void connect_to_mngif(void)
-{
-    errval_t r;
-    iref_t iref;
-    const char *suffix = "_sfn5122fmng";
-    char name[strlen(service_name) + strlen(suffix) + 1];
-
-    // Build label for interal management service
-    sprintf(name, "%s%s", service_name, suffix);
-
-    // Connect to service
-    DEBUG_QUEUE("Looking up management interface (%s)\n", name);
-    r = nameservice_blocking_lookup(name, &iref);
-    assert(err_is_ok(r));
-
-    DEBUG_QUEUE("Binding to management interface\n");
-    r = sfn5122f_bind(iref, bind_cb, NULL, get_default_waitset(),
-            IDC_BIND_FLAGS_DEFAULT);
-    assert(err_is_ok(r));
-}
-
-void qd_argument(const char *arg)
-{
-    if (strncmp(arg, "cardname=", strlen("cardname=") - 1) == 0) {
-        service_name = arg + strlen("cardname=");
-        ethersrv_argument(arg);
-
-    } else if (strncmp(arg, "queue=", strlen("queue=") - 1) == 0) {
-        qi = atol(arg + strlen("queue="));
-        ethersrv_argument(arg);
-
-    } else if (strncmp(arg, "cache_coherence=", 
-                       strlen("cache_coherence=") - 1) == 0) {
-        cache_coherence = !!atol(arg + strlen("cache_coherence="));
-
-    } else if (strncmp(arg, "interrupts=", strlen("interrupts=") - 1) == 0) {
-        use_interrupts = !!atol(arg + strlen("interrupts="));
-        DEBUG_QUEUE("Interrupts enabled: legacy interrupts for fatal device errors\n");
-    } else if (strncmp(arg, "msix=", strlen("msix=") - 1) == 0) {
-        USER_PANIC("MSI-X not fully implemented yet!");
-        use_msix = !!atol(arg + strlen("msix="));
-        DEBUG_QUEUE("Using msix \n");
-    } else if (strncmp(arg, "userspace=", strlen("userspace=") - 1) == 0) {
-       USER_PANIC("Userspace networking for SFN5122F not implemented!");
-       /*
-        userspace = atol(arg + strlen("userspace="));
-        ethersrv_argument(arg);
-       */
-    } else {
-        ethersrv_argument(arg);
+    if (err_is_fail(err)) {
+        return err;
     }
-}
-
-static void parse_cmdline(int argc, char **argv)
-{
-    int i;
-    for (i = 1; i < argc; i++) {
-        qd_argument(argv[i]);
+    err = cap_delete(rx_frame);
+    if (err_is_fail(err)) {
+        return err;
     }
-}
-
-static void eventloop(void)
-{
-    struct waitset *ws;
-    errval_t err;
-
-    DEBUG_QUEUE("eventloop()\n");
-
-    ws = get_default_waitset();
-    while (1) {
-        err = event_dispatch_non_block(ws);
-        do_pending_work_for_all();
-        check_for_new_events();
+    err = cap_delete(ev_frame);
+    if (err_is_fail(err)) {
+        return err;
     }
+    return SYS_ERR_OK;
 }
 
-static void eventloop_ints(void)
+errval_t init_queue_0(char* cname, uint64_t mac_addr, void* device, 
+                      bool interrupts, bool userspace, struct capref* ev,
+                      struct capref* tx, struct capref* rx) 
 {
-    struct waitset *ws;
-    DEBUG_QUEUE("eventloop_ints()\n");
-
-    ws = get_default_waitset();
-    while (1) {
-        event_dispatch(ws);
-        do_pending_work_for_all();
-    }
-}
+    use_interrupts = interrupts;
+    mac_address = mac_addr;    
 
-void qd_main(void)
-{
-    // Validate some settings
-    if (qi == -1) {
-        USER_PANIC("For queue driver the queue= parameter has to be specified "
-                   "on the command line!");
-    }
+    d = malloc(sizeof(*d));
+    sfn5122f_initialize(d, device);
+    // Initialize queue
+    setup_queue(ev, tx, rx);
 
-    connect_to_mngif();
+    ethersrv_init((char*) cname, 0, 
+                  get_mac_address_fn, 
+                  terminate_queue_fn,
+                  transmit_pbuf_list_fn, 
+                  find_tx_free_slot_count_fn,
+                  handle_free_tx_slot_fn, 
+                  MTU_MAX, 
+                  register_rx_buffer_fn,
+                  find_rx_free_slot_count_fn);
  
-    if (use_interrupts) {
-        eventloop_ints();
-    } else {
-        eventloop();
-    }
-}
+    tx_frame = *tx;
+    rx_frame = *tx;
+    ev_frame = *tx;
 
-int main(int argc, char **argv)
-{
-    DEBUG_QUEUE("Started\n");
-    parse_cmdline(argc, argv);
-    qd_main();
+    initialized = true;
+
+    return SYS_ERR_OK;      
 }
diff --git a/usr/drivers/solarflare/sfn5122f_qdriver.h b/usr/drivers/solarflare/sfn5122f_qdriver.h
new file mode 100644 (file)
index 0000000..8ebca81
--- /dev/null
@@ -0,0 +1,19 @@
+/* Copyright (c) 2017, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitätstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef LIBQDRIVER_H_
+#define LIBQDRIVER_H_
+
+void write_queue_tails(void);
+size_t check_queue_0(void);
+errval_t terminate_queue_0(void);
+errval_t init_queue_0(char* cname, uint64_t mac_addr, void* device, 
+                      bool interrupts, bool userspace, struct capref* ev,
+                      struct capref* tx, struct capref* rx);
+
+#endif
index 860d9ec..e372707 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 
-#include <devif/queue_interface.h>
 #include <dev/sfn5122f_q_dev.h>
 #include <dev/sfn5122f_dev.h>
 #include "helper.h"
+#include "sfn5122f_debug.h"
 
 #define MTU_MAX 2048
 
-struct sfn5122f_devif_binding;
-struct sfn5122f_devif_rpc_client;
 struct sfn5122f_queue;
 
 struct sfn5122f_queue_ops {
@@ -80,10 +78,25 @@ struct sfn5122f_queue {
     uint16_t id;
     sfn5122f_t *device;
     struct region_entry* regions;
+
+    // TX envents might merge multiple TX descirptors
+    void* bufs[32];
+    uint8_t last;
+    uint8_t num_left;
 };
 
 typedef struct sfn5122f_queue sfn5122f_queue_t;
 
+
+static inline bool is_batched(size_t size, uint16_t tx_head, uint16_t q_tx_head)
+{
+    if (tx_head >= q_tx_head) {
+        return (tx_head - q_tx_head > 0);
+    } else {
+        return (((tx_head + size) - q_tx_head) > 0);
+    }
+}
+
 static inline sfn5122f_queue_t* sfn5122f_queue_init(void* tx, 
                                                     size_t tx_size,
                                                     void* rx, 
@@ -242,64 +255,6 @@ static inline int sfn5122f_queue_add_user_rxbuf(sfn5122f_queue_t* q,
     return 0;
 }
 
-
-static inline int sfn5122f_queue_add_user_rxbuf_devif(sfn5122f_queue_t* q, 
-                                                      uint32_t buf_id,
-                                                      uint16_t offset,
-                                                      regionid_t rid,
-                                                      bufferid_t devq_bid,
-                                                      lpaddr_t base,
-                                                      size_t len,
-                                                      uint64_t flags)
-{
-    struct devq_buf* buf;
-    sfn5122f_q_rx_user_desc_t d;
-    size_t tail = q->rx_tail;
-
-    d = q->rx_ring.user[tail];
-    buf = &q->rx_bufs[tail];
-
-    buf->rid = rid;
-    buf->bid = devq_bid;
-    buf->addr = base;
-    buf->len = len;
-    buf->flags = flags;
-    sfn5122f_q_rx_user_desc_rx_user_buf_id_insert(d, buf_id);
-    sfn5122f_q_rx_user_desc_rx_user_2byte_offset_insert(d, offset >> 1);
-    q->rx_tail = (tail + 1) % q->rx_size;
-    return 0;
-}
-
-static inline int sfn5122f_queue_add_rxbuf_devif(sfn5122f_queue_t* q, 
-                                                 regionid_t rid,
-                                                 bufferid_t bid,
-                                                 lpaddr_t addr,
-                                                 size_t len,
-                                                 uint64_t flags)
-{
-    struct devq_buf* buf;
-    sfn5122f_q_rx_ker_desc_t d;
-    size_t tail = q->rx_tail;
-
-    d = q->rx_ring.ker[tail];
-
-    buf = &q->rx_bufs[tail];
-
-    buf->rid = rid;
-    buf->bid = bid;
-    buf->addr = addr;
-    buf->len = len;
-    buf->flags = flags;
-
-    sfn5122f_q_rx_ker_desc_rx_ker_buf_addr_insert(d, addr);
-    sfn5122f_q_rx_ker_desc_rx_ker_buf_region_insert(d, 0);
-    // TODO: Check size
-    sfn5122f_q_rx_ker_desc_rx_ker_buf_size_insert(d, len);
-    q->rx_tail = (tail + 1) % q->rx_size;
-    return 0;
-}
-
-
 static inline errval_t sfn5122f_queue_handle_rx_ev(sfn5122f_queue_t* q, 
                                                    void** opaque, 
                                                    size_t* len)
@@ -313,15 +268,41 @@ static inline errval_t sfn5122f_queue_handle_rx_ev(sfn5122f_queue_t* q,
     sfn5122f_q_rx_user_desc_t d_user = 0;
 
     ev = q->ev_ring[ev_head];
+    rx_head = sfn5122f_q_rx_ev_rx_ev_desc_ptr_extract(ev);
 
     if(!sfn5122f_q_rx_ev_rx_ev_pkt_ok_extract(ev)) {   
          // TODO error handling
+         q->rx_head = (rx_head + 1) % q->rx_size;
          if (sfn5122f_q_rx_ev_rx_ev_tobe_disc_extract(ev)) {
             // packet discared by softare -> ok
             return NIC_ERR_RX_DISCARD;
          }
 
-         printf("Packet not ok \n");
+         if (sfn5122f_q_rx_ev_rx_ev_frm_trunc_extract(ev)) {
+            //printf("Packet truncated \n");
+         }
+
+         if (sfn5122f_q_rx_ev_rx_ev_pkt_not_parsed_extract(ev)) {
+            DEBUG_QUEUE("Packet not parsed\n");
+         }
+
+         if (sfn5122f_q_rx_ev_rx_ev_ip_frag_err_extract(ev)) {
+            DEBUG_QUEUE("Packet IP header err\n");
+         }
+
+         if (sfn5122f_q_rx_ev_rx_ev_ip_hdr_chksum_err_extract(ev)) {
+            DEBUG_QUEUE("Packet IP header checksum err\n");
+         }
+
+         if (sfn5122f_q_rx_ev_rx_ev_tcp_udp_chksum_err_extract(ev)) {
+            DEBUG_QUEUE("Packet TCP/UPD checksum err\n");
+         }
+
+         if (sfn5122f_q_rx_ev_rx_ev_eth_crc_err_extract(ev)) {
+            DEBUG_QUEUE("Packet Ethernet CRC err\n");
+         }
+
+         DEBUG_QUEUE("Packet not ok \n");
          return NIC_ERR_RX_PKT;
     }
 
@@ -331,7 +312,6 @@ static inline errval_t sfn5122f_queue_handle_rx_ev(sfn5122f_queue_t* q,
         *len = 16384;
     }
 
-    rx_head = sfn5122f_q_rx_ev_rx_ev_desc_ptr_extract(ev);
     if (q->userspace) {
         d_user = q->rx_ring.user[rx_head];  
     } else {
@@ -351,70 +331,6 @@ static inline errval_t sfn5122f_queue_handle_rx_ev(sfn5122f_queue_t* q,
     return SYS_ERR_OK;
 }
 
-
-static inline errval_t sfn5122f_queue_handle_rx_ev_devif(sfn5122f_queue_t* q, 
-                                                         regionid_t* rid,
-                                                         bufferid_t* bid,
-                                                         lpaddr_t* base,
-                                                         size_t* len,
-                                                         uint64_t* flags)
-{   
-    /*  Only one event is generated even if there is more than one
-        descriptor per packet  */
-    struct devq_buf* buf;
-    size_t ev_head = q->ev_head;
-    size_t rx_head;
-    sfn5122f_q_rx_ev_t ev;
-    sfn5122f_q_rx_user_desc_t d_user = 0;
-
-    ev = q->ev_ring[ev_head];
-    rx_head = sfn5122f_q_rx_ev_rx_ev_desc_ptr_extract(ev);
-
-    buf = &q->rx_bufs[rx_head];
-
-    *rid = buf->rid;
-    *bid = buf->bid;
-    *base = buf->addr;
-    *flags = buf->flags;
-
-    if(!sfn5122f_q_rx_ev_rx_ev_pkt_ok_extract(ev)) {   
-         // TODO error handling
-         q->rx_head = (rx_head + 1) % q->rx_size;
-         if (sfn5122f_q_rx_ev_rx_ev_tobe_disc_extract(ev)) {
-            // packet discared by softare -> ok
-            return NIC_ERR_RX_DISCARD;
-         }
-
-         printf("Packet not ok \n");
-         if (sfn5122f_q_rx_ev_rx_ev_buf_owner_id_extract(ev)) {
-             printf("Wrong owner \n");
-         }
-         return NIC_ERR_RX_PKT;
-    }
-
-    *len = sfn5122f_q_rx_ev_rx_ev_byte_ctn_extract(ev);
-    /* Length of 0 is treated as 16384 bytes */
-    if (*len == 0) {
-        *len = 16384;
-    }
-
-    rx_head = sfn5122f_q_rx_ev_rx_ev_desc_ptr_extract(ev);
-    d_user = q->rx_ring.user[rx_head];  
-
-    buf = &q->rx_bufs[rx_head];
-
-    *rid = buf->rid;
-    *bid = buf->bid;
-    *base = buf->addr;
-    *flags = buf->flags;
-
-    memset(ev, 0xff, sfn5122f_q_event_entry_size);
-    memset(d_user, 0 , sfn5122f_q_rx_user_desc_size);
-
-    q->rx_head = (rx_head + 1) % q->rx_size;
-    return SYS_ERR_OK;
-}
-
 static inline void sfn5122f_queue_bump_evhead(sfn5122f_queue_t* q)
 {     
      q->ev_head = (q->ev_head +1) % q->ev_size;
@@ -450,7 +366,7 @@ static inline size_t sfn5122f_queue_free_txslots(sfn5122f_queue_t* q)
 }
 
 
-static inline errval_t sfn5122f_queue_handle_tx_ev(sfn5122f_queue_t* q, void** opaque)
+static inline errval_t sfn5122f_queue_handle_tx_ev(sfn5122f_queue_t* q)
 {   
     /*  Only one event is generated even if there is more than one
         descriptor per packet  */
@@ -458,75 +374,39 @@ static inline errval_t sfn5122f_queue_handle_tx_ev(sfn5122f_queue_t* q, void** o
     size_t tx_head;
     sfn5122f_q_tx_ev_t ev;
     sfn5122f_q_tx_ker_desc_t d = 0;
-    sfn5122f_q_tx_user_desc_t d_user= 0;
     
+
     ev = q->ev_ring[ev_head];
+    tx_head = sfn5122f_q_tx_ev_tx_ev_desc_ptr_extract(ev);
+
     if(sfn5122f_q_tx_ev_tx_ev_pkt_err_extract(ev)){     
            //TODO error handling
            return NIC_ERR_TX_PKT;
     }
 
+
     if (sfn5122f_q_tx_ev_tx_ev_comp_extract(ev) == 1){  
-        tx_head = sfn5122f_q_tx_ev_tx_ev_desc_ptr_extract(ev);
-        if (q->userspace) {
-            d_user = q->tx_ring.user[tx_head];  
-        } else {
+        // TX Event is a batch
+        if (is_batched(q->tx_size, tx_head, q->tx_head)) {
+            uint8_t index = 0;
+            q->num_left = 0;
+            d = q->tx_ring.ker[q->tx_head];  
+            while (q->tx_head != (tx_head + 1) % q->tx_size ) {
+                q->bufs[index] = q->tx_opaque[q->tx_head];
+                index++;
+                q->tx_head = (q->tx_head + 1) % q->tx_size;
+                q->num_left++;
+            }          
+            memset(d, 0 , sfn5122f_q_tx_ker_desc_size*q->num_left);
+        } else { // Singe descriptor
             d = q->tx_ring.ker[tx_head];  
+            q->num_left = 1;
+            q->bufs[0] = q->tx_opaque[tx_head];
+            memset(d, 0 , sfn5122f_q_tx_ker_desc_size);
         }
 
-        *opaque = q->tx_opaque[tx_head]; 
-
         // reset entry event in queue
         memset(ev, 0xff, sfn5122f_q_event_entry_size);
-        if (q->userspace) {
-            memset(d_user, 0 , sfn5122f_q_tx_user_desc_size);
-        } else {
-           memset(d, 0 , sfn5122f_q_tx_ker_desc_size);
-        }
-        q->tx_head = (tx_head +1) % q->tx_size;
-    }
-
-    return SYS_ERR_OK;
-}
-
-
-static inline errval_t sfn5122f_queue_handle_tx_ev_devif(sfn5122f_queue_t* q, 
-                                                         regionid_t* rid,
-                                                         bufferid_t* bid,
-                                                         lpaddr_t* base,
-                                                         size_t* len,
-                                                         uint64_t* flags)
-{
-    /*  Only one event is generated even if there is more than one
-        descriptor per packet  */
-    size_t ev_head = q->ev_head;
-    size_t tx_head;
-    struct devq_buf* buf;
-    sfn5122f_q_tx_ev_t ev;
-    sfn5122f_q_tx_user_desc_t d_user= 0;
-   
-    ev = q->ev_ring[ev_head];
-    tx_head = sfn5122f_q_tx_ev_tx_ev_desc_ptr_extract(ev);
-    
-
-    buf = &q->tx_bufs[tx_head];
-
-    *rid = buf->rid;
-    *bid = buf->bid;
-    *base = buf->addr;
-    *flags = buf->flags;
-
-    if (sfn5122f_q_tx_ev_tx_ev_pkt_err_extract(ev)){     
-        q->tx_head = (tx_head +1) % q->tx_size;
-        return NIC_ERR_TX_PKT;
-    }
-
-    if (sfn5122f_q_tx_ev_tx_ev_comp_extract(ev) == 1){  
-        d_user = q->tx_ring.user[tx_head];  
-
-        // reset entry event in queue
-        memset(ev, 0xff, sfn5122f_q_event_entry_size);
-        memset(d_user, 0 , sfn5122f_q_tx_user_desc_size);
         q->tx_head = (tx_head +1) % q->tx_size;
     }
 
@@ -556,74 +436,5 @@ static inline int sfn5122f_queue_add_txbuf(sfn5122f_queue_t* q,
     return 0;
 }
 
-static inline int sfn5122f_queue_add_txbuf_devif(sfn5122f_queue_t* q, 
-                                                 regionid_t rid,
-                                                 bufferid_t bid,
-                                                 lpaddr_t base,
-                                                 size_t len,
-                                                 uint64_t flags)
-{
-    struct devq_buf* buf;
-    sfn5122f_q_tx_ker_desc_t d;
-    size_t tail = q->tx_tail;
-
-    d = q->tx_ring.ker[tail];
-    buf = &q->tx_bufs[tail];
-   
-    bool last = flags & DEVQ_BUF_FLAG_TX_LAST;    
-    buf->rid = rid;
-    buf->bid = bid;
-    buf->addr = base;
-    buf->len = len;
-    buf->flags = flags;
-
-    sfn5122f_q_tx_ker_desc_tx_ker_buf_addr_insert(d, base);
-    sfn5122f_q_tx_ker_desc_tx_ker_byte_count_insert(d, len);
-    sfn5122f_q_tx_ker_desc_tx_ker_cont_insert(d, !last);
-    sfn5122f_q_tx_ker_desc_tx_ker_buf_region_insert(d, 0);
-
-    __sync_synchronize();
-    q->tx_tail = (tail + 1) % q->tx_size;
-    return 0;
-}
-
-
-static inline int sfn5122f_queue_add_user_txbuf_devif(sfn5122f_queue_t* q, 
-                                                      uint64_t buftbl_idx, 
-                                                      uint64_t offset,
-                                                      regionid_t rid,
-                                                      bufferid_t devq_bid,
-                                                      lpaddr_t base,
-                                                      size_t len,
-                                                      uint64_t flags)
-{
-    sfn5122f_q_tx_user_desc_t d;
-    struct devq_buf* buf;
-    size_t tail = q->tx_tail;
-
-    d = q->tx_ring.ker[tail];
-    buf = &q->tx_bufs[tail];
-   
-    bool last = flags & DEVQ_BUF_FLAG_TX_LAST;    
-    buf->rid = rid;
-    buf->bid = devq_bid;
-    buf->addr = base;
-    buf->len = len;
-    buf->flags = flags;
-
-    sfn5122f_q_tx_user_desc_tx_user_sw_ev_en_insert(d, 0);
-    sfn5122f_q_tx_user_desc_tx_user_cont_insert(d, !last);
-    sfn5122f_q_tx_user_desc_tx_user_byte_cnt_insert(d, len);
-    sfn5122f_q_tx_user_desc_tx_user_buf_id_insert(d, buftbl_idx);
-    sfn5122f_q_tx_user_desc_tx_user_byte_ofs_insert(d, offset);
-
-    __sync_synchronize();
-    q->tx_tail = (tail + 1) % q->tx_size;
-    return 0;
-}
-
-#endif //ndef SFN5122F_CHANNEL_H_
+#endif