diff --git a/Makefile.dep b/Makefile.dep
index cc20a614d3086879b2fa4fb5c7ee0427989dbf8b..a40aae3c390dc51eb892354379170ac479ac917c 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -271,6 +271,10 @@ ifneq (,$(filter gnrc,$(USEMODULE)))
   USEMODULE += gnrc_pktbuf
 endif
 
+ifneq (,$(filter gnrc_netdev2,$(USEMODULE)))
+  USEMODULE += netopt
+endif
+
 ifneq (,$(filter hih6130,$(USEMODULE)))
   USEMODULE += vtimer
 endif
diff --git a/boards/native/Makefile.dep b/boards/native/Makefile.dep
index 317b8d73dbc949971b190346c365fe03915d3a3e..76c68a2dafe701edec095ffb1062a71e49f33dab 100644
--- a/boards/native/Makefile.dep
+++ b/boards/native/Makefile.dep
@@ -1,5 +1,4 @@
 ifneq (,$(filter gnrc_netif_default,$(USEMODULE)))
-    USEMODULE += dev_eth_tap
-    USEMODULE += gnrc_netdev_eth
-    USEMODULE += gnrc_nomac
+    USEMODULE += netdev2_tap
+    USEMODULE += gnrc_netdev2
 endif
diff --git a/boards/native/Makefile.include b/boards/native/Makefile.include
index 9f0ede99754c0109b50329c57538ae9d1261a83f..670da457e3cdd7304c3106ea49d940d119c70583 100644
--- a/boards/native/Makefile.include
+++ b/boards/native/Makefile.include
@@ -72,7 +72,7 @@ export LINKFLAGS += -ldl
 endif
 
 # set the tap interface for term/valgrind
-ifneq (,$(filter dev_eth_tap,$(USEMODULE)))
+ifneq (,$(filter netdev2_tap,$(USEMODULE)))
 	export PORT ?= tap0
 else
 	export PORT =
diff --git a/cpu/native/Makefile b/cpu/native/Makefile
index 7f538c1f419db01eca494a6d2ded0c034c07c633..c601d3323e7269b665185550674447586324b027 100644
--- a/cpu/native/Makefile
+++ b/cpu/native/Makefile
@@ -2,8 +2,8 @@ MODULE = cpu
 
 DIRS += periph
 
-ifneq (,$(filter dev_eth_tap,$(USEMODULE)))
-	DIRS += dev_eth_tap
+ifneq (,$(filter netdev2_tap,$(USEMODULE)))
+	DIRS += netdev2_tap
 endif
 
 include $(RIOTBASE)/Makefile.base
diff --git a/cpu/native/include/native_internal.h b/cpu/native/include/native_internal.h
index e51ddead5f6fc0b8872974cac8a912bd2d535e1b..cc514c2192cec27ed6217e31463846ff0812dff1 100644
--- a/cpu/native/include/native_internal.h
+++ b/cpu/native/include/native_internal.h
@@ -47,6 +47,7 @@
 #include <time.h>
 #include <sys/time.h>
 #include <sys/stat.h>
+#include <sys/uio.h>
 
 #include "kernel_types.h"
 
@@ -123,6 +124,7 @@ extern long int (*real_random)(void);
 extern const char* (*real_gai_strerror)(int errcode);
 extern FILE* (*real_fopen)(const char *path, const char *mode);
 extern mode_t (*real_umask)(mode_t cmask);
+extern ssize_t (*real_writev)(int fildes, const struct iovec *iov, int iovcnt);
 
 #ifdef __MACH__
 #else
@@ -160,6 +162,7 @@ extern fd_set _native_rfds;
 
 ssize_t _native_read(int fd, void *buf, size_t count);
 ssize_t _native_write(int fd, const void *buf, size_t count);
+ssize_t _native_writev(int fildes, const struct iovec *iov, int iovcnt);
 
 /**
  * register interrupt handler handler for interrupt sig
diff --git a/cpu/native/include/dev_eth_tap.h b/cpu/native/include/netdev2_tap.h
similarity index 60%
rename from cpu/native/include/dev_eth_tap.h
rename to cpu/native/include/netdev2_tap.h
index dcf707a848cd69fbfe519674224227ce318d7119..b8f32e9bc9a468e53a1a8a609b759f0e5a536e5c 100644
--- a/cpu/native/include/dev_eth_tap.h
+++ b/cpu/native/include/netdev2_tap.h
@@ -7,66 +7,67 @@
  */
 
 /**
- * @defgroup    dev_eth_tap     Ethernet driver for TAP interfaces
- * @ingroup     native_cpu
+ * @ingroup     netdev2
  * @brief       Low-level ethernet driver for native tap interfaces
  * @{
  *
  * @file
- * @brief       Definitions for @ref net_dev_eth driver for host system's
+ * @brief       Definitions for @ref netdev2 ethernet driver for host system's
  *              TAP interfaces
  *
  * @author      Kaspar Schleiser <kaspar@schleiser.de>
  */
-#ifndef DEV_ETH_TAP_H
-#define DEV_ETH_TAP_H
+#ifndef NETDEV2_TAP_H
+#define NETDEV2_TAP_H
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #include <stdint.h>
-#include "net/dev_eth.h"
+#include "net/netdev2.h"
 
-#include "net/if.h"
+#include "net/ethernet/hdr.h"
 
 #ifdef __MACH__
 #include "net/if_var.h"
+#else
+#include "net/if.h"
 #endif
 
 /**
  * @brief tap interface state
  */
-typedef struct dev_eth_tap {
-    dev_eth_t ethdev;                   /**< dev_eth internal member */
+typedef struct netdev2_tap {
+    netdev2_t netdev;                   /**< netdev2 internal member */
     char tap_name[IFNAMSIZ];            /**< host dev file name */
     int tap_fd;                         /**< host file descriptor for the TAP */
     uint8_t addr[ETHERNET_ADDR_LEN];    /**< The MAC address of the TAP */
     uint8_t promiscous;                 /**< Flag for promiscous mode */
-} dev_eth_tap_t;
+} netdev2_tap_t;
 
 /**
  * @brief global device struct. driver only supports one tap device as of now.
  */
-extern dev_eth_tap_t dev_eth_tap;
+extern netdev2_tap_t netdev2_tap;
 
 /**
- * @brief Setup dev_eth_tap_t structure.
+ * @brief Setup netdev2_tap_t structure.
  *
- * @param dev  the preallocated dev_eth_tap device handle to setup
+ * @param dev  the preallocated netdev2_tap device handle to setup
  * @param name Name of the host system's tap inteface to bind to.
  */
-void dev_eth_tap_setup(dev_eth_tap_t *dev, const char *name);
+void netdev2_tap_setup(netdev2_tap_t *dev, const char *name);
 
 /**
- * @brief Cleanup dev_eth_tap_t structure.
+ * @brief Cleanup tap resources
  *
- * @param dev  the dev_eth_tap device handle to cleanup
+ * @param dev  the netdev2_tap device handle to cleanup
  */
-void dev_eth_tap_cleanup(dev_eth_tap_t *dev);
+void netdev2_tap_cleanup(netdev2_tap_t *dev);
 
 #ifdef __cplusplus
 }
 #endif
 /** @} */
-#endif /* DEV_ETH_TAP_H */
+#endif /* NETDEV2_TAP_H */
diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c
index 0c6a9c4acf4ec9ef6e9b79bed019ba788b94ad89..366bbf002a006ce4e848c6a89595344988bbe8b9 100644
--- a/cpu/native/native_cpu.c
+++ b/cpu/native/native_cpu.c
@@ -49,9 +49,9 @@
 #include "cpu.h"
 #include "cpu_conf.h"
 
-#ifdef MODULE_DEV_ETH_TAP
-#include "dev_eth_tap.h"
-extern dev_eth_tap_t dev_eth_tap;
+#ifdef MODULE_NETDEV2_TAP
+#include "netdev2_tap.h"
+extern netdev2_tap_t netdev2_tap;
 #endif
 
 #include "native_internal.h"
@@ -75,8 +75,8 @@ int reboot_arch(int mode)
     /* TODO: close stdio fds */
 #endif
 
