network: replacing net_queue_manager with devif as a data path, still WIP so it'll...
authorAdam Turowski <adam.turowski@inf.ethz.ch>
Mon, 20 Mar 2017 13:35:20 +0000 (14:35 +0100)
committerAdam Turowski <adam.turowski@inf.ethz.ch>
Mon, 20 Mar 2017 13:35:20 +0000 (14:35 +0100)
Signed-off-by: Adam Turowski <adam.turowski@inf.ethz.ch>

30 files changed:
if/Hakefile
if/descq.if [moved from if/descq_ctrl.if with 57% similarity]
if/descq_data.if [deleted file]
include/barrelfish/domain.h
include/devif/backends/descq.h
include/devif/queue_interface.h
include/net_queue_manager/net_queue_manager.h
lib/barrelfish/domain.c
lib/barrelfish/waitset.c
lib/blk/blk_ahci/device_impl.c
lib/devif/backends/idc/Hakefile
lib/devif/backends/idc/desc_queue.c
lib/devif/backends/net/e10k/devif_backend_e10k.c
lib/devif/backends/net/solarflare/devif_backend_solarflare.c
lib/devif/queue_interface.c
lib/devif/queue_interface_internal.h
lib/lwip/Hakefile
lib/net_device_manager/Hakefile
lib/net_interfaces/Hakefile
lib/net_interfaces/interface_raw.c
lib/net_queue_manager/Hakefile
lib/net_queue_manager/net_soft_filters_srv_impl.c
lib/net_queue_manager/queue_manager.c
lib/net_queue_manager/queue_manager_local.h
tools/flounder/GCBackend.hs
tools/flounder/Local.hs
usr/device_managers/net_gen_dev/Hakefile
usr/drivers/e1000/e1000n.c
usr/tests/devif/idc_endpoint.c
usr/tests/devif/queue_interface.c

index f766813..d674a4f 100644 (file)
@@ -92,8 +92,7 @@
                "xomp_gateway",
                "sfn5122f",
                "sfn5122f_devif",
-               "descq_data",
-               "descq_ctrl"
+               "descq"
            ],
              arch <- allArchitectures
 ] ++
similarity index 57%
rename from if/descq_ctrl.if
rename to if/descq.if
index 01fe968..034557d 100644 (file)
@@ -9,17 +9,22 @@
 
 /*
  * This interface is used for the devif interface for communication between
- * domains.
+ * domains
  */
