Index: uspace/lib/c/generic/device/nic.c
===================================================================
--- uspace/lib/c/generic/device/nic.c	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/c/generic/device/nic.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -73,8 +73,7 @@
 }
 
-/** Connect the driver to the NET and NIL services
- *
- * @param[in] dev_sess
- * @param[in] nil_service Service identifier for the NIL service
+/** Create callback connection from NIC service
+ *
+ * @param[in] dev_sess
  * @param[in] device_id
  *
@@ -82,13 +81,24 @@
  *
  */
-int nic_connect_to_nil(async_sess_t *dev_sess, services_t nil_service,
-    nic_device_id_t device_id)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_3_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_CONNECT_TO_NIL, nil_service, device_id);
-	async_exchange_end(exch);
-	
-	return rc;
+int nic_callback_create(async_sess_t *dev_sess, async_client_conn_t cfun,
+    void *carg)
+{
+	ipc_call_t answer;
+	int rc;
+	sysarg_t retval;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_CALLBACK_CREATE, &answer);
+	
+	rc = async_connect_to_me(exch, 0, 0, 0, cfun, carg);
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return rc;
+	}
+	async_exchange_end(exch);
+	
+	async_wait_for(req, &retval);
+	return (int) retval;
 }
 
@@ -335,5 +345,5 @@
  * it can never force the NIC to advertise unsupported modes.
  *
- * The allowed modes are defined in "net/eth_phys.h" in the C library.
+ * The allowed modes are defined in "nic/eth_phys.h" in the C library.
  *
  * @param[in] dev_sess
@@ -372,5 +382,5 @@
 /** Probe current state of auto-negotiation.
  *
- * Modes are defined in the "net/eth_phys.h" in the C library.
+ * Modes are defined in the "nic/eth_phys.h" in the C library.
  *
  * @param[in]  dev_sess
Index: uspace/lib/c/generic/loc.c
===================================================================
--- uspace/lib/c/generic/loc.c	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/c/generic/loc.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -47,4 +47,5 @@
 static FIBRIL_MUTEX_INITIALIZE(loc_callback_mutex);
 static bool loc_callback_created = false;
+static loc_cat_change_cb_t cat_change_cb = NULL;
 
 static async_sess_t *loc_supp_block_sess = NULL;
@@ -54,10 +55,6 @@
 static async_sess_t *loc_consumer_sess = NULL;
 
-static loc_cat_change_cb_t cat_change_cb = NULL;
-
 static void loc_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
-	loc_cat_change_cb_t cb_fun;
-	
 	while (true) {
 		ipc_call_t call;
@@ -69,21 +66,19 @@
 		}
 		
-		int retval;
-		
 		switch (IPC_GET_IMETHOD(call)) {
 		case LOC_EVENT_CAT_CHANGE:
 			fibril_mutex_lock(&loc_callback_mutex);
-			cb_fun = cat_change_cb;
-			if (cb_fun != NULL) {
+			loc_cat_change_cb_t cb_fun = cat_change_cb;
+			fibril_mutex_unlock(&loc_callback_mutex);
+			
+			async_answer_0(callid, EOK);
+			
+			if (cb_fun != NULL)
 				(*cb_fun)();
-			}
-			fibril_mutex_unlock(&loc_callback_mutex);
-			retval = 0;
+			
 			break;
 		default:
-			retval = ENOTSUP;
+			async_answer_0(callid, ENOTSUP);
 		}
-		
-		async_answer_0(callid, retval);
 	}
 }
@@ -101,36 +96,34 @@
 }
 
+/** Create callback
+ *
+ * Must be called with loc_callback_mutex locked.
+ *
+ * @return EOK on success.
+ *
+ */
 static int loc_callback_create(void)
 {
-	async_exch_t *exch;
-	sysarg_t retval;
-	int rc = EOK;
-
-	fibril_mutex_lock(&loc_callback_mutex);
-	
 	if (!loc_callback_created) {
-		exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
+		async_exch_t *exch =
+		    loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
 		
 		ipc_call_t answer;
 		aid_t req = async_send_0(exch, LOC_CALLBACK_CREATE, &answer);
-		async_connect_to_me(exch, 0, 0, 0, loc_cb_conn, NULL);
+		int rc = async_connect_to_me(exch, 0, 0, 0, loc_cb_conn, NULL);
 		loc_exchange_end(exch);
 		
+		if (rc != EOK)
+			return rc;
+		
+		sysarg_t retval;
 		async_wait_for(req, &retval);
-		if (rc != EOK)
-			goto done;
-		
-		if (retval != EOK) {
-			rc = retval;
-			goto done;
-		}
+		if (retval != EOK)
+			return retval;
 		
 		loc_callback_created = true;
 	}
 	
-	rc = EOK;
-done:
-	fibril_mutex_unlock(&loc_callback_mutex);
-	return rc;
+	return EOK;
 }
 
