Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/nic/e1k/e1k.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -33,7 +33,4 @@
  */
 
-/* XXX Fix this */
-#define _DDF_DATA_IMPLANT
-
 #include <assert.h>
 #include <stdio.h>
@@ -42,9 +39,7 @@
 #include <align.h>
 #include <byteorder.h>
-#include <sysinfo.h>
-#include <ipc/irc.h>
-#include <ipc/ns.h>
+#include <irc.h>
+#include <as.h>
 #include <ddi.h>
-#include <as.h>
 #include <ddf/log.h>
 #include <ddf/interrupt.h>
@@ -1758,5 +1753,12 @@
 	e1000_enable_interrupts(e1000);
 	
-	nic_enable_interrupt(nic, e1000->irq);
+	int rc = irc_enable_interrupt(e1000->irq);
+	if (rc != EOK) {
+		e1000_disable_interrupts(e1000);
+		fibril_mutex_unlock(&e1000->ctrl_lock);
+		fibril_mutex_unlock(&e1000->tx_lock);
+		fibril_mutex_unlock(&e1000->rx_lock);
+		return rc;
+	}
 	
 	e1000_clear_rx_ring(e1000);
@@ -1796,5 +1798,5 @@
 	e1000_disable_rx(e1000);
 	
-	nic_disable_interrupt(nic, e1000->irq);
+	irc_disable_interrupt(e1000->irq);
 	e1000_disable_interrupts(e1000);
 	
@@ -2148,13 +2150,8 @@
 	nic_set_ddf_fun(nic, fun);
 	ddf_fun_set_ops(fun, &e1000_dev_ops);
-	ddf_fun_data_implant(fun, nic);
 	
 	rc = e1000_register_int_handler(nic);
 	if (rc != EOK)
 		goto err_fun_create;
-	
-	rc = nic_connect_to_services(nic);
-	if (rc != EOK)
-		goto err_irq;
 	
 	rc = e1000_initialize_rx_structure(nic);
@@ -2379,7 +2376,8 @@
 int main(void)
 {
-	int rc = nic_driver_init(NAME);
-	if (rc != EOK)
-		return rc;
+	printf("%s: HelenOS E1000 network adapter driver\n", NAME);
+	
+	if (nic_driver_init(NAME) != EOK)
+		return 1;
 	
 	nic_driver_implement(&e1000_driver_ops, &e1000_dev_ops,
@@ -2387,5 +2385,4 @@
 	
 	ddf_log_init(NAME);
-	ddf_msg(LVL_NOTE, "HelenOS E1000 driver started");
 	return ddf_driver_main(&e1000_driver);
 }
Index: uspace/drv/nic/ne2k/ne2k.c
===================================================================
--- uspace/drv/nic/ne2k/ne2k.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/nic/ne2k/ne2k.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -38,9 +38,7 @@
  */
 
-/* XXX Fix this */
-#define _DDF_DATA_IMPLANT
-
 #include <stdio.h>
 #include <errno.h>
+#include <irc.h>
 #include <stdlib.h>
 #include <str_error.h>
@@ -256,9 +254,12 @@
 	if (!ne2k->up) {
 		int rc = ne2k_up(ne2k);
+		if (rc != EOK)
+			return rc;
+
+		rc = irc_enable_interrupt(ne2k->irq);
 		if (rc != EOK) {
+			ne2k_down(ne2k);
 			return rc;
 		}
-
-		nic_enable_interrupt(nic_data, ne2k->irq);
 	}
 	return EOK;
@@ -269,5 +270,5 @@
 	ne2k_t *ne2k = (ne2k_t *) nic_get_specific(nic_data);
 
-	nic_disable_interrupt(nic_data, ne2k->irq);
+	(void) irc_disable_interrupt(ne2k->irq);
 	ne2k->receive_configuration = RCR_AB | RCR_AM;
 	ne2k_down(ne2k);
@@ -396,10 +397,4 @@
 	}
 	
-	rc = nic_connect_to_services(nic_data);
-	if (rc != EOK) {
-		ne2k_dev_cleanup(dev);
-		return rc;
-	}
-	
 	fun = ddf_fun_create(nic_get_ddf_dev(nic_data), fun_exposed, "port0");
 	if (fun == NULL) {
@@ -407,7 +402,7 @@
 		return ENOMEM;
 	}
+	
 	nic_set_ddf_fun(nic_data, fun);
 	ddf_fun_set_ops(fun, &ne2k_dev_ops);
-	ddf_fun_data_implant(fun, nic_data);
 	
 	rc = ddf_fun_bind(fun);
