From c554d30b268fbc92cc2017c56ec0537962c59249 Mon Sep 17 00:00:00 2001
From: zhuoshuguo <shuguo.zhuo@inria.fr>
Date: Thu, 19 Oct 2017 19:40:58 +0200
Subject: [PATCH] gnrc_lwmac: port to gnrc_netif2.

---
 Makefile.dep                                  |   2 +-
 sys/auto_init/netif/auto_init_at86rf2xx.c     |  15 +-
 sys/include/net/gnrc/lwmac/hdr.h              |  18 +-
 sys/include/net/gnrc/lwmac/lwmac.h            |  38 +-
 sys/include/net/gnrc/lwmac/timeout.h          |  22 +-
 sys/include/net/gnrc/lwmac/types.h            |  92 +--
 sys/include/net/gnrc/mac/internal.h           |  65 ++
 sys/include/net/gnrc/netif2/mac.h             |  38 +
 .../link_layer/lwmac/include/lwmac_internal.h | 172 ++--
 .../lwmac/include/rx_state_machine.h          |  14 +-
 .../lwmac/include/tx_state_machine.h          |  14 +-
 sys/net/gnrc/link_layer/lwmac/lwmac.c         | 759 +++++++++---------
 .../gnrc/link_layer/lwmac/lwmac_internal.c    | 159 +++-
 .../gnrc/link_layer/lwmac/rx_state_machine.c  | 178 ++--
 sys/net/gnrc/link_layer/lwmac/timeout.c       |  54 +-
 .../gnrc/link_layer/lwmac/tx_state_machine.c  | 420 +++++-----
 sys/net/gnrc/netif2/gnrc_netif2_ieee802154.c  |   4 +-
 17 files changed, 1149 insertions(+), 915 deletions(-)

diff --git a/Makefile.dep b/Makefile.dep
index 86dbc62bd9..342a8aa204 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -549,8 +549,8 @@ ifneq (,$(filter netstats_%, $(USEMODULE)))
 endif
 
 ifneq (,$(filter gnrc_lwmac,$(USEMODULE)))
+  USEMODULE += gnrc_netif2
   USEMODULE += gnrc_mac
-  USEMODULE += gnrc_netdev
   FEATURES_REQUIRED += periph_rtt
 endif
 
diff --git a/sys/auto_init/netif/auto_init_at86rf2xx.c b/sys/auto_init/netif/auto_init_at86rf2xx.c
index e49d355faa..803e317665 100644
--- a/sys/auto_init/netif/auto_init_at86rf2xx.c
+++ b/sys/auto_init/netif/auto_init_at86rf2xx.c
@@ -61,10 +61,17 @@ void auto_init_at86rf2xx(void)
 
         at86rf2xx_setup(&at86rf2xx_devs[i], &at86rf2xx_params[i]);
 #ifdef MODULE_GNRC_NETIF2
+#ifdef MODULE_GNRC_LWMAC
+        gnrc_netif2_lwmac_create(_at86rf2xx_stacks[i],
+                                 AT86RF2XX_MAC_STACKSIZE,
+                                 AT86RF2XX_MAC_PRIO, "at86rf2xx-lwmac",
+                                 (netdev_t *)&at86rf2xx_devs[i]);
+#else
         gnrc_netif2_ieee802154_create(_at86rf2xx_stacks[i],
                                       AT86RF2XX_MAC_STACKSIZE,
                                       AT86RF2XX_MAC_PRIO, "at86rf2xx",
                                       (netdev_t *)&at86rf2xx_devs[i]);
+#endif
 #else
         int res = gnrc_netdev_ieee802154_init(&gnrc_adpt[i],
                                               (netdev_ieee802154_t *)&at86rf2xx_devs[i]);
@@ -73,19 +80,11 @@ void auto_init_at86rf2xx(void)
             LOG_ERROR("[auto_init_netif] error initializing at86rf2xx radio #%u\n", i);
         }
         else {
-#ifdef MODULE_GNRC_LWMAC
-            gnrc_lwmac_init(_at86rf2xx_stacks[i],
-                            AT86RF2XX_MAC_STACKSIZE,
-                            AT86RF2XX_MAC_PRIO,
-                            "at86rf2xx-lwmac",
-                            &gnrc_adpt[i]);
-#else
             gnrc_netdev_init(_at86rf2xx_stacks[i],
                              AT86RF2XX_MAC_STACKSIZE,
                              AT86RF2XX_MAC_PRIO,
                              "at86rf2xx",
                              &gnrc_adpt[i]);
-#endif
         }
 #endif
     }
diff --git a/sys/include/net/gnrc/lwmac/hdr.h b/sys/include/net/gnrc/lwmac/hdr.h
index 08fd018a3f..b599604bdc 100644
--- a/sys/include/net/gnrc/lwmac/hdr.h
+++ b/sys/include/net/gnrc/lwmac/hdr.h
@@ -59,8 +59,8 @@ extern "C" {
  * @brief   LWMAC internal L2 address structure
  */
 typedef struct {
-    uint8_t addr[IEEE802154_LONG_ADDRESS_LEN]; /**< address of node */
-    uint8_t len;                               /**< address */
+    uint8_t addr[IEEE802154_LONG_ADDRESS_LEN];  /**< address of node */
+    uint8_t len;                                /**< address */
 } gnrc_lwmac_l2_addr_t;
 
 /**
@@ -79,25 +79,25 @@ typedef struct {
  * @brief   LWMAC WR (wake-up request packet, i.e., preamble packet) frame
  */
 typedef struct __attribute__((packed)) {
-    gnrc_lwmac_hdr_t header;       /**< WR packet header type */
-    gnrc_lwmac_l2_addr_t dst_addr; /**< WR is broadcast, so destination address needed */
+    gnrc_lwmac_hdr_t header;        /**< WR packet header type */
+    gnrc_lwmac_l2_addr_t dst_addr;  /**< WR is broadcast, so destination address needed */
 } gnrc_lwmac_frame_wr_t;
 
 /**
  * @brief   LWMAC WA (wake-up answer packet, i.e., preamble-ACK packet) frame
  */
 typedef struct __attribute__((packed)) {
-    gnrc_lwmac_hdr_t header;       /**< WA packet header type */
-    gnrc_lwmac_l2_addr_t dst_addr; /**< WA is broadcast, so destination address needed */
-    uint32_t current_phase;        /**< Node's current phase value */
+    gnrc_lwmac_hdr_t header;        /**< WA packet header type */
+    gnrc_lwmac_l2_addr_t dst_addr;  /**< WA is broadcast, so destination address needed */
+    uint32_t current_phase;         /**< Node's current phase value */
 } gnrc_lwmac_frame_wa_t;
 
 /**
  * @brief   LWMAC broadcast data frame
  */
 typedef struct __attribute__((packed)) {
-    gnrc_lwmac_hdr_t header; /**< Broadcast packet header type */
-    uint8_t seq_nr;          /**< Broadcast sequence */
+    gnrc_lwmac_hdr_t header;    /**< Broadcast packet header type */
+    uint8_t seq_nr;             /**< Broadcast sequence */
 } gnrc_lwmac_frame_broadcast_t;
 
 /**
diff --git a/sys/include/net/gnrc/lwmac/lwmac.h b/sys/include/net/gnrc/lwmac/lwmac.h
index b682da4c6e..081a6deb87 100644
--- a/sys/include/net/gnrc/lwmac/lwmac.h
+++ b/sys/include/net/gnrc/lwmac/lwmac.h
@@ -74,7 +74,7 @@
 #define NET_GNRC_LWMAC_LWMAC_H
 
 #include "kernel_types.h"
-#include "net/gnrc/netdev.h"
+#include "net/gnrc/netif2.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -95,7 +95,7 @@ extern "C" {
  * In LWMAC, by default, we regard the wake-up period as the beginning of a cycle.
  */
 #ifndef GNRC_LWMAC_WAKEUP_INTERVAL_US
-#define GNRC_LWMAC_WAKEUP_INTERVAL_US        (100LU * US_PER_MS)
+#define GNRC_LWMAC_WAKEUP_INTERVAL_US        (200LU *US_PER_MS)
 #endif
 
 /**
@@ -110,7 +110,7 @@ extern "C" {
  * @ref GNRC_LWMAC_WAKEUP_INTERVAL_US.
  */
 #ifndef GNRC_LWMAC_PREAMBLE_DURATION_US
-#define GNRC_LWMAC_PREAMBLE_DURATION_US      ((13LU * GNRC_LWMAC_WAKEUP_INTERVAL_US) / 10)
+#define GNRC_LWMAC_PREAMBLE_DURATION_US      ((13LU *GNRC_LWMAC_WAKEUP_INTERVAL_US) / 10)
 #endif
 
 /**
@@ -129,7 +129,7 @@ extern "C" {
  * send a WR with the given hardware (including processor) and data rate.
  */
 #ifndef GNRC_LWMAC_TIME_BETWEEN_WR_US
-#define GNRC_LWMAC_TIME_BETWEEN_WR_US        (5U * US_PER_MS)
+#define GNRC_LWMAC_TIME_BETWEEN_WR_US        (5U *US_PER_MS)
 #endif
 
 /**
@@ -187,7 +187,7 @@ extern "C" {
  * period of the receiver, otherwise will lead to a long WR procedure.
  */
 #ifndef GNRC_LWMAC_WR_PREPARATION_US
-#define GNRC_LWMAC_WR_PREPARATION_US         ((3U * US_PER_MS))
+#define GNRC_LWMAC_WR_PREPARATION_US         ((3U *US_PER_MS))
 #endif
 
 /**
@@ -207,7 +207,7 @@ extern "C" {
  * supports @ref NETDEV_EVENT_RX_STARTED event (this can be important for big packets).
  */
 #ifndef GNRC_LWMAC_DATA_DELAY_US
-#define GNRC_LWMAC_DATA_DELAY_US             (10U * US_PER_MS)
+#define GNRC_LWMAC_DATA_DELAY_US             (10U *US_PER_MS)
 #endif
 
 /**
@@ -298,24 +298,22 @@ extern "C" {
 #endif
 
 /**
- * @brief Initialize an instance of the LWMAC layer
+ * @brief   Creates an IEEE 802.15.4 LWMAC network interface
  *
- * The initialization starts a new thread that connects to the given netdev
- * device and starts a link layer event loop.
+ * @param[in] stack     The stack for the LWMAC network interface's thread.
+ * @param[in] stacksize Size of @p stack.
+ * @param[in] priority  Priority for the LWMAC network interface's thread.
+ * @param[in] name      Name for the LWMAC network interface. May be NULL.
+ * @param[in] dev       Device for the interface
  *
- * @param[in] stack         stack for the control thread
- * @param[in] stacksize     size of *stack*
- * @param[in] priority      priority for the thread housing the LWMAC instance
- * @param[in] name          name of the thread housing the LWMAC instance
- * @param[in] dev           netdev device, needs to be already initialized
+ * @see @ref gnrc_netif2_create()
  *
- * @return                  PID of LWMAC thread on success
- * @return                  -EINVAL if creation of thread fails
- * @return                  -ENODEV if *dev* is invalid
+ * @return  The network interface on success.
+ * @return  NULL, on error.
  */
-kernel_pid_t gnrc_lwmac_init(char *stack, int stacksize, char priority,
-                             const char *name, gnrc_netdev_t *dev);
-
+gnrc_netif2_t *gnrc_netif2_lwmac_create(char *stack, int stacksize,
+                                        char priority, char *name,
+                                        netdev_t *dev);
 #ifdef __cplusplus
 }
 #endif
diff --git a/sys/include/net/gnrc/lwmac/timeout.h b/sys/include/net/gnrc/lwmac/timeout.h
index 0a664b9dea..b3118e31bf 100644
--- a/sys/include/net/gnrc/lwmac/timeout.h
+++ b/sys/include/net/gnrc/lwmac/timeout.h
@@ -25,7 +25,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 
-#include "net/gnrc/netdev.h"
+#include "net/gnrc/netif2.h"
 #include "net/gnrc/lwmac/types.h"
 
 #ifdef __cplusplus