@@ -795,22 +788,18 @@
     sysarg_t **data, size_t *count)
 {
-	service_id_t *ids;
-	size_t act_size;
-	size_t alloc_size;
-	int rc;
-
 	*data = NULL;
-	act_size = 0;	/* silence warning */
-
-	rc = loc_category_get_ids_once(method, arg1, NULL, 0,
+	*count = 0;
+	
+	size_t act_size = 0;
+	int rc = loc_category_get_ids_once(method, arg1, NULL, 0,
 	    &act_size);
 	if (rc != EOK)
 		return rc;
-
-	alloc_size = act_size;
-	ids = malloc(alloc_size);
+	
+	size_t alloc_size = act_size;
+	service_id_t *ids = malloc(alloc_size);
 	if (ids == NULL)
 		return ENOMEM;
-
+	
 	while (true) {
 		rc = loc_category_get_ids_once(method, arg1, ids, alloc_size,
@@ -818,16 +807,14 @@
 		if (rc != EOK)
 			return rc;
-
+		
 		if (act_size <= alloc_size)
 			break;
-
-		alloc_size *= 2;
-		free(ids);
-
-		ids = malloc(alloc_size);
+		
+		alloc_size = act_size;
+		ids = realloc(ids, alloc_size);
 		if (ids == NULL)
 			return ENOMEM;
 	}
-
+	
 	*count = act_size / sizeof(category_id_t);
 	*data = ids;
@@ -867,8 +854,13 @@
 int loc_register_cat_change_cb(loc_cat_change_cb_t cb_fun)
 {
-	if (loc_callback_create() != EOK)
+	fibril_mutex_lock(&loc_callback_mutex);
+	if (loc_callback_create() != EOK) {
+		fibril_mutex_unlock(&loc_callback_mutex);
 		return EIO;
-
+	}
+	
 	cat_change_cb = cb_fun;
+	fibril_mutex_unlock(&loc_callback_mutex);
+	
 	return EOK;
 }
Index: uspace/lib/c/include/device/nic.h
===================================================================
--- uspace/lib/c/include/device/nic.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/c/include/device/nic.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -37,11 +37,10 @@
 
 #include <async.h>
-#include <net/device.h>
-#include <net/packet.h>
-#include <ipc/services.h>
+#include <nic/nic.h>
+#include <ipc/common.h>
 
 typedef enum {
 	NIC_SEND_MESSAGE = 0,
-	NIC_CONNECT_TO_NIL,
+	NIC_CALLBACK_CREATE,
 	NIC_GET_STATE,
 	NIC_SET_STATE,
@@ -85,6 +84,12 @@
 } nic_funcs_t;
 
+typedef enum {
+	NIC_EV_ADDR_CHANGED = IPC_FIRST_USER_METHOD,
+	NIC_EV_RECEIVED,
+	NIC_EV_DEVICE_STATE
+} nic_event_t;
+
 extern int nic_send_frame(async_sess_t *, void *, size_t);
-extern int nic_connect_to_nil(async_sess_t *, services_t, nic_device_id_t);
+extern int nic_callback_create(async_sess_t *, async_client_conn_t, void *);
 extern int nic_get_state(async_sess_t *, nic_device_state_t *);
 extern int nic_set_state(async_sess_t *, nic_device_state_t);
Index: uspace/lib/c/include/ipc/devman.h
===================================================================
--- uspace/lib/c/include/ipc/devman.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/c/include/ipc/devman.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -146,5 +146,4 @@
 typedef enum {
 	DRIVER_DEV_ADD = IPC_FIRST_USER_METHOD,
-	DRIVER_DEV_ADDED,
 	DRIVER_DEV_REMOVE,
 	DRIVER_DEV_GONE,
Index: uspace/lib/c/include/ipc/net.h
===================================================================
--- uspace/lib/c/include/ipc/net.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/c/include/ipc/net.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -305,5 +305,5 @@
  *
  */
-#define IPC_GET_DEVICE_HANDLE(call)  ((devman_handle_t) IPC_GET_ARG2(call))
+#define IPC_GET_DEVICE_HANDLE(call)  ((service_id_t) IPC_GET_ARG2(call))
 
 /** Return the device driver service message argument.
Index: uspace/lib/c/include/ipc/net_net.h
===================================================================
--- uspace/lib/c/include/ipc/net_net.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/c/include/ipc/net_net.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -54,7 +54,5 @@
 	NET_NET_GET_DEVICES_COUNT,
 	/** Return names and device IDs of all devices */
-	NET_NET_GET_DEVICES,
-	/** Notify the networking service about a ready device */
-	NET_NET_DRIVER_READY
+	NET_NET_GET_DEVICES
 } net_messages;
 
Index: uspace/lib/c/include/ipc/nil.h
===================================================================
--- uspace/lib/c/include/ipc/nil.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/c/include/ipc/nil.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -46,12 +46,4 @@
 	 */
 	NET_NIL_DEVICE = NET_NIL_FIRST,
-	/** New device state message.
-	 * @see nil_device_state_msg()
-	 */
-	NET_NIL_DEVICE_STATE,
-	/** Received packet queue message.
-	 * @see nil_received_msg()
-	 */
-	NET_NIL_RECEIVED,
 	/** Send packet queue message.
 	 * @see nil_send_msg()
@@ -69,9 +61,5 @@
 	 * @see nil_get_broadcast_addr()
 	 */
-	NET_NIL_BROADCAST_ADDR,
-	/** Device has changed address
-	 * @see nil_addr_changed_msg()
-	 */
-	NET_NIL_ADDR_CHANGED
+	NET_NIL_BROADCAST_ADDR
 } nil_messages;
 
Index: uspace/lib/c/include/net/device.h
===================================================================
--- uspace/lib/c/include/net/device.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/c/include/net/device.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -1,5 +1,4 @@
 /*
  * Copyright (c) 2009 Lukas Mejdrech
- * Copyright (c) 2011 Radim Vansa
  * All rights reserved.
  *
@@ -33,31 +32,12 @@
 
 /** @file
- * Device identifier, state and usage statistics.
+ * Network device.
  */
 
-#ifndef LIBC_DEVICE_ID_TYPE_H_
-#define LIBC_DEVICE_ID_TYPE_H_
+#ifndef LIBC_NET_DEVICE_H_
+#define LIBC_NET_DEVICE_H_
 
 #include <adt/int_map.h>
-#include <net/eth_phys.h>
-#include <bool.h>
-
-/** Ethernet address length. */
-#define ETH_ADDR  6
-
-/** MAC printing format */
-#define PRIMAC  "%02x:%02x:%02x:%02x:%02x:%02x"
-
-/** MAC arguments */
-#define ARGSMAC(__a) \
-	(__a)[0], (__a)[1], (__a)[2], (__a)[3], (__a)[4], (__a)[5]
-
-/* Compare MAC address with specific value */
-#define MAC_EQUALS_VALUE(__a, __a0, __a1, __a2, __a3, __a4, __a5) \
-	((__a)[0] == (__a0) && (__a)[1] == (__a1) && (__a)[2] == (__a2) \
-	&& (__a)[3] == (__a3) && (__a)[4] == (__a4) && (__a)[5] == (__a5))
-
-#define MAC_IS_ZERO(__x) \
-	MAC_EQUALS_VALUE(__x, 0, 0, 0, 0, 0, 0)
+#include <nic/nic.h>
 
 /** Device identifier to generic type map declaration. */
@@ -67,419 +47,9 @@
 #define DEVICE_MAP_IMPLEMENT  INT_MAP_IMPLEMENT
 
-/** Max length of any hw nic address (currently only eth) */
-#define NIC_MAX_ADDRESS_LENGTH  16
+/** Device identifier type. */
+typedef int nic_device_id_t;
 
 /** Invalid device identifier. */
 #define NIC_DEVICE_INVALID_ID  (-1)
-
-#define NIC_VENDOR_MAX_LENGTH         64
-#define NIC_MODEL_MAX_LENGTH          64
-#define NIC_PART_NUMBER_MAX_LENGTH    64
-#define NIC_SERIAL_NUMBER_MAX_LENGTH  64
-
-#define NIC_DEFECTIVE_LONG               0x0001
-#define NIC_DEFECTIVE_SHORT              0x0002
-#define NIC_DEFECTIVE_BAD_CRC            0x0010
-#define NIC_DEFECTIVE_BAD_IPV4_CHECKSUM  0x0020
-#define NIC_DEFECTIVE_BAD_IPV6_CHECKSUM  0x0040
-#define NIC_DEFECTIVE_BAD_TCP_CHECKSUM   0x0080
-#define NIC_DEFECTIVE_BAD_UDP_CHECKSUM   0x0100
-
-/**
- * The bitmap uses single bit for each of the 2^12 = 4096 possible VLAN tags.
- * This means its size is 4096/8 = 512 bytes.
- */
-#define NIC_VLAN_BITMAP_SIZE  512
-
-#define NIC_DEVICE_PRINT_FMT  "%x"
-
-/** Device identifier type. */
-typedef int nic_device_id_t;
-
-/**
- * Structure covering the MAC address.
- */
-typedef struct nic_address {
-	uint8_t address[ETH_ADDR];
-} nic_address_t;
-
-/** Device state. */
-typedef enum nic_device_state {
-	/**
-	 * Device present and stopped. Moving device to this state means to discard
-	 * all settings and WOL virtues, rebooting the NIC to state as if the
-	 * computer just booted (or the NIC was just inserted in case of removable
-	 * NIC).
-	 */
-	NIC_STATE_STOPPED,
-	/**
-	 * If the NIC is in this state no packets (frames) are transmitted nor
-	 * received. However, the settings are not restarted. You can use this state
-	 * to temporarily disable transmition/reception or atomically (with respect
-	 * to incoming/outcoming packets) change frames acceptance etc.
-	 */
-	NIC_STATE_DOWN,
-	/** Device is normally operating. */
-	NIC_STATE_ACTIVE,
-	/** Just a constant to limit the state numbers */
-	NIC_STATE_MAX,
-} nic_device_state_t;
-
-/**
- * Channel operating mode used on the medium.
- */
-typedef enum {
-	NIC_CM_UNKNOWN,
-	NIC_CM_FULL_DUPLEX,
-	NIC_CM_HALF_DUPLEX,
-	NIC_CM_SIMPLEX
-} nic_channel_mode_t;
-
-/**
- * Role for the device (used e.g. for 1000Gb ethernet)
- */
-typedef enum {
-	NIC_ROLE_UNKNOWN,
-	NIC_ROLE_AUTO,
-	NIC_ROLE_MASTER,
-	NIC_ROLE_SLAVE
-} nic_role_t;
-
-/**
- * Current state of the cable in the device
- */
-typedef enum {
-	NIC_CS_UNKNOWN,
-	NIC_CS_PLUGGED,
-	NIC_CS_UNPLUGGED
-} nic_cable_state_t;
-
-/**
- * Result of the requested operation
- */
-typedef enum {
-	/** Successfully disabled */
-	NIC_RESULT_DISABLED,
-	/** Successfully enabled */
-	NIC_RESULT_ENABLED,
-	/** Not supported at all */
-	NIC_RESULT_NOT_SUPPORTED,
-	/** Temporarily not available */
-	NIC_RESULT_NOT_AVAILABLE,
-	/** Result extensions */
-	NIC_RESULT_FIRST_EXTENSION
-} nic_result_t;
-
-/** Device usage statistics. */
-typedef struct nic_device_stats {
-	/** Total packets received (accepted). */
-	unsigned long receive_packets;
-	/** Total packets transmitted. */
-	unsigned long send_packets;
-	/** Total bytes received (accepted). */
-	unsigned long receive_bytes;
-	/** Total bytes transmitted. */
-	unsigned long send_bytes;
-	/** Bad packets received counter. */
-	unsigned long receive_errors;
-	/** Packet transmition problems counter. */
-	unsigned long send_errors;
-	/** Number of frames dropped due to insufficient space in RX buffers */
-	unsigned long receive_dropped;
-	/** Number of frames dropped due to insufficient space in TX buffers */
-	unsigned long send_dropped;
-	/** Total multicast packets received (accepted). */
-	unsigned long receive_multicast;
-	/** Total broadcast packets received (accepted). */
-	unsigned long receive_broadcast;
-	/** The number of collisions due to congestion on the medium. */
-	unsigned long collisions;
-	/** Unicast packets received but not accepted (filtered) */
-	unsigned long receive_filtered_unicast;
-	/** Multicast packets received but not accepted (filtered) */
-	unsigned long receive_filtered_multicast;
-	/** Broadcast packets received but not accepted (filtered) */
-	unsigned long receive_filtered_broadcast;
-
-	/* detailed receive_errors */
-
-	/** Received packet length error counter. */
-	unsigned long receive_length_errors;
-	/** Receiver buffer overflow counter. */
-	unsigned long receive_over_errors;
-	/** Received packet with crc error counter. */
-	unsigned long receive_crc_errors;
-	/** Received frame alignment error counter. */
-	unsigned long receive_frame_errors;
-	/** Receiver fifo overrun counter. */
-	unsigned long receive_fifo_errors;
-	/** Receiver missed packet counter. */
-	unsigned long receive_missed_errors;
-
-	/* detailed send_errors */
-
-	/** Transmitter aborted counter. */
-	unsigned long send_aborted_errors;
-	/** Transmitter carrier errors counter. */
-	unsigned long send_carrier_errors;
-	/** Transmitter fifo overrun counter. */
-	unsigned long send_fifo_errors;
-	/** Transmitter carrier errors counter. */
-	unsigned long send_heartbeat_errors;
-	/** Transmitter window errors counter. */
-	unsigned long send_window_errors;
-
-	/* for cslip etc */
-	
-	/** Total compressed packets received. */
-	unsigned long receive_compressed;
-	/** Total compressed packet transmitted. */
-	unsigned long send_compressed;
-} nic_device_stats_t;
-
-/** Errors corresponding to those in the nic_device_stats_t */
-typedef enum {
-	NIC_SEC_BUFFER_FULL,
-	NIC_SEC_ABORTED,
-	NIC_SEC_CARRIER_LOST,
-	NIC_SEC_FIFO_OVERRUN,
-	NIC_SEC_HEARTBEAT,
-	NIC_SEC_WINDOW_ERROR,
-	/* Error encountered during TX but with other type of error */
-	NIC_SEC_OTHER
-} nic_send_error_cause_t;
-
-/** Errors corresponding to those in the nic_device_stats_t */
-typedef enum {
-	NIC_REC_BUFFER_FULL,
-	NIC_REC_LENGTH,
-	NIC_REC_BUFFER_OVERFLOW,
-	NIC_REC_CRC,
-	NIC_REC_FRAME_ALIGNMENT,
-	NIC_REC_FIFO_OVERRUN,
-	NIC_REC_MISSED,
-	/* Error encountered during RX but with other type of error */
-	NIC_REC_OTHER
-} nic_receive_error_cause_t;
-
-/**
- * Information about the NIC that never changes - name, vendor, model,
- * capabilites and so on.
- */
-typedef struct nic_device_info {
-	/* Device identification */
-	char vendor_name[NIC_VENDOR_MAX_LENGTH];
-	char model_name[NIC_MODEL_MAX_LENGTH];
-	char part_number[NIC_PART_NUMBER_MAX_LENGTH];
-	char serial_number[NIC_SERIAL_NUMBER_MAX_LENGTH];
-	uint16_t vendor_id;
-	uint16_t device_id;
-	uint16_t subsystem_vendor_id;
-	uint16_t subsystem_id;
-	/* Device capabilities */
-	uint16_t ethernet_support[ETH_PHYS_LAYERS];
-
-	/** The mask of all modes which the device can advertise
-	 *
-	 *  see ETH_AUTONEG_ macros in net/eth_phys.h of libc
-	 */
-	uint32_t autoneg_support;
-} nic_device_info_t;
-
-/**
- * Type of the ethernet frame
- */
-typedef enum nic_frame_type {
-	NIC_FRAME_UNICAST,
-	NIC_FRAME_MULTICAST,
-	NIC_FRAME_BROADCAST
-} nic_frame_type_t;
-
-/**
- * Specifies which unicast frames is the NIC receiving.
- */
-typedef enum nic_unicast_mode {
-	NIC_UNICAST_UNKNOWN,
-	/** No unicast frames are received */
-	NIC_UNICAST_BLOCKED,
-	/** Only the frames with this NIC's MAC as destination are received */
-	NIC_UNICAST_DEFAULT,
-	/**
-	 * Both frames with this NIC's MAC and those specified in the list are
-	 * received
-	 */
-	NIC_UNICAST_LIST,
-	/** All unicast frames are received */
-	NIC_UNICAST_PROMISC
-} nic_unicast_mode_t;
-
-typedef enum nic_multicast_mode {
-	NIC_MULTICAST_UNKNOWN,
-	/** No multicast frames are received */
-	NIC_MULTICAST_BLOCKED,
-	/** Frames with multicast addresses specified in this list are received */
-	NIC_MULTICAST_LIST,
-	/** All multicast frames are received */
-	NIC_MULTICAST_PROMISC
-} nic_multicast_mode_t;
-
-typedef enum nic_broadcast_mode {
-	NIC_BROADCAST_UNKNOWN,
-	/** Broadcast frames are dropped */
-	NIC_BROADCAST_BLOCKED,
-	/** Broadcast frames are received */
-	NIC_BROADCAST_ACCEPTED
-} nic_broadcast_mode_t;
-
-/**
- * Structure covering the bitmap with VLAN tags.
- */
-typedef struct nic_vlan_mask {
-	uint8_t bitmap[NIC_VLAN_BITMAP_SIZE];
-} nic_vlan_mask_t;
-
-/* WOL virtue identifier */
-typedef unsigned int nic_wv_id_t;
-
-/**
- * Structure passed as argument for virtue NIC_WV_MAGIC_PACKET.
- */
-typedef struct nic_wv_magic_packet_data {
-	uint8_t password[6];
-} nic_wv_magic_packet_data_t;
-
-/**
- * Structure passed as argument for virtue NIC_WV_DIRECTED_IPV4
- */
-typedef struct nic_wv_ipv4_data {
-	uint8_t address[4];
-} nic_wv_ipv4_data_t;
-
-/**
- * Structure passed as argument for virtue NIC_WV_DIRECTED_IPV6
- */
-typedef struct nic_wv_ipv6_data {
-	uint8_t address[16];
-} nic_wv_ipv6_data_t;
-
-/**
- * WOL virtue types defining the interpretation of data passed to the virtue.
- * Those tagged with S can have only single virtue active at one moment, those
- * tagged with M can have multiple ones.
- */
-typedef enum nic_wv_type {
-	/**
-	 * Used for deletion of the virtue - in this case the mask, data and length
-	 * arguments are ignored.
-	 */
-	NIC_WV_NONE,
-	/** S
-	 * Enabled <=> wakeup upon link change
-	 */
-	NIC_WV_LINK_CHANGE,
-	/** S
-	 * If this virtue is set up, wakeup can be issued by a magic packet frame.
-	 * If the data argument is not NULL, it must contain
-	 * nic_wv_magic_packet_data structure with the SecureOn password.
-	 */
-	NIC_WV_MAGIC_PACKET,
-	/** M
-	 * If the virtue is set up, wakeup can be issued by a frame targeted to
-	 * device with MAC address specified in data. The data must contain
-	 * nic_address_t structure.
-	 */
-	NIC_WV_DESTINATION,
-	/** S
-	 * Enabled <=> wakeup upon receiving broadcast frame
-	 */
-	NIC_WV_BROADCAST,
-	/** S
-	 * Enabled <=> wakeup upon receiving ARP Request
-	 */
-	NIC_WV_ARP_REQUEST,
-	/** M
-	 * If enabled, the wakeup is issued upon receiving frame with an IPv4 packet
-	 * with IPv4 address specified in data. The data must contain
-	 * nic_wv_ipv4_data structure.
-	 */
-	NIC_WV_DIRECTED_IPV4,
-	/** M
-	 * If enabled, the wakeup is issued upon receiving frame with an IPv4 packet
-	 * with IPv6 address specified in data. The data must contain
-	 * nic_wv_ipv6_data structure.
-	 */
-	NIC_WV_DIRECTED_IPV6,
-	/** M
-	 * First length/2 bytes in the argument are interpreted as mask, second
-	 * length/2 bytes are interpreted as content.
-	 * If enabled, the wakeup is issued upon receiving frame where the bytes
-	 * with non-zero value in the mask equal to those in the content.
-	 */
-	NIC_WV_FULL_MATCH,
-	/**
-	 * Dummy value, do not use.
-	 */
-	NIC_WV_MAX
-} nic_wv_type_t;
-
-/**
- * Specifies the interrupt/polling mode used by the driver and NIC
- */
-typedef enum nic_poll_mode {
-	/**
-	 * NIC issues interrupts upon events.
-	 */
-	NIC_POLL_IMMEDIATE,
-	/**
-	 * Some uspace app calls nic_poll_now(...) in order to check the NIC state
-	 * - no interrupts are received from the NIC.
-	 */
-	NIC_POLL_ON_DEMAND,
-	/**
-	 * The driver itself issues a poll request in a periodic manner. It is
-	 * allowed to use hardware timer if the NIC supports it.
-	 */
-	NIC_POLL_PERIODIC,
-	/**
-	 * The driver itself issued a poll request in a periodic manner. The driver
-	 * must create software timer, internal hardware timer of NIC must not be
-	 * used even if the NIC supports it.
-	 */
-	NIC_POLL_SOFTWARE_PERIODIC
-} nic_poll_mode_t;
-
-/**
- * Says if this virtue type is a multi-virtue (there can be multiple virtues of
- * this type at once).
- *
- * @param type
- *
- * @return true or false
- */
-static inline int nic_wv_is_multi(nic_wv_type_t type) {
-	switch (type) {
-	case NIC_WV_FULL_MATCH:
-	case NIC_WV_DESTINATION:
-	case NIC_WV_DIRECTED_IPV4:
-	case NIC_WV_DIRECTED_IPV6:
-		return true;
-	default:
-		return false;
-	}
-}
-
-static inline const char *nic_device_state_to_string(nic_device_state_t state)
-{
-	switch (state) {
-	case NIC_STATE_STOPPED:
-		return "stopped";
-	case NIC_STATE_DOWN:
-		return "down";
-	case NIC_STATE_ACTIVE:
-		return "active";
-	default:
-		return "undefined";
-	}
-}
 
 #endif
Index: uspace/lib/c/include/net/eth_phys.h
===================================================================
--- uspace/lib/c/include/net/eth_phys.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ 	(revision )
@@ -1,142 +1,0 @@
-/*
- * Copyright (c) 2011 Radim Vansa
- * Copyright (c) 2011 Jiri Michalec
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBC_NET_ETH_PHYS_H_
-#define LIBC_NET_ETH_PHYS_H_
-
-#include <sys/types.h>
-
-/*****************************************************/
-/* Definitions of possible supported physical layers */
-/*****************************************************/
-
-/* Ethernet physical layers */
-#define ETH_OLD          0
-#define ETH_10M          1
-#define ETH_100M         2
-#define ETH_1000M        3
-#define ETH_10G          4
-#define ETH_40G_100G     5
-/* 6, 7 reserved for future use */
-#define ETH_PHYS_LAYERS  8
-
-/* < 10Mbs ethernets */
-#define ETH_EXPERIMENTAL     0x0001
-#define ETH_1BASE5           0x0002
-/* 10Mbs ethernets */
-#define ETH_10BASE5          0x0001
-#define ETH_10BASE2          0x0002
-#define ETH_10BROAD36        0x0004
-#define ETH_STARLAN_10       0x0008
-#define ETH_LATTISNET        0x0010
-#define ETH_10BASE_T         0x0020
-#define ETH_FOIRL            0x0040
-#define ETH_10BASE_FL        0x0080
-#define ETH_10BASE_FB        0x0100
-#define ETH_10BASE_FP        0x0200
-/* 100Mbs (fast) ethernets */
-#define ETH_100BASE_TX       0x0001
-#define ETH_100BASE_T4       0x0002
-#define ETH_100BASE_T2       0x0004
-#define ETH_100BASE_FX       0x0008
-#define ETH_100BASE_SX       0x0010
-#define ETH_100BASE_BX10     0x0020
-#define ETH_100BASE_LX10     0x0040
-#define ETH_100BASE_VG       0x0080
-/* 1000Mbs (gigabit) ethernets */
-#define ETH_1000BASE_T       0x0001
-#define ETH_1000BASE_TX      0x0002
-#define ETH_1000BASE_SX      0x0004
-#define ETH_1000BASE_LX      0x0008
-#define ETH_1000BASE_LH      0x0010
-#define ETH_1000BASE_CX      0x0020
-#define ETH_1000BASE_BX10    0x0040
-#define ETH_1000BASE_LX10    0x0080
-#define ETH_1000BASE_PX10_D  0x0100
-#define ETH_1000BASE_PX10_U  0x0200
-#define ETH_1000BASE_PX20_D  0x0400
-#define ETH_1000BASE_PX20_U  0x0800
-#define ETH_1000BASE_ZX      0x1000
-#define ETH_1000BASE_KX      0x2000
-/* 10Gbs ethernets */
-#define ETH_10GBASE_SR       0x0001
-#define ETH_10GBASE_LX4      0x0002
-#define ETH_10GBASE_LR       0x0004
-#define ETH_10GBASE_ER       0x0008
-#define ETH_10GBASE_SW       0x0010
-#define ETH_10GBASE_LW       0x0020
-#define ETH_10GBASE_EW       0x0040
-#define ETH_10GBASE_CX4      0x0080
-#define ETH_10GBASE_T        0x0100
-#define ETH_10GBASE_LRM      0x0200
-#define ETH_10GBASE_KX4      0x0400
-#define ETH_10GBASE_KR       0x0800
-/* 40Gbs and 100Gbs ethernets */
-#define ETH_40GBASE_SR4      0x0001
-#define ETH_40GBASE_LR4      0x0002
-#define ETH_40GBASE_CR4      0x0004
-#define ETH_40GBASE_KR4      0x0008
-#define ETH_100GBASE_SR10    0x0010
-#define ETH_100GBASE_LR4     0x0020
-#define ETH_100GBASE_ER4     0x0040
-#define ETH_100GBASE_CR10    0x0080
-
-/******************************************/
-/* Auto-negotiation advertisement options */
-/******************************************/
-
-#define ETH_AUTONEG_10BASE_T_HALF    UINT32_C(0x00000001)
-#define ETH_AUTONEG_10BASE_T_FULL    UINT32_C(0x00000002)
-#define ETH_AUTONEG_100BASE_TX_HALF  UINT32_C(0x00000004)
-#define ETH_AUTONEG_100BASE_T4_HALF  UINT32_C(0x00000008)
-#define ETH_AUTONEG_100BASE_T2_HALF  UINT32_C(0x00000010)
-#define ETH_AUTONEG_100BASE_TX_FULL  UINT32_C(0x00000020)
-#define ETH_AUTONEG_100BASE_T2_FULL  UINT32_C(0x00000040)
-#define ETH_AUTONEG_1000BASE_T_HALF  UINT32_C(0x00000080)
-#define ETH_AUTONEG_1000BASE_T_FULL  UINT32_C(0x00000100)
-
-/** Symetric pause packet (802.3x standard) */
-#define ETH_AUTONEG_PAUSE_SYMETRIC   UINT32_C(0x10000000)
-/** Asymetric pause packet (802.3z standard, gigabit ethernet) */
-#define ETH_AUTONEG_PAUSE_ASYMETRIC  UINT32_C(0x20000000)
-
-#define ETH_AUTONEG_MODE_MASK      UINT32_C(0x0FFFFFFF)
-#define ETH_AUTONEG_FEATURES_MASK  UINT32_C(~(ETH_AUTONEG_MODE_MASK))
-
-#define ETH_AUTONEG_MODES  9
-
-struct eth_autoneg_map {
-	uint32_t value;
-	const char *name;
-};
-
-extern const char *ethernet_names[8][17];
-extern const struct eth_autoneg_map ethernet_autoneg_mapping[ETH_AUTONEG_MODES];
-
-#endif
Index: uspace/lib/c/include/nic/eth_phys.h
===================================================================
--- uspace/lib/c/include/nic/eth_phys.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
+++ uspace/lib/c/include/nic/eth_phys.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2011 Radim Vansa
+ * Copyright (c) 2011 Jiri Michalec
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBC_NIC_ETH_PHYS_H_
+#define LIBC_NIC_ETH_PHYS_H_
+
+#include <sys/types.h>
+
+/*****************************************************/
+/* Definitions of possible supported physical layers */
+/*****************************************************/
+
+/* Ethernet physical layers */
+#define ETH_OLD          0
+#define ETH_10M          1
+#define ETH_100M         2
+#define ETH_1000M        3
+#define ETH_10G          4
+#define ETH_40G_100G     5
+/* 6, 7 reserved for future use */
+#define ETH_PHYS_LAYERS  8
+
+/* < 10Mbs ethernets */
+#define ETH_EXPERIMENTAL     0x0001
+#define ETH_1BASE5           0x0002
+/* 10Mbs ethernets */
+#define ETH_10BASE5          0x0001
+#define ETH_10BASE2          0x0002
+#define ETH_10BROAD36        0x0004
+#define ETH_STARLAN_10       0x0008
+#define ETH_LATTISNET        0x0010
+#define ETH_10BASE_T         0x0020
+#define ETH_FOIRL            0x0040
+#define ETH_10BASE_FL        0x0080
+#define ETH_10BASE_FB        0x0100
+#define ETH_10BASE_FP        0x0200
+/* 100Mbs (fast) ethernets */
+#define ETH_100BASE_TX       0x0001
+#define ETH_100BASE_T4       0x0002
+#define ETH_100BASE_T2       0x0004
+#define ETH_100BASE_FX       0x0008
+#define ETH_100BASE_SX       0x0010
+#define ETH_100BASE_BX10     0x0020
+#define ETH_100BASE_LX10     0x0040
+#define ETH_100BASE_VG       0x0080
+/* 1000Mbs (gigabit) ethernets */
+#define ETH_1000BASE_T       0x0001
+#define ETH_1000BASE_TX      0x0002
+#define ETH_1000BASE_SX      0x0004
+#define ETH_1000BASE_LX      0x0008
+#define ETH_1000BASE_LH      0x0010
+#define ETH_1000BASE_CX      0x0020
+#define ETH_1000BASE_BX10    0x0040
+#define ETH_1000BASE_LX10    0x0080
+#define ETH_1000BASE_PX10_D  0x0100
+#define ETH_1000BASE_PX10_U  0x0200
+#define ETH_1000BASE_PX20_D  0x0400
+#define ETH_1000BASE_PX20_U  0x0800
+#define ETH_1000BASE_ZX      0x1000
+#define ETH_1000BASE_KX      0x2000
+/* 10Gbs ethernets */
+#define ETH_10GBASE_SR       0x0001
+#define ETH_10GBASE_LX4      0x0002
+#define ETH_10GBASE_LR       0x0004
+#define ETH_10GBASE_ER       0x0008
+#define ETH_10GBASE_SW       0x0010
+#define ETH_10GBASE_LW       0x0020
+#define ETH_10GBASE_EW       0x0040
+#define ETH_10GBASE_CX4      0x0080
+#define ETH_10GBASE_T        0x0100
+#define ETH_10GBASE_LRM      0x0200
+#define ETH_10GBASE_KX4      0x0400
+#define ETH_10GBASE_KR       0x0800
+/* 40Gbs and 100Gbs ethernets */
+#define ETH_40GBASE_SR4      0x0001
+#define ETH_40GBASE_LR4      0x0002
+#define ETH_40GBASE_CR4      0x0004
+#define ETH_40GBASE_KR4      0x0008
+#define ETH_100GBASE_SR10    0x0010
+#define ETH_100GBASE_LR4     0x0020
+#define ETH_100GBASE_ER4     0x0040
+#define ETH_100GBASE_CR10    0x0080
+
+/******************************************/
+/* Auto-negotiation advertisement options */
+/******************************************/
+
+#define ETH_AUTONEG_10BASE_T_HALF    UINT32_C(0x00000001)
+#define ETH_AUTONEG_10BASE_T_FULL    UINT32_C(0x00000002)
+#define ETH_AUTONEG_100BASE_TX_HALF  UINT32_C(0x00000004)
+#define ETH_AUTONEG_100BASE_T4_HALF  UINT32_C(0x00000008)
+#define ETH_AUTONEG_100BASE_T2_HALF  UINT32_C(0x00000010)
+#define ETH_AUTONEG_100BASE_TX_FULL  UINT32_C(0x00000020)
+#define ETH_AUTONEG_100BASE_T2_FULL  UINT32_C(0x00000040)
+#define ETH_AUTONEG_1000BASE_T_HALF  UINT32_C(0x00000080)
+#define ETH_AUTONEG_1000BASE_T_FULL  UINT32_C(0x00000100)
+
+/** Symetric pause packet (802.3x standard) */
+#define ETH_AUTONEG_PAUSE_SYMETRIC   UINT32_C(0x10000000)
+/** Asymetric pause packet (802.3z standard, gigabit ethernet) */
+#define ETH_AUTONEG_PAUSE_ASYMETRIC  UINT32_C(0x20000000)
+
+#define ETH_AUTONEG_MODE_MASK      UINT32_C(0x0FFFFFFF)
+#define ETH_AUTONEG_FEATURES_MASK  UINT32_C(~(ETH_AUTONEG_MODE_MASK))
+
+#define ETH_AUTONEG_MODES  9
+
+struct eth_autoneg_map {
+	uint32_t value;
+	const char *name;
+};
+
+extern const char *ethernet_names[8][17];
+extern const struct eth_autoneg_map ethernet_autoneg_mapping[ETH_AUTONEG_MODES];
+
+#endif
Index: uspace/lib/c/include/nic/nic.h
===================================================================
--- uspace/lib/c/include/nic/nic.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
+++ uspace/lib/c/include/nic/nic.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * Copyright (c) 2011 Radim Vansa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+
+/** @file
+ * NIC interface definitions.
+ */
+
+#ifndef LIBC_NIC_H_
+#define LIBC_NIC_H_
+
+#include <nic/eth_phys.h>
+#include <bool.h>
+
+/** Ethernet address length. */
+#define ETH_ADDR  6
+
+/** MAC printing format */
+#define PRIMAC  "%02x:%02x:%02x:%02x:%02x:%02x"
+
+/** MAC arguments */
+#define ARGSMAC(__a) \
+	(__a)[0], (__a)[1], (__a)[2], (__a)[3], (__a)[4], (__a)[5]
+
+/* Compare MAC address with specific value */
+#define MAC_EQUALS_VALUE(__a, __a0, __a1, __a2, __a3, __a4, __a5) \
+	((__a)[0] == (__a0) && (__a)[1] == (__a1) && (__a)[2] == (__a2) \
+	&& (__a)[3] == (__a3) && (__a)[4] == (__a4) && (__a)[5] == (__a5))
+
+#define MAC_IS_ZERO(__x) \
+	MAC_EQUALS_VALUE(__x, 0, 0, 0, 0, 0, 0)
+
+/** Max length of any hw nic address (currently only eth) */
+#define NIC_MAX_ADDRESS_LENGTH  16
+
+#define NIC_VENDOR_MAX_LENGTH         64
+#define NIC_MODEL_MAX_LENGTH          64
+#define NIC_PART_NUMBER_MAX_LENGTH    64
+#define NIC_SERIAL_NUMBER_MAX_LENGTH  64
+
+#define NIC_DEFECTIVE_LONG               0x0001
+#define NIC_DEFECTIVE_SHORT              0x0002
+#define NIC_DEFECTIVE_BAD_CRC            0x0010
+#define NIC_DEFECTIVE_BAD_IPV4_CHECKSUM  0x0020
+#define NIC_DEFECTIVE_BAD_IPV6_CHECKSUM  0x0040
+#define NIC_DEFECTIVE_BAD_TCP_CHECKSUM   0x0080
+#define NIC_DEFECTIVE_BAD_UDP_CHECKSUM   0x0100
+
+/**
+ * The bitmap uses single bit for each of the 2^12 = 4096 possible VLAN tags.
+ * This means its size is 4096/8 = 512 bytes.
+ */
+#define NIC_VLAN_BITMAP_SIZE  512
+
+#define NIC_DEVICE_PRINT_FMT  "%x"
+
+/**
+ * Structure covering the MAC address.
+ */
+typedef struct nic_address {
+	uint8_t address[ETH_ADDR];
+} nic_address_t;
+
+/** Device state. */
+typedef enum nic_device_state {
+	/**
+	 * Device present and stopped. Moving device to this state means to discard
+	 * all settings and WOL virtues, rebooting the NIC to state as if the
+	 * computer just booted (or the NIC was just inserted in case of removable
+	 * NIC).
+	 */
+	NIC_STATE_STOPPED,
+	/**
+	 * If the NIC is in this state no packets (frames) are transmitted nor
+	 * received. However, the settings are not restarted. You can use this state
+	 * to temporarily disable transmition/reception or atomically (with respect
+	 * to incoming/outcoming packets) change frames acceptance etc.
+	 */
+	NIC_STATE_DOWN,
+	/** Device is normally operating. */
+	NIC_STATE_ACTIVE,
+	/** Just a constant to limit the state numbers */
+	NIC_STATE_MAX,
+} nic_device_state_t;
+
+/**
+ * Channel operating mode used on the medium.
+ */
+typedef enum {
+	NIC_CM_UNKNOWN,
+	NIC_CM_FULL_DUPLEX,
+	NIC_CM_HALF_DUPLEX,
+	NIC_CM_SIMPLEX
+} nic_channel_mode_t;
+
+/**
+ * Role for the device (used e.g. for 1000Gb ethernet)
+ */
+typedef enum {
+	NIC_ROLE_UNKNOWN,
+	NIC_ROLE_AUTO,
+	NIC_ROLE_MASTER,
+	NIC_ROLE_SLAVE
+} nic_role_t;
+
+/**
+ * Current state of the cable in the device
+ */
+typedef enum {
+	NIC_CS_UNKNOWN,
+	NIC_CS_PLUGGED,
+	NIC_CS_UNPLUGGED
+} nic_cable_state_t;
+
+/**
+ * Result of the requested operation
+ */
+typedef enum {
+	/** Successfully disabled */
+	NIC_RESULT_DISABLED,
+	/** Successfully enabled */
+	NIC_RESULT_ENABLED,
+	/** Not supported at all */
+	NIC_RESULT_NOT_SUPPORTED,
+	/** Temporarily not available */
+	NIC_RESULT_NOT_AVAILABLE,
+	/** Result extensions */
+	NIC_RESULT_FIRST_EXTENSION
+} nic_result_t;
+
+/** Device usage statistics. */
+typedef struct nic_device_stats {
+	/** Total packets received (accepted). */
+	unsigned long receive_packets;
+	/** Total packets transmitted. */
+	unsigned long send_packets;
+	/** Total bytes received (accepted). */
+	unsigned long receive_bytes;
+	/** Total bytes transmitted. */
+	unsigned long send_bytes;
+	/** Bad packets received counter. */
+	unsigned long receive_errors;
+	/** Packet transmition problems counter. */
+	unsigned long send_errors;
+	/** Number of frames dropped due to insufficient space in RX buffers */
+	unsigned long receive_dropped;
+	/** Number of frames dropped due to insufficient space in TX buffers */
+	unsigned long send_dropped;
+	/** Total multicast packets received (accepted). */
+	unsigned long receive_multicast;
+	/** Total broadcast packets received (accepted). */
+	unsigned long receive_broadcast;
+	/** The number of collisions due to congestion on the medium. */
+	unsigned long collisions;
+	/** Unicast packets received but not accepted (filtered) */
+	unsigned long receive_filtered_unicast;
+	/** Multicast packets received but not accepted (filtered) */
+	unsigned long receive_filtered_multicast;
+	/** Broadcast packets received but not accepted (filtered) */
+	unsigned long receive_filtered_broadcast;
+
+	/* detailed receive_errors */
+
+	/** Received packet length error counter. */
+	unsigned long receive_length_errors;
+	/** Receiver buffer overflow counter. */
+	unsigned long receive_over_errors;
+	/** Received packet with crc error counter. */
+	unsigned long receive_crc_errors;
+	/** Received frame alignment error counter. */
+	unsigned long receive_frame_errors;
+	/** Receiver fifo overrun counter. */
+	unsigned long receive_fifo_errors;
+	/** Receiver missed packet counter. */
+	unsigned long receive_missed_errors;
+
+	/* detailed send_errors */
+
+	/** Transmitter aborted counter. */
+	unsigned long send_aborted_errors;
+	/** Transmitter carrier errors counter. */
+	unsigned long send_carrier_errors;
+	/** Transmitter fifo overrun counter. */
+	unsigned long send_fifo_errors;
+	/** Transmitter carrier errors counter. */
+	unsigned long send_heartbeat_errors;
+	/** Transmitter window errors counter. */
+	unsigned long send_window_errors;
+
+	/* for cslip etc */
+	
+	/** Total compressed packets received. */
+	unsigned long receive_compressed;
+	/** Total compressed packet transmitted. */
+	unsigned long send_compressed;
+} nic_device_stats_t;
+
+/** Errors corresponding to those in the nic_device_stats_t */
+typedef enum {
+	NIC_SEC_BUFFER_FULL,
+	NIC_SEC_ABORTED,
+	NIC_SEC_CARRIER_LOST,
+	NIC_SEC_FIFO_OVERRUN,
+	NIC_SEC_HEARTBEAT,
+	NIC_SEC_WINDOW_ERROR,
+	/* Error encountered during TX but with other type of error */
+	NIC_SEC_OTHER
+} nic_send_error_cause_t;
+
+/** Errors corresponding to those in the nic_device_stats_t */
+typedef enum {
+	NIC_REC_BUFFER_FULL,
+	NIC_REC_LENGTH,
+	NIC_REC_BUFFER_OVERFLOW,
+	NIC_REC_CRC,
+	NIC_REC_FRAME_ALIGNMENT,
+	NIC_REC_FIFO_OVERRUN,
+	NIC_REC_MISSED,
+	/* Error encountered during RX but with other type of error */
+	NIC_REC_OTHER
+} nic_receive_error_cause_t;
+
+/**
+ * Information about the NIC that never changes - name, vendor, model,
+ * capabilites and so on.
+ */
+typedef struct nic_device_info {
+	/* Device identification */
+	char vendor_name[NIC_VENDOR_MAX_LENGTH];
+	char model_name[NIC_MODEL_MAX_LENGTH];
+	char part_number[NIC_PART_NUMBER_MAX_LENGTH];
+	char serial_number[NIC_SERIAL_NUMBER_MAX_LENGTH];
+	uint16_t vendor_id;
+	uint16_t device_id;
+	uint16_t subsystem_vendor_id;
+	uint16_t subsystem_id;
+	/* Device capabilities */
+	uint16_t ethernet_support[ETH_PHYS_LAYERS];
+
+	/** The mask of all modes which the device can advertise
+	 *
+	 *  see ETH_AUTONEG_ macros in nic/eth_phys.h of libc
+	 */
+	uint32_t autoneg_support;
+} nic_device_info_t;
+
+/**
+ * Type of the ethernet frame
+ */
+typedef enum nic_frame_type {
+	NIC_FRAME_UNICAST,
+	NIC_FRAME_MULTICAST,
+	NIC_FRAME_BROADCAST
+} nic_frame_type_t;
+
+/**
+ * Specifies which unicast frames is the NIC receiving.
+ */
+typedef enum nic_unicast_mode {
+	NIC_UNICAST_UNKNOWN,
+	/** No unicast frames are received */
+	NIC_UNICAST_BLOCKED,
+	/** Only the frames with this NIC's MAC as destination are received */
+	NIC_UNICAST_DEFAULT,
+	/**
+	 * Both frames with this NIC's MAC and those specified in the list are
+	 * received
+	 */
+	NIC_UNICAST_LIST,
+	/** All unicast frames are received */
+	NIC_UNICAST_PROMISC
+} nic_unicast_mode_t;
+
+typedef enum nic_multicast_mode {
+	NIC_MULTICAST_UNKNOWN,
+	/** No multicast frames are received */
+	NIC_MULTICAST_BLOCKED,
+	/** Frames with multicast addresses specified in this list are received */
+	NIC_MULTICAST_LIST,
+	/** All multicast frames are received */
+	NIC_MULTICAST_PROMISC
+} nic_multicast_mode_t;
+
+typedef enum nic_broadcast_mode {
+	NIC_BROADCAST_UNKNOWN,
+	/** Broadcast frames are dropped */
+	NIC_BROADCAST_BLOCKED,
+	/** Broadcast frames are received */
+	NIC_BROADCAST_ACCEPTED
+} nic_broadcast_mode_t;
+
+/**
+ * Structure covering the bitmap with VLAN tags.
+ */
+typedef struct nic_vlan_mask {
+	uint8_t bitmap[NIC_VLAN_BITMAP_SIZE];
+} nic_vlan_mask_t;
+
+/* WOL virtue identifier */
+typedef unsigned int nic_wv_id_t;
+
+/**
+ * Structure passed as argument for virtue NIC_WV_MAGIC_PACKET.
+ */
+typedef struct nic_wv_magic_packet_data {
+	uint8_t password[6];
+} nic_wv_magic_packet_data_t;
+
+/**
+ * Structure passed as argument for virtue NIC_WV_DIRECTED_IPV4
+ */
+typedef struct nic_wv_ipv4_data {
+	uint8_t address[4];
+} nic_wv_ipv4_data_t;
+
+/**
+ * Structure passed as argument for virtue NIC_WV_DIRECTED_IPV6
+ */
+typedef struct nic_wv_ipv6_data {
+	uint8_t address[16];
+} nic_wv_ipv6_data_t;
+
+/**
+ * WOL virtue types defining the interpretation of data passed to the virtue.
+ * Those tagged with S can have only single virtue active at one moment, those
+ * tagged with M can have multiple ones.
+ */
+typedef enum nic_wv_type {
+	/**
+	 * Used for deletion of the virtue - in this case the mask, data and length
+	 * arguments are ignored.
+	 */
+	NIC_WV_NONE,
+	/** S
+	 * Enabled <=> wakeup upon link change
+	 */
+	NIC_WV_LINK_CHANGE,
+	/** S
+	 * If this virtue is set up, wakeup can be issued by a magic packet frame.
+	 * If the data argument is not NULL, it must contain
+	 * nic_wv_magic_packet_data structure with the SecureOn password.
+	 */
+	NIC_WV_MAGIC_PACKET,
+	/** M
+	 * If the virtue is set up, wakeup can be issued by a frame targeted to
+	 * device with MAC address specified in data. The data must contain
+	 * nic_address_t structure.
+	 */
+	NIC_WV_DESTINATION,
+	/** S
+	 * Enabled <=> wakeup upon receiving broadcast frame
+	 */
+	NIC_WV_BROADCAST,
+	/** S
+	 * Enabled <=> wakeup upon receiving ARP Request
+	 */
+	NIC_WV_ARP_REQUEST,
+	/** M
+	 * If enabled, the wakeup is issued upon receiving frame with an IPv4 packet
+	 * with IPv4 address specified in data. The data must contain
+	 * nic_wv_ipv4_data structure.
+	 */
+	NIC_WV_DIRECTED_IPV4,
+	/** M
+	 * If enabled, the wakeup is issued upon receiving frame with an IPv4 packet
+	 * with IPv6 address specified in data. The data must contain
+	 * nic_wv_ipv6_data structure.
+	 */
+	NIC_WV_DIRECTED_IPV6,
+	/** M
+	 * First length/2 bytes in the argument are interpreted as mask, second
+	 * length/2 bytes are interpreted as content.
+	 * If enabled, the wakeup is issued upon receiving frame where the bytes
+	 * with non-zero value in the mask equal to those in the content.
+	 */
+	NIC_WV_FULL_MATCH,
+	/**
+	 * Dummy value, do not use.
+	 */
+	NIC_WV_MAX
+} nic_wv_type_t;
+
+/**
+ * Specifies the interrupt/polling mode used by the driver and NIC
+ */
+typedef enum nic_poll_mode {
+	/**
+	 * NIC issues interrupts upon events.
+	 */
+	NIC_POLL_IMMEDIATE,
+	/**
+	 * Some uspace app calls nic_poll_now(...) in order to check the NIC state
+	 * - no interrupts are received from the NIC.
+	 */
+	NIC_POLL_ON_DEMAND,
+	/**
+	 * The driver itself issues a poll request in a periodic manner. It is
+	 * allowed to use hardware timer if the NIC supports it.
+	 */
+	NIC_POLL_PERIODIC,
+	/**
+	 * The driver itself issued a poll request in a periodic manner. The driver
+	 * must create software timer, internal hardware timer of NIC must not be
+	 * used even if the NIC supports it.
+	 */
+	NIC_POLL_SOFTWARE_PERIODIC
+} nic_poll_mode_t;
+
+/**
+ * Says if this virtue type is a multi-virtue (there can be multiple virtues of
+ * this type at once).
+ *
+ * @param type
+ *
+ * @return true or false
+ */
+static inline int nic_wv_is_multi(nic_wv_type_t type) {
+	switch (type) {
+	case NIC_WV_FULL_MATCH:
+	case NIC_WV_DESTINATION:
+	case NIC_WV_DIRECTED_IPV4:
+	case NIC_WV_DIRECTED_IPV6:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static inline const char *nic_device_state_to_string(nic_device_state_t state)
+{
+	switch (state) {
+	case NIC_STATE_STOPPED:
+		return "stopped";
+	case NIC_STATE_DOWN:
+		return "down";
+	case NIC_STATE_ACTIVE:
+		return "active";
+	default:
+		return "undefined";
+	}
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/drv/Makefile
===================================================================
--- uspace/lib/drv/Makefile	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/drv/Makefile	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -35,4 +35,5 @@
 	generic/driver.c \
 	generic/dev_iface.c \
+	generic/interrupt.c \
 	generic/log.c \
 	generic/logbuf.c \
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/drv/generic/driver.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -70,20 +70,4 @@
 FIBRIL_MUTEX_INITIALIZE(functions_mutex);
 
-/** Interrupts */
-static interrupt_context_list_t interrupt_contexts;
-
-static irq_cmd_t default_cmds[] = {
-	{
-		.cmd = CMD_ACCEPT
-	}
-};
-
-static irq_code_t default_pseudocode = {
-	0,
-	NULL,
-	sizeof(default_cmds) / sizeof(irq_cmd_t),
-	default_cmds
-};
-
 static ddf_dev_t *create_device(void);
 static void delete_device(ddf_dev_t *);
@@ -95,132 +79,4 @@
 static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t);
 
-static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall)
-{
-	int id = (int)IPC_GET_IMETHOD(*icall);
-	interrupt_context_t *ctx;
-	
-	ctx = find_interrupt_context_by_id(&interrupt_contexts, id);
-	if (ctx != NULL && ctx->handler != NULL)
-		(*ctx->handler)(ctx->dev, iid, icall);
-}
-
-interrupt_context_t *create_interrupt_context(void)
-{
-	interrupt_context_t *ctx;
-	
-	ctx = (interrupt_context_t *) malloc(sizeof(interrupt_context_t));
-	if (ctx != NULL)
-		memset(ctx, 0, sizeof(interrupt_context_t));
-	
-	return ctx;
-}
-
-void delete_interrupt_context(interrupt_context_t *ctx)
-{
-	if (ctx != NULL)
-		free(ctx);
-}
-
-void init_interrupt_context_list(interrupt_context_list_t *list)
-{
-	memset(list, 0, sizeof(interrupt_context_list_t));
-	fibril_mutex_initialize(&list->mutex);
-	list_initialize(&list->contexts);
-}
-
-void
-add_interrupt_context(interrupt_context_list_t *list, interrupt_context_t *ctx)
-{
-	fibril_mutex_lock(&list->mutex);
-	ctx->id = list->curr_id++;
-	list_append(&ctx->link, &list->contexts);
-	fibril_mutex_unlock(&list->mutex);
-}
-
-void remove_interrupt_context(interrupt_context_list_t *list,
-    interrupt_context_t *ctx)
-{
-	fibril_mutex_lock(&list->mutex);
-	list_remove(&ctx->link);
-	fibril_mutex_unlock(&list->mutex);
-}
-
-interrupt_context_t *
-find_interrupt_context_by_id(interrupt_context_list_t *list, int id)
-{
-	interrupt_context_t *ctx;
-	
-	fibril_mutex_lock(&list->mutex);
-	
-	list_foreach(list->contexts, link) {
-		ctx = list_get_instance(link, interrupt_context_t, link);
-		if (ctx->id == id) {
-			fibril_mutex_unlock(&list->mutex);
-			return ctx;
-		}
-	}
-	
-	fibril_mutex_unlock(&list->mutex);
-	return NULL;
-}
-
-interrupt_context_t *
-find_interrupt_context(interrupt_context_list_t *list, ddf_dev_t *dev, int irq)
-{
-	interrupt_context_t *ctx;
-	
-	fibril_mutex_lock(&list->mutex);
-	
-	list_foreach(list->contexts, link) {
-		ctx = list_get_instance(link, interrupt_context_t, link);
-		if (ctx->irq == irq && ctx->dev == dev) {
-			fibril_mutex_unlock(&list->mutex);
-			return ctx;
-		}
-	}
-	
-	fibril_mutex_unlock(&list->mutex);
-	return NULL;
-}
-
-
-int
-register_interrupt_handler(ddf_dev_t *dev, int irq, interrupt_handler_t *handler,
-    irq_code_t *pseudocode)
-{
-	interrupt_context_t *ctx = create_interrupt_context();
-	
-	ctx->dev = dev;
-	ctx->irq = irq;
-	ctx->handler = handler;
-	
-	add_interrupt_context(&interrupt_contexts, ctx);
-	
-	if (pseudocode == NULL)
-		pseudocode = &default_pseudocode;
-	
-	int res = irq_register(irq, dev->handle, ctx->id, pseudocode);
-	if (res != EOK) {
-		remove_interrupt_context(&interrupt_contexts, ctx);
-		delete_interrupt_context(ctx);
-	}
-
-	return res;
-}
-
-int unregister_interrupt_handler(ddf_dev_t *dev, int irq)
-{
-	interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts,
-	    dev, irq);
-	int res = irq_unregister(irq, dev->handle);
-	
-	if (ctx != NULL) {
-		remove_interrupt_context(&interrupt_contexts, ctx);
-		delete_interrupt_context(ctx);
-	}
-	
-	return res;
-}
-
 static void add_to_functions_list(ddf_fun_t *fun)
 {
@@ -303,14 +159,4 @@
 	
 	async_answer_0(iid, res);
-}
-
-static void driver_dev_added(ipc_callid_t iid, ipc_call_t *icall)
-{
-	fibril_mutex_lock(&devices_mutex);
-	ddf_dev_t *dev = driver_get_device(IPC_GET_ARG1(*icall));
-	fibril_mutex_unlock(&devices_mutex);
-	
-	if (dev != NULL && driver->driver_ops->device_added != NULL)
-		driver->driver_ops->device_added(dev);
 }
 
@@ -462,8 +308,4 @@
 		case DRIVER_DEV_ADD:
 			driver_dev_add(callid, &call);
-			break;
-		case DRIVER_DEV_ADDED:
-			async_answer_0(callid, EOK);
-			driver_dev_added(callid, &call);
 			break;
 		case DRIVER_DEV_REMOVE:
@@ -753,5 +595,5 @@
 
 /** Allocate driver-specific device data. */
-extern void *ddf_dev_data_alloc(ddf_dev_t *dev, size_t size)
+void *ddf_dev_data_alloc(ddf_dev_t *dev, size_t size)
 {
 	void *data;
@@ -815,5 +657,5 @@
 
 /** Allocate driver-specific function data. */
-extern void *ddf_fun_data_alloc(ddf_fun_t *fun, size_t size)
+void *ddf_fun_data_alloc(ddf_fun_t *fun, size_t size)
 {
 	void *data;
@@ -1008,9 +850,6 @@
 	driver = drv;
 	
-	/* Initialize the list of interrupt contexts. */
-	init_interrupt_context_list(&interrupt_contexts);
-	
-	/* Set generic interrupt handler. */
-	async_set_interrupt_received(driver_irq_handler);
+	/* Initialize interrupt module */
+	interrupt_init();
 	
 	/*
Index: uspace/lib/drv/generic/interrupt.c
===================================================================
--- uspace/lib/drv/generic/interrupt.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
+++ uspace/lib/drv/generic/interrupt.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @defgroup libdrv generic device driver support.
+ * @brief HelenOS generic device driver support.
+ * @{
+ */
+
+/** @file
+ */
+
+#include <async.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#include "ddf/interrupt.h"
+
+static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall);
+static interrupt_context_t *create_interrupt_context(void);
+static void delete_interrupt_context(interrupt_context_t *ctx);
+static void init_interrupt_context_list(interrupt_context_list_t *list);
+static void add_interrupt_context(interrupt_context_list_t *list,
+    interrupt_context_t *ctx);
+static void remove_interrupt_context(interrupt_context_list_t *list,
+    interrupt_context_t *ctx);
+static interrupt_context_t *find_interrupt_context_by_id(
+    interrupt_context_list_t *list, int id);
+static interrupt_context_t *find_interrupt_context(
+    interrupt_context_list_t *list, ddf_dev_t *dev, int irq);
+int register_interrupt_handler(ddf_dev_t *dev, int irq,
+    interrupt_handler_t *handler, irq_code_t *pseudocode);
+int unregister_interrupt_handler(ddf_dev_t *dev, int irq);
+
+/** Interrupts */
+static interrupt_context_list_t interrupt_contexts;
+
+static irq_cmd_t default_cmds[] = {
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+static irq_code_t default_pseudocode = {
+	0,
+	NULL,
+	sizeof(default_cmds) / sizeof(irq_cmd_t),
+	default_cmds
+};
+
+void interrupt_init(void)
+{
+	/* Initialize the list of interrupt contexts. */
+	init_interrupt_context_list(&interrupt_contexts);
+	
+	/* Set generic interrupt handler. */
+	async_set_interrupt_received(driver_irq_handler);
+}
+
+static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall)
+{
+	int id = (int)IPC_GET_IMETHOD(*icall);
+	interrupt_context_t *ctx;
+	
+	ctx = find_interrupt_context_by_id(&interrupt_contexts, id);
+	if (ctx != NULL && ctx->handler != NULL)
+		(*ctx->handler)(ctx->dev, iid, icall);
+}
+
+static interrupt_context_t *create_interrupt_context(void)
+{
+	interrupt_context_t *ctx;
+	
+	ctx = (interrupt_context_t *) malloc(sizeof(interrupt_context_t));
+	if (ctx != NULL)
+		memset(ctx, 0, sizeof(interrupt_context_t));
+	
+	return ctx;
+}
+
+static void delete_interrupt_context(interrupt_context_t *ctx)
+{
+	if (ctx != NULL)
+		free(ctx);
+}
+
+static void init_interrupt_context_list(interrupt_context_list_t *list)
+{
+	memset(list, 0, sizeof(interrupt_context_list_t));
+	fibril_mutex_initialize(&list->mutex);
+	list_initialize(&list->contexts);
+}
+
+static void
+add_interrupt_context(interrupt_context_list_t *list, interrupt_context_t *ctx)
+{
+	fibril_mutex_lock(&list->mutex);
+	ctx->id = list->curr_id++;
+	list_append(&ctx->link, &list->contexts);
+	fibril_mutex_unlock(&list->mutex);
+}
+
+static void remove_interrupt_context(interrupt_context_list_t *list,
+    interrupt_context_t *ctx)
+{
+	fibril_mutex_lock(&list->mutex);
+	list_remove(&ctx->link);
+	fibril_mutex_unlock(&list->mutex);
+}
+
+static interrupt_context_t *
+find_interrupt_context_by_id(interrupt_context_list_t *list, int id)
+{
+	interrupt_context_t *ctx;
+	
+	fibril_mutex_lock(&list->mutex);
+	
+	list_foreach(list->contexts, link) {
+		ctx = list_get_instance(link, interrupt_context_t, link);
+		if (ctx->id == id) {
+			fibril_mutex_unlock(&list->mutex);
+			return ctx;
+		}
+	}
+	
+	fibril_mutex_unlock(&list->mutex);
+	return NULL;
+}
+
+static interrupt_context_t *
+find_interrupt_context(interrupt_context_list_t *list, ddf_dev_t *dev, int irq)
+{
+	interrupt_context_t *ctx;
+	
+	fibril_mutex_lock(&list->mutex);
+	
+	list_foreach(list->contexts, link) {
+		ctx = list_get_instance(link, interrupt_context_t, link);
+		if (ctx->irq == irq && ctx->dev == dev) {
+			fibril_mutex_unlock(&list->mutex);
+			return ctx;
+		}
+	}
+	
+	fibril_mutex_unlock(&list->mutex);
+	return NULL;
+}
+
+
+int
+register_interrupt_handler(ddf_dev_t *dev, int irq, interrupt_handler_t *handler,
+    irq_code_t *pseudocode)
+{
+	interrupt_context_t *ctx = create_interrupt_context();
+	
+	ctx->dev = dev;
+	ctx->irq = irq;
+	ctx->handler = handler;
+	
+	add_interrupt_context(&interrupt_contexts, ctx);
+	
+	if (pseudocode == NULL)
+		pseudocode = &default_pseudocode;
+	
+	int res = irq_register(irq, dev->handle, ctx->id, pseudocode);
+	if (res != EOK) {
+		remove_interrupt_context(&interrupt_contexts, ctx);
+		delete_interrupt_context(ctx);
+	}
+
+	return res;
+}
+
+int unregister_interrupt_handler(ddf_dev_t *dev, int irq)
+{
+	interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts,
+	    dev, irq);
+	int res = irq_unregister(irq, dev->handle);
+	
+	if (ctx != NULL) {
+		remove_interrupt_context(&interrupt_contexts, ctx);
+		delete_interrupt_context(ctx);
+	}
+	
+	return res;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/remote_nic.c
===================================================================
--- uspace/lib/drv/generic/remote_nic.c	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/drv/generic/remote_nic.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -63,14 +63,11 @@
 }
 
-static void remote_nic_connect_to_nil(ddf_fun_t *dev, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	nic_iface_t *nic_iface = (nic_iface_t *) iface;
-	assert(nic_iface->connect_to_nil);
-	
-	services_t nil_service = (services_t) IPC_GET_ARG2(*call);
-	nic_device_id_t device_id = (nic_device_id_t) IPC_GET_ARG3(*call);
-	
-	int rc = nic_iface->connect_to_nil(dev, nil_service, device_id);
+static void remote_nic_callback_create(ddf_fun_t *dev, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	nic_iface_t *nic_iface = (nic_iface_t *) iface;
+	assert(nic_iface->callback_create);
+	
+	int rc = nic_iface->callback_create(dev);
 	async_answer_0(callid, rc);
 }
@@ -1203,5 +1200,5 @@
 static remote_iface_func_ptr_t remote_nic_iface_ops[] = {
 	&remote_nic_send_frame,
-	&remote_nic_connect_to_nil,
+	&remote_nic_callback_create,
 	&remote_nic_get_state,
 	&remote_nic_set_state,
Index: uspace/lib/drv/include/ddf/driver.h
===================================================================
--- uspace/lib/drv/include/ddf/driver.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/drv/include/ddf/driver.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -145,13 +145,4 @@
 	/** Ask driver to offline a specific function */
 	int (*fun_offline)(ddf_fun_t *);
-
-	/**
-	 * Notification that the device was succesfully added.
-	 * The driver can do any blocking operation without
-	 * blocking the device manager.
-	 *
-	 * XXX REMOVE THIS
-	 */
-	void (*device_added)(ddf_dev_t *dev);
 } driver_ops_t;
 
Index: uspace/lib/drv/include/ddf/interrupt.h
===================================================================
--- uspace/lib/drv/include/ddf/interrupt.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/drv/include/ddf/interrupt.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -64,16 +64,5 @@
 } interrupt_context_list_t;
 
-extern interrupt_context_t *create_interrupt_context(void);
-extern void delete_interrupt_context(interrupt_context_t *);
-extern void init_interrupt_context_list(interrupt_context_list_t *);
-extern void add_interrupt_context(interrupt_context_list_t *,
-    interrupt_context_t *);
-extern void remove_interrupt_context(interrupt_context_list_t *,
-    interrupt_context_t *);
-extern interrupt_context_t *find_interrupt_context_by_id(
-    interrupt_context_list_t *, int);
-extern interrupt_context_t *find_interrupt_context(
-    interrupt_context_list_t *, ddf_dev_t *, int);
-
+extern void interrupt_init(void);
 extern int register_interrupt_handler(ddf_dev_t *, int, interrupt_handler_t *,
     irq_code_t *);
Index: uspace/lib/drv/include/ops/nic.h
===================================================================
--- uspace/lib/drv/include/ops/nic.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/drv/include/ops/nic.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -38,5 +38,5 @@
 
 #include <ipc/services.h>
-#include <net/device.h>
+#include <nic/nic.h>
 #include <sys/time.h>
 
@@ -46,5 +46,5 @@
 	/** Mandatory methods */
 	int (*send_frame)(ddf_fun_t *, void *, size_t);
-	int (*connect_to_nil)(ddf_fun_t *, services_t, nic_device_id_t);
+	int (*callback_create)(ddf_fun_t *);
 	int (*get_state)(ddf_fun_t *, nic_device_state_t *);
 	int (*set_state)(ddf_fun_t *, nic_device_state_t);
Index: uspace/lib/drv/include/usbhc_iface.h
===================================================================
--- uspace/lib/drv/include/usbhc_iface.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/drv/include/usbhc_iface.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -27,8 +27,10 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 /** @addtogroup libdrv
  * @addtogroup usb
  * @{
  */
+
 /** @file
  * @brief USB host controller interface definition.
Index: uspace/lib/net/generic/net_checksum.c
===================================================================
--- uspace/lib/net/generic/net_checksum.c	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/net/generic/net_checksum.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -45,7 +45,4 @@
 #define CRC_DIVIDER_LE  0xedb88320
 
-/** Polynomial used in multicast address hashing */
-#define CRC_MCAST_POLYNOMIAL  0x04c11db6
-
 /** Compacts the computed checksum to the 16 bit number adding the carries.
  *
@@ -224,39 +221,4 @@
 }
 
-/** Compute the standard hash from MAC
- *
- * Hashing MAC into 64 possible values and using the value as index to
- * 64bit number.
- *
- * The code is copied from qemu-0.13's implementation of ne2000 and rt8139
- * drivers, but according to documentation there it originates in FreeBSD.
- *
- * @param[in] addr The 6-byte MAC address to be hashed
- *
- * @return 64-bit number with only single bit set to 1
- *
- */
-uint64_t multicast_hash(const uint8_t addr[6])
-{
-	uint32_t crc;
-    int carry, i, j;
-    uint8_t b;
-
-    crc = 0xffffffff;
-    for (i = 0; i < 6; i++) {
-        b = addr[i];
-        for (j = 0; j < 8; j++) {
-            carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
-            crc <<= 1;
-            b >>= 1;
-            if (carry)
-                crc = ((crc ^ CRC_MCAST_POLYNOMIAL) | carry);
-        }
-    }
-	
-    uint64_t one64 = 1;
-    return one64 << (crc >> 26);
-}
-
 /** @}
  */
Index: uspace/lib/net/generic/net_remote.c
===================================================================
--- uspace/lib/net/generic/net_remote.c	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/net/generic/net_remote.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -167,13 +167,4 @@
 }
 
-int net_driver_ready(async_sess_t *sess, devman_handle_t handle)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	int rc = async_req_1_0(exch, NET_NET_DRIVER_READY, handle);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
 /** @}
  */
Index: uspace/lib/net/include/net_checksum.h
===================================================================
--- uspace/lib/net/include/net_checksum.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/net/include/net_checksum.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -67,5 +67,4 @@
 extern uint16_t flip_checksum(uint16_t);
 extern uint16_t ip_checksum(uint8_t *, size_t);
-extern uint64_t multicast_hash(const uint8_t addr[6]);
 
 #endif
Index: uspace/lib/net/include/net_interface.h
===================================================================
--- uspace/lib/net/include/net_interface.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/net/include/net_interface.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -52,5 +52,4 @@
 extern int net_get_devices_req(async_sess_t *, measured_string_t **, size_t *,
     uint8_t **);
-extern int net_driver_ready(async_sess_t *, devman_handle_t);
 extern async_sess_t *net_connect_module(void);
 
Index: uspace/lib/net/include/nil_remote.h
===================================================================
--- uspace/lib/net/include/nil_remote.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/net/include/nil_remote.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -34,4 +34,5 @@
 #define __NET_NIL_REMOTE_H__
 
+#include <ipc/loc.h>
 #include <net/device.h>
 #include <net/packet.h>
@@ -39,4 +40,5 @@
 #include <generic.h>
 #include <async.h>
+#include <sys/types.h>
 
 #define nil_bind_service(service, device_id, me, receiver) \
@@ -60,8 +62,4 @@
 extern int nil_device_req(async_sess_t *, nic_device_id_t, devman_handle_t,
     size_t);
-extern int nil_device_state_msg(async_sess_t *, nic_device_id_t, sysarg_t);
-extern int nil_received_msg(async_sess_t *, nic_device_id_t, packet_id_t);
-extern int nil_addr_changed_msg(async_sess_t *, nic_device_id_t,
-    const nic_address_t *);
 
 #endif
Index: uspace/lib/net/nil/nil_remote.c
===================================================================
--- uspace/lib/net/nil/nil_remote.c	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/net/nil/nil_remote.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -36,4 +36,5 @@
  */
 
+#include <ipc/loc.h>
 #include <nil_remote.h>
 #include <generic.h>
@@ -43,75 +44,10 @@
 #include <ipc/nil.h>
 
-/** Notify the network interface layer about the device state change.
- *
- * @param[in] sess      Network interface layer session.
- * @param[in] device_id Device identifier.
- * @param[in] state     New device state.
- *
- * @return EOK on success.
- * @return Other error codes as defined for each specific module
- *         device state function.
- *
- */
-int nil_device_state_msg(async_sess_t *sess, nic_device_id_t device_id,
-    sysarg_t state)
-{
-	return generic_device_state_msg_remote(sess, NET_NIL_DEVICE_STATE,
-	    device_id, state, 0);
-}
-
-/** Pass the packet queue to the network interface layer.
- *
- * Process and redistribute the received packet queue to the registered
- * upper layers.
- *
- * @param[in] sess      Network interface layer session.
- * @param[in] device_id Source device identifier.
- * @param[in] packet    Received packet or the received packet queue.
- * @param[in] target    Target service. Ignored parameter.
- *
- * @return EOK on success.
- * @return Other error codes as defined for each specific module
- *         received function.
- *
- */
-int nil_received_msg(async_sess_t *sess, nic_device_id_t device_id,
-    packet_id_t packet_id)
-{
-	return generic_received_msg_remote(sess, NET_NIL_RECEIVED,
-	    device_id, packet_id, 0, 0);
-}
-
-/** Notify upper layers that device address has changed
- *
- */
-int nil_addr_changed_msg(async_sess_t *sess, nic_device_id_t device_id,
-    const nic_address_t *address)
-{
-	assert(sess);
-	
-	async_exch_t *exch = async_exchange_begin(sess);
-	
-	aid_t message_id = async_send_1(exch, NET_NIL_ADDR_CHANGED,
-	    (sysarg_t) device_id, NULL);
-	int rc = async_data_write_start(exch, address, sizeof (nic_address_t));
-	
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-    async_wait_for(message_id, &res);
-	
-    if (rc != EOK)
-		return rc;
-	
-    return (int) res;
-}
-
 int nil_device_req(async_sess_t *sess, nic_device_id_t device_id,
-    devman_handle_t handle, size_t mtu)
+    service_id_t sid, size_t mtu)
 {
 	async_exch_t *exch = async_exchange_begin(sess);
 	int rc = async_req_3_0(exch, NET_NIL_DEVICE, (sysarg_t) device_id,
-	    (sysarg_t) handle, (sysarg_t) mtu);
+	    (sysarg_t) sid, (sysarg_t) mtu);
 	async_exchange_end(exch);
 	return rc;