-interface descq_ctrl "Devif communication queue control path" {
-    
+interface descq "Devif communication queue" {
     // create and destroy a queue
-    rpc create_queue(in uint32 slots, in cap rx, in cap tx, out errval err);
+    rpc create_queue(in uint32 slots, in cap rx, in cap tx, in bool notifications, in uint8 role, out errval err, out uint64 queue_id);
     rpc destroy_queue(out errval err);
 
     // add a memory region to the buffer table
     rpc register_region(in cap cap, in uint32 rid, out errval err);
     rpc deregister_region(in uint32 rid, out errval err);
 
-    rpc control(in uint64 cmd, in uint64 value, out errval err);
+    rpc control(in uint64 cmd, in uint64 value, out uint64 result, out errval err);
+
+    message enqueue_buffer(uint32 region_id, uint64 offset, uint64 length,
+        uint64 valid_data, uint64 valid_length, uint64 flags, uint64 seq);
+
+    message enqueued();
+    message notify();
 };
diff --git a/if/descq_data.if b/if/descq_data.if
deleted file mode 100644 (file)
index 3afcadb..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2007-2011, 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.
- */
-
-/*
- * This interface is used for the devif interface for communication between
- * domains.
- */
-interface descq_data "Devif communication queue data path" {
-    
-    // create and destroy a queue
-    message notify();
-};
index 6910996..ff7e9ff 100644 (file)
@@ -41,6 +41,7 @@ domainid_t disp_get_domain_id(void);
 coreid_t disp_handle_get_core_id(dispatcher_handle_t handle);
 void set_monitor_binding(struct monitor_binding *b);
 struct monitor_binding *get_monitor_binding(void);
+struct waitset_chanstate *get_monitor_binding_chanstate(void);
 void set_monitor_blocking_binding(struct monitor_blocking_binding *st);
 struct monitor_blocking_binding *get_monitor_blocking_binding(void);
 void set_mem_client(struct mem_binding *st);
index e5e3cd2..bb4f6ef 100644 (file)
 
 struct descq;
 
-typedef errval_t (*descq_create_t) (struct descq *q);
+typedef errval_t (*descq_create_t) (struct descq *q, bool notifications, uint8_t role, uint64_t *queue_id);
 typedef errval_t (*descq_destroy_t) (struct descq *q);
 typedef errval_t (*descq_notify_t) (struct descq *q);
 typedef errval_t (*descq_register_t)(struct descq *q, struct capref cap,
                                     regionid_t region_id);
 typedef errval_t (*descq_deregister_t)(struct descq *q, regionid_t region_id);
-typedef errval_t (*descq_control_t)(struct descq *q, 
+typedef errval_t (*descq_control_t)(struct descq *q,
                                    uint64_t request,
-                                   uint64_t value);
+                                   uint64_t value,
+                                   uint64_t *result);
+typedef errval_t (*descq_enqueued_t)(struct descq* q);
 
 struct descq_func_pointer {
     descq_create_t create;
-    descq_create_t destroy;
+    descq_destroy_t destroy;
     descq_notify_t notify;
     descq_register_t reg;
     descq_deregister_t dereg;
@@ -53,6 +55,9 @@ errval_t descq_create(struct descq** q,
                       size_t slots,
                       char* name,
                       bool exp,
+                      bool notifications,
+                      uint8_t role,
+                      uint64_t *queue_id,
                       struct descq_func_pointer* f);
 
 /**
index c8c041f..25f332d 100644 (file)
@@ -22,10 +22,10 @@ struct region_pool;
 
 // For convinience reason buffer descritpion in one struct
 struct devq_buf{
-    genoffset_t offset; // 8 
+    genoffset_t offset; // 8
     genoffset_t length; // 16
-    genoffset_t valid_data; // 24 
-    genoffset_t valid_length; // 32 
+    genoffset_t valid_data; // 24
+    genoffset_t valid_length; // 32
     uint64_t flags; // 40
     regionid_t rid; // 44
 };
@@ -64,14 +64,14 @@ errval_t devq_enqueue(struct devq *q,
  * @brief dequeue a buffer from the device queue
  *
  * @param q             The device queue to call the operation on
- * @param region_id     Return pointer to the id of the memory 
+ * @param region_id     Return pointer to the id of the memory
  *                      region the buffer belongs to
  * @param region_offset Return pointer to the offset into the region where
  *                      this buffer starts.
  * @param lenght        Return pointer to the lenght of the dequeue buffer
  * @param valid_data    Return pointer to an offset into the buffer where the
  *                      valid data of this buffer starts
- * @param valid_length  Return pointer to the length of the valid data of 
+ * @param valid_length  Return pointer to the length of the valid data of
  *                      this buffer
  * @param misc_flags    Return value from other endpoint
  *
@@ -93,7 +93,7 @@ errval_t devq_dequeue(struct devq *q,
  */
 
 /**
- * @brief Add a memory region that can be used as buffers to 
+ * @brief Add a memory region that can be used as buffers to
  *        the device queue
  *
  * @param q              The device queue to call the operation on
@@ -109,10 +109,10 @@ errval_t devq_register(struct devq *q,
                        regionid_t* region_id);
 
 /**
- * @brief Remove a memory region 
+ * @brief Remove a memory region
  *
  * @param q              The device queue to call the operation on
- * @param region_id      The region id to remove from the device 
+ * @param region_id      The region id to remove from the device
  *                       queues memory
  * @param cap            The capability to the removed memory
  *
@@ -156,6 +156,10 @@ errval_t devq_prepare(struct devq *q);
  */
 errval_t devq_control(struct devq *q,
                       uint64_t request,
-                      uint64_t value);
+                      uint64_t value,
+                      uint64_t *result);
+
+void devq_set_state(struct devq *q, void *state);
+void * devq_get_state(struct devq *q);
 
 #endif /* QUEUE_INTERFACE_H_ */
index 2db06c6..072311d 100644 (file)
@@ -21,6 +21,7 @@
 #include <procon/procon.h>
 #include <barrelfish/net_constants.h>
 #include <net_interfaces/flags.h>
+#include <devif/queue_interface.h>
 
 /*****************************************************************
  * Constants:
@@ -57,7 +58,7 @@ struct filter {
 
 // State required in TX path to remember information about buffers
 struct buffer_state_metadata {
-    struct net_queue_manager_binding *binding;
+    struct devq *device_queue;
     uint64_t offset;
 //    uint64_t spp_index;
 //    uint64_t tx_pending;
@@ -73,7 +74,7 @@ struct bsm_queue {
 
 struct buffer_descriptor {
     uint64_t buffer_id;  // buffer identifier
-    struct net_queue_manager_binding *con; // binding to which buffer belongs
+    struct devq *device_queue; // device queue
     struct capref cap; // cap backing the buffer memory
 //    struct shared_pool_private *spp_prv; // shared producer consumer pool
 
@@ -132,9 +133,10 @@ struct client_closure {
     uint64_t rx_index;  // index of which is next slot to be received
 
     uint64_t queueid; // The queueid to which this buffer belongs
-    struct net_queue_manager_binding *app_connection; // Binding pointer to talk back
-    struct cont_queue *q; // Cont management queue to report events
-    uint64_t *queue;
+    struct devq *app_connection; // Application device queue
+    regionid_t region_id;
+    uint8_t role;  // Role of buffer (RX/TX)
+    uint64_t buffer_id;  // buffer identifier
 
     // Place to store data when there are multiple parts to the packet
     struct driver_buffer driver_buff_list[MAX_CHUNKS]; // list of already seen chunks
@@ -285,6 +287,11 @@ enum Recorded_Events {
 
 extern struct netbench_details *bm;
 
+struct net_soft_filter_state
+{
+    struct waitset_chanstate initialization_completed;
+};
+
 // **************************************
 // Use of optimised memcpy for SCC
 
index a882446..fd53c9c 100644 (file)
@@ -1152,6 +1152,11 @@ struct monitor_binding *get_monitor_binding(void)
     return disp->core_state.c.monitor_binding;
 }
 
+struct waitset_chanstate *get_monitor_binding_chanstate(void)
+{
+    struct monitor_binding *mb = get_monitor_binding();
+    return mb->get_receiving_chanstate(mb);
+}
 
 /**
  * \brief set the  blocking rpc monitor client binding on the dispatcher priv
index 2f9c55f..8e23d7a 100644 (file)
@@ -626,7 +626,7 @@ errval_t waitset_chan_register_disabled(struct waitset *ws,
     assert_disabled(chan->state == CHAN_UNREGISTERED);
 
     // this is probably insane! :)
-    assert_disabled(closure.handler != NULL);
+    // assert_disabled(closure.handler != NULL);
 
     // store closure
     chan->closure = closure;
index dda23ce..204d6ca 100644 (file)
@@ -110,8 +110,8 @@ errval_t ahci_destroy(struct ahci_queue *q)
     return SYS_ERR_OK;
 }
 
-static errval_t ahci_enqueue(struct devq *q, 
-                             regionid_t region_id, 
+static errval_t ahci_enqueue(struct devq *q,
+                             regionid_t region_id,
                              genoffset_t offset,
                              genoffset_t length,
                              genoffset_t valid_data,
@@ -148,7 +148,7 @@ static errval_t ahci_enqueue(struct devq *q,
     uint64_t block = flags_get_block(flags);
     bool write = flags_is_write(flags);
 
-    err = blk_ahci_port_dma_async(queue->port, slot, block, mem->paddr+offset, 
+    err = blk_ahci_port_dma_async(queue->port, slot, block, mem->paddr+offset,
                                   length, write);
     return err;
 }
@@ -233,7 +233,8 @@ static errval_t ahci_notify(struct devq *q)
     return SYS_ERR_OK;
 }
 
-static errval_t ahci_control(struct devq *q, uint64_t request, uint64_t value)
+static errval_t ahci_control(struct devq *q, uint64_t request, uint64_t value,
+                             uint64_t *result)
 {
     return SYS_ERR_OK;
 }
index 48fa452..a4a309e 100644 (file)
         target = "devif_backend_idc",
         cFiles = ["desc_queue.c"],
         addCFlags = [ "-DLIBRARY" ],
-        flounderBindings = ["descq_data", "descq_ctrl"],
-        flounderExtraBindings = [("descq_ctrl",["rpcclient"])],
-        flounderDefs = ["descq_data", "descq_ctrl"],
-        flounderExtraDefs = [("descq_ctrl",["rpcclient"])],
+        flounderBindings = ["descq"],
+        flounderDefs = ["descq"],
         addLibraries = libDeps ["devif_internal"]
     }
 ]
index d19c35a..ff93257 100644 (file)
 #include <barrelfish/nameservice_client.h>
 #include <devif/queue_interface.h>
 #include <devif/backends/descq.h>
-#include <if/descq_data_defs.h>
-#include <if/descq_ctrl_defs.h>
+#include <if/descq_defs.h>
 #include "../../queue_interface_internal.h"
 #include "descq_debug.h"
 
 
 struct __attribute__((aligned(DESCQ_ALIGNMENT))) desc {
-    genoffset_t offset; // 8 
-    genoffset_t length; // 16 
+    genoffset_t offset; // 8
+    genoffset_t length; // 16
     genoffset_t valid_data; // 24
     genoffset_t valid_length; // 32
     uint64_t flags; // 40
@@ -54,12 +53,16 @@ struct descq {
     union pointer* tx_seq_ack;
    
     // Flounder
-    struct descq_data_binding* data;
-    struct descq_ctrl_binding* ctrl;
-
+    struct descq_binding* binding;
+    bool local_bind;
+    bool lmp_bind;
+    bool ump_bind;
+    
     // linked list
     struct descq* next;
     uint64_t qid;
+    
+    bool notifications;
 };
 
 struct descq_endpoint_state {
@@ -73,7 +76,7 @@ struct descq_endpoint_state {
 
 
 /**
- * @brief Enqueue a descriptor (as seperate fields) 
+ * @brief Enqueue a descriptor (as seperate fields)
  *        into the descriptor queue
  *
  * @param q                     The descriptor queue
@@ -107,22 +110,25 @@ static errval_t descq_enqueue(struct devq* queue,
     q->tx_descs[head].valid_data = valid_data;
     q->tx_descs[head].valid_length = valid_length;
     q->tx_descs[head].flags = misc_flags;
-    q->tx_descs[head].seq = q->tx_seq;    
+    q->tx_descs[head].seq = q->tx_seq;
 
     // only write local head
     q->tx_seq++;
 
-    DESCQ_DEBUG("tx_seq=%lu tx_seq_ack=%lu \n", 
+    DESCQ_DEBUG("tx_seq=%lu tx_seq_ack=%lu \n",
                     q->tx_seq, q->tx_seq_ack->value);
+    // if (q->local_bind) {
+        q->binding->tx_vtbl.notify(q->binding, NOP_CONT);
+    // }
     return SYS_ERR_OK;
 }
 
 /**
- * @brief Dequeue a descriptor (as seperate fields) 
+ * @brief Dequeue a descriptor (as seperate fields)
  *        from the descriptor queue
  *
  * @param q                     The descriptor queue
- * @param region_id             Return pointer to the region id of 
+ * @param region_id             Return pointer to the region id of
  *                              the denqueued buffer
  * @param offset                Return pointer to the offset into the region
  *                              where the buffer resides
@@ -144,7 +150,7 @@ static errval_t descq_dequeue(struct devq* queue,
                               uint64_t* misc_flags)
 {
     struct descq* q = (struct descq*) queue;
-    uint64_t seq = q->rx_descs[q->rx_seq % q->slots].seq;   
+    uint64_t seq = q->rx_descs[q->rx_seq % q->slots].seq;
     
     if (!(q->rx_seq == seq)) {
         return DEVQ_ERR_QUEUE_EMPTY;
@@ -170,7 +176,7 @@ static void resend_notify(void* a)
 {
     errval_t err;
     struct descq* queue = (struct descq*) a;
-    err = queue->data->tx_vtbl.notify(queue->data, NOP_CONT);
+    err = queue->binding->tx_vtbl.notify(queue->binding, NOP_CONT);
 }
 
 static errval_t descq_notify(struct devq* q)
@@ -180,14 +186,14 @@ static errval_t descq_notify(struct devq* q)
     struct descq* queue = (struct descq*) q;
     /*
     DESCQ_DEBUG("start \n");
-    err = queue->ctrl->rpc_tx_vtbl.notify(queue->rpc, &err2);
+    err = queue->binding->rpc_tx_vtbl.notify(queue->rpc, &err2);
     err = err_is_fail(err) ? err : err2;
     DESCQ_DEBUG("end\n");
     */
-    err = queue->data->tx_vtbl.notify(queue->data, NOP_CONT);
+    err = queue->binding->tx_vtbl.notify(queue->binding, NOP_CONT);
     if (err_is_fail(err)) {
         while(err_is_fail(err)) {
-            err = queue->data->register_send(queue->data, get_default_waitset(), 
+            err = queue->binding->register_send(queue->binding, get_default_waitset(),
                                              MKCONT(resend_notify, queue));
             if (err_is_fail(err)) {
                 event_dispatch(get_default_waitset());
@@ -198,13 +204,13 @@ static errval_t descq_notify(struct devq* q)
 }
 
 static errval_t descq_control(struct devq* q, uint64_t cmd,
-                              uint64_t value)
+                              uint64_t value, uint64_t *result)
 {
     errval_t err, err2;
     struct descq* queue = (struct descq*) q;
 
     DESCQ_DEBUG("start \n");
-    err = queue->ctrl->rpc_tx_vtbl.control(queue->ctrl, cmd, value, &err2);
+    err = queue->binding->rpc_tx_vtbl.control(queue->binding, cmd, value, result, &err2);
     err = err_is_fail(err) ? err : err2;
     DESCQ_DEBUG("end\n");
     return err;
@@ -217,7 +223,7 @@ static errval_t descq_register(struct devq* q, struct capref cap,
     struct descq* queue = (struct descq*) q;
 
     DESCQ_DEBUG("start %p\n", queue);
-    err = queue->ctrl->rpc_tx_vtbl.register_region(queue->ctrl, cap, rid, &err2);
+    err = queue->binding->rpc_tx_vtbl.register_region(queue->binding, cap, rid, &err2);
     err = err_is_fail(err) ? err : err2;
     DESCQ_DEBUG("end\n");
     return err;
@@ -228,7 +234,7 @@ static errval_t descq_deregister(struct devq* q, regionid_t rid)
     errval_t err, err2;
     struct descq* queue = (struct descq*) q;
 
-    err = queue->ctrl->rpc_tx_vtbl.deregister_region(queue->ctrl, rid, &err2);
+    err = queue->binding->rpc_tx_vtbl.deregister_region(queue->binding, rid, &err2);
     err = err_is_fail(err) ? err : err2;
     return err;
 }
@@ -237,10 +243,9 @@ static errval_t descq_deregister(struct devq* q, regionid_t rid)
  * Flounder interface implementation
  */
 
-static void mp_notify(struct descq_data_binding* b) {
-    
+static void mp_notify(struct descq_binding* b) {
     DESCQ_DEBUG("start \n");
-    errval_t err;    
+    errval_t err;
     struct descq* q = (struct descq*) b->st;
 
     DESCQ_DEBUG("%p \n",q->f.notify);
@@ -251,87 +256,74 @@ static void mp_notify(struct descq_data_binding* b) {
 }
 
 
-static void mp_reg(struct descq_ctrl_binding* b, struct capref cap,
-                   uint32_t rid) 
+static errval_t mp_reg(struct descq_binding* b, struct capref cap,
+                   uint32_t rid, errval_t *err)
 {
     DESCQ_DEBUG("start \n");
-    errval_t err;    
-    struct descq* q = (struct descq*) b->st;    
+    struct descq* q = (struct descq*) b->st;
 
-    err = devq_add_region((struct devq*) q, cap, rid);
-    if (err_is_fail(err)) {
-        err = b->tx_vtbl.register_region_response(b, NOP_CONT, err);
-        assert(err_is_ok(err));
+    *err = devq_add_region((struct devq*) q, cap, rid);
+    if (err_is_fail(*err)) {
+        return SYS_ERR_OK;
     }
 
-    err = q->f.reg(q, cap, rid);
-
-    err = b->tx_vtbl.register_region_response(b, NOP_CONT, err);
+    *err = q->f.reg(q, cap, rid);
     DESCQ_DEBUG("end \n");
-    assert(err_is_ok(err));
+    return SYS_ERR_OK;
 }
 
-static void mp_dereg(struct descq_ctrl_binding* b, uint32_t rid) 
+static errval_t mp_dereg(struct descq_binding* b, uint32_t rid,
+                         errval_t *err)
 {
-    errval_t err;    
     struct descq* q = (struct descq*) b->st;
 
-    err = devq_remove_region((struct devq*) q, rid);
-    if (err_is_fail(err)) {
-        err = b->tx_vtbl.deregister_region_response(b, NOP_CONT, err);
-        assert(err_is_ok(err));
+    *err = devq_remove_region((struct devq*) q, rid);
+    if (err_is_fail(*err)) {
+        return SYS_ERR_OK;
     }
 
-    err = q->f.dereg(q, rid);
-
-    err = b->tx_vtbl.deregister_region_response(b, NOP_CONT, err);
-    assert(err_is_ok(err));
+    *err = q->f.dereg(q, rid);
+    return SYS_ERR_OK;
 }
 
-static void mp_control(struct descq_ctrl_binding* b, uint64_t cmd,
-                       uint64_t value) 
+static errval_t mp_control(struct descq_binding* b, uint64_t cmd,
+                       uint64_t value, uint64_t *result, errval_t *err)
 {
-    errval_t err;    
     struct descq* q = (struct descq*) b->st;
 
-    err = q->f.control(q, cmd, value);
-
-    err = b->tx_vtbl.control_response(b, NOP_CONT, err);
-    assert(err_is_ok(err));
+    *err = q->f.control(q, cmd, value, result);
+    return SYS_ERR_OK;
 }
 
-static void mp_destroy(struct descq_ctrl_binding* b) 
+static errval_t mp_destroy(struct descq_binding* b, errval_t *err)
 {
-    errval_t err;    
     struct descq* q = (struct descq*) b->st;
 
-    err = q->f.destroy(q);
+    *err = q->f.destroy(q);
     
     USER_PANIC("Destroy NYI \n");
-
-    err = b->tx_vtbl.destroy_queue_response(b, NOP_CONT, err);
-    assert(err_is_ok(err));
+    return SYS_ERR_OK;
 }
 
-static void mp_create(struct descq_ctrl_binding* b, uint32_t slots,
-                      struct capref rx, struct capref tx) {
+static errval_t mp_create(struct descq_binding* b, uint32_t slots,
+        struct capref rx, struct capref tx, bool notifications, uint8_t role,
+        uint64_t *queue_id, errval_t *err) {
     
     struct descq* q = (struct descq*) b->st;
     DESCQ_DEBUG("start %p\n",q);
-    errval_t err;    
     
     // switch RX/TX for correct setup
-    err = vspace_map_one_frame_attr((void**) &(q->rx_descs),
-                                    slots*DESCQ_ALIGNMENT, tx, 
+    *err = vspace_map_one_frame_attr((void**) &(q->rx_descs),
+                                    slots*DESCQ_ALIGNMENT, tx,
                                     VREGION_FLAGS_READ_WRITE, NULL, NULL);
-    if (err_is_fail(err)) {
+    if (err_is_fail(*err)) {
         goto end2;
     }
 
-    err = vspace_map_one_frame_attr((void**) &(q->tx_descs),
-                                    slots*DESCQ_ALIGNMENT, rx, 
+    *err = vspace_map_one_frame_attr((void**) &(q->tx_descs),
+                                    slots*DESCQ_ALIGNMENT, rx,
                                     VREGION_FLAGS_READ_WRITE, NULL, NULL);
-    if (err_is_fail(err)) {
+    if (err_is_fail(*err)) {
         goto end1;
     }
  
@@ -350,21 +342,20 @@ static void mp_create(struct descq_ctrl_binding* b, uint32_t slots,
     q->q.f.dereg = descq_deregister;
     q->q.f.ctrl = descq_control;
      
-    err = q->f.create(q);
-    if (err_is_ok(err)) {
+    *err = q->f.create(q, notifications, role, queue_id);
+    if (err_is_ok(*err)) {
         goto end2;
     }
 
 end1:
-    err = vspace_unmap(q->rx_descs);
-    assert(err_is_ok(err));
+    *err = vspace_unmap(q->rx_descs);
+    assert(err_is_ok(*err));
 end2:
-    err = b->tx_vtbl.create_queue_response(b, NOP_CONT, err);
-    assert(err_is_ok(err));
     DESCQ_DEBUG("end \n");
+    return SYS_ERR_OK;
 }
 
-static struct descq_ctrl_rx_vtbl ctrl_rx_vtbl = {
+static struct descq_rpc_rx_vtbl rpc_rx_vtbl = {
     .create_queue_call = mp_create,
     .destroy_queue_call = mp_destroy,
     .register_region_call = mp_reg,
@@ -372,51 +363,23 @@ static struct descq_ctrl_rx_vtbl ctrl_rx_vtbl = {
     .control_call = mp_control,
 };
 
-static struct descq_data_rx_vtbl data_rx_vtbl = {
+static struct descq_rx_vtbl rx_vtbl = {
     .notify = mp_notify,
 };
 
-static void ctrl_export_cb(void *st, errval_t err, iref_t iref)
+static void export_cb(void *st, errval_t err, iref_t iref)
 {
     struct descq_endpoint_state* q = (struct descq_endpoint_state*) st;
-    const char* suffix = "_ctrl";
-    char name[strlen(q->name)+strlen(suffix)+1];
-    
-    sprintf(name, "%s%s", q->name, suffix);
-    err = nameservice_register(name, iref);
+
+    err = nameservice_register(q->name, iref);
     assert(err_is_ok(err));
     q->exp_done = true;
     // state is only function pointers
     DESCQ_DEBUG("Control interface exported (%s)\n", name);
 }
 
-static void data_export_cb(void *st, errval_t err, iref_t iref)
+static errval_t connect_cb(void *st, struct descq_binding* b)
 {
-    struct descq_endpoint_state* q = (struct descq_endpoint_state*) st;
-    const char* suffix = "_data";
-    char name[strlen(q->name)+strlen(suffix)+1];
-    
-    sprintf(name, "%s%s", q->name, suffix);
-    err = nameservice_register(name, iref);
-    DESCQ_DEBUG("Data interface exported (%s)\n", name);
-    assert(err_is_ok(err));
-}
-
-static errval_t data_connect_cb(void *st, struct descq_data_binding* b)
-{
-
-    struct descq_endpoint_state* state = (struct descq_endpoint_state*) st;
-    struct descq* q = state->tail;
-    b->rx_vtbl = data_rx_vtbl;
-    b->st = q;
-    q->data = b;
-    DESCQ_DEBUG("New connection data %p q->data %p \n", q, q->data);
-    return SYS_ERR_OK;
-}
-
-static errval_t ctrl_connect_cb(void *st, struct descq_ctrl_binding* b)
-{
-    //errval_t err;
     struct descq* q;
     struct descq_endpoint_state* state = (struct descq_endpoint_state*) st;
     // Allocate state
@@ -424,7 +387,7 @@ static errval_t ctrl_connect_cb(void *st, struct descq_ctrl_binding* b)
     if (q == NULL) {
         return DEVQ_ERR_DESCQ_INIT;
     }
-    q->ctrl = b;
+    q->binding = b;
 
     q->qid = state->qid;
     state->qid++;
@@ -446,33 +409,32 @@ static errval_t ctrl_connect_cb(void *st, struct descq_ctrl_binding* b)
         state->tail = q;
     }
 
-    b->rx_vtbl = ctrl_rx_vtbl;
+    b->rpc_rx_vtbl = rpc_rx_vtbl;
+    b->rx_vtbl = rx_vtbl;
     b->st = q;
+    q->local_bind = b->local_binding != NULL;
+    // if (q->local_bind) {
+        q->ump_bind = false;
+        q->lmp_bind = false;
+    // } else {
+    //     q->ump_bind = b->get_receiving_chanstate(b)->chantype == CHANTYPE_UMP_IN;
+    //     q->lmp_bind = !q->ump_bind;
+    // }
 
     return SYS_ERR_OK;
 }
 
 
-static void ctrl_bind_cb(void *st, errval_t err, struct descq_ctrl_binding* b)
+static void bind_cb(void *st, errval_t err, struct descq_binding* b)
 
 {
 
     struct descq* q = (struct descq*) st;
-    DESCQ_DEBUG("Control interface bound \n");
-    q->ctrl = b;
-    descq_ctrl_rpc_client_init(q->ctrl);
+    DESCQ_DEBUG("Interface bound \n");
+    q->binding = b;
+    b->rx_vtbl = rx_vtbl;
+    descq_rpc_client_init(q->binding);
 
-    b->rx_vtbl = ctrl_rx_vtbl;
-    b->st = q;
-}
-
-static void data_bind_cb(void *st, errval_t err, struct descq_data_binding* b)
-
-{
-    struct descq* q = (struct descq*) st;
-    q->data = b;
-    b->rx_vtbl = data_rx_vtbl;
-    DESCQ_DEBUG("Data interface bound\n");
     q->bound_done = true;
     b->st = q;
 }
@@ -485,6 +447,9 @@ errval_t descq_create(struct descq** q,
                       size_t slots,
                       char* name,
                       bool exp,
+                      bool notifications,
+                      uint8_t role,
+                      uint64_t *queue_id,
                       struct descq_func_pointer* f)
 {
     DESCQ_DEBUG("create start\n");
@@ -496,14 +461,13 @@ errval_t descq_create(struct descq** q,
     // Init basic struct fields
     tmp = malloc(sizeof(struct descq));
     assert(tmp != NULL);
-    tmp->name = malloc(sizeof(strlen(name)));
+    tmp->name = strdup(name);
     assert(tmp->name != NULL);
-    strncpy(tmp->name, name, strlen(name));
 
-    if (exp) {
+    if (exp) {  // exporting
         struct descq_endpoint_state* state = malloc(sizeof(struct descq_endpoint_state));
-        state->name = malloc(sizeof(strlen(name)));
-        strncpy(state->name, name, strlen(name));
+        state->name = strdup(name);
+        assert(state->name);
 
         state->f.notify = f->notify;
         state->f.dereg = f->dereg;
@@ -512,13 +476,7 @@ errval_t descq_create(struct descq** q,
         state->f.destroy = f->destroy;
         state->f.control = f->control;
 
-        err = descq_data_export(state, data_export_cb, data_connect_cb, 
-                                get_default_waitset(), IDC_BIND_FLAGS_DEFAULT);
-        if (err_is_fail(err)) {
-            goto cleanup1;
-        }
-
-        err = descq_ctrl_export(state, ctrl_export_cb, ctrl_connect_cb, 
+        err = descq_export(state, export_cb, connect_cb,
                                 get_default_waitset(), IDC_BIND_FLAGS_DEFAULT);
         if (err_is_fail(err)) {
             goto cleanup1;
@@ -553,14 +511,14 @@ errval_t descq_create(struct descq** q,
         assert(bytes >= DESCQ_ALIGNMENT*slots);
 
         err = vspace_map_one_frame_attr((void**) &(tmp->rx_descs),
-                                        slots*DESCQ_ALIGNMENT, rx, 
+                                        slots*DESCQ_ALIGNMENT, rx,
                                         VREGION_FLAGS_READ_WRITE, NULL, NULL);
         if (err_is_fail(err)) {
             goto cleanup3;
         }
 
         err = vspace_map_one_frame_attr((void**) &(tmp->tx_descs),
-                                        slots*DESCQ_ALIGNMENT, tx, 
+                                        slots*DESCQ_ALIGNMENT, tx,
                                         VREGION_FLAGS_READ_WRITE, NULL, NULL);
         if (err_is_fail(err)) {
             goto cleanup4;
@@ -572,43 +530,33 @@ errval_t descq_create(struct descq** q,
         tmp->bound_done = false;
         iref_t iref;
 
-        const char *suffix_ctrl = "_ctrl";
-        char name_ctrl[strlen(name)+strlen(suffix_ctrl)+1];
-        sprintf(name_ctrl, "%s%s", name, suffix_ctrl);
-
-        err = nameservice_blocking_lookup(name_ctrl, &iref);
+        err = nameservice_blocking_lookup(name, &iref);
         if (err_is_fail(err)) {
             goto cleanup5;
         }
 
-        err = descq_ctrl_bind(iref, ctrl_bind_cb, tmp, get_default_waitset(),
+        err = descq_bind(iref, bind_cb, tmp, get_default_waitset(),
                               IDC_BIND_FLAGS_DEFAULT);
         if (err_is_fail(err)) {
             goto cleanup5;
         }
  
-        const char *suffix_data = "_data";
-        char name_data[strlen(name)+strlen(suffix_data)+1];
-        sprintf(name_data, "%s%s", name, suffix_data);
-        iref_t iref2;
-   
-        err = nameservice_blocking_lookup(name_data, &iref2);
-        if (err_is_fail(err)) {
-            goto cleanup5;
-        }
-    
-        err = descq_data_bind(iref2, data_bind_cb, tmp, get_default_waitset(),
-                              IDC_BIND_FLAGS_DEFAULT);
-        if (err_is_fail(err)) {
-            goto cleanup5;
-        }
-
         while(!tmp->bound_done) {
             event_dispatch(get_default_waitset());
         }
 
+        tmp->local_bind = tmp->binding->local_binding != NULL;
+        // if (tmp->local_bind) {
+            tmp->ump_bind = false;
+            tmp->lmp_bind = false;
+        // } else {
+        //     tmp->ump_bind = tmp->binding->get_receiving_chanstate(tmp->binding)->chantype == CHANTYPE_UMP_IN;
+        //     tmp->lmp_bind = !tmp->ump_bind;
+        // }
+        
         errval_t err2;
-        err = tmp->ctrl->rpc_tx_vtbl.create_queue(tmp->ctrl, slots, rx, tx, &err2);
+        err = tmp->binding->rpc_tx_vtbl.create_queue(tmp->binding, slots, rx, tx,
+            notifications, role, queue_id, &err2);
         if (err_is_fail(err) || err_is_fail(err2)) {
             err = err_is_fail(err) ? err: err2;
             goto cleanup5;
@@ -628,7 +576,8 @@ errval_t descq_create(struct descq** q,
         tmp->q.f.reg = descq_register;
         tmp->q.f.dereg = descq_deregister;
         tmp->q.f.ctrl = descq_control;
-
+        
+        tmp->notifications = notifications;
     }
 
 
@@ -638,9 +587,9 @@ errval_t descq_create(struct descq** q,
     return SYS_ERR_OK;
 
 cleanup5:
-    vspace_unmap(tmp->rx_descs);    
+    vspace_unmap(tmp->rx_descs);
 cleanup4:
-    vspace_unmap(tmp->rx_descs);    
+    vspace_unmap(tmp->rx_descs);
 cleanup3:
     cap_destroy(tx);
 cleanup2:
@@ -663,7 +612,7 @@ cleanup1:
  * @returns error on failure or SYS_ERR_OK on success
  */
 errval_t descq_destroy(struct descq* q)
-{   
+{
     errval_t err;
     err = vspace_unmap(q->tx_descs);
     if (err_is_fail(err)) {
index 47178e9..f60148b 100644 (file)
@@ -106,7 +106,7 @@ static errval_t enqueue_tx_buf(struct e10k_queue* q, regionid_t rid,
     DEBUG_QUEUE("Enqueueing TX buf \n");
 
     if (e10k_queue_free_txslots(q) == 0) {
-        DEBUG_QUEUE("e10k_%d: Not enough space in TX ring, not adding buffer\n", 
+        DEBUG_QUEUE("e10k_%d: Not enough space in TX ring, not adding buffer\n",
                 q->id);
         // TODO better error
         return NIC_ERR_ENQUEUE;
@@ -136,7 +136,7 @@ static errval_t enqueue_tx_buf(struct e10k_queue* q, regionid_t rid,
             lpaddr_t addr = 0;
             addr = (lpaddr_t) entry->virt + offset;
             e10k_queue_add_txbuf_ctx(q, addr, rid, offset, length,
-                                     valid_data, valid_length, flags, 
+                                     valid_data, valid_length, flags,
                                      first, last, length, 0, true, l4len !=0);
            } else {
 
@@ -147,7 +147,7 @@ static errval_t enqueue_tx_buf(struct e10k_queue* q, regionid_t rid,
             lpaddr_t addr = 0;
             addr = (lpaddr_t) entry->phys + offset;
             e10k_queue_add_txbuf_ctx(q, addr, rid, offset, length,
-                                     valid_data, valid_length, flags, 
+                                     valid_data, valid_length, flags,
                                      first, last, length, 0, true, l4len != 0);
         }
     } else {
@@ -159,7 +159,7 @@ static errval_t enqueue_tx_buf(struct e10k_queue* q, regionid_t rid,
             lpaddr_t addr = 0;
             addr = (lpaddr_t) entry->virt + offset;
             e10k_queue_add_txbuf(q, addr, rid, offset, length, valid_data,
-                                 valid_length, flags, 
+                                 valid_length, flags,
                                  first, last, length);
         } else {
             struct region_entry* entry = get_region(q, rid);
@@ -186,7 +186,7 @@ static errval_t enqueue_rx_buf(struct e10k_queue* q, regionid_t rid,
     DEBUG_QUEUE("Enqueueing RX buf \n");
     // check if there is space
     if (e10k_queue_free_rxslots(q) == 0) {
-        DEBUG_QUEUE("e10k_%d: Not enough space in RX ring, not adding buffer\n", 
+        DEBUG_QUEUE("e10k_%d: Not enough space in RX ring, not adding buffer\n",
                 q->id);
         // TODO better error
         return NIC_ERR_ENQUEUE;
@@ -237,7 +237,7 @@ static errval_t e10k_enqueue(struct devq* q, regionid_t rid, genoffset_t offset,
                              valid_length, flags);
         if (err_is_fail(err)) {
             return err;
-        }      
+        }
     } else if (flags & NETIF_TXFLAG) {
 
         assert(length <= 2048);
@@ -246,7 +246,7 @@ static errval_t e10k_enqueue(struct devq* q, regionid_t rid, genoffset_t offset,
                              valid_length, flags);
         if (err_is_fail(err)) {
             return err;
-        } 
+        }
     }
 
     return SYS_ERR_OK;
@@ -262,7 +262,7 @@ static errval_t e10k_dequeue(struct devq* q, regionid_t* rid,
     int last;
     errval_t err = SYS_ERR_OK;
 
-    if (!e10k_queue_get_rxbuf(que, rid, offset, length, valid_data, 
+    if (!e10k_queue_get_rxbuf(que, rid, offset, length, valid_data,
                              valid_length, flags, &last)) {
         err = DEVQ_ERR_QUEUE_EMPTY;
     } else {
@@ -279,7 +279,7 @@ static errval_t e10k_dequeue(struct devq* q, regionid_t* rid,
     return err;
 }
 
-static errval_t e10k_register(struct devq* q, struct capref cap, regionid_t rid) 
+static errval_t e10k_register(struct devq* q, struct capref cap, regionid_t rid)
 {
     errval_t err;
     struct e10k_queue* queue = (struct e10k_queue*) q;
@@ -302,7 +302,7 @@ static errval_t e10k_register(struct devq* q, struct capref cap, regionid_t rid)
     }
 
     void* va;
-    err = vspace_map_one_frame_attr(&va, id.bytes, cr, 
+    err = vspace_map_one_frame_attr(&va, id.bytes, cr,
                                     VREGION_FLAGS_READ_WRITE_NOCACHE,
                                     NULL, NULL);
     if (err_is_fail(err)) {
@@ -315,7 +315,7 @@ static errval_t e10k_register(struct devq* q, struct capref cap, regionid_t rid)
     entry->cap = cap;
     entry->phys = id.base;
     entry->virt = (lvaddr_t)va;
-    entry->size = id.bytes;     
+    entry->size = id.bytes;
     entry->next = NULL;
 
     // linked list of regions
@@ -334,12 +334,12 @@ static errval_t e10k_register(struct devq* q, struct capref cap, regionid_t rid)
     return SYS_ERR_OK;
 }
 
-static errval_t e10k_deregister(struct devq* q, regionid_t rid) 
+static errval_t e10k_deregister(struct devq* q, regionid_t rid)
 {
     return SYS_ERR_OK;
 }
 
-static errval_t e10k_control(struct devq* q, uint64_t cmd, uint64_t value)
+static errval_t e10k_control(struct devq* q, uint64_t cmd, uint64_t value, uint64_t *result)
 {
     return SYS_ERR_OK;
 }
@@ -396,7 +396,7 @@ static void connect_to_mngif(struct e10k_queue* q)
 }
 
 /*********************************************************
- * Queue creation and destruction 
+ * Queue creation and destruction
  */
 
 
@@ -407,7 +407,7 @@ errval_t e10k_queue_destroy(struct e10k_queue* queue)
 }
 
 static errval_t map_device_memory(struct e10k_queue* q,
-                                  struct capref regs) 
+                                  struct capref regs)
 {
 
     struct frame_identity id = {.base = 0, .bytes = 0};
@@ -419,8 +419,8 @@ static errval_t map_device_memory(struct e10k_queue* q,
     }
 
     void* va;
-    err = vspace_map_one_frame_attr(&va, id.bytes, regs, 
-                                    VREGION_FLAGS_READ_WRITE_NOCACHE, 
+    err = vspace_map_one_frame_attr(&va, id.bytes, regs,
+                                    VREGION_FLAGS_READ_WRITE_NOCACHE,
                                     NULL, NULL);
     if (err_is_fail(err)) {
         return err;
@@ -434,7 +434,7 @@ static errval_t map_device_memory(struct e10k_queue* q,
     return SYS_ERR_OK;
 }
 // TODO mostly cleanup when fail
-errval_t e10k_queue_create(struct e10k_queue** queue, e10k_event_cb_t cb, 
+errval_t e10k_queue_create(struct e10k_queue** queue, e10k_event_cb_t cb,
                            bool use_vf, bool interrupts)
 {
 
@@ -442,18 +442,18 @@ errval_t e10k_queue_create(struct e10k_queue** queue, e10k_event_cb_t cb,
     struct e10k_queue* q;
     // start VF driver
     
-    q = malloc(sizeof(struct e10k_queue));    
+    q = malloc(sizeof(struct e10k_queue));
     q->pci_function = 0; // TODO allow also function 1
 
     if (use_vf) {
         USER_PANIC("NOT YET WORKING \n");
         // Start VF
         if (!e10k_vf_started()) {
-            err = e10k_init_vf_driver(q->pci_function, interrupts); 
+            err = e10k_init_vf_driver(q->pci_function, interrupts);
             if (err_is_fail(err)) {
                 return err;
             }
-        }  
+        }
 
         // If i can not create any more queues -> start new VF
         if (!e10k_vf_can_create_queue()) {
@@ -506,7 +506,7 @@ errval_t e10k_queue_create(struct e10k_queue** queue, e10k_event_cb_t cb,
     void* txhwb_virt = NULL;
 #if 0
     if (use_txhwb) {
-        txhwb_virt = alloc_map_frame(VREGION_FLAGS_READ_WRITE, BASE_PAGE_SIZE, 
+        txhwb_virt = alloc_map_frame(VREGION_FLAGS_READ_WRITE, BASE_PAGE_SIZE,
         &txhwb_frame);
         if (txhwb_virt == NULL) {
             return DEVQ_ERR_INIT_QUEUE;
@@ -522,7 +522,7 @@ errval_t e10k_queue_create(struct e10k_queue** queue, e10k_event_cb_t cb,
     q->use_vf = use_vf;
     q->rx_frame = rx_frame;
     q->tx_frame = tx_frame;
-    q->txhwb_frame = txhwb_frame;    
+    q->txhwb_frame = txhwb_frame;
     q->use_irq = interrupts;
 
     // XXX:disable by default for now
@@ -553,10 +553,10 @@ errval_t e10k_queue_create(struct e10k_queue** queue, e10k_event_cb_t cb,
         }
 
         int q_id;
-        err = q->binding->rpc_tx_vtbl.create_queue(q->binding, tx_frame, txhwb_frame, 
-                                            rx_frame, 2048, q->msix_intvec, 
+        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);   
+                                            &regs);
         if (err_is_fail(err)) {
             return err;
         }
index 22c2e04..fdce6e2 100644 (file)
@@ -163,7 +163,7 @@ static errval_t sfn5122f_deregister(struct devq* q, regionid_t rid)
    
     // do rpc do inform carddriver to remove buftbl entries
     if (queue->userspace) {
-        err = queue->b->rpc_tx_vtbl.deregister_region(queue->b, cur->buftbl_idx, 
+        err = queue->b->rpc_tx_vtbl.deregister_region(queue->b, cur->buftbl_idx,
                                                       cur->size, &err2);
         if (err_is_fail(err) || err_is_fail(err2)) {
             err = err_is_fail(err) ? err: err2;
@@ -175,7 +175,7 @@ static errval_t sfn5122f_deregister(struct devq* q, regionid_t rid)
 }
 
 
-static errval_t sfn5122f_control(struct devq* q, uint64_t cmd, uint64_t value)
+static errval_t sfn5122f_control(struct devq* q, uint64_t cmd, uint64_t value, uint64_t *result)
 {
 
     DEBUG_QUEUE("Control cmd=%lu value=%lu \n", cmd, value);
@@ -281,7 +281,7 @@ static errval_t enqueue_tx_buf(struct sfn5122f_queue* q, regionid_t rid,
     } else {
 
         DEBUG_QUEUE("TX_BUF flags=%lu \n", flags);
-        sfn5122f_queue_add_txbuf_devif(q, entry->phys + offset, rid, offset, 
+        sfn5122f_queue_add_txbuf_devif(q, entry->phys + offset, rid, offset,
                                        length, valid_data, valid_length,
                                        flags);
     }
@@ -289,7 +289,7 @@ static errval_t enqueue_tx_buf(struct sfn5122f_queue* q, regionid_t rid,
     return SYS_ERR_OK;
 }
 
-static errval_t sfn5122f_enqueue(struct devq* q, regionid_t rid, 
+static errval_t sfn5122f_enqueue(struct devq* q, regionid_t rid,
                                  genoffset_t offset, genoffset_t length,
                                  genoffset_t valid_data, genoffset_t valid_length,
                                  uint64_t flags)
@@ -310,7 +310,7 @@ static errval_t sfn5122f_enqueue(struct devq* q, regionid_t rid,
     } else if (flags & NETIF_TXFLAG) {
         assert(length <= BASE_PAGE_SIZE);
 
-        err = enqueue_tx_buf(queue, rid, offset, length, valid_data, valid_length, 
+        err = enqueue_tx_buf(queue, rid, offset, length, valid_data, valid_length,
                              flags);
         if (err_is_fail(err)) {
             return err;
@@ -350,7 +350,7 @@ static errval_t sfn5122f_dequeue(struct devq* q, regionid_t* rid, genoffset_t* o
         case EV_CODE_RX:
             // TODO multiple packets
             err = sfn5122f_queue_handle_rx_ev_devif(queue, rid, offset, length,
-                                                    valid_data, valid_length, 
+                                                    valid_data, valid_length,
                                                     flags);
             if (err_is_ok(err)) {
                 DEBUG_QUEUE(" RX_EV Q_ID: %d len %ld \n", queue->id, *length);
@@ -490,8 +490,8 @@ errval_t sfn5122f_queue_create(struct sfn5122f_queue** q, sfn5122f_event_cb_t cb
 
     if (!interrupts) {
         printf("Solarflare queue used in polling mode \n");
-        err = queue->b->rpc_tx_vtbl.create_queue(queue->b, frame, userlevel, 
-                                                 interrupts, 
+        err = queue->b->rpc_tx_vtbl.create_queue(queue->b, frame, userlevel,
+                                                 interrupts,
                                                  0, 0, &queue->id, &regs, &err2);
         if (err_is_fail(err) || err_is_fail(err2)) {
             err = err_is_fail(err) ? err: err2;
index 63573d1..01646f9 100644 (file)
@@ -52,7 +52,7 @@ errval_t devq_enqueue(struct devq *q,
     errval_t err;
     
     // check if the buffer to enqueue is valid
-    if (!region_pool_buffer_check_bounds(q->pool, region_id, offset, 
+    if (!region_pool_buffer_check_bounds(q->pool, region_id, offset,
         length, valid_data, valid_length)) {
         return DEVQ_ERR_INVALID_BUFFER_ARGS;
     }
@@ -61,7 +61,7 @@ errval_t devq_enqueue(struct devq *q,
     err = q->f.enq(q, region_id, offset, length, valid_data,
                    valid_length, misc_flags);
 
-    DQI_DEBUG("Enqueue q=%p rid=%d, offset=%lu, lenght=%lu, err=%s \n", 
+    DQI_DEBUG("Enqueue q=%p rid=%d, offset=%lu, lenght=%lu, err=%s \n",
               q, region_id, offset, length, err_getstring(err));
 
     return err;
@@ -71,14 +71,14 @@ errval_t devq_enqueue(struct devq *q,
  * @brief dequeue a buffer from the device queue
  *
  * @param q             The device queue to call the operation on
- * @param region_id     Return pointer to the id of the memory 
+ * @param region_id     Return pointer to the id of the memory
  *                      region the buffer belongs to
  * @param region_offset Return pointer to the offset into the region where
  *                      this buffer starts.
  * @param lenght        Return pointer to the lenght of the dequeue buffer
  * @param valid_data    Return pointer to an offset into the region where the
  *                      valid data of this buffer starts
- * @param valid_length  Return pointer to the length of the valid data of 
+ * @param valid_length  Return pointer to the length of the valid data of
  *                      this buffer
  * @param misc_flags    Return value from other endpoint
  *
@@ -106,7 +106,7 @@ errval_t devq_dequeue(struct devq *q,
     }
 
     // check if the dequeue buffer is valid
-    if (!region_pool_buffer_check_bounds(q->pool, *region_id, *offset, 
+    if (!region_pool_buffer_check_bounds(q->pool, *region_id, *offset,
         *length, *valid_data, *valid_length)) {
         return DEVQ_ERR_INVALID_BUFFER_ARGS;
     }
@@ -119,11 +119,11 @@ errval_t devq_dequeue(struct devq *q,
 /*
  * ===========================================================================
  * Control Path
- * =========================================================================== 
+ * ===========================================================================
 */
 
 /**
- * @brief Add a memory region that can be used as buffers to 
+ * @brief Add a memory region that can be used as buffers to
  *        the device queue
  *
  * @param q              The device queue to call the operation on
@@ -140,24 +140,24 @@ errval_t devq_register(struct devq *q,
 {
     errval_t err;
 
-    err = region_pool_add_region(q->pool, cap, region_id); 
+    err = region_pool_add_region(q->pool, cap, region_id);
     if (err_is_fail(err)) {
         return err;
     }
 
-    DQI_DEBUG("register q=%p, cap=%p, regionid=%d \n", (void*) q, 
+    DQI_DEBUG("register q=%p, cap=%p, regionid=%d \n", (void*) q,
               (void*) &cap, *region_id);
 
-    err = q->f.reg(q, cap, *region_id);   
+    err = q->f.reg(q, cap, *region_id);
 
     return err;
 }
 
 /**
- * @brief Remove a memory region 
+ * @brief Remove a memory region
  *
  * @param q              The device queue to call the operation on
- * @param region_id      The region id to remove from the device 
+ * @param region_id      The region id to remove from the device
  *                       queues memory
  * @param cap            The capability to the removed memory
  *
@@ -170,14 +170,14 @@ errval_t devq_deregister(struct devq *q,
 {
     errval_t err;
     
-    err = region_pool_remove_region(q->pool, region_id, cap); 
+    err = region_pool_remove_region(q->pool, region_id, cap);
     if (err_is_fail(err)) {
         return err;
     }
-    DQI_DEBUG("deregister q=%p, cap=%p, regionid=%d \n", (void*) q, 
+    DQI_DEBUG("deregister q=%p, cap=%p, regionid=%d \n", (void*) q,
               (void*) cap, region_id);
     
-    err = q->f.dereg(q, region_id);   
+    err = q->f.dereg(q, region_id);
 
     return err;
 }
@@ -227,13 +227,23 @@ errval_t devq_prepare(struct devq *q)
  */
 errval_t devq_control(struct devq *q,
                       uint64_t request,
-                      uint64_t value)
+                      uint64_t value,
+                      uint64_t *result)
 {
     errval_t err;
 
-    err = q->f.ctrl(q, request, value);
+    err = q->f.ctrl(q, request, value, result);
 
     return err;
 
 }
 
+void devq_set_state(struct devq *q, void *state)
+{
+    q->state = state;
+}
+
+void * devq_get_state(struct devq *q)
+{
+    return q->state;
+}
index edec46c..e23d801 100644 (file)
@@ -70,7 +70,8 @@ typedef errval_t (*devq_deregister_t)(struct devq *q, regionid_t region_id);
   */
 typedef errval_t (*devq_control_t)(struct devq *q,
                                    uint64_t request,
-                                   uint64_t value);
+                                   uint64_t value,
+                                   uint64_t *result);
 
 
  /**
@@ -83,13 +84,13 @@ typedef errval_t (*devq_control_t)(struct devq *q,
   * @param length       Length of the buffer
   * @param valid_data   Offset into the region where the valid data of the
   *                     buffer starts
-  * @param valid_length Length of the valid data in this buffer   
+  * @param valid_length Length of the valid data in this buffer
   * @param misc_flags   Misc flags
   *
   * @returns error on failure or SYS_ERR_OK on success
   */
 typedef errval_t (*devq_enqueue_t)(struct devq *q, regionid_t region_id,
-                                   genoffset_t offset, genoffset_t length, 
+                                   genoffset_t offset, genoffset_t length,
                                    genoffset_t valid_offset,
                                    genoffset_t valid_length,
                                    uint64_t misc_flags);
@@ -112,7 +113,7 @@ typedef errval_t (*devq_enqueue_t)(struct devq *q, regionid_t region_id,
   * @returns error on failure if the queue is empty or SYS_ERR_OK on success
   */
 typedef errval_t (*devq_dequeue_t)(struct devq *q, regionid_t* region_id,
-                                   genoffset_t* offset, genoffset_t* length, 
+                                   genoffset_t* offset, genoffset_t* length,
                                    genoffset_t* valid_offset,
                                    genoffset_t* valid_length,
                                    uint64_t* misc_flags);
@@ -141,6 +142,7 @@ struct devq {
        has to be handeled differently in the bookkeeping part
     */
     bool exp;
+    void *state;
 };
 
 
index 2b06641..b3cd054 100644 (file)
@@ -21,11 +21,9 @@ in
                     flounderBindings = [ "net_queue_manager", "net_ports",
                                 "net_ARP" ],
                     omitCFlags = [ "-Werror" ],
-                    flounderExtraBindings = [ ("net_ports", ["rpcclient"]),
-                     ("net_ARP", ["rpcclient"]) ],
                     addCFlags =  [ "-Wno-redundant-decls",
                                    "-DBF_LWIP_CHAN_SUPPORT" ],
                     addIncludes = [ "src/barrelfish" ],
-                    addLibraries = [ "netbench", "procon"]
+                    addLibraries = [ "netbench", "procon", "net_if_raw" ]
                   }
   ]
index 48e5d3b..42d5d3e 100644 (file)
 
 [ build library { target = "net_device_manager",
                   cFiles = [ "port_service_impl.c", "device_manager.c",
-                  "soft_filt_cl_impl.c", "e10k_filt_cl_impl.c", 
+                  "soft_filt_cl_impl.c", "e10k_filt_cl_impl.c",
                   "sfn5122f_filt_cl_impl.c", "portalloc.c" ],
                   flounderBindings = [ "net_soft_filters", "net_ports",
                                        "e10k", "sfn5122f" ],
-                  flounderExtraBindings = [ ("net_soft_filters", ["rpcclient"])],
-                  addLibraries = [ "bfdmuxtools", "trace"
--- try to get rid of "lwip" as it is only used for hton[s/l]
-                    , "lwip"
-                  ]
+                  addLibraries = [ "bfdmuxtools", "trace" ]
                  }
 ]
 
index f666a01..9ba5394 100644 (file)
@@ -12,7 +12,6 @@
 
 [ build library { target = "net_if_raw",
                   cFiles = [ "interface_raw.c" ],
-                  flounderBindings = [ "net_queue_manager" ],
-                  flounderExtraBindings = [("net_queue_manager", ["rpcclient"])] }
+                  addLibraries = libDeps [ "devif", "devif_backend_idc" ] }
 ]
 
index 09e5ff4..e6a9aca 100644 (file)
 #include <net_interfaces/net_interfaces.h>
 
 #include <barrelfish/net_constants.h>
-#include <if/net_queue_manager_defs.h>
+#include <devif/queue_interface.h>
+#include <devif/backends/descq.h>
 
 #define MAX_SERVICE_NAME_LEN  256   // Max len that a name of service can have
 #define BUFFER_SIZE 2048
 #define BUFFER_COUNT ((128*1024*1024) / BUFFER_SIZE)
 
-#define QUEUE_SIZE 2048
-
-static errval_t idc_raw_add_buffer(struct net_queue_manager_binding *binding,
-                               uint64_t *queue, uint64_t offset, uint64_t len,
-                               uint64_t more_chunks, uint64_t flags,
-                               bool blocking);
-
-static uint64_t queue = 0;
+static uint64_t queue_id = 0;
 static uint64_t card_mac = -1ULL;
 
-static struct net_queue_manager_binding *binding_rx = NULL;
-static uint64_t bufid_rx = -1ULL;
+static struct descq *devq_rx = NULL;
+static uint64_t bufid_rx;
+static regionid_t regid_rx;
 
-static struct net_queue_manager_binding *binding_tx = NULL;
-static uint64_t bufid_tx = -1ULL;
+static struct descq *devq_tx = NULL;
+static uint64_t bufid_tx;
+static regionid_t regid_tx;
 
 static struct capref buffer_frame;
 void *buffer_base = NULL;
 size_t buffer_size = 2048;
 size_t buffer_count = BUFFER_COUNT;
 
-static struct capref rx_queue_frame;
-uint64_t *rx_queue_base = NULL;
-static struct capref tx_queue_frame;
-uint64_t *tx_queue_base = NULL;
-
-static void init_queue(uint64_t *q)
-{
-    q[0] = 1;
-    q[1] = 1;
-    q[2] = 0;
-    q[3] = 0;
-}
-
-static int put_to_queue(uint64_t *q, uint64_t v1, uint64_t v2, uint64_t v3, uint64_t v4)
-{
-    uint64_t start = q[0];
-    uint64_t end = q[1];
-
-    if (end == (QUEUE_SIZE - 1)) {
-        assert(start > 1);
-    } else {
-        assert((end + 1) != start);
-    }
-
-    q[4 * end] = v1;
-    q[4 * end + 1] = v2;
-    q[4 * end + 2] = v3;
-    q[4 * end + 3] = v4;
-    bool s = start == end;
-    if (end == (QUEUE_SIZE - 1))
-        q[1] = 1;
-    else
-        q[1]++;
-    end = q[1];
-    bool f = (end == (QUEUE_SIZE - 1)) ? (start == 1): (start == end + 1);
-    return s + 2 * f;
-}
-
-static bool check_queue(uint64_t *q)
-{
-    uint64_t start = q[0];
-    uint64_t end = q[1];
-
-    return start != end;
-}
-
-static bool get_from_queue(uint64_t *q, uint64_t *v1, uint64_t *v2, uint64_t *v3, uint64_t *v4)
-{
-    uint64_t start = q[0];
-    uint64_t end = q[1];
-
-    assert(start != end);
-    *v1 = q[4 * start];
-    *v2 = q[4 * start + 1];
-    *v3 = q[4 * start + 2];
-    *v4 = q[4 * start + 3];
-    if (start == (QUEUE_SIZE - 1))
-        q[0] = 1;
-    else
-        q[0]++;
-    return !q[2];
-}
-
-static errval_t register_buffer(struct net_queue_manager_binding *b, struct capref buf, struct capref sp, uint64_t queueid, uint64_t slots, uint8_t role, struct capref queue_cap, uint64_t *idx)
-{
-    errval_t _err = SYS_ERR_OK;
-    b->error = SYS_ERR_OK;
-    thread_set_outgoing_token(thread_set_token(b->message_chanstate + net_queue_manager_register_buffer_response__msgnum));
-    _err = b->tx_vtbl.register_buffer_call(b, BLOCKING_CONT, buf, sp, queueid, slots, role, queue_cap);
-    if (err_is_fail(_err))
-        goto out;
-    _err = wait_for_channel(get_default_waitset(), b->message_chanstate + net_queue_manager_register_buffer_response__msgnum, &b->error);
-    if (err_is_fail(_err))
-        goto out;
-    *idx = b->rx_union.register_buffer_response.idx;
-    _err = b->receive_next(b);
-out:
-    thread_clear_token(b->get_receiving_chanstate(b));
-    return(_err);
-}
-
-static errval_t get_mac_address(struct net_queue_manager_binding *b, uint64_t queueid, uint64_t *hwaddr)
-{
-    errval_t _err = SYS_ERR_OK;
-    b->error = SYS_ERR_OK;
-    thread_set_outgoing_token(thread_set_token(b->message_chanstate + net_queue_manager_get_mac_address_response__msgnum));
-    _err = b->tx_vtbl.get_mac_address_call(b, BLOCKING_CONT, queueid);
-    if (err_is_fail(_err))
-        goto out;
-    _err = wait_for_channel(get_default_waitset(), b->message_chanstate + net_queue_manager_get_mac_address_response__msgnum, &b->error);
-    if (err_is_fail(_err))
-        goto out;
-    *hwaddr = b->rx_union.get_mac_address_response.hwaddr;
-    _err = b->receive_next(b);
-out:
-    thread_clear_token(b->get_receiving_chanstate(b));
-    return(_err);
-}
 
 /******************************************************************************/
 /* Buffer management */
 
-errval_t buffer_tx_add(size_t idx, size_t offset, size_t len,
+errval_t buffer_tx_add(size_t idx, size_t offset, size_t length,
                        size_t more_chunks, uint64_t flags)
 {
-
-    errval_t err = SYS_ERR_OK;
-    err = idc_raw_add_buffer(binding_tx, tx_queue_base, idx * BUFFER_SIZE + offset, len,
-            (uint64_t)more_chunks, flags, 0);
+    errval_t err;
+    
+    offset += idx * BUFFER_SIZE;
+    err = devq_enqueue((struct devq *)devq_tx, regid_tx, offset, length, 0, 0, flags);
+    assert(err_is_ok(err));
     return err;
 }
 
 errval_t buffer_rx_add(size_t idx)
 {
-
-    errval_t err = SYS_ERR_OK;
-    err = idc_raw_add_buffer(binding_rx, rx_queue_base, idx * BUFFER_SIZE, BUFFER_SIZE, 0, 0, 0);
+    errval_t err;
+    size_t offset;
+    
+    offset = idx * BUFFER_SIZE;
+    err = devq_enqueue((struct devq *)devq_rx, regid_rx, offset, BUFFER_SIZE, 0, 0, 0);
+    assert(err_is_ok(err));
     return err;
 }
 
@@ -187,26 +89,10 @@ static void alloc_mem(struct capref *frame, void** virt, size_t size)
 static void buffers_init(size_t count)
 {
     alloc_mem(&buffer_frame, &buffer_base, BUFFER_SIZE * count);
-
     errval_t err;
-    void *va;
-
-    alloc_mem(&rx_queue_frame, &va, QUEUE_SIZE * 4 * sizeof(uint64_t) * 2);
-    rx_queue_base = va;
-    alloc_mem(&tx_queue_frame, &va, QUEUE_SIZE * 4 * sizeof(uint64_t) * 2);
-    tx_queue_base = va;
-    memset(rx_queue_base, 0, QUEUE_SIZE * 4 * sizeof(uint64_t) * 2);
-    memset(tx_queue_base, 0, QUEUE_SIZE * 4 * sizeof(uint64_t) * 2);
-    init_queue(rx_queue_base);
-    init_queue(rx_queue_base + QUEUE_SIZE * 4);
-    init_queue(tx_queue_base);
-    init_queue(tx_queue_base + QUEUE_SIZE * 4);
-
-    err = register_buffer(binding_rx, buffer_frame, NULL_CAP, queue, count,
-        RX_BUFFER_ID, rx_queue_frame, &bufid_rx);
+    err = devq_register((struct devq *)devq_rx, buffer_frame, &regid_rx);
     assert(err_is_ok(err));
-    err = register_buffer(binding_tx, buffer_frame, NULL_CAP, queue, count,
-        TX_BUFFER_ID, tx_queue_frame, &bufid_tx);
+    err = devq_register((struct devq *)devq_tx, buffer_frame, &regid_tx);
     assert(err_is_ok(err));
 }
 
@@ -214,26 +100,6 @@ static void buffers_init(size_t count)
 /******************************************************************************/
 /* Flounder interface */
 
-static errval_t idc_raw_add_buffer(struct net_queue_manager_binding *binding, uint64_t *q,
-                               uint64_t offset, uint64_t len,
-                               uint64_t more_chunks, uint64_t flags, bool blocking)
-{
-    int r;
-    r = put_to_queue(q, offset, len, more_chunks, flags);
-    if (r) {
-        if (r == 2) {//} || binding == binding_tx) {
-            binding->control(binding, IDC_CONTROL_SET_SYNC);
-        }
-        errval_t err = binding->tx_vtbl.raw_add_buffer(binding, BLOCKING_CONT, offset, len, more_chunks, flags);
-        assert(err_is_ok(err));
-        if (r == 2) {//} || binding == binding_tx)
-            binding->control(binding, IDC_CONTROL_CLEAR_SYNC);
-        }
-    }
-    return SYS_ERR_OK;
-}
-
-
 // Returns the bufferid for specified type (RX, TX)
 uint64_t get_rx_bufferid(void)
 {
@@ -245,69 +111,62 @@ uint64_t get_tx_bufferid(void)
     return bufid_tx;
 }
 
-static void raw_xmit_done(struct net_queue_manager_binding *st,
-                          uint64_t offset, uint64_t len, uint64_t more,
-                          uint64_t flags)
-{
-    if (st == binding_rx) {
-        for (;;) {
-            bool c = check_queue(rx_queue_base + QUEUE_SIZE * 4);
-            if (c) {
-                get_from_queue(rx_queue_base + QUEUE_SIZE * 4, &offset, &len, &more, &flags);
-                size_t idx = offset / BUFFER_SIZE;
-                benchmark_rx_done(idx, len, more, flags);
-            } else
-                break;
-        }
-    } else {
-        for (;;) {
-            bool c = check_queue(tx_queue_base + QUEUE_SIZE * 4);
-            if (c) {
-                get_from_queue(tx_queue_base + QUEUE_SIZE * 4, &offset, &len, &more, &flags);
-                size_t idx = offset / BUFFER_SIZE;
-                benchmark_tx_done(idx);
-            } else
-                break;
-        }
-    }
-}
-
-static struct net_queue_manager_rx_vtbl rx_vtbl = {
-    .raw_xmit_done = raw_xmit_done,
-};
-
-
-static void bind_cb_rx(void *st, errval_t err, struct net_queue_manager_binding *b)
+static errval_t notify_rx(struct descq *queue)
 {
-    assert(err_is_ok(err));
+    regionid_t rid;
+    genoffset_t offset;
+    genoffset_t length;
+    genoffset_t valid_data;
+    genoffset_t valid_length;
+    uint64_t flags;
 
-    b->rx_vtbl = rx_vtbl;
-    b->control(b, IDC_CONTROL_CLEAR_SYNC);
-    binding_rx = b;
+    for (;;) {
+        errval_t err;
+        err = devq_dequeue((struct devq *)queue, &rid, &offset, &length,
+                           &valid_data, &valid_length, &flags);
+        if (err_is_fail(err))
+            break;
+        size_t idx = offset / BUFFER_SIZE;
+        benchmark_rx_done(idx, length, 0/*more*/, flags);
+    }
+    return SYS_ERR_OK;
 }
 
-static void bind_cb_tx(void *st, errval_t err, struct net_queue_manager_binding *b)
+static errval_t notify_tx(struct descq *queue)
 {
-    assert(err_is_ok(err));
+    regionid_t rid;
+    genoffset_t offset;
+    genoffset_t length;
+    genoffset_t valid_data;
+    genoffset_t valid_length;
+    uint64_t flags;
 
-    b->rx_vtbl = rx_vtbl;
-    b->control(b, IDC_CONTROL_CLEAR_SYNC);
-    binding_tx = b;
+    for (;;) {
+        errval_t err;
+        err = devq_dequeue((struct devq *)queue, &rid, &offset, &length,
+                           &valid_data, &valid_length, &flags);
+        if (err_is_fail(err))
+            break;
+        size_t idx = offset / BUFFER_SIZE;
+        benchmark_tx_done(idx);
+    }
+    return SYS_ERR_OK;
 }
 
-
 static void connect_to_driver(const char *cname, uint64_t qid, bool isRX, struct waitset *ws)
 {
     errval_t err;
-    iref_t iref;
     char qm_name[MAX_SERVICE_NAME_LEN] = { 0 };
 
     snprintf(qm_name, sizeof(qm_name), "%s_%"PRIu64"", cname, qid);
-    err = nameservice_blocking_lookup(qm_name, &iref);
-    assert(err_is_ok(err));
-
-    err = net_queue_manager_bind(iref, isRX ? bind_cb_rx: bind_cb_tx, NULL, ws,
-            IDC_BIND_FLAGS_DEFAULT);
+    debug_printf("%s: nqm bind [%s]\n", __func__, qm_name);
+
+    struct descq_func_pointer f;
+    f.notify = isRX ? notify_rx: notify_tx;
+    
+    debug_printf("Descriptor queue test started \n");
+    err = descq_create(isRX ? &devq_rx: &devq_tx, DESCQ_DEFAULT_SIZE, qm_name,
+                       false, true, !isRX, isRX ? &bufid_rx: &bufid_tx, &f);
     assert(err_is_ok(err));
 }
 
@@ -321,21 +180,17 @@ void net_if_init(const char* cardname, uint64_t qid)
         return;
     }
 
-    queue = qid;
+    queue_id = qid;
 
     // Connect RX path
-    connect_to_driver(cardname, queue, true, ws);
+    connect_to_driver(cardname, queue_id, true, ws);
     // Connect TX path
-    connect_to_driver(cardname, queue, false, ws);
-
-    while (binding_rx == NULL  || binding_tx == NULL) {
-        event_dispatch(ws);
-    }
-
+    connect_to_driver(cardname, queue_id, false, ws);
     buffers_init(BUFFER_COUNT);
 
     // Get MAC address
-    errval_t err = get_mac_address(binding_rx, queue, &card_mac);
+    errval_t err;
+    err = devq_control((struct devq *)devq_rx, 0, 0, &card_mac);
     assert(err_is_ok(err));
 
     initialized = true;
index cbe32d9..45ac30d 100644 (file)
@@ -16,6 +16,5 @@
                   flounderDefs = [ "net_queue_manager"],
                   flounderBindings = [ "net_queue_manager",
                                        "net_soft_filters" ],
-                  flounderExtraBindings = [ ("net_soft_filters", ["rpcclient"]) ],
-                  addLibraries = [ "procon", "netbench", "bfdmuxvm", "trace"] }
+                  addLibraries = [ "procon", "netbench", "bfdmuxvm", "trace", "devif", "devif_backend_idc" ] }
 ]
index 7ef3559..cbc09fa 100644 (file)
@@ -20,6 +20,7 @@
 #include <barrelfish/barrelfish.h>
 #include <barrelfish/nameservice_client.h>
 #include <barrelfish/net_constants.h>
+#include <barrelfish/waitset_chan.h>
 
 #include <stdio.h>
 #include <string.h>
@@ -108,7 +109,8 @@ static uint64_t filter_id_counter = 0;
 static void export_soft_filters_cb(void *st, errval_t err, iref_t iref)
 {
     char service_name[MAX_NET_SERVICE_NAME_LEN];
-
+    struct net_soft_filter_state *state = st;
+    
     snprintf(service_name, sizeof(service_name), "%s%s", sf_srv_name,
              FILTER_SERVICE_SUFFIX);
     if (err_is_fail(err)) {
@@ -124,6 +126,7 @@ static void export_soft_filters_cb(void *st, errval_t err, iref_t iref)
         DEBUG_ERR(err, "nameservice_register failed for [%s]", service_name);
         abort();
     }
+    waitset_chan_trigger(&state->initialization_completed);
 }
 
 static errval_t connect_soft_filters_cb(void *st,
@@ -517,9 +520,9 @@ static errval_t pause_filter(struct net_soft_filters_binding *cc, uint64_t filte
         for (int i = 0; i < rx_filter->pause_bufpos; i++) {
             struct bufdesc *bd = &rx_filter->pause_buffer[i];
 
-            struct net_queue_manager_binding *b = rx_filter->buffer->con;
-            assert(b != NULL);
-            struct client_closure *cl = (struct client_closure *)b->st;
+            struct devq *q = rx_filter->buffer->device_queue;
+            assert(q != NULL);
+            struct client_closure *cl = devq_get_state(q);
             assert(cl != NULL);
             copy_packet_to_user(rx_filter->buffer, bd->pkt_data, bd->pkt_len,
                     bd->flags);
@@ -581,12 +584,12 @@ static void send_arp_to_all(void *data, uint64_t len, uint64_t flags)
 
     /* FIXME: this code will send two copies or ARP if there are two filters
      * registered, which is incorrect.  Fix it. */
-    struct net_queue_manager_binding *b = NULL;
+    struct devq *q = NULL;
     struct client_closure *cl = NULL;
     while (head) {
-        b = head->buffer->con;
-        assert(b != NULL);
-        cl = (struct client_closure *) b->st;
+        q = head->buffer->device_queue;
+        assert(q != NULL);
+        cl = devq_get_state(q);
         assert(cl != NULL);
         copy_packet_to_user(head->buffer, data, len, flags);
         head = head->next;
@@ -596,9 +599,7 @@ static void send_arp_to_all(void *data, uint64_t len, uint64_t flags)
        return;
     }
     // Forwarding it to netd as well.
-    struct buffer_descriptor *buffer = ((struct client_closure *)
-                                        (netd[RECEIVE_CONNECTION]->st))->
-      buffer_ptr;
+    struct buffer_descriptor *buffer = ((struct client_closure *)devq_get_state(netd[RECEIVE_CONNECTION]))->buffer_ptr;
 
 
 #if TRACE_ETHERSRV_MODE
@@ -705,7 +706,7 @@ static void init_rx_ring(size_t rx_bufsz)
     }
 }
 
-void init_soft_filters_service(char *service_name, uint64_t qid,
+void init_soft_filters_service(struct net_soft_filter_state *state, char *service_name, uint64_t qid,
                                size_t rx_bufsz)
 {
     // FIXME: do I need separate sf_srv_name for ether_netd services
@@ -717,7 +718,7 @@ void init_soft_filters_service(char *service_name, uint64_t qid,
     filter_id_counter = 0;
     snprintf(sf_srv_name, sizeof(sf_srv_name), "%s_%"PRIu64"",
             service_name, qid);
-    errval_t err = net_soft_filters_export(NULL, export_soft_filters_cb,
+    errval_t err = net_soft_filters_export(state, export_soft_filters_cb,
                                connect_soft_filters_cb, get_default_waitset(),
                                IDC_EXPORT_FLAGS_DEFAULT);
     if (err_is_fail(err)) {
@@ -750,9 +751,9 @@ static bool handle_application_packet(void *packet, size_t len, uint64_t flags)
 
     // Matching filter found, sending packet to application
     struct buffer_descriptor *buffer = filter->buffer;
-    struct net_queue_manager_binding *b = buffer->con;
-    assert(b != NULL);
-    struct client_closure *cl = (struct client_closure *) b->st;
+    struct devq *q = buffer->device_queue;
+    assert(q != NULL);
+    struct client_closure *cl = devq_get_state(q);
     assert(cl != NULL);
 
     if (cl->debug_state == 4) {
@@ -853,8 +854,7 @@ static bool handle_netd_packet(void *packet, size_t len, uint64_t flags)
     }
 
   ETHERSRV_DEBUG("No client wants, giving it to netd\n");
-    struct buffer_descriptor *buffer = ((struct client_closure *)
-              (netd[RECEIVE_CONNECTION]->st))->buffer_ptr;
+    struct buffer_descriptor *buffer = ((struct client_closure *)devq_get_state(netd[RECEIVE_CONNECTION]))->buffer_ptr;
 
 //    ETHERSRV_DEBUG("sending packet up.\n");
     /* copy the packet to userspace */
@@ -863,13 +863,13 @@ static bool handle_netd_packet(void *packet, size_t len, uint64_t flags)
         return false;
     }
 
-    struct net_queue_manager_binding *b = buffer->con;
-    if(b == NULL) {
+    struct devq *q = buffer->device_queue;
+    if(q == NULL) {
         printf("netd buffer->con not present\n");
         return false;
     }
 
-    struct client_closure *cl = (struct client_closure *)b->st;
+    struct client_closure *cl = devq_get_state(q);
     assert(cl != NULL);
     if (copy_packet_to_user(buffer, packet, len, flags) == false) {
         ETHERSRV_DEBUG("Copy packet to userspace failed\n");
@@ -1018,4 +1018,3 @@ void sf_process_received_packet(struct driver_rx_buffer *buf, size_t count,
 out:
      rx_ring_register_buffer(opaque);
 } // end function: process_received_packet
-
index 5a3707a..d4515d2 100755 (executable)
@@ -24,7 +24,9 @@
 #include <trace/trace.h>
 #include <trace_definitions/trace_defs.h>
 #include <net_queue_manager/net_queue_manager.h>
-#include <if/net_queue_manager_defs.h>
+#include <barrelfish/waitset_chan.h>
+#include <devif/queue_interface.h>
+#include <devif/backends/descq.h>
 
 #include "QM_benchmark.h"
 #include "queue_manager_debug.h"
@@ -64,39 +66,39 @@ struct buffer_descriptor *buffers_list = NULL;
  * Prototypes
  *****************************************************************/
 
-static errval_t register_buffer(struct net_queue_manager_binding *cc,
-        struct capref cap, struct capref sp, uint64_t queueid,
-        uint64_t slots, uint8_t role, struct capref queue_cap, uint64_t *idx);
-static void raw_add_buffer_signal(struct net_queue_manager_binding *cc,
-                           uint64_t offset, uint64_t length,
-                           uint64_t more, uint64_t flags);
-static void raw_add_buffer(struct net_queue_manager_binding *cc,
-                           uint64_t offset, uint64_t length,
-                           uint64_t more, uint64_t flags);
-static errval_t get_mac_addr_qm(struct net_queue_manager_binding *cc,
-        uint64_t queueid, uint64_t *mac);
-static void print_statistics_handler(struct net_queue_manager_binding *cc,
-        uint64_t queueid);
-static void terminate_queue(struct net_queue_manager_binding *cc);
-
-static void do_pending_work(struct net_queue_manager_binding *b);
+// static errval_t register_buffer(struct net_queue_manager_binding *cc,
+//         struct capref cap, struct capref sp, uint64_t queueid,
+//         uint64_t slots, uint8_t role, struct capref queue_cap, uint64_t *idx);
+// static void raw_add_buffer_signal(struct net_queue_manager_binding *cc,
+//                            uint64_t offset, uint64_t length,
+//                            uint64_t more, uint64_t flags);
+// static void raw_add_buffer(struct client_closure *cl,
+//                            uint64_t offset, uint64_t length,
+//                            uint64_t more, uint64_t flags);
+// static errval_t get_mac_addr_qm(struct net_queue_manager_binding *cc,
+//         uint64_t queueid, uint64_t *mac);
+// static void print_statistics_handler(struct net_queue_manager_binding *cc,
+//         uint64_t queueid);
+// static void terminate_queue(struct net_queue_manager_binding *cc);
+
+static void do_pending_work(struct devq *q);
 
 /*****************************************************************
  * VTABLE
  *****************************************************************/
 
-// Initialize service
-static struct net_queue_manager_rx_vtbl rx_nqm_vtbl = {
-    .raw_add_buffer = raw_add_buffer_signal,
-    .print_statistics = print_statistics_handler,
-    .benchmark_control_request = benchmark_control_request,
-    .terminate_queue = terminate_queue,
-};
-
-static struct net_queue_manager_rpc_rx_vtbl rpc_rx_nqm_vtbl = {
-    .register_buffer_call = register_buffer,
-    .get_mac_address_call = get_mac_addr_qm,
-};
+// // Initialize service
+// static struct net_queue_manager_rx_vtbl rx_nqm_vtbl = {
+//     .raw_add_buffer = raw_add_buffer_signal,
+//     .print_statistics = print_statistics_handler,
+//     .benchmark_control_request = benchmark_control_request,
+//     .terminate_queue = terminate_queue,
+// };
+//
+// static struct net_queue_manager_rpc_rx_vtbl rpc_rx_nqm_vtbl = {
+//     .register_buffer_call = register_buffer,
+//     .get_mac_address_call = get_mac_addr_qm,
+// };
 
 /*****************************************************************
  * Pointers to driver functionalities:
@@ -119,14 +121,12 @@ static size_t rx_buffer_size = 0;
 // client_no used to give id's to clients
 // WARN: should start at 0 as loopback table lookup depends on this assumption
 static int client_no = 0;  // number of clients(apps) connected
-static struct net_queue_manager_binding *all_apps[1024];
+static struct devq *all_apps[1024];
 
 static uint64_t buffer_id_counter = 0; // number of buffers registered
 // FIXME: following should be gone in next version of code
 static uint64_t netd_buffer_count = 0; // way to identify the netd
 
-static struct buffer_descriptor *first_app_b = NULL;
-
 // *************************************************************
 //  local loopback device related code
 // *************************************************************
@@ -145,74 +145,6 @@ static struct loopback_mapping lo_map_tbl[4] = {{0,0, NULL},};
 // client_no initialization value
 static int lo_tbl_idx = 0;
 
-static int put_to_queue(uint64_t *q, uint64_t v1, uint64_t v2, uint64_t v3, uint64_t v4)
-{
-    uint64_t start = q[0];
-    uint64_t end = q[1];
-
-    if (end == (QUEUE_SIZE - 1)) {
-        assert(start > 1);
-    } else {
-        assert((end + 1) != start);
-    }
-
-    q[4 * end] = v1;
-    q[4 * end + 1] = v2;
-    q[4 * end + 2] = v3;
-    q[4 * end + 3] = v4;
-    bool s = start == end;
-    if (end == (QUEUE_SIZE - 1))
-        q[1] = 1;
-    else
-        q[1]++;
-    end = q[1];
-    bool f = (end == (QUEUE_SIZE - 1)) ? (start == 1): (start == end + 1);
-    return s + 2 * f;
-}
-
-static bool check_queue(uint64_t *q)
-{
-    uint64_t start = q[0];
-    uint64_t end = q[1];
-
-    return start != end;
-}
-
-static bool get_from_queue(uint64_t *q, uint64_t *v1, uint64_t *v2, uint64_t *v3, uint64_t *v4)
-{
-    uint64_t start = q[0];
-    uint64_t end = q[1];
-
-    assert(start != end);
-    *v1 = q[4 * start];
-    *v2 = q[4 * start + 1];
-    *v3 = q[4 * start + 2];
-    *v4 = q[4 * start + 3];
-    if (start == (QUEUE_SIZE - 1))
-        q[0] = 1;
-    else
-        q[0]++;
-    return !q[2];
-}
-
-void check_queues(void)
-{
-    int i;
-
-    for (i = 0; i < client_no; i++) {
-        struct client_closure *cc = all_apps[i]->st;
-        for (;;) {
-            if (!cc->queue)
-                break;
-            bool r = check_queue(cc->queue);
-            if (r)
-                raw_add_buffer(cc->app_connection, 0, 0, 0, 0);
-            else
-                break;
-        }
-    }
-}
-
 // fill up the lo_map_tbl with valid entries
 // Assumptions:
 //  * client_no starts at 0
@@ -286,11 +218,11 @@ struct buffer_descriptor *get_lo_receiver(void *opaque)
 
     struct buffer_state_metadata *bsm = opaque;
 
-    struct net_queue_manager_binding *b = bsm->binding;
+    struct devq *q = bsm->device_queue;
 
     // find client_no of sending app
-    assert(b != NULL);
-    struct client_closure *cc = (struct client_closure *)b->st;
+    assert(q != NULL);
+    struct client_closure *cc = devq_get_state(q);
     assert(cc != NULL);
 
     int cl_no = cc->cl_no;
@@ -309,8 +241,7 @@ struct buffer_descriptor *get_lo_receiver(void *opaque)
 
 
 // Creates a new client for given connection
-static struct client_closure *create_new_client(
-        struct net_queue_manager_binding *b)
+static struct client_closure *create_new_client(struct devq *q, uint8_t role, uint64_t *queue_id)
 {
     struct client_closure *cc =
       (struct client_closure *) malloc(sizeof(struct client_closure));
@@ -328,14 +259,14 @@ static struct client_closure *create_new_client(
         return NULL;
     }
     memset(buffer, 0, sizeof(struct buffer_descriptor));
-
-    b->st = cc;
-    cc->app_connection = b;
+    
+    devq_set_state(q, cc);
+    cc->app_connection = q;
 
     // FIXME: I should not need this as now netd is normal app
     // save it if it is netd app
     if (client_no < 2) {
-        netd[client_no] = b;
+        netd[client_no] = q;
     }
 
     cc->buffer_ptr = buffer;
@@ -343,10 +274,13 @@ static struct client_closure *create_new_client(
     reset_client_closure_stat(cc);
     cc->start_ts = rdtsc();
 
-    all_apps[client_no] = b;
+    all_apps[client_no] = q;
 
     cc->cl_no = client_no++;
-
+    cc->role = role;
+    buffer_id_counter++;
+    cc->buffer_id = buffer_id_counter;
+    *queue_id = buffer_id_counter;
     char name[64];
     sprintf(name, "ether_a_%d_%s", cc->cl_no,
                 ((cc->cl_no % 2) == 0)? "RX" : "TX");
@@ -354,8 +288,8 @@ static struct client_closure *create_new_client(
 } // end function: create_new_client
 
 // populates the given buffer with given capref
-static errval_t populate_buffer(struct buffer_descriptor *buffer,
-        struct capref cap)
+static errval_t populate_buffer(struct client_closure *closure,
+        struct buffer_descriptor *buffer, struct capref cap)
 {
 
     buffer->cap = cap;
@@ -382,13 +316,8 @@ static errval_t populate_buffer(struct buffer_descriptor *buffer,
         return(ETHERSRV_ERR_TOO_MANY_BUFFERS);
     }
     netd_buffer_count++;
-    buffer_id_counter++;
-    buffer->buffer_id = buffer_id_counter;
+    buffer->buffer_id = closure->buffer_id;
 //    printf("### buffer gets id %"PRIu64"\n", buffer->buffer_id);
-    if (buffer->buffer_id == 3) {
-        first_app_b = buffer;
-    }
-
     buffer->next = buffers_list;
     // Adding the buffer on the top of buffer list.
 //    buffers_list = buffer;
@@ -419,29 +348,34 @@ struct buffer_descriptor *find_buffer(uint64_t buffer_id)
 // Interface  implementation
 // **********************************************************
 
-// Actual register_buffer function with all it's logic
-static errval_t register_buffer(struct net_queue_manager_binding *cc,
-            struct capref cap, struct capref sp, uint64_t queueid,
-            uint64_t slots, uint8_t role, struct capref queue_cap, uint64_t *idx)
+// register region
+static errval_t register_region(struct descq* q, struct capref cap,
+                    regionid_t rid)
 {
+    debug_printf("Register \n");
+// Actual register_buffer function with all it's logic
     ETHERSRV_DEBUG("ethersrv:register buffer called with slots %"PRIu64"\n",
             slots);
     errval_t err;
-    struct client_closure *closure = (struct client_closure *)cc->st;
-    assert(exported_queueid == queueid);
-    closure->queueid = queueid;
-
+    struct client_closure *closure = (struct client_closure *)devq_get_state((struct devq *)q);
+    closure->queueid = exported_queueid;
+    closure->region_id = rid;
+    
     struct buffer_descriptor *buffer = closure->buffer_ptr;
-    err = populate_buffer(buffer, cap);
-    if (err_is_fail(err)) {
-        *idx = 0;
-        return SYS_ERR_OK;
-    }
-    buffer->role = role;
-    buffer->con = cc;
-    buffer->queueid = queueid;
+    err = populate_buffer(closure, buffer, cap);
+    assert(err_is_ok(err));
+
+    buffer->role = closure->role;
+    buffer->device_queue = (struct devq *)q;
+    buffer->queueid = exported_queueid;
+
+    struct capability capability;
+    err = debug_cap_identify(cap, &capability);
+    assert(err_is_ok(err));
+    assert(capability.type == ObjType_Frame);
 
     // Create a list to hold metadata for sending
+    uint64_t slots = buffer->bytes / 2048;
     buffer->rxq.buffer_state_size = slots;
     buffer->rxq.buffer_state = calloc(slots,
             sizeof(struct buffer_state_metadata));
@@ -457,14 +391,6 @@ static errval_t register_buffer(struct net_queue_manager_binding *cc,
     buffer->txq.buffer_state_head = 0;
     buffer->txq.buffer_state_used = 0;
 
-    void *va;
-    uint64_t *ptr;
-
-    err = vspace_map_one_frame(&va, QUEUE_SIZE * 4 * sizeof(uint64_t) * 2, queue_cap, NULL, NULL);
-    assert(err_is_ok(err));
-    ptr = va;
-    closure->queue = ptr;
-
     if (is_loopback_device) {
         populate_lo_mapping_table(closure->cl_no, closure->buffer_ptr);
     } // end if: loopback device
@@ -474,7 +400,6 @@ static errval_t register_buffer(struct net_queue_manager_binding *cc,
     use_raw_if = true;
 
     buffers_list = buffer;
-    *idx = buffer->buffer_id;
 
     return SYS_ERR_OK;
 } // end function: register_buffer
@@ -504,22 +429,15 @@ handle_single_event_nonblock(struct waitset *ws)
 } // end function: handle_single_event_nonblock
 
 
-static errval_t send_raw_xmit_done(struct net_queue_manager_binding *binding,
+static errval_t send_raw_xmit_done(struct devq *queue,
                                    uint64_t offset, uint64_t length,
                                    uint64_t more, uint64_t flags)
 {
-    struct client_closure *cl = (struct client_closure *) binding->st;
-    errval_t err = SYS_ERR_OK;
-    int r;
-    r = put_to_queue(cl->queue + QUEUE_SIZE * 4, offset, length, more, flags);
-    if (r) {
-        if (r == 2)
-            binding->control(binding, IDC_CONTROL_SET_SYNC);
-        err = binding->tx_vtbl.raw_xmit_done(binding, BLOCKING_CONT, offset, length, more, flags);
-        assert(err_is_ok(err));
-        if (r == 2)
-            binding->control(binding, IDC_CONTROL_CLEAR_SYNC);
-    }
+    struct client_closure *cl = (struct client_closure *)devq_get_state(queue);
+    errval_t err;
+    err = devq_enqueue(queue, cl->region_id, offset, length, 0, 0, flags);
+    debug_printf("%s: %d %ld\n", __func__, cl->region_id, err);
+    assert(err_is_ok(err));
     return err;
 } // end function: send_raw_xmit_done
 
@@ -539,24 +457,10 @@ uint64_t get_mac_addr_from_device(void)
 }
 
 // function to handle incoming mac address requests
-static errval_t get_mac_addr_qm(struct net_queue_manager_binding *cc,
-        uint64_t queueid, uint64_t *mac)
-{
-    struct client_closure *ccl = (struct client_closure *) cc->st;
-    assert(ccl->queueid == queueid);
-    *mac = get_mac_addr_from_device();
-    return SYS_ERR_OK;
-}
 
 // *********** Interface: print_statistics ****************
 
 // FIXME: NYI
-static void print_statistics_handler(struct net_queue_manager_binding *cc,
-        uint64_t queueid)
-{
-    //ETHERSRV_DEBUG
-    printf("ETHERSRV: print_statistics_handler: called.\n");
-}
 
 
 // **********************************************************
@@ -569,14 +473,14 @@ bool handle_tx_done(void *opaque)
 
     assert(opaque != NULL);
     struct buffer_state_metadata *bsm = opaque;
-    struct client_closure *cl = bsm->binding->st;
+    struct client_closure *cl = devq_get_state(bsm->device_queue);
     struct buffer_descriptor *buffer = cl->buffer_ptr;
 
     assert((buffer->txq.buffer_state_used > 0));
     --buffer->txq.buffer_state_used;
 
     // Handle raw interface
-    errval_t err = send_raw_xmit_done(bsm->binding, (uintptr_t)bsm->offset, 0,
+    errval_t err = send_raw_xmit_done(bsm->device_queue, (uintptr_t)bsm->offset, 0,
             0, 0);
     if (err_is_ok(err)) {
         return true;
@@ -591,7 +495,7 @@ bool handle_tx_done(void *opaque)
 // Do all the work related TX path for perticular client
 // It includes
 //   * Take care of descriptors which are sent.
-static void do_pending_work(struct net_queue_manager_binding *b)
+static void do_pending_work(struct devq *queue)
 {
     // Handle raw interface
     if (use_raw_if) {
@@ -607,7 +511,7 @@ void do_pending_work_for_all(void)
 {
     struct buffer_descriptor *next_buf = buffers_list;
     while (next_buf != NULL) {
-        do_pending_work(next_buf->con);
+        do_pending_work(next_buf->device_queue);
         next_buf = next_buf->next;
     }
 }
@@ -632,11 +536,11 @@ void process_received_packet(struct driver_rx_buffer* bufs, size_t count,
         for (i = 0; i < count; i++) {
             assert(bufs[i].opaque != NULL);
             struct buffer_state_metadata *bsm = bufs[i].opaque;
-            struct client_closure *cl = bsm->binding->st;
+            struct client_closure *cl = devq_get_state(bsm->device_queue);
             struct buffer_descriptor *buf = cl->buffer_ptr;
             assert(buf->rxq.buffer_state_used > 0);
 
-            errval_t err = send_raw_xmit_done(bsm->binding, bsm->offset,
+            errval_t err = send_raw_xmit_done(bsm->device_queue, bsm->offset,
                     bufs[i].len, (i != count - 1), flags);
             if (err_is_ok(err)) {
                 --buf->rxq.buffer_state_used;
@@ -670,14 +574,13 @@ bool copy_packet_to_user(struct buffer_descriptor *buffer,
     assert(len > 0);
     assert(data != NULL);
     assert(buffer != NULL);
-    struct net_queue_manager_binding *b = buffer->con;
-    assert(b != NULL);
-    struct client_closure *cl = (struct client_closure *) b->st;
+    struct devq *q = buffer->device_queue;
+    assert(q != NULL);
+    struct client_closure *cl = devq_get_state(q);
     assert(cl != NULL);
 
     // check if there are slots which can be used in app (!isempty)
     if(buffer->rxq.buffer_state_used == 0) {
-
         printf("[%s] Dropping packet as no space in userspace "
                 "2cp pkt buf [%" PRIu64 "]: "
                 "size[%zu] used[%zu], after [%"PRIu64"] sent"
@@ -721,7 +624,7 @@ bool copy_packet_to_user(struct buffer_descriptor *buffer,
 #endif // TRACE_ETHERSRV_MODE
 
     // Handle raw interface
-    errval_t err = send_raw_xmit_done(b, offset, len, 0, flags);
+    errval_t err = send_raw_xmit_done(q, offset, len, 0, flags);
     if (err_is_ok(err)) {
         return true;
     } else {
@@ -740,166 +643,182 @@ bool copy_packet_to_user(struct buffer_descriptor *buffer,
 /*****************************************************************
  * Interface related: raw interface
  ****************************************************************/
-static void raw_add_buffer_signal(struct net_queue_manager_binding *cc,
+static void raw_add_buffer_tx(struct client_closure *cl,
                            uint64_t offset, uint64_t length,
                            uint64_t more, uint64_t flags)
 {
-    struct client_closure *cl = (struct client_closure *) cc->st;
-
-    for (;;) {
-        bool c = check_queue(cl->queue);
-        if (c)
-            raw_add_buffer(cc, offset, length, more, flags);
-        else
-            break;
-    }
-}
-
-static void raw_add_buffer(struct net_queue_manager_binding *cc,
-                           uint64_t offset, uint64_t length,
-                           uint64_t more, uint64_t flags)
-{
-    struct client_closure *cl = (struct client_closure *) cc->st;
     struct buffer_descriptor *buffer = cl->buffer_ptr;
     errval_t err;
     uint64_t paddr;
     void *vaddr, *opaque;
 
-    bool c = check_queue(cl->queue);
-    if (!c)
-        return;
-    get_from_queue(cl->queue, &offset, &length, &more, &flags);
-    c = check_queue(cl->queue);
-
     paddr = ((uint64_t)(uintptr_t) buffer->pa) + offset;
     vaddr = (void*) ((uintptr_t) buffer->va + (size_t)offset);
 
-    if (buffer->role == TX_BUFFER_ID) {
-        // Make sure that there is opaque slot available (isfull)
-        assert(buffer->txq.buffer_state_used < (buffer->txq.buffer_state_size - 1));
-
-        // Save state for handle_tx_done()/handle_receive_packet
-        struct buffer_state_metadata *bsm = buffer->txq.buffer_state +
-            buffer->txq.buffer_state_head;
-        buffer->txq.buffer_state_head = (buffer->txq.buffer_state_head + 1)
-            % buffer->txq.buffer_state_size;
-        bsm->binding = cc;
-        bsm->offset = offset;
-        ++buffer->txq.buffer_state_used;
-
-        opaque = (void*)bsm;
-
-        // save information as list of packet-chunks before sending to HW
-        cl->driver_buff_list[cl->chunk_counter].va = vaddr;
-        cl->driver_buff_list[cl->chunk_counter].pa = paddr;
-        cl->driver_buff_list[cl->chunk_counter].len = length;
-        cl->driver_buff_list[cl->chunk_counter].opaque = opaque;
-        cl->driver_buff_list[cl->chunk_counter].flags = flags;
-        ++cl->chunk_counter;
-        if (more == 0) {
-            // ETHERSRV_DEBUG
+    // debug_printf("%s: %p: %lx:%ld\n", __func__, cc, offset, length);
+    // Make sure that there is opaque slot available (isfull)
+    assert(buffer->txq.buffer_state_used < (buffer->txq.buffer_state_size - 1));
+
+    // Save state for handle_tx_done()/handle_receive_packet
+    struct buffer_state_metadata *bsm = buffer->txq.buffer_state +
+        buffer->txq.buffer_state_head;
+    buffer->txq.buffer_state_head = (buffer->txq.buffer_state_head + 1)
+        % buffer->txq.buffer_state_size;
+    bsm->device_queue = cl->app_connection;
+    bsm->offset = offset;
+    ++buffer->txq.buffer_state_used;
+
+    opaque = (void*)bsm;
+
+    // save information as list of packet-chunks before sending to HW
+    cl->driver_buff_list[cl->chunk_counter].va = vaddr;
+    cl->driver_buff_list[cl->chunk_counter].pa = paddr;
+    cl->driver_buff_list[cl->chunk_counter].len = length;
+    cl->driver_buff_list[cl->chunk_counter].opaque = opaque;
+    cl->driver_buff_list[cl->chunk_counter].flags = flags;
+    ++cl->chunk_counter;
+    if (more == 0) {
+        // ETHERSRV_DEBUG
 //            printf("sending out packet\n");
-            if (cl->chunk_counter > 1) {
-                ETHERSRV_DEBUG
-                //printf
-                    ("%s:%s: handle=%p\n", disp_name(), __func__,
-                        opaque);
-            }
-            err = ether_transmit_pbuf_list_ptr(cl->driver_buff_list,
-                    cl->chunk_counter);
-            if (c == false) // no more buffers -> start sending
-                ether_transmit_pbuf_list_ptr(cl->driver_buff_list, 0);
-            assert(err_is_ok(err));
-            cl->chunk_counter = 0;
-        }
-    } else { // RX_BUFFER_ID
-
-        // Sanity check.  Making sure that more flag is not set
-        if (more == 1) {
-            USER_PANIC("broken buffer registerd with for RX buffer\n");
+        if (cl->chunk_counter > 1) {
+            ETHERSRV_DEBUG
+            //printf
+                ("%s:%s: handle=%p\n", disp_name(), __func__,
+                    opaque);
         }
-
-        // Make sure that there is opaque slot available (isfull)
-        assert(buffer->rxq.buffer_state_used <
-                (buffer->rxq.buffer_state_size - 1));
-
-        // Save state for handle_tx_done()/handle_receive_packet
-        struct buffer_state_metadata *bsm = buffer->rxq.buffer_state +
-            buffer->rxq.buffer_state_head;
-        buffer->rxq.buffer_state_head = (buffer->rxq.buffer_state_head + 1)
-            % buffer->rxq.buffer_state_size;
-        bsm->binding = cc;
-        bsm->offset = offset;
-        ++buffer->rxq.buffer_state_used;
-        ++rx_added;
-        opaque = (void*)bsm;
-
-        // role == RX_BUFFER_ID
-        if (use_sf) {
-            // nothing to do!
-
-        } else {
-            assert(length == rx_buffer_size);
-            rx_register_buffer_fn_ptr(paddr, vaddr, opaque);
-        }
-
-        // FIXME: send a message back acking receiving of message.
-
-    } // end else: RX_BUFFER_ID
+        err = ether_transmit_pbuf_list_ptr(cl->driver_buff_list,
+                cl->chunk_counter);
+        assert(err_is_ok(err));
+        cl->chunk_counter = 0;
+    }
 } // end function: raw_add_buffer
 
-/*****************************************************************
- * Interface related: Exporting and handling connections
- ****************************************************************/
-
-static void export_ether_cb(void *st, errval_t err, iref_t iref)
+static void raw_add_buffer_rx(struct client_closure *cl,
+                           uint64_t offset, uint64_t length,
+                           uint64_t more, uint64_t flags)
 {
-    if (err_is_fail(err)) {
-        DEBUG_ERR(err, "service [%s] export failed", exported_queue_name);
-        abort();
+    struct buffer_descriptor *buffer = cl->buffer_ptr;
+    uint64_t paddr;
+    void *vaddr, *opaque;
+
+    paddr = ((uint64_t)(uintptr_t) buffer->pa) + offset;
+    vaddr = (void*) ((uintptr_t) buffer->va + (size_t)offset);
+
+    // Sanity check.  Making sure that more flag is not set
+    if (more == 1) {
+        USER_PANIC("broken buffer registerd with for RX buffer\n");
     }
 
-   // ETHERSRV_DEBUG
-    printf("service [%s] exported at iref %"PRIu32"\n", exported_queue_name,
-           (uint32_t)iref);
+    // Make sure that there is opaque slot available (isfull)
+    assert(buffer->rxq.buffer_state_used <
+            (buffer->rxq.buffer_state_size - 1));
 
-    // register this iref with the name service
-    err = nameservice_register(exported_queue_name, iref);
-    if (err_is_fail(err)) {
-        DEBUG_ERR(err, "nameservice_register failed for [%s]",
-                exported_queue_name);
-        abort();
+    // Save state for handle_tx_done()/handle_receive_packet
+    struct buffer_state_metadata *bsm = buffer->rxq.buffer_state +
+        buffer->rxq.buffer_state_head;
+    buffer->rxq.buffer_state_head = (buffer->rxq.buffer_state_head + 1)
+        % buffer->rxq.buffer_state_size;
+    bsm->device_queue = cl->app_connection;
+    bsm->offset = offset;
+    ++buffer->rxq.buffer_state_used;
+    ++rx_added;
+    opaque = (void*)bsm;
+
+    // role == RX_BUFFER_ID
+    if (use_sf) {
+        // nothing to do!
+    } else {
+        assert(length == rx_buffer_size);
+        rx_register_buffer_fn_ptr(paddr, vaddr, opaque);
     }
-}
+    // FIXME: send a message back acking receiving of message.
+} // end function: raw_add_buffer
 
-static void error_handler(struct net_queue_manager_binding *b, errval_t err)
+static errval_t notify_queue(struct descq *queue)
 {
-    ETHERSRV_DEBUG("ether service error_handler: called\n");
-    if (err == SYS_ERR_CAP_NOT_FOUND) {
-        struct client_closure *cc = b->st;
+    struct client_closure *cl = devq_get_state((struct devq *)queue);
 
-        assert(cc != NULL);
-        struct buffer_descriptor *buffer = cc->buffer_ptr;
+    regionid_t rid;
+    genoffset_t offset;
+    genoffset_t length;
+    genoffset_t valid_data;
+    genoffset_t valid_length;
+    uint64_t flags;
 
-        assert(buffer != NULL);
-        free(buffer);
-        free(cc);
+    for (;;) {
+        errval_t err;
+        err = devq_dequeue((struct devq *)queue, &rid, &offset, &length,
+                           &valid_data, &valid_length, &flags);
+        if (err_is_fail(err))
+            break;
+
+        if (cl->buffer_ptr->role == TX_BUFFER_ID) {
+            // debug_printf("notify_queue_tx: %p: %d:%lx:%ld\n", queue, rid, offset, length);
+            raw_add_buffer_tx(cl, offset, length, 0, flags);
+        } else {
+            // debug_printf("notify_queue_rx: %p: %d:%lx:%ld\n", queue, rid, offset, length);
+            raw_add_buffer_rx(cl, offset, length, 0, flags);
+        }
     }
-    ETHERSRV_DEBUG("ether service error_handler: terminated\n");
+    return SYS_ERR_OK;
 }
 
-static errval_t connect_ether_cb(void *st, struct net_queue_manager_binding *b)
+/*****************************************************************
+ * Interface related: Exporting and handling connections
+ ****************************************************************/
+
+// static void export_ether_cb(void *st, errval_t err, iref_t iref)
+// {
+//     if (err_is_fail(err)) {
+//         DEBUG_ERR(err, "service [%s] export failed", exported_queue_name);
+//         abort();
+//     }
+//
+//    // ETHERSRV_DEBUG
+//     debug_printf("service [%s] exported at iref %"PRIu32"\n", exported_queue_name,
+//            (uint32_t)iref);
+//
+//     // register this iref with the name service
+//     debug_printf("%s: nqm export [%s]\n", __func__, exported_queue_name);
+//     err = nameservice_register(exported_queue_name, iref);
+//     if (err_is_fail(err)) {
+//         DEBUG_ERR(err, "nameservice_register failed for [%s]",
+//                 exported_queue_name);
+//         abort();
+//     }
+//     debug_printf("service [%s] registered\n", exported_queue_name);
+// }
+//
+// static void error_handler(struct net_queue_manager_binding *b, errval_t err)
+// {
+//     ETHERSRV_DEBUG("ether service error_handler: called\n");
+//     if (err == SYS_ERR_CAP_NOT_FOUND) {
+//         struct client_closure *cc = b->st;
+//
+//         assert(cc != NULL);
+//         struct buffer_descriptor *buffer = cc->buffer_ptr;
+//
+//         assert(buffer != NULL);
+//         free(buffer);
+//         free(cc);
+//     }
+//     ETHERSRV_DEBUG("ether service error_handler: terminated\n");
+// }
+
+//static errval_t connect_ether_cb(void *st, struct net_queue_manager_binding *b)
+static errval_t create_queue(struct descq* q, bool notifications, uint8_t role, uint64_t *queue_id)
 {
-    ETHERSRV_DEBUG("ether service got a connection!44\n");
+    ETHERSRV_DEBUG("ether service got a connection!\n");
 
     // copy my message receive handler vtable to the binding
-    b->rx_vtbl = rx_nqm_vtbl;
-    b->rpc_rx_vtbl = rpc_rx_nqm_vtbl;
-    b->error_handler = error_handler;
-    b->control(b, IDC_CONTROL_CLEAR_SYNC);
+    // b->rx_vtbl = rx_nqm_vtbl;
+    // b->rpc_rx_vtbl = rpc_rx_nqm_vtbl;
+    // b->error_handler = error_handler;
+    // b->control(b, IDC_CONTROL_CLEAR_SYNC);
 
     // Create a new client for this connection
-    struct client_closure *cc = create_new_client(b);
+    struct client_closure *cc = create_new_client((struct devq *)q, role, queue_id);
+    debug_printf("%s: %p regid:%ld\n", __func__, q, *queue_id);
     if (cc == NULL) {
         return ETHERSRV_ERR_NOT_ENOUGH_MEM;
     }
@@ -907,6 +826,28 @@ static errval_t connect_ether_cb(void *st, struct net_queue_manager_binding *b)
     return SYS_ERR_OK;
 } // end function: connect_ether_cb
 
+static errval_t destroy_queue(struct descq* q)
+{
+    debug_printf("Destroy \n");
+    return SYS_ERR_OK;
+}
+
+static errval_t deregister_region(struct descq* q, regionid_t rid)
+{
+    debug_printf("Deregister \n");
+    return SYS_ERR_OK;
+}
+
+static errval_t control_queue(struct descq* q, uint64_t cmd, uint64_t value, uint64_t *result)
+{
+    debug_printf("Control \n");
+    if (cmd == 0) // get mac
+        *result = get_mac_addr_from_device();
+
+    return SYS_ERR_OK;
+}
+
+
 
 /*****************************************************************
  * ethersrv initialization wrapper:
@@ -965,21 +906,51 @@ void ethersrv_init(char *service_name, uint64_t queueid,
     printf("using %zd slots for internal buffer\n", driver_supported_buffers);
     assert(driver_supported_buffers >= 1);
 
+    debug_printf("%s: exporting\n", __func__);
+    
     /* exporting ether interface */
-    err = net_queue_manager_export(NULL, // state for connect/export callbacks
-                       export_ether_cb, connect_ether_cb, get_default_waitset(),
-                       IDC_EXPORT_FLAGS_DEFAULT);
-    if (err_is_fail(err)) {
-        DEBUG_ERR(err, "%s export failed", exported_queue_name);
-        abort();
-    }
+
+    struct descq_func_pointer f;
+
+    f.notify = notify_queue;
+    f.create = create_queue;
+    f.destroy = destroy_queue;
+    f.reg = register_region;
+    f.dereg = deregister_region;
+    f.control = control_queue;
+    
+    struct descq* exp_queue;
+    uint64_t queue_id;
+    
+    debug_printf("Creating queue...\n");
+    err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, exported_queue_name,
+                       true, true, 0, &queue_id, &f);
+
+    assert(err_is_ok(err));
+
+    debug_printf("Queue created\n");
 
     // FIXME: How do we decide this reasonably
     use_sf = !force_disable_sf && (queueid == 0);
 
     if (use_sf || is_loopback_device) {
         // start software filtering service
-        init_soft_filters_service(service_name, queueid, rx_bufsz);
+        struct net_soft_filter_state *state;
+        
+        state = malloc(sizeof(struct net_soft_filter_state));
+        waitset_chanstate_init(&state->initialization_completed, CHANTYPE_OTHER);
+        state->initialization_completed.trigger = get_monitor_binding_chanstate();
+        err = waitset_chan_register(get_default_waitset(), &state->initialization_completed,
+                               NOP_CLOSURE);
+        assert(err_is_ok(err));
+        
+        init_soft_filters_service(state, service_name, queueid, rx_bufsz);
+        
+        errval_t err2;
+        err2 = SYS_ERR_OK;
+        err = wait_for_channel(get_default_waitset(), &state->initialization_completed, &err2);
+        assert(err_is_ok(err));
+        assert(err_is_ok(err2));
     }
 } // end function: ethersrv_init
 
@@ -1003,22 +974,22 @@ void ethersrv_argument(const char* arg)
     }
 }
 
-static void terminate_queue(struct net_queue_manager_binding *cc)
-{
-    errval_t err;
-    struct buffer_descriptor *buffer;
-
-    // Free buffers
-    for (buffer = buffers_list; buffer != NULL; buffer = buffer->next) {
-        err = vspace_unmap(buffer->va);
-        assert(err_is_ok(err));
-        err = cap_delete(buffer->cap);
-        assert(err_is_ok(err));
-    }
-
-    assert(ether_terminate_queue_ptr != NULL);
-    ether_terminate_queue_ptr();
-}
+// static void terminate_queue(struct net_queue_manager_binding *cc)
+// {
+//     errval_t err;
+//     struct buffer_descriptor *buffer;
+//
+//     // Free buffers
+//     for (buffer = buffers_list; buffer != NULL; buffer = buffer->next) {
+//         err = vspace_unmap(buffer->va);
+//         assert(err_is_ok(err));
+//         err = cap_delete(buffer->cap);
+//         assert(err_is_ok(err));
+//     }
+//
+//     assert(ether_terminate_queue_ptr != NULL);
+//     ether_terminate_queue_ptr();
+// }
 
 // **********************************************************
 // Additional functions
index c2dcda8..8560d58 100644 (file)
@@ -16,7 +16,7 @@ extern struct buffer_descriptor *buffers_list;
 
 /* NETD connections */
 #define NETD_BUF_NR 2
-struct net_queue_manager_binding *netd[NETD_BUF_NR];
+struct devq *netd[NETD_BUF_NR];
 
 // Measurement purpose, counting interrupt numbers
 extern uint64_t interrupt_counter;
@@ -29,7 +29,7 @@ extern uint64_t total_rx_datasize;
 //struct buffer_descriptor *find_buffer(uint64_t buffer_id);
 
 // Function prototypes for ether_control service
-void init_soft_filters_service(char *service_name, uint64_t qid,
+void init_soft_filters_service(struct net_soft_filter_state *state, char *service_name, uint64_t qid,
                                size_t rx_bufsz);
 void sf_process_received_packet(struct driver_rx_buffer *buf, size_t count,
                                 uint64_t flags);
index 5758fa8..a170c27 100644 (file)
@@ -526,6 +526,7 @@ rpc_fn ifn typedefs msg@(RPC n args _) =
 local_rpc_fn :: String -> [TypeDef] -> MessageDef -> C.Unit
 local_rpc_fn ifn typedefs msg@(RPC n args _) =
     C.FunctionDef C.Static (C.TypeName "errval_t") (local_rpc_fn_name ifn n) params [
+        C.Ex $ C.Call "assert" [C.Binary C.NotEquals tx_func (C.Variable "NULL")],
         C.Return $ C.CallInd tx_func (localbindvar:(map C.Variable $ concat $ map mkargs rpc_args))
     ]
     where
index 028ae1b..9edc4c5 100644 (file)
@@ -189,9 +189,12 @@ tx_fn ifn msg@(Message _ mn args _) =
             C.Ex $ C.CallInd handler ((local_binding):(concat $ map mkvars args)),
             C.SBlank,
             C.SComment "run continuation, if any",
-            C.If (C.Binary C.NotEquals
+            C.If (C.Binary C.And (C.Binary C.NotEquals
                                 (C.Variable intf_cont_var `C.FieldOf` "handler")
                                 (C.Variable "NULL"))
+                (C.Binary C.NotEquals
+                        (C.Variable intf_cont_var `C.FieldOf` "handler")
+                        (C.Variable "blocking_cont")))
                 [C.Ex $ C.CallInd (C.Variable intf_cont_var `C.FieldOf` "handler")
                                 [C.Variable intf_cont_var `C.FieldOf` "arg"]] [],
             C.SBlank,
index cb22b90..a796ea1 100644 (file)
@@ -12,8 +12,7 @@
 
 [ build application { target = "NGD_mng",
                         cFiles = [ "NGD_mng.c" ],
-                       addLibraries = [ "contmng", "net_device_manager",
-                        "trace" ]
+                       addLibraries = [ "net_device_manager", "contmng", "netbench", "trace" ]
                     }
 ]
 
index 5b2e703..a8091fd 100644 (file)
@@ -353,10 +353,6 @@ static errval_t transmit_pbuf_list_fn(struct driver_buffer *buffers,
                                       size_t                count)
 
 {
-    if (!count) { // flush
-        update_e1000_tdt();
-        return SYS_ERR_OK;
-    }
     E1000_DEBUG("transmit_pbuf_list_fn(count=%"PRIu64")\n", count);
     if (!can_transmit(count)){
         while(handle_free_TX_slot_fn());
@@ -385,6 +381,7 @@ static errval_t transmit_pbuf_list_fn(struct driver_buffer *buffers,
         (uint32_t)0);
 #endif // TRACE_ONLY_SUB_NNET
 
+    update_e1000_tdt();
     return SYS_ERR_OK;
 } // end function: transmit_pbuf_list_fn
 
@@ -763,7 +760,6 @@ static void e1000_interrupt_handler_fn(void *arg)
         handle_multiple_packets(1);
 #endif
     }
-    check_queues();
     while(handle_free_TX_slot_fn());
 }
 
index 2aa0e3d..edf5a44 100644 (file)
@@ -28,7 +28,7 @@ struct ele {
     struct ele* next;
 };
 
-static errval_t create(struct descq* q)
+static errval_t create(struct descq* q, bool notifications)
 {
     printf("Create \n");
     if (list == NULL) {
@@ -73,7 +73,7 @@ static errval_t notify(struct descq* q)
     bool exit = false;
     uint16_t num_enq = 0;
     while(!exit) {
-        err = devq_dequeue(queue, &rid, &offset, &length, 
+        err = devq_dequeue(queue, &rid, &offset, &length,
                            &valid_data, &valid_length, &flags);
         if (err_is_fail(err)) {
             exit = true;
@@ -94,7 +94,7 @@ static errval_t notify(struct descq* q)
         err = devq_notify(queue);
     } else {
         err = SYS_ERR_OK;
-    }   
+    }
 
     return err;
 }
@@ -131,12 +131,12 @@ int main(int argc, char *argv[])
     f->destroy = destroy;
     f->reg = reg;
     f->dereg = dereg;
-    f->control = control;   
+    f->control = control;
 
     struct descq* exp_queue;
 
-    err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, "test_queue", 
-                       true, f);
+    err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, "test_queue",
+                       true, true, f);
 
     assert(err_is_ok(err));
 
index 3ac3b31..d082cf1 100644 (file)
@@ -78,13 +78,13 @@ static void print_buffer(size_t len, bufferid_t bid)
 {
    /*
     uint8_t* buf = (uint8_t*) va_rx+bid;
-    printf("Packet in region %p at address %p len %zu \n", 
+    printf("Packet in region %p at address %p len %zu \n",
            va_rx, buf, len);
     for (int i = 0; i < len; i++) {
         if (((i % 10) == 0) && i > 0) {
             printf("\n");
         }
-        printf("%2X ", buf[i]);   
+        printf("%2X ", buf[i]);
     }
     printf("\n");
     */
@@ -113,8 +113,8 @@ static void event_cb(void* queue)
 
     err = SYS_ERR_OK;
 
-    while (err == SYS_ERR_OK) {    
-        err = devq_dequeue(q, &rid, &offset, &length, &valid_data,  
+    while (err == SYS_ERR_OK) {
+        err = devq_dequeue(q, &rid, &offset, &length, &valid_data,
                            &valid_length, &flags);
         if (err_is_fail(err)) {
             break;
@@ -133,7 +133,7 @@ static void event_cb(void* queue)
     }
 
     // MSIX is not working on so we have to "simulate interrupts"
-    err = waitset_chan_register(&card_ws, chan, 
+    err = waitset_chan_register(&card_ws, chan,
                                 MKCLOSURE(event_cb, queue));
     if (err_is_fail(err) && err_no(err) == LIB_ERR_CHAN_ALREADY_REGISTERED) {
         printf("Got actual interrupt?\n");
@@ -153,23 +153,23 @@ static struct devq* create_net_queue(char* card_name)
     if (strcmp(card_name, "sfn5122f") == 0) {
         struct sfn5122f_queue* q;
         
-        err = sfn5122f_queue_create(&q, event_cb, /* userlevel*/ true, 
+        err = sfn5122f_queue_create(&q, event_cb, /* userlevel*/ true,
                                     /*MSIX interrupts*/ false);
         if (err_is_fail(err)){
             USER_PANIC("Allocating devq failed \n");
         }
-        return (struct devq*) q;    
+        return (struct devq*) q;
     }
 
     if (strcmp(card_name, "e10k") == 0) {
         struct e10k_queue* q;
         
-        err = e10k_queue_create(&q, event_cb, /*VFs */ false, 
+        err = e10k_queue_create(&q, event_cb, /*VFs */ false,
                                 /*MSIX interrupts*/ false);
         if (err_is_fail(err)){
             USER_PANIC("Allocating devq failed \n");
         }
-        return (struct devq*) q;    
+        return (struct devq*) q;
     }
 
     USER_PANIC("Unknown card name\n");
@@ -185,7 +185,7 @@ static errval_t destroy_net_queue(struct devq* q, char* card_name)
         if (err_is_fail(err)){
             USER_PANIC("Destroying devq failed \n");
         }
-        return err;    
+        return err;
     }
 
     if (strcmp(card_name, "e10k") == 0) {
@@ -193,7 +193,7 @@ static errval_t destroy_net_queue(struct devq* q, char* card_name)
         if (err_is_fail(err)){
             USER_PANIC("Destroying devq failed \n");
         }
-        return err;    
+        return err;
     }
 
     USER_PANIC("Unknown card name\n");
@@ -201,13 +201,13 @@ static errval_t destroy_net_queue(struct devq* q, char* card_name)
     return SYS_ERR_OK;
 }
 
-static void test_net_tx(void) 
+static void test_net_tx(void)
 {
     num_tx = 0;
     num_rx = 0;
 
     errval_t err;
-    struct devq* q;   
+    struct devq* q;
     
 
     q = create_net_queue(card);
@@ -249,16 +249,16 @@ static void test_net_tx(void)
     }
 
     // Send something
-    cycles_t t1 = bench_tsc();   
+    cycles_t t1 = bench_tsc();
 
     for (int z = 0; z < NUM_ROUNDS_TX; z++) {
         for (int i = 0; i < NUM_ENQ; i++) {
-            err = devq_enqueue(q, regid_tx, i*(TX_BUF_SIZE), TX_BUF_SIZE, 
+            err = devq_enqueue(q, regid_tx, i*(TX_BUF_SIZE), TX_BUF_SIZE,
                                0, TX_BUF_SIZE,
                                NETIF_TXFLAG | NETIF_TXFLAG_LAST);
             if (err_is_fail(err)){
                 USER_PANIC("Devq enqueue failed \n");
-            }    
+            }
         }
 
         while(true) {
@@ -278,9 +278,9 @@ static void test_net_tx(void)
     double result_ms = (double) bench_tsc_to_ms(result);
     double bw = sent_bytes / result_ms / 1000;
     
-    printf("Write throughput %.2f [MB/s] for %.2f ms \n", bw, result_ms);  
+    printf("Write throughput %.2f [MB/s] for %.2f ms \n", bw, result_ms);
 
-    err = devq_control(q, 1, 1);
+    err = devq_control(q, 1, 1, NULL);
     if (err_is_fail(err)){
         printf("%s \n", err_getstring(err));
         USER_PANIC("Devq control failed \n");
@@ -302,14 +302,14 @@ static void test_net_tx(void)
 }
 
 
-static void test_net_rx(void) 
+static void test_net_rx(void)
 {
 
     num_tx = 0;
     num_rx = 0;
 
     errval_t err;
-    struct devq* q;   
+    struct devq* q;
    
     q = create_net_queue(card);
     assert(q != NULL);
@@ -337,12 +337,12 @@ static void test_net_rx(void)
     
     // Enqueue RX buffers to receive into
     for (int i = 0; i < NUM_ROUNDS_RX; i++){
-        err = devq_enqueue(q, regid_rx, i*RX_BUF_SIZE, RX_BUF_SIZE, 
+        err = devq_enqueue(q, regid_rx, i*RX_BUF_SIZE, RX_BUF_SIZE,
                            0, RX_BUF_SIZE,
                            NETIF_RXFLAG);
         if (err_is_fail(err)){
             USER_PANIC("Devq enqueue failed: %s\n", err_getstring(err));
-        }    
+        }
 
     }
 
@@ -355,7 +355,7 @@ static void test_net_rx(void)
     }
 
 
-    err = devq_control(q, 1, 1);
+    err = devq_control(q, 1, 1, NULL);
     if (err_is_fail(err)){
         printf("%s \n", err_getstring(err));
         USER_PANIC("Devq control failed \n");
@@ -377,8 +377,8 @@ static void test_net_rx(void)
 }
 
 
-static errval_t descq_notify(struct descq* q) 
-{   
+static errval_t descq_notify(struct descq* q)
+{
     errval_t err = SYS_ERR_OK;
     struct devq* queue = (struct devq*) q;
     
@@ -390,7 +390,7 @@ static errval_t descq_notify(struct descq* q)
     uint64_t flags;
 
     while(err_is_ok(err)) {
-        err = devq_dequeue(queue, &rid, &offset, &length, &valid_data, 
+        err = devq_dequeue(queue, &rid, &offset, &length, &valid_data,
                            &valid_length, &flags);
         if (err_is_ok(err)){
             num_rx++;
@@ -405,20 +405,19 @@ static void test_idc_queue(void)
     num_rx = 0;
 
     errval_t err;
-    struct devq* q;   
+    struct devq* q;
     struct descq* queue;
-    struct descq_func_pointer* f;
-    f = malloc(sizeof(struct descq_func_pointer));
-    f->notify = descq_notify;
-
-    printf("Descriptor queue test started \n");
+    struct descq_func_pointer f;
+    f.notify = descq_notify;
+    
+    debug_printf("Descriptor queue test started \n");
     err = descq_create(&queue, DESCQ_DEFAULT_SIZE, "test_queue",
-                       false, f);
+                       false, true, true, NULL, &f);
     if (err_is_fail(err)){
         USER_PANIC("Allocating devq failed \n");
-    }    
+    }
    
-    q = (struct devq*) queue;    
+    q = (struct devq*) queue;
 
     err = devq_register(q, memory_rx, &regid_rx);
     if (err_is_fail(err)){
@@ -454,7 +453,7 @@ static void test_idc_queue(void)
         event_dispatch(get_default_waitset());
     }
 
-    err = devq_control(q, 1, 1);
+    err = devq_control(q, 1, 1, NULL);
     if (err_is_fail(err)){
         printf("%s \n", err_getstring(err));
         USER_PANIC("Devq control failed \n");
@@ -476,18 +475,18 @@ static void test_idc_queue(void)
 }
 
 int main(int argc, char *argv[])
-{   
+{
     errval_t err;
     // Allocate memory
     err = frame_alloc(&memory_rx, MEMORY_SIZE, NULL);
     if (err_is_fail(err)){
         USER_PANIC("Allocating cap failed \n");
-    }    
+    }
 
     err = frame_alloc(&memory_tx, MEMORY_SIZE, NULL);
     if (err_is_fail(err)){
         USER_PANIC("Allocating cap failed \n");
-    }    
+    }
     
     // RX frame
     err = invoke_frame_identify(memory_rx, &id);
@@ -496,7 +495,7 @@ int main(int argc, char *argv[])
     }
 
     err = vspace_map_one_frame_attr(&va_rx, id.bytes, memory_rx,
-                                    VREGION_FLAGS_READ, NULL, NULL); 
+                                    VREGION_FLAGS_READ, NULL, NULL);
     if (err_is_fail(err)) {
         USER_PANIC("Frame mapping failed \n");
     }
@@ -510,7 +509,7 @@ int main(int argc, char *argv[])
     }
    
     err = vspace_map_one_frame_attr(&va_tx, id.bytes, memory_tx,
-                                    VREGION_FLAGS_WRITE, NULL, NULL); 
+                                    VREGION_FLAGS_WRITE, NULL, NULL);
     if (err_is_fail(err)) {
         USER_PANIC("Frame mapping failed \n");
     }