@@ -40,52 +40,52 @@ extern "C" {
 /**
  * @brief   Set LWMAC timeout of type @p type of offset @p offset.
  *
- * @param[in,out] gnrc_netdev  gnrc_netdev structure
+ * @param[in,out] netif        the network interface
  * @param[in]     type         LWMAC timeout type
  * @param[in]     offset       timeout offset
  */
-void gnrc_lwmac_set_timeout(gnrc_netdev_t *gnrc_netdev,
+void gnrc_lwmac_set_timeout(gnrc_netif2_t *netif,
                             gnrc_lwmac_timeout_type_t type,
                             uint32_t offset);
 
 /**
  * @brief   Clear LWMAC timeout of type @p type.
  *
- * @param[in,out] gnrc_netdev  gnrc_netdev structure
+ * @param[in,out] netif        the network interface
  * @param[in]     type         LWMAC timeout type
  */
-void gnrc_lwmac_clear_timeout(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_timeout_type_t type);
+void gnrc_lwmac_clear_timeout(gnrc_netif2_t *netif, gnrc_lwmac_timeout_type_t type);
 
 /**
  * @brief   Check whether LWMAC timeout of type @p type is running.
  *
- * @param[in]     gnrc_netdev  gnrc_netdev structure
+ * @param[in]     netif        the network interface
  * @param[in]     type         LWMAC timeout type
  *
  * @return        true, if timeout of type @p type is running.
  * @return        false, if timeout of type @p type is not running.
  */
-bool gnrc_lwmac_timeout_is_running(gnrc_netdev_t *gnrc_netdev,
+bool gnrc_lwmac_timeout_is_running(gnrc_netif2_t *netif,
                                    gnrc_lwmac_timeout_type_t type);
 
 /**
  * @brief   Check whether LWMAC timeout of type @p type is expired. It will clear
  *          the timeout once it is found expired.
  *
- * @param[in,out] gnrc_netdev  gnrc_netdev structure
+ * @param[in,out] netif        the network interface
  * @param[in]     type         LWMAC timeout type
  *
  * @return        true, if timeout of type @p type is expired.
  * @return        false, if timeout of type @p type is not expired, or not exist.
  */
-bool gnrc_lwmac_timeout_is_expired(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_timeout_type_t type);
+bool gnrc_lwmac_timeout_is_expired(gnrc_netif2_t *netif, gnrc_lwmac_timeout_type_t type);
 
 /**
  * @brief   Reset all LWMAC timeouts.
  *
- * @param[in,out] gnrc_netdev  gnrc_netdev structure
+ * @param[in,out] netif        the network interface
  */
-void gnrc_lwmac_reset_timeouts(gnrc_netdev_t *gnrc_netdev);
+void gnrc_lwmac_reset_timeouts(gnrc_netif2_t *netif);
 
 /**
  * @brief   Make a specific LWMAC timeout expired.
diff --git a/sys/include/net/gnrc/lwmac/types.h b/sys/include/net/gnrc/lwmac/types.h
index 4d2e03815e..2185a4ee9b 100644
--- a/sys/include/net/gnrc/lwmac/types.h
+++ b/sys/include/net/gnrc/lwmac/types.h
@@ -109,32 +109,32 @@ extern "C" {
  * @brief   Internal states of LWMAC
  */
 typedef enum {
-    GNRC_LWMAC_UNDEF = -1,     /**< Undefined state of LWMAC */
-    GNRC_LWMAC_STOPPED,        /**< LWMAC's main state machine has been stopped */
-    GNRC_LWMAC_START,          /**< Start LWMAC's main state machine */
-    GNRC_LWMAC_STOP,           /**< Stop LWMAC's main state machine */
-    GNRC_LWMAC_RESET,          /**< Reset LWMAC's main state machine */
-    GNRC_LWMAC_LISTENING,      /**< Listen the channel for receiving packets */
-    GNRC_LWMAC_RECEIVING,      /**< RX is handled in own state machine */
-    GNRC_LWMAC_TRANSMITTING,   /**< TX is handled in own state machine */
-    GNRC_LWMAC_SLEEPING,       /**< Turn off radio to conserve power */
-    GNRC_LWMAC_STATE_COUNT     /**< Count of LWMAC's states */
+    GNRC_LWMAC_UNDEF = -1,      /**< Undefined state of LWMAC */
+    GNRC_LWMAC_STOPPED,         /**< LWMAC's main state machine has been stopped */
+    GNRC_LWMAC_START,           /**< Start LWMAC's main state machine */
+    GNRC_LWMAC_STOP,            /**< Stop LWMAC's main state machine */
+    GNRC_LWMAC_RESET,           /**< Reset LWMAC's main state machine */
+    GNRC_LWMAC_LISTENING,       /**< Listen the channel for receiving packets */
+    GNRC_LWMAC_RECEIVING,       /**< RX is handled in own state machine */
+    GNRC_LWMAC_TRANSMITTING,    /**< TX is handled in own state machine */
+    GNRC_LWMAC_SLEEPING,        /**< Turn off radio to conserve power */
+    GNRC_LWMAC_STATE_COUNT      /**< Count of LWMAC's states */
 } gnrc_lwmac_state_t;
 
 /**
  * @brief   TX states of LWMAC
  */
 typedef enum {
-    GNRC_LWMAC_TX_STATE_STOPPED,           /**< Tx schedule stopped, stop sending packet */
-    GNRC_LWMAC_TX_STATE_INIT,              /**< Initiate transmission */
-    GNRC_LWMAC_TX_STATE_SEND_BROADCAST,    /**< directly goes to SUCCESSFUL or FAILED when finished */
-    GNRC_LWMAC_TX_STATE_SEND_WR,           /**< Send a wakeup request */
-    GNRC_LWMAC_TX_STATE_WAIT_WR_SENT,      /**< Wait until WR sent to set timeout */
-    GNRC_LWMAC_TX_STATE_WAIT_FOR_WA,       /**< Wait for dest node's wakeup ackknowledge */
-    GNRC_LWMAC_TX_STATE_SEND_DATA,         /**< Send the actual payload data */
-    GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK,     /**< Wait if packet was ACKed */
-    GNRC_LWMAC_TX_STATE_SUCCESSFUL,        /**< Transmission has finished successfully */
-    GNRC_LWMAC_TX_STATE_FAILED             /**< Payload data couldn't be delivered to dest */
+    GNRC_LWMAC_TX_STATE_STOPPED,            /**< Tx schedule stopped, stop sending packet */
+    GNRC_LWMAC_TX_STATE_INIT,               /**< Initiate transmission */
+    GNRC_LWMAC_TX_STATE_SEND_BROADCAST,     /**< directly goes to SUCCESSFUL or FAILED when finished */
+    GNRC_LWMAC_TX_STATE_SEND_WR,            /**< Send a wakeup request */
+    GNRC_LWMAC_TX_STATE_WAIT_WR_SENT,       /**< Wait until WR sent to set timeout */
+    GNRC_LWMAC_TX_STATE_WAIT_FOR_WA,        /**< Wait for dest node's wakeup ackknowledge */
+    GNRC_LWMAC_TX_STATE_SEND_DATA,          /**< Send the actual payload data */
+    GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK,      /**< Wait if packet was ACKed */
+    GNRC_LWMAC_TX_STATE_SUCCESSFUL,         /**< Transmission has finished successfully */
+    GNRC_LWMAC_TX_STATE_FAILED              /**< Payload data couldn't be delivered to dest */
 } gnrc_lwmac_tx_state_t;
 
 /**
@@ -146,14 +146,14 @@ typedef enum {
  * @brief   RX states of LWMAC
  */
 typedef enum {
-    GNRC_LWMAC_RX_STATE_STOPPED,       /**< Rx schedule stopped */
-    GNRC_LWMAC_RX_STATE_INIT,          /**< Initiate reception */
-    GNRC_LWMAC_RX_STATE_WAIT_FOR_WR,   /**< Wait for a wakeup request */
-    GNRC_LWMAC_RX_STATE_SEND_WA,       /**< Send wakeup ackknowledge to requesting node */
-    GNRC_LWMAC_RX_STATE_WAIT_WA_SENT,  /**< Wait until WA sent to set timeout */
-    GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA, /**< Wait for actual payload data */
-    GNRC_LWMAC_RX_STATE_SUCCESSFUL,    /**< Recption has finished successfully */
-    GNRC_LWMAC_RX_STATE_FAILED         /**< Reception over, but nothing received */
+    GNRC_LWMAC_RX_STATE_STOPPED,        /**< Rx schedule stopped */
+    GNRC_LWMAC_RX_STATE_INIT,           /**< Initiate reception */
+    GNRC_LWMAC_RX_STATE_WAIT_FOR_WR,    /**< Wait for a wakeup request */
+    GNRC_LWMAC_RX_STATE_SEND_WA,        /**< Send wakeup ackknowledge to requesting node */
+    GNRC_LWMAC_RX_STATE_WAIT_WA_SENT,   /**< Wait until WA sent to set timeout */
+    GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA,  /**< Wait for actual payload data */
+    GNRC_LWMAC_RX_STATE_SUCCESSFUL,     /**< Recption has finished successfully */
+    GNRC_LWMAC_RX_STATE_FAILED          /**< Reception over, but nothing received */
 } gnrc_lwmac_rx_state_t;
 
 /**
@@ -175,14 +175,14 @@ typedef enum {
  * @brief   LWMAC timeout types
  */
 typedef enum {
-    GNRC_LWMAC_TIMEOUT_DISABLED,              /**< Timeout is diabled */
-    GNRC_LWMAC_TIMEOUT_WR,                    /**< WR timeout, waiting WA */
-    GNRC_LWMAC_TIMEOUT_NO_RESPONSE,           /**< Maximum WR duration timeout awaiting WA */
-    GNRC_LWMAC_TIMEOUT_DATA,                  /**< Timeout awaiting data packet from receiver */
-    GNRC_LWMAC_TIMEOUT_WAIT_DEST_WAKEUP,      /**< Timeout for waiting receiver's wake-up phase */
-    GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD,         /**< Wake up period timeout for going to sleep */
-    GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST,        /**< Timeout for waiting to send the next broadcast packet */
-    GNRC_LWMAC_TIMEOUT_BROADCAST_END,         /**< Timeout awaiting the end of the whole broadcast period */
+    GNRC_LWMAC_TIMEOUT_DISABLED,                /**< Timeout is diabled */
+    GNRC_LWMAC_TIMEOUT_WR,                      /**< WR timeout, waiting WA */
+    GNRC_LWMAC_TIMEOUT_NO_RESPONSE,             /**< Maximum WR duration timeout awaiting WA */
+    GNRC_LWMAC_TIMEOUT_DATA,                    /**< Timeout awaiting data packet from receiver */
+    GNRC_LWMAC_TIMEOUT_WAIT_DEST_WAKEUP,        /**< Timeout for waiting receiver's wake-up phase */
+    GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD,           /**< Wake up period timeout for going to sleep */
+    GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST,          /**< Timeout for waiting to send the next broadcast packet */
+    GNRC_LWMAC_TIMEOUT_BROADCAST_END,           /**< Timeout awaiting the end of the whole broadcast period */
 } gnrc_lwmac_timeout_type_t;
 
 /**
@@ -199,19 +199,19 @@ typedef struct {
  * @brief   LWMAC specific structure for storing internal states.
  */
 typedef struct lwmac {
-    gnrc_lwmac_state_t state;                                /**< Internal state of MAC layer */
-    uint32_t last_wakeup;                                    /**< Used to calculate wakeup times */
-    uint8_t lwmac_info;                                      /**< LWMAC's internal informations (flags) */
-    gnrc_lwmac_timeout_t timeouts[GNRC_LWMAC_TIMEOUT_COUNT]; /**< Store timeouts used for protocol */
+    gnrc_lwmac_state_t state;                                   /**< Internal state of MAC layer */
+    uint32_t last_wakeup;                                       /**< Used to calculate wakeup times */
+    uint8_t lwmac_info;                                         /**< LWMAC's internal informations (flags) */
+    gnrc_lwmac_timeout_t timeouts[GNRC_LWMAC_TIMEOUT_COUNT];    /**< Store timeouts used for protocol */
 
 #if (GNRC_LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
     /* Parameters for recording duty-cycle */
-    uint32_t last_radio_on_time_ticks;                       /**< The last time in ticks when radio is on */
-    uint32_t radio_off_time_ticks;                           /**< The time in ticks when radio is off */
-    uint32_t system_start_time_ticks;                        /**< The time in ticks when chip is started */
-    uint32_t awake_duration_sum_ticks;                       /**< The sum of time in ticks when radio is on */
-    uint32_t pkt_start_sending_time_ticks;                   /**< The time in ticks when the packet is started
-                                                                  to be sent */
+    uint32_t last_radio_on_time_ticks;                          /**< The last time in ticks when radio is on */
+    uint32_t radio_off_time_ticks;                              /**< The time in ticks when radio is off */
+    uint32_t system_start_time_ticks;                           /**< The time in ticks when chip is started */
+    uint32_t awake_duration_sum_ticks;                          /**< The sum of time in ticks when radio is on */
+    uint32_t pkt_start_sending_time_ticks;                      /**< The time in ticks when the packet is started
+                                                                     to be sent */
 #endif
 } gnrc_lwmac_t;
 
diff --git a/sys/include/net/gnrc/mac/internal.h b/sys/include/net/gnrc/mac/internal.h
index a9dd8924e3..3c7f8f64b9 100644
--- a/sys/include/net/gnrc/mac/internal.h
+++ b/sys/include/net/gnrc/mac/internal.h
@@ -25,11 +25,76 @@
 
 #include "net/ieee802154.h"
 #include "net/gnrc/mac/types.h"
+#include "net/gnrc/netif2.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/**
+ * @brief get the 'rx_started' state of the device
+ *
+ * This function checks whether the device has started receiving a packet.
+ *
+ * @param[in] netif the network interface
+ *
+ * @return          the rx_started state
+ */
+static inline bool gnrc_netif2_get_rx_started(gnrc_netif2_t *netif)
+{
+    return (netif->mac.mac_info & GNRC_NETIF2_MAC_INFO_RX_STARTED);
+}
+
+/**
+ * @brief set the rx_started state of the device
+ *
+ * This function is intended to be called only in netdev_t::event_callback().
+ *
+ * @param[in] netif       the network interface
+ * @param[in] rx_started  the rx_started state
+ */
+static inline void gnrc_netif2_set_rx_started(gnrc_netif2_t *netif, bool rx_started)
+{
+    if (rx_started) {
+        netif->mac.mac_info |= GNRC_NETIF2_MAC_INFO_RX_STARTED;
+    }
+    else {
+        netif->mac.mac_info &= ~GNRC_NETIF2_MAC_INFO_RX_STARTED;
+    }
+}
+
+/**
+ * @brief get the transmission feedback of the device
+ *
+ * @param[in] netif  the network interface
+ *
+ * @return           the transmission feedback
+ */
+static inline gnrc_mac_tx_feedback_t gnrc_netif2_get_tx_feedback(gnrc_netif2_t *netif)
+{
+    return (gnrc_mac_tx_feedback_t)(netif->mac.mac_info &
+                                    GNRC_NETIF2_MAC_INFO_TX_FEEDBACK_MASK);
+}
+
+/**
+ * @brief set the transmission feedback of the device
+ *
+ * This function is intended to be called only in netdev_t::event_callback().
+ *
+ * @param[in] netif  the network interface
+ * @param[in] txf    the transmission feedback
+ */
+static inline void gnrc_netif2_set_tx_feedback(gnrc_netif2_t *netif,
+                                               gnrc_mac_tx_feedback_t txf)
+{
+    /* check if gnrc_mac_tx_feedback does not collide with
+     * GNRC_NETIF2_MAC_INFO_RX_STARTED */
+    assert(!(txf & GNRC_NETIF2_MAC_INFO_RX_STARTED));
+    /* unset previous value */
+    netif->mac.mac_info &= ~GNRC_NETIF2_MAC_INFO_TX_FEEDBACK_MASK;
+    netif->mac.mac_info |= (uint16_t)(txf & GNRC_NETIF2_MAC_INFO_TX_FEEDBACK_MASK);
+}
+
 #if (GNRC_MAC_TX_QUEUE_SIZE != 0) || defined(DOXYGEN)
 /**
  * @brief Queues the packet into the related transmission packet queue in netdev_t::tx.
diff --git a/sys/include/net/gnrc/netif2/mac.h b/sys/include/net/gnrc/netif2/mac.h
index 8aed068f3f..08dc954253 100644
--- a/sys/include/net/gnrc/netif2/mac.h
+++ b/sys/include/net/gnrc/netif2/mac.h
@@ -19,15 +19,46 @@
 #define NET_GNRC_NETIF2_MAC_H
 
 #include "net/gnrc/mac/types.h"
+#include "net/csma_sender.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/**
+ * @brief   Mask for @ref gnrc_mac_tx_feedback_t
+ */
+#define GNRC_NETIF2_MAC_INFO_TX_FEEDBACK_MASK   (0x0003U)
+
+/**
+ * @brief   Flag to track if a transmission might have corrupted a received
+ *          packet
+ */
+#define GNRC_NETIF2_MAC_INFO_RX_STARTED         (0x0004U)
+
+/**
+ * @brief   Flag to track if a device has enabled CSMA for transmissions
+ *
+ * In case the device doesn't support on-chip CSMA and this flag is set for
+ * requiring CSMA transmission, then, the device will run software CSMA
+ * using `csma_sender` APIs.
+ */
+#define GNRC_NETIF2_MAC_INFO_CSMA_ENABLED       (0x0100U)
+
 /**
  * @brief   @ref net_gnrc_mac component of @ref gnrc_netif2_mac_t
  */
 typedef struct {
+    /**
+     * @brief general information for the MAC protocol
+     */
+    uint16_t mac_info;
+
+    /**
+     * @brief device's software CSMA configuration
+     */
+    csma_sender_conf_t csma_conf;
+
 #if ((GNRC_MAC_RX_QUEUE_SIZE != 0) || (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0)) || DOXYGEN
     /**
      * @brief MAC internal object which stores reception parameters, queues, and
@@ -48,6 +79,13 @@ typedef struct {
      */
     gnrc_mac_tx_t tx;
 #endif  /* ((GNRC_MAC_TX_QUEUE_SIZE != 0) || (GNRC_MAC_NEIGHBOR_COUNT == 0)) || DOXYGEN */
+
+#ifdef MODULE_GNRC_LWMAC
+    /**
+     * @brief LWMAC specific structure object for storing LWMAC internal states.
+     */
+    gnrc_lwmac_t lwmac;
+#endif
 } gnrc_netif2_mac_t;
 
 #ifdef __cplusplus
diff --git a/sys/net/gnrc/link_layer/lwmac/include/lwmac_internal.h b/sys/net/gnrc/link_layer/lwmac/include/lwmac_internal.h
index 88a5a1e397..7103c635a5 100644
--- a/sys/net/gnrc/link_layer/lwmac/include/lwmac_internal.h
+++ b/sys/net/gnrc/link_layer/lwmac/include/lwmac_internal.h
@@ -24,7 +24,7 @@
 #include <stdint.h>
 
 #include "periph/rtt.h"
-#include "net/gnrc/netdev.h"
+#include "net/gnrc/netif2.h"
 #include "net/gnrc/mac/types.h"
 #include "net/gnrc/lwmac/types.h"
 
@@ -41,7 +41,7 @@ extern "C" {
  * successively transmit its packets back to back with this flag set up,
  * with the awareness that the receiver will also keep awake for receptions.
  */
-#define GNRC_NETDEV_LWMAC_TX_CONTINUE          (0x0008U)
+#define GNRC_LWMAC_TX_CONTINUE          (0x0008U)
 
 /**
  * @brief   Flag to track if the sender should quit Tx in current cycle.
@@ -53,7 +53,7 @@ extern "C" {
  * cycle (started by the wake-up period), thus not to collide with other
  * (neighbor) nodes' transmissions.
  */
-#define GNRC_NETDEV_LWMAC_QUIT_TX              (0x0010U)
+#define GNRC_LWMAC_QUIT_TX              (0x0010U)
 
 /**
  * @brief   Flag to track if the device need to reselect a new wake-up phase.
@@ -65,7 +65,7 @@ extern "C" {
  * sender finds its phase close to its receiver's, it sets up this flag and then
  * randomly reselects a new wake-up phase.
  */
-#define GNRC_NETDEV_LWMAC_PHASE_BACKOFF        (0x0020U)
+#define GNRC_LWMAC_PHASE_BACKOFF        (0x0020U)
 
 /**
  * @brief   Flag to track if the device needs to quit the wake-up (listening) procedure.
@@ -78,15 +78,15 @@ extern "C" {
  * should immediately goto sleep (by setting up this flag) after one reception, thus not
  * to receive duplicate broadcast packets.
  */
-#define GNRC_NETDEV_LWMAC_QUIT_RX              (0x0040U)
+#define GNRC_LWMAC_QUIT_RX              (0x0040U)
 
 /**
  * @brief Type to pass information about parsing.
  */
 typedef struct {
-    gnrc_lwmac_hdr_t *header;      /**< LWMAC header of packet */
-    gnrc_lwmac_l2_addr_t src_addr; /**< copied source address of packet  */
-    gnrc_lwmac_l2_addr_t dst_addr; /**< copied destination address of packet */
+    gnrc_lwmac_hdr_t *header;       /**< LWMAC header of packet */
+    gnrc_lwmac_l2_addr_t src_addr;  /**< copied source address of packet  */
+    gnrc_lwmac_l2_addr_t dst_addr;  /**< copied destination address of packet */
 } gnrc_lwmac_packet_info_t;
 
 /**
@@ -98,185 +98,209 @@ typedef struct {
 #define GNRC_LWMAC_RTT_EVENT_MARGIN_TICKS    (RTT_MS_TO_TICKS(2))
 
 /**
- * @brief set the TX-continue flag of the device
+ * @brief set the @ref GNRC_LWMAC_TX_CONTINUE flag of the device
  *
- * @param[in] dev          ptr to netdev device
+ * @param[in] netif        ptr to the network interface
  * @param[in] tx_continue  value for LWMAC tx-continue flag
  *
  */
-static inline void gnrc_netdev_lwmac_set_tx_continue(gnrc_netdev_t *dev, bool tx_continue)
+static inline void gnrc_lwmac_set_tx_continue(gnrc_netif2_t *netif, bool tx_continue)
 {
     if (tx_continue) {
-        dev->mac_info |= GNRC_NETDEV_LWMAC_TX_CONTINUE;
+        netif->mac.mac_info |= GNRC_LWMAC_TX_CONTINUE;
     }
     else {
-        dev->mac_info &= ~GNRC_NETDEV_LWMAC_TX_CONTINUE;
+        netif->mac.mac_info &= ~GNRC_LWMAC_TX_CONTINUE;
     }
 }
 
 /**
- * @brief get the TX-continue flag of the device
+ * @brief get the @ref GNRC_LWMAC_TX_CONTINUE flag of the device
  *
- * @param[in] dev          ptr to netdev device
+ * @param[in] netif        ptr to the network interface
  *
  * @return                 true if tx continue
- * @return                 false if tx will continue
+ * @return                 false if tx will not continue
  */
-static inline bool gnrc_netdev_lwmac_get_tx_continue(gnrc_netdev_t *dev)
+static inline bool gnrc_lwmac_get_tx_continue(gnrc_netif2_t *netif)
 {
-    return (dev->mac_info & GNRC_NETDEV_LWMAC_TX_CONTINUE);
+    return (netif->mac.mac_info & GNRC_LWMAC_TX_CONTINUE);
 }
 
 /**
- * @brief set the quit-TX flag of the device
+ * @brief set the @ref GNRC_LWMAC_QUIT_TX flag of the device
  *
- * @param[in] dev          ptr to netdev device
- * @param[in] quit_tx      value for LWMAC quit-TX flag
+ * @param[in] netif        ptr to the network interface
+ * @param[in] quit_tx      value for @ref GNRC_LWMAC_QUIT_TX flag
  *
  */
-static inline void gnrc_netdev_lwmac_set_quit_tx(gnrc_netdev_t *dev, bool quit_tx)
+static inline void gnrc_lwmac_set_quit_tx(gnrc_netif2_t *netif, bool quit_tx)
 {
     if (quit_tx) {
-        dev->mac_info |= GNRC_NETDEV_LWMAC_QUIT_TX;
+        netif->mac.mac_info |= GNRC_LWMAC_QUIT_TX;
     }
     else {
-        dev->mac_info &= ~GNRC_NETDEV_LWMAC_QUIT_TX;
+        netif->mac.mac_info &= ~GNRC_LWMAC_QUIT_TX;
     }
 }
 
 /**
- * @brief get the quit-TX flag of the device
+ * @brief get the @ref GNRC_LWMAC_QUIT_TX flag of the device
  *
- * @param[in] dev          ptr to netdev device
+ * @param[in] netif        ptr to the network interface
  *
  * @return                 true if quit tx
  * @return                 false if will not quit tx
  */
-static inline bool gnrc_netdev_lwmac_get_quit_tx(gnrc_netdev_t *dev)
+static inline bool gnrc_lwmac_get_quit_tx(gnrc_netif2_t *netif)
 {
-    return (dev->mac_info & GNRC_NETDEV_LWMAC_QUIT_TX);
+    return (netif->mac.mac_info & GNRC_LWMAC_QUIT_TX);
 }
 
 /**
- * @brief set the phase-backoff flag of the device
+ * @brief set the @ref GNRC_LWMAC_PHASE_BACKOFF flag of the device
  *
- * @param[in] dev          ptr to netdev device
- * @param[in] backoff      value for LWMAC phase-backoff flag
+ * @param[in] netif        ptr to the network interface
+ * @param[in] backoff      value for LWMAC @ref GNRC_LWMAC_PHASE_BACKOFF flag
  *
  */
-static inline void gnrc_netdev_lwmac_set_phase_backoff(gnrc_netdev_t *dev, bool backoff)
+static inline void gnrc_lwmac_set_phase_backoff(gnrc_netif2_t *netif, bool backoff)
 {
     if (backoff) {
-        dev->mac_info |= GNRC_NETDEV_LWMAC_PHASE_BACKOFF;
+        netif->mac.mac_info |= GNRC_LWMAC_PHASE_BACKOFF;
     }
     else {
-        dev->mac_info &= ~GNRC_NETDEV_LWMAC_PHASE_BACKOFF;
+        netif->mac.mac_info &= ~GNRC_LWMAC_PHASE_BACKOFF;
     }
 }
 
 /**
- * @brief get the phase-backoff of the device
+ * @brief get the @ref GNRC_LWMAC_PHASE_BACKOFF flag of the device
  *
- * @param[in] dev          ptr to netdev device
+ * @param[in] netif        ptr to the network interface
  *
  * @return                 true if will run phase-backoff
  * @return                 false if will not run phase-backoff
  */
-static inline bool gnrc_netdev_lwmac_get_phase_backoff(gnrc_netdev_t *dev)
+static inline bool gnrc_lwmac_get_phase_backoff(gnrc_netif2_t *netif)
 {
-    return (dev->mac_info & GNRC_NETDEV_LWMAC_PHASE_BACKOFF);
+    return (netif->mac.mac_info & GNRC_LWMAC_PHASE_BACKOFF);
 }
 
 /**
- * @brief set the quit-RX flag of the device
+ * @brief set the @ref GNRC_LWMAC_QUIT_RX flag of the device
  *
- * @param[in] dev          ptr to netdev device
- * @param[in] quit_rx      value for LWMAC quit-Rx flag
+ * @param[in] netif        ptr to the network interface
+ * @param[in] quit_rx      value for LWMAC @ref GNRC_LWMAC_QUIT_RX flag
  *
  */
-static inline void gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev_t *dev, bool quit_rx)
+static inline void gnrc_lwmac_set_quit_rx(gnrc_netif2_t *netif, bool quit_rx)
 {
     if (quit_rx) {
-        dev->mac_info |= GNRC_NETDEV_LWMAC_QUIT_RX;
+        netif->mac.mac_info |= GNRC_LWMAC_QUIT_RX;
     }
     else {
-        dev->mac_info &= ~GNRC_NETDEV_LWMAC_QUIT_RX;
+        netif->mac.mac_info &= ~GNRC_LWMAC_QUIT_RX;
     }
 }
 
 /**
- * @brief get the quit-RX flag of the device
+ * @brief get the @ref GNRC_LWMAC_QUIT_RX flag of the device
  *
- * @param[in] dev          ptr to netdev device
+ * @param[in] netif        ptr to the network interface
  *
  * @return                 true if will quit rx
  * @return                 false if will not quit rx
  */
-static inline bool gnrc_netdev_lwmac_get_quit_rx(gnrc_netdev_t *dev)
+static inline bool gnrc_lwmac_get_quit_rx(gnrc_netif2_t *netif)
 {
-    return (dev->mac_info & GNRC_NETDEV_LWMAC_QUIT_RX);
+    return (netif->mac.mac_info & GNRC_LWMAC_QUIT_RX);
 }
 
 /**
- * @brief set the duty-cycle-active flag of LWMAC
+ * @brief set the @ref GNRC_LWMAC_DUTYCYCLE_ACTIVE flag of LWMAC
  *
- * @param[in] dev          ptr to netdev device
- * @param[in] active       value for LWMAC duty-cycle-active flag
+ * @param[in] netif        ptr to the network interface
+ * @param[in] active       value for LWMAC @ref GNRC_LWMAC_DUTYCYCLE_ACTIVE flag
  *
  */
-static inline void gnrc_netdev_lwmac_set_dutycycle_active(gnrc_netdev_t *dev, bool active)
+static inline void gnrc_lwmac_set_dutycycle_active(gnrc_netif2_t *netif, bool active)
 {
     if (active) {
-        dev->lwmac.lwmac_info |= GNRC_LWMAC_DUTYCYCLE_ACTIVE;
+        netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_DUTYCYCLE_ACTIVE;
     }
     else {
-        dev->lwmac.lwmac_info &= ~GNRC_LWMAC_DUTYCYCLE_ACTIVE;
+        netif->mac.lwmac.lwmac_info &= ~GNRC_LWMAC_DUTYCYCLE_ACTIVE;
     }
 }
 
 /**
- * @brief get the duty-cycle-active flag of LWMAC
+ * @brief get the @ref GNRC_LWMAC_DUTYCYCLE_ACTIVE flag of LWMAC
  *
- * @param[in] dev          ptr to netdev device
+ * @param[in] netif        ptr to the network interface
  *
  * @return                 true if active
  * @return                 false if not active
  */
-static inline bool gnrc_netdev_lwmac_get_dutycycle_active(gnrc_netdev_t *dev)
+static inline bool gnrc_lwmac_get_dutycycle_active(gnrc_netif2_t *netif)
 {
-    return (dev->lwmac.lwmac_info & GNRC_LWMAC_DUTYCYCLE_ACTIVE);
+    return (netif->mac.lwmac.lwmac_info & GNRC_LWMAC_DUTYCYCLE_ACTIVE);
 }
 
 /**
- * @brief set the needs-rescheduling flag of LWMAC
+ * @brief set the @ref GNRC_LWMAC_NEEDS_RESCHEDULE flag of LWMAC
  *
- * @param[in] dev          ptr to netdev device
- * @param[in] reschedule   value for LWMAC needs-rescheduling flag
+ * @param[in] netif        ptr to the network interface
+ * @param[in] reschedule   value for @ref GNRC_LWMAC_NEEDS_RESCHEDULE flag
  *
  */
-static inline void gnrc_netdev_lwmac_set_reschedule(gnrc_netdev_t *dev, bool reschedule)
+static inline void gnrc_lwmac_set_reschedule(gnrc_netif2_t *netif, bool reschedule)
 {
     if (reschedule) {
-        dev->lwmac.lwmac_info |= GNRC_LWMAC_NEEDS_RESCHEDULE;
+        netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_NEEDS_RESCHEDULE;
     }
     else {
-        dev->lwmac.lwmac_info &= ~GNRC_LWMAC_NEEDS_RESCHEDULE;
+        netif->mac.lwmac.lwmac_info &= ~GNRC_LWMAC_NEEDS_RESCHEDULE;
     }
 }
 
 /**
- * @brief get the needs-rescheduling flag of LWMAC
+ * @brief get the @ref GNRC_LWMAC_NEEDS_RESCHEDULE flag of LWMAC
  *
- * @param[in] dev          ptr to netdev device
+ * @param[in] netif        ptr to the network interface
  *
  * @return                 true if needs rescheduling
  * @return                 false if no need for rescheduling
  */
-static inline bool gnrc_netdev_lwmac_get_reschedule(gnrc_netdev_t *dev)
+static inline bool gnrc_lwmac_get_reschedule(gnrc_netif2_t *netif)
 {
-    return (dev->lwmac.lwmac_info & GNRC_LWMAC_NEEDS_RESCHEDULE);
+    return (netif->mac.lwmac.lwmac_info & GNRC_LWMAC_NEEDS_RESCHEDULE);
 }
 
+/**
+ * @brief send a @ref net_gnrc_pkt "packet" over the network interface in LWMAC
+ *
+ * @internal
+ *
+ * @pre `netif != NULL && pkt != NULL`
+ *
+ * @note The function re-formats the content of @p pkt to a format expected
+ *       by the netdev_driver_t::send() method of gnrc_netif_t::dev and
+ *       releases the packet before returning (so no additional release
+ *       should be required after calling this method).
+ *
+ * @param[in] netif The network interface.
+ * @param[in] pkt   A packet to send.
+ *
+ * @return  The number of bytes actually sent on success
+ * @return  -EBADMSG, if the @ref net_gnrc_netif_hdr in @p pkt is missing
+ *          or is in an unexpected format.
+ * @return  -ENOTSUP, if sending @p pkt in the given format isn't supported
+ *          (e.g. empty payload with Ethernet).
+ * @return  Any negative error code reported by gnrc_netif2_t::dev.
+ */
+int _gnrc_lwmac_transmit(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt);
+
 /**
  * @brief Parse an incoming packet and extract important information.
  *
@@ -293,19 +317,19 @@ int _gnrc_lwmac_parse_packet(gnrc_pktsnip_t *pkt, gnrc_lwmac_packet_info_t *info
 /**
  * @brief Shortcut to get the state of netdev.
  *
- * @param[in]   gnrc_netdev    gnrc_netdev structure
+ * @param[in]   netif    ptr to the network interface
  *
- * @return                     state of netdev
+ * @return               state of netdev
  */
-netopt_state_t _gnrc_lwmac_get_netdev_state(gnrc_netdev_t *gnrc_netdev);
+netopt_state_t _gnrc_lwmac_get_netdev_state(gnrc_netif2_t *netif);
 
 /**
  * @brief Shortcut to set the state of netdev
  *
- * @param[in]   gnrc_netdev    gnrc_netdev structure
- * @param[in]   devstate       new state for netdev
+ * @param[in]   netif       ptr to the network interface
+ * @param[in]   devstate    new state for netdev
  */
-void _gnrc_lwmac_set_netdev_state(gnrc_netdev_t *gnrc_netdev, netopt_state_t devstate);
+void _gnrc_lwmac_set_netdev_state(gnrc_netif2_t *netif, netopt_state_t devstate);
 
 /**
  * @brief Convert RTT ticks to device phase
diff --git a/sys/net/gnrc/link_layer/lwmac/include/rx_state_machine.h b/sys/net/gnrc/link_layer/lwmac/include/rx_state_machine.h
index 4d585e0dad..f045e19133 100644
--- a/sys/net/gnrc/link_layer/lwmac/include/rx_state_machine.h
+++ b/sys/net/gnrc/link_layer/lwmac/include/rx_state_machine.h
@@ -23,7 +23,7 @@
 #define RX_STATE_MACHINE_H
 
 #include "net/gnrc/pkt.h"
-#include "net/gnrc/netdev.h"
+#include "net/gnrc/netif2.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -32,26 +32,26 @@ extern "C" {
 /**
  * @brief Start LWMAC RX procedure to receive packet
  *
- * @param[in,out]   gnrc_netdev   gnrc_netdev structure
+ * @param[in,out]   netif    ptr to the network interface
  *
  */
-void gnrc_lwmac_rx_start(gnrc_netdev_t *gnrc_netdev);
+void gnrc_lwmac_rx_start(gnrc_netif2_t *netif);
 
 /**
  * @brief Stop LWMAC RX procedure
  *
- * @param[in,out]   gnrc_netdev   gnrc_netdev structure
+ * @param[in,out]   netif    ptr to the network interface
  *
  */
-void gnrc_lwmac_rx_stop(gnrc_netdev_t *gnrc_netdev);
+void gnrc_lwmac_rx_stop(gnrc_netif2_t *netif);
 
 /**
  * @brief Update LWMAC RX procedure for packet reception
  *
- * @param[in,out]   gnrc_netdev   gnrc_netdev structure
+ * @param[in,out]   netif    ptr to the network interface
  *
  */
-void gnrc_lwmac_rx_update(gnrc_netdev_t *gnrc_netdev);
+void gnrc_lwmac_rx_update(gnrc_netif2_t *netif);
 
 #ifdef __cplusplus
 }
diff --git a/sys/net/gnrc/link_layer/lwmac/include/tx_state_machine.h b/sys/net/gnrc/link_layer/lwmac/include/tx_state_machine.h
index 4787c23444..f8da8bdc98 100644
--- a/sys/net/gnrc/link_layer/lwmac/include/tx_state_machine.h
+++ b/sys/net/gnrc/link_layer/lwmac/include/tx_state_machine.h
@@ -23,7 +23,7 @@
 #define TX_STATE_MACHINE_H
 
 #include "net/gnrc/pkt.h"
-#include "net/gnrc/netdev.h"
+#include "net/gnrc/netif2.h"
 #include "net/gnrc/mac/types.h"
 
 #ifdef __cplusplus
@@ -33,30 +33,30 @@ extern "C" {
 /**
  * @brief Start LWMAC TX procedure to transmit packet @p pkt to @p neighbor
  *
- * @param[in,out]   gnrc_netdev   gnrc_netdev structure
+ * @param[in,out]   netif         ptr to the network interface
  * @param[in]       pkt           packet to transmit
  * @param[in]       neighbor      Tx neighbor
  *
  */
-void gnrc_lwmac_tx_start(gnrc_netdev_t *gnrc_netdev,
+void gnrc_lwmac_tx_start(gnrc_netif2_t *netif,
                          gnrc_pktsnip_t *pkt,
                          gnrc_mac_tx_neighbor_t *neighbor);
 
 /**
  * @brief Stop LWMAC TX procedure
  *
- * @param[in,out]   gnrc_netdev   gnrc_netdev structure
+ * @param[in,out]   netif    ptr to the network interface
  *
  */
-void gnrc_lwmac_tx_stop(gnrc_netdev_t *gnrc_netdev);
+void gnrc_lwmac_tx_stop(gnrc_netif2_t *netif);
 
 /**
  * @brief Update LWMAC TX procedure for transmission
  *
- * @param[in,out]   gnrc_netdev   gnrc_netdev structure
+ * @param[in,out]   netif    ptr to the network interface
  *
  */
-void gnrc_lwmac_tx_update(gnrc_netdev_t *gnrc_netdev);
+void gnrc_lwmac_tx_update(gnrc_netif2_t *netif);
 
 #ifdef __cplusplus
 }
diff --git a/sys/net/gnrc/link_layer/lwmac/lwmac.c b/sys/net/gnrc/link_layer/lwmac/lwmac.c
index db855afcc1..d9627a0e79 100644
--- a/sys/net/gnrc/link_layer/lwmac/lwmac.c
+++ b/sys/net/gnrc/link_layer/lwmac/lwmac.c
@@ -25,15 +25,13 @@
 #include <stdint.h>
 #include <stdbool.h>
 
-#include "kernel_types.h"
-#include "msg.h"
-#include "thread.h"
 #include "timex.h"
 #include "random.h"
 #include "periph/rtt.h"
-#include "net/gnrc.h"
-#include "net/netdev.h"
-#include "net/gnrc/netdev.h"
+#include "net/gnrc/netif2.h"
+#include "net/gnrc/netif2/internal.h"
+#include "net/gnrc/netif2/ieee802154.h"
+#include "net/netdev/ieee802154.h"
 #include "net/gnrc/lwmac/types.h"
 #include "net/gnrc/lwmac/lwmac.h"
 #include "net/gnrc/mac/internal.h"
@@ -60,22 +58,156 @@
 kernel_pid_t lwmac_pid;
 
 static void rtt_cb(void *arg);
-static void lwmac_set_state(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_state_t newstate);
-static void lwmac_schedule_update(gnrc_netdev_t *gnrc_netdev);
-static void rtt_handler(uint32_t event, gnrc_netdev_t *gnrc_netdev);
+static void lwmac_set_state(gnrc_netif2_t *netif, gnrc_lwmac_state_t newstate);
+static void lwmac_schedule_update(gnrc_netif2_t *netif);
+static void rtt_handler(uint32_t event, gnrc_netif2_t *netif);
+static void _lwmac_init(gnrc_netif2_t *netif);
+static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt);
+static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif);
+static void _lwmac_msg_handler(gnrc_netif2_t *netif, msg_t *msg);
+
+static const gnrc_netif2_ops_t lwmac_ops = {
+    .init = _lwmac_init,
+    .send = _send,
+    .recv = _recv,
+    .get = gnrc_netif2_get_from_netdev,
+    .set = gnrc_netif2_set_from_netdev,
+    .msg_handler = _lwmac_msg_handler,
+};
+
+gnrc_netif2_t *gnrc_netif2_lwmac_create(char *stack, int stacksize,
+                                        char priority, char *name,
+                                        netdev_t *dev)
+{
+    return gnrc_netif2_create(stack, stacksize, priority, name, dev,
+                              &lwmac_ops);
+}
+
+static gnrc_pktsnip_t *_make_netif_hdr(uint8_t *mhr)
+{
+    gnrc_pktsnip_t *snip;
+    uint8_t src[IEEE802154_LONG_ADDRESS_LEN], dst[IEEE802154_LONG_ADDRESS_LEN];
+    int src_len, dst_len;
+    le_uint16_t _pan_tmp;   /* TODO: hand-up PAN IDs to GNRC? */
+
+    dst_len = ieee802154_get_dst(mhr, dst, &_pan_tmp);
+    src_len = ieee802154_get_src(mhr, src, &_pan_tmp);
+    if ((dst_len < 0) || (src_len < 0)) {
+        DEBUG("_make_netif_hdr: unable to get addresses\n");
+        return NULL;
+    }
+    /* allocate space for header */
+    snip = gnrc_netif_hdr_build(src, (size_t)src_len, dst, (size_t)dst_len);
+    if (snip == NULL) {
+        DEBUG("_make_netif_hdr: no space left in packet buffer\n");
+        return NULL;
+    }
+    /* set broadcast flag for broadcast destination */
+    if ((dst_len == 2) && (dst[0] == 0xff) && (dst[1] == 0xff)) {
+        gnrc_netif_hdr_t *hdr = snip->data;
+        hdr->flags |= GNRC_NETIF_HDR_FLAGS_BROADCAST;
+    }
+    return snip;
+}
+
+static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif)
+{
+    netdev_t *dev = netif->dev;
+    netdev_ieee802154_rx_info_t rx_info;
+    netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev;
+    gnrc_pktsnip_t *pkt = NULL;
+    int bytes_expected = dev->driver->recv(dev, NULL, 0, NULL);
+
+    if (bytes_expected > 0) {
+        int nread;
+
+        pkt = gnrc_pktbuf_add(NULL, NULL, bytes_expected, GNRC_NETTYPE_UNDEF);
+        if (pkt == NULL) {
+            DEBUG("_recv_ieee802154: cannot allocate pktsnip.\n");
+            return NULL;
+        }
+        nread = dev->driver->recv(dev, pkt->data, bytes_expected, &rx_info);
+        if (nread <= 0) {
+            gnrc_pktbuf_release(pkt);
+            return NULL;
+        }
+        if (!(state->flags & NETDEV_IEEE802154_RAW)) {
+            gnrc_pktsnip_t *ieee802154_hdr, *netif_hdr;
+            gnrc_netif_hdr_t *hdr;
+#if ENABLE_DEBUG
+            char src_str[GNRC_NETIF_HDR_L2ADDR_PRINT_LEN];
+#endif
+            size_t mhr_len = ieee802154_get_frame_hdr_len(pkt->data);
+
+            if (mhr_len == 0) {
+                DEBUG("_recv_ieee802154: illegally formatted frame received\n");
+                gnrc_pktbuf_release(pkt);
+                return NULL;
+            }
+            nread -= mhr_len;
+            /* mark IEEE 802.15.4 header */
+            ieee802154_hdr = gnrc_pktbuf_mark(pkt, mhr_len, GNRC_NETTYPE_UNDEF);
+            if (ieee802154_hdr == NULL) {
+                DEBUG("_recv_ieee802154: no space left in packet buffer\n");
+                gnrc_pktbuf_release(pkt);
+                return NULL;
+            }
+            netif_hdr = _make_netif_hdr(ieee802154_hdr->data);
+            if (netif_hdr == NULL) {
+                DEBUG("_recv_ieee802154: no space left in packet buffer\n");
+                gnrc_pktbuf_release(pkt);
+                return NULL;
+            }
+
+            hdr = netif_hdr->data;
+
+#ifdef MODULE_L2FILTER
+            if (!l2filter_pass(dev->filter, gnrc_netif_hdr_get_src_addr(hdr),
+                               hdr->src_l2addr_len)) {
+                gnrc_pktbuf_release(pkt);
+                gnrc_pktbuf_release(netif_hdr);
+                DEBUG("_recv_ieee802154: packet dropped by l2filter\n");
+                return NULL;
+            }
+#endif
+
+            hdr->lqi = rx_info.lqi;
+            hdr->rssi = rx_info.rssi;
+            hdr->if_pid = thread_getpid();
+            pkt->type = state->proto;
+#if ENABLE_DEBUG
+            DEBUG("_recv_ieee802154: received packet from %s of length %u\n",
+                  gnrc_netif_addr_to_str(src_str, sizeof(src_str),
+                                         gnrc_netif_hdr_get_src_addr(hdr),
+                                         hdr->src_l2addr_len),
+                  nread);
+#if defined(MODULE_OD)
+            od_hex_dump(pkt->data, nread, OD_WIDTH_DEFAULT);
+#endif
+#endif
+            gnrc_pktbuf_remove_snip(pkt, ieee802154_hdr);
+            LL_APPEND(pkt, netif_hdr);
+        }
+
+        DEBUG("_recv_ieee802154: reallocating.\n");
+        gnrc_pktbuf_realloc_data(pkt, nread);
+    }
+
+    return pkt;
+}
 