Index: uspace/lib/nic/Makefile
===================================================================
--- uspace/lib/nic/Makefile	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/nic/Makefile	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -29,9 +29,9 @@
 USPACE_PREFIX = ../..
 LIBRARY = libnic
-LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBNET_PREFIX)/libnet.a
-EXTRA_CFLAGS += -DLIBNIC_INTERNAL -Iinclude -I$(LIBDRV_PREFIX)/include -I$(LIBNET_PREFIX)/include
+EXTRA_CFLAGS += -DLIBNIC_INTERNAL -Iinclude -I$(LIBDRV_PREFIX)/include
 
 SOURCES = \
 	src/nic_driver.c \
+	src/nic_ev.c \
 	src/nic_addr_db.c \
 	src/nic_rx_control.c \
Index: uspace/lib/nic/include/nic.h
===================================================================
--- uspace/lib/nic/include/nic.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/nic/include/nic.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -42,6 +42,7 @@
 #include <ddf/driver.h>
 #include <device/hw_res_parsed.h>
-#include <net/packet.h>
 #include <ops/nic.h>
+
+#define DEVICE_CATEGORY_NIC "nic"
 
 struct nic;
@@ -61,9 +62,10 @@
 
 /**
- * Simple structure for sending the allocated frames (packets) in a list.
+ * Simple structure for sending lists of frames.
  */
 typedef struct {
 	link_t link;
-	packet_t *packet;
+	void *data;
+	size_t size;
 } nic_frame_t;
 
