Index: uspace/srv/hw/netif/dp8390/dp8390.c
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390.c	(revision 4fc2b3bfdba83c97d0b6715c3e6412d29f2af0d6)
+++ uspace/srv/hw/netif/dp8390/dp8390.c	(revision 7300c37ab7aa70033e59d49e8effd10625ac3a40)
@@ -54,7 +54,5 @@
 #include <errno.h>
 #include <libarch/ddi.h>
-#include <netif_skel.h>
 #include <net/packet.h>
-#include <nil_interface.h>
 #include <packet_client.h>
 #include "dp8390.h"
@@ -344,5 +342,5 @@
 	
 	/* Step 10: */
-	pio_write_8(ne2k->port + DP_CR, CR_DM_ABORT | CR_STA);
+	pio_write_8(ne2k->port + DP_CR, CR_PS_P0 | CR_DM_ABORT | CR_STA);
 	
 	/* Step 11: */
@@ -449,12 +447,19 @@
 }
 
-static void ne2k_receive_frame(ne2k_t *ne2k, uint8_t page, size_t length,
-    int nil_phone, device_id_t device_id)
-{
-	packet_t *packet = netif_packet_get_1(length);
-	if (!packet)
-		return;
-	
-	void *buf = packet_suffix(packet, length);
+static frame_t *ne2k_receive_frame(ne2k_t *ne2k, uint8_t page, size_t length)
+{
+	frame_t *frame = (frame_t *) malloc(sizeof(frame_t));
+	if (frame == NULL)
+		return NULL;
+	
+	link_initialize(&frame->link);
+	
+	frame->packet = netif_packet_get_1(length);
+	if (frame->packet == NULL) {
+		free(frame);
+		return NULL;
+	}
+	
+	void *buf = packet_suffix(frame->packet, length);
 	bzero(buf, length);
 	uint8_t last = page + length / DP_PAGE;
@@ -473,9 +478,18 @@
 	
 	ne2k->stats.receive_packets++;
-	nil_received_msg(nil_phone, device_id, packet, SERVICE_NONE);
-}
-
-static void ne2k_receive(ne2k_t *ne2k, int nil_phone, device_id_t device_id)
-{
+	return frame;
+}
+
+static link_t *ne2k_receive(ne2k_t *ne2k)
+{
+	/*
+	 * Allocate memory for the list of received frames.
+	 * If the allocation fails here we still receive the
+	 * frames from the network, but they will be lost.
+	 */
+	link_t *frames = (link_t *) malloc(sizeof(link_t));
+	if (frames != NULL)
+		list_initialize(frames);
+	
 	while (true) {
 		uint8_t boundary = pio_read_8(ne2k->port + DP_BNRY) + 1;
@@ -526,6 +540,9 @@
 			ne2k->overruns++;
 			next = current;
-		} else if ((header.status & RSR_PRX) && (ne2k->up))
-			ne2k_receive_frame(ne2k, boundary, length, nil_phone, device_id);
+		} else if ((header.status & RSR_PRX) && (ne2k->up)) {
+			frame_t *frame = ne2k_receive_frame(ne2k, boundary, length);
+			if ((frame != NULL) && (frames != NULL))
+				list_append(&frame->link, frames);
+		}
 		
 		/*
@@ -542,14 +559,17 @@
 		pio_write_8(ne2k->port + DP_BNRY, next);
 	}
-}
-
-void ne2k_interrupt(ne2k_t *ne2k, uint8_t isr, int nil_phone, device_id_t device_id)
-{
+	
+	return frames;
+}
+
+link_t *ne2k_interrupt(ne2k_t *ne2k, uint8_t isr, uint8_t tsr)
+{
+	/* List of received frames */
+	link_t *frames = NULL;
+	
 	if (isr & (ISR_PTX | ISR_TXE)) {
 		if (isr & ISR_TXE)
 			ne2k->stats.send_errors++;
 		else {
-			uint8_t tsr = pio_read_8(ne2k->port + DP_TSR);
-			
 			if (tsr & TSR_PTX)
 				ne2k->stats.send_packets++;
@@ -598,7 +618,4 @@
 	}
 	
-	if (isr & ISR_PRX)
-		ne2k_receive(ne2k, nil_phone, device_id);
-	
 	if (isr & ISR_RXE)
 		ne2k->stats.receive_errors++;
@@ -613,4 +630,7 @@
 	}
 	
+	if (isr & ISR_PRX)
+		frames = ne2k_receive(ne2k);
+	
 	if (isr & ISR_RST) {
 		/*
@@ -624,4 +644,6 @@
 	pio_write_8(ne2k->port + DP_IMR,
 	    IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE | IMR_OVWE | IMR_CNTE);
+	
+	return frames;
 }
 
Index: uspace/srv/hw/netif/dp8390/dp8390.h
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390.h	(revision 4fc2b3bfdba83c97d0b6715c3e6412d29f2af0d6)
+++ uspace/srv/hw/netif/dp8390/dp8390.h	(revision 7300c37ab7aa70033e59d49e8effd10625ac3a40)
@@ -50,5 +50,7 @@
 
 #include <fibril_synch.h>
+#include <adt/list.h>
 #include <net/packet.h>
+#include <netif_skel.h>
 
 /** Module name */
@@ -230,9 +232,14 @@
 } ne2k_t;
 
+typedef struct {
+	link_t link;
+	packet_t *packet;
+} frame_t;
+
 extern int ne2k_probe(ne2k_t *, void *, int);
 extern int ne2k_up(ne2k_t *);
 extern void ne2k_down(ne2k_t *);
 extern void ne2k_send(ne2k_t *, packet_t *);
-extern void ne2k_interrupt(ne2k_t *, uint8_t isr, int, device_id_t);
+extern link_t *ne2k_interrupt(ne2k_t *, uint8_t, uint8_t);
 
 #endif
Index: uspace/srv/hw/netif/dp8390/ne2000.c
===================================================================
--- uspace/srv/hw/netif/dp8390/ne2000.c	(revision 4fc2b3bfdba83c97d0b6715c3e6412d29f2af0d6)
+++ uspace/srv/hw/netif/dp8390/ne2000.c	(revision 7300c37ab7aa70033e59d49e8effd10625ac3a40)
@@ -68,4 +68,11 @@
 #define IRQ_GET_ISR(call)  ((int) IPC_GET_ARG2(call))
 
+/** Return the TSR from the interrupt call.
+ *
+ * @param[in] call The interrupt call.
+ *
+ */
+#define IRQ_GET_TSR(call)  ((int) IPC_GET_ARG3(call))
+
 static int irc_service = 0;
 static int irc_phone = -1;
@@ -92,5 +99,5 @@
 		/* Predicate for accepting the interrupt */
 		.cmd = CMD_PREDICATE,
-		.value = 3,
+		.value = 4,
 		.srcarg = 3
 	},