-static gnrc_mac_tx_neighbor_t *_next_tx_neighbor(gnrc_netdev_t *gnrc_netdev)
+static gnrc_mac_tx_neighbor_t *_next_tx_neighbor(gnrc_netif2_t *netif)
 {
     int next = -1;
 
     uint32_t phase_nearest = GNRC_LWMAC_PHASE_MAX;
 
     for (int i = 0; i < GNRC_MAC_NEIGHBOR_COUNT; i++) {
-        if (gnrc_priority_pktqueue_length(&gnrc_netdev->tx.neighbors[i].queue) > 0) {
+        if (gnrc_priority_pktqueue_length(&netif->mac.tx.neighbors[i].queue) > 0) {
             /* Unknown destinations are initialized with their phase at the end
              * of the local interval, so known destinations that still wakeup
              * in this interval will be preferred. */
-            uint32_t phase_check = _gnrc_lwmac_ticks_until_phase(gnrc_netdev->tx.neighbors[i].phase);
+            uint32_t phase_check = _gnrc_lwmac_ticks_until_phase(netif->mac.tx.neighbors[i].phase);
 
             if (phase_check <= phase_nearest) {
                 next = i;
@@ -85,7 +217,7 @@ static gnrc_mac_tx_neighbor_t *_next_tx_neighbor(gnrc_netdev_t *gnrc_netdev)
         }
     }
 
-    return (next < 0) ? NULL : &(gnrc_netdev->tx.neighbors[next]);
+    return (next < 0) ? NULL : &(netif->mac.tx.neighbors[next]);
 }
 
 static uint32_t _next_inphase_event(uint32_t last, uint32_t interval)
@@ -107,14 +239,14 @@ static uint32_t _next_inphase_event(uint32_t last, uint32_t interval)
     return last;
 }
 
-inline void lwmac_schedule_update(gnrc_netdev_t *gnrc_netdev)
+inline void lwmac_schedule_update(gnrc_netif2_t *netif)
 {
-    gnrc_netdev_lwmac_set_reschedule(gnrc_netdev, true);
+    gnrc_lwmac_set_reschedule(netif, true);
 }
 
-void lwmac_set_state(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_state_t newstate)
+void lwmac_set_state(gnrc_netif2_t *netif, gnrc_lwmac_state_t newstate)
 {
-    gnrc_lwmac_state_t oldstate = gnrc_netdev->lwmac.state;
+    gnrc_lwmac_state_t oldstate = netif->mac.lwmac.state;
 
     if (newstate == oldstate) {
         return;
@@ -126,26 +258,26 @@ void lwmac_set_state(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_state_t newstate)
     }
 
     /* Already change state, but might be reverted to oldstate when needed */
-    gnrc_netdev->lwmac.state = newstate;
+    netif->mac.lwmac.state = newstate;
 
     /* Actions when leaving old state */
     switch (oldstate) {
         case GNRC_LWMAC_RECEIVING:
         case GNRC_LWMAC_TRANSMITTING: {
             /* Enable duty cycling again */
-            rtt_handler(GNRC_LWMAC_EVENT_RTT_RESUME, gnrc_netdev);
+            rtt_handler(GNRC_LWMAC_EVENT_RTT_RESUME, netif);
 #if (GNRC_LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
             /* Output duty-cycle ratio */
             uint64_t duty;
             duty = (uint64_t) rtt_get_counter();
-            duty = ((uint64_t) gnrc_netdev->lwmac.awake_duration_sum_ticks) * 100 /
-                   (duty - (uint64_t)gnrc_netdev->lwmac.system_start_time_ticks);
+            duty = ((uint64_t) netif->mac.lwmac.awake_duration_sum_ticks) * 100 /
+                   (duty - (uint64_t)netif->mac.lwmac.system_start_time_ticks);
             printf("[LWMAC]: achieved duty-cycle: %lu %% \n", (uint32_t)duty);
 #endif
             break;
         }
         case GNRC_LWMAC_SLEEPING: {
-            gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD);
+            gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD);
             break;
         }
         default:
@@ -156,17 +288,17 @@ void lwmac_set_state(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_state_t newstate)
     switch (newstate) {
         /*********************** Operation states *********************************/
         case GNRC_LWMAC_LISTENING: {
-            _gnrc_lwmac_set_netdev_state(gnrc_netdev, NETOPT_STATE_IDLE);
+            _gnrc_lwmac_set_netdev_state(netif, NETOPT_STATE_IDLE);
             break;
         }
         case GNRC_LWMAC_SLEEPING: {
             /* Put transceiver to sleep */
-            _gnrc_lwmac_set_netdev_state(gnrc_netdev, NETOPT_STATE_SLEEP);
+            _gnrc_lwmac_set_netdev_state(netif, NETOPT_STATE_SLEEP);
             /* We may have come here through RTT handler, so timeout may still be active */
-            gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD);
+            gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD);
 
-            if (gnrc_netdev_lwmac_get_phase_backoff(gnrc_netdev)) {
-                gnrc_netdev_lwmac_set_phase_backoff(gnrc_netdev, false);
+            if (gnrc_lwmac_get_phase_backoff(netif)) {
+                gnrc_lwmac_set_phase_backoff(netif, false);
                 uint32_t alarm;
 
                 rtt_clear_alarm();
@@ -174,8 +306,8 @@ void lwmac_set_state(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_state_t newstate)
                                             RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US -
                                                             (3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2)));
                 LOG_WARNING("WARNING: [LWMAC] phase backoffed: %lu us\n", RTT_TICKS_TO_US(alarm));
-                gnrc_netdev->lwmac.last_wakeup = gnrc_netdev->lwmac.last_wakeup + alarm;
-                alarm = _next_inphase_event(gnrc_netdev->lwmac.last_wakeup,
+                netif->mac.lwmac.last_wakeup = netif->mac.lwmac.last_wakeup + alarm;
+                alarm = _next_inphase_event(netif->mac.lwmac.last_wakeup,
                                             RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US));
                 rtt_set_alarm(alarm, rtt_cb, (void *) GNRC_LWMAC_EVENT_RTT_WAKEUP_PENDING);
             }
@@ -185,35 +317,35 @@ void lwmac_set_state(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_state_t newstate)
         }
         /* Trying to send data */
         case GNRC_LWMAC_TRANSMITTING: {
-            rtt_handler(GNRC_LWMAC_EVENT_RTT_PAUSE, gnrc_netdev);    /**< No duty cycling while RXing */
-            _gnrc_lwmac_set_netdev_state(gnrc_netdev, NETOPT_STATE_IDLE);  /**< Power up netdev */
+            rtt_handler(GNRC_LWMAC_EVENT_RTT_PAUSE, netif);         /**< No duty cycling while RXing */
+            _gnrc_lwmac_set_netdev_state(netif, NETOPT_STATE_IDLE); /**< Power up netdev */
             break;
         }
         /* Receiving incoming data */
         case GNRC_LWMAC_RECEIVING: {
-            rtt_handler(GNRC_LWMAC_EVENT_RTT_PAUSE, gnrc_netdev);    /**< No duty cycling while TXing */
-            _gnrc_lwmac_set_netdev_state(gnrc_netdev, NETOPT_STATE_IDLE);  /**< Power up netdev */
+            rtt_handler(GNRC_LWMAC_EVENT_RTT_PAUSE, netif);         /**< No duty cycling while TXing */
+            _gnrc_lwmac_set_netdev_state(netif, NETOPT_STATE_IDLE); /**< Power up netdev */
             break;
         }
         case GNRC_LWMAC_STOPPED: {
-            _gnrc_lwmac_set_netdev_state(gnrc_netdev, NETOPT_STATE_OFF);
+            _gnrc_lwmac_set_netdev_state(netif, NETOPT_STATE_OFF);
             break;
         }
         /*********************** Control states ***********************************/
         case GNRC_LWMAC_START: {
-            rtt_handler(GNRC_LWMAC_EVENT_RTT_START, gnrc_netdev);
-            lwmac_set_state(gnrc_netdev, GNRC_LWMAC_LISTENING);
+            rtt_handler(GNRC_LWMAC_EVENT_RTT_START, netif);
+            lwmac_set_state(netif, GNRC_LWMAC_LISTENING);
             break;
         }
         case GNRC_LWMAC_STOP: {
-            rtt_handler(GNRC_LWMAC_EVENT_RTT_STOP, gnrc_netdev);
-            lwmac_set_state(gnrc_netdev, GNRC_LWMAC_STOPPED);
+            rtt_handler(GNRC_LWMAC_EVENT_RTT_STOP, netif);
+            lwmac_set_state(netif, GNRC_LWMAC_STOPPED);
             break;
         }
         case GNRC_LWMAC_RESET: {
             LOG_WARNING("WARNING: [LWMAC] Reset not yet implemented\n");
-            lwmac_set_state(gnrc_netdev, GNRC_LWMAC_STOP);
-            lwmac_set_state(gnrc_netdev, GNRC_LWMAC_START);
+            lwmac_set_state(netif, GNRC_LWMAC_STOP);
+            lwmac_set_state(netif, GNRC_LWMAC_START);
             break;
         }
         /**************************************************************************/
@@ -223,38 +355,38 @@ void lwmac_set_state(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_state_t newstate)
         }
     }
 
-    lwmac_schedule_update(gnrc_netdev);
+    lwmac_schedule_update(netif);
 }
 