@@ -443,4 +438,6 @@
 int main(int argc, char *argv[])
 {
+	printf("%s: HelenOS NE 2000 network adapter driver\n", NAME);
+	
 	nic_driver_init(NAME);
 	nic_driver_implement(&ne2k_driver_ops, &ne2k_dev_ops, &ne2k_nic_iface);
Index: uspace/drv/nic/rtl8139/driver.c
===================================================================
--- uspace/drv/nic/rtl8139/driver.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/nic/rtl8139/driver.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -27,7 +27,4 @@
  */
 
-/* XXX Fix this */
-#define _DDF_DATA_IMPLANT
-
 #include <assert.h>
 #include <errno.h>
@@ -35,5 +32,4 @@
 #include <byteorder.h>
 #include <libarch/barrier.h>
-
 #include <as.h>
 #include <ddf/log.h>
@@ -42,9 +38,6 @@
 #include <nic.h>
 #include <pci_dev_iface.h>
-
-#include <ipc/irc.h>
-#include <sysinfo.h>
-#include <ipc/ns.h>
-
+#include <irc.h>
+#include <stdio.h>
 #include <str.h>
 
@@ -960,5 +953,10 @@
 	rtl8139->int_mask = RTL_DEFAULT_INTERRUPTS;
 	rtl8139_hw_int_enable(rtl8139);
-	nic_enable_interrupt(nic_data, rtl8139->irq);
+
+	int rc = irc_enable_interrupt(rtl8139->irq);
+	if (rc != EOK) {
+		rtl8139_on_stopped(nic_data);
+		return rc;
+	}
 
 	ddf_msg(LVL_DEBUG, "Device activated, interrupt %d registered", rtl8139->irq);
@@ -1325,10 +1323,4 @@
 		goto err_pio;
 
-	rc = nic_connect_to_services(nic_data);
-	if (rc != EOK) {
-		ddf_msg(LVL_ERROR, "Failed to connect to services (%d)", rc);
-		goto err_irq;
-	}
-
 	fun = ddf_fun_create(nic_get_ddf_dev(nic_data), fun_exposed, "port0");
 	if (fun == NULL) {
@@ -1336,7 +1328,7 @@
 		goto err_srv;
 	}
+
 	nic_set_ddf_fun(nic_data, fun);
 	ddf_fun_set_ops(fun, &rtl8139_dev_ops);
-	ddf_fun_data_implant(fun, nic_data);
 
 	rc = ddf_fun_bind(fun);
@@ -1361,6 +1353,4 @@
 	ddf_fun_destroy(fun);
 err_srv:
-	/* XXX Disconnect from services */
-err_irq:
 	unregister_interrupt_handler(dev, rtl8139->irq);
 err_pio:
@@ -2180,12 +2170,14 @@
 int main(void)
 {
+	printf("%s: HelenOS RTL8139 network adapter driver\n", NAME);
+
 	int rc = nic_driver_init(NAME);
 	if (rc != EOK)
 		return rc;
-	nic_driver_implement(
-		&rtl8139_driver_ops, &rtl8139_dev_ops, &rtl8139_nic_iface);
+
+	nic_driver_implement(&rtl8139_driver_ops, &rtl8139_dev_ops,
+	    &rtl8139_nic_iface);
 
 	ddf_log_init(NAME);
-	ddf_msg(LVL_NOTE, "HelenOS RTL8139 driver started");
 	return ddf_driver_main(&rtl8139_driver);
 }
Index: uspace/drv/nic/rtl8169/defs.h
===================================================================
--- uspace/drv/nic/rtl8169/defs.h	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/nic/rtl8169/defs.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -39,4 +39,7 @@
 #include <sys/types.h>
 #include <ddi.h>
+
+#define	PCI_VID_REALTEK		0x10ec
+#define	PCI_VID_DLINK		0x1186
 
 /** Size of RTL8169 registers address space */
Index: uspace/drv/nic/rtl8169/driver.c
===================================================================
--- uspace/drv/nic/rtl8169/driver.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/nic/rtl8169/driver.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -33,4 +33,5 @@
 #include <align.h>
 #include <byteorder.h>
+#include <irc.h>
 #include <libarch/barrier.h>
 
@@ -388,4 +389,15 @@
 	rtl8169_t *rtl8169 = nic_get_specific(nic_data);
 
+	/* Get PCI VID & PID */
+	rc = pci_config_space_read_16(ddf_dev_parent_sess_get(dev),
+	    PCI_VENDOR_ID, &rtl8169->pci_vid);
+	if (rc != EOK)
+		return rc;
+
+	rc = pci_config_space_read_16(ddf_dev_parent_sess_get(dev),
+	    PCI_DEVICE_ID, &rtl8169->pci_pid);
+	if (rc != EOK)
+		return rc;
+
 	/* Map register space */
 	rc = pio_enable(rtl8169->regs_phys, RTL8169_IO_SIZE, &rtl8169->regs);
@@ -418,10 +430,4 @@
 	uint8_t cr_value = pio_read_8(rtl8169->regs + CR);
 	pio_write_8(rtl8169->regs + CR, cr_value | CR_TE | CR_RE);
-
-	rc = nic_connect_to_services(nic_data);
-	if (rc != EOK) {
-		ddf_msg(LVL_ERROR, "Failed to connect to services (%d)", rc);
-		goto err_irq;
-	}
 
 	fun = ddf_fun_create(nic_get_ddf_dev(nic_data), fun_exposed, "port0");
@@ -473,5 +479,6 @@
 	int rc;
 
-	rtl8169_set_hwaddr(rtl8169, addr);
+	fibril_mutex_lock(&rtl8169->rx_lock);
+	fibril_mutex_lock(&rtl8169->tx_lock);
 
 	rc = nic_report_address(nic_data, addr);
@@ -479,4 +486,9 @@
 		return rc;
 
+	rtl8169_set_hwaddr(rtl8169, addr);
+
+	fibril_mutex_unlock(&rtl8169->rx_lock);
+	fibril_mutex_unlock(&rtl8169->tx_lock);
+
 	return EOK;
 }
