merged
authorpravin@inf.ethz.ch <pravin@inf.ethz.ch>
Thu, 6 Jun 2013 07:56:12 +0000 (09:56 +0200)
committerpravin@inf.ethz.ch <pravin@inf.ethz.ch>
Thu, 6 Jun 2013 07:56:12 +0000 (09:56 +0200)
19 files changed:
1  2 
errors/errno.fugu
hake/Main.hs
hake/RuleDefs.hs
hake/symbolic_targets.mk
if/Hakefile
include/barrelfish/spawn_client.h
include/bench/bench.h
include/contmng/contmng.h
include/trace/trace.h
kernel/arch/x86_64/irq.c
lib/barrelfish/spawn_client.c
lib/lwip/src/barrelfish/idc_barrelfish.c
lib/net_queue_manager/net_soft_filters_srv_impl.c
lib/net_queue_manager/queue_manager.c
usr/bfscope/Hakefile
usr/drivers/e1000/e1000n.c
usr/drivers/e1000/e1000n_debug.h
usr/echoserver/tcpechoserver.c
usr/vmkitmon/guest.c

index 597fc2b,eca7b32..984cda2
mode 100755,100644..100755
diff --cc hake/Main.hs
index 25e52d3,21edf14..21edf14
mode 100755,100644..100755
Simple merge
Simple merge
diff --cc if/Hakefile
Simple merge
@@@ -40,9 -43,8 +43,10 @@@ errval_t spawn_program_on_all_cores(boo
                                      spawn_flags_t flags, domainid_t *ret_domainid);
  errval_t spawn_kill(domainid_t domainid);
  errval_t spawn_exit(uint8_t exitcode);