@@ -71,6 +73,6 @@
 
 /**
- * Handler for writing packet data to the NIC device.
- * The function is responsible for releasing the packet.
+ * Handler for writing frame data to the NIC device.
+ * The function is responsible for releasing the frame.
  * It does not return anything, if some error is detected the function just
  * silently fails (logging on debug level is suggested).
@@ -158,5 +160,5 @@
  * @return ENOTSUP	If this filter cannot work on this NIC (e.g. the NIC
  * 					cannot run in promiscuous node or the limit of WOL
- * 					packets' specifications was reached).
+ * 					frames' specifications was reached).
  * @return ELIMIT	If this filter must implemented in HW but currently the
  * 					limit of these HW filters was reached.
@@ -204,5 +206,4 @@
 /* Functions called in add_device */
 extern int nic_connect_to_services(nic_t *);
-extern int nic_register_as_ddf_fun(nic_t *, ddf_dev_ops_t *);
 extern int nic_get_resources(nic_t *, hw_res_list_parsed_t *);
 extern void nic_set_specific(nic_t *, void *);
@@ -219,10 +220,8 @@
 	poll_mode_change_handler, poll_request_handler);
 
-/* Functions called in device_added */
-extern int nic_ready(nic_t *);
-
 /* General driver functions */
 extern ddf_dev_t *nic_get_ddf_dev(nic_t *);
 extern ddf_fun_t *nic_get_ddf_fun(nic_t *);