-#ifdef MODULE_DEV_ETH_TAP
-    dev_eth_tap_cleanup(&dev_eth_tap);
+#ifdef MODULE_NETDEV2_TAP
+    netdev2_tap_cleanup(&netdev2_tap);
 #endif
 
     if (real_execve(_native_argv[0], _native_argv, NULL) == -1) {
diff --git a/cpu/native/dev_eth_tap/Makefile b/cpu/native/netdev2_tap/Makefile
similarity index 74%
rename from cpu/native/dev_eth_tap/Makefile
rename to cpu/native/netdev2_tap/Makefile
index 655e12c6908daa9e1186eb911ed17e7666e0e1d8..7d178b6174522e5864eb1770e5088aa590f02ee4 100644
--- a/cpu/native/dev_eth_tap/Makefile
+++ b/cpu/native/netdev2_tap/Makefile
@@ -1,5 +1,3 @@
-MODULE = dev_eth_tap
-
 include $(RIOTBASE)/Makefile.base
 
 INCLUDES = $(NATIVEINCLUDES)
diff --git a/cpu/native/dev_eth_tap/dev_eth_tap.c b/cpu/native/netdev2_tap/netdev2_tap.c
similarity index 61%
rename from cpu/native/dev_eth_tap/dev_eth_tap.c
rename to cpu/native/netdev2_tap/netdev2_tap.c
index 2cfbb3f9538ba4e32de0c3fa7bd1bf38cf838f0f..6c25c8c6e06a01b06dd9f45fd10e15f1f168a139 100644
--- a/cpu/native/dev_eth_tap/dev_eth_tap.c
+++ b/cpu/native/netdev2_tap/netdev2_tap.c
@@ -10,12 +10,13 @@
  */
 
 /*
- * @ingroup net_dev_eth
+ * @ingroup netdev2
  * @{
  * @brief   Low-level ethernet driver for tap interfaces
  * @author  Kaspar Schleiser <kaspar@schleiser.de>
  * @}
  */
+#include <assert.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -47,55 +48,157 @@
 
 #include "native_internal.h"
 
-#include "net/dev_eth.h"
-#include "dev_eth_tap.h"
+#include "net/eui64.h"
+#include "net/netdev2.h"
+#include "net/ethernet.h"
+#include "net/ethernet/hdr.h"
+#include "netdev2_tap.h"
+#include "net/netopt.h"
+#include "net/eui64.h"
 
-#define ENABLE_DEBUG 0
+#define ENABLE_DEBUG (0)
 #include "debug.h"
 
 /* support one tap interface for now */
-dev_eth_tap_t dev_eth_tap;
+netdev2_tap_t netdev2_tap;
 
 #ifdef __MACH__
 pid_t _sigio_child_pid;
-static void _sigio_child(dev_eth_tap_t *dev);
+static void _sigio_child(netdev2_tap_t *dev);
 #endif
 
-/* dev_eth interface */
-static int _init(dev_eth_t *ethdev);
-static void _cleanup(dev_eth_t *ethdev);
-static int _send(dev_eth_t *ethdev, char* buf, int n);
-static int _recv(dev_eth_t *ethdev, char* buf, int n);
+/* netdev2 interface */
+static int _init(netdev2_t *netdev);
+static int _send(netdev2_t *netdev, const struct iovec *vector, int n);
+static int _recv(netdev2_t *netdev, char* buf, int n);
 
-static inline void _get_mac_addr(dev_eth_t *ethdev, uint8_t *dst) {
-    dev_eth_tap_t *dev = (dev_eth_tap_t*)ethdev;
+static inline void _get_mac_addr(netdev2_t *netdev, uint8_t *dst)
+{
+    netdev2_tap_t *dev = (netdev2_tap_t*)netdev;
     memcpy(dst, dev->addr, ETHERNET_ADDR_LEN);
 }
 
-static inline int _get_promiscous(dev_eth_t *ethdev) {
-    dev_eth_tap_t *dev = (dev_eth_tap_t*)ethdev;
+static inline void _set_mac_addr(netdev2_t *netdev, uint8_t *src)
+{
+    netdev2_tap_t *dev = (netdev2_tap_t*)netdev;
+    memcpy(dev->addr, src, ETHERNET_ADDR_LEN);
+}
+
+static inline int _get_promiscous(netdev2_t *netdev)
+{
+    netdev2_tap_t *dev = (netdev2_tap_t*)netdev;
     return dev->promiscous;
 }
 
-static inline int _set_promiscous(dev_eth_t *ethdev, int value) {
-    dev_eth_tap_t *dev = (dev_eth_tap_t*)ethdev;
+static inline int _set_promiscous(netdev2_t *netdev, int value)
+{
+    netdev2_tap_t *dev = (netdev2_tap_t*)netdev;
     dev->promiscous = value;
     return value;
 }
 
-static inline void _isr(dev_eth_t *ethdev) {
-    dev_eth_rx_handler(ethdev);
+static inline int _get_iid(netdev2_t *netdev, eui64_t *value, size_t max_len)
+{
+    if (max_len < sizeof(eui64_t)) {
+        return -EOVERFLOW;
+    }
+
+    uint8_t addr[ETHERNET_ADDR_LEN];
+    _get_mac_addr(netdev, addr);
+    ethernet_get_iid(value, addr);
+
+    return sizeof(eui64_t);
+}
+static inline void _isr(netdev2_t *netdev)
+{
+    if (netdev->event_callback) {
+        netdev->event_callback(netdev, NETDEV2_EVENT_RX_COMPLETE, (void*)NETDEV2_TYPE_ETHERNET);
+    }
+#if DEVELHELP
+    else {
+        puts("netdev2_tap: _isr(): no event_callback set.");
+    }
+#endif
 }
 
-static eth_driver_t eth_driver_tap = {
-    .init = _init,
-    .cleanup = _cleanup,
+int _get(netdev2_t *dev, netopt_t opt, void *value, size_t max_len)
+{
+    if (dev != (netdev2_t *)&netdev2_tap) {
+        return -ENODEV;
+    }
+
+    int res = 0;
+
+    switch (opt) {
+        case NETOPT_DEVICE_TYPE:
+            {
+               uint16_t *tgt = (uint16_t *)value;
+                *tgt = NETDEV2_TYPE_ETHERNET;
+                res = 2;
+                break;
+            }
+        case NETOPT_ADDRESS:
+            if (max_len < ETHERNET_ADDR_LEN) {
+                res = -EINVAL;
+            }
+            else {
+                _get_mac_addr(dev, (uint8_t*)value);
+                res = ETHERNET_ADDR_LEN;
+            }
+            break;
+        case NETOPT_ADDR_LEN:
+        case NETOPT_SRC_LEN:
+            assert(max_len == 2);
+            uint16_t *tgt = (uint16_t*)value;
+            *tgt=6;
+            res = sizeof(uint16_t);
+            break;
+        case NETOPT_PROMISCUOUSMODE:
+            *((bool*)value) = (bool)_get_promiscous(dev);
+            res = sizeof(bool);
+            break;
+        case NETOPT_IPV6_IID:
+            return _get_iid(dev, value, max_len);
+        default:
+            res = -ENOTSUP;
+            break;
+    }
+
+    return res;
+}
+
+int _set(netdev2_t *dev, netopt_t opt, void *value, size_t value_len)
+{
+    (void)value_len;
+
+    if (dev != (netdev2_t *)&netdev2_tap) {
+        return -ENODEV;
+    }
+
+    int res = 0;
+
+    switch (opt) {
+        case NETOPT_ADDRESS:
+            assert(value_len==ETHERNET_ADDR_LEN);
+            _set_mac_addr(dev, (uint8_t*)value);
+            break;
+        case NETOPT_PROMISCUOUSMODE:
+            _set_promiscous(dev, ((bool *)value)[0]);
+            break;
+        default:
+            return -ENOTSUP;
+    }
+
+    return res;
+}
+
+static netdev2_driver_t netdev2_driver_tap = {
     .send = _send,
     .recv = _recv,
-    .get_mac_addr = _get_mac_addr,
-    .get_promiscous = _get_promiscous,
-    .set_promiscous = _set_promiscous,
+    .init = _init,
     .isr = _isr,
+    .get = _get,
+    .set = _set,
 };
 
 /* driver implementation */
@@ -111,18 +214,25 @@ static inline bool _is_addr_multicast(uint8_t *addr)
     return (addr[0] & 0x01);
 }
 
-static int _recv(dev_eth_t *dev_eth, char *buf, int len) {
-    dev_eth_tap_t *dev = (dev_eth_tap_t*)dev_eth;
+static int _recv(netdev2_t *netdev2, char *buf, int len)
+{
+    netdev2_tap_t *dev = (netdev2_tap_t*)netdev2;
+
+    if (!buf) {
+        /* no way of figuring out packet size without racey buffering,
+         * so we return the maximum possible size */
+        return 576;
+    }
 
     int nread = real_read(dev->tap_fd, buf, len);
-    DEBUG("gnrc_tapnet: read %d bytes\n", nread);
+    DEBUG("netdev2_tap: read %d bytes\n", nread);
 
     if (nread > 0) {
         ethernet_hdr_t *hdr = (ethernet_hdr_t *)buf;
         if (!(dev->promiscous) && !_is_addr_multicast(hdr->dst) &&
             !_is_addr_broadcast(hdr->dst) &&
             (memcmp(hdr->dst, dev->addr, ETHERNET_ADDR_LEN) != 0)) {
-            DEBUG("gnrc_eth_dev: received for %02x:%02x:%02x:%02x:%02x:%02x\n"
+            DEBUG("netdev2_tap: received for %02x:%02x:%02x:%02x:%02x:%02x\n"
                   "That's not me => Dropped\n",
                   hdr->dst[0], hdr->dst[1], hdr->dst[2],
                   hdr->dst[3], hdr->dst[4], hdr->dst[5]);
@@ -146,7 +256,7 @@ static int _recv(dev_eth_t *dev_eth, char *buf, int len) {
             extern ssize_t (*real_write)(int fd, const void * buf, size_t count);
             real_write(_sig_pipefd[1], &sig, sizeof(int));
             _native_sigpend++;
-            DEBUG("dev_eth_tap: sigpend++\n");
+            DEBUG("netdev2_tap: sigpend++\n");
         }
         else {
 #ifdef __MACH__
@@ -162,7 +272,7 @@ static int _recv(dev_eth_t *dev_eth, char *buf, int len) {
         if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
         }
         else {
-            err(EXIT_FAILURE, "dev_eth_tap: read");
+            err(EXIT_FAILURE, "netdev2_tap: read");
         }
     }
     else if (nread == 0) {
@@ -175,30 +285,33 @@ static int _recv(dev_eth_t *dev_eth, char *buf, int len) {
     return -1;
 }
 
-static int _send(dev_eth_t *ethdev, char* buf, int n) {
-    dev_eth_tap_t *dev = (dev_eth_tap_t*)ethdev;
-    return _native_write(dev->tap_fd, buf, n);
+static int _send(netdev2_t *netdev, const struct iovec *vector, int n)
+{
+    netdev2_tap_t *dev = (netdev2_tap_t*)netdev;
+    return _native_writev(dev->tap_fd, vector, n);
 }
 
-void dev_eth_tap_setup(dev_eth_tap_t *dev, const char *name) {
-    dev->ethdev.driver = &eth_driver_tap;
+void netdev2_tap_setup(netdev2_tap_t *dev, const char *name) {
+    dev->netdev.driver = &netdev2_driver_tap;
     strncpy(dev->tap_name, name, IFNAMSIZ);
 }
 
-void dev_eth_tap_cleanup(dev_eth_tap_t *dev) {
-    if (!dev) {
-        return;
-    }
-    dev_eth_cleanup((dev_eth_t *) dev);
-}
-
 static void _tap_isr(void) {
-    dev_eth_isr(((dev_eth_t *) &dev_eth_tap));
+    netdev2_t *netdev = (netdev2_t *)&netdev2_tap;
+
+    if (netdev->event_callback) {
+        netdev->event_callback(netdev, NETDEV2_EVENT_ISR, netdev->isr_arg);
+    }
+    else {
+        puts("netdev2_tap: _isr: no event callback.");
+    }
 }
 
-static int _init(dev_eth_t *ethdev)
+static int _init(netdev2_t *netdev)
 {
-    dev_eth_tap_t *dev = (dev_eth_tap_t*)ethdev;
+    DEBUG("%s:%s:%u\n", RIOT_FILE_RELATIVE, __func__, __LINE__);
+
+    netdev2_tap_t *dev = (netdev2_tap_t*)netdev;
 
     /* check device parametrs */
     if (dev == NULL) {
@@ -284,10 +397,8 @@ static int _init(dev_eth_t *ethdev)
     return 0;
 }
 
-static void _cleanup(dev_eth_t *ethdev)
+void netdev2_tap_cleanup(netdev2_tap_t *dev)
 {
-    dev_eth_tap_t *dev = (dev_eth_tap_t*)ethdev;
-
     /* Do we have a device */
     if (!dev) {
         return;
@@ -304,7 +415,7 @@ static void _cleanup(dev_eth_t *ethdev)
 }
 
 #ifdef __MACH__
-static void _sigio_child(dev_eth_tap_t *dev)
+static void _sigio_child(netdev2_tap_t *dev)
 {
     pid_t parent = _native_pid;
     if ((_sigio_child_pid = real_fork()) == -1) {
diff --git a/cpu/native/startup.c b/cpu/native/startup.c
index 0d46b540c6f72dcc4c96048417fa565a8f1253ac..b3add71f26187f805211e71eaec8d382e0f6dad7 100644
--- a/cpu/native/startup.c
+++ b/cpu/native/startup.c
@@ -46,9 +46,9 @@ unsigned _native_rng_seed = 0;
 int _native_rng_mode = 0;
 const char *_native_unix_socket_path = NULL;
 
-#ifdef MODULE_DEV_ETH_TAP
-#include "dev_eth_tap.h"
-extern dev_eth_tap_t dev_eth_tap;
+#ifdef MODULE_NETDEV2_TAP
+#include "netdev2_tap.h"
+extern netdev2_tap_t netdev2_tap;
 #endif
 
 /**
@@ -196,7 +196,7 @@ void usage_exit(void)
 {
     real_printf("usage: %s", _progname);
 
-#if defined(MODULE_DEV_ETH_TAP)
+#if defined(MODULE_NETDEV2_TAP)
     real_printf(" <tap interface>");
 #endif
 
@@ -256,7 +256,7 @@ __attribute__((constructor)) static void startup(int argc, char **argv)
     int replay = 0;
 #endif
 
-#if defined(MODULE_DEV_ETH_TAP)
+#if defined(MODULE_NETDEV2_TAP)
     if (
             (argc < 2)
             || (
@@ -367,8 +367,8 @@ __attribute__((constructor)) static void startup(int argc, char **argv)
 
     native_cpu_init();
     native_interrupt_init();
-#ifdef MODULE_DEV_ETH_TAP
-    dev_eth_tap_setup(&dev_eth_tap, argv[1]);
+#ifdef MODULE_NETDEV2_TAP
+    netdev2_tap_setup(&netdev2_tap, argv[1]);
 #endif
 
     board_init();
diff --git a/cpu/native/syscalls.c b/cpu/native/syscalls.c
index 727d13d66f3e4b54a1881869fe96f5e7a81075e1..a2cab09d5ca01bd9877564ab13ef2345bf48333b 100644
--- a/cpu/native/syscalls.c
+++ b/cpu/native/syscalls.c
@@ -91,6 +91,7 @@ long int (*real_random)(void);
 const char* (*real_gai_strerror)(int errcode);
 FILE* (*real_fopen)(const char *path, const char *mode);
 mode_t (*real_umask)(mode_t cmask);
+ssize_t (*real_writev)(int fildes, const struct iovec *iov, int iovcnt);
 
 #ifdef __MACH__
 #else
@@ -209,6 +210,17 @@ ssize_t _native_write(int fd, const void *buf, size_t count)
     return r;
 }
 
+ssize_t _native_writev(int fd, const struct iovec *iov, int iovcnt)
+{
+    ssize_t r;
+
+    _native_syscall_enter();
+    r = real_writev(fd, iov, iovcnt);
+    _native_syscall_leave();
+
+    return r;
+}
+
 #if defined(__FreeBSD__)
 #undef putchar
 #endif
@@ -424,6 +436,7 @@ void _native_init_syscalls(void)
     *(void **)(&real_ferror) = dlsym(RTLD_NEXT, "ferror");
     *(void **)(&real_clearerr) = dlsym(RTLD_NEXT, "clearerr");
     *(void **)(&real_umask) = dlsym(RTLD_NEXT, "umask");
+    *(void **)(&real_writev) = dlsym(RTLD_NEXT, "writev");
 #ifdef __MACH__
 #else
     *(void **)(&real_clock_gettime) = dlsym(RTLD_NEXT, "clock_gettime");
diff --git a/sys/Makefile b/sys/Makefile
index c25602c6374b35aed49367d4fe10d17d6d6958f4..2a30486950f0afaa6fbe645aecbf3232350e4718 100644
--- a/sys/Makefile
+++ b/sys/Makefile
@@ -40,6 +40,9 @@ endif
 ifneq (,$(filter nhdp,$(USEMODULE)))
     DIRS += net/routing/nhdp
 endif
+ifneq (,$(filter gnrc_netdev2,$(USEMODULE)))
+    DIRS += net/gnrc/link_layer/netdev2
+endif
 ifneq (,$(filter fib,$(USEMODULE)))
     DIRS += net/network_layer/fib
 endif
diff --git a/sys/auto_init/Makefile b/sys/auto_init/Makefile
index 94641a8e4af1c820657ce7a55efc09ae0e168a03..a72b05b9eedc633874f10b8abb2aede18dd5e7f3 100644
--- a/sys/auto_init/Makefile
+++ b/sys/auto_init/Makefile
@@ -4,8 +4,4 @@ ifneq (,$(filter auto_init_gnrc_netif,$(USEMODULE)))
 DIRS += netif
 endif
 
-ifneq (,$(filter dev_eth_autoinit,$(USEMODULE)))
-DIRS += $(RIOTBASE)/sys/auto_init/dev_eth
-endif
-
 include $(RIOTBASE)/Makefile.base
diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c
index a4b0641ef79f6f4cfd6e9865ffe0520aa5f6acf8..32692045fd6499cccb2edf46c8998be199b2e245 100644
--- a/sys/auto_init/auto_init.c
+++ b/sys/auto_init/auto_init.c
@@ -84,9 +84,8 @@
 #include "net/gnrc/udp.h"
 #endif
 
-#ifdef MODULE_DEV_ETH_AUTOINIT
-#include "net/dev_eth.h"
-#include "dev_eth_autoinit.h"
+#ifdef MODULE_FIB
+#include "net/fib.h"
 #endif
 
 #define ENABLE_DEBUG (0)
@@ -182,9 +181,9 @@ void auto_init(void)
     auto_init_kw2xrf();
 #endif
 
-#ifdef MODULE_GNRC_NETDEV_ETH
-    extern void auto_init_gnrc_netdev_eth(void);
-    auto_init_gnrc_netdev_eth();
+#ifdef MODULE_NETDEV2_TAP
+    extern void auto_init_netdev2_tap(void);
+    auto_init_netdev2_tap();
 #endif
 
 #endif /* MODULE_AUTO_INIT_GNRC_NETIF */
diff --git a/sys/auto_init/dev_eth/Makefile b/sys/auto_init/dev_eth/Makefile
deleted file mode 100644
index 347f229678e44021c7fc81b2c63a632cfa6cc89a..0000000000000000000000000000000000000000
--- a/sys/auto_init/dev_eth/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-MODULE = dev_eth_autoinit
-
-include $(RIOTBASE)/Makefile.base
diff --git a/sys/auto_init/dev_eth/dev_eth_autoinit.c b/sys/auto_init/dev_eth/dev_eth_autoinit.c
deleted file mode 100644
index b4b290b72fa70f16663759fd3f251f03330fdf7b..0000000000000000000000000000000000000000
--- a/sys/auto_init/dev_eth/dev_eth_autoinit.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License v2.1. See the file LICENSE in the top level
- * directory for more details.
- */
-
-#include "net/dev_eth.h"
-#include "dev_eth_autoinit.h"
-
-#ifdef MODULE_DEV_ETH_TAP
-#include "dev_eth_tap.h"
-#endif
-
-#ifdef MODULE_ENCX24J600
-#include "encx24j600.h"
-encx24j600_t dev_eth_encx24j600;
-#endif
-
-dev_eth_t * const dev_eth_devices[] = {
-#ifdef MODULE_DEV_ETH_TAP
-    [DEV_ETH_TAP] = (dev_eth_t*)&dev_eth_tap,
-#endif
-#ifdef MODULE_ENCX24J600
-    [DEV_ETH_ENCX24J600] = (dev_eth_t*)&dev_eth_encx24j600,
-#endif
-};
-
-void dev_eth_autoinit(void)
-{
-#ifdef MODULE_ENCX24J600
-    /* TODO: use sensible defines */
-    encx24j600_setup(&dev_eth_encx24j600, SPI_0, GPIO_1, GPIO_2);
-#endif
-}
diff --git a/sys/auto_init/netif/auto_init_gnrc_netdev_eth.c b/sys/auto_init/netif/auto_init_gnrc_netdev_eth.c
deleted file mode 100644
index b713c3329aed333a3de95c747402f33bf3e741cf..0000000000000000000000000000000000000000
--- a/sys/auto_init/netif/auto_init_gnrc_netdev_eth.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License v2.1. See the file LICENSE in the top level
- * directory for more details.
- *
- */
-
-/*
- * @ingroup auto_init_gnrc_netif
- * @{
- *
- * @file
- * @brief   Auto initialization for netdev Ethernet network interfaces
- *
- * @author  Kaspar Schleiser <kaspar@schleiser.de>
- * @author  Oliver Hahm <oliver.hahm@inria.fr>
- */
-
-#ifdef MODULE_GNRC_NETDEV_ETH
-
-#include "board.h"
-#include "net/gnrc/nomac.h"
-#include "net/gnrc.h"
-
-#include "net/gnrc/netdev_eth.h"
-#include "net/dev_eth.h"
-#include "dev_eth_tap.h"
-
-#define ENABLE_DEBUG (0)
-#include "debug.h"
-
-/**
- * @brief   Define stack parameters for the MAC layer thread
- * @{
- */
-#define NETDEV_ETH_MAC_STACKSIZE     (THREAD_STACKSIZE_DEFAULT)
-#define NETDEV_ETH_MAC_PRIO          (THREAD_PRIORITY_MAIN - 4)
-
-static char _nomac_stack[NETDEV_ETH_MAC_STACKSIZE];
-
-void auto_init_gnrc_netdev_eth(void)
-{
-    DEBUG("Initializing NETDEV_ETH device\n");
-    int res = gnrc_netdev_eth_init(&gnrc_netdev_eth, (dev_eth_t*)&dev_eth_tap);
-
-    if (res < 0) {
-        DEBUG("Error initializing NETDEV_ETH device!");
-    }
-    else {
-        gnrc_nomac_init(_nomac_stack, NETDEV_ETH_MAC_STACKSIZE, NETDEV_ETH_MAC_PRIO,
-                        "tapnet", (gnrc_netdev_t *)&gnrc_netdev_eth);
-    }
-}
-#else
-typedef int dont_be_pedantic;
-#endif /* MODULE_GNRC_NETDEV_ETH */
-
-/** @} */
diff --git a/sys/auto_init/netif/auto_init_netdev2_tap.c b/sys/auto_init/netif/auto_init_netdev2_tap.c
new file mode 100644
index 0000000000000000000000000000000000000000..a6e02c67dc78752704761225684c646e3119b8e5
--- /dev/null
+++ b/sys/auto_init/netif/auto_init_netdev2_tap.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ *
+ */
+
+/**
+ * @ingroup auto_init_ng_netif
+ * @{
+ *
+ * @file
+ * @brief   Auto initialization for ethernet devices
+ *
+ * @author  Kaspar Schleiser <kaspar@schleiser.de>
+ */
+
+#ifdef MODULE_NETDEV2_TAP
+
+#define ENABLE_DEBUG (1)
+#include "debug.h"
+
+#include "netdev2_tap.h"
+#include "net/gnrc/gnrc_netdev2_eth.h"
+
+extern netdev2_tap_t netdev2_tap;
+
+/**
+ * @brief   Define stack parameters for the MAC layer thread
+ * @{
+ */
+#define TAP_MAC_STACKSIZE           (THREAD_STACKSIZE_DEFAULT + DEBUG_EXTRA_STACKSIZE)
+#define TAP_MAC_PRIO                (THREAD_PRIORITY_MAIN - 3)
+
+/**
+ * @brief   Stacks for the MAC layer threads
+ */
+static char _netdev2_eth_stack[TAP_MAC_STACKSIZE + DEBUG_EXTRA_STACKSIZE];
+static gnrc_netdev2_t _gnrc_netdev2_tap;
+
+void auto_init_netdev2_tap(void)
+{
+    gnrc_netdev2_eth_init(&_gnrc_netdev2_tap, (netdev2_t*)&netdev2_tap);
+
+    gnrc_netdev2_init(_netdev2_eth_stack, TAP_MAC_STACKSIZE,
+            TAP_MAC_PRIO, "gnrc_netdev2_tap", &_gnrc_netdev2_tap);
+}
+
+#else
+typedef int dont_be_pedantic;
+#endif /* MODULE_NETDEV2_TAP */
+/** @} */
diff --git a/sys/include/dev_eth_autoinit.h b/sys/include/dev_eth_autoinit.h
deleted file mode 100644
index a8d393be87b93b01d2981d82831d451c9add6dac..0000000000000000000000000000000000000000
--- a/sys/include/dev_eth_autoinit.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License v2.1. See the file LICENSE in the top level
- * directory for more details.
- */
-
-/**
- * @defgroup    sys_net_dev_eth dev_eth auto setup
- * @ingroup     net_ethernet
- * @file
- * @brief       Automatically setup available ethernet devices
- * @{
- *
- * @brief       header for dev_eth automatic initialization
- *
- * @author      Kaspar Schleiser <kaspar@schleiser.de>
- */
-
-#ifndef DEV_ETH_AUTOINIT_H
-#define DEV_ETH_AUTOINIT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief enum for available ethernet devices
- */
-enum {
-#ifdef MODULE_DEV_ETH_TAP
-    DEV_ETH_TAP,
-#endif
-#ifdef MODULE_ENCX24J600
-    DEV_ETH_ENCX24J600,
-#endif
-    /* must be last: */
-    NUM_DEV_ETH
-};
-
-/**
- * @brief Array of const pointers to available ethernet devices
- */
-extern dev_eth_t *const dev_eth_devices[];
-
-/**
- * @brief Automatically sets up available dev_eth ethernet devices
- *
- * ... by calling the respective *_setup() functions if available.
- */
-void dev_eth_autoinit(void);
-
-#ifdef __cplusplus
-}
-#endif
-/** @} */
-#endif /* DEV_ETH_AUTOINIT_H */
diff --git a/sys/include/net/dev_eth.h b/sys/include/net/dev_eth.h
deleted file mode 100644
index 487d6e750a8093c90bef8d20d9d9a3e7ae4dbe2d..0000000000000000000000000000000000000000
--- a/sys/include/net/dev_eth.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
- *                    Ell-i open source co-operative
- *
- * This file is subject to the terms and conditions of the GNU Lesser General
- * Public License v2.1. See the file LICENSE in the top level directory for
- * more details.
- */
-
-/**
- * @defgroup    net_dev_eth Low-Level Driver Interface
- * @ingroup     net_ethernet
- * @brief       Low-level ethernet driver interface
- *
- * This interface is supposed to be a low-level interface for ethernet drivers.
- * In order to be universally usable, it leaves out many implementation details
- * to the implementation of an actual network stack using this interface.
- *
- * In order to write a driver for this interface, you have to
- *
- * 1. create a (possibly const) eth_driver_t structure for your device type,
- *    implement it's functions
- *
- * 2. create a dev_eth_t structure, used as device state and handle, for each device
- *
- * In order to use this interface, you have to
- *
- * 1. implement dev_eth_isr, dev_eth_rx_handler and dev_eth_linkstate_handler
- * 2. run a loop that get's notified by dev_eth_isr
- *
- * A devices send function should always be able to send a frame (and make sure of proper locking).
- *
- * Receive packet flow:
- *
- * 1. Ethernet driver receives packet, executes driver's internal ISR.
- * 2. driver's internal ISR should do minimal acknowledging and house keeping and then
- *    call dev_eth_isr
- * 3. dev_eth_isr should notify a user of this API (e.g., the network stack's L2 thread)
- * 4. That thread executes the driver's user-space isr (dev->driver->isr)
- * 5. user space ISR handles less timing critical stuff, eventually calling
- *    dev_eth_linkstate_handler and / or dev_eth_rx_handler
- *
- * Check out the dev_eth test application as example.
- *
- * @{
- *
- * @file
- * @brief       Definitions low-level ethernet driver interface
- *
- * @author      Kaspar Schleiser <kaspar@schleiser.de>
- */
-
-#ifndef DEV_ETH_H
-#define DEV_ETH_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-#include "ethernet/hdr.h"
-
-/**
- * @brief Structure to hold driver state
- *
- * Supposed to be extended by driver implementations.
- * The extended structure should contain all variable driver state.
- */
-typedef struct dev_eth {
-    const struct eth_driver *driver; /**< ptr to that driver's interface.
-                                     driver->init() expects this to be present,
-                                     so set this before using the device. */
-} dev_eth_t;
-
-/**
- * @brief Structure to hold driver interface -> function mapping
- *
- * The send/receive functions expect/return a full ethernet
- * frame (dst mac, src mac, ethertype, payload, no checksum).
- */
-typedef struct eth_driver {
-    /**
-     * @brief Send ethernet frame
-     *
-     * Expects a full ethernet frame (dst mac, src mac, ethertype, payload,
-     * no checksum).
-     *
-     * @param buf buffer to read from
-     * @param len nr of bytes to send
-     *
-     * @return nr of bytes sent, or <=0 on error
-     */
-    int (*send)(dev_eth_t *dev, char* buf, int len);
-
-    /**
-     * @brief Get a received ethernet frame
-     *
-     * Supposed to be called from dev_eth_rx_handler().
-     *
-     * Make sure buf can hold the maximum expected ethernet frame size.
-     *
-     * @param buf buffer to write to
-     * @param len maximum nr. of bytes to read
-     *
-     * @return nr of bytes read or <=0 on error
-     */
-    int (*recv)(dev_eth_t *dev, char* buf, int len);
-
-    /**
-     * @brief get the device's MAC address
-     *
-     * @param buf location to write to. Make sure this is can take least 6 bytes
-     */
-    void (*get_mac_addr)(dev_eth_t *dev, uint8_t *buf);
-
-    /**
-     * @brief get the device's promiscous status
-     *
-     * Default is not promiscous.
-     * Promiscous means, receive all ethernet frames.
-     * Not promiscous means only receive broadcast, multicast or frames with
-     * the device's MAC address as dst address.
-     *
-     * @return 1 for promiscous, 0 for not promiscous
-     */
-    int (*get_promiscous)(dev_eth_t *dev);
-    /**
-     * @brief set the devices promiscous mode
-     *
-     * @param value 1 for promiscous, 0 for not promiscous
-     * @return the new value (device might not support wanted mode)
-     */
-    int (*set_promiscous)(dev_eth_t *dev, int value);
-    /**
-     * @brief the driver's initialization function
-     *
-     * @return <=0 on error, >0 on success
-     */
-    int (*init)(dev_eth_t *dev);
-    /**
-     * @brief the driver's cleanup function (optional)
-     */
-    void (*cleanup)(dev_eth_t *dev);
-    /**
-     * @brief a driver's user-space ISR handler
-     *
-     * This function will be called from a network stack's loop when being notified
-     * by dev_eth_isr.
-     *
-     * It is supposed to call dev_eth_rx_handler for each available received packed,
-     * and dev_eth_linkstate_handler whenever a link state change event occurs.
-     *
-     * See receive packet flow description for details.
-     */
-    void (*isr)(dev_eth_t *dev);
-} eth_driver_t;
-
-/**
- * @brief Initialize a device given by dev (convenience function)
- *
- * The device given as parameter *must* be previously setup by the
- * drivers *_setup() function.
- *
- */
-static inline int dev_eth_init(dev_eth_t *dev) {
-    return dev->driver->init(dev);
-}
-
-/**
- * @brief Cleanup a device given by dev (convenience function)
- *
- * This function is to be called on reboot if the init function is not
- * idempotent.
- *
- */
-static inline void dev_eth_cleanup(dev_eth_t *dev) {
-    if (dev->driver->cleanup) {
-        dev->driver->cleanup(dev);
-    }
-}
-
-/**
- * @brief global dev_eth interrupt handling function.
- *
- * This function should be called from your device's ISR from whithin ISR context.
- * It is supposed to wake up a waiting user-space event loop.
- */
-extern void dev_eth_isr(dev_eth_t *dev);
-
-/**
- * @brief dev_eth event callback for packets that were received.
- *
- * This function should be called from whithin your driver's isr()
- * (as defined in eth_driver_t), once for every packet that was received.
- *
- * It needs to call dev->driver->recv() in order to get received packet
- * from the driver.
- */
-extern void dev_eth_rx_handler(dev_eth_t *dev);
-
-/**
- * @brief dev_eth ethernet link state handler
- *
- * This function should be called from whithin your driver's isr()
- * (as defined in eth_driver_t) for every layer 2 link state change.
- *
- * @param dev device that triggered the event
- * @param newstate 1 for "link established", 0 for "link down"
- */
-extern void dev_eth_linkstate_handler(dev_eth_t *dev, int newstate);
-
-#ifdef __cplusplus
-}
-#endif
-/** @} */
-#endif /* DEV_ETH_H */
diff --git a/sys/include/net/gnrc/gnrc_netdev2.h b/sys/include/net/gnrc/gnrc_netdev2.h
new file mode 100644
index 0000000000000000000000000000000000000000..f0b388f8d06f9f2a4a71ded55466d07db401a122
--- /dev/null
+++ b/sys/include/net/gnrc/gnrc_netdev2.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @ingroup   net_gnrc
+ * @{
+ *
+ * @file
+ * @brief     netdev2 gnrc glue code interface
+ *
+ * This interface is supposed to provide common adaption code between the
+ * low-level network device interface "netdev2" and the gnrc network stack.
+ *
+ * GNRC sends around "gnrc_pktsnip_t" structures, but netdev can only handle
+ * "struct iovec" structures when sending, or a flat buffer when receiving.
+ *
+ * The purpose of gnrc_netdev is to bring these two interfaces together.
+ *
+ * @author    Kaspar Schleiser <kaspar@schleiser.de>
+ */
+
+#ifndef GNRC_NETDEV2_H
+#define GNRC_NETDEV2_H
+
+#include "kernel_types.h"
+#include "net/netdev2.h"
+#include "net/gnrc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NETDEV2_MSG_TYPE_EVENT 0x1234
+
+typedef struct gnrc_netdev2 gnrc_netdev2_t;
+
+/**
+ * @brief Structure holding gnrc netdev2 adapter state
+ *
+ * This structure is supposed to hold any state parameters needed
+ * to use a netdev2 device from gnrc.
+ *
+ * It can be extended
+ */
+struct gnrc_netdev2 {
+    /**
+     * @brief Send a pktsnip using this device
+     *
+     * This function should convert the pktsnip into a format
+     * the underlying device understands and send it.
+     */
+    int (*send)(gnrc_netdev2_t *dev, gnrc_pktsnip_t *snip);
+
+    /**
+     * @brief Receive a pktsnip from this device
+     *
+     * This function should receive a raw frame from the underlying
+     * device and convert it into a pktsnip while adding a netif header
+     * and possibly marking out higher-layer headers.
+     */
+    gnrc_pktsnip_t * (*recv)(gnrc_netdev2_t *dev);
+
+    /**
+     * @brief netdev2 handle this adapter is working with
+     */
+    netdev2_t *dev;
+
+    /**
+     * @brief PID of this adapter for netapi messages
+     */
+    kernel_pid_t pid;
+};
+
+/**
+ * @brief Initialize gnrc netdev2 handler thread
+ *
+ * @param[in] stack         ptr to preallocated stack buffer
+ * @param[in] stacksize     size of stack buffer
+ * @param[in] priority      priority of thread
+ * @param[in] name          name of thread
+ * @param[in] gnrc_netdev2  ptr to netdev2 device to handle in created thread
+ *
+ * @return pid of created thread
+ * @return KERNEL_PID_UNDEF on error
+ */
+kernel_pid_t gnrc_netdev2_init(char *stack, int stacksize, char priority,
+                        const char *name, gnrc_netdev2_t *gnrc_netdev2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GNRC_NETDEV2_H */
+/** @} */
diff --git a/sys/include/net/gnrc/gnrc_netdev2_eth.h b/sys/include/net/gnrc/gnrc_netdev2_eth.h
new file mode 100644
index 0000000000000000000000000000000000000000..d14b4930c88872d2a01ab2f5ff02d02111266e52
--- /dev/null
+++ b/sys/include/net/gnrc/gnrc_netdev2_eth.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @ingroup   net_gnrc
+ * @{
+ *
+ * @file
+ * @brief     netdev2 gnrc ethernet glue code interface
+ *
+ * @author    Kaspar Schleiser <kaspar@schleiser.de>
+ */
+
+#ifndef GNRC_NETDEV2_ETH_H
+#define GNRC_NETDEV2_ETH_H
+
+#include "net/gnrc/gnrc_netdev2.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Initialize gnrc handler thread for netdev2 ethernet device
+ *
+ * @param[in] gnrc_netdev2  gnrc_netdev2 struct to initialize
+ * @param[in] dev           netdev2 device to handle
+ *
+ * @return 1    on success
+ * @return <=0  on error
+ */
+int gnrc_netdev2_eth_init(gnrc_netdev2_t *gnrc_netdev2, netdev2_t *dev);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GNRC_NETDEV2_ETH_H */
+/** @} */
diff --git a/sys/include/net/netopt.h b/sys/include/net/netopt.h
index 21ba41dab9548174336695b5c67b19e9d2547d6a..ef9193128e77c578947969f0e61aae51d0aa3c78 100644
--- a/sys/include/net/netopt.h
+++ b/sys/include/net/netopt.h
@@ -172,6 +172,11 @@ typedef enum {
      */
     NETOPT_IS_WIRED,
 
+    /**
+     * @brief get a device's "type", e.g., ethernet, 802.15.4, ...
+     */
+    NETOPT_DEVICE_TYPE,
+
     /* add more options if needed */
 
     /**
diff --git a/sys/net/crosslayer/netopt/netopt.c b/sys/net/crosslayer/netopt/netopt.c
index 0841fe4a95ba307fdf62c20be75510e3f8ab18c3..0106a3ce607344b154013cc6e121ddc8e6ae1e5d 100644
--- a/sys/net/crosslayer/netopt/netopt.c
+++ b/sys/net/crosslayer/netopt/netopt.c
@@ -49,6 +49,7 @@ static const char *_netopt_strmap[] = {
     [NETOPT_CSMA]            = "NETOPT_CSMA",
     [NETOPT_CSMA_RETRIES]    = "NETOPT_CSMA_RETRIES",
     [NETOPT_IS_WIRED]        = "NETOPT_IS_WIRED",
+    [NETOPT_DEVICE_TYPE]     = "NETOPT_DEVICE_TYPE",
     [NETOPT_NUMOF]           = "NETOPT_NUMOF",
 };
 
diff --git a/sys/net/gnrc/link_layer/netdev_eth/Makefile b/sys/net/gnrc/link_layer/netdev2/Makefile
similarity index 58%
rename from sys/net/gnrc/link_layer/netdev_eth/Makefile
rename to sys/net/gnrc/link_layer/netdev2/Makefile
index 22db6eb87572d592d25e80cd16f90c55d2ef7c8d..2cfcb37ec91ebc41f2905b9df4b68669c2c72e3b 100644
--- a/sys/net/gnrc/link_layer/netdev_eth/Makefile
+++ b/sys/net/gnrc/link_layer/netdev2/Makefile
@@ -1,3 +1,3 @@
-MODULE = gnrc_netdev_eth
+MODULE = gnrc_netdev2
 
 include $(RIOTBASE)/Makefile.base
diff --git a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2.c b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2.c
new file mode 100644
index 0000000000000000000000000000000000000000..320079cc37f6da873a006fbe41f0c39e09436922
--- /dev/null
+++ b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2015 Freie Universität Berlin
+ *               2015 Kaspar Schleiser <kaspar@schleiser.de>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @{
+ * @ingroup     net
+ * @file
+ * @brief       Glue for netdev2 devices to netapi
+ *
+ * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
+ * @author      Kaspar Schleiser <kaspar@schleiser.de>
+ * @}
+ */
+
+#include <errno.h>
+
+#include "kernel.h"
+#include "msg.h"
+#include "thread.h"
+
+#include "net/gnrc.h"
+#include "net/gnrc/nettype.h"
+#include "net/netdev2.h"
+
+#include "net/gnrc/gnrc_netdev2.h"
+#include "net/ethernet/hdr.h"
+
+#define ENABLE_DEBUG    (0)
+#include "debug.h"
+
+#if defined(MODULE_OD) && ENABLE_DEBUG
+#include "od.h"
+#endif
+
+#define NETDEV2_NETAPI_MSG_QUEUE_SIZE 8
+
+static void _pass_on_packet(gnrc_pktsnip_t *pkt);
+
+/**
+ * @brief   Function called by the device driver on device events
+ *
+ * @param[in] event     type of event
+ * @param[in] data      optional parameter
+ */
+static void _event_cb(netdev2_t *dev, netdev2_event_t event, void *data)
+{
+    (void) data;
+    gnrc_netdev2_t *gnrc_netdev2 = (gnrc_netdev2_t*) dev->isr_arg;
+
+    if (event == NETDEV2_EVENT_ISR) {
+        msg_t msg;
+
+        msg.type = NETDEV2_MSG_TYPE_EVENT;
+        msg.content.ptr = (void*) gnrc_netdev2;
+
+        if (msg_send(&msg, gnrc_netdev2->pid) <= 0) {
+            puts("gnrc_netdev2: possibly lost interrupt.");
+        }
+    }
+    else {
+        DEBUG("gnrc_netdev2: event triggered -> %i\n", event);
+        switch(event) {
+            case NETDEV2_EVENT_RX_COMPLETE:
+                {
+                    gnrc_pktsnip_t *pkt = gnrc_netdev2->recv(gnrc_netdev2);
+
+                    if (pkt) {
+                        _pass_on_packet(pkt);
+                    }
+
+                    break;
+                }
+            default:
+                DEBUG("gnrc_netdev2: warning: unhandled event %u.\n", event);
+        }
+    }
+}
+
+static void _pass_on_packet(gnrc_pktsnip_t *pkt)
+{
+    gnrc_netreg_entry_t *sendto;
+
+    /* find out, who to send the packet to */
+    sendto = gnrc_netreg_lookup(pkt->type, GNRC_NETREG_DEMUX_CTX_ALL);
+
+    /* throw away packet if no one is interested */
+    if (sendto == NULL) {
+        DEBUG("gnrc_netdev2: unable to forward packet of type %i\n", pkt->type);
+        gnrc_pktbuf_release(pkt);
+        return;
+    }
+
+    /* send the packet to everyone interested in it's type */
+    gnrc_pktbuf_hold(pkt, gnrc_netreg_num(pkt->type, GNRC_NETREG_DEMUX_CTX_ALL) - 1);
+    while (sendto != NULL) {
+        DEBUG("gnrc_netdev2: sending pkt %p to PID %u\n", (void*)pkt, sendto->pid);
+        gnrc_netapi_receive(sendto->pid, pkt);
+        sendto = gnrc_netreg_getnext(sendto);
+    }
+}
+
+/**
+ * @brief   Startup code and event loop of the gnrc_netdev2 layer
+ *
+ * @param[in] args  expects a pointer to the underlying netdev device
+ *
+ * @return          never returns
+ */
+static void *_gnrc_netdev2_thread(void *args)
+{
+    DEBUG("gnrc_netdev2: starting thread\n");
+
+    gnrc_netdev2_t *gnrc_netdev2 = (gnrc_netdev2_t*) args;
+    netdev2_t *dev = gnrc_netdev2->dev;
+
+    gnrc_netdev2->pid = thread_getpid();
+
+    gnrc_netapi_opt_t *opt;
+    int res;
+    msg_t msg, reply, msg_queue[NETDEV2_NETAPI_MSG_QUEUE_SIZE];
+
+    /* setup the MAC layers message queue */
+    msg_init_queue(msg_queue, NETDEV2_NETAPI_MSG_QUEUE_SIZE);
+
+    /* register the event callback with the device driver */
+    dev->event_callback = _event_cb;
+    dev->isr_arg = (void*) gnrc_netdev2;
+
+    /* register the device to the network stack*/
+    gnrc_netif_add(thread_getpid());
+
+    /* initialize low-level driver */
+    dev->driver->init(dev);
+
+    /* start the event loop */
+    while (1) {
+        DEBUG("gnrc_netdev2: waiting for incoming messages\n");
+        msg_receive(&msg);
+        /* dispatch NETDEV and NETAPI messages */
+        switch (msg.type) {
+            case NETDEV2_MSG_TYPE_EVENT:
+                DEBUG("gnrc_netdev2: GNRC_NETDEV_MSG_TYPE_EVENT received\n");
+                dev->driver->isr(dev);
+                break;
+            case GNRC_NETAPI_MSG_TYPE_SND:
+                DEBUG("gnrc_netdev2: GNRC_NETAPI_MSG_TYPE_SND received\n");
+                gnrc_pktsnip_t *pkt = (gnrc_pktsnip_t *)msg.content.ptr;
+                gnrc_netdev2->send(gnrc_netdev2, pkt);
+                break;
+            case GNRC_NETAPI_MSG_TYPE_SET:
+                /* read incoming options */
+                opt = (gnrc_netapi_opt_t *)msg.content.ptr;
+                DEBUG("gnrc_netdev2: GNRC_NETAPI_MSG_TYPE_SET received. opt=%s\n",
+                        netopt2str(opt->opt));
+                /* set option for device driver */
+                res = dev->driver->set(dev, opt->opt, opt->data, opt->data_len);
+                DEBUG("gnrc_netdev2: response of netdev->set: %i\n", res);
+                /* send reply to calling thread */
+                reply.type = GNRC_NETAPI_MSG_TYPE_ACK;
+                reply.content.value = (uint32_t)res;
+                msg_reply(&msg, &reply);
+                break;
+            case GNRC_NETAPI_MSG_TYPE_GET:
+                /* read incoming options */
+                opt = (gnrc_netapi_opt_t *)msg.content.ptr;
+                DEBUG("gnrc_netdev2: GNRC_NETAPI_MSG_TYPE_GET received. opt=%s\n",
+                        netopt2str(opt->opt));
+                /* get option from device driver */
+                res = dev->driver->get(dev, opt->opt, opt->data, opt->data_len);
+                DEBUG("gnrc_netdev2: response of netdev->get: %i\n", res);
+                /* send reply to calling thread */
+                reply.type = GNRC_NETAPI_MSG_TYPE_ACK;
+                reply.content.value = (uint32_t)res;
+                msg_reply(&msg, &reply);
+                break;
+            default:
+                DEBUG("gnrc_netdev2: Unknown command %" PRIu16 "\n", msg.type);
+                break;
+        }
+    }
+    /* never reached */
+    return NULL;
+}
+
+kernel_pid_t gnrc_netdev2_init(char *stack, int stacksize, char priority,
+                        const char *name, gnrc_netdev2_t *gnrc_netdev2)
+{
+    kernel_pid_t res;
+
+    /* check if given netdev device is defined and the driver is set */
+    if (gnrc_netdev2 == NULL || gnrc_netdev2->dev == NULL) {
+        return -ENODEV;
+    }
+
+    /* create new gnrc_netdev2 thread */
+    res = thread_create(stack, stacksize, priority, CREATE_STACKTEST,
+                         _gnrc_netdev2_thread, (void *)gnrc_netdev2, name);
+    if (res <= 0) {
+        return -EINVAL;
+    }
+
+    return res;
+}
diff --git a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_eth.c b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_eth.c
new file mode 100644
index 0000000000000000000000000000000000000000..e63c09283c3aa28375836da8b4e112b6ff06c963
--- /dev/null
+++ b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_eth.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @{
+ * @ingroup     net
+ * @file
+ * @brief       gnrc netdev2 ethernet glue code
+ *
+ * @author      Kaspar Schleiser <kaspar@schleiser.de>
+ * @}
+ */
+
+#include "net/gnrc.h"
+#include "net/gnrc/gnrc_netdev2.h"
+#include "net/ethernet/hdr.h"
+
+#include "od.h"
+
+#define ENABLE_DEBUG (0)
+#include "debug.h"
+
+static gnrc_pktsnip_t *_recv(gnrc_netdev2_t *gnrc_netdev2)
+{
+    netdev2_t *dev = gnrc_netdev2->dev;
+    int bytes_expected = dev->driver->recv(dev, NULL, 0);
+    gnrc_pktsnip_t *pkt = NULL;
+
+    if (bytes_expected) {
+        pkt = gnrc_pktbuf_add(NULL, NULL,
+                bytes_expected,
+                GNRC_NETTYPE_UNDEF);
+
+        if(!pkt) {
+            DEBUG("_recv_ethernet_packet: cannot allocate pktsnip.\n");
+            goto out;
+        }
+
+        int nread = dev->driver->recv(dev, pkt->data, bytes_expected);
+        if(nread <= 0) {
+            DEBUG("_recv_ethernet_packet: read error.\n");
+            goto safe_out;
+        }
+
+        if (nread < bytes_expected) {
+            /* we've got less then the expected packet size,
+             * so free the unused space.*/
+
+            DEBUG("_recv_ethernet_packet: reallocating.\n");
+            gnrc_pktbuf_realloc_data(pkt, nread);
+        }
+
+        /* mark ethernet header */
+        gnrc_pktsnip_t *eth_hdr = gnrc_pktbuf_mark(pkt, sizeof(ethernet_hdr_t), GNRC_NETTYPE_UNDEF);
+        if (!eth_hdr) {
+            DEBUG("gnrc_netdev2_eth: no space left in packet buffer\n");
+            goto safe_out;
+        }
+
+        ethernet_hdr_t *hdr = (ethernet_hdr_t *)eth_hdr->data;
+
+        /* set payload type from ethertype */
+        pkt->type = gnrc_nettype_from_ethertype(byteorder_ntohs(hdr->type));
+
+        /* create netif header */
+        gnrc_pktsnip_t *netif_hdr;
+        netif_hdr = gnrc_pktbuf_add(NULL, NULL,
+                sizeof(gnrc_netif_hdr_t) + (2 * ETHERNET_ADDR_LEN),
+                GNRC_NETTYPE_NETIF);
+
+        if (netif_hdr == NULL) {
+            DEBUG("gnrc_netdev2_eth: no space left in packet buffer\n");
+            pkt = eth_hdr;
+            goto safe_out;
+        }
+
+        gnrc_netif_hdr_init(netif_hdr->data, ETHERNET_ADDR_LEN, ETHERNET_ADDR_LEN);
+        gnrc_netif_hdr_set_src_addr(netif_hdr->data, hdr->src, ETHERNET_ADDR_LEN);
+        gnrc_netif_hdr_set_dst_addr(netif_hdr->data, hdr->dst, ETHERNET_ADDR_LEN);
+        ((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = thread_getpid();
+
+        DEBUG("gnrc_netdev2_eth: received packet from %02x:%02x:%02x:%02x:%02x:%02x "
+                "of length %zu\n",
+                hdr->src[0], hdr->src[1], hdr->src[2], hdr->src[3], hdr->src[4],
+                hdr->src[5], nread);
+#if defined(MODULE_OD) && ENABLE_DEBUG
+        od_hex_dump(hdr, nread, OD_WIDTH_DEFAULT);
+#endif
+
+        gnrc_pktbuf_remove_snip(pkt, eth_hdr);
+        LL_APPEND(pkt, netif_hdr);
+    }
+
+out:
+    return pkt;
+
+safe_out:
+    gnrc_pktbuf_release(pkt);
+    return NULL;
+}
+
+static inline void _addr_set_broadcast(uint8_t *dst)
+{
+    memset(dst, 0xff, ETHERNET_ADDR_LEN);
+}
+
+#define _IPV6_DST_OFFSET    (36)    /* sizeof(ipv6_hdr_t) - 4  */
+
+static inline void _addr_set_multicast(uint8_t *dst, gnrc_pktsnip_t *payload)
+{
+    switch (payload->type) {
+#ifdef MODULE_IPV6
+        case GNRC_NETTYPE_IPV6:
+            dst[0] = 0x33;
+            dst[1] = 0x33;
+            memcpy(dst + 2, ((uint8_t *)payload->data) + _IPV6_DST_OFFSET, 4);
+            /* TODO change to proper types when gnrc_ipv6_hdr_t got merged */
+            break;
+#endif
+        default:
+            _addr_set_broadcast(dst);
+            break;
+    }
+}
+
+static int _send(gnrc_netdev2_t *gnrc_netdev2, gnrc_pktsnip_t *pkt)
+{
+    ethernet_hdr_t hdr;
+    gnrc_netif_hdr_t *netif_hdr;
+    gnrc_pktsnip_t *payload;
+
+    netdev2_t *dev = gnrc_netdev2->dev;
+
+    if (pkt == NULL) {
+        DEBUG("gnrc_netdev2_eth: pkt was NULL");
+        return -EINVAL;
+    }
+
+    payload = pkt->next;
+
+    if (pkt->type != GNRC_NETTYPE_NETIF) {
+        DEBUG("gnrc_netdev2_eth: First header was not generic netif header\n");
+        return -EBADMSG;
+    }
+
+    if (payload) {
+        hdr.type = byteorder_htons(gnrc_nettype_to_ethertype(payload->type));
+    }
+    else {
+        hdr.type = byteorder_htons(ETHERTYPE_UNKNOWN);
+    }
+
+    netif_hdr = pkt->data;
+
+    /* set ethernet header */
+    if (netif_hdr->src_l2addr_len == ETHERNET_ADDR_LEN) {
+        memcpy(hdr.dst, gnrc_netif_hdr_get_src_addr(netif_hdr),
+               netif_hdr->src_l2addr_len);
+    }
+    else {
+        dev->driver->get(dev, NETOPT_ADDRESS, hdr.src, ETHERNET_ADDR_LEN);
+    }
+
+    if (netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_BROADCAST) {
+        _addr_set_broadcast(hdr.dst);
+    }
+    else if (netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_MULTICAST) {
+        _addr_set_multicast(hdr.dst, payload);
+    }
+    else if (netif_hdr->dst_l2addr_len == ETHERNET_ADDR_LEN) {
+        memcpy(hdr.dst, gnrc_netif_hdr_get_dst_addr(netif_hdr),
+               ETHERNET_ADDR_LEN);
+    }
+    else {
+        DEBUG("gnrc_netdev2_eth: destination address had unexpected format\n");
+        return -EBADMSG;
+    }
+
+    DEBUG("gnrc_netdev2_eth: send to %02x:%02x:%02x:%02x:%02x:%02x\n",
+          hdr.dst[0], hdr.dst[1], hdr.dst[2],
+          hdr.dst[3], hdr.dst[4], hdr.dst[5]);
+
+    size_t n;
+    pkt = gnrc_pktbuf_get_iovec(pkt, &n);
+    struct iovec *vector = (struct iovec *)pkt->data;
+    vector[0].iov_base = (char*)&hdr;
+    vector[0].iov_len = sizeof(ethernet_hdr_t);
+    dev->driver->send(dev, vector, n);
+
+    gnrc_pktbuf_release(pkt);
+
+    return 0;
+}
+
+int gnrc_netdev2_eth_init(gnrc_netdev2_t *gnrc_netdev2, netdev2_t *dev)
+{
+    gnrc_netdev2->send = _send;
+    gnrc_netdev2->recv = _recv;
+    gnrc_netdev2->dev = dev;
+
+    return 0;
+}
diff --git a/sys/net/gnrc/link_layer/netdev_eth/gnrc_netdev_eth.c b/sys/net/gnrc/link_layer/netdev_eth/gnrc_netdev_eth.c
deleted file mode 100644
index 2772c329b97493307a7ee407f59714211ac5c3cc..0000000000000000000000000000000000000000
--- a/sys/net/gnrc/link_layer/netdev_eth/gnrc_netdev_eth.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Copyright (C) 2015 Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>,
- *                    Martine Lenders <mlenders@inf.fu-berlin.de>
- *                    Kaspar Schleiser <kaspar@schleiser.de>
- *
- *
- * This file is subject to the terms and conditions of the GNU Lesser General
- * Public License v2.1. See the file LICENSE in the top level directory for
- * more details.
- */
-
-/**
- * @ingroup     sys_net_link_layer
- * @{
- *
- * @file
- *
- * @author      Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
- * @author      Martine Lenders <mlenders@inf.fu-berlin.de>
- * @author      Kaspar Schleiser <kaspar@schleiser.de>
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "byteorder.h"
-#include "net/eui64.h"
-#include "net/ethernet.h"
-#include "net/ethertype.h"
-#include "net/ipv6/hdr.h"
-#include "net/gnrc/netdev.h"
-#include "net/gnrc/netif/hdr.h"
-#include "net/gnrc/pkt.h"
-#include "net/gnrc/pktbuf.h"
-#include "net/gnrc/netdev_eth.h"
-#include "net/dev_eth.h"
-#include "od.h"
-#include "thread.h"
-#include "utlist.h"
-
-#define ENABLE_DEBUG    (0)
-#include "debug.h"
-
-gnrc_netdev_eth_t gnrc_netdev_eth;
-
-static uint8_t send_buffer[ETHERNET_MAX_LEN];
-static uint8_t recv_buffer[ETHERNET_MAX_LEN];
-
-#define _ISR_EVENT_RX (1U)
-
-/* driver function definitions */
-static int _send_data(gnrc_netdev_t *netdev, gnrc_pktsnip_t *pkt);
-static int _add_event_callback(gnrc_netdev_t *dev, gnrc_netdev_event_cb_t cb);
-static int _rem_event_callback(gnrc_netdev_t *dev, gnrc_netdev_event_cb_t cb);
-static int _get(gnrc_netdev_t *dev, netopt_t opt, void *value, size_t max_len);
-static int _set(gnrc_netdev_t *dev, netopt_t opt, void *value, size_t value_len);
-static void _isr_event(gnrc_netdev_t *dev, uint32_t event_type);
-
-/* netdev driver struct */
-const gnrc_netdev_driver_t gnrc_netdev_eth_driver = {
-    _send_data,
-    _add_event_callback,
-    _rem_event_callback,
-    _get,
-    _set,
-    _isr_event,
-};
-
-/* These functions are not used */
-#if !(defined(__FreeBSD__) || defined(__MACH__))
-/* internal function definitions */
-static inline bool _is_addr_broadcast(uint8_t *addr)
-{
-    return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
-            (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
-}
-
-static inline bool _is_addr_multicast(uint8_t *addr)
-{
-    /* source: http://ieee802.org/secmail/pdfocSP2xXA6d.pdf */
-    return (addr[0] & 0x01);
-}
-#endif /* !(defined(__FreeBSD__) || defined(__MACH__)) */
-
-
-/* build Ethernet packet from pkt */
-static int _marshall_ethernet(gnrc_netdev_eth_t *dev, uint8_t *buffer, gnrc_pktsnip_t *pkt);
-
-/* build ISR handler for ISR events */
-void _trigger_isr_event(void);
-
-static int _send_data(gnrc_netdev_t *netdev, gnrc_pktsnip_t *pkt)
-{
-    int nsent, to_send;
-    gnrc_netdev_eth_t *dev = (gnrc_netdev_eth_t *)netdev;
-
-    DEBUG("gnrc_netdev_eth: send data ");
-
-    if (pkt == NULL) {
-        return -EFAULT;
-    }
-
-    if ((dev == NULL) || (netdev->driver != &gnrc_netdev_eth_driver)) {
-        DEBUG("[wrong device descriptor]\n");
-        gnrc_pktbuf_release(pkt);
-        return -ENODEV;
-    }
-
-    DEBUG("\n");
-
-    to_send = _marshall_ethernet(dev, send_buffer, pkt);
-    gnrc_pktbuf_release(pkt);
-
-    if (to_send < 0) {
-        errno = -to_send;
-        DEBUG("marshall\n");
-        return to_send;
-    }
-
-    DEBUG("gnrc_netdev_eth: send %d bytes\n", to_send);
-#if defined(MODULE_OD) && ENABLE_DEBUG
-    od_hex_dump(send_buffer, to_send, OD_WIDTH_DEFAULT);
-#endif
-
-    dev_eth_t *ethdev = dev->ethdev;
-    if ((nsent = ethdev->driver->send(ethdev, (char*)send_buffer, to_send)) < 0) {
-        DEBUG("write\n");
-        return -EIO;
-    }
-
-    return nsent;
-}
-
-static int _add_event_callback(gnrc_netdev_t *dev, gnrc_netdev_event_cb_t cb)
-{
-    DEBUG("gnrc_netdev_eth: add event callback");
-
-    if ((dev == NULL) || (dev->driver != &gnrc_netdev_eth_driver)) {
-        DEBUG(" [wrong device descriptor]\n");
-        return -ENODEV;
-    }
-
-    if (dev->event_cb != NULL) {
-        DEBUG(" [no space left]\n");
-        return -ENOBUFS;
-    }
-
-    DEBUG("\n");
-    dev->event_cb = cb;
-
-    return 0;
-}
-
-static int _rem_event_callback(gnrc_netdev_t *dev, gnrc_netdev_event_cb_t cb)
-{
-    DEBUG("gnrc_netdev_eth: remove event callback");
-
-    if ((dev == NULL) || (dev->driver != &gnrc_netdev_eth_driver)) {
-        DEBUG(" [wrong device descriptor]\n");
-        return -ENODEV;
-    }
-
-    if (dev->event_cb != cb) {
-        DEBUG(" [not found]\n");
-        return -ENOENT;
-    }
-
-    DEBUG("\n");
-    dev->event_cb = NULL;
-
-    return 0;
-}
-
-/* individual option getters to be called by _get() */
-static inline int _get_addr(gnrc_netdev_eth_t *netdev, uint8_t *value, size_t max_len)
-{
-    if (max_len < ETHERNET_ADDR_LEN) {
-        /* value buffer not big enough */
-        return -EOVERFLOW;
-    }
-
-    dev_eth_t *dev = netdev->ethdev;
-    dev->driver->get_mac_addr(dev, value);
-
-    return ETHERNET_ADDR_LEN;
-}
-
-static inline int _get_addr_len(uint16_t *value, size_t max_len)
-{
-    if (max_len != sizeof(uint16_t)) {
-        /* value buffer not big enough */
-        return -EOVERFLOW;
-    }
-
-    *value = ETHERNET_ADDR_LEN;
-
-    return sizeof(uint16_t);
-}
-
-static inline int _get_iid(gnrc_netdev_eth_t *netdev, eui64_t *value, size_t max_len)
-{
-    if (max_len < sizeof(eui64_t)) {
-        /* value buffer not big enough */
-        return -EOVERFLOW;
-    }
-
-    dev_eth_t *dev = netdev->ethdev;
-    uint8_t addr[ETHERNET_ADDR_LEN];
-    dev->driver->get_mac_addr(dev, addr);
-    ethernet_get_iid(value, addr);
-
-    return sizeof(eui64_t);
-}
-
-static inline int _get_max_pkt_sz(uint16_t *value, size_t max_len)
-{
-    if (max_len != sizeof(uint16_t)) {
-        /* value buffer not big enough */
-        return -EOVERFLOW;
-    }
-
-    *value = ETHERNET_DATA_LEN;
-
-    return sizeof(uint16_t);
-}
-
-static inline int _get_promiscousmode(gnrc_netdev_eth_t *netdev, netopt_enable_t *value,
-                                      size_t max_len)
-{
-    if (max_len != sizeof(netopt_enable_t)) {
-        /* value buffer not big enough */
-        return -EOVERFLOW;
-    }
-
-
-    dev_eth_t *dev = netdev->ethdev;
-    *value = (netopt_enable_t)dev->driver->get_promiscous(dev);
-
-    return sizeof(netopt_enable_t);
-}
-
-static int _get(gnrc_netdev_t *dev, netopt_t opt, void *value, size_t max_len)
-{
-    DEBUG("gnrc_netdev_eth: get ");
-
-    if ((dev == NULL) || (dev->driver != &gnrc_netdev_eth_driver)) {
-        DEBUG("[wrong device descriptor]\n");
-        return -ENODEV;
-    }
-
-    switch (opt) {
-        case NETOPT_ADDRESS:
-            DEBUG("address\n");
-            return _get_addr((gnrc_netdev_eth_t *)dev, value, max_len);
-
-        case NETOPT_ADDR_LEN:
-            DEBUG("address length\n");
-            return _get_addr_len(value, max_len);
-
-        case NETOPT_IPV6_IID:
-            DEBUG("IPv6 IID\n");
-            return _get_iid((gnrc_netdev_eth_t *)dev, value, max_len);
-
-        case NETOPT_MAX_PACKET_SIZE:
-            DEBUG("maximum packet size\n");
-            return _get_max_pkt_sz(value, max_len);
-
-        case NETOPT_PROMISCUOUSMODE:
-            DEBUG("promiscous mode\n");
-            return _get_promiscousmode((gnrc_netdev_eth_t *)dev, value, max_len);
-
-        case NETOPT_IS_WIRED:
-            DEBUG("is wired\n");
-            return 1;
-
-        default:
-            DEBUG("[not supported: %d]\n", opt);
-            return -ENOTSUP;
-    }
-}
-
-/* individual option getters to be called by _get() */
-static inline int _set_promiscousmode(gnrc_netdev_eth_t *netdev, netopt_enable_t *value,
-                                      size_t value_len)
-{
-    if (value_len != sizeof(netopt_enable_t)) {
-        /* value buffer not big enough */
-        return -EOVERFLOW;
-    }
-
-    dev_eth_t *dev = netdev->ethdev;
-
-    dev->driver->set_promiscous(dev, (uint8_t)*value);
-
-    return sizeof(netopt_enable_t);
-}
-
-static int _set(gnrc_netdev_t *dev, netopt_t opt, void *value, size_t value_len)
-{
-    DEBUG("gnrc_netdev_eth: set ");
-
-    if ((dev == NULL) || (dev->driver != &gnrc_netdev_eth_driver)) {
-        DEBUG("[wrong device descriptor]\n");
-        return -ENODEV;
-    }
-
-    switch (opt) {
-        case NETOPT_PROMISCUOUSMODE:
-            DEBUG("promiscous mode\n");
-            return _set_promiscousmode((gnrc_netdev_eth_t *)dev, value, value_len);
-
-        default:
-            DEBUG("[not supported: %d]\n", opt);
-            return -ENOTSUP;
-    }
-}
-
-/* individual event handlers called by _isr_event() */
-static void _rx_event(gnrc_netdev_eth_t *dev);
-
-static void _isr_event(gnrc_netdev_t *dev, uint32_t event_type)
-{
-    DEBUG("gnrc_netdev_eth: ISR event ");
-
-    if ((dev == NULL) || (dev->driver != &gnrc_netdev_eth_driver)) {
-        return;
-    }
-
-    gnrc_netdev_eth_t *netdev = (gnrc_netdev_eth_t*)dev;
-
-    switch (event_type) {
-        case _ISR_EVENT_RX:
-
-            DEBUG("[ISR]\n");
-
-#ifdef NETDEV_ETH_DELAY_SEND
-            DEBUG("netdev_eth: delaying send...\n");
-            volatile int i = NETDEV_ETH_DELAY_SEND;
-            while(i--);
-            DEBUG("netdev_eth: delay done.\n");
-#endif
-
-            dev_eth_t *ethdev = netdev->ethdev;
-            ethdev->driver->isr(ethdev);
-            break;
-
-        default:
-            DEBUG("[unknown event_type]\n");
-            break;
-    }
-}
-
-static inline void _addr_set_broadcast(uint8_t *dst)
-{
-    memset(dst, 0xff, ETHERNET_ADDR_LEN);
-}
-
-static inline void _addr_set_multicast(uint8_t *dst, gnrc_pktsnip_t *payload)
-{
-    switch (payload->type) {
-#ifdef MODULE_GNRC_IPV6
-        case GNRC_NETTYPE_IPV6:
-            dst[0] = 0x33;
-            dst[1] = 0x33;
-            if (payload->data != NULL) {
-                ipv6_hdr_t *hdr = payload->data;
-                uint16_t *prefix = (uint16_t *)(&dst[2]);
-                prefix[0] = hdr->dst.u16[6].u16;
-                prefix[1] = hdr->dst.u16[7].u16;
-            }
-            break;
-#endif
-        default:
-            _addr_set_broadcast(dst);
-            break;
-    }
-}
-
-static int _marshall_ethernet(gnrc_netdev_eth_t *dev, uint8_t *buffer, gnrc_pktsnip_t *pkt)
-{
-    int data_len = 0;
-    ethernet_hdr_t *hdr = (ethernet_hdr_t *)buffer;
-    gnrc_netif_hdr_t *netif_hdr;
-    gnrc_pktsnip_t *payload;
-
-    if (pkt == NULL) {
-        DEBUG("gnrc_netdev_eth: pkt was NULL");
-        return -EINVAL;
-    }
-
-    payload = pkt->next;
-
-    if (pkt->type != GNRC_NETTYPE_NETIF) {
-        DEBUG("gnrc_netdev_eth: First header was not generic netif header\n");
-        return -EBADMSG;
-    }
-
-    if (payload) {
-        hdr->type = byteorder_htons(gnrc_nettype_to_ethertype(payload->type));
-    }
-    else {
-        hdr->type = byteorder_htons(ETHERTYPE_UNKNOWN);
-    }
-
-    netif_hdr = pkt->data;
-
-    /* set ethernet header */
-    if (netif_hdr->src_l2addr_len == ETHERNET_ADDR_LEN) {
-        memcpy(hdr->dst, gnrc_netif_hdr_get_src_addr(netif_hdr),
-               netif_hdr->src_l2addr_len);
-    }
-    else {
-        dev_eth_t *ethdev = dev->ethdev;
-        ethdev->driver->get_mac_addr(ethdev, hdr->src);
-    }
-
-    if (netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_BROADCAST) {
-        _addr_set_broadcast(hdr->dst);
-    }
-    else if (netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_MULTICAST) {
-        if (payload == NULL) {
-            DEBUG("gnrc_netdev_eth: empty multicast packets over Ethernet are "\
-                  "not yet supported\n");
-            return -ENOTSUP;
-
-        }
-        _addr_set_multicast(hdr->dst, payload);
-    }
-    else if (netif_hdr->dst_l2addr_len == ETHERNET_ADDR_LEN) {
-        memcpy(hdr->dst, gnrc_netif_hdr_get_dst_addr(netif_hdr),
-               ETHERNET_ADDR_LEN);
-    }
-    else {
-        DEBUG("gnrc_netdev_eth: destination address had unexpected format\n");
-        return -EBADMSG;
-    }
-
-    DEBUG("gnrc_netdev_eth: send to %02x:%02x:%02x:%02x:%02x:%02x\n",
-          hdr->dst[0], hdr->dst[1], hdr->dst[2],
-          hdr->dst[3], hdr->dst[4], hdr->dst[5]);
-
-    data_len += sizeof(ethernet_hdr_t);
-
-    while (payload != NULL) {
-        if ((data_len + payload->size) > ETHERNET_MAX_LEN) {
-            DEBUG("gnrc_netdev_eth: Packet too big for ethernet frame\n");
-            return -ENOBUFS;
-        }
-
-        memcpy(send_buffer + data_len, payload->data, payload->size);
-
-        data_len += payload->size;
-        payload = payload->next;
-    }
-
-    /* Pad to minimum payload size.
-     * Linux does this on its own, but it doesn't hurt to do it here.
-     * As of now only tuntaposx needs this. */
-    if (data_len < (ETHERNET_MIN_LEN)) {
-        DEBUG("gnrc_netdev_eth: padding data! (%d -> ", data_len);
-        memset(send_buffer + data_len, 0, ETHERNET_MIN_LEN - data_len);
-        data_len = ETHERNET_MIN_LEN;
-        DEBUG("%d)\n", data_len);
-    }
-
-    return data_len;
-}
-
-void dev_eth_isr(dev_eth_t* dev)
-{
-    (void)dev;
-    msg_t msg;
-
-    DEBUG("gnrc_netdev_eth: Trigger ISR event\n");
-
-    /* TODO: check whether this is an input or an output event
-       TODO: refactor this into general io-signal multiplexer */
-
-    msg.type = GNRC_NETDEV_MSG_TYPE_EVENT;
-    msg.content.value = _ISR_EVENT_RX;
-
-    if (msg_send(&msg, gnrc_netdev_eth.mac_pid) <= 0) {
-        puts("dev_eth_isr: possibly lost interrupt.");
-    }
-}
-
-void dev_eth_rx_handler(dev_eth_t* dev) {
-    (void)dev;
-    _rx_event(&gnrc_netdev_eth);
-}
-
-void dev_eth_linkstate_handler(dev_eth_t *dev, int newstate)
-{
-    DEBUG("gnrc_dev_eth: dev=0x%08x link %s\n", (unsigned)dev, newstate ? "UP" : "DOWN");
-    (void)dev; (void)newstate;
-}
-
-static void _rx_event(gnrc_netdev_eth_t *netdev)
-{
-    dev_eth_t *dev = netdev->ethdev;
-    int nread = dev->driver->recv(dev, (char*)recv_buffer, ETHERNET_MAX_LEN);
-
-    DEBUG("gnrc_netdev_eth: read %d bytes\n", nread);
-
-    if (nread > 0) {
-        ethernet_hdr_t *hdr = (ethernet_hdr_t *)recv_buffer;
-        gnrc_pktsnip_t *netif_hdr, *pkt;
-        gnrc_nettype_t receive_type = GNRC_NETTYPE_UNDEF;
-        size_t data_len = (nread - sizeof(ethernet_hdr_t));
-
-        /* TODO: implement multicast groups? */
-
-        netif_hdr = gnrc_pktbuf_add(NULL, NULL,
-                                    sizeof(gnrc_netif_hdr_t) + (2 * ETHERNET_ADDR_LEN),
-                                    GNRC_NETTYPE_NETIF);
-
-        if (netif_hdr == NULL) {
-            DEBUG("gnrc_netdev_eth: no space left in packet buffer\n");
-            return;
-        }
-
-        gnrc_netif_hdr_init(netif_hdr->data, ETHERNET_ADDR_LEN, ETHERNET_ADDR_LEN);
-        gnrc_netif_hdr_set_src_addr(netif_hdr->data, hdr->src, ETHERNET_ADDR_LEN);
-        gnrc_netif_hdr_set_dst_addr(netif_hdr->data, hdr->dst, ETHERNET_ADDR_LEN);
-        ((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = thread_getpid();
-
-        receive_type = gnrc_nettype_from_ethertype(byteorder_ntohs(hdr->type));
-
-        DEBUG("gnrc_netdev_eth: received packet from %02x:%02x:%02x:%02x:%02x:%02x "
-              "of length %zu\n",
-              hdr->src[0], hdr->src[1], hdr->src[2], hdr->src[3], hdr->src[4],
-              hdr->src[5], data_len);
-#if defined(MODULE_OD) && ENABLE_DEBUG
-        od_hex_dump(hdr, nread, OD_WIDTH_DEFAULT);
-#endif
-
-        /* Mark netif header and payload for next layer */
-        if ((pkt = gnrc_pktbuf_add(netif_hdr, recv_buffer + sizeof(ethernet_hdr_t),
-                                   data_len, receive_type)) == NULL) {
-            gnrc_pktbuf_release(netif_hdr);
-            DEBUG("gnrc_netdev_eth: no space left in packet buffer\n");
-            return;
-        }
-
-        if (netdev->event_cb != NULL) {
-            netdev->event_cb(NETDEV_EVENT_RX_COMPLETE, pkt);
-        }
-        else {
-            gnrc_pktbuf_release(pkt);   /* netif_hdr is released automatically too */
-        }
-    }
-    else {
-        DEBUG("gnrc_netdev_eth: spurious _rx_event: %d\n", nread);
-    }
-}
-
-int gnrc_netdev_eth_init(gnrc_netdev_eth_t *netdev, dev_eth_t *ethdev)
-{
-    if ((netdev == NULL) || (ethdev == NULL) || (netdev != &gnrc_netdev_eth)) {
-        return -ENODEV;
-    }
-
-    /* initialize low-level driver */
-    dev_eth_init(ethdev);
-
-    /* initialize device descriptor */
-    netdev->driver = (gnrc_netdev_driver_t *)(&gnrc_netdev_eth_driver);
-    netdev->ethdev = ethdev;
-
-    DEBUG("gnrc_netdev_eth: initialized.\n");
-
-    return 0;
-}
-/**
- * @}
- */
diff --git a/tests/dev_eth/Makefile b/tests/dev_eth/Makefile
deleted file mode 100644
index ac9ca51a9a297151cc374e6cb85f63a146b90bc1..0000000000000000000000000000000000000000
--- a/tests/dev_eth/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-APPLICATION = dev_eth
-include ../Makefile.tests_common
-
-BOARD_WHITELIST = native
-FEATURES_REQUIRED += ethernet
-
-ifneq (,$(filter native,$(BOARD)))
-USEMODULE += dev_eth_tap
-endif
-
-USEMODULE += dev_eth_autoinit
-
-include $(RIOTBASE)/Makefile.include
diff --git a/tests/dev_eth/main.c b/tests/dev_eth/main.c
deleted file mode 100644
index ac59b67594fa426eca908d0138ec35c96fe838c8..0000000000000000000000000000000000000000
--- a/tests/dev_eth/main.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
- *                    Ell-i open source co-operative
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License v2.1. See the file LICENSE in the top level
- * directory for more details.
- */
-
-/**
- * @ingroup tests
- * @{
- *
- * @file
- * @brief       Test application for dev_eth low level ethernet drivers
- *
- * This test application will bounce back every received l2 ethernet
- * frame by exchanging target and destination MAC addresses.
- *
- * @author      Kaspar Schleiser <kaspar@schleiser.de>
- *
- * @}
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "thread.h"
-#include "board.h"
-#include "vtimer.h"
-#include "periph/spi.h"
-#include "periph/gpio.h"
-
-#include "net/dev_eth.h"
-#include "dev_eth_autoinit.h"
-
-#define ENABLE_DEBUG 0
-#include "debug.h"
-
-kernel_pid_t handler_pid = KERNEL_PID_UNDEF;
-
-char _rxbuf[2000];
-
-/* reverse src/dst addresses in raw ethernet packet */
-void turn_packet(char *pkt) {
-    uint8_t mac[6];
-    /* save old dst addr */
-    memcpy(mac, pkt, 6);
-
-    /* use sender MAC address as new destination */
-    memcpy(pkt, pkt+6, 6);
-
-    /* set our MAC address as sender */
-    memcpy(pkt+6, mac, 6);
-}
-
-void dev_eth_isr(dev_eth_t *dev) {
-    (void)dev;
-    thread_wakeup(handler_pid);
-}
-
-void dev_eth_rx_handler(dev_eth_t *dev) {
-    DEBUG("dev_eth_rx_handler dev=0x%08x\n", (unsigned) dev);
-
-    int n = dev->driver->recv(dev, _rxbuf, sizeof(_rxbuf));
-
-    DEBUG("handle_incoming: received %i bytes\n", n);
-
-    if (n>0) {
-        turn_packet(_rxbuf);
-        dev->driver->send(dev, _rxbuf, n);
-    }
-}
-
-void dev_eth_linkstate_handler(dev_eth_t *dev, int newstate)
-{
-    DEBUG("dev_eth: dev=0x%08x link %s\n", (unsigned)dev, newstate ? "UP" : "DOWN");
-    (void)dev; (void)newstate;
-}
-
-int main(void)
-{
-    handler_pid = thread_getpid();
-
-    /* always use first ethernet device for test */
-    dev_eth_t *const dev = dev_eth_devices[0];
-
-    dev_eth_init(dev);
-
-    while(1) {
-        dev->driver->isr(dev);
-        thread_sleep();
-        DEBUG("main: woke up\n");
-    }
-
-    return 0;
-}
diff --git a/tests/driver_netdev_eth/Makefile b/tests/driver_netdev_eth/Makefile
deleted file mode 100644
index 78b4b382379255f7cd9fee8639702e4cfe505ba1..0000000000000000000000000000000000000000
--- a/tests/driver_netdev_eth/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-APPLICATION = driver_netdev_eth
-include ../Makefile.tests_common
-
-BOARD_WHITELIST := native
-
-USEMODULE += dev_eth_tap
-USEMODULE += gnrc
-USEMODULE += gnrc_nomac
-USEMODULE += gnrc_pktdump
-USEMODULE += gnrc_netdev_eth
-USEMODULE += auto_init_gnrc_netif
-USEMODULE += shell
-USEMODULE += shell_commands
-
-include $(RIOTBASE)/Makefile.include
diff --git a/tests/driver_netdev_eth/main.c b/tests/driver_netdev_eth/main.c
deleted file mode 100644
index f9dabde9ec0760d00731ea6452aac28eb2f7e033..0000000000000000000000000000000000000000
--- a/tests/driver_netdev_eth/main.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
- *                    Kaspar Schleiser <kaspar@schleiser.de>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License v2.1. See the file LICENSE in the top level
- * directory for more details.
- */
-
-/**
- * @ingroup     tests
- * @{
- *
- * @file
- * @brief       Test application for netdev ethernet device driver
- *
- * @author      Martine Lenders <mlenders@inf.fu-berlin.de>
- *              Kaspar Schleiser <kaspar@schleiser.de>
- *
- * @}
- */
-
-#include <stdio.h>
-
-#include "board.h"
-#include "kernel.h"
-#include "shell.h"
-#include "shell_commands.h"
-#include "net/gnrc.h"
-#include "net/gnrc/nomac.h"
-#include "net/gnrc/pktdump.h"
-#include "net/gnrc/netdev_eth.h"
-#include "net/dev_eth.h"
-#include "dev_eth_tap.h"
-
-/**
- * @brief   Maybe you are a golfer?!
- */
-int main(void)
-{
-    gnrc_netreg_entry_t dump;
-
-    puts("netdev ethernet device driver test");
-
-    /* initialize and register pktdump */
-    dump.pid = gnrc_pktdump_init();
-    dump.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL;
-
-    if (dump.pid <= KERNEL_PID_UNDEF) {
-        puts("Error starting pktdump thread");
-        return -1;
-    }
-
-    gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &dump);
-
-    /* start the shell */
-    char line_buf[SHELL_DEFAULT_BUFSIZE];
-    shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);
-
-    return 0;
-}