@@ -111,4 +118,10 @@
 	},
 	{
+		/* Read Transmit Status Register */
+		.cmd = CMD_PIO_READ_8,
+		.addr = NULL,
+		.dstarg = 3
+	},
+	{
 		.cmd = CMD_ACCEPT
 	}
@@ -125,5 +138,9 @@
 /** Handle the interrupt notification.
  *
- * This is the interrupt notification function.
+ * This is the interrupt notification function. It is quarantied
+ * that there is only a single instance of this notification
+ * function running at one time until the return from the
+ * ne2k_interrupt() function (where the interrupts are unmasked
+ * again).
  *
  * @param[in] iid  Interrupt notification identifier.
@@ -148,6 +165,22 @@
 	fibril_rwlock_read_unlock(&netif_globals.lock);
 	
-	if (ne2k != NULL)
-		ne2k_interrupt(ne2k, IRQ_GET_ISR(*call), nil_phone, device_id);
+	if (ne2k != NULL) {
+		link_t *frames =
+		    ne2k_interrupt(ne2k, IRQ_GET_ISR(*call), IRQ_GET_TSR(*call));
+		
+		if (frames != NULL) {
+			while (!list_empty(frames)) {
+				frame_t *frame =
+				    list_get_instance(frames->next, frame_t, link);
+				
+				list_remove(&frame->link);
+				nil_received_msg(nil_phone, device_id, frame->packet,
+				    SERVICE_NONE);
+				free(frame);
+			}
+			
+			free(frames);
+		}
+	}
 }
 