-static void _sleep_management(gnrc_netdev_t *gnrc_netdev)
+static void _sleep_management(gnrc_netif2_t *netif)
 {
     /* If a packet is scheduled, no other (possible earlier) packet can be
      * sent before the first one is handled, even no broadcast
      */
-    if (!gnrc_lwmac_timeout_is_running(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WAIT_DEST_WAKEUP)) {
+    if (!gnrc_lwmac_timeout_is_running(netif, GNRC_LWMAC_TIMEOUT_WAIT_DEST_WAKEUP)) {
         gnrc_mac_tx_neighbor_t *neighbour;
 
         /* Check if there is packet remaining for retransmission */
-        if (gnrc_netdev->tx.current_neighbor != NULL) {
-            neighbour = gnrc_netdev->tx.current_neighbor;
+        if (netif->mac.tx.current_neighbor != NULL) {
+            neighbour = netif->mac.tx.current_neighbor;
         }
         else {
             /* Check if there are broadcasts to send and transmit immediately */
-            if (gnrc_priority_pktqueue_length(&(gnrc_netdev->tx.neighbors[0].queue)) > 0) {
-                gnrc_netdev->tx.current_neighbor = &(gnrc_netdev->tx.neighbors[0]);
-                lwmac_set_state(gnrc_netdev, GNRC_LWMAC_TRANSMITTING);
+            if (gnrc_priority_pktqueue_length(&(netif->mac.tx.neighbors[0].queue)) > 0) {
+                netif->mac.tx.current_neighbor = &(netif->mac.tx.neighbors[0]);
+                lwmac_set_state(netif, GNRC_LWMAC_TRANSMITTING);
                 return;
             }
-            neighbour = _next_tx_neighbor(gnrc_netdev);
+            neighbour = _next_tx_neighbor(netif);
         }
 
         if (neighbour != NULL) {
             /* if phase is unknown, send immediately. */
             if (neighbour->phase > RTT_TICKS_TO_US(GNRC_LWMAC_WAKEUP_INTERVAL_US)) {
-                gnrc_netdev->tx.current_neighbor = neighbour;
-                gnrc_netdev_lwmac_set_tx_continue(gnrc_netdev, false);
-                gnrc_netdev->tx.tx_burst_count = 0;
-                lwmac_set_state(gnrc_netdev, GNRC_LWMAC_TRANSMITTING);
+                netif->mac.tx.current_neighbor = neighbour;
+                gnrc_lwmac_set_tx_continue(netif, false);
+                netif->mac.tx.tx_burst_count = 0;
+                lwmac_set_state(netif, GNRC_LWMAC_TRANSMITTING);
                 return;
             }
 
@@ -276,275 +408,276 @@ static void _sleep_management(gnrc_netdev_t *gnrc_netdev)
             random_backoff = random_uint32_range(0, GNRC_LWMAC_TIME_BETWEEN_WR_US);
             time_until_tx = time_until_tx + random_backoff;
 
-            gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WAIT_DEST_WAKEUP, time_until_tx);
+            gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_WAIT_DEST_WAKEUP, time_until_tx);
 
             /* Register neighbour to be the next */
-            gnrc_netdev->tx.current_neighbor = neighbour;
+            netif->mac.tx.current_neighbor = neighbour;
 
             /* Stop dutycycling, we're preparing to send. This prevents the
              * timeout arriving late, so that the destination phase would
              * be missed. */
             /* TODO: bad for power savings */
-            rtt_handler(GNRC_LWMAC_EVENT_RTT_PAUSE, gnrc_netdev);
+            rtt_handler(GNRC_LWMAC_EVENT_RTT_PAUSE, netif);
         }
     }
-    else if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WAIT_DEST_WAKEUP)) {
+    else if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_WAIT_DEST_WAKEUP)) {
         LOG_DEBUG("[LWMAC] Got timeout for dest wakeup, ticks: %" PRIu32 "\n", rtt_get_counter());
-        gnrc_netdev_lwmac_set_tx_continue(gnrc_netdev, false);
-        gnrc_netdev->tx.tx_burst_count = 0;
-        lwmac_set_state(gnrc_netdev, GNRC_LWMAC_TRANSMITTING);
+        gnrc_lwmac_set_tx_continue(netif, false);
+        netif->mac.tx.tx_burst_count = 0;
+        lwmac_set_state(netif, GNRC_LWMAC_TRANSMITTING);
     }
 }
 
-static void _rx_management_failed(gnrc_netdev_t *gnrc_netdev)
+static void _rx_management_failed(gnrc_netif2_t *netif)
 {
     /* This may happen frequently because we'll receive WA from
      * every node in range. */
     LOG_DEBUG("[LWMAC] Reception was NOT successful\n");
-    gnrc_lwmac_rx_stop(gnrc_netdev);
+    gnrc_lwmac_rx_stop(netif);
 
-    if (gnrc_netdev->rx.rx_bad_exten_count >= GNRC_LWMAC_MAX_RX_EXTENSION_NUM) {
-        gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
+    if (netif->mac.rx.rx_bad_exten_count >= GNRC_LWMAC_MAX_RX_EXTENSION_NUM) {
+        gnrc_lwmac_set_quit_rx(netif, true);
     }
 
     /* Here we check if we are close to the end of the cycle. If yes,
      * go to sleep. Firstly, get the relative phase. */
     uint32_t phase = rtt_get_counter();
-    if (phase < gnrc_netdev->lwmac.last_wakeup) {
-        phase = (RTT_US_TO_TICKS(GNRC_LWMAC_PHASE_MAX) - gnrc_netdev->lwmac.last_wakeup) +
-                 phase;
+    if (phase < netif->mac.lwmac.last_wakeup) {
+        phase = (RTT_US_TO_TICKS(GNRC_LWMAC_PHASE_MAX) - netif->mac.lwmac.last_wakeup) +
+                phase;
     }
     else {
-        phase = phase - gnrc_netdev->lwmac.last_wakeup;
+        phase = phase - netif->mac.lwmac.last_wakeup;
     }
     /* If the relative phase is beyond 4/5 cycle time, go to sleep. */
-    if (phase > (4*RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US)/5)) {
-        gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
+    if (phase > (4 * RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US) / 5)) {
+        gnrc_lwmac_set_quit_rx(netif, true);
     }
 
-    if (gnrc_netdev_lwmac_get_quit_rx(gnrc_netdev)) {
-        lwmac_set_state(gnrc_netdev, GNRC_LWMAC_SLEEPING);
+    if (gnrc_lwmac_get_quit_rx(netif)) {
+        lwmac_set_state(netif, GNRC_LWMAC_SLEEPING);
     }
     else {
         /* Go back to LISTENING for keep hearing on the channel */
-        lwmac_set_state(gnrc_netdev, GNRC_LWMAC_LISTENING);
+        lwmac_set_state(netif, GNRC_LWMAC_LISTENING);
     }
 }
 
-static void _rx_management_success(gnrc_netdev_t *gnrc_netdev)
+static void _rx_management_success(gnrc_netif2_t *netif)
 {
     LOG_DEBUG("[LWMAC] Reception was successful\n");
-    gnrc_lwmac_rx_stop(gnrc_netdev);
+    gnrc_lwmac_rx_stop(netif);
     /* Dispatch received packets, timing is not critical anymore */
-    gnrc_mac_dispatch(&gnrc_netdev->rx);
+    gnrc_mac_dispatch(&netif->mac.rx);
 
     /* Here we check if we are close to the end of the cycle. If yes,
      * go to sleep. Firstly, get the relative phase. */
     uint32_t phase = rtt_get_counter();
-    if (phase < gnrc_netdev->lwmac.last_wakeup) {
-        phase = (RTT_US_TO_TICKS(GNRC_LWMAC_PHASE_MAX) - gnrc_netdev->lwmac.last_wakeup) +
-                 phase;
+    if (phase < netif->mac.lwmac.last_wakeup) {
+        phase = (RTT_US_TO_TICKS(GNRC_LWMAC_PHASE_MAX) - netif->mac.lwmac.last_wakeup) +
+                phase;
     }
     else {
-        phase = phase - gnrc_netdev->lwmac.last_wakeup;
+        phase = phase - netif->mac.lwmac.last_wakeup;
     }
     /* If the relative phase is beyond 4/5 cycle time, go to sleep. */
-    if (phase > (4*RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US)/5)) {
-        gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
+    if (phase > (4 * RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US) / 5)) {
+        gnrc_lwmac_set_quit_rx(netif, true);
     }
 
-    if (gnrc_netdev_lwmac_get_quit_rx(gnrc_netdev)) {
-        lwmac_set_state(gnrc_netdev, GNRC_LWMAC_SLEEPING);
+    if (gnrc_lwmac_get_quit_rx(netif)) {
+        lwmac_set_state(netif, GNRC_LWMAC_SLEEPING);
     }
     else {
         /* Go back to LISTENING after successful reception */
-        lwmac_set_state(gnrc_netdev, GNRC_LWMAC_LISTENING);
+        lwmac_set_state(netif, GNRC_LWMAC_LISTENING);
     }
 }
-static void _rx_management(gnrc_netdev_t *gnrc_netdev)
+
+static void _rx_management(gnrc_netif2_t *netif)
 {
-    gnrc_lwmac_rx_state_t state_rx = gnrc_netdev->rx.state;
+    gnrc_lwmac_rx_state_t state_rx = netif->mac.rx.state;
 
     switch (state_rx) {
         case GNRC_LWMAC_RX_STATE_STOPPED: {
-            gnrc_lwmac_rx_start(gnrc_netdev);
-            gnrc_lwmac_rx_update(gnrc_netdev);
+            gnrc_lwmac_rx_start(netif);
+            gnrc_lwmac_rx_update(netif);
             break;
         }
         case GNRC_LWMAC_RX_STATE_FAILED: {
-            _rx_management_failed(gnrc_netdev);
+            _rx_management_failed(netif);
             break;
         }
         case GNRC_LWMAC_RX_STATE_SUCCESSFUL: {
-            _rx_management_success(gnrc_netdev);
+            _rx_management_success(netif);
             break;
         }
         default:
-            gnrc_lwmac_rx_update(gnrc_netdev);
+            gnrc_lwmac_rx_update(netif);
     }
 
     /* If state has changed, reschedule main state machine */
-    if (state_rx != gnrc_netdev->rx.state) {
-        lwmac_schedule_update(gnrc_netdev);
+    if (state_rx != netif->mac.rx.state) {
+        lwmac_schedule_update(netif);
     }
 }
 
-static void _tx_management_stopped(gnrc_netdev_t *gnrc_netdev)
+static void _tx_management_stopped(gnrc_netif2_t *netif)
 {
     gnrc_pktsnip_t *pkt;
 
     /* If there is packet remaining for retransmission,
      * retransmit it (i.e., the retransmission scheme of LWMAC). */
-    if (gnrc_netdev->tx.packet != NULL) {
+    if (netif->mac.tx.packet != NULL) {
         LOG_WARNING("WARNING: [LWMAC] TX %d times retry\n",
-                         gnrc_netdev->tx.tx_retry_count);
-        gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_INIT;
-        gnrc_netdev->tx.wr_sent = 0;
-        gnrc_lwmac_tx_update(gnrc_netdev);
+                    netif->mac.tx.tx_retry_count);
+        netif->mac.tx.state = GNRC_LWMAC_TX_STATE_INIT;
+        netif->mac.tx.wr_sent = 0;
+        gnrc_lwmac_tx_update(netif);
     }
     else {
         if ((pkt = gnrc_priority_pktqueue_pop(
-                 &gnrc_netdev->tx.current_neighbor->queue))) {
-            gnrc_netdev->tx.tx_retry_count = 0;
-            gnrc_lwmac_tx_start(gnrc_netdev, pkt, gnrc_netdev->tx.current_neighbor);
-            gnrc_lwmac_tx_update(gnrc_netdev);
+                 &netif->mac.tx.current_neighbor->queue))) {
+            netif->mac.tx.tx_retry_count = 0;
+            gnrc_lwmac_tx_start(netif, pkt, netif->mac.tx.current_neighbor);
+            gnrc_lwmac_tx_update(netif);
         }
         else {
             /* Shouldn't happen, but never observed this case */
-            lwmac_set_state(gnrc_netdev, GNRC_LWMAC_SLEEPING);
+            lwmac_set_state(netif, GNRC_LWMAC_SLEEPING);
         }
     }
 }
 
-static void _tx_management_success(gnrc_netdev_t *gnrc_netdev)
+static void _tx_management_success(gnrc_netif2_t *netif)
 {
-    if (gnrc_netdev->tx.current_neighbor == &(gnrc_netdev->tx.neighbors[0])) {
+    if (netif->mac.tx.current_neighbor == &(netif->mac.tx.neighbors[0])) {
         LOG_INFO("[LWMAC] Broadcast transmission done\n");
     }
 
-    gnrc_lwmac_tx_stop(gnrc_netdev);
+    gnrc_lwmac_tx_stop(netif);
 
     /* In case have pending packets for the same receiver, continue to
      * send immediately, before the maximum transmit-limit */
-    if ((gnrc_netdev_lwmac_get_tx_continue(gnrc_netdev)) &&
-        (gnrc_netdev->tx.tx_burst_count < GNRC_LWMAC_MAX_TX_BURST_PKT_NUM)) {
-        lwmac_schedule_update(gnrc_netdev);
+    if ((gnrc_lwmac_get_tx_continue(netif)) &&
+        (netif->mac.tx.tx_burst_count < GNRC_LWMAC_MAX_TX_BURST_PKT_NUM)) {
+        lwmac_schedule_update(netif);
     }
     else {
-        lwmac_set_state(gnrc_netdev, GNRC_LWMAC_SLEEPING);
+        lwmac_set_state(netif, GNRC_LWMAC_SLEEPING);
     }
 }
 
-static void _tx_management(gnrc_netdev_t *gnrc_netdev)
+static void _tx_management(gnrc_netif2_t *netif)
 {
-    gnrc_lwmac_tx_state_t state_tx = gnrc_netdev->tx.state;
+    gnrc_lwmac_tx_state_t state_tx = netif->mac.tx.state;
 
     switch (state_tx) {
         case GNRC_LWMAC_TX_STATE_STOPPED: {
-            _tx_management_stopped(gnrc_netdev);
+            _tx_management_stopped(netif);
             break;
         }
         case GNRC_LWMAC_TX_STATE_FAILED: {
             /* If transmission failure, do not try burst transmissions and quit other
              * transmission attempts in this cycle for collision avoidance */
-            gnrc_netdev_lwmac_set_tx_continue(gnrc_netdev, false);
-            gnrc_netdev_lwmac_set_quit_tx(gnrc_netdev, true);
+            gnrc_lwmac_set_tx_continue(netif, false);
+            gnrc_lwmac_set_quit_tx(netif, true);
             /* falls through */
             /* TX packet will therefore be dropped. No automatic resending here,
              * we did our best.
              */
         }
         case GNRC_LWMAC_TX_STATE_SUCCESSFUL: {
-            _tx_management_success(gnrc_netdev);
+            _tx_management_success(netif);
             break;
         }
         default:
-            gnrc_lwmac_tx_update(gnrc_netdev);
+            gnrc_lwmac_tx_update(netif);
     }
 
     /* If state has changed, reschedule main state machine */
-    if (state_tx != gnrc_netdev->tx.state) {
-        lwmac_schedule_update(gnrc_netdev);
+    if (state_tx != netif->mac.tx.state) {
+        lwmac_schedule_update(netif);
     }
 }
 
-static void _lwmac_update_listening(gnrc_netdev_t *gnrc_netdev)
+static void _lwmac_update_listening(gnrc_netif2_t *netif)
 {
     /* In case has pending packet to send, clear rtt alarm thus to goto
      * transmission initialization (in SLEEPING management) right after the
      * listening period */
-    if ((_next_tx_neighbor(gnrc_netdev) != NULL) ||
-        (gnrc_netdev->tx.current_neighbor != NULL)) {
-        rtt_handler(GNRC_LWMAC_EVENT_RTT_PAUSE, gnrc_netdev);
+    if ((_next_tx_neighbor(netif) != NULL) ||
+        (netif->mac.tx.current_neighbor != NULL)) {
+        rtt_handler(GNRC_LWMAC_EVENT_RTT_PAUSE, netif);
     }
 
     /* Set timeout for if there's no successful rx transaction that will
      * change state to SLEEPING. */
-    if (!gnrc_lwmac_timeout_is_running(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD)) {
-        gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD, GNRC_LWMAC_WAKEUP_DURATION_US);
+    if (!gnrc_lwmac_timeout_is_running(netif, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD)) {
+        gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD, GNRC_LWMAC_WAKEUP_DURATION_US);
     }
-    else if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD)) {
+    else if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD)) {
         /* Dispatch first as there still may be broadcast packets. */
-        gnrc_mac_dispatch(&gnrc_netdev->rx);
+        gnrc_mac_dispatch(&netif->mac.rx);
 
-        gnrc_netdev->lwmac.state = GNRC_LWMAC_SLEEPING;
+        netif->mac.lwmac.state = GNRC_LWMAC_SLEEPING;
         /* Enable duty cycling again */
-        rtt_handler(GNRC_LWMAC_EVENT_RTT_RESUME, gnrc_netdev);
+        rtt_handler(GNRC_LWMAC_EVENT_RTT_RESUME, netif);
 
-        _gnrc_lwmac_set_netdev_state(gnrc_netdev, NETOPT_STATE_SLEEP);
-        gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD);
+        _gnrc_lwmac_set_netdev_state(netif, NETOPT_STATE_SLEEP);
+        gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD);
 
         /* if there is a packet for transmission, schedule update to start
          * transmission initialization immediately. */
-        gnrc_mac_tx_neighbor_t *neighbour = _next_tx_neighbor(gnrc_netdev);
-        if ((neighbour != NULL) || (gnrc_netdev->tx.current_neighbor != NULL)) {
+        gnrc_mac_tx_neighbor_t *neighbour = _next_tx_neighbor(netif);
+        if ((neighbour != NULL) || (netif->mac.tx.current_neighbor != NULL)) {
             /* This triggers packet sending procedure in sleeping immediately. */
-            lwmac_schedule_update(gnrc_netdev);
+            lwmac_schedule_update(netif);
             return;
         }
     }
 
-    if (gnrc_priority_pktqueue_length(&gnrc_netdev->rx.queue) > 0) {
+    if (gnrc_priority_pktqueue_length(&netif->mac.rx.queue) > 0) {
         /* Do wake-up extension in each packet reception. */
-        gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD);
-        lwmac_set_state(gnrc_netdev, GNRC_LWMAC_RECEIVING);
+        gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD);
+        lwmac_set_state(netif, GNRC_LWMAC_RECEIVING);
     }
 }
 
 /* Main state machine. Call whenever something happens */
-static bool lwmac_update(gnrc_netdev_t *gnrc_netdev)
+static bool lwmac_update(gnrc_netif2_t *netif)
 {
-    gnrc_netdev_lwmac_set_reschedule(gnrc_netdev, false);
+    gnrc_lwmac_set_reschedule(netif, false);
 
-    switch (gnrc_netdev->lwmac.state) {
+    switch (netif->mac.lwmac.state) {
         case GNRC_LWMAC_SLEEPING: {
             /* Quit scheduling transmission if 'quit-tx' flag is found set, thus
              * to avoid potential collisions with ongoing transmissions of other
              * neighbor nodes */
-            if (gnrc_netdev_lwmac_get_quit_tx(gnrc_netdev)) {
+            if (gnrc_lwmac_get_quit_tx(netif)) {
                 return false;
             }
 
-            _sleep_management(gnrc_netdev);
+            _sleep_management(netif);
             break;
         }
         case GNRC_LWMAC_LISTENING: {
-            _lwmac_update_listening(gnrc_netdev);
+            _lwmac_update_listening(netif);
             break;
         }
         case GNRC_LWMAC_RECEIVING: {
-            _rx_management(gnrc_netdev);
+            _rx_management(netif);
             break;
         }
         case GNRC_LWMAC_TRANSMITTING: {
-            _tx_management(gnrc_netdev);
+            _tx_management(netif);
             break;
         }
         default:
-            LOG_DEBUG("[LWMAC] No actions in state %u\n", gnrc_netdev->lwmac.state);
+            LOG_DEBUG("[LWMAC] No actions in state %u\n", netif->mac.lwmac.state);
     }
 
-    return gnrc_netdev_lwmac_get_reschedule(gnrc_netdev);
+    return gnrc_lwmac_get_reschedule(netif);
 }
 
 static void rtt_cb(void *arg)
@@ -560,30 +693,30 @@ static void rtt_cb(void *arg)
     }
 }
 
-void rtt_handler(uint32_t event, gnrc_netdev_t *gnrc_netdev)
+void rtt_handler(uint32_t event, gnrc_netif2_t *netif)
 {
     uint32_t alarm;
 
     switch (event & 0xffff) {
         case GNRC_LWMAC_EVENT_RTT_WAKEUP_PENDING: {
             /* A new cycle starts, set sleep timing and initialize related MAC-info flags. */
-            gnrc_netdev->lwmac.last_wakeup = rtt_get_alarm();
-            alarm = _next_inphase_event(gnrc_netdev->lwmac.last_wakeup,
+            netif->mac.lwmac.last_wakeup = rtt_get_alarm();
+            alarm = _next_inphase_event(netif->mac.lwmac.last_wakeup,
                                         RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_DURATION_US));
             rtt_set_alarm(alarm, rtt_cb, (void *) GNRC_LWMAC_EVENT_RTT_SLEEP_PENDING);
-            gnrc_netdev_lwmac_set_quit_tx(gnrc_netdev, false);
-            gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, false);
-            gnrc_netdev_lwmac_set_phase_backoff(gnrc_netdev, false);
-            gnrc_netdev->rx.rx_bad_exten_count = 0;
-            lwmac_set_state(gnrc_netdev, GNRC_LWMAC_LISTENING);
+            gnrc_lwmac_set_quit_tx(netif, false);
+            gnrc_lwmac_set_quit_rx(netif, false);
+            gnrc_lwmac_set_phase_backoff(netif, false);
+            netif->mac.rx.rx_bad_exten_count = 0;
+            lwmac_set_state(netif, GNRC_LWMAC_LISTENING);
             break;
         }
         case GNRC_LWMAC_EVENT_RTT_SLEEP_PENDING: {
             /* Set next wake-up timing. */
-            alarm = _next_inphase_event(gnrc_netdev->lwmac.last_wakeup,
+            alarm = _next_inphase_event(netif->mac.lwmac.last_wakeup,
                                         RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US));
             rtt_set_alarm(alarm, rtt_cb, (void *) GNRC_LWMAC_EVENT_RTT_WAKEUP_PENDING);
-            lwmac_set_state(gnrc_netdev, GNRC_LWMAC_SLEEPING);
+            lwmac_set_state(netif, GNRC_LWMAC_SLEEPING);
             break;
         }
         /* Set initial wake-up alarm that starts the cycle */
@@ -591,24 +724,24 @@ void rtt_handler(uint32_t event, gnrc_netdev_t *gnrc_netdev)
             LOG_DEBUG("[LWMAC] RTT: Initialize duty cycling\n");
             alarm = rtt_get_counter() + RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_DURATION_US);
             rtt_set_alarm(alarm, rtt_cb, (void *) GNRC_LWMAC_EVENT_RTT_SLEEP_PENDING);
