Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision 3fe58d3c98a1a1ef32bfc4718efd64ae275de456)
+++ uspace/drv/nic/e1k/e1k.c	(revision e86b8f0a4a36b968e6ed12053ec2fbf42b8b5f9e)
@@ -2097,4 +2097,5 @@
 int e1000_dev_add(ddf_dev_t *dev)
 {
+	ddf_fun_t *fun;
 	assert(dev);
 	
@@ -2127,11 +2128,14 @@
 	e1000_initialize_vlan(e1000);
 	
-	rc = nic_register_as_ddf_fun(nic, &e1000_dev_ops);
-	if (rc != EOK)
+	fun = ddf_fun_create(nic_get_ddf_dev(nic), fun_exposed, "port0");
+	if (fun == NULL)
 		goto err_tx_structure;
+	nic_set_ddf_fun(nic, fun);
+	fun->ops = &e1000_dev_ops;
+	fun->driver_data = nic;
 	
 	rc = e1000_register_int_handler(nic);
 	if (rc != EOK)
-		goto err_tx_structure;
+		goto err_fun_create;
 	
 	rc = nic_connect_to_services(nic);
@@ -2156,10 +2160,24 @@
 		goto err_rx_structure;
 	
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK)
+		goto err_fun_bind;
+	
+	rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC);
+	if (rc != EOK)
+		goto err_add_to_cat;
+	
 	return EOK;
 	
+err_add_to_cat:
+	ddf_fun_unbind(fun);
+err_fun_bind:
 err_rx_structure:
 	e1000_uninitialize_rx_structure(nic);
 err_irq:
 	unregister_interrupt_handler(dev, DRIVER_DATA_DEV(dev)->irq);
+err_fun_create:
+	ddf_fun_destroy(fun);
+	nic_set_ddf_fun(nic, NULL);
 err_tx_structure:
 	e1000_uninitialize_tx_structure(e1000);
Index: uspace/drv/nic/lo/lo.c
===================================================================
--- uspace/drv/nic/lo/lo.c	(revision 3fe58d3c98a1a1ef32bfc4718efd64ae275de456)
+++ uspace/drv/nic/lo/lo.c	(revision e86b8f0a4a36b968e6ed12053ec2fbf42b8b5f9e)
@@ -80,36 +80,59 @@
 static int lo_dev_add(ddf_dev_t *dev)
 {
-	nic_t *nic_data = nic_create_and_bind(dev);
-	if (nic_data == NULL) {
+	ddf_fun_t *fun = NULL;
+	bool bound = false;
+	
+	nic_t *nic = nic_create_and_bind(dev);
+	if (nic == NULL) {
 		printf("%s: Failed to initialize\n", NAME);
 		return ENOMEM;
 	}
 	
-	dev->driver_data = nic_data;
-	nic_set_send_frame_handler(nic_data, lo_send_frame);
+	dev->driver_data = nic;
+	nic_set_send_frame_handler(nic, lo_send_frame);
 	
-	int rc = nic_connect_to_services(nic_data);
+	int rc = nic_connect_to_services(nic);
 	if (rc != EOK) {
 		printf("%s: Failed to connect to services\n", NAME);
-		nic_unbind_and_destroy(dev);
-		return rc;
+		goto error;
 	}
 	
-	rc = nic_register_as_ddf_fun(nic_data, &lo_dev_ops);
+	fun = ddf_fun_create(nic_get_ddf_dev(nic), fun_exposed, "port0");
+	if (fun == NULL) {
+		printf("%s: Failed creating function\n", NAME);
+		rc = ENOMEM;
+		goto error;
+	}
+	nic_set_ddf_fun(nic, fun);
+	fun->ops = &lo_dev_ops;
+	fun->driver_data = nic;
+	
+	rc = nic_report_address(nic, &lo_addr);
 	if (rc != EOK) {
-		printf("%s: Failed to register as DDF function\n", NAME);
-		nic_unbind_and_destroy(dev);
-		return rc;
+		printf("%s: Failed to setup loopback address\n", NAME);
+		goto error;
 	}
 	
-	rc = nic_report_address(nic_data, &lo_addr);
+	rc = ddf_fun_bind(fun);
 	if (rc != EOK) {
-		printf("%s: Failed to setup loopback address\n", NAME);
-		nic_unbind_and_destroy(dev);
-		return rc;
+		printf("%s: Failed binding function\n", NAME);
+		goto error;
 	}
+	bound = true;
+	
+	rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC);
+	if (rc != EOK)
+		goto error;
 	
 	printf("%s: Adding loopback device '%s'\n", NAME, dev->name);
 	return EOK;
+error:
+	if (bound)
+		ddf_fun_unbind(fun);
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
+	
+	nic_unbind_and_destroy(dev);
+	return rc;
 }
 
