interface net_queue_manager "Ethernet hardware RX/TX queue manager" {
/* antoinek: I think most of the queue id arguments are not needed here */
- message register_buffer(cap buf,
- cap sp,
- uint64 queueid,
- uint64 slots,
- uint8 role);
- message new_buffer_id(errval err,
- uint64 queueid,
- uint64 idx);
-
- message get_mac_address(uint64 queueid);
- message get_mac_address_response(uint64 queueid, uint64 hwaddr);
+ rpc register_buffer(in cap buf,
+ in cap sp,
+ in uint64 queueid,
+ in uint64 slots,
+ in uint8 role,
+ in cap queue,
+ out uint64 idx);
+ rpc get_mac_address(in uint64 queueid, out uint64 hwaddr);
message sp_notification_from_app(uint64 queueid, uint64 type,
uint64 ts);
message raw_xmit_done(uint64 offset, uint64 length, uint64 more,
uint64 flags);
-
message print_statistics(uint64 queueid);
message print_cardinfo();
message benchmark_control_request(uint64 queueid, uint8 state,
interface net_soft_filters "Software based filter Interface" {
- message register_filter_memory_request(cap mem);
- message register_filter_memory_response(errval err);
-
- message register_filter_request(uint64 id,
- uint64 len_rx,
- uint64 len_tx,
- uint64 buffer_id_rx,
- uint64 buffer_id_tx,
- uint64 filter_type,
- uint64 paused);
- message register_filter_response(uint64 id,
- errval err,
- uint64 filter_id,
- uint64 buffer_id_rx,
- uint64 buffer_id_tx,
- uint64 filter_type);
-
- message re_register_filter_request(uint64 filter_id,
- uint64 buffer_id_rx,
- uint64 buffer_id_tx);
- message re_register_filter_response(errval err,
- uint64 filter_id,
- uint64 buffer_id_rx,
- uint64 buffer_id_tx);
-
- message deregister_filter_request(uint64 filter_id);
- message deregister_filter_response(errval err,
- uint64 filter_id);
-
- message register_arp_filter_request(uint64 id,
- uint64 len_rx,
- uint64 len_tx);
- message register_arp_filter_response(uint64 id,
- errval err);
-
- message pause(uint64 filter_id, uint64 buffer_id_rx, uint64 buffer_id_tx);
- message pause_response(uint64 filter_id, errval err);
- message unpause(uint64 filter_id);
- message unpause_response(uint64 filter_id, errval err);
+ rpc register_filter_memory(in cap mem, out errval err);
+
+ rpc register_filter(in uint64 id,
+ in uint64 len_rx,
+ in uint64 len_tx,
+ in uint64 buffer_id_rx,
+ in uint64 buffer_id_tx,
+ in uint64 filter_type,
+ in uint64 paused,
+ out errval err,
+ out uint64 filter_id);
+
+ rpc re_register_filter(in uint64 filter_id,
+ in uint64 buffer_id_rx,
+ in uint64 buffer_id_tx,
+ out errval err);
+
+ rpc deregister_filter(in uint64 filter_id,
+ out errval err);
+
+ rpc register_arp_filter(in uint64 id,
+ in uint64 len_rx,
+ in uint64 len_tx,
+ out errval err);
+
+ rpc pause(in uint64 filter_id, in uint64 buffer_id_rx, in uint64 buffer_id_tx,
+ out errval err);
+ rpc unpause(in uint64 filter_id, out errval err);
/* Hack to pass the mac addr info to */
- message mac_address_request();
- message mac_address_response(errval err, uint64 macaddr);
+ rpc mac_address(out errval err, out uint64 macaddr);
};
-
#include <barrelfish/barrelfish.h>
#include <barrelfish/bulk_transfer.h>
-#include <contmng/contmng.h>
#include <contmng/netbench.h>
#include <procon/procon.h>
#include <barrelfish/net_constants.h>
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;
// 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
//debug
void print_statistics(void);
+void check_queues(void);
+
// For recording statistics
if (kcb->irq_dispatch[i].cap.type == ObjType_EndPoint) {
struct capability *cap = &kcb->irq_dispatch[i].cap;
// 1 word message as notification
- errval_t err = lmp_deliver_payload(cap, NULL, msg, 1, false);
+ errval_t err = lmp_deliver_payload(cap, NULL, msg, 1, false, false);
if (err_is_fail(err)) {
if (err_no(err) == SYS_ERR_LMP_BUF_OVERFLOW) {
struct dispatcher_shared_generic *disp =
NULL,
(uintptr_t*) &data,
payload_len,
- false);
+ false, false);
// Make sure delivery was okay. SYS_ERR_LMP_BUF_OVERFLOW is okay for now
assert(err_is_ok(err) || err_no(err)==SYS_ERR_LMP_BUF_OVERFLOW);
retval.error = lmp_deliver(to, dcb_current, args, length_words,
arg1, send_level, give_away);
- /* Switch to reciever upon successful delivery with sync flag,
+ /* Switch to receiver upon successful delivery with sync flag,
* or (some cases of) unsuccessful delivery with yield flag */
enum err_code err_code = err_no(retval.error);
if ((sync && err_is_ok(retval.error)) ||
save_area = &disp->enabled_save_area;
}
- // Should be enabled. Else, how do we do an invocation??
- if(dcb_current->disabled) {
- panic("Dispatcher needs to be enabled for this invocation");
- }
-
- // save calling dispatcher's registers, so that when the dispatcher
- // next runs, it has a valid state in the relevant save area.
- // Save RIP, RFLAGS, RSP and set RAX (return value) for later resume
- save_area->rax = retval.error; // XXX: x86 1st return register
- save_area->rip = rip;
- save_area->eflags = rflags;
- save_area->rsp = user_stack_save;
-
- if(!dcb_current->is_vm_guest) {
- /* save and zero FS/GS selectors (they're unmodified by the syscall path) */
- __asm ("mov %%fs, %[fs] \n\t"
- "mov %%gs, %[gs] \n\t"
- "mov %[zero], %%fs \n\t"
- "mov %[zero], %%gs \n\t"
- : /* No output */
- :
- [fs] "m" (save_area->fs),
- [gs] "m" (save_area->gs),
- [zero] "r" (0)
- );
- } else {
+ // Should be enabled. Else, how do we do an invocation??
+ if (dcb_current->disabled) {
+ panic("Dispatcher needs to be enabled for this invocation");
+ }
+
+ // save calling dispatcher's registers, so that when the dispatcher
+ // next runs, it has a valid state in the relevant save area.
+ // Save RIP, RFLAGS, RSP and set RAX (return value) for later resume
+ save_area->rax = retval.error; // XXX: x86 1st return register
+ save_area->rip = rip;
+ save_area->eflags = rflags;
+ save_area->rsp = user_stack_save;
+
+ if (!dcb_current->is_vm_guest) {
+ /* save and zero FS/GS selectors (they're unmodified by the syscall path) */
+ __asm ("mov %%fs, %[fs] \n\t"
+ "mov %%gs, %[gs] \n\t"
+ "mov %[zero], %%fs \n\t"
+ "mov %[zero], %%gs \n\t"
+ : /* No output */
+ :
+ [fs] "m" (save_area->fs),
+ [gs] "m" (save_area->gs),
+ [zero] "r" (0)
+ );
+ } else {
#ifndef __k1om__
#ifdef CONFIG_SVM
- lpaddr_t lpaddr = gen_phys_to_local_phys(dcb_current->guest_desc.vmcb.cap.u.frame.base);
- amd_vmcb_t vmcb;
- amd_vmcb_initialize(&vmcb, (void *)local_phys_to_mem(lpaddr));
- save_area->fs = amd_vmcb_fs_selector_rd(&vmcb);
- save_area->gs = amd_vmcb_gs_selector_rd(&vmcb);
+ lpaddr_t lpaddr = gen_phys_to_local_phys(dcb_current->guest_desc.vmcb.cap.u.frame.base);
+ amd_vmcb_t vmcb;
+ amd_vmcb_initialize(&vmcb, (void *)local_phys_to_mem(lpaddr));
+ save_area->fs = amd_vmcb_fs_selector_rd(&vmcb);
+ save_area->gs = amd_vmcb_gs_selector_rd(&vmcb);
#else
- errval_t err;
- err = vmread(VMX_GUEST_FS_SEL, (uint64_t *)&save_area->fs);
- err += vmread(VMX_GUEST_GS_SEL, (uint64_t *)&save_area->gs);
- assert(err_is_ok(err));
+ errval_t err;
+ err = vmread(VMX_GUEST_FS_SEL, (uint64_t *)&save_area->fs);
+ err += vmread(VMX_GUEST_GS_SEL, (uint64_t *)&save_area->gs);
+ assert(err_is_ok(err));
#endif
#else
- panic("VM Guests not supported on Xeon Phi");
+ panic("VM Guests not supported on Xeon Phi");
#endif
- }
-
+ }
dispatch(to->u.endpoint.listener);
panic("dispatch returned");
+ } else {
+ struct dcb *dcb = to->u.endpoint.listener;
+
+ schedule_now(dcb);
}
} else { // not endpoint cap, call kernel handler through dispatch table
// printk(LOG_NOTE, "sys_invoke: to->type = %d, cmd = %"PRIu64"\n",
monitor_ep.u.endpoint.listener = NULL;
} else if (monitor_ep.u.endpoint.listener != NULL) {
uintptr_t payload = dcb->domain_id;
- err = lmp_deliver_payload(&monitor_ep, NULL, &payload, 1, false);
+ err = lmp_deliver_payload(&monitor_ep, NULL, &payload, 1, false, false);
if (err_is_fail(err)) {
printk(LOG_NOTE, "while notifying monitor about domain exit: %"PRIuERRV".\n", err);
printk(LOG_NOTE, "please add the console output to the following bug report: https://code.systems.ethz.ch/T78\n");
// XXX: This looks pretty ugly. We need an interface.
err = lmp_deliver_payload(&monitor_ep, NULL,
(uintptr_t *)&ram,
- len, false);
+ len, false, false);
}
else {
printk(LOG_WARN, "dropping ram cap base %08"PRIxGENPADDR" bytes 0x%"PRIxGENSIZE"\n", ram.base, ram.bytes);
disp->systime = kernel_now + kcb_current->kernel_off;
}
TRACE(KERNEL, SC_YIELD, 1);
-
+
if (dcb->disabled) {
if (disp != NULL) {
- debug(SUBSYS_DISPATCH, "resume %.*s at 0x%" PRIx64 ", %s\n",
- DISP_NAME_LEN, disp->name,
+ debug(SUBSYS_DISPATCH, "resume %.*s at 0x%" PRIx64 ", %s\n",
+ DISP_NAME_LEN, disp->name,
(uint64_t)registers_get_ip(disabled_area),
disp->disabled ? "disp->disabled" : "disp->enabled"
);
*/
errval_t lmp_deliver_payload(struct capability *ep, struct dcb *send,
uintptr_t *payload, size_t payload_len,
- bool captransfer)
+ bool captransfer, bool now)
{
assert(ep != NULL);
assert(ep->type == ObjType_EndPoint);
// Make target runnable
make_runnable(recv);
+ if (now)
+ schedule_now(recv);
return SYS_ERR_OK;
}
}
/* Send msg */
- err = lmp_deliver_payload(ep, send, payload, len, captransfer);
+ err = lmp_deliver_payload(ep, send, payload, len, captransfer, false);
// shouldn't fail, if we delivered the cap successfully
assert(!(captransfer && err_is_fail(err)));
return err;
size_t payload_len);
errval_t lmp_deliver_payload(struct capability *ep, struct dcb *send,
uintptr_t *payload, size_t payload_len,
- bool captransfer);
+ bool captransfer, bool now);
errval_t lmp_deliver(struct capability *ep, struct dcb *send,
uintptr_t *payload, size_t payload_len,
capaddr_t send_cptr, uint8_t send_bits, bool give_away);
/// Deliver an empty LMP as a notification
static inline errval_t lmp_deliver_notification(struct capability *ep)
{
- return lmp_deliver_payload(ep, NULL, NULL, 0, false);
+ return lmp_deliver_payload(ep, NULL, NULL, 0, false, true);
}
/// Reset csc
struct dcb *schedule(void);
void make_runnable(struct dcb *dcb);
+void schedule_now(struct dcb *dcb);
void scheduler_remove(struct dcb *dcb);
void scheduler_yield(struct dcb *dcb);
void scheduler_reset_time(void);
goto start_over;
}
+void schedule_now(struct dcb *dcb)
+{
+ if (dcb->release_time >= kernel_now) {
+ dcb->release_time = kernel_now;
+ }
+ dcb->deadline = 1;
+}
+
void make_runnable(struct dcb *dcb)
{
// No-Op if already in schedule
#include <lwip/ip_addr.h>
#include <if/net_queue_manager_defs.h>
#include <procon/procon.h>
-#include <contmng/contmng.h>
/**
* \brief Receive and transmit sides
#include <netif/etharp.h>
#include <netif/bfeth.h>
#include "lwip/init.h"
-#include <contmng/contmng.h>
#include <contmng/netbench.h>
#include <if/net_ports_defs.h>
#include <if/net_ports_rpcclient_defs.h>
/* create a linked list of memp elements */
for (j = 0; j < memp_num[i]; ++j) {
- memp->next = NULL;
memp->next = memp_tab[i];
memp_tab[i] = memp;
memp = (struct memp *) ((u8_t *) memp + memp_sizes[i]);
}
- // Check if there is anything else that we should before sending back the
- // ack that we consumed packet.
-
- perform_lwip_work();
-
//now we have consumed the preregistered pbuf containing a received packet
//which was processed in this function. Therefore we have to register a new
//free buffer for receiving packets. We can reuse the odl buffer's index
"soft_filt_cl_impl.c", "e10k_filt_cl_impl.c", "portalloc.c" ],
flounderBindings = [ "net_soft_filters", "net_ports",
"e10k" ],
- addLibraries = [ "contmng", "bfdmuxtools", "trace"
+ flounderExtraBindings = [ ("net_soft_filters", ["rpcclient"])],
+ addLibraries = [ "bfdmuxtools", "trace"
-- try to get rid of "lwip" as it is only used for hton[s/l]
, "lwip"
]
bp->closing = false;
bp->redirected = false;
+ // add this flow to the list of all flows for this app
+ bp->next = this_net_app->open_ports;
+ this_net_app->open_ports = bp;
+
// FIXME: qlist[queueid].insert_rule();
err = qlist[queueid].filt_mng->reg_filters(port, type, buffer_id_rx,
buffer_id_tx, appid, queueid);
return err;
} // end if: err
- // add this flow to the list of all flows for this app
- bp->next = this_net_app->open_ports;
- this_net_app->open_ports = bp;
-
NDM_DEBUG("res_port: waiting for response\n");
return err;
} // end function: res_port
}
+
#include <barrelfish/bulk_transfer.h>
//#include <net_device_manager/net_ports_service.h>
#include <if/net_soft_filters_defs.h>
+#include <if/net_soft_filters_rpcclient_defs.h>
//#include <if/net_ports_defs.h>
-#include <contmng/contmng.h>
// For filter generation
#include <bfdmuxtools/tools.h>
#define REDIRECT_FILTER (2)
/****************************************************************
-* Global datastructure
-*****************************************************************/
-// client closure for connection between netd and ethernet driver
-struct client_closure_ND {
- struct cont_queue *q;
-};
-
-
-/****************************************************************
* Local states
*****************************************************************/
static void share_common_memory_with_filter_manager(void);
static void sf_mac_lookup(void);
-static void register_filter_memory_response(
- struct net_soft_filters_binding *st,
- errval_t err);
static void send_soft_filter(uint64_t id, uint64_t len_rx, uint64_t len_tx,
uint64_t buffer_id_rx, uint64_t buffer_id_tx,
uint8_t ftype, uint8_t paused);
-
-static void deregister_filter_response(struct net_soft_filters_binding *st,
- errval_t err, uint64_t filter_id);
-static void register_filter_response(struct net_soft_filters_binding *st,
- uint64_t id, errval_t err,
- uint64_t filter_id, uint64_t buffer_id_rx,
- uint64_t buffer_id_tx, uint64_t ftype);
-static void register_arp_filter_response(struct net_soft_filters_binding *st,
- uint64_t id, errval_t err);
-
-
-static void sf_mac_address_response(struct net_soft_filters_binding *st,
- errval_t err, uint64_t mac);
-
-
-static struct net_soft_filters_rx_vtbl rx_vtbl = {
- .register_filter_memory_response = register_filter_memory_response,
- .register_filter_response = register_filter_response,
- .deregister_filter_response = deregister_filter_response,
- .register_arp_filter_response = register_arp_filter_response,
-// .pause_response = pause_response,
- .mac_address_response = sf_mac_address_response,
-};
-
// *****************************************************************
// * Get signature of this service
// *****************************************************************
}
NDM_DEBUG("soft_filters_bind_cb: started\n");
-
- struct client_closure_ND *ccnd = (struct client_closure_ND *)
- malloc(sizeof(struct client_closure_ND));
-
- memset(ccnd, 0, sizeof(struct client_closure_ND));
- ccnd->q = create_cont_q("SF_C");
-
- // set client closure
- enb->st = ccnd;
- // copy my message receive handler vtable to the binding
- enb->rx_vtbl = rx_vtbl;
+ struct net_soft_filters_rpc_client *rpc_client = malloc(sizeof(struct net_soft_filters_rpc_client));
+ net_soft_filters_rpc_client_init(rpc_client, enb);
+ enb->st = rpc_client;
soft_filters_connection = enb;
NDM_DEBUG(" soft_filters_bind_cb: connection made,"
// * filter memory registration
// * One time process
// *****************************************************************
-static errval_t send_filter_memory_cap(struct q_entry e)
-{
- struct net_soft_filters_binding *b =
- (struct net_soft_filters_binding *) e.binding_ptr;
- struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.register_filter_memory_request(b,
- MKCONT
- (cont_queue_callback,
- ccnc->q), e.cap);
- } else {
- NDM_DEBUG("send_filter_memory_cap: Flounder busy,rtry++\n");
- return FLOUNDER_ERR_TX_BUSY;
- }
-}
-
-
-/**
-* \brief: Called by driver when memory is registered with driver.
-*/
-static void register_filter_memory_response(
- struct net_soft_filters_binding *st,
- errval_t err)
-{
- assert(err_is_ok(err));
- soft_filters_ready = true;
- NDM_DEBUG("########################################################\n");
- NDM_DEBUG("memory registration successful.\n");
-}
-
-
/**
* \brief sends cap to the memory which is to be shared between filter_manager
* of network driver and netd.
*/
static void register_filter_memory(struct capref cap)
{
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_filter_memory_cap;
struct net_soft_filters_binding *b = soft_filters_connection;
+ struct net_soft_filters_rpc_client *rpc = b->st;
- entry.binding_ptr = (void *) b;
- struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
- entry.cap = cap;
- enqueue_cont_q(ccnc->q, &entry);
-
- NDM_DEBUG("register_filter_memory: terminated\n");
+ errval_t err, rerr;
+ err = rpc->vtbl.register_filter_memory(rpc, cap, &rerr);
+ assert(err_is_ok(err));
+ assert(err_is_ok(rerr));
+ soft_filters_ready = true;
}
filter_mem_lock = false; // marking memory as ready to use
} // end function: share_common_memory_with_filter_manager
-
-static errval_t send_mac_address_request(struct q_entry e)
-{
- struct net_soft_filters_binding *b =
- (struct net_soft_filters_binding *) e.binding_ptr;
- struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.mac_address_request(b,
- MKCONT(cont_queue_callback, ccnc->q));
- } else {
- NDM_DEBUG("send_mac_address_request: Flounder busy,rtry++\n");
- return FLOUNDER_ERR_TX_BUSY;
- }
-} // end function: send_mac_address_request
-
-// lookup the mac address
-static void sf_mac_lookup(void)
-{
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_mac_address_request;
- struct net_soft_filters_binding *b = soft_filters_connection;
-
- entry.binding_ptr = (void *) b;
- struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
- enqueue_cont_q(ccnc->q, &entry);
-
- // waiting for mac address response.
- NDM_DEBUG("connect_to_ether_filter_manager: wait connection\n");
- while (!valid_mac_addr_assigned) {
- messages_wait_and_handle_next();
- }
-
-
- NDM_DEBUG("sf_mac_lookup: terminated\n");
-} // end function: sf_mac_lookup
-
-// *****************************************************************
-// * filter memory registration
-// * One time process
-// *****************************************************************
-
-static void deregister_filter_response(struct net_soft_filters_binding *st,
- errval_t err, uint64_t filter_id)
-{
- if (err_is_ok(err)) {
- NDM_DEBUG("filter at id %" PRIu64 " deregistered.\n", filter_id);
- }
-}
-
-static void register_filter_response(struct net_soft_filters_binding *st,
- uint64_t id, errval_t err,
- uint64_t filter_id, uint64_t buffer_id_rx,
- uint64_t buffer_id_tx, uint64_t ftype)
-{
- assert(err_is_ok(err));
- NDM_DEBUG("filter at id [%" PRIu64 "] type[%" PRIu64
- "] registered with filt_id %" PRIu64 ".\n", id, ftype,
- filter_id);
-
- /* free the memory in shared area */
- errval_t free_err = bulk_free(&bt_filter_tx, id);
-
- assert(err_is_ok(free_err));
- filter_mem_lock = false; // NOTE: filter memory can be used by others now
-
- handle_filter_response(id, err, filter_id, buffer_id_rx, buffer_id_tx,
- ftype);
-
-}
-
-static void register_arp_filter_response(struct net_soft_filters_binding *st,
- uint64_t id, errval_t err)
-{
-
- if (err_is_fail(err)) {
- DEBUG_ERR(err, "register_arp_filter_response failed for ID %" PRIu64 "",
- id);
- abort();
- }
- NDM_DEBUG("register_arp_filter_response: ARP filter ID %" PRIu64
- " registered\n", id);
-
- assert(!"NYI register_arp_filter_response");
-}
-
// Support code to convert mac address from uint64_t into eth_addr type
union mac_addr_un1 {
struct eth_addr ethaddr;
return tmp_mac.ethaddr;
}
-
-static void sf_mac_address_response(struct net_soft_filters_binding *st,
- errval_t err, uint64_t mac_addr)
+// lookup the mac address
+static void sf_mac_lookup(void)
{
- if (err_is_fail(err)) {
- DEBUG_ERR(err, "sf_mac_address_response failed\n");
- abort();
- }
- assert(mac_addr != 0);
-
- NDM_DEBUG("sf_mac_address_response: reported MAC addr %" PRIu64 "\n",
- mac_addr);
+ struct net_soft_filters_binding *b = soft_filters_connection;
+ struct net_soft_filters_rpc_client *rpc = b->st;
+ uint64_t mac_addr;
+ errval_t err, rerr;
+ err = rpc->vtbl.mac_address(rpc, &rerr, &mac_addr);
+ assert(err_is_ok(err));
+ assert(err_is_ok(rerr));
mac = my_convert_uint64_to_eth_addr(mac_addr);
valid_mac_addr_assigned = true;
-}
-
-/********* Functionality for filter registration *********/
-
-static errval_t send_filter_for_registration(struct q_entry e)
-{
- struct net_soft_filters_binding *b =
- (struct net_soft_filters_binding *) e.binding_ptr;
- struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.register_filter_request(b,
- MKCONT(cont_queue_callback,
- ccnc->q), e.plist[0],
- e.plist[1], e.plist[2],
- e.plist[3], e.plist[4],
- e.plist[5], e.plist[6]);
- // id, len_rx, len_tx, buf_id_rx, buf_id_rx, ftype, paused
-
- } else {
- NDM_DEBUG("send_filter_for_registration: ID %" PRIu64
- " Flounder busy,rtry++\n", e.plist[0]);
- return FLOUNDER_ERR_TX_BUSY;
- }
-} // end function:
+} // end function: sf_mac_lookup
/**
* \brief sends the filter for registration to network driver.
NDM_DEBUG("send_soft_filter: called for id %" PRIu64
" and type %x, paused = %d\n", id, ftype, paused);
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_filter_for_registration;
-
struct net_soft_filters_binding *b = soft_filters_connection;
+ struct net_soft_filters_rpc_client *rpc = b->st;
- entry.binding_ptr = (void *) b;
-
- struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
+ errval_t err, rerr;
+ uint64_t filter_id;
+ err = rpc->vtbl.register_filter(rpc, id, len_rx, len_tx, buffer_id_rx, buffer_id_tx, ftype, paused, &rerr, &filter_id);
+ assert(err_is_ok(err));
+ assert(err_is_ok(rerr));
+ NDM_DEBUG("filter at id [%" PRIu64 "] type[%" PRIu64
+ "] registered with filt_id %" PRIu64 ".\n", id, ftype,
+ filter_id);
- entry.plist[0] = id;
- entry.plist[1] = len_rx;
- entry.plist[2] = len_tx;
- entry.plist[3] = buffer_id_rx;
- entry.plist[4] = buffer_id_tx;
- entry.plist[5] = ftype;
- entry.plist[6] = paused;
- /* e.plist[0], e.plist[1], e.plist[2], e.plist[3], e.plist[4], e.plist[4]);
- e.id, e.len_rx, e.len_tx, e.buffer_id_rx, e.buffer_id_rx, ftype */
+ /* free the memory in shared area */
+ err = bulk_free(&bt_filter_tx, id);
+ assert(err_is_ok(err));
- enqueue_cont_q(ccnc->q, &entry);
+ filter_mem_lock = false; // NOTE: filter memory can be used by others now
- NDM_DEBUG("send_soft_filter: terminated for id %" PRIu64 "\n", id);
+ handle_filter_response(id, err, filter_id, buffer_id_rx, buffer_id_tx,
+ ftype);
} // end function: send_soft_filter
-static errval_t send_filterID_for_deregistration(struct q_entry e)
-{
- struct net_soft_filters_binding *b =
- (struct net_soft_filters_binding *) e.binding_ptr;
- struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.deregister_filter_request(b,
- MKCONT(cont_queue_callback,
- ccnc->q),
- e.plist[0]);
- /* e.filterID */
-
- } else {
- NDM_DEBUG("send_filterID_for_deregistration: ID %" PRIu64
- " Flounder busy,rtry++\n", e.plist[0]);
- return FLOUNDER_ERR_TX_BUSY;
- }
-} // end function: send_filterID_for_deregistration
-
/**
* \brief sends the filterID for de-registration to network driver.
*
*/
static void unregister_soft_filter(uint64_t filter_id, qid_t qid)
{
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_filterID_for_deregistration;
-
struct net_soft_filters_binding *b = soft_filters_connection;
+ struct net_soft_filters_rpc_client *rpc = b->st;
- entry.binding_ptr = (void *) b;
-
- struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
- entry.plist[0] = filter_id;
- /* e.plist[0]
- e.filter_id */
-
- enqueue_cont_q(ccnc->q, &entry);;
+ errval_t err, rerr;
+ err = rpc->vtbl.deregister_filter(rpc, filter_id, &rerr);
+ assert(err_is_ok(err));
+ assert(err_is_ok(rerr));
} // end function: unregister_soft_filter
-
-static errval_t send_arp_filter_for_registration(struct q_entry e)
-{
- struct net_soft_filters_binding *b =
- (struct net_soft_filters_binding *) e.binding_ptr;
- struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.register_arp_filter_request(b,
- MKCONT
- (cont_queue_callback,
- ccnc->q), e.plist[0],
- e.plist[1], e.plist[2]);
- /* id, e.len_rx, e.len_tx */
-
- } else {
- NDM_DEBUG("send_arp_filter_for_registration: Flounder busy,rtry++\n");
- return FLOUNDER_ERR_TX_BUSY;
- }
-
-}
-
/**
* \brief sends the filter for registration to network driver.
*
uint64_t len_tx)
{
NDM_DEBUG("register_arp_soft_filter: called\n");
-
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_arp_filter_for_registration;
-
struct net_soft_filters_binding *b = soft_filters_connection;
+ struct net_soft_filters_rpc_client *rpc = b->st;
- entry.binding_ptr = (void *) b;
-
- struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
- entry.plist[0] = id;
- entry.plist[1] = len_rx;
- entry.plist[2] = len_tx;
- /* e.plist[0], e.plist[1], e.plist[2]
- id, e.len_rx, e.len_tx */
-
- enqueue_cont_q(ccnc->q, &entry);
+ errval_t err, rerr;
+ err = rpc->vtbl.register_arp_filter(rpc, id, len_rx, len_tx, &rerr);
+ assert(err_is_ok(err));
+ assert(err_is_ok(rerr));
- NDM_DEBUG("register_arp_soft_filter: terminated\n");
} // end function: register_arp_soft_filter
-
-
static uint64_t populate_rx_tx_filter_mem(uint16_t port, net_ports_port_type_t type,
int32_t * len_rx, int32_t * len_tx)
{
return id;
}
-
-
[ build library { target = "net_if_raw",
cFiles = [ "interface_raw.c" ],
flounderBindings = [ "net_queue_manager" ],
- addLibraries = [ "contmng" ] }
+ flounderExtraBindings = [("net_queue_manager", ["rpcclient"])] }
]
#include <barrelfish/net_constants.h>
#include <if/net_queue_manager_defs.h>
-#include <contmng/contmng.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)
-
-static void idc_register_buffer(struct net_queue_manager_binding *binding,
- struct capref buf, struct capref sp,
- uint64_t qid, uint64_t slots, uint8_t role);
+#define QUEUE_SIZE 512
static errval_t idc_raw_add_buffer(struct net_queue_manager_binding *binding,
- uint64_t offset, uint64_t len,
+ uint64_t *queue, uint64_t offset, uint64_t len,
uint64_t more_chunks, uint64_t flags,
bool blocking);
-static void idc_get_mac_address(struct net_queue_manager_binding *binding,
- uint64_t qid);
-
static uint64_t queue = 0;
static uint64_t card_mac = -1ULL;
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 err = SYS_ERR_OK;
- err = idc_raw_add_buffer(binding_tx, idx * BUFFER_SIZE + offset, len,
+ err = idc_raw_add_buffer(binding_tx, tx_queue_base, idx * BUFFER_SIZE + offset, len,
(uint64_t)more_chunks, flags, 0);
return err;
}
{
errval_t err = SYS_ERR_OK;
- err = idc_raw_add_buffer(binding_rx, idx * BUFFER_SIZE, BUFFER_SIZE, 0, 0, 1);
+ err = idc_raw_add_buffer(binding_rx, rx_queue_base, idx * BUFFER_SIZE, BUFFER_SIZE, 0, 0, 0);
return err;
}
static void buffers_init(size_t count)
{
- struct waitset *ws = get_default_waitset();
-
alloc_mem(&buffer_frame, &buffer_base, BUFFER_SIZE * count);
- idc_register_buffer(binding_rx, buffer_frame, NULL_CAP, queue, count,
- RX_BUFFER_ID);
- while (bufid_rx == -1ULL) { event_dispatch(ws); }
-
- idc_register_buffer(binding_tx, buffer_frame, NULL_CAP, queue, count,
- TX_BUFFER_ID);
- while (bufid_tx == -1ULL) { event_dispatch(ws); }
+ 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);
+ assert(err_is_ok(err));
+ err = register_buffer(binding_tx, buffer_frame, NULL_CAP, queue, count,
+ TX_BUFFER_ID, tx_queue_frame, &bufid_tx);
+ assert(err_is_ok(err));
}
/******************************************************************************/
/* Flounder interface */
-static errval_t send_raw_add_buffer(struct q_entry entry)
-{
- struct net_queue_manager_binding *b = entry.binding_ptr;
-
- if (b->can_send(b)) {
-
- errval_t err = b->tx_vtbl.raw_add_buffer(
- b, MKCONT(cont_queue_callback, b->st),
- entry.plist[0], entry.plist[1], entry.plist[2],
- entry.plist[3]);
- return err;
- } else {
- return FLOUNDER_ERR_TX_BUSY;
- }
-}
-
-
-static errval_t idc_raw_add_buffer(struct net_queue_manager_binding *binding,
+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)
{
-
- struct q_entry entry;
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_raw_add_buffer;
- entry.binding_ptr = binding;
- entry.plist[0] = offset;
- entry.plist[1] = len;
- entry.plist[2] = more_chunks;
- entry.plist[3] = flags;
-
-
- struct waitset *ws = get_default_waitset();
- int passed_events = 0;
- while (can_enqueue_cont_q(binding->st) == false) {
- if (passed_events > 5) {
- return CONT_ERR_NO_MORE_SLOTS;
+ 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);
}
- event_dispatch(ws);
- ++passed_events;
- }
-
-
- if (blocking) {
- while (queue_used_slots(binding->st) > 1) {
- /*
- printf("%s:The event count is %d\n", disp_name(),
- queue_used_slots(binding->st));
- cont_queue_show_queue(binding->st);
- */
- event_dispatch(ws);
+ 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);
}
}
-
- enqueue_cont_q(binding->st, &entry);
return SYS_ERR_OK;
}
-static errval_t send_register_buffer(struct q_entry entry)
-{
- struct net_queue_manager_binding *b = entry.binding_ptr;
-
- if (b->can_send(b)) {
-// printf("#### send_register_buffer, calling continuation\n");
- errval_t err = b->tx_vtbl.register_buffer(
- b, MKCONT(cont_queue_callback, b->st),
- entry.cap, entry.cap2,
- entry.plist[0], entry.plist[1], entry.plist[2]);
- return err;
- } else {
- return FLOUNDER_ERR_TX_BUSY;
- }
-}
-
-
-static void idc_register_buffer(struct net_queue_manager_binding *binding,
- struct capref buf, struct capref sp,
- uint64_t qid, uint64_t slots, uint8_t role)
-{
- struct q_entry entry;
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_register_buffer;
- entry.binding_ptr = binding;
- entry.cap = buf;
- entry.cap2 = sp;
- entry.plist[0] = qid;
- entry.plist[1] = slots;
- entry.plist[2] = role;
-
- enqueue_cont_q(binding->st, &entry);
-}
-
-static errval_t send_get_mac_address(struct q_entry entry)
-{
- struct net_queue_manager_binding *b = entry.binding_ptr;
-
- if (b->can_send(b)) {
- // printf("#### send_get_mac_address, calling continuation\n");
- errval_t err = b->tx_vtbl.get_mac_address(
- b, MKCONT(cont_queue_callback, b->st),
- entry.plist[0]);
- return err;
- } else {
- return FLOUNDER_ERR_TX_BUSY;
- }
-}
-
-
-static void idc_get_mac_address(struct net_queue_manager_binding *binding,
- uint64_t qid)
-{
- struct q_entry entry;
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_get_mac_address;
- entry.binding_ptr = binding;
- entry.plist[0] = qid;
-
- enqueue_cont_q(binding->st, &entry);
-}
-
-static void new_buffer_id(struct net_queue_manager_binding *st, errval_t err,
- uint64_t queueid, uint64_t buffer_id)
-{
- assert(err_is_ok(err));
-
- if (st == binding_rx) {
- bufid_rx = buffer_id;
- } else {
- bufid_tx = buffer_id;
- }
-}
-
// Returns the bufferid for specified type (RX, TX)
uint64_t get_rx_bufferid(void)
{
uint64_t offset, uint64_t len, uint64_t more,
uint64_t flags)
{
- size_t idx = offset / BUFFER_SIZE;
-
if (st == binding_rx) {
- benchmark_rx_done(idx, len, more, flags);
+ 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 {
- benchmark_tx_done(idx);
+ 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 void get_mac_address_response(struct net_queue_manager_binding *st,
- uint64_t qid, uint64_t mac)
-{
- card_mac = mac;
-}
-
static struct net_queue_manager_rx_vtbl rx_vtbl = {
- .new_buffer_id = new_buffer_id,
.raw_xmit_done = raw_xmit_done,
- .get_mac_address_response = get_mac_address_response,
};
{
assert(err_is_ok(err));
- b->st = create_cont_q("interface_raw_rx");
-// struct cont_queue *q = (struct cont_queue *)b->st;
-// q->debug = 1;
b->rx_vtbl = rx_vtbl;
+ b->control(b, IDC_CONTROL_CLEAR_SYNC);
binding_rx = b;
}
{
assert(err_is_ok(err));
- b->st = create_cont_q("interface_raw_tx");
-// struct cont_queue *q = (struct cont_queue *)b->st;
-// q->debug = 1;
b->rx_vtbl = rx_vtbl;
+ b->control(b, IDC_CONTROL_CLEAR_SYNC);
binding_tx = b;
}
-static void connect_to_driver(const char *cname, uint64_t qid, bool isRX)
+static void connect_to_driver(const char *cname, uint64_t qid, bool isRX, struct waitset *ws)
{
errval_t err;
iref_t iref;
err = nameservice_blocking_lookup(qm_name, &iref);
assert(err_is_ok(err));
- if (isRX) {
- err = net_queue_manager_bind(iref, bind_cb_rx, NULL, get_default_waitset(),
- IDC_BIND_FLAGS_DEFAULT);
- assert(err_is_ok(err));
- } else {
- err = net_queue_manager_bind(iref, bind_cb_tx, NULL, get_default_waitset(),
- IDC_BIND_FLAGS_DEFAULT);
- assert(err_is_ok(err));
- }
+ err = net_queue_manager_bind(iref, isRX ? bind_cb_rx: bind_cb_tx, NULL, ws,
+ IDC_BIND_FLAGS_DEFAULT);
+ assert(err_is_ok(err));
}
void net_if_init(const char* cardname, uint64_t qid)
queue = qid;
// Connect RX path
- connect_to_driver(cardname, queue, true);
- while (binding_rx == NULL) { event_dispatch(ws); }
-
+ connect_to_driver(cardname, queue, true, ws);
// Connect TX path
- connect_to_driver(cardname, queue, false);
- while (binding_tx == NULL) { event_dispatch(ws); }
+ connect_to_driver(cardname, queue, false, ws);
+
+ while (binding_rx == NULL || binding_tx == NULL) {
+ event_dispatch(ws);
+ }
buffers_init(BUFFER_COUNT);
// Get MAC address
- idc_get_mac_address(binding_rx, queue);
- while (card_mac == -1ULL) { event_dispatch(ws); }
-
+ errval_t err = get_mac_address(binding_rx, queue, &card_mac);
+ assert(err_is_ok(err));
initialized = true;
}
{
memcpy(mac, &card_mac, 6);
}
-
-
flounderDefs = [ "net_queue_manager"],
flounderBindings = [ "net_queue_manager",
"net_soft_filters" ],
- addLibraries = [ "contmng", "procon", "bfdmuxvm", "trace"] }
+ flounderExtraBindings = [ ("net_soft_filters", ["rpcclient"]) ],
+ addLibraries = [ "procon", "bfdmuxvm", "trace"] }
]
// Interface: benchmark_control
// *****************************************************
-// Wrapper function:
-static errval_t send_benchmark_control_response(struct q_entry e)
-{
- struct net_queue_manager_binding *b = (struct net_queue_manager_binding *)
- e.binding_ptr;
- struct client_closure *ccl = (struct client_closure *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.benchmark_control_response(b,
- MKCONT(cont_queue_callback, ccl->q),
- e.plist[0], e.plist[1], e.plist[2], e.plist[3]);
- // queueid, state, delta, cl
- } else {
- ETHERSRV_DEBUG("send_benchmark_control_response Flounder busy.."
- " will retry\n");
- return FLOUNDER_ERR_TX_BUSY;
- }
-}
-
static void send_benchmark_control(struct net_queue_manager_binding *cc,
uint64_t queueid, uint64_t state, uint64_t delta, uint64_t cl)
{
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_benchmark_control_response;
- entry.binding_ptr = (void *) cc;
- struct client_closure *ccl = (struct client_closure *) cc->st;
-
- entry.plist[0] = queueid;
- entry.plist[1] = state;
- entry.plist[2] = delta;
- entry.plist[3] = cl;
- enqueue_cont_q(ccl->q, &entry);
+ errval_t err = cc->tx_vtbl.benchmark_control_response(cc, NOP_CONT, queueid, state, delta, cl);
+ assert(err_is_ok(err));
}
#include <net_queue_manager/net_queue_manager.h>
#include <bfdmuxvm/vm.h>
#include <if/net_soft_filters_defs.h>
+#include <if/net_soft_filters_rpcclient_defs.h>
#include <if/net_queue_manager_defs.h>
#include "queue_manager_local.h"
#include "queue_manager_debug.h"
/* This is client_closure for filter management */
struct client_closure_FM {
struct net_soft_filters_binding *app_connection; /* FIXME: Do I need this? */
- struct cont_queue *q;
/* FIXME: this should contain the registered buffer ptr */
};
-static void register_filter_memory_request(struct net_soft_filters_binding *cc,
- struct capref mem_cap);
-static void register_filter(struct net_soft_filters_binding *cc, uint64_t id,
+static errval_t register_filter_memory(struct net_soft_filters_binding *cc,
+ struct capref mem_cap, errval_t *rerr);
+static errval_t register_filter(struct net_soft_filters_binding *cc, uint64_t id,
uint64_t len_rx, uint64_t len_tx,
uint64_t buffer_id_rx, uint64_t buffer_id_tx,
- uint64_t ftype, uint64_t paused);
-static void register_arp_filter(struct net_soft_filters_binding *cc, uint64_t id,
- uint64_t len_rx, uint64_t len_tx);
-static void deregister_filter(struct net_soft_filters_binding *cc,
- uint64_t filter_id);
-static void re_register_filter(struct net_soft_filters_binding *cc,
+ uint64_t ftype, uint64_t paused, errval_t *rerr,
+ uint64_t *filter_id);
+static errval_t register_arp_filter(struct net_soft_filters_binding *cc, uint64_t id,
+ uint64_t len_rx, uint64_t len_tx, errval_t *rerr);
+static errval_t deregister_filter(struct net_soft_filters_binding *cc,
+ uint64_t filter_id, errval_t *rerr);
+static errval_t re_register_filter(struct net_soft_filters_binding *cc,
uint64_t filter_id, uint64_t buffer_id_rx,
- uint64_t buffer_id_tx);
-static void pause_filter(struct net_soft_filters_binding *cc, uint64_t filter_id,
- uint64_t buffer_id_rx, uint64_t buffer_id_tx);
-static void mac_address_request_sf(struct net_soft_filters_binding *cc);
+ uint64_t buffer_id_tx, errval_t *rerr);
+static errval_t pause_filter(struct net_soft_filters_binding *cc, uint64_t filter_id,
+ uint64_t buffer_id_rx, uint64_t buffer_id_tx, errval_t *rerr);
+static errval_t mac_address_request_sf(struct net_soft_filters_binding *cc,
+ errval_t *rerr, uint64_t *mac);
// Initialize interface for soft_filters channel
-static struct net_soft_filters_rx_vtbl rx_net_soft_filters_vtbl = {
- .register_filter_memory_request = register_filter_memory_request,
- .register_filter_request = register_filter,
- .re_register_filter_request = re_register_filter,
- .deregister_filter_request = deregister_filter,
- .register_arp_filter_request = register_arp_filter,
- .pause = pause_filter,
- .mac_address_request = mac_address_request_sf,
+static struct net_soft_filters_rpc_rx_vtbl rpc_rx_net_soft_filters_vtbl = {
+ .register_filter_memory_call = register_filter_memory,
+ .register_filter_call = register_filter,
+ .re_register_filter_call = re_register_filter,
+ .deregister_filter_call = deregister_filter,
+ .register_arp_filter_call = register_arp_filter,
+ .pause_call = pause_filter,
+ .mac_address_call = mac_address_request_sf,
};
}
}
-
static errval_t connect_soft_filters_cb(void *st,
struct net_soft_filters_binding *b)
{
ETHERSRV_DEBUG("ether_netd service got a connection!55\n");
// copy my message receive handler vtable to the binding
- b->rx_vtbl = rx_net_soft_filters_vtbl;
+ b->rpc_rx_vtbl = rpc_rx_net_soft_filters_vtbl;
//b->error_handler = error_handler;
struct client_closure_FM *ccfm =
(struct client_closure_FM *) malloc(sizeof(struct client_closure_FM));
b->st = ccfm;
- ccfm->q = create_cont_q("FILTER-MANAGER");
ccfm->app_connection = b;
// FIXME: should I refuse more than one connections for FM services?
return SYS_ERR_OK;
} // end function: connect_soft_filters_cb
-
-
/*****************************************************************
* filter registration
*****************************************************************/
-static errval_t send_mac_address_response(struct q_entry entry)
-{
- // ETHERSRV_DEBUG("send_mac_address_response -----\n");
- struct net_soft_filters_binding *b =
- (struct net_soft_filters_binding *) entry.binding_ptr;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.mac_address_response(b,
- MKCONT(cont_queue_callback, ccfm->q),
- entry.plist[0], entry.plist[1]);
- // entry.error, entry.mac
- } else {
- ETHERSRV_DEBUG("send_resigered_netd_memory Flounder bsy will retry\n");
- return FLOUNDER_ERR_TX_BUSY;
- }
-}
-
-static void mac_address_request_sf(struct net_soft_filters_binding *cc)
+static errval_t mac_address_request_sf(struct net_soft_filters_binding *cc,
+ errval_t *err, uint64_t *mac)
{
- // call mac_address_request_sf with mac address
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_mac_address_response;
- entry.binding_ptr = (void *) cc;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
- entry.plist[0] = SYS_ERR_OK;
- entry.plist[1] = get_mac_addr_from_device();
- // e.error , e.mac
-
- enqueue_cont_q(ccfm->q, &entry);
- ETHERSRV_DEBUG("register_netd_memory: sent IDC\n");
-
+ *err = SYS_ERR_OK;
+ *mac = get_mac_addr_from_device();
+ return SYS_ERR_OK;
} // end function: mac_address_request_sf
-/* FIXME: provide proper handler here */
-static errval_t send_resiger_filter_memory_response(struct q_entry entry)
-{
- // ETHERSRV_DEBUG("send_resigered_netd_memory -----\n");
- struct net_soft_filters_binding *b =
- (struct net_soft_filters_binding *) entry.binding_ptr;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.register_filter_memory_response(b,
- MKCONT
- (cont_queue_callback,
- ccfm->q),
- entry.plist[0]);
- /* entry.error */
- } else {
- ETHERSRV_DEBUG("send_resigered_netd_memory Flounder bsy will retry\n");
- return FLOUNDER_ERR_TX_BUSY;
- }
-}
-
static struct bulk_transfer_slave bt_filter_rx;
-static void register_filter_memory_request(struct net_soft_filters_binding *cc,
- struct capref mem_cap)
+static errval_t register_filter_memory(struct net_soft_filters_binding *cc,
+ struct capref mem_cap, errval_t *err)
{
-
- errval_t err = SYS_ERR_OK;
+ *err = SYS_ERR_OK;
struct frame_identity pa;
- err = frame_identify(mem_cap, &pa);
- if(!err_is_ok(err)) {
+ *err = frame_identify(mem_cap, &pa);
+ if(!err_is_ok(*err)) {
printf("invoke_frame_identity failed\n");
abort();
}
// 2 is rx + tx
if (pa.bytes < BASE_PAGE_SIZE * 2) {
ETHERSRV_DEBUG("netd did not provided enough for filter transfer\n");
- err = FILTER_ERR_NOT_ENOUGH_MEMORY; /* ps: FIXME: enable this error */
+ *err = FILTER_ERR_NOT_ENOUGH_MEMORY; /* ps: FIXME: enable this error */
} /* end if: not enough memory */
else { /* enough memory, try to map it */
void *pool;
- err = vspace_map_one_frame_attr((void *) (&pool), BASE_PAGE_SIZE * 2,
+ *err = vspace_map_one_frame_attr((void *) (&pool), BASE_PAGE_SIZE * 2,
mem_cap,
VREGION_FLAGS_READ_WRITE_NOCACHE, NULL,
NULL);
- if (err_is_fail(err)) {
- DEBUG_ERR(err, "vspace_map_one_frame failed");
+ if (err_is_fail(*err)) {
+ DEBUG_ERR(*err, "vspace_map_one_frame failed");
// abort();
} /* end if: mapping failed */
else {
// Init receiver
- err = bulk_slave_init(pool, BASE_PAGE_SIZE * 2, &bt_filter_rx);
+ *err = bulk_slave_init(pool, BASE_PAGE_SIZE * 2, &bt_filter_rx);
// assert(err_is_ok(err));
} /* end else: mapping sucessful */
} /* end else : */
-
- /* call registered_netd_memory with new IDC */
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_resiger_filter_memory_response;
- entry.binding_ptr = (void *) cc;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
- entry.plist[0] = err;
- /* entry.plist[0]
- entry.error */
-
- enqueue_cont_q(ccfm->q, &entry);
- ETHERSRV_DEBUG("register_netd_memory: sent IDC\n");
-
+ return SYS_ERR_OK;
} /* end function : register_netd_memory */
-/* Handler for sending response to register_filter */
-static errval_t send_register_filter_response(struct q_entry e)
-{
- // ETHERSRV_DEBUG("send_resigered_filter for ID %lu --\n", e.plist[0]);
- struct net_soft_filters_binding *b =
- (struct net_soft_filters_binding *) e.binding_ptr;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.register_filter_response(b,
- MKCONT(cont_queue_callback,
- ccfm->q), e.plist[0],
- e.plist[1], e.plist[2],
- e.plist[3], e.plist[4],
- e.plist[5]);
- /* e.id, e.error, e.filter_id, e.buffer_id_rx,
- * e.buffer_id_tx, e.filter_type */
-
- } else {
- ETHERSRV_DEBUG("send_resigered_filter: ID %" PRIu64
- ": Flounder bsy will retry\n", e.plist[0]);
- return FLOUNDER_ERR_TX_BUSY;
- }
-}
-
-static void wrapper_send_filter_registered_msg(struct net_soft_filters_binding *cc,
- uint64_t id, errval_t err,
- uint64_t filter_id,
- uint64_t buffer_id_rx,
- uint64_t buffer_id_tx,
- uint64_t ftype)
-{
-
- /* call registered_netd_memory with new IDC */
-
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_register_filter_response;
- entry.binding_ptr = (void *) cc;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
- entry.plist[0] = id;
- entry.plist[1] = err;
- entry.plist[2] = filter_id;
- entry.plist[3] = buffer_id_rx;
- entry.plist[4] = buffer_id_tx;
- entry.plist[5] = ftype;
- // e.plist[0], e.plist[1], e.plist[2], e.plist[3], e.plist[4], e.plist[5])
- // id, error, filter_id, buffer_id_rx, buffer_id_tx, filter_type
-
- enqueue_cont_q(ccfm->q, &entry);
-
-}
-
/**
* \brief: Registers the filter with network driver
*/
-static void register_filter(struct net_soft_filters_binding *cc, uint64_t id,
+static errval_t register_filter(struct net_soft_filters_binding *cc, uint64_t id,
uint64_t len_rx, uint64_t len_tx,
uint64_t buffer_id_rx, uint64_t buffer_id_tx,
- uint64_t ftype, uint64_t paused)
+ uint64_t ftype, uint64_t paused, errval_t *err,
+ uint64_t *filter_id)
{
- errval_t err = SYS_ERR_OK;
-
- ETHERSRV_DEBUG("Register_filter: ID:%" PRIu64 " of type[%" PRIu64
- "] buffers RX[%" PRIu64 "] and TX[%" PRIu64 "]\n", id, ftype,
- buffer_id_rx, buffer_id_tx);
+ *err = SYS_ERR_OK;
struct buffer_descriptor *buffer_rx = NULL;
struct buffer_descriptor *buffer_tx = NULL;
if (buffer_rx == NULL || buffer_tx == NULL) {
ETHERSRV_DEBUG("no buffer found for the provided buffer id\n");
- err = FILTER_ERR_BUFF_NOT_FOUND;
-
- wrapper_send_filter_registered_msg(cc, id, err, 0, buffer_id_rx,
- buffer_id_tx, ftype);
- return;
+ *err = FILTER_ERR_BUFF_NOT_FOUND;
+ *filter_id = 0;
+ return SYS_ERR_OK;
}
if (len_rx > BASE_PAGE_SIZE) {
if (buf == NULL) {
ETHERSRV_DEBUG("no memory available for filter transfer\n");
- err = FILTER_ERR_NO_NETD_MEM;
- wrapper_send_filter_registered_msg(cc, id, err, 0, buffer_id_rx,
- buffer_id_tx, ftype);
- return;
+ *err = FILTER_ERR_NO_NETD_MEM;
+ *filter_id = 0;
+ return SYS_ERR_OK;
}
/* Create the filter data-structures */
/* FIXME: use goto to deal with failure conditions and reduce the code */
if (new_filter_rx == NULL || new_filter_tx == NULL) {
ETHERSRV_DEBUG("out of memory for filter registration\n");
- err = ETHERSRV_ERR_NOT_ENOUGH_MEM;
- wrapper_send_filter_registered_msg(cc, id, err, 0, buffer_id_rx,
- buffer_id_tx, ftype);
+ *err = ETHERSRV_ERR_NOT_ENOUGH_MEM;
+ *filter_id = 0;
if (new_filter_rx) {
free(new_filter_rx);
if (new_filter_tx) {
free(new_filter_tx);
}
- return;
+ return SYS_ERR_OK;
}
/* Zero out the filters */
if (new_filter_rx->data == NULL || new_filter_tx->data == NULL) {
ETHERSRV_DEBUG("out of memory for filter data registration\n");
- err = ETHERSRV_ERR_NOT_ENOUGH_MEM;
- wrapper_send_filter_registered_msg(cc, id, err, 0, buffer_id_rx,
- buffer_id_tx, ftype);
+ *err = ETHERSRV_ERR_NOT_ENOUGH_MEM;
+ *filter_id = 0;
if (new_filter_rx->data) {
free(new_filter_rx->data);
free(new_filter_rx);
free(new_filter_tx);
- return;
+ return SYS_ERR_OK;
}
/* Zero-out the area of filter-data */
buffer_rx->tx_filters = new_filter_tx; // sometimes rx buffers transmit
/* reporting back the success/failure */
- wrapper_send_filter_registered_msg(cc, id, err, filter_id_counter,
- buffer_id_rx, buffer_id_tx, ftype);
-
- ETHERSRV_DEBUG("Register_filter: ID %" PRIu64 ": type[%" PRIu64
- "] successful [%" PRIu64 "]\n", id, ftype,
- filter_id_counter);
-
+ *filter_id = filter_id_counter;
+ return SYS_ERR_OK;
} /* end function: register filter */
-
-/* Handler for sending response to deregister_filter */
-static errval_t send_deregister_filter_response(struct q_entry e)
-{
- // ETHERSRV_DEBUG("send_deresigered_filter_response for ID %lu -----\n", e.plist[0]);
- struct net_soft_filters_binding *b =
- (struct net_soft_filters_binding *) e.binding_ptr;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.deregister_filter_response(b,
- MKCONT(cont_queue_callback,
- ccfm->q),
- e.plist[0], e.plist[1]);
- /* e.error, e.filter_id, */
-
- } else {
- ETHERSRV_DEBUG("send_deresiger_filter_response: Filter_ID %" PRIu64
- ": Flounder bsy will retry\n", e.plist[1]);
- return FLOUNDER_ERR_TX_BUSY;
- }
-}
-
-static void wrapper_send_filter_deregister_msg(struct net_soft_filters_binding *cc,
- errval_t err, uint64_t filter_id)
-{
-
- /* call registered_netd_memory with new IDC */
-
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_deregister_filter_response;
- entry.binding_ptr = (void *) cc;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
- entry.plist[0] = err;
- entry.plist[1] = filter_id;
- /* e.plist[0], e.plist[1] );
- e.error, e.filter_id */
- enqueue_cont_q(ccfm->q, &entry);
-}
-
static struct filter *delete_from_filter_list(struct filter *head,
uint64_t filter_id)
{
return NULL; /* could not not find the id. */
}
-
/**
* \brief: Deregisters the filter with network driver
*/
-static void deregister_filter(struct net_soft_filters_binding *cc,
- uint64_t filter_id)
+static errval_t deregister_filter(struct net_soft_filters_binding *cc,
+ uint64_t filter_id, errval_t *err)
{
- errval_t err = SYS_ERR_OK;
+ *err = SYS_ERR_OK;
ETHERSRV_DEBUG("DeRegister_filter: ID:%" PRIu64 "\n", filter_id);
if (rx_filter == NULL /*|| tx_filter == NULL */ ) {
ETHERSRV_DEBUG("Deregister_filter:requested filter_ID [%" PRIu64
"] not found\n", filter_id);
- err = FILTER_ERR_FILTER_NOT_FOUND;
+ *err = FILTER_ERR_FILTER_NOT_FOUND;
}
if (rx_filter) {
}
/* reporting back the success/failure */
- wrapper_send_filter_deregister_msg(cc, err, filter_id);
-
ETHERSRV_DEBUG("Deregister_filter: ID %" PRIu64 ": Done\n", filter_id);
+ return SYS_ERR_OK;
} /* end function: deregister_filter */
-
-
-/* Handler for sending response to re register_filter */
-static errval_t send_re_register_filter_response(struct q_entry e)
-{
- // ETHERSRV_DEBUG("send_re_register_filter_response for ID %lu -----\n", e.plist[0]);
- struct net_soft_filters_binding *b =
- (struct net_soft_filters_binding *) e.binding_ptr;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.re_register_filter_response(b,
- MKCONT
- (cont_queue_callback,
- ccfm->q), e.plist[0],
- e.plist[1], e.plist[2],
- e.plist[2]);
- /* e.error, e.filter_id, e.buffer_id_rx, e.buffer_id_rx */
-
- } else {
- ETHERSRV_DEBUG("send_re_register_filter_response: Filter_ID %" PRIu64
- ": Flounder bsy will retry\n", e.plist[1]);
- return FLOUNDER_ERR_TX_BUSY;
- }
-} /* end function: send_re_register_filter_response */
-
-static errval_t send_pause_filter_response(struct q_entry e)
-{
- // ETHERSRV_DEBUG("send_re_register_filter_response for ID %lu -----\n", e.plist[0]);
- struct net_soft_filters_binding *b =
- (struct net_soft_filters_binding *) e.binding_ptr;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.pause_response(b,
- MKCONT(cont_queue_callback, ccfm->q),
- e.plist[0], e.plist[1]);
- /* e.error, e.filter_id, e.buffer_id_rx, e.buffer_id_rx */
-
- } else {
- ETHERSRV_DEBUG("send_re_register_filter_response: Filter_ID %" PRIu64
- ": Flounder bsy will retry\n", e.plist[1]);
- return FLOUNDER_ERR_TX_BUSY;
- }
-} /* end function: send_re_register_filter_response */
-
-static void wrapper_send_filter_re_register_msg(struct net_soft_filters_binding
- *cc, errval_t err,
- uint64_t filter_id,
- uint64_t buffer_id_rx,
- uint64_t buffer_id_tx)
-{
-
- /* call registered_netd_memory with new IDC */
-
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_re_register_filter_response;
- entry.binding_ptr = (void *) cc;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
- entry.plist[0] = err;
- entry.plist[1] = filter_id;
- entry.plist[2] = buffer_id_rx;
- entry.plist[3] = buffer_id_tx;
-/* e.plist[0], e.plist[1], e.plist[2], e.plist[2]
- e.error, e.filter_id, e.buffer_id_rx, e.buffer_id_rx */
- enqueue_cont_q(ccfm->q, &entry);
-} /* end function: wrapper_send_filter_re_register_msg */
-
-static void wrapper_send_filter_pause_msg(struct net_soft_filters_binding *cc,
- errval_t err, uint64_t filter_id)
-{
-
- /* call registered_netd_memory with new IDC */
-
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_pause_filter_response;
- entry.binding_ptr = (void *) cc;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
- entry.plist[0] = filter_id;
- entry.plist[1] = err;
-/* e.plist[0], e.plist[1], e.plist[2], e.plist[2]
- e.error, e.filter_id, e.buffer_id_rx, e.buffer_id_rx */
- enqueue_cont_q(ccfm->q, &entry);
-} /* end function: wrapper_send_filter_re_register_msg */
-
-
static struct filter *find_from_filter_list(struct filter *head,
uint64_t filter_id)
{
/**
* \brief: re-registers the filter with network driver
*/
-static void re_register_filter(struct net_soft_filters_binding *cc,
+static errval_t re_register_filter(struct net_soft_filters_binding *cc,
uint64_t filter_id, uint64_t buffer_id_rx,
- uint64_t buffer_id_tx)
+ uint64_t buffer_id_tx, errval_t *err)
{
- errval_t err = SYS_ERR_OK;
+ *err = SYS_ERR_OK;
ETHERSRV_DEBUG("re_register_filter: ID:%" PRIu64 "\n", filter_id);
if (rx_filter == NULL /*|| tx_filter == NULL */ ) {
ETHERSRV_DEBUG("re_register_filter: requested filter_ID [%" PRIu64
"] not found\n", filter_id);
- err = FILTER_ERR_FILTER_NOT_FOUND;
- wrapper_send_filter_re_register_msg(cc, err, filter_id,
- buffer_id_rx, buffer_id_tx);
- return;
+ *err = FILTER_ERR_FILTER_NOT_FOUND;
+ return SYS_ERR_OK;
}
/* Find the buffer with given buffer_id */
ETHERSRV_DEBUG("re_register_filter: rx=[[%" PRIu64 "] = %p], tx=[[%"
PRIu64 "] = %p]\n", buffer_id_rx, buffer_rx,
buffer_id_tx, buffer_tx);
- err = FILTER_ERR_BUFFER_NOT_FOUND; /* set error value */
- wrapper_send_filter_re_register_msg(cc, err, filter_id, buffer_id_rx,
- buffer_id_tx);
+ *err = FILTER_ERR_BUFFER_NOT_FOUND; /* set error value */
+ return SYS_ERR_OK;
}
rx_filter->buffer = buffer_rx;
/* FIXME: Also, set the new buffer for tx_filters */
/* reporting back the success/failure */
- wrapper_send_filter_re_register_msg(cc, err, filter_id, buffer_id_rx,
- buffer_id_tx);
-
ETHERSRV_DEBUG("re_register_filter: ID %" PRIu64 ": Done\n", filter_id);
+ return SYS_ERR_OK;
} /* end function: re_register_filter */
/**
* \brief: pause the filter with network driver
*/
-static void pause_filter(struct net_soft_filters_binding *cc, uint64_t filter_id,
- uint64_t buffer_id_rx, uint64_t buffer_id_tx)
+static errval_t pause_filter(struct net_soft_filters_binding *cc, uint64_t filter_id,
+ uint64_t buffer_id_rx, uint64_t buffer_id_tx, errval_t *err)
{
- errval_t err = SYS_ERR_OK;
+ *err = SYS_ERR_OK;
ETHERSRV_DEBUG("(un)pause_filter: ID:%" PRIu64 "\n", filter_id);
if (rx_filter == NULL /*|| tx_filter == NULL */ ) {
ETHERSRV_DEBUG("pause_filter: requested filter_ID [%" PRIu64
"] not found\n", filter_id);
- err = FILTER_ERR_FILTER_NOT_FOUND;
+ *err = FILTER_ERR_FILTER_NOT_FOUND;
assert(!"NYI");
/* wrapper_send_filter_re_register_msg(cc, err, filter_id, */
/* buffer_id_rx, buffer_id_tx); */
- return;
+ return SYS_ERR_OK;
}
/* Find the buffer with given buffer_id */
rx_filter->buffer = buffer_rx;
/* FIXME: Also, set the new buffer for tx_filters */
/* reporting back the success/failure */
- wrapper_send_filter_pause_msg(cc, err, filter_id);
rx_filter->paused = false;
if (rx_filter->pause_bufpos > 0) {
rx_filter->pause_bufpos = 0;
ETHERSRV_DEBUG("(un)pause_filter: ID %" PRIu64 ": Done\n", filter_id);
-
+ return SYS_ERR_OK;
} /* end function: re_register_filter */
-
-/* Handler for sending response to register_filter */
-static errval_t send_register_arp_filter_response(struct q_entry entry)
-{
- // ETHERSRV_DEBUG("send_resigered_arp_filter -----\n");
- struct net_soft_filters_binding *b =
- (struct net_soft_filters_binding *) entry.binding_ptr;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.register_arp_filter_response(b,
- MKCONT
- (cont_queue_callback,
- ccfm->q),
- entry.plist[0],
- entry.plist[1]);
- /* e.id, e.error */
-
- } else {
- ETHERSRV_DEBUG("send_resigered_arp_filter Flounder bsy will retry\n");
- return FLOUNDER_ERR_TX_BUSY;
- }
-}
-
-static void wrapper_send_arp_filter_registered_msg(struct net_soft_filters_binding
- *cc, uint64_t id,
- errval_t err)
-{
-
- /* call registered_netd_memory with new IDC */
-
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_register_arp_filter_response;
- entry.binding_ptr = (void *) cc;
- struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
- entry.plist[0] = id;
- entry.plist[1] = err;
- /* entry.plist[0], entry.plist[1]
- id, e.error */
-
- enqueue_cont_q(ccfm->q, &entry);
-}
-
-static void register_arp_filter(struct net_soft_filters_binding *cc, uint64_t id,
- uint64_t len_rx, uint64_t len_tx)
+static errval_t register_arp_filter(struct net_soft_filters_binding *cc, uint64_t id,
+ uint64_t len_rx, uint64_t len_tx, errval_t *err)
{
-
- errval_t err = SYS_ERR_OK;
+ *err = SYS_ERR_OK;
if (len_rx > BASE_PAGE_SIZE) {
len_rx = BASE_PAGE_SIZE;
if (buf == NULL) {
ETHERSRV_DEBUG("no memory available for arp_filter transfer\n");
- err = FILTER_ERR_NO_NETD_MEM;
- wrapper_send_arp_filter_registered_msg(cc, id, err);
- return;
+ *err = FILTER_ERR_NO_NETD_MEM;
+ return SYS_ERR_OK;
}
arp_filter_rx.data = (uint8_t *) malloc(len_rx);
arp_filter_tx.len = len_tx;
ETHERSRV_DEBUG("#### The received arp RX filter is\n");
// show_binary_blob(arp_filter_tx.data, arp_filter_tx.len);
-
- wrapper_send_arp_filter_registered_msg(cc, id, err);
+ return SYS_ERR_OK;
}
-
-
static void send_arp_to_all(void *data, uint64_t len, uint64_t flags)
{
struct filter *head = rx_filters;
copy_packet_to_user(buffer, data, len, flags);
}
-
struct filter *execute_filters(void *data, size_t len)
{
struct filter *head = rx_filters;
rx_ring_register_buffer(opaque);
} // end function: process_received_packet
-
// FIXME: This is repeated, make it common
#define MAX_SERVICE_NAME_LEN 256 // Max len that a name of service can have
+#define QUEUE_SIZE 512
+
/*****************************************************************
* Global datastructure
*****************************************************************/
* Prototypes
*****************************************************************/
-static void register_buffer(struct net_queue_manager_binding *cc,
+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);
+ 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 void get_mac_addr_qm(struct net_queue_manager_binding *cc,
- uint64_t queueid);
+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);
// Initialize service
static struct net_queue_manager_rx_vtbl rx_nqm_vtbl = {
- .register_buffer = register_buffer,
- .raw_add_buffer = raw_add_buffer,
- .get_mac_address = get_mac_addr_qm,
+ .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:
*****************************************************************/
// 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
char name[64];
sprintf(name, "ether_a_%d_%s", cc->cl_no,
((cc->cl_no % 2) == 0)? "RX" : "TX");
- cc->q = create_cont_q(name);
- if (cc->q == NULL) {
- ETHERSRV_DEBUG("create_new_client: queue allocation failed\n");
- free(buffer);
- free(cc);
- return NULL;
- }
- // cc->q->debug = 1;
return cc;
} // end function: create_new_client
// Interface implementation
// **********************************************************
-// *********** Interface: register_buffer *******************
-static errval_t send_new_buffer_id(struct q_entry entry)
-{
- struct net_queue_manager_binding *b = (struct net_queue_manager_binding *)
- entry.binding_ptr;
- struct client_closure *ccl = (struct client_closure *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.new_buffer_id(b, MKCONT(cont_queue_callback, ccl->q),
- entry.plist[0],
- entry.plist[1],
- entry.plist[2]);
- // entry.error, entry.queueid, entry.buffer_id
- } else {
- ETHERSRV_DEBUG("send_new_buffer_id Flounder busy.. will retry\n");
- return FLOUNDER_ERR_TX_BUSY;
- }
-}
-
-static void report_register_buffer_result(struct net_queue_manager_binding *cc,
- errval_t err, uint64_t queueid, uint64_t buffer_id)
-{
- struct q_entry entry;
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = send_new_buffer_id;
- entry.binding_ptr = (void *) cc;
- struct client_closure *ccl = (struct client_closure *) cc->st;
-
- entry.plist[0] = err;
- entry.plist[1] = queueid;
- entry.plist[2] = buffer_id;
- // error, queue_id, buffer_id
-
- struct waitset *ws = get_default_waitset();
- int passed_events = 0;
- while (can_enqueue_cont_q(ccl->q) == false) {
-
- // USER_PANIC("queue full, can go further\n");
-
- if (passed_events > 5) {
- USER_PANIC("queue full, can go further\n");
- //return CONT_ERR_NO_MORE_SLOTS;
- }
- event_dispatch_debug(ws);
- ++passed_events;
- }
-
-
- enqueue_cont_q(ccl->q, &entry);
-}
-
-
// Actual register_buffer function with all it's logic
-static void register_buffer(struct net_queue_manager_binding *cc,
+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)
+ uint64_t slots, uint8_t role, struct capref queue_cap, uint64_t *idx)
{
-
ETHERSRV_DEBUG("ethersrv:register buffer called with slots %"PRIu64"\n",
slots);
errval_t err;
struct buffer_descriptor *buffer = closure->buffer_ptr;
err = populate_buffer(buffer, cap);
if (err_is_fail(err)) {
- report_register_buffer_result(cc, err, queueid, 0);
- return;
+ *idx = 0;
+ return SYS_ERR_OK;
}
buffer->role = role;
buffer->con = cc;
buffer->queueid = queueid;
-
// Create a list to hold metadata for sending
buffer->rxq.buffer_state_size = slots;
buffer->rxq.buffer_state = calloc(slots,
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
use_raw_if = true;
buffers_list = buffer;
- report_register_buffer_result(cc, SYS_ERR_OK, queueid,
- buffer->buffer_id);
- return;
+ *idx = buffer->buffer_id;
+
+ return SYS_ERR_OK;
} // end function: register_buffer
-static errval_t wrapper_send_raw_xmit_done(struct q_entry e)
-{
- struct net_queue_manager_binding *b = (struct net_queue_manager_binding *)
- e.binding_ptr;
- struct client_closure *ccl = (struct client_closure *) b->st;
-
- if (b->can_send(b)) {
- errval_t err = b->tx_vtbl.raw_xmit_done(b,
- MKCONT(cont_queue_callback, ccl->q),
- e.plist[0], e.plist[1], e.plist[2], e.plist[3]);
- return err;
- } else {
- return FLOUNDER_ERR_TX_BUSY;
- }
-}
-
static __attribute__((unused)) void
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 *b,
+static errval_t send_raw_xmit_done(struct net_queue_manager_binding *binding,
uint64_t offset, uint64_t length,
uint64_t more, uint64_t flags)
{
- struct client_closure *ccl = (struct client_closure *) b->st;
-
- // Send notification to application
- struct q_entry entry;
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = wrapper_send_raw_xmit_done;
- entry.binding_ptr = b;
- entry.plist[0] = offset;
- entry.plist[1] = length;
- entry.plist[2] = more;
- entry.plist[3] = flags;
-
- struct waitset *ws = get_default_waitset();
- int passed_events = 0;
- while (can_enqueue_cont_q(ccl->q) == false) {
-
-// USER_PANIC("queue full, can go further\n");
-
- if (passed_events > 5) {
- cont_queue_show_queue(ccl->q);
- printf("## queue full, dropping raw_xmit_done notification\n");
- // USER_PANIC("queue full, can't go further\n");
- return CONT_ERR_NO_MORE_SLOTS;
- }
-
-// errval_t err = handle_single_event_nonblock(ws);
- errval_t err = event_dispatch_debug(ws);
- if (err_is_fail(err)) {
- ETHERSRV_DEBUG("Error in event_dispatch, returned %d\n",
- (unsigned int)err);
- // There should be a serious panic and failure here
- USER_PANIC_ERR(err, "event_dispatch_non_block failed in handle_single_event\n");
- break;
- }
-
- ++passed_events;
+ 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);
}
-
- enqueue_cont_q(ccl->q, &entry);
- return SYS_ERR_OK;
+ return err;
} // end function: send_raw_xmit_done
-
-
-
-
-
// *********** Interface: get_mac_address ****************
// wrapper function for responce
-static errval_t wrapper_send_mac_addr_response(struct q_entry entry)
-{
- struct net_queue_manager_binding *b = (struct net_queue_manager_binding *)
- entry.binding_ptr;
- struct client_closure *ccl = (struct client_closure *) b->st;
-
- if (b->can_send(b)) {
- return b->tx_vtbl.get_mac_address_response(b,
- MKCONT(cont_queue_callback, ccl->q),
- entry.plist[0], entry.plist[1]);
- // queueid, hwaddr
- } else {
- ETHERSRV_DEBUG("send_mac_addr_response Flounder busy.. will retry\n");
- return FLOUNDER_ERR_TX_BUSY;
- }
-}
-
uint64_t get_mac_addr_from_device(void)
{
union {
}
// function to handle incoming mac address requests
-static void get_mac_addr_qm(struct net_queue_manager_binding *cc,
- uint64_t queueid)
+static errval_t get_mac_addr_qm(struct net_queue_manager_binding *cc,
+ uint64_t queueid, uint64_t *mac)
{
- struct q_entry entry;
-
- memset(&entry, 0, sizeof(struct q_entry));
- entry.handler = wrapper_send_mac_addr_response;
- entry.binding_ptr = (void *) cc;
struct client_closure *ccl = (struct client_closure *) cc->st;
assert(ccl->queueid == queueid);
-
- entry.plist[0] = queueid;
- entry.plist[1] = get_mac_addr_from_device();
- // queueid, hwaddr
-
- struct waitset *ws = get_default_waitset();
- int passed_events = 0;
- while (can_enqueue_cont_q(ccl->q) == false) {
-
- // USER_PANIC("queue full, can go further\n");
-
- if (passed_events > 5) {
- USER_PANIC("queue full, can go further\n");
- // return CONT_ERR_NO_MORE_SLOTS;
- }
- event_dispatch_debug(ws);
- ++passed_events;
- }
-
-
- enqueue_cont_q(ccl->q, &entry);
+ *mac = get_mac_addr_from_device();
+ return SYS_ERR_OK;
}
// *********** Interface: print_statistics ****************
return false;
}
- if (!is_enough_space_in_queue(cl->q)) {
-
- printf("[%s] Dropping packet as app [%d] is not processing packets"
- "fast enough. Cont queue is almost full [%d], pkt count [%"PRIu64"]\n",
- disp_name(), cl->cl_no, queue_free_slots(cl->q), sent_packets);
- if (cl->debug_state == 4) {
- ++cl->in_dropped_app_buf_full;
- }
-// abort(); // FIXME: temparary halt to simplify debugging
- return false;
- }
-
// pop the latest buffer from head of queue (this is stack)
--buffer->rxq.buffer_state_head;
struct buffer_state_metadata *bsm = buffer->rxq.buffer_state +
/*****************************************************************
* Interface related: raw interface
****************************************************************/
+static void raw_add_buffer_signal(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;
+
+ 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)
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);
}
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;
}
// 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);
// Create a new client for this connection
struct client_closure *cc = create_new_client(b);
{
return memcpy(dst0, src0, length);
}
-
case "$ARCH" in
"x86_64")
QEMU_CMD="${QEMU_PATH}qemu-system-x86_64 \
- -machine type=q35
- -smp $SMP \
+ -machine type=q35 -cpu host -enable-kvm \
+ -smp 2 \
-m 1024 \
- -net nic,model=$NIC_MODEL \
- -net user \
+ -net nic,model=e1000 \
+ -net bridge,br=br0 \
-device ahci,id=ahci \
-device ide-drive,drive=disk,bus=ahci.0 \
-drive id=disk,file="$HDFILE",if=none"
return sent;
}
+static void update_e1000_tdt(void)
+{
+ e1000_dqval_t dqval = 0;
+ dqval = e1000_dqval_val_insert(dqval, ether_transmit_index);
+ e1000_tdt_wr(&(e1000), 0, dqval);
+}
+
/*****************************************************************
* Setup transmit descriptor for packet transmission.
*
static uint64_t transmit_pbuf(uint64_t buffer_address,
size_t packet_len, bool last, void *opaque)
{
- e1000_dqval_t dqval = 0;
struct tx_desc tdesc;
/*
* application can't temper with it. */
transmit_ring[ether_transmit_index] = tdesc;
pbuf_list_tx[ether_transmit_index].opaque = opaque;
-
ether_transmit_index = (ether_transmit_index + 1) % DRIVER_TRANSMIT_BUFFERS;
- dqval = e1000_dqval_val_insert(dqval, ether_transmit_index);
- e1000_tdt_wr(&(e1000), 0, dqval);
E1000_DEBUG("ether_transmit_index %"PRIu32"\n", ether_transmit_index);
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());
return true;
}
+static void update_e1000_rdt(void)
+{
+ e1000_dqval_t dqval = 0;
+ dqval = e1000_dqval_val_insert(dqval, receive_index);
+ e1000_rdt_wr(&e1000, 0, dqval);
+}
static int add_desc(uint64_t paddr, void *opaque)
{
- e1000_dqval_t dqval = 0;
union rx_desc desc;
desc.raw[0] = desc.raw[1] = 0;
desc.rx_read_format.buffer_address = paddr;
-
if(receive_free == DRIVER_RECEIVE_BUFFERS) {
// This is serious error condition.
// Printing debug information to help user!
receive_opaque[receive_index] = opaque;
receive_index = (receive_index + 1) % DRIVER_RECEIVE_BUFFERS;
- dqval = e1000_dqval_val_insert(dqval, receive_index);
- e1000_rdt_wr(&e1000, 0, dqval);
receive_free++;
return 0;
NULL, transmit_pbuf_list_fn, find_tx_free_slot_count_fn,
handle_free_TX_slot_fn, receive_buffer_size,rx_register_buffer_fn,
rx_find_free_slot_count_fn);
+ update_e1000_rdt();
#else
ethernetif_backend_init(global_service_name, assumed_queue_id, get_mac_address_fn,
NULL,
}
}
- if (e1000_intreg_rxt0_extract(icr) == 0) {
- return;
- }
+ if (e1000_intreg_rxt0_extract(icr) != 0) {
#ifndef LIBRARY
- E1000_DEBUG("e1000 interrupt came in\n");
- handle_multiple_packets(MAX_ALLOWED_PKT_PER_ITERATION);
+ E1000_DEBUG("e1000 interrupt came in\n");
+ if (handle_multiple_packets(MAX_ALLOWED_PKT_PER_ITERATION))
+ update_e1000_rdt();
#else
- handle_multiple_packets(1);
+ handle_multiple_packets(1);
#endif
+ }
+ check_queues();
+ while(handle_free_TX_slot_fn());
}
e1000_print_link_status(&e1000_device);
#ifndef LIBRARY
- E1000_DEBUG("#### starting polling.\n");
- // FIXME: hack to force the driver in polling mode, as interrupts are
- // not reliably working
- use_interrupt = false;
- polling_loop();
+ if (!use_interrupt) {
+ E1000_DEBUG("#### starting polling.\n");
+ polling_loop();
+ } else {
+ struct waitset *ws = get_default_waitset();
+
+ while (1) {
+ err = event_dispatch(ws);
+ if (err_is_fail(err)) {
+ DEBUG_ERR(err, "in event_dispatch");
+ break;
+ }
+ } // end while: infinite
+ }
#endif
return 1;
}
-
* Initial default values
*/
-#define E1000_DEFAULT_INT_THROTTLE_RATE 5580
+#define E1000_DEFAULT_INT_THROTTLE_RATE 130
#define E1000_INT_THROTTLE_RATE_DISABLED 0
{
uint16_t data;
errval_t err;
-
+
if(dev->mac_type == e1000_82574){
// For the 82574 we just check the auto rd flag without issuing
// an eeprom read. (FreeBSD does it like this)
/*
* If acquired, release mdio ownership
- */
+ */
if (mdio_acquired) {
timeout = 1000;
do {
/*
* Set interrupt throttle for all interrupts
*/
-void e1000_set_interrupt_throttle(e1000_device_t *dev, uint16_t rate){
- /* Enable interrupt throttling rate.
- *
- * The optimal performance setting for this register is very system and
- * configuration specific. A initial suggested range is 651-5580 (28Bh - 15CCh).
- * The value 0 will disable interrupt throttling
- */
- if (dev->mac_type == e1000_82575
- || dev->mac_type == e1000_82576
- || dev->mac_type == e1000_I210
- || dev->mac_type == e1000_I350) {
- // TODO(lh): Check if these cards really dont need the itr set as well.
- e1000_eitr_interval_wrf(dev->device, 0, rate);
- e1000_eitr_interval_wrf(dev->device, 1, rate);
- e1000_eitr_interval_wrf(dev->device, 2, rate);
- e1000_eitr_interval_wrf(dev->device, 3, rate);
- }
- else if(dev->mac_type == e1000_82574){
- e1000_itr_interval_wrf(dev->device, rate);
- e1000_eitr_82574_interval_wrf(dev->device, 0, rate);
- e1000_eitr_82574_interval_wrf(dev->device, 1, rate);
- e1000_eitr_82574_interval_wrf(dev->device, 2, rate);
- e1000_eitr_82574_interval_wrf(dev->device, 3, rate);
- }
- else {
- e1000_itr_interval_wrf(dev->device, 5580);
- }
+void e1000_set_interrupt_throttle(e1000_device_t *dev, uint16_t usec)
+{
+ /* Enable interrupt throttling rate.
+ *
+ * The optimal performance setting for this register is very system and
+ * configuration specific. A initial suggested range is 651-5580 (28Bh - 15CCh).
+ * The value 0 will disable interrupt throttling
+ */
+ int16_t rate = usec * 4;
+
+ if (dev->mac_type == e1000_82575
+ || dev->mac_type == e1000_82576
+ || dev->mac_type == e1000_I210
+ || dev->mac_type == e1000_I350) {
+ // TODO(lh): Check if these cards really dont need the itr set as well.
+ e1000_eitr_interval_wrf(dev->device, 0, rate);
+ e1000_eitr_interval_wrf(dev->device, 1, rate);
+ e1000_eitr_interval_wrf(dev->device, 2, rate);
+ e1000_eitr_interval_wrf(dev->device, 3, rate);
+ }
+ else if(dev->mac_type == e1000_82574){
+ e1000_itr_interval_wrf(dev->device, rate);
+ e1000_eitr_82574_interval_wrf(dev->device, 0, rate);
+ e1000_eitr_82574_interval_wrf(dev->device, 1, rate);
+ e1000_eitr_82574_interval_wrf(dev->device, 2, rate);
+ e1000_eitr_82574_interval_wrf(dev->device, 3, rate);
+ }
+ else {
+ e1000_itr_interval_wrf(dev->device, rate);
+ }
}
/*****************************************************************
}
e1000_initialize(dev->device, (void *) bar_info[0].vaddr);
-
+
/*
* XXX: This is a check if we are using legacy descriptors and virtual functions
* are enabled to display an error message and abort execution.
}
}
}
-
#include <barrelfish/waitset.h>
-// for handling contiuations
-#include <contmng/contmng.h>
-
// standard libraries
#include <stdio.h>
#include <string.h>