-            gnrc_netdev_lwmac_set_dutycycle_active(gnrc_netdev, true);
+            gnrc_lwmac_set_dutycycle_active(netif, true);
             break;
         }
         case GNRC_LWMAC_EVENT_RTT_STOP:
         case GNRC_LWMAC_EVENT_RTT_PAUSE: {
             rtt_clear_alarm();
             LOG_DEBUG("[LWMAC] RTT: Stop duty cycling, now in state %u\n",
-                           gnrc_netdev->lwmac.state);
-            gnrc_netdev_lwmac_set_dutycycle_active(gnrc_netdev, false);
+                      netif->mac.lwmac.state);
+            gnrc_lwmac_set_dutycycle_active(netif, false);
             break;
         }
         case GNRC_LWMAC_EVENT_RTT_RESUME: {
             LOG_DEBUG("[LWMAC] RTT: Resume duty cycling\n");
             rtt_clear_alarm();
-            alarm = _next_inphase_event(gnrc_netdev->lwmac.last_wakeup,
+            alarm = _next_inphase_event(netif->mac.lwmac.last_wakeup,
                                         RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US));
             rtt_set_alarm(alarm, rtt_cb, (void *) GNRC_LWMAC_EVENT_RTT_WAKEUP_PENDING);
-            gnrc_netdev_lwmac_set_dutycycle_active(gnrc_netdev, true);
+            gnrc_lwmac_set_dutycycle_active(netif, true);
             break;
         }
         default:
@@ -622,17 +755,17 @@ void rtt_handler(uint32_t event, gnrc_netdev_t *gnrc_netdev)
  * @param[in] event         type of event
  * @param[in] data          optional parameter
  */
-static void _event_cb(netdev_t *dev, netdev_event_t event)
+static void _lwmac_event_cb(netdev_t *dev, netdev_event_t event)
 {
-    gnrc_netdev_t *gnrc_netdev = (gnrc_netdev_t *) dev->context;
+    gnrc_netif2_t *netif = (gnrc_netif2_t *) dev->context;
 
     if (event == NETDEV_EVENT_ISR) {
         msg_t msg;
 
         msg.type = NETDEV_MSG_TYPE_EVENT;
-        msg.content.ptr = (void *) gnrc_netdev;
+        msg.content.ptr = (void *) netif;
 
-        if (msg_send(&msg, gnrc_netdev->pid) <= 0) {
+        if (msg_send(&msg, netif->pid) <= 0) {
             LOG_WARNING("WARNING: [LWMAC] gnrc_netdev: possibly lost interrupt.\n");
         }
     }
@@ -641,13 +774,12 @@ static void _event_cb(netdev_t *dev, netdev_event_t event)
         switch (event) {
             case NETDEV_EVENT_RX_STARTED: {
                 LOG_DEBUG("[LWMAC] NETDEV_EVENT_RX_STARTED\n");
-                gnrc_netdev_set_rx_started(gnrc_netdev, true);
+                gnrc_netif2_set_rx_started(netif, true);
                 break;
             }
             case NETDEV_EVENT_RX_COMPLETE: {
                 LOG_DEBUG("[LWMAC] NETDEV_EVENT_RX_COMPLETE\n");
-
-                gnrc_pktsnip_t *pkt = gnrc_netdev->recv(gnrc_netdev);
+                gnrc_pktsnip_t *pkt = netif->ops->recv(netif);
 
                 /* Prevent packet corruption when a packet is sent before the previous
                  * received packet has been downloaded. This happens e.g. when a timeout
@@ -661,87 +793,121 @@ static void _event_cb(netdev_t *dev, netdev_event_t event)
                  * TODO: transceivers might have 2 frame buffers, so make this optional
                  */
                 if (pkt == NULL) {
-                    gnrc_netdev_set_rx_started(gnrc_netdev, false);
+                    gnrc_netif2_set_rx_started(netif, false);
                     break;
                 }
 
-                gnrc_netdev_set_rx_started(gnrc_netdev, false);
+                gnrc_netif2_set_rx_started(netif, false);
 
-                if (!gnrc_mac_queue_rx_packet(&gnrc_netdev->rx, 0, pkt)) {
+                if (!gnrc_mac_queue_rx_packet(&netif->mac.rx, 0, pkt)) {
                     LOG_ERROR("ERROR: [LWMAC] Can't push RX packet @ %p, memory full?\n", pkt);
                     gnrc_pktbuf_release(pkt);
                     break;
                 }
-                lwmac_schedule_update(gnrc_netdev);
+                lwmac_schedule_update(netif);
                 break;
             }
             case NETDEV_EVENT_TX_STARTED: {
-                gnrc_netdev_set_tx_feedback(gnrc_netdev, TX_FEEDBACK_UNDEF);
-                gnrc_netdev_set_rx_started(gnrc_netdev, false);
+                gnrc_netif2_set_tx_feedback(netif, TX_FEEDBACK_UNDEF);
+                gnrc_netif2_set_rx_started(netif, false);
                 break;
             }
             case NETDEV_EVENT_TX_COMPLETE: {
-                gnrc_netdev_set_tx_feedback(gnrc_netdev, TX_FEEDBACK_SUCCESS);
-                gnrc_netdev_set_rx_started(gnrc_netdev, false);
-                lwmac_schedule_update(gnrc_netdev);
+                gnrc_netif2_set_tx_feedback(netif, TX_FEEDBACK_SUCCESS);
+                gnrc_netif2_set_rx_started(netif, false);
+                lwmac_schedule_update(netif);
                 break;
             }
             case NETDEV_EVENT_TX_NOACK: {
-                gnrc_netdev_set_tx_feedback(gnrc_netdev, TX_FEEDBACK_NOACK);
-                gnrc_netdev_set_rx_started(gnrc_netdev, false);
-                lwmac_schedule_update(gnrc_netdev);
+                gnrc_netif2_set_tx_feedback(netif, TX_FEEDBACK_NOACK);
+                gnrc_netif2_set_rx_started(netif, false);
+                lwmac_schedule_update(netif);
                 break;
             }
             case NETDEV_EVENT_TX_MEDIUM_BUSY: {
-                gnrc_netdev_set_tx_feedback(gnrc_netdev, TX_FEEDBACK_BUSY);
-                gnrc_netdev_set_rx_started(gnrc_netdev, false);
-                lwmac_schedule_update(gnrc_netdev);
+                gnrc_netif2_set_tx_feedback(netif, TX_FEEDBACK_BUSY);
+                gnrc_netif2_set_rx_started(netif, false);
+                lwmac_schedule_update(netif);
                 break;
             }
             default:
                 LOG_WARNING("WARNING: [LWMAC] Unhandled netdev event: %u\n", event);
         }
     }
+
+    /* Execute main state machine because something just happend*/
+    while (gnrc_lwmac_get_reschedule(netif)) {
+        lwmac_update(netif);
+    }
 }
 
-/**
- * @brief   Startup code and event loop of the LWMAC layer
- *
- * @param[in] args          expects a pointer to the underlying netdev device
- *
- * @return                  never returns
- */
-static void *_lwmac_thread(void *args)
+static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
 {
-    gnrc_netdev_t *gnrc_netdev = (gnrc_netdev_t *)args;
-    netdev_t *dev = gnrc_netdev->dev;
+    if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, pkt)) {
+        gnrc_pktbuf_release(pkt);
+        LOG_WARNING("WARNING: [LWMAC] TX queue full, drop packet\n");
+        return -ENOBUFS;
+    }
 
-    gnrc_netdev->pid = thread_getpid();
+    lwmac_schedule_update(netif);
 
-    gnrc_netapi_opt_t *opt;
-    int res;
-    msg_t msg, reply, msg_queue[GNRC_LWMAC_IPC_MSG_QUEUE_SIZE];
+    /* Execute main state machine because something just happend*/
+    while (gnrc_lwmac_get_reschedule(netif)) {
+        lwmac_update(netif);
+    }
 
-    LOG_INFO("[LWMAC] Starting LWMAC\n");
+    return 0;
+}
 