+extern void nic_set_ddf_fun(nic_t *, ddf_fun_t *);
 extern nic_t *nic_get_from_ddf_dev(ddf_dev_t *);
 extern nic_t *nic_get_from_ddf_fun(ddf_fun_t *);
@@ -233,6 +232,5 @@
 extern int nic_report_poll_mode(nic_t *, nic_poll_mode_t, struct timeval *);
 extern void nic_query_address(nic_t *, nic_address_t *);
-extern void nic_received_packet(nic_t *, packet_t *);
-extern void nic_received_noneth_packet(nic_t *, packet_t *);
+extern void nic_received_noneth_frame(nic_t *, void *, size_t);
 extern void nic_received_frame(nic_t *, nic_frame_t *);
 extern void nic_received_frame_list(nic_t *, nic_frame_list_t *);
@@ -248,7 +246,5 @@
 extern void nic_report_collisions(nic_t *, unsigned);
 
-/* Packet / frame / frame list allocation and deallocation */
-extern packet_t *nic_alloc_packet(nic_t *, size_t);
-extern void nic_release_packet(nic_t *, packet_t *);
+/* Frame / frame list allocation and deallocation */
 extern nic_frame_t *nic_alloc_frame(nic_t *, size_t);
 extern nic_frame_list_t *nic_alloc_frame_list(void);