@@ -484,7 +496,24 @@
 static int rtl8169_get_device_info(ddf_fun_t *fun, nic_device_info_t *info)
 {
-
-	str_cpy(info->vendor_name, NIC_VENDOR_MAX_LENGTH, "Realtek");
-	str_cpy(info->model_name, NIC_MODEL_MAX_LENGTH, "RTL8169");
+	nic_t *nic_data = nic_get_from_ddf_fun(fun);
+	rtl8169_t *rtl8169 = nic_get_specific(nic_data);
+
+	str_cpy(info->vendor_name, NIC_VENDOR_MAX_LENGTH, "Unknown");
+	str_cpy(info->model_name, NIC_MODEL_MAX_LENGTH, "Unknown");
+
+	if (rtl8169->pci_vid == PCI_VID_REALTEK)
+		str_cpy(info->vendor_name, NIC_VENDOR_MAX_LENGTH, "Realtek");
+	
+	if (rtl8169->pci_vid == PCI_VID_DLINK)
+		str_cpy(info->vendor_name, NIC_VENDOR_MAX_LENGTH, "D-Link");
+	
+	if (rtl8169->pci_pid == 0x8168)
+		str_cpy(info->model_name, NIC_MODEL_MAX_LENGTH, "RTL8168");
+	
+	if (rtl8169->pci_pid == 0x8169)
+		str_cpy(info->model_name, NIC_MODEL_MAX_LENGTH, "RTL8169");
+
+	if (rtl8169->pci_pid == 0x8110)
+		str_cpy(info->model_name, NIC_MODEL_MAX_LENGTH, "RTL8110");
 
 	return EOK;
@@ -541,4 +570,7 @@
 	bmcr &= ~(BMCR_DUPLEX | BMCR_SPD_100 | BMCR_SPD_1000);
 	
+	/* Disable autonegotiation */
+	bmcr &= ~BMCR_AN_ENABLE;
+
 	if (duplex == NIC_CM_FULL_DUPLEX)
 		bmcr |= BMCR_DUPLEX;
@@ -609,4 +641,9 @@
 static int rtl8169_autoneg_restart(ddf_fun_t *fun)
 {
+	rtl8169_t *rtl8169 = nic_get_specific(nic_get_from_ddf_fun(fun));
+	uint16_t bmcr = rtl8169_mii_read(rtl8169, MII_BMCR);
+
+	bmcr |= BMCR_AN_ENABLE;
+	rtl8169_mii_write(rtl8169, MII_BMCR, bmcr);
 	return EOK;
 }
@@ -706,5 +743,5 @@
 
 	pio_write_16(rtl8169->regs + IMR, 0xffff);
-	nic_enable_interrupt(nic_data, rtl8169->irq);
+	irc_enable_interrupt(rtl8169->irq);
 
 	return EOK;
@@ -888,4 +925,10 @@
 		}
 
+		/* Receive underrun */
+		if (isr & INT_RXOVW) {
+			/* just ack.. */
+			pio_write_16(rtl8169->regs + ISR, INT_RXOVW);
+		}
+
 		if (isr & INT_SERR) {
 			ddf_msg(LVL_ERROR, "System error interrupt");
Index: uspace/drv/nic/rtl8169/driver.h
===================================================================
--- uspace/drv/nic/rtl8169/driver.h	(revision 96e368a61482194923fef78ac804b0906e9668b9)
+++ uspace/drv/nic/rtl8169/driver.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
@@ -55,4 +55,7 @@
 	/** The irq assigned */
 	int irq;
+	/** PCI Vendor and Product ids */
+	uint16_t pci_vid;
+	uint16_t pci_pid;
 	/** Mask of the turned interupts (IMR value) */
 	uint16_t int_mask;