-    /* RTT is used for scheduling wakeup */
-    rtt_init();
+static void _lwmac_msg_handler(gnrc_netif2_t *netif, msg_t *msg)
+{
+    switch (msg->type) {
+        /* RTT raised an interrupt */
+        case GNRC_LWMAC_EVENT_RTT_TYPE: {
+            if (gnrc_lwmac_get_dutycycle_active(netif)) {
+                rtt_handler(msg->content.value, netif);
+                lwmac_schedule_update(netif);
+            }
+            else {
+                LOG_DEBUG("[LWMAC] Ignoring late RTT event while duty-cycling is off\n");
+            }
+            break;
+        }
 
-    /* Store pid globally, so that IRQ can use it to send msg */
-    lwmac_pid = thread_getpid();
+        /* An LWMAC timeout occurred */
+        case GNRC_LWMAC_EVENT_TIMEOUT_TYPE: {
+            gnrc_lwmac_timeout_make_expire((gnrc_lwmac_timeout_t *) msg->content.ptr);
+            lwmac_schedule_update(netif);
+            break;
+        }
 
-    /* setup the MAC layers message queue */
-    msg_init_queue(msg_queue, GNRC_LWMAC_IPC_MSG_QUEUE_SIZE);
+        default: {
+#if ENABLE_DEBUG
+            DEBUG("[LWMAC]: unknown message type 0x%04x"
+                  "(no message handler defined)\n", msg->type);
+#endif
+            break;
+        }
+    }
+
+    /* Execute main state machine because something just happend*/
+    while (gnrc_lwmac_get_reschedule(netif)) {
+        lwmac_update(netif);
+    }
+}
+
+static void _lwmac_init(gnrc_netif2_t *netif)
+{
+    netdev_t *dev;
 
-    /* register the event callback with the device driver */
-    dev->event_callback = _event_cb;
-    dev->context = (void *) gnrc_netdev;
+    dev = netif->dev;
+    dev->event_callback = _lwmac_event_cb;
 
-    /* register the device to the network stack*/
-    gnrc_netif_add(thread_getpid());
+    /* RTT is used for scheduling wakeup */
+    rtt_init();
 
-    /* initialize low-level driver */
-    dev->driver->init(dev);
+    /* Store pid globally, so that IRQ can use it to send msg */
+    lwmac_pid = netif->pid;
 
     /* Enable RX- and TX-started interrupts  */
     netopt_enable_t enable = NETOPT_ENABLE;
@@ -749,172 +915,29 @@ static void *_lwmac_thread(void *args)
     dev->driver->set(dev, NETOPT_TX_START_IRQ, &enable, sizeof(enable));
     dev->driver->set(dev, NETOPT_TX_END_IRQ, &enable, sizeof(enable));
 
-    uint16_t src_len = 8;
+    uint16_t src_len = IEEE802154_LONG_ADDRESS_LEN;
     dev->driver->set(dev, NETOPT_SRC_LEN, &src_len, sizeof(src_len));
 
     /* Get own address from netdev */
-    gnrc_netdev->l2_addr_len = dev->driver->get(dev, NETOPT_ADDRESS_LONG,
-                                                &gnrc_netdev->l2_addr,
-                                                IEEE802154_LONG_ADDRESS_LEN);
-    assert(gnrc_netdev->l2_addr_len > 0);
+    netif->l2addr_len = dev->driver->get(dev, NETOPT_ADDRESS_LONG,
+                                         &netif->l2addr,
+                                         IEEE802154_LONG_ADDRESS_LEN);
 
     /* Initialize broadcast sequence number. This at least differs from board
      * to board */
-    gnrc_netdev->tx.bcast_seqnr = gnrc_netdev->l2_addr[0];
+    netif->mac.tx.bcast_seqnr = netif->l2addr[0];
 
     /* Reset all timeouts just to be sure */
-    gnrc_lwmac_reset_timeouts(gnrc_netdev);
+    gnrc_lwmac_reset_timeouts(netif);
 
     /* Start duty cycling */
-    lwmac_set_state(gnrc_netdev, GNRC_LWMAC_START);
+    lwmac_set_state(netif, GNRC_LWMAC_START);
 
 #if (GNRC_LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
     /* Start duty cycle recording */
-    gnrc_netdev->lwmac.system_start_time_ticks = rtt_get_counter();
-    gnrc_netdev->lwmac.last_radio_on_time_ticks = gnrc_netdev->lwmac.system_start_time_ticks;
-    gnrc_netdev->lwmac.awake_duration_sum_ticks = 0;
-    gnrc_netdev->lwmac.lwmac_info |= GNRC_LWMAC_RADIO_IS_ON;
+    netif->mac.lwmac.system_start_time_ticks = rtt_get_counter();
+    netif->mac.lwmac.last_radio_on_time_ticks = netif->mac.lwmac.system_start_time_ticks;
+    netif->mac.lwmac.awake_duration_sum_ticks = 0;
+    netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_RADIO_IS_ON;
 #endif
-
-    /* start the event loop */
-    while (1) {
-        msg_receive(&msg);
-
-        /* Handle NETDEV, NETAPI, RTT and TIMEOUT messages */
-        switch (msg.type) {
-            /* RTT raised an interrupt */
-            case GNRC_LWMAC_EVENT_RTT_TYPE: {
-                if (gnrc_netdev_lwmac_get_dutycycle_active(gnrc_netdev)) {
-                    rtt_handler(msg.content.value, gnrc_netdev);
-                    lwmac_schedule_update(gnrc_netdev);
-                }
-                else {
-                    LOG_DEBUG("[LWMAC] Ignoring late RTT event while dutycycling is off\n");
-                }
-                break;
-            }
-            /* An LWMAC timeout occured */
-            case GNRC_LWMAC_EVENT_TIMEOUT_TYPE: {
-                gnrc_lwmac_timeout_make_expire((gnrc_lwmac_timeout_t *) msg.content.ptr);
-                lwmac_schedule_update(gnrc_netdev);
-                break;
-            }
-            /* Transceiver raised an interrupt */
-            case NETDEV_MSG_TYPE_EVENT: {
-                LOG_DEBUG("[LWMAC] GNRC_NETDEV_MSG_TYPE_EVENT received\n");
-                /* Forward event back to driver */
-                dev->driver->isr(dev);
-                break;
-            }
-            /* TX: Queue for sending */
-            case GNRC_NETAPI_MSG_TYPE_SND: {
-                /* TODO: how to announce failure to upper layers? */
-                LOG_DEBUG("[LWMAC] GNRC_NETAPI_MSG_TYPE_SND received\n");
-                gnrc_pktsnip_t *pkt = (gnrc_pktsnip_t *) msg.content.ptr;
-
-                if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, pkt)) {
-                    gnrc_pktbuf_release(pkt);
-                    LOG_WARNING("WARNING: [LWMAC] TX queue full, drop packet\n");
-                }
-
-                lwmac_schedule_update(gnrc_netdev);
-                break;
-            }
-            /* NETAPI set/get. Can't this be refactored away from here? */
-            case GNRC_NETAPI_MSG_TYPE_SET: {
-                LOG_DEBUG("[LWMAC] GNRC_NETAPI_MSG_TYPE_SET received\n");
-                opt = (gnrc_netapi_opt_t *)msg.content.ptr;
-
-                /* Depending on option forward to NETDEV or handle here */
-                switch (opt->opt) {
-                    /* Handle state change requests */
-                    case NETOPT_STATE: {
-                        netopt_state_t *state = (netopt_state_t *) opt->data;
-                        res = opt->data_len;
-                        switch (*state) {
-                            case NETOPT_STATE_OFF: {
-                                lwmac_set_state(gnrc_netdev, GNRC_LWMAC_STOP);
-                                break;
-                            }
-                            case NETOPT_STATE_IDLE: {
-                                lwmac_set_state(gnrc_netdev, GNRC_LWMAC_START);
-                                break;
-                            }
-                            case NETOPT_STATE_RESET: {
-                                lwmac_set_state(gnrc_netdev, GNRC_LWMAC_RESET);
-                                break;
-                            }
-                            default:
-                                res = -EINVAL;
-                                LOG_ERROR("ERROR: [LWMAC] NETAPI tries to set unsupported"
-                                               " state %u\n",*state);
-                        }
-                        lwmac_schedule_update(gnrc_netdev);
-                        break;
-                    }
-                    /* Forward to netdev by default*/
-                    default:
-                        /* set option for device driver */
-                        res = dev->driver->set(dev, opt->opt, opt->data, opt->data_len);
-                        LOG_DEBUG("[LWMAC] 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: {
-                /* TODO: filter out MAC layer options -> for now forward
-                         everything to the device driver */
-                LOG_DEBUG("[LWMAC] GNRC_NETAPI_MSG_TYPE_GET received\n");
-                /* read incoming options */
-                opt = (gnrc_netapi_opt_t *)msg.content.ptr;
-                /* get option from device driver */
-                res = dev->driver->get(dev, opt->opt, opt->data, opt->data_len);
-                LOG_DEBUG("[LWMAC] 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:
-                LOG_ERROR("ERROR: [LWMAC] Unknown command %" PRIu16 "\n", msg.type);
-                break;
-        }
-
-        /* Execute main state machine because something just happend*/
-        while (gnrc_netdev_lwmac_get_reschedule(gnrc_netdev)) {
-            lwmac_update(gnrc_netdev);
-        }
-    }
-
-    LOG_ERROR("ERROR: [LWMAC] terminated\n");
-
-    /* never reached */
-    return NULL;
-}
-
-kernel_pid_t gnrc_lwmac_init(char *stack, int stacksize, char priority,
-                             const char *name, gnrc_netdev_t *dev)
-{
-    kernel_pid_t res;
-
-    /* check if given netdev device is defined and the driver is set */
-    if (dev == NULL || dev->dev == NULL) {
-        LOG_ERROR("ERROR: [LWMAC] No netdev supplied or driver not set\n");
-        return -ENODEV;
-    }
-
-    /* create new LWMAC thread */
-    res = thread_create(stack, stacksize, priority, THREAD_CREATE_STACKTEST,
-                        _lwmac_thread, (void *)dev, name);
-    if (res <= 0) {
-        LOG_ERROR("ERROR: [LWMAC] Couldn't create thread\n");
-        return -EINVAL;
-    }
-
-    return res;
 }
diff --git a/sys/net/gnrc/link_layer/lwmac/lwmac_internal.c b/sys/net/gnrc/link_layer/lwmac/lwmac_internal.c
index 5ec6686013..2ee4af3fd2 100644
--- a/sys/net/gnrc/link_layer/lwmac/lwmac_internal.c
+++ b/sys/net/gnrc/link_layer/lwmac/lwmac_internal.c
@@ -27,10 +27,97 @@
 #include "net/gnrc/netdev.h"
 #include "net/gnrc/lwmac/lwmac.h"
 #include "include/lwmac_internal.h"
+#include "net/gnrc/netif2/ieee802154.h"
+#include "net/netdev/ieee802154.h"
 
 #define ENABLE_DEBUG    (0)
 #include "debug.h"
 
+int _gnrc_lwmac_transmit(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
+{
+    netdev_t *dev = netif->dev;
+    netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev;
+    gnrc_netif_hdr_t *netif_hdr;
+    gnrc_pktsnip_t *vec_snip;
+    const uint8_t *src, *dst = NULL;
+    int res = 0;
+    size_t n, src_len, dst_len;
+    uint8_t mhr[IEEE802154_MAX_HDR_LEN];
+    uint8_t flags = (uint8_t)(state->flags & NETDEV_IEEE802154_SEND_MASK);
+    le_uint16_t dev_pan = byteorder_btols(byteorder_htons(state->pan));
+
+    flags |= IEEE802154_FCF_TYPE_DATA;
+    if (pkt == NULL) {
+        DEBUG("_send_ieee802154: pkt was NULL\n");
+        return -EINVAL;
+    }
+    if (pkt->type != GNRC_NETTYPE_NETIF) {
+        DEBUG("_send_ieee802154: first header is not generic netif header\n");
+        return -EBADMSG;
+    }
+    netif_hdr = pkt->data;
+    /* prepare destination address */
+    if (netif_hdr->flags & /* If any of these flags is set assume broadcast */
+        (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) {
+        dst = ieee802154_addr_bcast;
+        dst_len = IEEE802154_ADDR_BCAST_LEN;
+    }
+    else {
+        dst = gnrc_netif_hdr_get_dst_addr(netif_hdr);
+        dst_len = netif_hdr->dst_l2addr_len;
+    }
+    src_len = netif_hdr->src_l2addr_len;
+    if (src_len > 0) {
+        src = gnrc_netif_hdr_get_src_addr(netif_hdr);
+    }
+    else {
+        src_len = netif->l2addr_len;
+        src = netif->l2addr;
+    }
+    /* fill MAC header, seq should be set by device */
+    if ((res = ieee802154_set_frame_hdr(mhr, src, src_len,
+                                        dst, dst_len, dev_pan,
+                                        dev_pan, flags, state->seq++)) == 0) {
+        DEBUG("_send_ieee802154: Error preperaring frame\n");
+        return -EINVAL;
+    }
+    /* prepare packet for sending */
+    vec_snip = gnrc_pktbuf_get_iovec(pkt, &n);
+    if (vec_snip != NULL) {
+        struct iovec *vector;
+
+        pkt = vec_snip;     /* reassign for later release; vec_snip is prepended to pkt */
+        vector = (struct iovec *)pkt->data;
+        vector[0].iov_base = mhr;
+        vector[0].iov_len = (size_t)res;
+#ifdef MODULE_NETSTATS_L2
+        if (netif_hdr->flags &
+            (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) {
+            netif->dev->stats.tx_mcast_count++;
+        }
+        else {
+            netif->dev->stats.tx_unicast_count++;
+        }
+#endif
+#ifdef MODULE_GNRC_MAC
+        if (netif->mac.mac_info & GNRC_NETDEV_MAC_INFO_CSMA_ENABLED) {
+            res = csma_sender_csma_ca_send(dev, vector, n, &netif->mac.csma_conf);
+        }
+        else {
+            res = dev->driver->send(dev, vector, n);
+        }
+#else
+        res = dev->driver->send(dev, vector, n);
+#endif
+    }
+    else {
+        return -ENOBUFS;
+    }
+    /* release old data */
+    gnrc_pktbuf_release(pkt);
+    return res;
+}
+
 int _gnrc_lwmac_parse_packet(gnrc_pktsnip_t *pkt, gnrc_lwmac_packet_info_t *info)
 {
     gnrc_netif_hdr_t *netif_hdr;
@@ -103,42 +190,42 @@ int _gnrc_lwmac_parse_packet(gnrc_pktsnip_t *pkt, gnrc_lwmac_packet_info_t *info
     return 0;
 }
 
-void _gnrc_lwmac_set_netdev_state(gnrc_netdev_t *gnrc_netdev, netopt_state_t devstate)
+void _gnrc_lwmac_set_netdev_state(gnrc_netif2_t *netif, netopt_state_t devstate)
 {
-    gnrc_netdev->dev->driver->set(gnrc_netdev->dev,
-                                  NETOPT_STATE,
-                                  &devstate,
-                                  sizeof(devstate));
+    netif->dev->driver->set(netif->dev,
+                            NETOPT_STATE,
+                            &devstate,
+                            sizeof(devstate));
 
 #if (GNRC_LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
     if (devstate == NETOPT_STATE_IDLE) {
-        if (!(gnrc_netdev->lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
-            gnrc_netdev->lwmac.last_radio_on_time_ticks = rtt_get_counter();
-            gnrc_netdev->lwmac.lwmac_info |= GNRC_LWMAC_RADIO_IS_ON;
+        if (!(netif->mac.lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
+            netif->mac.lwmac.last_radio_on_time_ticks = rtt_get_counter();
+            netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_RADIO_IS_ON;
         }
         return;
     }
     else if ((devstate == NETOPT_STATE_SLEEP) &&
-             (gnrc_netdev->lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
-        gnrc_netdev->lwmac.radio_off_time_ticks = rtt_get_counter();
+             (netif->mac.lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
+        netif->mac.lwmac.radio_off_time_ticks = rtt_get_counter();
 
-        gnrc_netdev->lwmac.awake_duration_sum_ticks +=
-            (gnrc_netdev->lwmac.radio_off_time_ticks -
-             gnrc_netdev->lwmac.last_radio_on_time_ticks);
+        netif->mac.lwmac.awake_duration_sum_ticks +=
+            (netif->mac.lwmac.radio_off_time_ticks -
+             netif->mac.lwmac.last_radio_on_time_ticks);
 
-        gnrc_netdev->lwmac.lwmac_info &= ~GNRC_LWMAC_RADIO_IS_ON;
+        netif->mac.lwmac.lwmac_info &= ~GNRC_LWMAC_RADIO_IS_ON;
     }
 #endif
 }
 
-netopt_state_t _gnrc_lwmac_get_netdev_state(gnrc_netdev_t *gnrc_netdev)
+netopt_state_t _gnrc_lwmac_get_netdev_state(gnrc_netif2_t *netif)
 {
     netopt_state_t state;
 
-    if (0 < gnrc_netdev->dev->driver->get(gnrc_netdev->dev,
-                                          NETOPT_STATE,
-                                          &state,
-                                          sizeof(state))) {
+    if (0 < netif->dev->driver->get(netif->dev,
+                                    NETOPT_STATE,
+                                    &state,
+                                    sizeof(state))) {
         return state;
     }
     return -1;
@@ -165,23 +252,23 @@ int _gnrc_lwmac_dispatch_defer(gnrc_pktsnip_t *buffer[], gnrc_pktsnip_t *pkt)
             return 0;
         }
         else if (bcast &&
-                (((gnrc_lwmac_hdr_t *)buffer[i]->next->data)->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) &&
-                (bcast->seq_nr == ((gnrc_lwmac_frame_broadcast_t *)buffer[i]->next->data)->seq_nr)) {
-                /* Filter same broadcasts, compare sequence number */
-                gnrc_netif_hdr_t *hdr_queued, *hdr_new;
-                hdr_new = pkt->next->next->data;
-                hdr_queued = buffer[i]->next->next->data;
-
-                /* Sequence numbers match, compare source addresses */
-                if ((hdr_new->src_l2addr_len == hdr_queued->src_l2addr_len) &&
-                    (memcmp(gnrc_netif_hdr_get_src_addr(hdr_new),
-                            gnrc_netif_hdr_get_src_addr(hdr_queued),
-                            hdr_new->src_l2addr_len) == 0)) {
-                    /* Source addresses match, same packet */
-                    DEBUG("[LWMAC] Found duplicate broadcast packet, dropping\n");
-                    gnrc_pktbuf_release(pkt);
-                    return -2;
-                }
+                 (((gnrc_lwmac_hdr_t *)buffer[i]->next->data)->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) &&
+                 (bcast->seq_nr == ((gnrc_lwmac_frame_broadcast_t *)buffer[i]->next->data)->seq_nr)) {
+            /* Filter same broadcasts, compare sequence number */
+            gnrc_netif_hdr_t *hdr_queued, *hdr_new;
+            hdr_new = pkt->next->next->data;
+            hdr_queued = buffer[i]->next->next->data;
+
+            /* Sequence numbers match, compare source addresses */
+            if ((hdr_new->src_l2addr_len == hdr_queued->src_l2addr_len) &&
+                (memcmp(gnrc_netif_hdr_get_src_addr(hdr_new),
+                        gnrc_netif_hdr_get_src_addr(hdr_queued),
+                        hdr_new->src_l2addr_len) == 0)) {
+                /* Source addresses match, same packet */
+                DEBUG("[LWMAC] Found duplicate broadcast packet, dropping\n");
+                gnrc_pktbuf_release(pkt);
+                return -2;
+            }
         }
     }
 
diff --git a/sys/net/gnrc/link_layer/lwmac/rx_state_machine.c b/sys/net/gnrc/link_layer/lwmac/rx_state_machine.c
index 3f35ad7e68..7707453207 100644
--- a/sys/net/gnrc/link_layer/lwmac/rx_state_machine.c
+++ b/sys/net/gnrc/link_layer/lwmac/rx_state_machine.c
@@ -52,14 +52,14 @@
  */
 #define GNRC_LWMAC_RX_FOUND_DATA              (0x04U)
 
-static uint8_t _packet_process_in_wait_for_wr(gnrc_netdev_t *gnrc_netdev)
+static uint8_t _packet_process_in_wait_for_wr(gnrc_netif2_t *netif)
 {
     uint8_t rx_info = 0;
     gnrc_pktsnip_t *pkt;
 
-    assert(gnrc_netdev != NULL);
+    assert(netif != NULL);
 
-    while ((pkt = gnrc_priority_pktqueue_pop(&gnrc_netdev->rx.queue)) != NULL) {
+    while ((pkt = gnrc_priority_pktqueue_pop(&netif->mac.rx.queue)) != NULL) {
         LOG_DEBUG("[LWMAC-rx] Inspecting pkt @ %p\n", pkt);
 
         /* Parse packet */
@@ -72,13 +72,13 @@ static uint8_t _packet_process_in_wait_for_wr(gnrc_netdev_t *gnrc_netdev)
         }
 
         if (info.header->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) {
-            _gnrc_lwmac_dispatch_defer(gnrc_netdev->rx.dispatch_buffer, pkt);
-            gnrc_mac_dispatch(&gnrc_netdev->rx);
+            _gnrc_lwmac_dispatch_defer(netif->mac.rx.dispatch_buffer, pkt);
+            gnrc_mac_dispatch(&netif->mac.rx);
             rx_info |= GNRC_LWMAC_RX_FOUND_BROADCAST;
             /* quit listening period to avoid receiving duplicate broadcast packets */
-            gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
+            gnrc_lwmac_set_quit_rx(netif, true);
             /* quit TX in this cycle to avoid collisions with broadcast packets */
-            gnrc_netdev_lwmac_set_quit_tx(gnrc_netdev, true);
+            gnrc_lwmac_set_quit_tx(netif, true);
             break;
         }
 
@@ -91,18 +91,18 @@ static uint8_t _packet_process_in_wait_for_wr(gnrc_netdev_t *gnrc_netdev)
         /* No need to keep pkt anymore */
         gnrc_pktbuf_release(pkt);
 
-        if (!(memcmp(&info.dst_addr.addr, &gnrc_netdev->l2_addr,
-                     gnrc_netdev->l2_addr_len) == 0)) {
+        if (!(memcmp(&info.dst_addr.addr, &netif->l2addr,
+                     netif->l2addr_len) == 0)) {
             LOG_DEBUG("[LWMAC-rx] Packet is WR but not for us\n");
             /* quit TX in this cycle to avoid collisions with other senders, since
              * found ongoing WR (preamble) stream */
-            gnrc_netdev_lwmac_set_quit_tx(gnrc_netdev, true);
+            gnrc_lwmac_set_quit_tx(netif, true);
             continue;
         }
 
         /* If reach here, the node gets a WR for itself. */
         /* Save source address for later addressing */
-        gnrc_netdev->rx.l2_addr = info.src_addr;
+        netif->mac.rx.l2_addr = info.src_addr;
 
         rx_info |= GNRC_LWMAC_RX_FOUND_WR;
         break;
@@ -112,56 +112,56 @@ static uint8_t _packet_process_in_wait_for_wr(gnrc_netdev_t *gnrc_netdev)
 }
 
 /* return false if send wa failed, otherwise return true */
-static bool _send_wa(gnrc_netdev_t *gnrc_netdev)
+static bool _send_wa(gnrc_netif2_t *netif)
 {
     gnrc_pktsnip_t *pkt;
     gnrc_pktsnip_t *pkt_lwmac;
     gnrc_netif_hdr_t *nethdr_wa;
 
-    assert(gnrc_netdev != NULL);
-    assert(gnrc_netdev->rx.l2_addr.len != 0);
+    assert(netif != NULL);
+    assert(netif->mac.rx.l2_addr.len != 0);
 
     /* if found ongoing transmission,
      * quit sending WA for collision avoidance. */
-    if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
-        gnrc_netdev->rx.rx_bad_exten_count++;
+    if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
+        netif->mac.rx.rx_bad_exten_count++;
         return false;
     }
 
     /* Assemble WA packet */
     gnrc_lwmac_frame_wa_t lwmac_hdr;
     lwmac_hdr.header.type = GNRC_LWMAC_FRAMETYPE_WA;
-    lwmac_hdr.dst_addr = gnrc_netdev->rx.l2_addr;
+    lwmac_hdr.dst_addr = netif->mac.rx.l2_addr;
 
     uint32_t phase_now = _gnrc_lwmac_phase_now();
 
     /* Embed the current 'relative phase timing' (counted from the start of this cycle)
      * of the receiver into its WA packet, thus to allow the sender to infer the
      * receiver's exact wake-up timing */
-    if (phase_now > _gnrc_lwmac_ticks_to_phase(gnrc_netdev->lwmac.last_wakeup)) {
+    if (phase_now > _gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup)) {
         lwmac_hdr.current_phase = (phase_now -
-                                   _gnrc_lwmac_ticks_to_phase(gnrc_netdev->lwmac.last_wakeup));
+                                   _gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup));
     }
     else {
         lwmac_hdr.current_phase = (phase_now + RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US)) -
-                                  _gnrc_lwmac_ticks_to_phase(gnrc_netdev->lwmac.last_wakeup);
+                                  _gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup);
     }
 
     pkt = gnrc_pktbuf_add(NULL, &lwmac_hdr, sizeof(lwmac_hdr), GNRC_NETTYPE_LWMAC);
     if (pkt == NULL) {
         LOG_ERROR("ERROR: [LWMAC-rx] Cannot allocate pktbuf of type GNRC_NETTYPE_LWMAC\n");
-        gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
+        gnrc_lwmac_set_quit_rx(netif, true);
         return false;
     }
     pkt_lwmac = pkt;
 
     pkt = gnrc_pktbuf_add(pkt, NULL,
-                          sizeof(gnrc_netif_hdr_t) + gnrc_netdev->rx.l2_addr.len,
+                          sizeof(gnrc_netif_hdr_t) + netif->mac.rx.l2_addr.len,
                           GNRC_NETTYPE_NETIF);
     if (pkt == NULL) {
         LOG_ERROR("ERROR: [LWMAC-rx] Cannot allocate pktbuf of type GNRC_NETTYPE_NETIF\n");
         gnrc_pktbuf_release(pkt_lwmac);
-        gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
+        gnrc_lwmac_set_quit_rx(netif, true);
         return false;
     }
 
@@ -170,44 +170,44 @@ static bool _send_wa(gnrc_netdev_t *gnrc_netdev)
     nethdr_wa = (gnrc_netif_hdr_t *)(gnrc_pktsnip_search_type(pkt,
                                                               GNRC_NETTYPE_NETIF)->data);
     /* Construct NETIF header and insert address for WA packet */
-    gnrc_netif_hdr_init(nethdr_wa, 0, gnrc_netdev->rx.l2_addr.len);
+    gnrc_netif_hdr_init(nethdr_wa, 0, netif->mac.rx.l2_addr.len);
 
     /* Send WA as broadcast*/
     nethdr_wa->flags |= GNRC_NETIF_HDR_FLAGS_BROADCAST;
 
     /* Disable Auto ACK */
     netopt_enable_t autoack = NETOPT_DISABLE;
-    gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK, &autoack,
-                                  sizeof(autoack));
+    netif->dev->driver->set(netif->dev, NETOPT_AUTOACK, &autoack,
+                            sizeof(autoack));
 
     /* Send WA */
-    if (gnrc_netdev->send(gnrc_netdev, pkt) < 0) {
+    if (_gnrc_lwmac_transmit(netif, pkt) < 0) {
         LOG_ERROR("ERROR: [LWMAC-rx] Send WA failed.");
         if (pkt != NULL) {
             gnrc_pktbuf_release(pkt);
         }
-        gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
+        gnrc_lwmac_set_quit_rx(netif, true);
         return false;
     }
 
     /* Enable Auto ACK again for data reception */
     autoack = NETOPT_ENABLE;
-    gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK, &autoack,
-                                  sizeof(autoack));
+    netif->dev->driver->set(netif->dev, NETOPT_AUTOACK, &autoack,
+                            sizeof(autoack));
 
     return true;
 }
 
-static uint8_t _packet_process_in_wait_for_data(gnrc_netdev_t *gnrc_netdev)
+static uint8_t _packet_process_in_wait_for_data(gnrc_netif2_t *netif)
 {
     uint8_t rx_info = 0;
     gnrc_pktsnip_t *pkt;
 
-    assert(gnrc_netdev != NULL);
+    assert(netif != NULL);
 
     pkt = NULL;
 
-    while ((pkt = gnrc_priority_pktqueue_pop(&gnrc_netdev->rx.queue)) != NULL) {
+    while ((pkt = gnrc_priority_pktqueue_pop(&netif->mac.rx.queue)) != NULL) {
         LOG_DEBUG("[LWMAC-rx] Inspecting pkt @ %p\n", pkt);
 
         /* Parse packet */
@@ -220,40 +220,40 @@ static uint8_t _packet_process_in_wait_for_data(gnrc_netdev_t *gnrc_netdev)
         }
 
         if (info.header->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) {
-            _gnrc_lwmac_dispatch_defer(gnrc_netdev->rx.dispatch_buffer, pkt);
-            gnrc_mac_dispatch(&gnrc_netdev->rx);
+            _gnrc_lwmac_dispatch_defer(netif->mac.rx.dispatch_buffer, pkt);
+            gnrc_mac_dispatch(&netif->mac.rx);
             /* quit listening period to avoid receiving duplicate broadcast packets */
-            gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
+            gnrc_lwmac_set_quit_rx(netif, true);
             continue;
         }
 
-        if (!(memcmp(&info.src_addr.addr, &gnrc_netdev->rx.l2_addr.addr,
-                     gnrc_netdev->rx.l2_addr.len) == 0)) {
+        if (!(memcmp(&info.src_addr.addr, &netif->mac.rx.l2_addr.addr,
+                     netif->mac.rx.l2_addr.len) == 0)) {
             LOG_DEBUG("[LWMAC-rx] Packet is not from destination\n");
             gnrc_pktbuf_release(pkt);
             /* Reset timeout to wait for the data packet */
-            gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
-            gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
+            gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
+            gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
             continue;
         }
 
-        if (!(memcmp(&info.dst_addr.addr, &gnrc_netdev->l2_addr,
-                     gnrc_netdev->l2_addr_len) == 0)) {
+        if (!(memcmp(&info.dst_addr.addr, &netif->l2addr,
+                     netif->l2addr_len) == 0)) {
             LOG_DEBUG("[LWMAC-rx] Packet is not for us\n");
             gnrc_pktbuf_release(pkt);
             /* Reset timeout to wait for the data packet */
-            gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
-            gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
+            gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
+            gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
             continue;
         }
 
         /* Sender maybe didn't get the WA */
         if (info.header->type == GNRC_LWMAC_FRAMETYPE_WR) {
             LOG_DEBUG("[LWMAC-rx] Found a WR while waiting for DATA\n");
-            gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
+            gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
             rx_info |= GNRC_LWMAC_RX_FOUND_WR;
             /* Push WR back to rx queue */
-            gnrc_mac_queue_rx_packet(&gnrc_netdev->rx, 0, pkt);
+            gnrc_mac_queue_rx_packet(&netif->mac.rx, 0, pkt);
             break;
         }
 
@@ -261,10 +261,10 @@ static uint8_t _packet_process_in_wait_for_data(gnrc_netdev_t *gnrc_netdev)
             case GNRC_LWMAC_FRAMETYPE_DATA:
             case GNRC_LWMAC_FRAMETYPE_DATA_PENDING: {
                 /* Receiver gets the data packet */
-                _gnrc_lwmac_dispatch_defer(gnrc_netdev->rx.dispatch_buffer, pkt);
-                gnrc_mac_dispatch(&gnrc_netdev->rx);
+                _gnrc_lwmac_dispatch_defer(netif->mac.rx.dispatch_buffer, pkt);
+                gnrc_mac_dispatch(&netif->mac.rx);
                 LOG_DEBUG("[LWMAC-rx] Found DATA!\n");
-                gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
+                gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
                 rx_info |= GNRC_LWMAC_RX_FOUND_DATA;
                 return rx_info;
             }
@@ -277,117 +277,117 @@ static uint8_t _packet_process_in_wait_for_data(gnrc_netdev_t *gnrc_netdev)
     return rx_info;
 }
 
-void gnrc_lwmac_rx_start(gnrc_netdev_t *gnrc_netdev)
+void gnrc_lwmac_rx_start(gnrc_netif2_t *netif)
 {
-    if (gnrc_netdev == NULL) {
+    if (netif == NULL) {
         return;
     }
 
     /* RX address should have been reset, probably not stopped then */
-    assert(gnrc_netdev->rx.l2_addr.len == 0);
+    assert(netif->mac.rx.l2_addr.len == 0);
 
     /* Don't attempt to send a WA if channel is busy to get timings right */
-    gnrc_netdev->mac_info &= ~GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
+    netif->mac.mac_info &= ~GNRC_NETIF2_MAC_INFO_CSMA_ENABLED;
     netopt_enable_t csma_disable = NETOPT_DISABLE;
-    gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA, &csma_disable,
-                                  sizeof(csma_disable));
+    netif->dev->driver->set(netif->dev, NETOPT_CSMA, &csma_disable,
+                            sizeof(csma_disable));
 
-    gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_INIT;
+    netif->mac.rx.state = GNRC_LWMAC_RX_STATE_INIT;
 }
 
-void gnrc_lwmac_rx_stop(gnrc_netdev_t *gnrc_netdev)
+void gnrc_lwmac_rx_stop(gnrc_netif2_t *netif)
 {
-    if (!gnrc_netdev) {
+    if (!netif) {
         return;
     }
 
-    gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
-    gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_STOPPED;
-    gnrc_netdev->rx.l2_addr.len = 0;
+    gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
+    netif->mac.rx.state = GNRC_LWMAC_RX_STATE_STOPPED;
+    netif->mac.rx.l2_addr.len = 0;
 }
 
 /* Returns whether rescheduling is needed or not */
-static bool _lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
+static bool _lwmac_rx_update(gnrc_netif2_t *netif)
 {
     bool reschedule = false;
 
-    if (!gnrc_netdev) {
+    if (!netif) {
         return reschedule;
     }
 
-    switch (gnrc_netdev->rx.state) {
+    switch (netif->mac.rx.state) {
         case GNRC_LWMAC_RX_STATE_INIT: {
-            gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
-            gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_WAIT_FOR_WR;
+            gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
+            netif->mac.rx.state = GNRC_LWMAC_RX_STATE_WAIT_FOR_WR;
             reschedule = true;
             break;
         }
         case GNRC_LWMAC_RX_STATE_WAIT_FOR_WR: {
             LOG_DEBUG("[LWMAC-rx] GNRC_LWMAC_RX_STATE_WAIT_FOR_WR\n");
 
-            uint8_t rx_info = _packet_process_in_wait_for_wr(gnrc_netdev);
+            uint8_t rx_info = _packet_process_in_wait_for_wr(netif);
 
             /* if found broadcast packet, goto rx successful */
             if (rx_info & GNRC_LWMAC_RX_FOUND_BROADCAST) {
-                gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_SUCCESSFUL;
+                netif->mac.rx.state = GNRC_LWMAC_RX_STATE_SUCCESSFUL;
                 reschedule = true;
                 break;
             }
 
             if (!(rx_info & GNRC_LWMAC_RX_FOUND_WR)) {
                 LOG_DEBUG("[LWMAC-rx] No WR found, stop RX\n");
-                gnrc_netdev->rx.rx_bad_exten_count++;
-                gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_FAILED;
+                netif->mac.rx.rx_bad_exten_count++;
+                netif->mac.rx.state = GNRC_LWMAC_RX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
 
-            gnrc_priority_pktqueue_flush(&gnrc_netdev->rx.queue);
+            gnrc_priority_pktqueue_flush(&netif->mac.rx.queue);
             /* Found WR packet (preamble), goto next state to send WA (preamble-ACK) */
-            gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_SEND_WA;
+            netif->mac.rx.state = GNRC_LWMAC_RX_STATE_SEND_WA;
             reschedule = true;
             break;
         }
         case GNRC_LWMAC_RX_STATE_SEND_WA: {
             LOG_DEBUG("[LWMAC-rx] GNRC_LWMAC_RX_STATE_SEND_WA\n");
 
-            if (!_send_wa(gnrc_netdev)) {
-                gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_FAILED;
+            if (!_send_wa(netif)) {
+                netif->mac.rx.state = GNRC_LWMAC_RX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
 
-            gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_WAIT_WA_SENT;
+            netif->mac.rx.state = GNRC_LWMAC_RX_STATE_WAIT_WA_SENT;
             reschedule = false;
             break;
         }
         case GNRC_LWMAC_RX_STATE_WAIT_WA_SENT: {
             LOG_DEBUG("[LWMAC-rx] GNRC_LWMAC_RX_STATE_WAIT_WA_SENT\n");
 
-            if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_UNDEF) {
+            if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_UNDEF) {
                 LOG_DEBUG("[LWMAC-rx] WA not yet completely sent\n");
                 break;
             }
 
             /* When reach here, WA has been sent, set timeout for expected data arrival */
-            gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
+            gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
 
-            _gnrc_lwmac_set_netdev_state(gnrc_netdev, NETOPT_STATE_IDLE);
-            gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA;
+            _gnrc_lwmac_set_netdev_state(netif, NETOPT_STATE_IDLE);
+            netif->mac.rx.state = GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA;
             reschedule = false;
             break;
         }
         case GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA: {
             LOG_DEBUG("[LWMAC-rx] GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA\n");
 
-            uint8_t rx_info = _packet_process_in_wait_for_data(gnrc_netdev);
+            uint8_t rx_info = _packet_process_in_wait_for_data(netif);
 
             /* If WA got lost we wait for data but we will be hammered with WR
              * packets. So a WR indicates a lost WA => reset RX state machine. */
             if (rx_info & GNRC_LWMAC_RX_FOUND_WR) {
                 LOG_INFO("[LWMAC-rx] WA probably got lost, reset RX state machine\n");
                 /* Start over again */
-                gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_INIT;
+                netif->mac.rx.state = GNRC_LWMAC_RX_STATE_INIT;
                 reschedule = true;
                 break;
             }
@@ -396,16 +396,16 @@ static bool _lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
              * received. This won't be blocked by WRs as they restart the state
              * machine (see above).
              */
-            if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA)) {
-                if (!gnrc_netdev_get_rx_started(gnrc_netdev)) {
+            if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_DATA)) {
+                if (!gnrc_netif2_get_rx_started(netif)) {
                     LOG_INFO("[LWMAC-rx] DATA timed out\n");
-                    gnrc_netdev->rx.rx_bad_exten_count++;
-                    gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_FAILED;
+                    netif->mac.rx.rx_bad_exten_count++;
+                    netif->mac.rx.state = GNRC_LWMAC_RX_STATE_FAILED;
                     reschedule = true;
                 }
                 else {
                     /* If radio is receiving packet, reset wait data timeout */
-                    gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
+                    gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
                 }
                 break;
             }
@@ -415,7 +415,7 @@ static bool _lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
                 break;
             }
 
-            gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_SUCCESSFUL;
+            netif->mac.rx.state = GNRC_LWMAC_RX_STATE_SUCCESSFUL;
             reschedule = true;
             break;
         }
@@ -430,8 +430,8 @@ static bool _lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
     return reschedule;
 }
 
-void gnrc_lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
+void gnrc_lwmac_rx_update(gnrc_netif2_t *netif)
 {
     /* Update until no rescheduling needed */
-    while (_lwmac_rx_update(gnrc_netdev)) {}
+    while (_lwmac_rx_update(netif)) {}
 }
diff --git a/sys/net/gnrc/link_layer/lwmac/timeout.c b/sys/net/gnrc/link_layer/lwmac/timeout.c
index 6291f2ee93..39fa8b7732 100644
--- a/sys/net/gnrc/link_layer/lwmac/timeout.c
+++ b/sys/net/gnrc/link_layer/lwmac/timeout.c
@@ -58,40 +58,40 @@ static int _lwmac_find_timeout(gnrc_lwmac_t *lwmac, gnrc_lwmac_timeout_type_t ty
     return -ENOENT;
 }
 
-inline bool gnrc_lwmac_timeout_is_running(gnrc_netdev_t *gnrc_netdev,
+inline bool gnrc_lwmac_timeout_is_running(gnrc_netif2_t *netif,
                                           gnrc_lwmac_timeout_type_t type)
 {
-    assert(gnrc_netdev);
-    return (_lwmac_find_timeout(&gnrc_netdev->lwmac, type) >= 0);
+    assert(netif);
+    return (_lwmac_find_timeout(&netif->mac.lwmac, type) >= 0);
 }
 
-bool gnrc_lwmac_timeout_is_expired(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_timeout_type_t type)
+bool gnrc_lwmac_timeout_is_expired(gnrc_netif2_t *netif, gnrc_lwmac_timeout_type_t type)
 {
-    assert(gnrc_netdev);
+    assert(netif);
 
-    int index = _lwmac_find_timeout(&gnrc_netdev->lwmac, type);
+    int index = _lwmac_find_timeout(&netif->mac.lwmac, type);
     if (index >= 0) {
-        if (gnrc_netdev->lwmac.timeouts[index].expired) {
-            _lwmac_clear_timeout(&gnrc_netdev->lwmac.timeouts[index]);
+        if (netif->mac.lwmac.timeouts[index].expired) {
+            _lwmac_clear_timeout(&netif->mac.lwmac.timeouts[index]);
         }
-        return gnrc_netdev->lwmac.timeouts[index].expired;
+        return netif->mac.lwmac.timeouts[index].expired;
     }
     return false;
 }
 
-gnrc_lwmac_timeout_t *_lwmac_acquire_timeout(gnrc_netdev_t *gnrc_netdev,
+gnrc_lwmac_timeout_t *_lwmac_acquire_timeout(gnrc_netif2_t *netif,
                                              gnrc_lwmac_timeout_type_t type)
 {
-    assert(gnrc_netdev);
+    assert(netif);
 
-    if (gnrc_lwmac_timeout_is_running(gnrc_netdev, type)) {
+    if (gnrc_lwmac_timeout_is_running(netif, type)) {
         return NULL;
     }
 
     for (unsigned i = 0; i < GNRC_LWMAC_TIMEOUT_COUNT; i++) {
-        if (gnrc_netdev->lwmac.timeouts[i].type == GNRC_LWMAC_TIMEOUT_DISABLED) {
-            gnrc_netdev->lwmac.timeouts[i].type = type;
-            return &gnrc_netdev->lwmac.timeouts[i];
+        if (netif->mac.lwmac.timeouts[i].type == GNRC_LWMAC_TIMEOUT_DISABLED) {
+            netif->mac.lwmac.timeouts[i].type = type;
+            return &netif->mac.lwmac.timeouts[i];
         }
     }
     return NULL;
@@ -104,31 +104,31 @@ void gnrc_lwmac_timeout_make_expire(gnrc_lwmac_timeout_t *timeout)
     timeout->expired = true;
 }
 
-void gnrc_lwmac_clear_timeout(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_timeout_type_t type)
+void gnrc_lwmac_clear_timeout(gnrc_netif2_t *netif, gnrc_lwmac_timeout_type_t type)
 {
-    assert(gnrc_netdev);
+    assert(netif);
 
-    int index = _lwmac_find_timeout(&gnrc_netdev->lwmac, type);
+    int index = _lwmac_find_timeout(&netif->mac.lwmac, type);
     if (index >= 0) {
-        _lwmac_clear_timeout(&gnrc_netdev->lwmac.timeouts[index]);
+        _lwmac_clear_timeout(&netif->mac.lwmac.timeouts[index]);
     }
 }
 
-void gnrc_lwmac_set_timeout(gnrc_netdev_t *gnrc_netdev,
+void gnrc_lwmac_set_timeout(gnrc_netif2_t *netif,
                             gnrc_lwmac_timeout_type_t type,
                             uint32_t offset)
 {
-    assert(gnrc_netdev);
+    assert(netif);
 
     gnrc_lwmac_timeout_t *timeout;
-    if ((timeout = _lwmac_acquire_timeout(gnrc_netdev, type))) {
+    if ((timeout = _lwmac_acquire_timeout(netif, type))) {
         DEBUG("[LWMAC] Set timeout %s in %" PRIu32 " us\n",
               lwmac_timeout_names[type], offset);
         timeout->expired = false;
         timeout->msg.type = GNRC_LWMAC_EVENT_TIMEOUT_TYPE;
         timeout->msg.content.ptr = (void *) timeout;
         xtimer_set_msg(&(timeout->timer), offset,
-                       &(timeout->msg), gnrc_netdev->pid);
+                       &(timeout->msg), netif->pid);
     }
     else {
         DEBUG("[LWMAC] Cannot set timeout %s, too many concurrent timeouts\n",
@@ -136,13 +136,13 @@ void gnrc_lwmac_set_timeout(gnrc_netdev_t *gnrc_netdev,
     }
 }
 
-void gnrc_lwmac_reset_timeouts(gnrc_netdev_t *gnrc_netdev)
+void gnrc_lwmac_reset_timeouts(gnrc_netif2_t *netif)
 {
-    assert(gnrc_netdev);
+    assert(netif);
 
     for (unsigned i = 0; i < GNRC_LWMAC_TIMEOUT_COUNT; i++) {
-        if (gnrc_netdev->lwmac.timeouts[i].type != GNRC_LWMAC_TIMEOUT_DISABLED) {
-            _lwmac_clear_timeout(&gnrc_netdev->lwmac.timeouts[i]);
+        if (netif->mac.lwmac.timeouts[i].type != GNRC_LWMAC_TIMEOUT_DISABLED) {
+            _lwmac_clear_timeout(&netif->mac.lwmac.timeouts[i]);
         }
     }
 }
diff --git a/sys/net/gnrc/link_layer/lwmac/tx_state_machine.c b/sys/net/gnrc/link_layer/lwmac/tx_state_machine.c
index 44df3bd520..c201b50968 100644
--- a/sys/net/gnrc/link_layer/lwmac/tx_state_machine.c
+++ b/sys/net/gnrc/link_layer/lwmac/tx_state_machine.c
@@ -49,77 +49,77 @@
  */
 #define GNRC_LWMAC_TX_FAIL            (0x02U)
 
-static uint8_t _send_bcast(gnrc_netdev_t *gnrc_netdev)
+static uint8_t _send_bcast(gnrc_netif2_t *netif)
 {
-    assert(gnrc_netdev != NULL);
+    assert(netif != NULL);
 
     uint8_t tx_info = 0;
-    gnrc_pktsnip_t *pkt = gnrc_netdev->tx.packet;
+    gnrc_pktsnip_t *pkt = netif->mac.tx.packet;
     bool first = false;
 
-    if (gnrc_lwmac_timeout_is_running(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END)) {
-        if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END)) {
-            gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
+    if (gnrc_lwmac_timeout_is_running(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END)) {
+        if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END)) {
+            gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
             gnrc_pktbuf_release(pkt);
-            gnrc_netdev->tx.packet = NULL;
+            netif->mac.tx.packet = NULL;
             tx_info |= GNRC_LWMAC_TX_SUCCESS;
             return tx_info;
         }
     }
     else {
         LOG_INFO("[LWMAC-tx] Initialize broadcasting\n");
-        gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END,
-                          GNRC_LWMAC_BROADCAST_DURATION_US);
+        gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END,
+                               GNRC_LWMAC_BROADCAST_DURATION_US);
 
         gnrc_pktsnip_t *pkt_payload;
 
         /* Prepare packet with LWMAC header*/
         gnrc_lwmac_frame_broadcast_t hdr = {};
         hdr.header.type = GNRC_LWMAC_FRAMETYPE_BROADCAST;
-        hdr.seq_nr = gnrc_netdev->tx.bcast_seqnr++;
+        hdr.seq_nr = netif->mac.tx.bcast_seqnr++;
 
         pkt_payload = pkt->next;
         pkt->next = gnrc_pktbuf_add(pkt->next, &hdr, sizeof(hdr), GNRC_NETTYPE_LWMAC);
         if (pkt->next == NULL) {
             LOG_ERROR("ERROR: [LWMAC-tx] Cannot allocate pktbuf of type FRAMETYPE_BROADCAST\n");
-            gnrc_netdev->tx.packet->next = pkt_payload;
+            netif->mac.tx.packet->next = pkt_payload;
             /* Drop the broadcast packet */
             LOG_ERROR("ERROR: [LWMAC-tx] Memory maybe full, drop the broadcast packet\n");
-            gnrc_pktbuf_release(gnrc_netdev->tx.packet);
+            gnrc_pktbuf_release(netif->mac.tx.packet);
             /* clear packet point to avoid TX retry */
-            gnrc_netdev->tx.packet = NULL;
+            netif->mac.tx.packet = NULL;
             tx_info |= GNRC_LWMAC_TX_FAIL;
             return tx_info;
         }
 
         /* No Auto-ACK for broadcast packets */
         netopt_enable_t autoack = NETOPT_DISABLE;
-        gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK, &autoack,
-                                      sizeof(autoack));
+        netif->dev->driver->set(netif->dev, NETOPT_AUTOACK, &autoack,
+                                sizeof(autoack));
         first = true;
     }
 
-    if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST) ||
+    if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST) ||
         first) {
         /* if found ongoing transmission, quit this cycle for collision avoidance.
-         * Broadcast packet will be re-queued and try to send in the next cycle. */
-        if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
+        * Broadcast packet will be re-queued and try to send in the next cycle. */
+        if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
             /* save pointer to netif header */
-            gnrc_pktsnip_t *netif = pkt->next->next;
+            gnrc_pktsnip_t *netif_snip = pkt->next->next;
 
             /* remove LWMAC header */
             pkt->next->next = NULL;
             gnrc_pktbuf_release(pkt->next);
 
             /* make append netif header after payload again */
-            pkt->next = netif;
+            pkt->next = netif_snip;
 
-            if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
-                gnrc_pktbuf_release(gnrc_netdev->tx.packet);
+            if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
+                gnrc_pktbuf_release(netif->mac.tx.packet);
                 LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
             }
             /* drop pointer so it wont be free'd */
-            gnrc_netdev->tx.packet = NULL;
+            netif->mac.tx.packet = NULL;
             tx_info |= GNRC_LWMAC_TX_FAIL;
             return tx_info;
         }
@@ -127,24 +127,24 @@ static uint8_t _send_bcast(gnrc_netdev_t *gnrc_netdev)
         /* Don't let the packet be released yet, we want to send it again */
         gnrc_pktbuf_hold(pkt, 1);
 
-        int res = gnrc_netdev->send(gnrc_netdev, pkt);
+        int res = _gnrc_lwmac_transmit(netif, pkt);
         if (res < 0) {
             LOG_ERROR("ERROR: [LWMAC-tx] Send broadcast pkt failed.");
             tx_info |= GNRC_LWMAC_TX_FAIL;
             return tx_info;
         }
 
-        gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST,
-                          GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US);
+        gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST,
+                               GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US);
         LOG_INFO("[LWMAC-tx] Broadcast sent\n");
     }
 
     return tx_info;
 }
 
-static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
+static uint8_t _send_wr(gnrc_netif2_t *netif)
 {
-    assert(gnrc_netdev != NULL);
+    assert(netif != NULL);
 
     uint8_t tx_info = 0;
     gnrc_pktsnip_t *pkt;
@@ -153,13 +153,13 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
 
     /* if found ongoing transmission, quit this cycle for collision avoidance.
      * Data packet will be re-queued and try to send in the next cycle. */
-    if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
-        if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
-            gnrc_pktbuf_release(gnrc_netdev->tx.packet);
+    if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
+        if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
+            gnrc_pktbuf_release(netif->mac.tx.packet);
             LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
         }
         /* drop pointer so it wont be free'd */
-        gnrc_netdev->tx.packet = NULL;
+        netif->mac.tx.packet = NULL;
         tx_info |= GNRC_LWMAC_TX_FAIL;
         return tx_info;
     }
@@ -167,17 +167,17 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
     /* Assemble WR */
     gnrc_lwmac_frame_wr_t wr_hdr = {};
     wr_hdr.header.type = GNRC_LWMAC_FRAMETYPE_WR;
-    memcpy(&(wr_hdr.dst_addr.addr), gnrc_netdev->tx.current_neighbor->l2_addr,
-           gnrc_netdev->tx.current_neighbor->l2_addr_len);
-    wr_hdr.dst_addr.len = gnrc_netdev->tx.current_neighbor->l2_addr_len;
+    memcpy(&(wr_hdr.dst_addr.addr), netif->mac.tx.current_neighbor->l2_addr,
+           netif->mac.tx.current_neighbor->l2_addr_len);
+    wr_hdr.dst_addr.len = netif->mac.tx.current_neighbor->l2_addr_len;
 
     pkt = gnrc_pktbuf_add(NULL, &wr_hdr, sizeof(wr_hdr), GNRC_NETTYPE_LWMAC);
     if (pkt == NULL) {
         LOG_ERROR("ERROR: [LWMAC-tx] Cannot allocate pktbuf of type GNRC_NETTYPE_LWMAC\n");
-        gnrc_pktbuf_release(gnrc_netdev->tx.packet);
+        gnrc_pktbuf_release(netif->mac.tx.packet);
         LOG_ERROR("ERROR: [LWMAC-tx] Memory maybe full, drop the data packet\n");
         /* clear packet point to avoid TX retry */
-        gnrc_netdev->tx.packet = NULL;
+        netif->mac.tx.packet = NULL;
         tx_info |= GNRC_LWMAC_TX_FAIL;
         return tx_info;
     }
@@ -190,9 +190,9 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
         LOG_ERROR("ERROR: [LWMAC-tx] Cannot allocate pktbuf of type GNRC_NETTYPE_NETIF\n");
         gnrc_pktbuf_release(pkt_lwmac);
         LOG_ERROR("ERROR: [LWMAC-tx] Memory maybe full, drop the data packet\n");
-        gnrc_pktbuf_release(gnrc_netdev->tx.packet);
+        gnrc_pktbuf_release(netif->mac.tx.packet);
         /* clear packet point to avoid TX retry */
-        gnrc_netdev->tx.packet = NULL;
+        netif->mac.tx.packet = NULL;
         tx_info |= GNRC_LWMAC_TX_FAIL;
         return tx_info;
     }
@@ -209,12 +209,12 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
 
     /* Disable Auto ACK */
     netopt_enable_t autoack = NETOPT_DISABLE;
-    gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK, &autoack,
-                                  sizeof(autoack));
+    netif->dev->driver->set(netif->dev, NETOPT_AUTOACK, &autoack,
+                            sizeof(autoack));
 
     /* Prepare WR, this will discard any frame in the transceiver that has
-     * possibly arrived in the meantime but we don't care at this point. */
-    int res = gnrc_netdev->send(gnrc_netdev, pkt);
+    * possibly arrived in the meantime but we don't care at this point. */
+    int res = _gnrc_lwmac_transmit(netif, pkt);
     if (res < 0) {
         LOG_ERROR("ERROR: [LWMAC-tx] Send WR failed.");
         if (pkt != NULL) {
@@ -224,13 +224,13 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
         return tx_info;
     }
 
-    gnrc_priority_pktqueue_flush(&gnrc_netdev->rx.queue);
+    gnrc_priority_pktqueue_flush(&netif->mac.rx.queue);
     return tx_info;
 }
 
-static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
+static uint8_t _packet_process_in_wait_for_wa(gnrc_netif2_t *netif)
 {
-    assert(gnrc_netdev != NULL);
+    assert(netif != NULL);
 
     uint8_t tx_info = 0;
     gnrc_pktsnip_t *pkt;
@@ -238,7 +238,7 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
     bool postponed = false;
     bool from_expected_destination = false;
 
-    while ((pkt = gnrc_priority_pktqueue_pop(&gnrc_netdev->rx.queue)) != NULL) {
+    while ((pkt = gnrc_priority_pktqueue_pop(&netif->mac.rx.queue)) != NULL) {
         LOG_DEBUG("[LWMAC-tx] Inspecting pkt @ %p\n", pkt);
 
         /* Parse packet */
@@ -251,14 +251,14 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
             continue;
         }
 
-        if (memcmp(&info.src_addr.addr, &gnrc_netdev->tx.current_neighbor->l2_addr,
-                   gnrc_netdev->tx.current_neighbor->l2_addr_len) == 0) {
+        if (memcmp(&info.src_addr.addr, &netif->mac.tx.current_neighbor->l2_addr,
+                   netif->mac.tx.current_neighbor->l2_addr_len) == 0) {
             from_expected_destination = true;
         }
 
         if (info.header->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) {
-            _gnrc_lwmac_dispatch_defer(gnrc_netdev->rx.dispatch_buffer, pkt);
-            gnrc_mac_dispatch(&gnrc_netdev->rx);
+            _gnrc_lwmac_dispatch_defer(netif->mac.rx.dispatch_buffer, pkt);
+            gnrc_mac_dispatch(&netif->mac.rx);
             /* Drop pointer to it can't get released */
             pkt = NULL;
             continue;
@@ -267,14 +267,14 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
         /* Check if destination is talking to another node. It will sleep
          * after a finished transaction so there's no point in trying any
          * further now. */
-        if (!(memcmp(&info.dst_addr.addr, &gnrc_netdev->l2_addr,
-                     gnrc_netdev->l2_addr_len) == 0) && from_expected_destination) {
-            if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
-                gnrc_pktbuf_release(gnrc_netdev->tx.packet);
+        if (!(memcmp(&info.dst_addr.addr, &netif->l2addr,
+                     netif->l2addr_len) == 0) && from_expected_destination) {
+            if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
+                gnrc_pktbuf_release(netif->mac.tx.packet);
                 LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
             }
             /* drop pointer so it wont be free'd */
-            gnrc_netdev->tx.packet = NULL;
+            netif->mac.tx.packet = NULL;
             postponed = true;
             gnrc_pktbuf_release(pkt);
             break;
@@ -283,12 +283,12 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
         /* if found anther node is also trying to send data,
          * quit this cycle for collision avoidance. */
         if (info.header->type == GNRC_LWMAC_FRAMETYPE_WR) {
-            if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
-                gnrc_pktbuf_release(gnrc_netdev->tx.packet);
+            if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
+                gnrc_pktbuf_release(netif->mac.tx.packet);
                 LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
             }
             /* drop pointer so it wont be free'd */
-            gnrc_netdev->tx.packet = NULL;
+            netif->mac.tx.packet = NULL;
             postponed = true;
             gnrc_pktbuf_release(pkt);
             break;
@@ -302,33 +302,33 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
 
         if (from_expected_destination) {
             /* calculate the phase of the receiver based on WA */
-            gnrc_netdev->tx.timestamp = _gnrc_lwmac_phase_now();
+            netif->mac.tx.timestamp = _gnrc_lwmac_phase_now();
             gnrc_lwmac_frame_wa_t *wa_hdr;
             wa_hdr = (gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_LWMAC))->data;
 
-            if (gnrc_netdev->tx.timestamp >= wa_hdr->current_phase) {
-                gnrc_netdev->tx.timestamp = gnrc_netdev->tx.timestamp -
-                                            wa_hdr->current_phase;
+            if (netif->mac.tx.timestamp >= wa_hdr->current_phase) {
+                netif->mac.tx.timestamp = netif->mac.tx.timestamp -
+                                          wa_hdr->current_phase;
             }
             else {
-                gnrc_netdev->tx.timestamp += RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US);
-                gnrc_netdev->tx.timestamp -= wa_hdr->current_phase;
+                netif->mac.tx.timestamp += RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US);
+                netif->mac.tx.timestamp -= wa_hdr->current_phase;
             }
 
             uint32_t own_phase;
-            own_phase = _gnrc_lwmac_ticks_to_phase(gnrc_netdev->lwmac.last_wakeup);
+            own_phase = _gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup);
 
-            if (own_phase >= gnrc_netdev->tx.timestamp) {
-                own_phase = own_phase - gnrc_netdev->tx.timestamp;
+            if (own_phase >= netif->mac.tx.timestamp) {
+                own_phase = own_phase - netif->mac.tx.timestamp;
             }
             else {
-                own_phase = gnrc_netdev->tx.timestamp - own_phase;
+                own_phase = netif->mac.tx.timestamp - own_phase;
             }
 
             if ((own_phase < RTT_US_TO_TICKS((3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2))) ||
                 (own_phase > RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US -
                                              (3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2)))) {
-                gnrc_netdev_lwmac_set_phase_backoff(gnrc_netdev, true);
+                gnrc_lwmac_set_phase_backoff(netif, true);
                 LOG_WARNING("WARNING: [LWMAC-tx] phase close\n");
             }
         }
@@ -342,7 +342,7 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
         }
 
         /* All checks passed so this must be a valid WA */
-        gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR);
+        gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_WR);
 
         found_wa = true;
         break;
@@ -360,39 +360,39 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
     }
 
     /* Save newly calculated phase for destination */
-    gnrc_netdev->tx.current_neighbor->phase = gnrc_netdev->tx.timestamp;
-    LOG_INFO("[LWMAC-tx] New phase: %" PRIu32 "\n", gnrc_netdev->tx.timestamp);
+    netif->mac.tx.current_neighbor->phase = netif->mac.tx.timestamp;
+    LOG_INFO("[LWMAC-tx] New phase: %" PRIu32 "\n", netif->mac.tx.timestamp);
 
     /* We've got our WA, so discard the rest, TODO: no flushing */
-    gnrc_priority_pktqueue_flush(&gnrc_netdev->rx.queue);
+    gnrc_priority_pktqueue_flush(&netif->mac.rx.queue);
 
     tx_info |= GNRC_LWMAC_TX_SUCCESS;
     return tx_info;
 }
 
 /* return false if send data failed, otherwise return true */
-static bool _send_data(gnrc_netdev_t *gnrc_netdev)
+static bool _send_data(gnrc_netif2_t *netif)
 {
-    assert(gnrc_netdev != NULL);
+    assert(netif != NULL);
 
-    gnrc_pktsnip_t *pkt = gnrc_netdev->tx.packet;
+    gnrc_pktsnip_t *pkt = netif->mac.tx.packet;
     gnrc_pktsnip_t *pkt_payload;
 
     /* Enable Auto ACK again */
     netopt_enable_t autoack = NETOPT_ENABLE;
-    gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK,
-                                  &autoack, sizeof(autoack));
+    netif->dev->driver->set(netif->dev, NETOPT_AUTOACK,
+                            &autoack, sizeof(autoack));
 
     /* It's okay to retry sending DATA. Timing doesn't matter anymore and
      * destination is waiting for a certain amount of time. */
     uint8_t csma_retries = GNRC_LWMAC_DATA_CSMA_RETRIES;
-    gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA_RETRIES,
-                                  &csma_retries, sizeof(csma_retries));
+    netif->dev->driver->set(netif->dev, NETOPT_CSMA_RETRIES,
+                            &csma_retries, sizeof(csma_retries));
 
-    gnrc_netdev->mac_info |= GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
+    netif->mac.mac_info |= GNRC_NETIF2_MAC_INFO_CSMA_ENABLED;
     netopt_enable_t csma_enable = NETOPT_ENABLE;
-    gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA,
-                                  &csma_enable, sizeof(csma_enable));
+    netif->dev->driver->set(netif->dev, NETOPT_CSMA,
+                            &csma_enable, sizeof(csma_enable));
 
     pkt_payload = pkt->next;
 
@@ -403,198 +403,198 @@ static bool _send_data(gnrc_netdev_t *gnrc_netdev)
      * In case the sender has no more packet for the receiver, it simply sets the
      * data type to FRAMETYPE_DATA. */
     gnrc_lwmac_hdr_t hdr;
-    if ((gnrc_priority_pktqueue_length(&gnrc_netdev->tx.current_neighbor->queue) > 0) &&
-        (gnrc_netdev->tx.tx_burst_count < GNRC_LWMAC_MAX_TX_BURST_PKT_NUM)) {
+    if ((gnrc_priority_pktqueue_length(&netif->mac.tx.current_neighbor->queue) > 0) &&
+        (netif->mac.tx.tx_burst_count < GNRC_LWMAC_MAX_TX_BURST_PKT_NUM)) {
         hdr.type = GNRC_LWMAC_FRAMETYPE_DATA_PENDING;
-        gnrc_netdev_lwmac_set_tx_continue(gnrc_netdev, true);
-        gnrc_netdev->tx.tx_burst_count++;
+        gnrc_lwmac_set_tx_continue(netif, true);
+        netif->mac.tx.tx_burst_count++;
     }
     else {
         hdr.type = GNRC_LWMAC_FRAMETYPE_DATA;
-        gnrc_netdev_lwmac_set_tx_continue(gnrc_netdev, false);
+        gnrc_lwmac_set_tx_continue(netif, false);
     }
 
     pkt->next = gnrc_pktbuf_add(pkt->next, &hdr, sizeof(hdr), GNRC_NETTYPE_LWMAC);
     if (pkt->next == NULL) {
         LOG_ERROR("ERROR: [LWMAC-tx] Cannot allocate pktbuf of type GNRC_NETTYPE_LWMAC\n");
         LOG_ERROR("ERROR: [LWMAC-tx] Memory maybe full, drop the data packet\n");
-        gnrc_netdev->tx.packet->next = pkt_payload;
-        gnrc_pktbuf_release(gnrc_netdev->tx.packet);
+        netif->mac.tx.packet->next = pkt_payload;
+        gnrc_pktbuf_release(netif->mac.tx.packet);
         /* clear packet point to avoid TX retry */
-        gnrc_netdev->tx.packet = NULL;
+        netif->mac.tx.packet = NULL;
         return false;
     }
 
     /* if found ongoing transmission, quit this cycle for collision avoidance.
      * Data packet will be re-queued and try to send in the next cycle. */
-    if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
+    if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
         /* save pointer to netif header */
-        gnrc_pktsnip_t *netif = pkt->next->next;
+        gnrc_pktsnip_t *netif_snip = pkt->next->next;
 
         /* remove LWMAC header */
         pkt->next->next = NULL;
         gnrc_pktbuf_release(pkt->next);
 
         /* make append netif header after payload again */
-        pkt->next = netif;
+        pkt->next = netif_snip;
 
-        if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
-            gnrc_pktbuf_release(gnrc_netdev->tx.packet);
+        if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
+            gnrc_pktbuf_release(netif->mac.tx.packet);
             LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
         }
         /* drop pointer so it wont be free'd */
-        gnrc_netdev->tx.packet = NULL;
+        netif->mac.tx.packet = NULL;
         return false;
     }
 
     /* Send data */
-    int res = gnrc_netdev->send(gnrc_netdev, pkt);
+    int res = _gnrc_lwmac_transmit(netif, pkt);
     if (res < 0) {
         LOG_ERROR("ERROR: [LWMAC-tx] Send data failed.");
         if (pkt != NULL) {
             gnrc_pktbuf_release(pkt);
         }
         /* clear packet point to avoid TX retry */
-        gnrc_netdev->tx.packet = NULL;
+        netif->mac.tx.packet = NULL;
         return false;
     }
 
     /* Packet has been released by netdev, so drop pointer */
-    gnrc_netdev->tx.packet = NULL;
+    netif->mac.tx.packet = NULL;
 
-    DEBUG("[LWMAC-tx]: spent %lu WR in TX\n", gnrc_netdev->tx.wr_sent);
+    DEBUG("[LWMAC-tx]: spent %lu WR in TX\n", netif->mac.tx.wr_sent);
 
 #if (LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
-    gnrc_netdev->lwmac.pkt_start_sending_time_ticks =
-        rtt_get_counter() - gnrc_netdev->lwmac.pkt_start_sending_time_ticks;
+    netif->mac.lwmac.pkt_start_sending_time_ticks =
+        rtt_get_counter() - netif->mac.lwmac.pkt_start_sending_time_ticks;
     DEBUG("[LWMAC-tx]: pkt sending delay in TX: %lu us\n",
-          RTT_TICKS_TO_US(gnrc_netdev->lwmac.pkt_start_sending_time_ticks));
+          RTT_TICKS_TO_US(netif->mac.lwmac.pkt_start_sending_time_ticks));
 #endif
 
     return true;
 }
 