+ errval_t spawn_wait_coreid(coreid_t coreid, domainid_t domainid, uint8_t *exitcode, bool nohang);
  errval_t spawn_wait(domainid_t domainid, uint8_t *exitcode, bool nohang);
 +errval_t spawn_wait_core(coreid_t coreid, domainid_t domainid,
 +                         uint8_t *exitcode, bool nohang);
  errval_t spawn_rpc_client(coreid_t coreid, struct spawn_rpc_client **ret_client);
  errval_t spawn_get_domain_list(uint8_t **domains, size_t *len);
  errval_t spawn_get_status(uint8_t domain, struct spawn_ps_entry *pse,
@@@ -23,115 -25,7 +25,116 @@@ __BEGIN_DECL
  void bench_init(void);
  cycles_t bench_avg(cycles_t *array, size_t len);
  cycles_t bench_variance(cycles_t *array, size_t len);
 +cycles_t bench_min(cycles_t *array, size_t len);
 +cycles_t bench_max(cycles_t *array, size_t len);
  cycles_t bench_tscoverhead(void);
+ __END_DECLS
  
 +
 +/*
 + * Control functions for benchmarks
 + */
 +
 +enum bench_ctl_mode {
 +    // Fixed number of runs (exactly min_runs)
 +    BENCH_MODE_FIXEDRUNS,
 +};
 +
 +struct bench_ctl {
 +    enum bench_ctl_mode mode;
 +    size_t              result_dimensions;
 +
 +    size_t              min_runs;
 +    size_t              dry_runs;
 +
 +    size_t              result_count;
 +    cycles_t           *data;
 +};
 +
 +typedef struct bench_ctl bench_ctl_t;
 +
 +
 +/**
 + * Initialize a benchmark control instance.
 + *
 + * @param mode       Mode of the benchmark (enum bench_ctl_mode)
 + * @param dimensions Number of values each run produces
 + * @param min_runs   Minimal number of runs to be executed
 + *
 + * @return Control handle, to be passed on subsequent calls to bench_ctl_
 + *         functions.
 + */
 +bench_ctl_t *bench_ctl_init(enum bench_ctl_mode mode,
 +                            size_t              dimensions,
 +                            size_t              min_runs);
 +
 +/**
 + * Frees all resources associated with this benchmark control instance. Should
 + * be called after the benchmark is done and the results are dumped.
 + *
 + * @param ctl Control handle
 + */
 +void bench_ctl_destroy(bench_ctl_t *ctl);
 +
 +/**
 + * Add a fixed number of dry runs whose results should not be recorded. Should
 + * be called before any calls to bench_ctl_add_run().
 + *
 + * @param ctl      Control handle
 + * @param dry_runs Number of dry runs
 + */
 +void bench_ctl_dry_runs(bench_ctl_t *ctl,
 +                        size_t       dry_runs);
 +
 +/**
 + * Add results from one run of the benchmark.
 + *
 + * @param ctl    Control handle
 + * @param result Pointer to the 'dimensions' values of this run
 + *
 + * @return true if this was the last run necessary, false if more runs are
 + *         needed.
 + */
 +bool bench_ctl_add_run(bench_ctl_t *ctl,
 +                       cycles_t* result);
 +
 +/**
 + * Dump results of the benchmark to the standard output. One line per run, the
 + * lines will be prefixed with prefix, the values separeted using commas.
 + *
 + * @param ctl    Control handle
 + * @param prefix String to be printed before each line
 + */
 +void bench_ctl_dump_csv(bench_ctl_t *ctl,
 +                        const char  *prefix, uint64_t tscperus);
 +/**
 + * Use bincounting to reduce the amount of data that is printed.
 + * One line per bin (bin_count + 2 for those below and above the specified
 + * range) with two columns each is emited at most. Lines for empty bins are
 + * omitted except for above and below. The first column contains the start
 + * of the range for this bin (or below/above for the border cases), while the
 + * second column contains the number of values in that bin.
 + *
 + * @param ctl       Control handle
 + * @param dimenison Index of the value in the run
 + * @param bin_count Number of bins to create
 + * @param min       Minimum of range to be represented by bins
 + * @param max       Maximum of range to be represented by bins
 + * @param prefix    String to be printed before each line
 + * @param tscperus  cpu ticks per micro-second
 + */
 +void bench_ctl_dump_csv_bincounting(bench_ctl_t *ctl,
 +                                    size_t dimension,
 +                                    size_t bin_count,
 +                                    cycles_t min,
 +                                    cycles_t max,
 +                                    const char *prefix,
 +                                    cycles_t tscperus);
 +
 +
 +void bench_ctl_dump_analysis(bench_ctl_t *ctl,
 +                                    size_t dimension,
 +                                    const char *prefix,
 +                                    cycles_t tscperus);
 +
  #endif // BENCH_H
Simple merge
  #define TRACE_ONLY_SUB_BNET 1
  #endif // CONFIG_TRACE && NETWORK_STACK_BENCHMARK
  
 -#if CONFIG_TRACE
 -#define TRACE_ONLY_SUB_NNET 1
 -#endif
 +#if CONFIG_TRACE && NETWORK_LLSTACK_TRACE
 +#define TRACE_ONLY_LLNET 1
 +#endif // CONFIG_TRACE && NETWORK_LLSTACK_TRACE
 +
 +
  
  /**
-  * \brief Constants for trace subsystems and events.
-  *
-  * Please try and keep this under control.  Each subsystem should be
-  * preceeded by two blank lines and followed by its events.  If events
-  * within a subsystem need to be grouped with whitespace then use a
-  * single blank line.
-  *
+  * The constants for the subsystems and events are generated from the file
+  * trace_definitions/trace_defs.pleco that can be included after compiling with
+  * #include <trace_definitions/trace_defs.h>
+  * .
   */
- #define TRACE_SUBSYS_KERNEL             0xFFFF
- #define TRACE_EVENT_CSWITCH             0xCCCC
- #define TRACE_EVENT_BZERO               0xB0
- #define TRACE_EVENT_TIMER               0x1
- #define TRACE_EVENT_TIMER_SYNC          0x2
- #define TRACE_EVENT_SCHED_MAKE_RUNNABLE 0xED00
- #define TRACE_EVENT_SCHED_REMOVE        0xED01
- #define TRACE_EVENT_SCHED_YIELD         0xED02
- #define TRACE_EVENT_SCHED_SCHEDULE      0xED03
- #define TRACE_EVENT_SCHED_CURRENT       0xED04
- #define TRACE_SUBSYS_THREADS            0xEEEE
- #define TRACE_EVENT_BARRIER_ENTER       0x0100
- #define TRACE_EVENT_BARRIER_LEAVE       0x0101
- #define TRACE_EVENT_MUTEX_LOCK_ENTER    0x0200
- #define TRACE_EVENT_MUTEX_LOCK_LEAVE    0x0201
- #define TRACE_EVENT_MUTEX_LOCK_NESTED_ENTER    0x0202
- #define TRACE_EVENT_MUTEX_LOCK_NESTED_LEAVE    0x0203
- #define TRACE_EVENT_MUTEX_TRYLOCK       0x0204
- #define TRACE_EVENT_MUTEX_UNLOCK        0x0205
- #define TRACE_EVENT_COND_WAIT_ENTER     0x0300
- #define TRACE_EVENT_COND_WAIT_LEAVE     0x0301
- #define TRACE_EVENT_COND_SIGNAL         0x0302
- #define TRACE_EVENT_COND_BROADCAST      0x0303
- #define TRACE_EVENT_SEM_WAIT_ENTER      0x0400
- #define TRACE_EVENT_SEM_WAIT_LEAVE      0x0401
- #define TRACE_EVENT_SEM_TRYWAIT         0x0402
- #define TRACE_EVENT_SEM_POST            0x0403
- #define TRACE_SUBSYS_MEMSERV 0xA000
- #define TRACE_EVENT_ALLOC    0x0001
- #define TRACE_SUBSYS_MONITOR 0xB000
- #define TRACE_EVENT_SPAN0    0x0000
- #define TRACE_EVENT_SPAN1    0x0001
- #define TRACE_EVENT_SPAN     0x0002
- #define TRACE_EVENT_PCREQ    0x0003
- #define TRACE_EVENT_PCREPLY  0x0004
- #define TRACE_EVENT_PCREQ_INTER   0x0005
- #define TRACE_EVENT_PCREPLY_INTER 0x0006
- #define TRACE_EVENT_URPC_BLOCK   0x0007
- #define TRACE_EVENT_URPC_UNBLOCK 0x0008
- #define TRACE_EVENT_REMOTE_CAP_RETYPE 0x0009
- #define TRACE_EVENT_REMOTE_CAP_RETYPE_RETRY 0x0010
- #define TRACE_EVENT_REMOTE_CAP_RETYPE_MSG   0x0011
- #define TRACE_EVENT_REMOTE_CAP_RETYPE_END   0x0012
- #define TRACE_EVENT_POLLING  0xBBBB
- #define TRACE_SUBSYS_CHIPS   0xC000
- #define TRACE_EVENT_CHIPS_LISTENCB 0x0001
- #define TRACE_SUBSYS_BFLIB   0xBFBF
- #define TRACE_SUBSYS_TWEED        0x2000
- #define TRACE_EVENT_TWEED_START   0x0000
- #define TRACE_EVENT_TWEED_END     0x0001
- #define TRACE_EVENT_STEAL         0x0002
- #define TRACE_EVENT_STEAL_END     0x0003
- #define TRACE_EVENT_WAIT          0x0004
- #define TRACE_EVENT_WAIT_END      0x0005
- #define TRACE_EVENT_LOCKING       0x0006
- #define TRACE_EVENT_LOCKING_END   0x0007
- #define TRACE_SUBSYS_ROUTE                0x3000
- #define TRACE_EVENT_BCAST_WITH_CCAST_SEND 0x0001
- #define TRACE_EVENT_BCAST_WITH_CCAST      0x0002
- #define TRACE_EVENT_RECV_BCAST_WITH_CCAST 0x0003
- #define TRACE_EVENT_RECV_CCAST            0x0004
- #define TRACE_EVENT_ROUTE_BENCH_START     0x0005
- #define TRACE_EVENT_ROUTE_BENCH_STOP      0x0006
- #define TRACE_EVENT_ROUTE_SEND_PING       0x0007
- #define TRACE_EVENT_ROUTE_SEND_PONG       0x0008
- #define TRACE_EVENT_ROUTE_RECV_PING       0x0009
- #define TRACE_EVENT_ROUTE_RECV_PONG       0x000A
- #define TRACE_EVENT_ROUTE_POLL            0x000B
- #define TRACE_SUBSYS_BENCH        0x1234
- #define TRACE_EVENT_PCBENCH       0x0000
- #define TRACE_EVENT_RXPING        0x0001
- #define TRACE_EVENT_RXPONG        0x0002
- #define TRACE_SUBSYS_BOMP               0x4000
- #define TRACE_EVENT_BOMP_START          0x0001
- #define TRACE_EVENT_BOMP_STOP           0x0002
- #define TRACE_EVENT_BOMP_ITER           0x0003
- #define TRACE_SUBSYS_BARRIERS                0x5000
- #define TRACE_EVENT_BARRIERS_START           0X0001
- #define TRACE_EVENT_BARRIERS_STOP            0X0002
- #define TRACE_EVENT_BARRIERS_BARRIER_WAIT    0X0003
- #define TRACE_EVENT_BARRIERS_CENTRAL_REQ     0X0004
- #define TRACE_EVENT_BARRIERS_CENTRAL_REP     0X0005
- #define TRACE_EVENT_BARRIERS_TREE_REQ        0X0006
- #define TRACE_EVENT_BARRIERS_TREE_REP        0X0007
- #define TRACE_EVENT_BARRIERS_DIST            0X0008
- #define TRACE_EVENT_BARRIERS_SEND            0X0009
- #define TRACE_EVENT_BARRIERS_POLL1           0X000A
- #define TRACE_EVENT_BARRIERS_POLL2           0X000B
- #define TRACE_EVENT_BARRIERS_HEAP_REQ        0X000C
- #define TRACE_EVENT_BARRIERS_HEAP_REP        0X000D
- #define TRACE_EVENT_BARRIERS_SEQ_BCAST_REQ   0X000E
- #define TRACE_EVENT_BARRIERS_SEQ_BCAST_RECV  0X000F
- #define TRACE_EVENT_BARRIERS_TREE_BCAST_REQ  0X0010
- #define TRACE_EVENT_BARRIERS_TREE_BCAST_RECV 0X0011
- /* Following constants are used in network subsystem. */
- #define TRACE_SUBSYS_NET                    0x6000
- #define TRACE_EVENT_NET_START               0X0001
- #define TRACE_EVENT_NET_STOP                0X0002
- #define TRACE_EVENT_NET_NI_AI               0X0012 /* added, 0 */
- #define TRACE_EVENT_NET_NI_I                0X0010 /* added, 0 */
- #define TRACE_EVENT_NET_NI_A                0X0003 /* added, pkt data location */
- #define TRACE_EVENT_NET_NI_FILTER_FRAG      0X0018 /* added, pkt data location */
- #define TRACE_EVENT_NET_NI_FILTER_EX_1      0X0015 /* added, pkt data location */
- #define TRACE_EVENT_NET_NI_ARP              0X0011 /* added, pkt data location */
- #define TRACE_EVENT_NET_NI_FILTER_EX_2      0X0016 /* added, pkt data location */
- #define TRACE_EVENT_NET_NI_PKT_CPY_1          0X0019 /* added, pkt data location */
- #define TRACE_EVENT_NET_NI_PKT_CPY_2          0X001A /* added, pkt data location */
- #define TRACE_EVENT_NET_NI_PKT_CPY_3          0X001B /* added, pkt data location */
- #define TRACE_EVENT_NET_NI_PKT_CPY_4          0X001C /* added, pkt data location */
- #define TRACE_EVENT_NET_NI_PKT_CPY          0X0017 /* added, pkt data location */
- #define TRACE_EVENT_NET_NI_P                0X0004 /* added, pbuf_id */
- #define TRACE_EVENT_NET_NI_S                0X0005 /* added, pbuf_id */
- #define TRACE_EVENT_NET_AI_A                0X0006 /* added, pbuf_id */
- #define TRACE_EVENT_NET_AI_P                0X0007 /* added, pbuf_addr */
- #define TRACE_EVENT_NET_AO_C                0X0008 /* added, pbuf_addr */
- #define TRACE_EVENT_NET_AO_Q                0X0009 /* added, pbuf_addr */
- #define TRACE_EVENT_NET_AO_S                0X000A /* added, pbuf_addr (as client_data ) */
- #define TRACE_EVENT_NET_NO_A                0X000B /* added, client_data (pbuf_address in lwip) */
- #define TRACE_EVENT_NET_NO_S                0X000C /* added, e1000n.c client_data (pbuf_address in lwip) */
- /* FIXME: Add the timings of when does NIC gets TX_done */
- #define TRACE_EVENT_NET_NO_TXD              0X0013 /* yet to add */
- #define TRACE_EVENT_NET_AIR_R               0x000E /* added, pbuf_addr (TX DONE in app) */
- /* Response flow */
- #define TRACE_EVENT_NET_AOR_S               0x000D /* added, pbuf_id ( register_pbuf from APP)*/
- #define TRACE_EVENT_NET_NIR_REG_PBUF        0x0014 /* commented pbuf_id ( register_pbuf in NIC)*/
- #define TRACE_SUBSYS_MULTIHOP              0x7000
- #define TRACE_EVENT_MULTIHOP_BENCH_START     0x0001
- #define TRACE_EVENT_MULTIHOP_BENCH_STOP      0x0002
- #define TRACE_EVENT_MULTIHOP_MESSAGE_SEND    0x0003
- #define TRACE_EVENT_MULTIHOP_MESSAGE_RECEIVE 0x0004
- /* Following constants are used in network benchmark. */
- #define TRACE_SUBSYS_BNET                    0x8000
- #define TRACE_EVENT_BNET_START               0x0001
- #define TRACE_EVENT_BNET_STOP                0x0002
- #define TRACE_EVENT_BNET_DRV_SEE             0x0003
- #define TRACE_EVENT_BNET_APP_SEE             0x0004
- #define TRACE_EVENT_BNET_DRV_INT             0x0005
- #define TRACE_EVENT_BNET_DRV_POLL            0x0006
- #define TRACE_EVENT_BNET_YIELD               0x0007
- #define TRACE_EVENT_BNET_I                   0x0008
- /* Following constans are used for profiling modified stack */
- #define TRACE_SUBSYS_NNET                    0x9000
- #define TRACE_EVENT_NNET_START               0x0001
- #define TRACE_EVENT_NNET_STOP                0x0002
- #define TRACE_EVENT_NNET_RXDRVSEE            0x0003 // Driver saw pkg (RX)
- #define TRACE_EVENT_NNET_RXESVSEE            0x0004 // Ethersrv saw pkg
- #define TRACE_EVENT_NNET_RXESVFRGDONE        0x0005 // Ethersrv checked frag
- #define TRACE_EVENT_NNET_RXESVAPPFDONE       0x0006 // Ethersrv app filtered
- #define TRACE_EVENT_NNET_RXESVAPPCSTART      0x0007 // Ethersrv app c2u started
- #define TRACE_EVENT_NNET_RXESVCOPIED         0x0008 // Ethersrv copied pkg
- #define TRACE_EVENT_NNET_RXESVSPPDONE        0x000D // Ethersrv spp produce done
- #define TRACE_EVENT_NNET_RXESVAPPNOTIF       0x0009 // Ethersrv app notify
- #define TRACE_EVENT_NNET_RXLWIINCOM          0x000A // LWIP handle_incoming_
- #define TRACE_EVENT_NNET_RXLWIRECH           0x000B // LWIP call rec_handler
- #define TRACE_EVENT_NNET_RXAPPRCV            0x000C // APP received
- #define TRACE_EVENT_NNET_TXAPPSNT            0x0020 // APP sent
- #define TRACE_EVENT_NNET_TXLWISEE            0x0021 // LWIP idc_send_packet
- #define TRACE_EVENT_NNET_TXLWIBFFENCE        0x0029 // LWIP before mfence
- #define TRACE_EVENT_NNET_TXLWIAFFENCE        0x002A // LWIP after mfence
- #define TRACE_EVENT_NNET_TXLWIFLUSHED        0x002B // LWIP payload flushed
- #define TRACE_EVENT_NNET_TXLWIBDESC          0x002C // LWIP bufferdesc fetched
- #define TRACE_EVENT_NNET_TXLWISPPSND         0x0022 // LWIP spp produced
- #define TRACE_EVENT_NNET_TXLWISPPIDX         0x0023 // LWIP update spp index
- #define TRACE_EVENT_NNET_TXLWITXWORK         0x002D // LWIP pending TX work
- #define TRACE_EVENT_NNET_TXLWINOTIF          0x0024 // LWIP notify driver
- #define TRACE_EVENT_NNET_TXESVNOTIF          0x0025 // Ethersrv notify recieved
- #define TRACE_EVENT_NNET_TXESVSPOW           0x002E // Ethersrv send_pkt_on_w..
- #define TRACE_EVENT_NNET_TXESVSSPOW          0x0026 // Ethersrv send_sng_pkt..
- #define TRACE_EVENT_NNET_TXDRVADD            0x0027 // Driver add pkg (TX)
- #define TRACE_EVENT_NNET_TXDRVSEE            0x0028 // Driver saw pkg done (TX)
- #define TRACE_EVENT_NNET_TX_TCP_WRITE        0x0030 // tcp_write done
- #define TRACE_EVENT_NNET_TX_TCP_OUTPUT       0x0031 // tcp_output done
- #define TRACE_EVENT_NNET_TX_TCP_RECV         0x0032 // tcp_recved done
- #define TRACE_EVENT_NNET_TX_TCP_FREE         0x0033 // tx pbuf freed
- #define TRACE_EVENT_NNET_TX_MEMP             0x0034 // tx pbuf memp start
- #define TRACE_EVENT_NNET_TX_MEMP_D           0x0035 // tx pbuf memp done
+ #include <trace_definitions/trace_defs.h>
  
 +
 +/* Constant for low-level networking trace */
 +#define TRACE_SUBSYS_LLNET                  0xD000
 +#define TRACE_EVENT_LLNET_START             0x0001
 +#define TRACE_EVENT_LLNET_STOP              0x0002
 +#define TRACE_EVENT_LLNET_IRQ               0x0003
 +#define TRACE_EVENT_LLNET_LMPDISP           0x0004
 +
 +#define TRACE_EVENT_LLNET_DRVIRQ            0x0010
 +#define TRACE_EVENT_LLNET_DRVRX             0x0011
 +#define TRACE_EVENT_LLNET_DRVTXADD          0x0012
 +#define TRACE_EVENT_LLNET_DRVTXDONE         0x0013
 +
 +#define TRACE_EVENT_LLNET_LWIPPBA1          0x0020
 +#define TRACE_EVENT_LLNET_LWIPPBA2          0x0021
 +#define TRACE_EVENT_LLNET_LWIPPBF1          0x0022
 +#define TRACE_EVENT_LLNET_LWIPPBF2          0x0023
 +#define TRACE_EVENT_LLNET_LWIPRX            0x0024
 +#define TRACE_EVENT_LLNET_LWIPTX            0x0025
 +
 +#define TRACE_EVENT_LLNET_APPRX             0x0030
 +#define TRACE_EVENT_LLNET_APPTX             0x0031
 +
 +
 +
  #define TRACE_EVENT(s,e,a) ((uint64_t)(s)<<48|(uint64_t)(e)<<32|(a))
  
  /* XXX: this is a temp kludge. The tracing code wants to allocate a fixed buffer
Simple merge
@@@ -387,19 -387,10 +387,19 @@@ errval_t spawn_exit(uint8_t exitcode
  }
  
  /**
-  * \brief Exit this domain.
+  * \brief Wait for spawned proccess to exit on core.
   */
- errval_t spawn_wait(domainid_t domainid, uint8_t *exitcode, bool nohang)
+ errval_t spawn_wait_coreid(coreid_t coreid, domainid_t domainid, uint8_t *exitcode, bool nohang)
  {
 +    return spawn_wait_core(disp_get_core_id(), domainid, exitcode, nohang);
 +}
 +
 +/**
 + * \brief Wait for the termination of a domain on a remote core.
 + */
 +errval_t spawn_wait_core(coreid_t coreid, domainid_t domainid,
 +                         uint8_t *exitcode, bool nohang)
 +{
      errval_t err, reterr;
  
      err = bind_client(coreid);
@@@ -23,8 -23,8 +23,9 @@@
  
  #include <stdio.h>
  #include <string.h>
 +#include <sys/param.h>
  #include <trace/trace.h>
+ #include <trace_definitions/trace_defs.h>
  #include <net_queue_manager/net_queue_manager.h>
  #include <bfdmuxvm/vm.h>
  #include <if/net_soft_filters_defs.h>
@@@ -12,6 -12,7 +12,7 @@@
  
  [ build application { target = "bfscope",
                        cFiles = [ "bfscope.c" ],
-                       addLibraries = [ "lwip", "contmng", "net_if_raw", "trace" ]
 -                      addLibraries = [ "lwip", "contmng", "trace" ],
++                      addLibraries = [ "lwip", "contmng", "net_if_raw", "trace" ],
+                       flounderBindings = [ "empty" ]
                      }
  ]
  
  #if CONFIG_TRACE && NETWORK_STACK_BENCHMARK
  #define TRACE_N_BM 1
 -#endif
 +#endif // CONFIG_TRACE && NETWORK_STACK_BENCHMARK
  
+ #define MAX_ALLOWED_PKT_PER_ITERATION   (0xff)  // working value
+ /* Transmit and receive buffers must be multiples of 8 */
+ #define DRIVER_RECEIVE_BUFFERS      (1024 * 8)
+ #define DRIVER_TRANSMIT_BUFFERS     (1024 * 8)
 +//#define ENABLE_DEBUGGING_E1000 1
 +#ifdef ENABLE_DEBUGGING_E1000
 +static bool local_debug = true;
 +#define E1000N_DPRINT(x...) do{if(local_debug) printf("e1000n: " x); } while(0)
 +#else
 +#define E1000N_DPRINT(x...) ((void)0)
 +#endif // ENABLE_DEBUGGING_E1000
  
- /*****************************************************************
-  * Data types:
-  *****************************************************************/
+ /* MTU is 1500 bytes, plus Ethernet header plus CRC. */
+ #define RX_PACKET_MAX_LEN       (1500 + 14 + 4)
  
+ #define PACKET_SIZE_LIMIT       1073741824      /* 1 Gigabyte */
+ /*****************************************************************
+  * External declarations for net_queue_manager
+  *
+  ****************************************************************/
  extern uint64_t interrupt_counter;
  extern uint64_t total_rx_p_count;
- extern uint64_t total_interrupt_time;
  extern struct client_closure *g_cl;
- extern uint64_t total_processing_time;
  extern uint64_t total_rx_datasize;
  
- static uint8_t macaddr[6]; ///< buffers the card's MAC address upon card reset
- e1000_t d;  ///< Mackerel state
- static bool user_macaddr; /// True iff the user specified the MAC address
- static bool use_interrupt = true;
- #define MAX_ALLOWED_PKT_PER_ITERATION    (0xff)  // working value
- #define DRIVER_RECEIVE_BUFFERS   (1024 * 8) // Number of buffers with driver
- #define RECEIVE_BUFFER_SIZE (2048) // MAX size of ethernet packet
- #define DRIVER_TRANSMIT_BUFFER   (1024 * 8)
- //transmit
+ /*****************************************************************
+  * Receive and transmit
+  *****************************************************************/
+ static e1000_rx_bsize_t receive_buffer_size = bsize_16384;
  static volatile struct tx_desc *transmit_ring;
 +
 +// Data-structure to map sent buffer slots back to application slots
 +struct pbuf_desc {
 +    void *opaque;
 +};
 +static struct pbuf_desc pbuf_list_tx[DRIVER_TRANSMIT_BUFFER];
 +//remember the tx pbufs in use
 +
 +//receive
  static volatile union rx_desc *receive_ring;
  
- static uint32_t ether_transmit_index = 0, ether_transmit_bufptr = 0;
- /* TODO: check if these variables are used */
- static uint32_t receive_index = 0, receive_bufptr = 0;
- static uint32_t receive_free = 0;
+ static void *receive_ring_phys_addr = NULL;
+ static void *receive_ring_virt_addr = NULL;
 -
+ static uint32_t receive_bufptr_index = 0;
+ static uint32_t receive_ring_index = 0;
+ static uint32_t receive_ring_free = 0;
 -
 +static void **receive_opaque = NULL;
+ /*****************************************************************
++
+  * e1000 states:
+  *****************************************************************/
+ static e1000_t e1000;
+ static e1000_device_t e1000_device;
+ static uint8_t mac_address[MAC_ADDRESS_LEN]; /* buffers the card's MAC address upon card reset */
  
+ /*****************************************************************
+  * argument states:
+  *****************************************************************/
+ static bool user_mac_address; /* True if the user specified the MAC address */
+ static bool use_interrupt = true; /* don't use card polling mode */
+ static bool use_force = false; /* don't attempt to find card force load */
  
  /*****************************************************************
   * Local states:
   *****************************************************************/
- static uint64_t bus = PCI_DONT_CARE;
- static uint64_t device = PCI_DONT_CARE;
 -static uint64_t minbase = -1;
 -static uint64_t maxbase = -1;
 -
+ static uint32_t class = PCI_CLASS_ETHERNET;
+ static uint32_t subclass = PCI_DONT_CARE;
+ static uint32_t bus = PCI_DONT_CARE;
+ static uint32_t device = PCI_DONT_CARE;
  static uint32_t function = PCI_DONT_CARE;
  static uint32_t deviceid = PCI_DONT_CARE;
+ static uint32_t vendor = PCI_VENDOR_INTEL;
+ static uint32_t program_interface = PCI_DONT_CARE;
+ static e1000_mac_type_t mac_type = e1000_undefined;
  
- /* FIXME: most probably, I don't need this.  So, remove it.  */
+ /*****************************************************************
+  * For use with the net_queue_manager
+  *
+  *****************************************************************/
  static char *global_service_name = 0;
- static uint64_t assumed_queue_id = 0;
- static bool handle_free_TX_slot_fn(void);
+ static uint64_t assumed_queue_id = 0;   /* what net queue to bind to */
+ static uint32_t ether_transmit_index = 0;
+ static uint32_t ether_transmit_bufptr_index = 0;
 -/*
 - * Structure to map sent buffer slots back to application slots
 - */
 -struct pbuf_desc {
 -    struct net_queue_manager_binding *sr; /* which application binding */
 -    uint64_t spp_index; /* which slot within spp */
 -};
 -
+ static struct pbuf_desc pbuf_list_tx[DRIVER_TRANSMIT_BUFFERS];
+ /*****************************************************************
+  * Print physical link status.
+  *
+  ****************************************************************/
+ static void e1000_print_link_status(e1000_device_t *dev)
+ {
+     const char *media_type = NULL;
+     e1000_status_t status;
+     status = e1000_status_rd(dev->device);
+     e1000_ledctl_rd(dev->device);
+     switch (dev->media_type) {
+     case e1000_media_type_copper:
+         media_type = "copper";
+         break;
+     case e1000_media_type_fiber:
+         media_type = "fiber";
+         break;
+     case e1000_media_type_serdes:
+         media_type = "SerDes";
+         break;
+     default:
+         media_type = "Unknown";
+         break;
+     }
+     if (e1000_check_link_up(dev)) {
+         const char *duplex;
+         if (e1000_status_fd_extract(status)) {
+             duplex = "Full";
+         } else {
+             duplex = "Half";
+         }
+         switch (e1000_status_speed_extract(status)) {
+         case 0x0:
+             E1000_PRINT("Media type: %s, Link speed: 10 Mb in %s duplex.\n",
+                         media_type, duplex);
+             break;
+         case 0x1:
+             E1000_PRINT("Media type: %s, Link speed: 100 Mb in %s duplex.\n",
+                         media_type, duplex);
+             break;
+         default:
+             E1000_PRINT("Media type: %s, Link speed: 1 Gb in %s duplex.\n",
+                         media_type, duplex);
+             break;
+         }
+     } else {
+         E1000_PRINT("Media type: %s, Link down.\n", media_type);
+     }
+ }
+ /*****************************************************************
+  * And descriptor to receive ring
+  *
+  ****************************************************************/
+ static int add_desc(uint64_t paddr)
+ {
+     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_ring_free == DRIVER_RECEIVE_BUFFERS) {
+         return -1;
+     }
+     receive_ring[receive_ring_index] = desc;
+     receive_ring_index = (receive_ring_index + 1) % DRIVER_RECEIVE_BUFFERS;
+     dqval = e1000_dqval_val_insert(dqval, receive_ring_index);
+     e1000_rdt_wr(&e1000, 0, dqval);
+     receive_ring_free++;
+     return 0;
+ }
  
  /*****************************************************************
-  * MAC address
+  * get_mac_address_fn for net_queue_manager
+  *
+  * NOTE: This function gets called in ethersrv.c.
   ****************************************************************/
- /* NOTE: This function will get called from ethersrv.c */
  static void get_mac_address_fn(uint8_t *mac)
  {
-     memcpy(mac, macaddr, sizeof(macaddr));
+     memcpy(mac, mac_address, sizeof(mac_address));
  }
  
- static bool parse_mac(uint8_t *mac, const char *str)
+ /*****************************************************************
+  * find_tx_free_slot for net_queue_manager
+  *
+  *****************************************************************/
+ static uint64_t find_tx_free_slot_count_fn(void)
  {
-     for (int i = 0; i < 6; i++) {
-         char *next = NULL;
-         unsigned long val = strtoul(str, &next, 16);
-         if (val > UINT8_MAX || next == NULL
-             || (i == 5 && *next != '\0')
-             || (i < 5 && (*next != ':' && *next != '-'))) {
-             return false; // parse error
-         }
-         mac[i] = val;
-         str = next + 1;
+     uint64_t free_slots;
+     if (ether_transmit_index >= ether_transmit_bufptr_index) {
+         free_slots = DRIVER_TRANSMIT_BUFFERS
+                      - ((ether_transmit_index - ether_transmit_bufptr_index)
+                         % DRIVER_TRANSMIT_BUFFERS);
+     } else {
+         free_slots = (ether_transmit_bufptr_index - ether_transmit_index)
+                      % DRIVER_TRANSMIT_BUFFERS;
      }
  
-     return true;
+     return free_slots;
  }
  
  /*****************************************************************
   * Transmit logic
-  ****************************************************************/
- /* check if there are enough free buffers with driver,
+  *
+  * Check if there are enough free buffers with driver,
   * so that packet can be sent
-  * */
- static bool can_transmit(int numbufs)
+  ****************************************************************/
+ static bool can_transmit(uint64_t numbufs)
  {
-     uint64_t nr_free;
-     assert(numbufs < DRIVER_TRANSMIT_BUFFER);
-     if (ether_transmit_index >= ether_transmit_bufptr) {
-         nr_free = DRIVER_TRANSMIT_BUFFER -
-             ((ether_transmit_index - ether_transmit_bufptr) %
-                 DRIVER_TRANSMIT_BUFFER);
-     } else {
-         nr_free = (ether_transmit_bufptr - ether_transmit_index) %
-             DRIVER_TRANSMIT_BUFFER;
+     uint64_t free_slots;
+     assert(numbufs < DRIVER_TRANSMIT_BUFFERS);
+     free_slots = find_tx_free_slot_count_fn();
+     return (free_slots > numbufs);
+ }
+ /*****************************************************************
+  * handle_free_TX_slot_fn for net_queue_manager
+  *
+  *****************************************************************/
+ static bool handle_free_TX_slot_fn(void)
+ {
+     uint64_t ts = rdtsc();
+     bool sent = false;
+     volatile struct tx_desc *txd;
+     if (ether_transmit_bufptr_index == ether_transmit_index) {
+         return false;
+     }
+     txd = &transmit_ring[ether_transmit_bufptr_index];
+     if (txd->ctrl.legacy.stat_rsv.d.dd != 1) {
+         return false;
++
      }
-     return (nr_free > numbufs);
+ #if TRACE_ONLY_SUB_NNET
+     trace_event(TRACE_SUBSYS_NNET, TRACE_EVENT_NNET_TXDRVSEE, 0);
+ #endif
 -    sent = handle_tx_done(pbuf_list_tx[ether_transmit_bufptr_index].sr,
 -                          pbuf_list_tx[ether_transmit_bufptr_index].spp_index);
++    sent = handle_tx_done(pbuf_list_tx[ether_transmit_bufptr_index].s.opaque); 
+     ether_transmit_bufptr_index = (ether_transmit_bufptr_index + 1)
+                                   % DRIVER_TRANSMIT_BUFFERS;
+     netbench_record_event_simple(bm, RE_TX_DONE, ts);
+     return true;
  }
  
- static uint64_t transmit_pbuf(uint64_t buffer_address,
+ /*****************************************************************
+  * Setup transmit descriptor for packet transmission.
+  *
+  *****************************************************************/
 -static uint64_t transmit_pbuf(lpaddr_t buffer_address, size_t packet_len,
 -                              uint64_t offset, bool last, uint64_t client_data, uint64_t spp_index,
 -                              struct net_queue_manager_binding *sr)
++ 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;
  
 -    tdesc.buffer_address = (uint64_t) buffer_address + offset;
 +    tdesc.buffer_address = buffer_address;
      tdesc.ctrl.raw = 0;
      tdesc.ctrl.legacy.data_len = packet_len;
      tdesc.ctrl.legacy.cmd.d.rs = 1;
      tdesc.ctrl.legacy.cmd.d.ifcs = 1;
      tdesc.ctrl.legacy.cmd.d.eop = (last ? 1 : 0);
  
+     /* FIXME: the packet should be copied into separate location, so that
+      * application can't temper with it. */
      transmit_ring[ether_transmit_index] = tdesc;
 -    pbuf_list_tx[ether_transmit_index].sr = sr;
 -    pbuf_list_tx[ether_transmit_index].spp_index = spp_index;
 +    pbuf_list_tx[ether_transmit_index].opaque = opaque;
  
-     ether_transmit_index = (ether_transmit_index + 1) % DRIVER_TRANSMIT_BUFFER;
-     e1000_tdt_wr(&(d), 0, (e1000_dqval_t){ .val = ether_transmit_index });
+     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);
  
-     E1000N_DEBUG("ether_transmit_index %"PRIu32"\n", ether_transmit_index);
      /* Actual place where packet is sent.  Adding trace_event here */
  #if TRACE_ETHERSRV_MODE
      trace_event(TRACE_SUBSYS_NET, TRACE_EVENT_NET_NO_S,
      return 0;
  }
  
- /* Send the buffer to device driver TX ring.
-  * NOTE: This function will get called from ethersrv.c */
+ /*****************************************************************
+  * transmit_pbuf_list_fn for net_queue_manager
+  *
+  * Send the buffer to device driver TX ring.
+  *
+  * NOTE: This function get called from ethersrv.c
+  *****************************************************************/
 -static errval_t transmit_pbuf_list_fn(struct client_closure *cl)
 -{
 -    struct shared_pool_private *spp = cl->spp_ptr;
 -    struct slot_data *sld = &spp->sp->slot_list[cl->tx_index].d;
 -    uint64_t rtpbuf = sld->no_pbufs;
 -    struct buffer_descriptor *cached_buffer;
 +static errval_t transmit_pbuf_list_fn(struct driver_buffer *buffers,
 +                                      size_t                count,
 +                                      void                 *opaque)
 -    if (!can_transmit(rtpbuf)) {
 -        while (handle_free_TX_slot_fn())
 -            ;
 +{
-     errval_t r;
 +    E1000N_DEBUG("transmit_pbuf_list_fn(count=%"PRIu64")\n", count);
 +    if (!can_transmit(count)){
 +        while(handle_free_TX_slot_fn());
 +        if (!can_transmit(count)){
              return ETHERSRV_ERR_CANT_TRANSMIT;
          }
      }
 -
 -    cached_buffer = find_buffer(sld->buffer_id);
 -
 -    if (cached_buffer == NULL) {
+         USER_PANIC("find_buffer failed.\n");
 -        abort();
 -    }
 -
 -    // FIXME: code should work with following assert enable.
 -    // Current problem is that, ARP request packets are reused to send the
 -    // response, and hence having different buffer_id than of tx buffer
 -    // assert(buffer == cl->buffer_ptr);
 -
 -    for (int i = 0; i < rtpbuf; i++) {
 -        struct buffer_descriptor *buffer;
 -        uint64_t slot_index;
 -        errval_t err;
 -        slot_index = (cl->tx_index + i) % cl->spp_ptr->c_size;
 -        sld = &spp->sp->slot_list[slot_index].d;
 -        assert(sld != NULL);
  
 -        if (sld->buffer_id == 0) {
 -            E1000_PRINT_ERROR("TX malformed packet at slot index %"PRIu64".\n",
 -                              slot_index);
 -            return -1;
 -        }
 -
 -        if (cached_buffer->buffer_id == sld->buffer_id) {
 -            buffer = cached_buffer;
 -        } else {
 -            buffer = find_buffer(sld->buffer_id);
 +    if (count > 1) {
 +        printf("Sending %zx chunks\n", count);
 +    }
 +    for (int i = 0; i < count; i++) {
 +        r = transmit_pbuf(buffers[i].pa, buffers[i].len,
 +                    i == (count - 1), //last?
 +                    opaque);
 +        if(err_is_fail(r)) {
 +            //E1000N_DEBUG("ERROR:transmit_pbuf failed\n");
 +            printf("ERROR:transmit_pbuf failed\n");
 +            return r;
          }
 +        E1000N_DEBUG("transmit_pbuf done for pbuf 0x%p, index %i\n",
 +            opaque, i);
 +    } // end for: for each pbuf
 +#if TRACE_ONLY_SUB_NNET
 +    trace_event(TRACE_SUBSYS_NNET,  TRACE_EVENT_NNET_TXDRVADD,
 +        (uint32_t)0);
 +#endif // TRACE_ONLY_SUB_NNET
  
 -        assert(buffer->buffer_id == sld->buffer_id);
 +    return SYS_ERR_OK;
 +} // end function: transmit_pbuf_list_fn
  
 -        err = transmit_pbuf(buffer->pa, sld->len, sld->offset,
 -                            i == (rtpbuf - 1), /* last? */
 -                            sld->client_data, slot_index, cl->app_connection);
  
- static uint64_t find_tx_free_slot_count_fn(void)
- {
-     uint64_t nr_free;
-     if (ether_transmit_index >= ether_transmit_bufptr) {
-         nr_free = DRIVER_TRANSMIT_BUFFER -
-             ((ether_transmit_index - ether_transmit_bufptr) %
-                 DRIVER_TRANSMIT_BUFFER);
-     } else {
-         nr_free = (ether_transmit_bufptr - ether_transmit_index) %
-             DRIVER_TRANSMIT_BUFFER;
-     }
-     return nr_free;
- } // end function: find_tx_queue_len
- static bool handle_free_TX_slot_fn(void)
- {
-     uint64_t ts = rdtsc();
-     bool sent = false;
-     volatile struct tx_desc *txd;
-     if (ether_transmit_bufptr == ether_transmit_index) {
-         return false;
-     }
-     txd = &transmit_ring[ether_transmit_bufptr];
-     if (txd->ctrl.legacy.sta_rsv.d.dd != 1) {
-         return false;
-     }
- #if TRACE_ONLY_SUB_NNET
-     trace_event(TRACE_SUBSYS_NNET, TRACE_EVENT_NNET_TXDRVSEE,
-                 0);
- #endif // TRACE_ONLY_SUB_NNET
 -        if (err_is_fail(err)) {
 -            E1000_PRINT_ERROR("transmit_pbuf failed.\n");
 -            return err;
 -        }
  
-     sent = handle_tx_done(pbuf_list_tx[ether_transmit_bufptr].opaque);
 -        E1000_DEBUG("transmit_pbuf done for pbuf %"PRIx64", index %"PRIu64"\n", sld->client_data, slot_index);
 -    }
  
-     ether_transmit_bufptr = (ether_transmit_bufptr + 1)%DRIVER_TRANSMIT_BUFFER;
-     netbench_record_event_simple(bm, RE_TX_DONE, ts);
-     return true;
- }
 -#if TRACE_ONLY_SUB_NNET
 -    trace_event(TRACE_SUBSYS_NNET, TRACE_EVENT_NNET_TXDRVADD, (uint32_t)0);
 -#endif
  
 -    return SYS_ERR_OK;
 -}
  
  /*****************************************************************
-  * Initialize internal memory for the device
-  ****************************************************************/
+  *
+  *
+  *
+  *****************************************************************/
 +static int add_desc(uint64_t paddr, void *opaque)
 +{
 +    union rx_desc r;
 +    r.raw[0] = r.raw[1] = 0;
 +    r.rx_read_format.buffer_address = paddr;
 +
 +    if(receive_free == DRIVER_RECEIVE_BUFFERS) {
 +        // This is serious error condition.
 +        // Printing debug information to help user!
 +      //E1000N_DEBUG("no space to add a new receive pbuf\n");
 +      printf("no space to add a new receive pbuf [%"PRIu32"], [%"PRIu32"]\n",
 +                receive_free, receive_index);
 +        printf("%p\n%p\n%p\n", __builtin_return_address(0),
 +                __builtin_return_address(1), __builtin_return_address(2));
 +        abort();
 +      /* FIXME: how can you return -1 as error here
 +       * when return type is unsigned?? */
 +      return -1;
 +    }
 +
 +    receive_ring[receive_index] = r;
 +    receive_opaque[receive_index] = opaque;
 +
 +    receive_index = (receive_index + 1) % DRIVER_RECEIVE_BUFFERS;
 +    e1000_rdt_wr(&d, 0, (e1000_dqval_t){ .val=receive_index } );
 +    receive_free++;
 +    return 0;
 +}
 +
- static void setup_internal_memory(void)
- {
-     receive_opaque = calloc(sizeof(void *), DRIVER_RECEIVE_BUFFERS);
- }
 +
 +static errval_t rx_register_buffer_fn(uint64_t paddr, void *vaddr, void *opaque)
 +{
 +    return add_desc(paddr, opaque);
 +}
 +static uint64_t rx_find_free_slot_count_fn(void)
 +{
 +    return DRIVER_RECEIVE_BUFFERS - receive_free;
 +}
 +
 +static void print_rx_bm_stats(bool stop_trace)
 +{
 +    if (g_cl == NULL) {
 +        return;
 +    }
 +
 +    if (g_cl->debug_state != 4) {
 +        return;
 +    }
 +
 +    uint64_t cts = rdtsc();
 +
 +    if (stop_trace) {
 +
 +#if TRACE_N_BM
 +    // stopping the tracing
 +        trace_event(TRACE_SUBSYS_BNET, TRACE_EVENT_BNET_STOP, 0);
 +
 +        /*
 +        char *buf = malloc(4096*4096);
 +        trace_dump(buf, 4096*4096);
 +        printf("%s\n", buf);
 +        */
 +#endif // TRACE_N_BM
 +
 +    } // end if: stop_trace
 +
 +    uint64_t running_time = cts - g_cl->start_ts;
 +    printf("D:I:%u: RX speed = [%"PRIu64"] packets "
 +        "data(%"PRIu64") / time(%"PU") = [%f] MB/s ([%f]Mbps) = "
 +        " [%f]mpps, INT [%"PRIu64"]\n",
 +        disp_get_core_id(),
 +        total_rx_p_count, total_rx_datasize, in_seconds(running_time),
 +        ((total_rx_datasize/in_seconds(running_time))/(1024 * 1024)),
 +        (((total_rx_datasize * 8)/in_seconds(running_time))/(1024 * 1024)),
 +        ((total_rx_p_count/in_seconds(running_time))/(double)(1000000)),
 +        interrupt_counter
 +        );
 +
 +    netbench_print_event_stat(bm, RE_COPY, "D: RX CP T", 1);
 +    netbench_print_event_stat(bm, RE_PROCESSING_ALL, "D: RX processing T", 1);
 +} // end function: print_rx_bm_stats
 +
 +static char tmp_buf[2000];
  static bool handle_next_received_packet(void)
  {
      volatile union rx_desc *rxd;
 +    size_t len = 0;
      bool new_packet = false;
-     tmp_buf[0] = 0; // FIXME: to avoid the warning of not using this variable
+     errval_t err;
  
-     if (receive_bufptr == receive_index) { //no packets received
+     if (receive_bufptr_index == receive_ring_index) {
          return false;
      }
  
- //    E1000N_DEBUG("Inside handle next packet 2\n");
-     rxd = &receive_ring[receive_bufptr];
+     rxd = &receive_ring[receive_bufptr_index];
  
-     if ((rxd->rx_read_format.info.status.dd) &&
-             (rxd->rx_read_format.info.status.eop)
- //            && (!local_pbuf[receive_bufptr].event_sent)
-             ) {
-         // valid packet received
+     if ((rxd->rx_read_format.info.status.dd)
+             && (rxd->rx_read_format.info.status.eop)) {
+         struct buffer_descriptor *buffer = NULL;
+         void *buffer_address = NULL;
+         void *data = NULL;
+         size_t len = 0;
  
-     E1000N_DPRINT("Potential packet receive [%"PRIu32"]!\n",
-             receive_bufptr);
+         /* A valid packet received */
 -
+         E1000_DEBUG("Potential packet receive [%"PRIu32"]!\n", receive_bufptr_index);
 -
          new_packet = true;
+         /* Ensures that netd is up and running */
+         if (waiting_for_netd()) {
+             E1000_DEBUG("still waiting for netd to register buffers.\n");
+             buffer = NULL;
+             goto end;
+         }
          len = rxd->rx_read_format.info.length;
+         if (len > RX_PACKET_MAX_LEN) {
+             E1000_DEBUG("Dropping packet with invalid length %zu.\n", len);
+             goto end;
+         }
          total_rx_datasize += len;
  
  #if TRACE_ONLY_SUB_NNET
          trace_event(TRACE_SUBSYS_NNET, TRACE_EVENT_NNET_RXDRVSEE,
                      (uint32_t) len);
- #endif // TRACE_ONLY_SUB_NNET
+ #endif
+         buffer_address = (void *) rxd->rx_read_format.buffer_address;
+         data = (buffer_address - receive_ring_phys_addr)
+                + receive_ring_virt_addr;
 -
+         if (data == NULL || len == 0) {
+             E1000_DEBUG("Dropping incorrect packet.\n");
+             // FIXME: What should I do when such errors occur.
+             buffer = NULL;
+             goto end;
+         }
  
-         process_received_packet(receive_opaque[receive_bufptr], len, true);
+ #if !defined(__scc__) && !defined(__i386__)
+         cache_flush_range(data, len);
+ #endif
  
- #if 0
-         // This code is useful for RX micro-benchmark
-         // only to measures performance of accepting incoming packets
+ #ifdef CONFIG_MICROBENCHMARKS
+         /* This code is useful for RX micro-benchmark
+          * only to measure performance of accepting incoming packets */
          if (g_cl != NULL) {
              if (g_cl->debug_state == 4) {
                  uint64_t ts = rdtsc();
  
- //                memcpy_fast(tmp_buf, data, len);
                  process_received_packet(data, len);
                  total_processing_time = total_processing_time +
-                     (rdtsc() - ts);
+                                         (rdtsc() - ts);
              } else {
                  process_received_packet(data, len);
              }
@@@ -506,19 -619,16 +677,16 @@@ static void polling_loop(void
          ++poll_count;
  
          ts = rdtsc();
 -        do_pending_work_for_all();
 +//        do_pending_work_for_all();
          netbench_record_event_simple(bm, RE_PENDING_WORK, ts);
  
 -        err = event_dispatch_non_block(ws);
 +//        err = event_dispatch(ws); // blocking // doesn't work correctly
-         err = event_dispatch_non_block(ws); // nonblocking
-         if (err != LIB_ERR_NO_EVENT) {
-             if (err_is_fail(err)) {
-                 DEBUG_ERR(err, "in event_dispatch_non_block");
-                 break;
-             } else {
-                 // Handled some event dispatch
-                 no_work = false;
-             }
+         if (err != LIB_ERR_NO_EVENT && err_is_fail(err)) {
+             E1000_DEBUG("Error in event_dispatch_non_block, returned %d\n",
+                         (unsigned int)err);
+             break;
+         } else {
+             no_work = false;
          }
  
  #if TRACE_N_BM
@@@ -570,47 -907,81 +966,85 @@@ static void check_possible_e1000_card(o
  int main(int argc, char **argv)
  {
      char *service_name = 0;
-     errval_t r;
+     errval_t err;
  
+     /** Parse command line arguments. */
+     for (int i = 1; i < argc; i++) {
 +    E1000N_DEBUG("e1000 standalone driver started.\n");
 +
 +    E1000N_DEBUG("argc = %d\n", argc);
 +    for (int i = 0; i < argc; i++) {
 +        E1000N_DEBUG("arg %d = %s\n", i, argv[i]);
-         if(strncmp(argv[i],"servicename=",strlen("servicename=")-1)==0) {
+         if (strncmp(argv[i], "affinitymin=", strlen("affinitymin=")) == 0) {
+             minbase = atol(argv[i] + strlen("affinitymin="));
+             E1000_DEBUG("minbase = %lu\n", minbase);
+         }
+         else if (strncmp(argv[i], "affinitymax=", strlen("affinitymax="))
+                  == 0) {
+             maxbase = atol(argv[i] + strlen("affinitymax="));
+             E1000_DEBUG("maxbase = %lu\n", maxbase);
+         }
+         else if (strncmp(argv[i], "servicename=", strlen("servicename="))
+                  == 0) {
              service_name = argv[i] + strlen("servicename=");
-             E1000N_DEBUG("service name = %s\n", service_name);
+             E1000_DEBUG("service name = %s\n", service_name);
 -        }
 +        } else if(strncmp(argv[i],"bus=",strlen("bus=")-1)==0) {
+         else if (strncmp(argv[i], "bus=", strlen("bus=")) == 0) {
              bus = atol(argv[i] + strlen("bus="));
-             E1000N_DEBUG("bus = %lu\n", bus);
-         } else if(strncmp(argv[i],"device=",strlen("device=")-1)==0) {
+             E1000_DEBUG("bus = %ul\n", bus);
+             use_force = true;
+         }
+         else if (strncmp(argv[i], "device=", strlen("device=")) == 0) {
              device = atol(argv[i] + strlen("device="));
-             E1000N_DEBUG("device = %lu\n", device);
-         } else if(strncmp(argv[i],"function=",strlen("function=")-1)==0) {
+             E1000_DEBUG("device = %ul\n", device);
+             use_force = true;
+         }
+         else if (strncmp(argv[i], "function=", strlen("function=")) == 0) {
              function = atol(argv[i] + strlen("function="));
-             E1000N_DEBUG("function = %u\n", function);
-         } else if(strncmp(argv[i],"deviceid=",strlen("deviceid=")-1)==0) {
+             E1000_DEBUG("function = %u\n", function);
+             use_force = true;
+         }
+         else if (strncmp(argv[i], "deviceid=", strlen("deviceid=")) == 0) {
              deviceid = strtoul(argv[i] + strlen("deviceid="), NULL, 0);
-             E1000N_DEBUG("deviceid = %u\n", deviceid);
-             printf("### deviceid = %u\n", deviceid);
-         } else if(strncmp(argv[i],"mac=",strlen("mac=")-1)==0) {
-             if (parse_mac(macaddr, argv[i] + strlen("mac="))) {
-                 user_macaddr = true;
-                 E1000N_DEBUG("MAC= %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
-                              macaddr[0], macaddr[1], macaddr[2],
-                              macaddr[3], macaddr[4], macaddr[5]);
+             E1000_DEBUG("deviceid = %u\n", deviceid);
+             use_force = true;
 -        }
+         else if (strncmp(argv[i], "mac=", strlen("mac=")) == 0) {
+             if (parse_mac(mac_address, argv[i] + strlen("mac="))) {
+                 user_mac_address = true;
+                 E1000_DEBUG("MAC= %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
+                             mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]);
              } else {
-                 fprintf(stderr, "%s: Error parsing MAC address '%s'\n",
-                         argv[0], argv[i]);
-                 return 1;
+                 E1000_PRINT_ERROR("Error: Failed parsing MAC address '%s'.\n", argv[i]);
+                 exit(1);
              }
 -        }
 +        } else if(strcmp(argv[i],"noirq")==0) {
+         else if (strcmp(argv[i], "noirq") == 0) {
+             E1000_DEBUG("Driver working in polling mode.\n");
              use_interrupt = false;
-             printf("Driver working in polling mode\n");
-         } else {
-             // Pass argument to library
-             ethersrv_argument(argv[i]);
          }
+         else if (strcmp(argv[i], "-h") == 0 ||
+                  strcmp(argv[i], "--help") == 0) {
+             exit_help(argv[0]);
+         }
+         else {
+             E1000_PRINT_ERROR("Error: unknown argument: %s.\n", argv[i]);
+             exit_help(argv[0]);
+         }
+     }
+     if ((minbase != -1) && (maxbase != -1)) {
+         E1000_DEBUG("set memory affinity [%lx, %lx]\n", minbase, maxbase);
+         ram_set_affinity(minbase, maxbase);
      }
  
      if (service_name == 0) {
  /*****************************************************************
   * Debug printer:
   *****************************************************************/
 -
 +//#define E1000N_SERVICE_DEBUG 1
- #if defined(E1000N_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
- #define E1000N_DEBUG(x...) printf("e1000n: " x)
+ #if defined(E1000_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
+ #define E1000_DEBUG(fmt, ...) printf(DRIVER_STRING fmt, ##__VA_ARGS__)
  #else
- #define E1000N_DEBUG(x...) ((void)0)
+ #define E1000_DEBUG(fmt, ...) ((void)0)
  #endif
  
- #endif // E1000_DEBUG_H_
+ #endif
Simple merge
Simple merge