@@ -275,8 +271,4 @@
 extern void nic_sw_period_stop(nic_t *);
 
-/* Packet DMA lock */
-extern int nic_dma_lock_packet(packet_t *, size_t, void **);
-extern int nic_dma_unlock_packet(packet_t *, size_t);
-
 #endif // __NIC_H__
 
Index: uspace/lib/nic/include/nic_driver.h
===================================================================
--- uspace/lib/nic/include/nic_driver.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/nic/include/nic_driver.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -44,5 +44,5 @@
 
 #include <fibril_synch.h>
-#include <net/device.h>
+#include <nic/nic.h>
 #include <async.h>
 
@@ -50,6 +50,4 @@
 #include "nic_rx_control.h"
 #include "nic_wol_virtues.h"
-
-#define DEVICE_CATEGORY_NIC "nic"
 
 struct sw_poll_info {
@@ -72,6 +70,4 @@
 	 */
 	ddf_fun_t *fun;
-	/** Identifier for higher network stack layers */
-	nic_device_id_t device_id;
 	/** Current state of the device */
 	nic_device_state_t state;
@@ -82,8 +78,6 @@
 	/** Device's default MAC address (assigned the first time, used in STOP) */
 	nic_address_t default_mac;
-	/** Session to SERVICE_NETWORKING */
-	async_sess_t *net_session;
-	/** Session to SERVICE_ETHERNET or SERVICE_NILDUMMY */
-	async_sess_t *nil_session;
+	/** Client callback session */
+	async_sess_t *client_session;
 	/** Phone to APIC or i8259 */
 	async_sess_t *irc_session;
Index: uspace/lib/nic/include/nic_ev.h
===================================================================
--- uspace/lib/nic/include/nic_ev.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
+++ uspace/lib/nic/include/nic_ev.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup libnic
+ * @{
+ */
+/**
+ * @file
+ * @brief Prototypes of default DDF NIC interface methods implementations
+ */
+
+#ifndef NIC_EV_H__
+#define NIC_EV_H__
+
+#include <async.h>
+#include <nic/nic.h>
+#include <sys/types.h>
+
+extern int nic_ev_addr_changed(async_sess_t *, const nic_address_t *);
+extern int nic_ev_device_state(async_sess_t *, sysarg_t);
+extern int nic_ev_received(async_sess_t *, void *, size_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/nic/include/nic_impl.h
===================================================================
--- uspace/lib/nic/include/nic_impl.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/nic/include/nic_impl.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -40,7 +40,6 @@
 
 #include <assert.h>
-#include <net/device.h>
+#include <nic/nic.h>
 #include <ddf/driver.h>
-#include <nil_remote.h>
 
 /* Inclusion of this file is not prohibited, because drivers could want to
@@ -49,6 +48,5 @@
 extern int nic_get_address_impl(ddf_fun_t *dev_fun, nic_address_t *address);
 extern int nic_send_frame_impl(ddf_fun_t *dev_fun, void *data, size_t size);
-extern int nic_connect_to_nil_impl(ddf_fun_t *dev_fun, services_t nil_service,
-	int device_id);
+extern int nic_callback_create_impl(ddf_fun_t *dev_fun);
 extern int nic_get_state_impl(ddf_fun_t *dev_fun, nic_device_state_t *state);
 extern int nic_set_state_impl(ddf_fun_t *dev_fun, nic_device_state_t state);
Index: uspace/lib/nic/include/nic_rx_control.h
===================================================================
--- uspace/lib/nic/include/nic_rx_control.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/nic/include/nic_rx_control.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -45,6 +45,5 @@
 #include <adt/hash_table.h>
 #include <fibril_synch.h>
-#include <net/device.h>
-#include <net/packet_header.h>
+#include <nic/nic.h>
 
 #include "nic_addr_db.h"
@@ -120,5 +119,5 @@
 	const nic_address_t *prev_addr, const nic_address_t *curr_addr);
 extern int nic_rxc_check(const nic_rxc_t *rxc,
-	const packet_t *packet, nic_frame_type_t *frame_type);
+	const void *data, size_t size, nic_frame_type_t *frame_type);
 extern void nic_rxc_hw_filtering(nic_rxc_t *rxc,
 	int unicast_exact, int multicast_exact, int vlan_exact);
Index: uspace/lib/nic/include/nic_wol_virtues.h
===================================================================
--- uspace/lib/nic/include/nic_wol_virtues.h	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/nic/include/nic_wol_virtues.h	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -43,5 +43,5 @@
 #endif
 
-#include <net/device.h>
+#include <nic/nic.h>
 #include <adt/hash_table.h>
 #include "nic.h"
Index: uspace/lib/nic/src/nic_driver.c
===================================================================
--- uspace/lib/nic/src/nic_driver.c	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/nic/src/nic_driver.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -49,12 +49,9 @@
 #include <devman.h>
 #include <ddf/interrupt.h>
-#include <net_interface.h>
 #include <ops/nic.h>
-#include <packet_client.h>
-#include <packet_remote.h>
-#include <net/packet_header.h>
 #include <errno.h>
 
 #include "nic_driver.h"
+#include "nic_ev.h"
 #include "nic_impl.h"
 
@@ -64,5 +61,5 @@
 
 /**
- * Initializes libraries required for NIC framework - logger, packet manager
+ * Initializes libraries required for NIC framework - logger
  *
  * @param name	Name of the device/driver (used in logging)
@@ -79,6 +76,5 @@
 	snprintf(buffer, 256, "drv/" DEVICE_CATEGORY_NIC "/%s", name);
 	
-	/* Initialize packet manager */
-	return pm_init();
+	return EOK;
 }
 
@@ -93,9 +89,4 @@
     nic_iface_t *iface)
 {
-	if (driver_ops) {
-		if (!driver_ops->device_added)
-			driver_ops->device_added = nic_device_added_impl;
-	}
-
 	if (dev_ops) {
 		if (!dev_ops->open)
@@ -116,6 +107,6 @@
 		if (!iface->send_frame)
 			iface->send_frame = nic_send_frame_impl;
-		if (!iface->connect_to_nil)
-			iface->connect_to_nil = nic_connect_to_nil_impl;
+		if (!iface->callback_create)
+			iface->callback_create = nic_callback_create_impl;
 		if (!iface->get_address)
 			iface->get_address = nic_get_address_impl;
@@ -162,5 +153,5 @@
 
 /**
- * Setup write packet handler. This MUST be called in the add_device handler
+ * Setup send frame handler. This MUST be called in the add_device handler
  * if the nic_send_message_impl function is used for sending messages (filled
  * as send_message member of the nic_iface_t structure). The function must not
@@ -270,29 +261,11 @@
 }
 
-/**
- * Just a wrapper over the packet_get_1_remote function
- */
-packet_t *nic_alloc_packet(nic_t *nic_data, size_t data_size)
-{
-	return packet_get_1_remote(nic_data->net_session, data_size);
-}
-
-
-/**
- * Just a wrapper over the pq_release_remote function
- */
-void nic_release_packet(nic_t *nic_data, packet_t *packet)
-{
-	pq_release_remote(nic_data->net_session, packet_get_id(packet));
-}
-
-/** Allocate frame and packet
+/** Allocate frame
  *
  *  @param nic_data 	The NIC driver data
- *  @param packet_size	Size of packet
- *  @param offload_size	Size of packet offload
+ *  @param size	        Frame size in bytes
  *  @return pointer to allocated frame if success, NULL otherwise
  */
-nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t packet_size)
+nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t size)
 {
 	nic_frame_t *frame;
@@ -313,11 +286,11 @@
 	}
 
-	packet_t *packet = nic_alloc_packet(nic_data, packet_size);
-	if (!packet) {
+	frame->data = malloc(size);
+	if (frame->data == NULL) {
 		free(frame);
 		return NULL;
 	}
 
-	frame->packet = packet;
+	frame->size = size;
 	return frame;
 }
@@ -332,7 +305,11 @@
 	if (!frame)
 		return;
-	if (frame->packet != NULL) {
-		nic_release_packet(nic_data, frame->packet);
-	}
+
+	if (frame->data != NULL) {
+		free(frame->data);
+		frame->data = NULL;
+		frame->size = 0;
+	}
+
 	fibril_mutex_lock(&nic_globals.lock);
 	if (nic_globals.frame_cache_size >= NIC_GLOBALS_MAX_CACHE_SIZE) {
@@ -447,5 +424,5 @@
 
 /**
- * Connect to the NET and IRQ services. This function should be called only from
+ * Connect to IRC service. This function should be called only from
  * the add_device handler, thus no locking is required.
  *
@@ -454,14 +431,8 @@
  * @return EOK		If connection was successful.
  * @return EINVAL	If the IRC service cannot be determined.
- * @return EREFUSED	If NET or IRC service cannot be connected.
+ * @return EREFUSED	If IRC service cannot be connected.
  */
 int nic_connect_to_services(nic_t *nic_data)
 {
-	/* NET service */
-	nic_data->net_session = service_connect_blocking(EXCHANGE_SERIALIZE,
-		SERVICE_NETWORKING, 0, 0);
-	if (nic_data->net_session == NULL)
-		return errno;
-	
 	/* IRC service */
 	sysarg_t apic;
@@ -480,26 +451,4 @@
 	
 	return EOK;
-}
-
-/** Notify the NET service that the device is ready
- *
- * @param nic NICF structure
- *
- * @return EOK on success
- *
- */
-int nic_ready(nic_t *nic)
-{
-	fibril_rwlock_read_lock(&nic->main_lock);
-	
-	async_sess_t *session = nic->net_session;
-	devman_handle_t handle = nic->dev->handle;
-	
-	fibril_rwlock_read_unlock(&nic->main_lock);
-	
-	if (session == NULL)
-		return EINVAL;
-	
-	return net_driver_ready(session, handle);
 }
 
@@ -546,7 +495,7 @@
 	
 	/* Notify NIL layer (and uppper) if bound - not in add_device */
-	if (nic_data->nil_session != NULL) {
-		int rc = nil_addr_changed_msg(nic_data->nil_session,
-		    nic_data->device_id, address);
+	if (nic_data->client_session != NULL) {
+		int rc = nic_ev_addr_changed(nic_data->client_session,
+		    address);
 		if (rc != EOK) {
 			fibril_rwlock_write_unlock(&nic_data->main_lock);
@@ -604,5 +553,5 @@
 
 /**
- * The busy flag can be set to 1 only in the write_packet handler, to 0 it can
+ * The busy flag can be set to 1 only in the send_frame handler, to 0 it can
  * be set anywhere.
  *
@@ -613,5 +562,5 @@
 {
 	/*
-	 * When the function is called in write_packet handler the main lock is
+	 * When the function is called in send_frame handler the main lock is
 	 * locked so no race can happen.
 	 * Otherwise, when it is unexpectedly set to 0 (even with main lock held
@@ -622,42 +571,26 @@
 
 /**
- * Provided for correct naming conventions.
- * The packet is checked by filters and then sent up to the NIL layer or
- * discarded, the frame is released.
- *
- * @param nic_data
- * @param frame		The frame containing received packet
+ * This is the function that the driver should call when it receives a frame.
+ * The frame is checked by filters and then sent up to the NIL layer or
+ * discarded. The frame is released.
+ *
+ * @param nic_data
+ * @param frame		The received frame
  */
 void nic_received_frame(nic_t *nic_data, nic_frame_t *frame)
 {
-	nic_received_packet(nic_data, frame->packet);
-	frame->packet = NULL;
-	nic_release_frame(nic_data, frame);
-}
-
-/**
- * This is the function that the driver should call when it receives a packet.
- * The packet is checked by filters and then sent up to the NIL layer or
- * discarded.
- *
- * @param nic_data
- * @param packet		The received packet
- */
-void nic_received_packet(nic_t *nic_data, packet_t *packet)
-{
 	/* Note: this function must not lock main lock, because loopback driver
-	 * 		 calls it inside write_packet handler (with locked main lock) */
-	packet_id_t pid = packet_get_id(packet);
-	
+	 * 		 calls it inside send_frame handler (with locked main lock) */
 	fibril_rwlock_read_lock(&nic_data->rxc_lock);
 	nic_frame_type_t frame_type;
-	int check = nic_rxc_check(&nic_data->rx_control, packet, &frame_type);
+	int check = nic_rxc_check(&nic_data->rx_control, frame->data,
+	    frame->size, &frame_type);
 	fibril_rwlock_read_unlock(&nic_data->rxc_lock);
 	/* Update statistics */
 	fibril_rwlock_write_lock(&nic_data->stats_lock);
-	/* Both sending message up and releasing packet are atomic IPC calls */
+
 	if (nic_data->state == NIC_STATE_ACTIVE && check) {
 		nic_data->stats.receive_packets++;
-		nic_data->stats.receive_bytes += packet_get_data_length(packet);
+		nic_data->stats.receive_bytes += frame->size;
 		switch (frame_type) {
 		case NIC_FRAME_MULTICAST:
@@ -671,5 +604,6 @@
 		}
 		fibril_rwlock_write_unlock(&nic_data->stats_lock);
-		nil_received_msg(nic_data->nil_session, nic_data->device_id, pid);
+		nic_ev_received(nic_data->client_session, frame->data,
+		    frame->size);
 	} else {
 		switch (frame_type) {
@@ -685,31 +619,31 @@
 		}
 		fibril_rwlock_write_unlock(&nic_data->stats_lock);
-		nic_release_packet(nic_data, packet);
-	}
+	}
+	nic_release_frame(nic_data, frame);
 }
 
 /**
  * This function is to be used only in the loopback driver. It's workaround
- * for the situation when the packet does not contain ethernet address.
+ * for the situation when the frame does not contain ethernet address.
  * The filtering is therefore not applied here.
  *
  * @param nic_data
- * @param packet
- */
-void nic_received_noneth_packet(nic_t *nic_data, packet_t *packet)
+ * @param data		Frame data
+ * @param size		Frame size in bytes
+ */
+void nic_received_noneth_frame(nic_t *nic_data, void *data, size_t size)
 {
 	fibril_rwlock_write_lock(&nic_data->stats_lock);
 	nic_data->stats.receive_packets++;
-	nic_data->stats.receive_bytes += packet_get_data_length(packet);
+	nic_data->stats.receive_bytes += size;
 	fibril_rwlock_write_unlock(&nic_data->stats_lock);
 	
-	nil_received_msg(nic_data->nil_session, nic_data->device_id,
-	    packet_get_id(packet));
-}
-
-/**
- * Some NICs can receive multiple packets during single interrupt. These can
+	nic_ev_received(nic_data->client_session, data, size);
+}
+
+/**
+ * Some NICs can receive multiple frames during single interrupt. These can
  * send them in whole list of frames (actually nic_frame_t structures), then
- * the list is deallocated and each packet is passed to the
+ * the list is deallocated and each frame is passed to the
  * nic_received_packet function.
  *
@@ -726,7 +660,5 @@
 
 		list_remove(&frame->link);
-		nic_received_packet(nic_data, frame->packet);
-		frame->packet = NULL;
-		nic_release_frame(nic_data, frame);
+		nic_received_frame(nic_data, frame);
 	}
 	nic_driver_release_frame_list(frames);
@@ -758,8 +690,6 @@
 	nic_data->dev = NULL;
 	nic_data->fun = NULL;
-	nic_data->device_id = NIC_DEVICE_INVALID_ID;
 	nic_data->state = NIC_STATE_STOPPED;
-	nic_data->net_session = NULL;
-	nic_data->nil_session = NULL;
+	nic_data->client_session = NULL;
 	nic_data->irc_session = NULL;
 	nic_data->poll_mode = NIC_POLL_IMMEDIATE;
@@ -815,10 +745,6 @@
  */
 static void nic_destroy(nic_t *nic_data) {
-	if (nic_data->net_session != NULL) {
-		async_hangup(nic_data->net_session);
-	}
-
-	if (nic_data->nil_session != NULL) {
-		async_hangup(nic_data->nil_session);
+	if (nic_data->client_session != NULL) {
+		async_hangup(nic_data->client_session);
 	}
 
@@ -846,41 +772,4 @@
 
 /**
- * Creates an exposed DDF function for the device, named "port0".
- * Device options are set as this function's options. The function is bound
- * (see ddf_fun_bind) and then registered to the DEVICE_CATEGORY_NIC class.
- * Note: this function should be called only from add_device handler, therefore
- * we don't need to use locks.
- *
- * @param nic_data	The NIC structure
- * @param ops		Device options for the DDF function.
- */
-int nic_register_as_ddf_fun(nic_t *nic_data, ddf_dev_ops_t *ops)
-{
-	int rc;
-	assert(nic_data);
-
-	nic_data->fun = ddf_fun_create(nic_data->dev, fun_exposed, "port0");
-	if (nic_data->fun == NULL)
-		return ENOMEM;
-	
-	nic_data->fun->ops = ops;
-	nic_data->fun->driver_data = nic_data;
-
-	rc = ddf_fun_bind(nic_data->fun);
-	if (rc != EOK) {
-		ddf_fun_destroy(nic_data->fun);
-		return rc;
-	}
-
-	rc = ddf_fun_add_to_category(nic_data->fun, DEVICE_CATEGORY_NIC);
-	if (rc != EOK) {
-		ddf_fun_destroy(nic_data->fun);
-		return rc;
-	}
-	
-	return EOK;
-}
-
-/**
  * Set information about current HW filtering.
  *  1 ...	Only those frames we want to receive are passed through HW
@@ -1097,4 +986,13 @@
 {
 	return nic_data->fun;
+}
+
+/**
+ * @param nic_data
+ * @param fun
+ */
+void nic_set_ddf_fun(nic_t *nic_data, ddf_fun_t *fun)
+{
+	nic_data->fun = fun;
 }
 
@@ -1329,23 +1227,4 @@
 }
 
-/** Lock packet for DMA usage
- *
- * @param packet
- * @return physical address of packet
- */
-int nic_dma_lock_packet(packet_t *packet, size_t size, void **phys)
-{
-	return dmamem_map(packet, SIZE2PAGES(size), 0, 0, phys);
-}
-
-/** Unlock packet after DMA usage
- *
- * @param packet
- */
-int nic_dma_unlock_packet(packet_t *packet, size_t size)
-{
-	return dmamem_unmap(packet, size);
-}
-
 /** @}
  */
Index: uspace/lib/nic/src/nic_ev.c
===================================================================
--- uspace/lib/nic/src/nic_ev.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
+++ uspace/lib/nic/src/nic_ev.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup libnic
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#include <async.h>
+#include <device/nic.h>
+#include <errno.h>
+#include "nic_ev.h"
+
+/** Device address changed. */
+int nic_ev_addr_changed(async_sess_t *sess, const nic_address_t *addr)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, NIC_EV_ADDR_CHANGED, &answer);
+	sysarg_t retval = async_data_write_start(exch, addr,
+	    sizeof(nic_address_t));
+
+	async_exchange_end(exch);
+
+	if (retval != EOK) {
+		async_wait_for(req, NULL);
+		return retval;
+	}
+
+	async_wait_for(req, &retval);
+	return retval;
+}
+
+/** Device state changed. */
+int nic_ev_device_state(async_sess_t *sess, sysarg_t state)
+{
+	int rc;
+
+	async_exch_t *exch = async_exchange_begin(sess);
+	rc = async_req_1_0(exch, NIC_EV_DEVICE_STATE, state);
+	async_exchange_end(exch);
+
+	return rc;
+}
+
+/** Frame received. */
+int nic_ev_received(async_sess_t *sess, void *data, size_t size)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, NIC_EV_RECEIVED, &answer);
+	sysarg_t retval = async_data_write_start(exch, data, size);
+
+	async_exchange_end(exch);
+
+	if (retval != EOK) {
+		async_wait_for(req, NULL);
+		return retval;
+	}
+
+	async_wait_for(req, &retval);
+	return retval;
+}
+
+/** @}
+ */
Index: uspace/lib/nic/src/nic_impl.c
===================================================================
--- uspace/lib/nic/src/nic_impl.c	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/nic/src/nic_impl.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -36,8 +36,10 @@
  */
 
+#include <errno.h>
 #include <str_error.h>
 #include <ipc/services.h>
 #include <ns.h>
 #include "nic_driver.h"
+#include "nic_ev.h"
 #include "nic_impl.h"
 
@@ -85,6 +87,5 @@
 	}
 	if (state == NIC_STATE_ACTIVE) {
-		if (nic_data->nil_session == NULL || nic_data->net_session == NULL
-		    || nic_data->device_id < 0) {
+		if (nic_data->client_session == NULL) {
 			fibril_rwlock_write_unlock(&nic_data->main_lock);
 			return EINVAL;
@@ -116,6 +117,6 @@
 	if (state == NIC_STATE_STOPPED) {
 		/* Notify upper layers that we are reseting the MAC */
-		int rc = nil_addr_changed_msg(nic_data->nil_session,
-			nic_data->device_id, &nic_data->default_mac);
+		int rc = nic_ev_addr_changed(nic_data->client_session,
+			&nic_data->default_mac);
 		nic_data->poll_mode = nic_data->default_poll_mode;
 		memcpy(&nic_data->poll_period, &nic_data->default_poll_period,
@@ -149,5 +150,5 @@
 	nic_data->state = state;
 
-	nil_device_state_msg(nic_data->nil_session, nic_data->device_id, state);
+	nic_ev_device_state(nic_data->client_session, state);
 
 	fibril_rwlock_write_unlock(&nic_data->main_lock);
@@ -182,31 +183,24 @@
 
 /**
- * Default implementation of the connect_to_nil method.
- * Connects the driver to the NIL service.
+ * Default implementation of the connect_client method.
+ * Creates callback connection to the client.
  *
  * @param	fun
- * @param	nil_service	ID of the server implementing the NIL service
- * @param	device_id	ID of the device as used in higher layers
- *
- * @return EOK		If the services were bound
- * @return 			Negative error code from service_connect_blocking
- */
-int nic_connect_to_nil_impl(ddf_fun_t *fun, services_t nil_service,
-    nic_device_id_t device_id)
-{
-	nic_t *nic_data = (nic_t *) fun->driver_data;
-	fibril_rwlock_write_lock(&nic_data->main_lock);
+ *
+ * @return EOK		On success, or negative error code.
+ */
+int nic_callback_create_impl(ddf_fun_t *fun)
+{
+	nic_t *nic = (nic_t *) fun->driver_data;
+	fibril_rwlock_write_lock(&nic->main_lock);
 	
-	nic_data->device_id = device_id;
+	nic->client_session = async_callback_receive(EXCHANGE_SERIALIZE);
+	if (nic->client_session == NULL) {
+		fibril_rwlock_write_unlock(&nic->main_lock);
+		return ENOMEM;
+	}
 	
-	nic_data->nil_session = service_connect_blocking(EXCHANGE_SERIALIZE,
-	    nil_service, 0, 0);
-	if (nic_data->nil_session != NULL) {
-		fibril_rwlock_write_unlock(&nic_data->main_lock);
-		return EOK;
-	}
-	
-	fibril_rwlock_write_unlock(&nic_data->main_lock);
-	return EHANGUP;
+	fibril_rwlock_write_unlock(&nic->main_lock);
+	return EOK;
 }
 
@@ -805,16 +799,4 @@
 }
 
-/** Default implementation of the device_added method
- *
- * Just calls nic_ready.
- *
- * @param dev
- *
- */
-void nic_device_added_impl(ddf_dev_t *dev)
-{
-	nic_ready((nic_t *) dev->driver_data);
-}
-
 /**
  * Default handler for unknown methods (outside of the NIC interface).
Index: uspace/lib/nic/src/nic_rx_control.c
===================================================================
--- uspace/lib/nic/src/nic_rx_control.c	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/nic/src/nic_rx_control.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -40,7 +40,6 @@
 #include <bool.h>
 #include <errno.h>
-#include <net/device.h>
-#include <net_checksum.h>
-#include <packet_client.h>
+#include <mem.h>
+#include <nic/nic.h>
 #include "nic_rx_control.h"
 
@@ -392,14 +391,17 @@
  *
  * @param rxc
- * @param packet	The probed frame
+ * @param frame	    The probed frame
  *
  * @return True if the frame passes, false if it does not
  */
-int nic_rxc_check(const nic_rxc_t *rxc, const packet_t *packet,
+int nic_rxc_check(const nic_rxc_t *rxc, const void *data, size_t size,
 	nic_frame_type_t *frame_type)
 {
 	assert(frame_type != NULL);
-	uint8_t *dest_addr = (uint8_t *) packet + packet->data_start;
+	uint8_t *dest_addr = (uint8_t *) data;
 	uint8_t *src_addr = dest_addr + ETH_ADDR;
+
+	if (size < 2 * ETH_ADDR)
+		return false;
 
 	if (dest_addr[0] & 1) {
@@ -448,5 +450,5 @@
 	if (!rxc->vlan_exact && rxc->vlan_mask != NULL) {
 		vlan_header_t *vlan_header = (vlan_header_t *)
-			((uint8_t *) packet + packet->data_start + 2 * ETH_ADDR);
+			((uint8_t *) data + 2 * ETH_ADDR);
 		if (vlan_header->tpid_upper == VLAN_TPID_UPPER &&
 			vlan_header->tpid_lower == VLAN_TPID_LOWER) {
@@ -484,4 +486,43 @@
 		rxc->vlan_exact = vlan_exact;
 }
+
+/** Polynomial used in multicast address hashing */
+#define CRC_MCAST_POLYNOMIAL  0x04c11db6
+
+/** Compute the standard hash from MAC
+ *
+ * Hashing MAC into 64 possible values and using the value as index to
+ * 64bit number.
+ *
+ * The code is copied from qemu-0.13's implementation of ne2000 and rt8139
+ * drivers, but according to documentation there it originates in FreeBSD.
+ *
+ * @param[in] addr The 6-byte MAC address to be hashed
+ *
+ * @return 64-bit number with only single bit set to 1
+ *
+ */
+static uint64_t multicast_hash(const uint8_t addr[6])
+{
+	uint32_t crc;
+    int carry, i, j;
+    uint8_t b;
+
+    crc = 0xffffffff;
+    for (i = 0; i < 6; i++) {
+        b = addr[i];
+        for (j = 0; j < 8; j++) {
+            carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
+            crc <<= 1;
+            b >>= 1;
+            if (carry)
+                crc = ((crc ^ CRC_MCAST_POLYNOMIAL) | carry);
+        }
+    }
+	
+    uint64_t one64 = 1;
+    return one64 << (crc >> 26);
+}
+
 
 /**
Index: uspace/lib/nic/src/nic_wol_virtues.c
===================================================================
--- uspace/lib/nic/src/nic_wol_virtues.c	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/nic/src/nic_wol_virtues.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -38,4 +38,5 @@
 #include "nic_wol_virtues.h"
 #include <assert.h>
+#include <errno.h>
 
 #define NIC_WV_HASH_COUNT 32
Index: uspace/lib/posix/ctype.c
===================================================================
--- uspace/lib/posix/ctype.c	(revision a996ae31af28626eb224d0fc0318932c1f196c19)
+++ uspace/lib/posix/ctype.c	(revision 2cc7f1601bf37a38c6fbe566c6f941f3ffef337e)
@@ -112,5 +112,5 @@
  * @return Non-zero if character match the definition, zero otherwise.
  */
-extern int posix_isascii(int c)
+int posix_isascii(int c)
 {
 	return c >= 0 && c < 128;
@@ -123,5 +123,5 @@
  * @return Coverted character.
  */
-extern int posix_toascii(int c)
+int posix_toascii(int c)
 {
 	return c & 0x7F;