-void gnrc_lwmac_tx_start(gnrc_netdev_t *gnrc_netdev,
+void gnrc_lwmac_tx_start(gnrc_netif2_t *netif,
                          gnrc_pktsnip_t *pkt,
                          gnrc_mac_tx_neighbor_t *neighbor)
 {
-    assert(gnrc_netdev != NULL);
+    assert(netif != NULL);
     assert(pkt != NULL);
     assert(neighbor != NULL);
 
-    if (gnrc_netdev->tx.packet) {
+    if (netif->mac.tx.packet) {
         LOG_WARNING("WARNING: [LWMAC-tx] Starting but tx.packet is still set\n");
-        gnrc_pktbuf_release(gnrc_netdev->tx.packet);
+        gnrc_pktbuf_release(netif->mac.tx.packet);
     }
 
-    gnrc_netdev->tx.packet = pkt;
-    gnrc_netdev->tx.current_neighbor = neighbor;
-    gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_INIT;
-    gnrc_netdev->tx.wr_sent = 0;
+    netif->mac.tx.packet = pkt;
+    netif->mac.tx.current_neighbor = neighbor;
+    netif->mac.tx.state = GNRC_LWMAC_TX_STATE_INIT;
+    netif->mac.tx.wr_sent = 0;
 
 #if (LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
-    gnrc_netdev->lwmac.pkt_start_sending_time_ticks = rtt_get_counter();
+    netif->mac.lwmac.pkt_start_sending_time_ticks = rtt_get_counter();
 #endif
 }
 
-void gnrc_lwmac_tx_stop(gnrc_netdev_t *gnrc_netdev)
+void gnrc_lwmac_tx_stop(gnrc_netif2_t *netif)
 {
-    assert(gnrc_netdev != NULL);
+    assert(netif != NULL);
 
-    gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR);
-    gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE);
-    gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
-    gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END);
-    gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_STOPPED;
+    gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_WR);
+    gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE);
+    gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
+    gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END);
+    netif->mac.tx.state = GNRC_LWMAC_TX_STATE_STOPPED;
 
     /* Release packet in case of failure */