Index: uspace/drv/nic/ne2k/ne2k.c
===================================================================
--- uspace/drv/nic/ne2k/ne2k.c	(revision 3fe58d3c98a1a1ef32bfc4718efd64ae275de456)
+++ uspace/drv/nic/ne2k/ne2k.c	(revision e86b8f0a4a36b968e6ed12053ec2fbf42b8b5f9e)
@@ -338,4 +338,6 @@
 static int ne2k_dev_add(ddf_dev_t *dev)
 {
+	ddf_fun_t *fun;
+	
 	/* Allocate driver data for the device. */
 	nic_t *nic_data = nic_create_and_bind(dev);
@@ -371,5 +373,5 @@
 	}
 	
-	rc = nic_register_as_ddf_fun(nic_data, &ne2k_dev_ops);
+	rc = nic_connect_to_services(nic_data);
 	if (rc != EOK) {
 		ne2k_dev_cleanup(dev);
@@ -377,7 +379,24 @@
 	}
 	
-	rc = nic_connect_to_services(nic_data);
-	if (rc != EOK) {
+	fun = ddf_fun_create(nic_get_ddf_dev(nic_data), fun_exposed, "port0");
+	if (fun == NULL) {
 		ne2k_dev_cleanup(dev);
+		return ENOMEM;
+	}
+	nic_set_ddf_fun(nic_data, fun);
+	fun->ops = &ne2k_dev_ops;
+	fun->driver_data = nic_data;
+	
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		ddf_fun_destroy(fun);
+		ne2k_dev_cleanup(dev);
+		return rc;
+	}
+	
+	rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC);
+	if (rc != EOK) {
+		ddf_fun_unbind(fun);
+		ddf_fun_destroy(fun);
 		return rc;
 	}
Index: uspace/drv/nic/rtl8139/driver.c
===================================================================
--- uspace/drv/nic/rtl8139/driver.c	(revision 3fe58d3c98a1a1ef32bfc4718efd64ae275de456)
+++ uspace/drv/nic/rtl8139/driver.c	(revision e86b8f0a4a36b968e6ed12053ec2fbf42b8b5f9e)
@@ -1280,4 +1280,6 @@
 int rtl8139_dev_add(ddf_dev_t *dev)
 {
+	ddf_fun_t *fun;
+
 	assert(dev);
 	ddf_msg(LVL_NOTE, "RTL8139_dev_add %s (handle = %d)", dev->name, dev->handle);
@@ -1316,8 +1318,22 @@
 	}
 
-	rc = nic_register_as_ddf_fun(nic_data, &rtl8139_dev_ops);
+	fun = ddf_fun_create(nic_get_ddf_dev(nic_data), fun_exposed, "port0");
+	if (fun == NULL) {
+		ddf_msg(LVL_ERROR, "Failed creating device function");
+		goto err_srv;
+	}
+	nic_set_ddf_fun(nic_data, fun);
+	fun->ops = &rtl8139_dev_ops;
+	fun->driver_data = nic_data;
+
+	rc = ddf_fun_bind(fun);
 	if (rc != EOK) {
-		ddf_msg(LVL_ERROR, "Failed to register as DDF function - error %d", rc);
-		goto err_irq;
+		ddf_msg(LVL_ERROR, "Failed binding device function");
+		goto err_fun_create;
+	}
+	rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function to category");
+		goto err_fun_bind;
 	}
 
@@ -1327,4 +1343,10 @@
 	return EOK;
 
+err_fun_bind:
+	ddf_fun_unbind(fun);
+err_fun_create:
+	ddf_fun_destroy(fun);
+err_srv:
+	/* XXX Disconnect from services */
 err_irq:
 	unregister_interrupt_handler(dev, rtl8139->irq);
Index: uspace/lib/nic/include/nic.h
===================================================================
--- uspace/lib/nic/include/nic.h	(revision 3fe58d3c98a1a1ef32bfc4718efd64ae275de456)
+++ uspace/lib/nic/include/nic.h	(revision e86b8f0a4a36b968e6ed12053ec2fbf42b8b5f9e)
@@ -44,4 +44,6 @@
 #include <ops/nic.h>
 
+#define DEVICE_CATEGORY_NIC "nic"
+
 struct nic;
 typedef struct nic nic_t;
@@ -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 *);
@@ -225,4 +226,5 @@
 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 *);
Index: uspace/lib/nic/include/nic_driver.h
===================================================================
--- uspace/lib/nic/include/nic_driver.h	(revision 3fe58d3c98a1a1ef32bfc4718efd64ae275de456)
+++ uspace/lib/nic/include/nic_driver.h	(revision e86b8f0a4a36b968e6ed12053ec2fbf42b8b5f9e)
@@ -50,6 +50,4 @@
 #include "nic_rx_control.h"
 #include "nic_wol_virtues.h"
-
-#define DEVICE_CATEGORY_NIC "nic"
 
 struct sw_poll_info {
Index: uspace/lib/nic/src/nic_driver.c
===================================================================
--- uspace/lib/nic/src/nic_driver.c	(revision 3fe58d3c98a1a1ef32bfc4718efd64ae275de456)
+++ uspace/lib/nic/src/nic_driver.c	(revision e86b8f0a4a36b968e6ed12053ec2fbf42b8b5f9e)
@@ -812,41 +812,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
@@ -1063,4 +1026,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;
 }
 