-    if (gnrc_netdev->tx.packet) {
-        if (gnrc_netdev->tx.tx_retry_count >= GNRC_LWMAC_MAX_DATA_TX_RETRIES) {
-            gnrc_netdev->tx.tx_retry_count = 0;
-            gnrc_pktbuf_release(gnrc_netdev->tx.packet);
-            gnrc_netdev->tx.packet = NULL;
+    if (netif->mac.tx.packet) {
+        if (netif->mac.tx.tx_retry_count >= GNRC_LWMAC_MAX_DATA_TX_RETRIES) {
+            netif->mac.tx.tx_retry_count = 0;
+            gnrc_pktbuf_release(netif->mac.tx.packet);
+            netif->mac.tx.packet = NULL;
             LOG_WARNING("WARNING: [LWMAC-tx] Drop TX packet\n");
         }
         else {
-            gnrc_netdev->tx.tx_retry_count++;
+            netif->mac.tx.tx_retry_count++;
             return;
         }
     }
 
-    if (!gnrc_netdev_lwmac_get_tx_continue(gnrc_netdev)) {
-        gnrc_netdev->tx.current_neighbor = NULL;
+    if (!gnrc_lwmac_get_tx_continue(netif)) {
+        netif->mac.tx.current_neighbor = NULL;
     }
 }
 
 /* Returns whether rescheduling is needed or not */
-static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
+static bool _lwmac_tx_update(gnrc_netif2_t *netif)
 {
-    assert(gnrc_netdev != NULL);
+    assert(netif != NULL);
 
     bool reschedule = false;
 
-    switch (gnrc_netdev->tx.state) {
+    switch (netif->mac.tx.state) {
         case GNRC_LWMAC_TX_STATE_INIT: {
-            gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR);
-            gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE);
-            gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
-            gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END);
+            gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_WR);
+            gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE);
+            gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
+            gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END);
 
             /* if found ongoing transmission,
              * quit this cycle for collision avoidance. */
-            if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
-                if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
-                    gnrc_pktbuf_release(gnrc_netdev->tx.packet);
+            if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
+                if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
+                    gnrc_pktbuf_release(netif->mac.tx.packet);
                     LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
                 }
                 /* drop pointer so it wont be free'd */
-                gnrc_netdev->tx.packet = NULL;
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+                netif->mac.tx.packet = NULL;
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
 
             /* check if the packet is for broadcast */
-            if (gnrc_netif_hdr_get_flag(gnrc_netdev->tx.packet) &
+            if (gnrc_netif_hdr_get_flag(netif->mac.tx.packet) &
                 (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) {
                 /* Set CSMA retries as configured and enable */
                 uint8_t csma_retries = GNRC_LWMAC_BROADCAST_CSMA_RETRIES;
-                gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA_RETRIES,
-                                              &csma_retries, sizeof(csma_retries));
-                gnrc_netdev->mac_info |= GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
+                netif->dev->driver->set(netif->dev, NETOPT_CSMA_RETRIES,
+                                        &csma_retries, sizeof(csma_retries));
+                netif->mac.mac_info |= GNRC_NETIF2_MAC_INFO_CSMA_ENABLED;
                 netopt_enable_t csma_enable = NETOPT_ENABLE;
-                gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA,
-                                              &csma_enable, sizeof(csma_enable));
+                netif->dev->driver->set(netif->dev, NETOPT_CSMA,
+                                        &csma_enable, sizeof(csma_enable));
 
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SEND_BROADCAST;
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_BROADCAST;
                 reschedule = true;
                 break;
             }
             else {
                 /* Use CSMA for the first WR */
-                gnrc_netdev->mac_info |= GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
+                netif->mac.mac_info |= GNRC_NETIF2_MAC_INFO_CSMA_ENABLED;
                 netopt_enable_t csma_disable = NETOPT_ENABLE;
-                gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA,
-                                              &csma_disable, sizeof(csma_disable));
+                netif->dev->driver->set(netif->dev, NETOPT_CSMA,
+                                        &csma_disable, sizeof(csma_disable));
                 /* Set a timeout for the maximum transmission procedure */
-                gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE, GNRC_LWMAC_PREAMBLE_DURATION_US);
+                gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE, GNRC_LWMAC_PREAMBLE_DURATION_US);
 
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SEND_WR;
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_WR;
                 reschedule = true;
                 break;
             }
         }
         case GNRC_LWMAC_TX_STATE_SEND_BROADCAST: {
-            uint8_t tx_info = _send_bcast(gnrc_netdev);
+            uint8_t tx_info = _send_bcast(netif);
 
             if (tx_info & GNRC_LWMAC_TX_SUCCESS) {
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SUCCESSFUL;
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SUCCESSFUL;
                 reschedule = true;
                 break;
             }
 
             if (tx_info & GNRC_LWMAC_TX_FAIL) {
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
@@ -603,23 +603,23 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
         }
         case GNRC_LWMAC_TX_STATE_SEND_WR: {
             /* In case of no Tx-isr error (e.g., no Tx-isr), goto TX failure. */
-            if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
+            if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
                 LOG_WARNING("WARNING: [LWMAC-tx] No response from destination, "
-                                 "probably no TX-ISR\n");
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+                            "probably no TX-ISR\n");
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
             LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_SEND_WR\n");
-            uint8_t tx_info = _send_wr(gnrc_netdev);
+            uint8_t tx_info = _send_wr(netif);
 
             if (tx_info & GNRC_LWMAC_TX_FAIL) {
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
 
-            gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_WAIT_WR_SENT;
+            netif->mac.tx.state = GNRC_LWMAC_TX_STATE_WAIT_WR_SENT;
             reschedule = false;
             break;
         }
@@ -627,84 +627,84 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
             LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_WAIT_WR_SENT\n");
 
             /* In case of no Tx-isr error (e.g., no Tx-isr), goto TX failure. */
-            if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
+            if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
                 LOG_WARNING("WARNING: [LWMAC-tx] No response from destination\n");
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
 
-            if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_UNDEF) {
+            if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_UNDEF) {
                 LOG_DEBUG("[LWMAC-tx] WR not yet completely sent\n");
                 break;
             }
 
             /* If found ongoing transmission, goto TX failure, i.e., postpone transmission to
              * next cycle. This is mainly for collision avoidance. */
-            if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_BUSY) {
-                if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
-                    gnrc_pktbuf_release(gnrc_netdev->tx.packet);
+            if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_BUSY) {
+                if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
+                    gnrc_pktbuf_release(netif->mac.tx.packet);
                     LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
                 }
                 /* clear packet point to avoid TX retry */
-                gnrc_netdev->tx.packet = NULL;
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+                netif->mac.tx.packet = NULL;
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
 
-            if (gnrc_netdev->tx.wr_sent == 0) {
+            if (netif->mac.tx.wr_sent == 0) {
                 /* Only the first WR use CSMA */
-                gnrc_netdev->mac_info &= ~GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
+                netif->mac.mac_info &= ~GNRC_NETIF2_MAC_INFO_CSMA_ENABLED;
                 netopt_enable_t csma_disable = NETOPT_DISABLE;
-                gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA,
-                                              &csma_disable, sizeof(csma_disable));
+                netif->dev->driver->set(netif->dev, NETOPT_CSMA,
+                                        &csma_disable, sizeof(csma_disable));
             }
 
-            gnrc_netdev->tx.wr_sent++;
+            netif->mac.tx.wr_sent++;
 
             /* Set timeout for next WR in case no WA will be received */
-            gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR, GNRC_LWMAC_TIME_BETWEEN_WR_US);
+            gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_WR, GNRC_LWMAC_TIME_BETWEEN_WR_US);
 
             /* Debug WR timing */
             LOG_DEBUG("[LWMAC-tx] Destination phase was: %" PRIu32 "\n",
-                           gnrc_netdev->tx.current_neighbor->phase);
+                      netif->mac.tx.current_neighbor->phase);
             LOG_DEBUG("[LWMAC-tx] Phase when sent was:   %" PRIu32 "\n",
-                           _gnrc_lwmac_ticks_to_phase(gnrc_netdev->tx.timestamp));
+                      _gnrc_lwmac_ticks_to_phase(netif->mac.tx.timestamp));
             LOG_DEBUG("[LWMAC-tx] Ticks when sent was:   %" PRIu32 "\n",
-                           gnrc_netdev->tx.timestamp);
-            _gnrc_lwmac_set_netdev_state(gnrc_netdev, NETOPT_STATE_IDLE);
-            gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_WAIT_FOR_WA;
+                      netif->mac.tx.timestamp);
+            _gnrc_lwmac_set_netdev_state(netif, NETOPT_STATE_IDLE);
+            netif->mac.tx.state = GNRC_LWMAC_TX_STATE_WAIT_FOR_WA;
             reschedule = false;
             break;
         }
         case GNRC_LWMAC_TX_STATE_WAIT_FOR_WA: {
             LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_WAIT_FOR_WA\n");
 
-            if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
+            if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
                 LOG_WARNING("WARNING: [LWMAC-tx] No response from destination\n");
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
 
-            if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR)) {
+            if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_WR)) {
                 /* In case the sender is in consecutive (burst) transmission to the receiver,
                  * meaning that the sender has already successfully sent at least one data to
                  * the receiver, then the sender will only spend one WR for triggering the next
                  * transmission procedure. And, if this WR doesn't work (no WA replied), the
                  * sender regards consecutive transmission failed.
                  */
-                if (gnrc_netdev_lwmac_get_tx_continue(gnrc_netdev)) {
+                if (gnrc_lwmac_get_tx_continue(netif)) {
                     LOG_DEBUG("[LWMAC-tx] Tx burst fail\n");
-                    if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
-                        gnrc_pktbuf_release(gnrc_netdev->tx.packet);
+                    if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
+                        gnrc_pktbuf_release(netif->mac.tx.packet);
                         LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
                     }
                     /* drop pointer so it wont be free'd */
-                    gnrc_netdev->tx.packet = NULL;
+                    netif->mac.tx.packet = NULL;
 
-                    gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+                    netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
                     reschedule = true;
                     break;
                 }
@@ -713,27 +713,27 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
                      * latter's wake-up period, the sender just keep sending WRs until it
                      * finds the WA.
                      */
-                    gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SEND_WR;
+                    netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_WR;
                     reschedule = true;
                     break;
                 }
             }
 
-            if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
+            if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
                 /* Wait for completion of frame reception */
                 break;
             }
 
-            uint8_t tx_info = _packet_process_in_wait_for_wa(gnrc_netdev);
+            uint8_t tx_info = _packet_process_in_wait_for_wa(netif);
 
             if (tx_info & GNRC_LWMAC_TX_FAIL) {
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
 
             if (tx_info & GNRC_LWMAC_TX_SUCCESS) {
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SEND_DATA;
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_DATA;
                 reschedule = true;
                 break;
             }
@@ -745,49 +745,49 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
         case GNRC_LWMAC_TX_STATE_SEND_DATA: {
             LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_SEND_DATA\n");
 
-            if (!_send_data(gnrc_netdev)) {
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+            if (!_send_data(netif)) {
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
 
-            gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK;
+            netif->mac.tx.state = GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK;
             reschedule = false;
             break;
         }
         case GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK: {
             /* In case of no Tx-isr error, goto TX failure. */
-            if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+            if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
 
             LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK\n");
-            if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_UNDEF) {
+            if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_UNDEF) {
                 break;
             }
-            else if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_SUCCESS) {
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SUCCESSFUL;
+            else if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_SUCCESS) {
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SUCCESSFUL;
                 reschedule = true;
                 break;
             }
-            else if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_NOACK) {
+            else if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_NOACK) {
                 LOG_ERROR("ERROR: [LWMAC-tx] Not ACKED\n");
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
-            else if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_BUSY) {
+            else if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_BUSY) {
                 LOG_ERROR("ERROR: [LWMAC-tx] Channel busy \n");
-                gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+                netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
                 reschedule = true;
                 break;
             }
 
             LOG_ERROR("ERROR: [LWMAC-tx] Tx feedback unhandled: %i\n",
-                           gnrc_netdev_get_tx_feedback(gnrc_netdev));
-            gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
+                      gnrc_netif2_get_tx_feedback(netif));
+            netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
             reschedule = true;
             break;
         }
@@ -803,8 +803,8 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
     return reschedule;
 }
 
-void gnrc_lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
+void gnrc_lwmac_tx_update(gnrc_netif2_t *netif)
 {
     /* Update until no rescheduling needed */
-    while (_lwmac_tx_update(gnrc_netdev)) {}
+    while (_lwmac_tx_update(netif)) {}
 }
diff --git a/sys/net/gnrc/netif2/gnrc_netif2_ieee802154.c b/sys/net/gnrc/netif2/gnrc_netif2_ieee802154.c
index ffad686c39..6ffeb71658 100644
--- a/sys/net/gnrc/netif2/gnrc_netif2_ieee802154.c
+++ b/sys/net/gnrc/netif2/gnrc_netif2_ieee802154.c
@@ -223,8 +223,8 @@ static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
         }
 #endif
 #ifdef MODULE_GNRC_MAC
-        if (netif->mac_info & GNRC_NETDEV_MAC_INFO_CSMA_ENABLED) {
-            res = csma_sender_csma_ca_send(dev, vector, n, &netif->csma_conf);
+        if (netif->mac.mac_info & GNRC_NETIF2_MAC_INFO_CSMA_ENABLED) {
+            res = csma_sender_csma_ca_send(dev, vector, n, &netif->mac.csma_conf);
         }
         else {
             res = dev->driver->send(dev, vector, n);
-- 
GitLab