diff --git a/boards/common/nrf52/Makefile.dep b/boards/common/nrf52/Makefile.dep
index b9f6fc79e55878a6e77dab26356150b72af5067b..6f369896e79dc294e8a146a4f6bb982316f4c11c 100644
--- a/boards/common/nrf52/Makefile.dep
+++ b/boards/common/nrf52/Makefile.dep
@@ -1,3 +1,5 @@
+include $(RIOTCPU)/nrf52/Makefile.dep
+
 ifneq (,$(filter skald,$(USEMODULE)))
   USEMODULE += nrfble
 endif
diff --git a/boards/common/nrf52/include/cfg_timer_default.h b/boards/common/nrf52/include/cfg_timer_default.h
index 43f61d1a6a9837f32d89165f27aba24b4ed4b569..8dd673806f289a211b86bb25f1d4fd2145610d9a 100644
--- a/boards/common/nrf52/include/cfg_timer_default.h
+++ b/boards/common/nrf52/include/cfg_timer_default.h
@@ -36,10 +36,17 @@ static const timer_conf_t timer_config[] = {
         .channels = 3,
         .bitmode  = TIMER_BITMODE_BITMODE_32Bit,
         .irqn     = TIMER1_IRQn
+    },
+    {
+        .dev      = NRF_TIMER2,
+        .channels = 3,
+        .bitmode  = TIMER_BITMODE_BITMODE_08Bit,
+        .irqn     = TIMER2_IRQn
     }
 };
 
 #define TIMER_0_ISR         isr_timer1
+#define TIMER_1_ISR         isr_timer2
 
 #define TIMER_NUMOF         (sizeof(timer_config) / sizeof(timer_config[0]))
 /** @} */
diff --git a/boards/nrf52840dk/Makefile.dep b/boards/nrf52840dk/Makefile.dep
index 68628f406a1a5367ae7c1252e6fae6a01d925792..f75b7b047ca5755d92ded1637f5ff55806844627 100644
--- a/boards/nrf52840dk/Makefile.dep
+++ b/boards/nrf52840dk/Makefile.dep
@@ -1 +1,7 @@
 include $(RIOTBOARD)/common/nrf52xxxdk/Makefile.dep
+
+ifneq (,$(filter gnrc_netdev_default netdev_default,$(USEMODULE)))
+  ifeq (,$(filter nrfmin,$(USEMODULE)))
+    USEMODULE += nrf802154
+  endif
+endif
diff --git a/boards/nrf52840dk/Makefile.features b/boards/nrf52840dk/Makefile.features
index b99cfa472a13eaf6b79ba38718a4f2fea3563259..4ab48c7cbc2ee092b5a24e524e994f601dbf4736 100644
--- a/boards/nrf52840dk/Makefile.features
+++ b/boards/nrf52840dk/Makefile.features
@@ -1 +1,5 @@
 include $(RIOTBOARD)/common/nrf52xxxdk/Makefile.features
+
+# Various other features (if any)
+FEATURES_PROVIDED += radio_nrf802154
+FEATURES_PROVIDED += periph_pwm
diff --git a/cpu/nrf52/Makefile b/cpu/nrf52/Makefile
index 7600b58931f0b077fcc2f99e9b59ab2973d42289..59c4f48c9bcb37daea1db3642b7e4ead34e2d924 100644
--- a/cpu/nrf52/Makefile
+++ b/cpu/nrf52/Makefile
@@ -7,4 +7,9 @@ DIRS = periph $(RIOTCPU)/cortexm_common $(RIOTCPU)/nrf5x_common
 # (file triggers compiler bug. see #5775)
 SRC_NOLTO += vectors.c
 
+# build the nrf802154 driver if selected
+ifneq (,$(filter nrf802154,$(USEMODULE)))
+    DIRS += radio/nrf802154
+endif
+
 include $(RIOTBASE)/Makefile.base
diff --git a/cpu/nrf52/Makefile.dep b/cpu/nrf52/Makefile.dep
new file mode 100644
index 0000000000000000000000000000000000000000..d5e4d42993000d1210d5b354e500154caa9362e7
--- /dev/null
+++ b/cpu/nrf52/Makefile.dep
@@ -0,0 +1,6 @@
+ifneq (,$(filter nrf802154,$(USEMODULE)))
+  FEATURES_REQUIRED += periph_timer
+  FEATURES_REQUIRED += radio_nrf802154
+  USEMODULE += luid
+  USEMODULE += netdev_ieee802154
+endif
diff --git a/cpu/nrf52/Makefile.include b/cpu/nrf52/Makefile.include
index d6e26d6147b4dc501542b2821c807c663a67986b..03647d823b65cf24efb2574df46bbd3f9029542a 100644
--- a/cpu/nrf52/Makefile.include
+++ b/cpu/nrf52/Makefile.include
@@ -7,5 +7,9 @@ export MCUBOOT_SLOT0_SIZE = 0x8000
 export MCUBOOT_SLOT1_SIZE = 0x3C000
 export MCUBOOT_SLOT2_SIZE = 0x3C000
 
+ifneq (,$(filter nrf802154,$(USEMODULE)))
+  CFLAGS += -DGNRC_NETIF_MSG_QUEUE_SIZE=16
+endif
+
 include $(RIOTCPU)/nrf5x_common/Makefile.include
 include $(RIOTMAKE)/arch/cortexm.inc.mk
diff --git a/cpu/nrf52/include/nrf802154.h b/cpu/nrf52/include/nrf802154.h
new file mode 100644
index 0000000000000000000000000000000000000000..de55018e7795775e25920f54e262cb710168d5cd
--- /dev/null
+++ b/cpu/nrf52/include/nrf802154.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 Freie Universität Berlin
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @defgroup    drivers_nrf52_802154 IEEE802.15.4 Driver for nRF52840 SoCs
+ * @ingroup     drivers_netdev
+ * @brief       Driver for using the nRF52's radio in IEEE802.15.4 mode
+ *
+ * ## Implementation state ##
+ * Netdev events supported:
+ *
+ * - NETDEV_EVENT_RX_COMPLETE
+ * - NETDEV_EVENT_TX_COMPLETE
+ *
+ * Transmission options not yet impemented:
+ * - Send acknowledgement for packages
+ * - Request acknowledgement
+ * - Retransmit unacked packages
+ * - Carrier Sense Multiple Access (CSMA) and Implementation of Clear Channel
+ *   Assessment Control (CCACTRL)
+ *
+ * @{
+ *
+ * @file
+ * @brief       Driver interface for using the nRF52 in IEEE802.15.4 mode
+ *
+ * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
+ * @author      Semjon Kerner <semjon.kerner@fu-berlin.de>
+ */
+
+#ifndef NRF802154_H
+#define NRF802154_H
+
+#include "net/netdev/ieee802154.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   Export the netdev device descriptor
+ */
+extern netdev_ieee802154_t nrf802154_dev;
+
+/**
+ * @brief   IEEE 802.15.4 radio timer configuration
+ *
+ *          this radio relies on a dedicated hardware timer to maintain IFS
+ *          the default timer may be overwritten in the board configuration
+ */
+#ifndef NRF802154_TIMER
+#define NRF802154_TIMER TIMER_DEV(1)
+#endif
+
+#endif /* NRF802154_H */
+/** @} */
diff --git a/cpu/nrf52/radio/nrf802154/Makefile b/cpu/nrf52/radio/nrf802154/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..b2dbcf3dfe5f1dbd3e269a975280305dde79c239
--- /dev/null
+++ b/cpu/nrf52/radio/nrf802154/Makefile
@@ -0,0 +1,3 @@
+MODULE = nrf802154
+
+include $(RIOTBASE)/Makefile.base
diff --git a/cpu/nrf52/radio/nrf802154/nrf802154.c b/cpu/nrf52/radio/nrf802154/nrf802154.c
new file mode 100644
index 0000000000000000000000000000000000000000..b69499a84cf29185d8e0c30a2dc1d02d1dac0aeb
--- /dev/null
+++ b/cpu/nrf52/radio/nrf802154/nrf802154.c
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2019 Freie Universität Berlin
+ *               2019 HAW Hamburg
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @ingroup     drivers_nrf52_802154
+ * @{
+ *
+ * @file
+ * @brief       Implementation of the radio driver for nRF52 radios
+ *
+ * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
+ * @author      Dimitri Nahm <dimitri.nahm@haw-hamburg.de>
+ * @author      Semjon Kerner <semjon.kerner@fu-berlin.de>
+ * @}
+ */
+
+#include <string.h>
+#include <errno.h>
+
+#include "cpu.h"
+#include "luid.h"
+#include "mutex.h"
+
+#include "net/ieee802154.h"
+#include "periph/timer.h"
+#include "net/netdev/ieee802154.h"
+#include "nrf802154.h"
+
+#define ENABLE_DEBUG    (0)
+#include "debug.h"
+
+static const netdev_driver_t nrf802154_netdev_driver;
+
+netdev_ieee802154_t nrf802154_dev = {
+    {
+        .driver = &nrf802154_netdev_driver,
+        .event_callback = NULL,
+        .context = NULL,
+    },
+#ifdef MODULE_GNRC
+#ifdef MODULE_GNRC_SIXLOWPAN
+    .proto = GNRC_NETTYPE_SIXLOWPAN,
+#else
+    .proto = GNRC_NETTYPE_UNDEF,
+#endif
+#endif
+    .pan = IEEE802154_DEFAULT_PANID,
+    .short_addr = { 0, 0 },
+    .long_addr = { 0, 0, 0, 0, 0, 0, 0, 0 },
+    .chan = IEEE802154_DEFAULT_CHANNEL,
+    .flags = 0
+};
+
+static uint8_t rxbuf[IEEE802154_FRAME_LEN_MAX + 3]; /* len PHR + PSDU + LQI */
+static uint8_t txbuf[IEEE802154_FRAME_LEN_MAX + 3]; /* len PHR + PSDU + LQI */
+
+#define RX_COMPLETE         (0x1)
+#define TX_COMPLETE         (0x2)
+#define LIFS                (40U)
+#define SIFS                (12U)
+#define SIFS_MAXPKTSIZE     (18U)
+#define TIMER_FREQ          (250000UL)
+static volatile uint8_t _state;
+static mutex_t _txlock;
+
+/**
+ * @brief   Set radio into DISABLED state
+ */
+static void _disable(void)
+{
+    /* set device into DISABLED state */
+    if (NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) {
+        NRF_RADIO->EVENTS_DISABLED = 0;
+        NRF_RADIO->TASKS_DISABLE = 1;
+        while (!(NRF_RADIO->EVENTS_DISABLED)) {};
+        DEBUG("[nrf802154] Device state: DISABLED\n");
+    }
+}
+
+/**
+ * @brief   Set radio into RXIDLE state
+ */
+static void _enable_rx(void)
+{
+    DEBUG("[nrf802154] Set device state to RXIDLE\n");
+    /* set device into RXIDLE state */
+    if (NRF_RADIO->STATE != RADIO_STATE_STATE_RxIdle) {
+        _disable();
+    }
+    NRF_RADIO->PACKETPTR = (uint32_t)rxbuf;
+    NRF_RADIO->EVENTS_RXREADY = 0;
+    NRF_RADIO->TASKS_RXEN = 1;
+    while (!(NRF_RADIO->EVENTS_RXREADY)) {};
+    DEBUG("[nrf802154] Device state: RXIDLE\n");
+}
+
+/**
+ * @brief   Set radio into TXIDLE state
+ */
+static void _enable_tx(void)
+{
+    DEBUG("[nrf802154] Set device state to TXIDLE\n");
+    /* set device into TXIDLE state */
+    if (NRF_RADIO->STATE != RADIO_STATE_STATE_TxIdle) {
+        _disable();
+    }
+    NRF_RADIO->PACKETPTR = (uint32_t)txbuf;
+    NRF_RADIO->EVENTS_TXREADY = 0;
+    NRF_RADIO->TASKS_TXEN = 1;
+    while (!(NRF_RADIO->EVENTS_TXREADY)) {};
+    DEBUG("[nrf802154] Device state: TXIDLE\n");
+}
+
+/**
+ * @brief   Reset the RXIDLE state
+ */
+ static void _reset_rx(void)
+ {
+    if (NRF_RADIO->STATE != RADIO_STATE_STATE_RxIdle) {
+        return;
+    }
+
+    /* reset RX state and listen for new packets */
+    _state &= ~RX_COMPLETE;
+    NRF_RADIO->TASKS_START = 1;
+ }
+
+static void _set_chan(uint16_t chan)
+{
+    assert((chan >= IEEE802154_CHANNEL_MIN) && (chan <= IEEE802154_CHANNEL_MAX));
+    /* Channel map between 2400 MHZ ... 2500 MHz
+     * -> Frequency = 2400 + FREQUENCY (MHz) */
+    NRF_RADIO->FREQUENCY = (chan - 10) * 5;
+    nrf802154_dev.chan = chan;
+}
+
+static int16_t _get_txpower(void)
+{
+    int8_t txpower = (int8_t)NRF_RADIO->TXPOWER;
+    if (txpower < 0) {
+        return (int16_t)(0xff00 | txpower);
+    }
+    return (int16_t)txpower;
+}
+
+static void _set_txpower(int16_t txpower)
+{
+    if (txpower > 8) {
+        NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Pos8dBm;
+    }
+    if (txpower > 1) {
+        NRF_RADIO->TXPOWER = (uint32_t)txpower;
+    }
+    else if (txpower > -1) {
+        NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_0dBm;
+    }
+    else if (txpower > -5) {
+        NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Neg4dBm;
+    }
+    else if (txpower > -9) {
+        NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Neg8dBm;
+    }
+    else if (txpower > -13) {
+        NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Neg12dBm;
+    }
+    else if (txpower > -17) {
+        NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Neg16dBm;
+    }
+    else if (txpower > -21) {
+        NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Neg20dBm;
+    }
+    else {
+        NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Neg40dBm;
+    }
+}
+
+static void _timer_cb(void *arg, int chan)
+{
+    (void)arg;
+    (void)chan;
+    mutex_unlock(&_txlock);
+    timer_stop(NRF802154_TIMER);
+    timer_clear(NRF802154_TIMER, 0);
+}
+
+static int _init(netdev_t *dev)
+{
+    (void)dev;
+
+    int result = timer_init(NRF802154_TIMER, TIMER_FREQ, _timer_cb, NULL);
+    assert(result >= 0);
+    (void)result;
+
+    /* initialize local variables */
+    mutex_init(&_txlock);
+
+    /* reset buffer */
+    rxbuf[0] = 0;
+    txbuf[0] = 0;
+    _state = 0;
+
+    /* power on peripheral */
+    NRF_RADIO->POWER = 1;
+
+    /* make sure the radio is disabled/stopped */
+    _disable();
+
+    /* we configure it to run in IEEE802.15.4 mode */
+    NRF_RADIO->MODE = RADIO_MODE_MODE_Ieee802154_250Kbit;
+    /* and set some fitting configuration */
+    NRF_RADIO->PCNF0 = ((8 << RADIO_PCNF0_LFLEN_Pos) |
+                        (RADIO_PCNF0_PLEN_32bitZero << RADIO_PCNF0_PLEN_Pos) |
+                        (RADIO_PCNF0_CRCINC_Include << RADIO_PCNF0_CRCINC_Pos));
+    NRF_RADIO->PCNF1 = IEEE802154_FRAME_LEN_MAX;
+    /* set start frame delimiter */
+    NRF_RADIO->SFD = IEEE802154_SFD;
+    /* set MHR filters */
+    NRF_RADIO->MHRMATCHCONF = 0;              /* Search Pattern Configuration */
+    NRF_RADIO->MHRMATCHMAS = 0xff0007ff;      /* Pattern mask */
+    /* configure CRC conform to IEEE802154 */
+    NRF_RADIO->CRCCNF = ((RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos) |
+                         (RADIO_CRCCNF_SKIPADDR_Ieee802154 << RADIO_CRCCNF_SKIPADDR_Pos));
+    NRF_RADIO->CRCPOLY = 0x011021;
+    NRF_RADIO->CRCINIT = 0;
+
+    /* assign default addresses */
+    luid_get(nrf802154_dev.short_addr, IEEE802154_SHORT_ADDRESS_LEN);
+    luid_get(nrf802154_dev.long_addr, IEEE802154_LONG_ADDRESS_LEN);
+
+    /* set default channel */
+    _set_chan(nrf802154_dev.chan);
+
+    /* configure some shortcuts */
+    NRF_RADIO->SHORTS = RADIO_SHORTS_RXREADY_START_Msk | RADIO_SHORTS_TXREADY_START_Msk;
+
+    /* enable interrupts */
+    NVIC_EnableIRQ(RADIO_IRQn);
+    NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
+
+    /* switch to RX mode */
+    _enable_rx();
+
+    return 0;
+}
+
+static int _send(netdev_t *dev,  const iolist_t *iolist)
+{
+    (void)dev;
+
+    DEBUG("[nrf802154] Send a packet\n");
+
+    assert(iolist);
+
+    mutex_lock(&_txlock);
+
+    /* copy packet data into the transmit buffer */
+    unsigned int len = 0;
+    for (; iolist; iolist = iolist->iol_next) {
+        if ((IEEE802154_FCS_LEN + len + iolist->iol_len) > (IEEE802154_FRAME_LEN_MAX)) {
+            DEBUG("[nrf802154] send: unable to do so, packet is too large!\n");
+            mutex_unlock(&_txlock);
+            return -EOVERFLOW;
+        }
+        memcpy(&txbuf[len + 1], iolist->iol_base, iolist->iol_len);
+        len += iolist->iol_len;
+    }
+
+    /* specify the length of the package. */
+    txbuf[0] = len + IEEE802154_FCS_LEN;
+
+    /* trigger the actual transmission */
+    _enable_tx();
+    DEBUG("[nrf802154] send: putting %i byte into the ether\n", len);
+
+    /* set interframe spacing based on packet size */
+    unsigned int ifs = (len > SIFS_MAXPKTSIZE) ? LIFS : SIFS;
+    timer_set_absolute(NRF802154_TIMER, 0, ifs);
+
+    return len;
+}
+
+static int _recv(netdev_t *dev, void *buf, size_t len, void *info)
+{
+    (void)dev;
+    (void)info;
+
+    size_t pktlen = (size_t)rxbuf[0] - IEEE802154_FCS_LEN;
+
+    /* check if packet data is readable */
+    if (!(_state & RX_COMPLETE)) {
+        DEBUG("[nrf802154] recv: no packet data available\n");
+        return 0;
+    }
+
+    if (buf == NULL) {
+        if (len > 0) {
+            /* drop packet */
+            DEBUG("[nrf802154] recv: dropping packet of length %i\n", pktlen);
+        }
+        else {
+          /* return packet length */
+          DEBUG("[nrf802154] recv: return packet length: %i\n", pktlen);
+          return pktlen;
+        }
+    }
+    else if (len < pktlen) {
+        DEBUG("[nrf802154] recv: buffer is to small\n");
+        return -ENOBUFS;
+    }
+    else {
+        DEBUG("[nrf802154] recv: reading packet of length %i\n", pktlen);
+        memcpy(buf, &rxbuf[1], pktlen);
+    }
+
+    _reset_rx();
+
+    return (int)pktlen;
+}
+
+static void _isr(netdev_t *dev)
+{
+    if (!nrf802154_dev.netdev.event_callback) {
+        return;
+    }
+    if (_state & RX_COMPLETE) {
+        nrf802154_dev.netdev.event_callback(dev, NETDEV_EVENT_RX_COMPLETE);
+    }
+    if (_state & TX_COMPLETE) {
+        nrf802154_dev.netdev.event_callback(dev, NETDEV_EVENT_TX_COMPLETE);
+        _state &= ~TX_COMPLETE;
+    }
+}
+
+static int _get(netdev_t *dev, netopt_t opt, void *value, size_t max_len)
+{
+    assert(dev);
+
+#ifdef MODULE_NETOPT
+    DEBUG("[nrf802154] get: %s\n", netopt2str(opt));
+#else
+    DEBUG("[nrf802154] get: %d\n", opt);
+#endif
+
+    switch (opt) {
+        case NETOPT_CHANNEL:
+            assert(max_len >= sizeof(uint16_t));
+            *((uint16_t *)value) = nrf802154_dev.chan;
+            return sizeof(uint16_t);
+        case NETOPT_TX_POWER:
+            assert(max_len >= sizeof(int16_t));
+            *((int16_t *)value) = _get_txpower();
+            return sizeof(int16_t);
+
+        default:
+            return netdev_ieee802154_get((netdev_ieee802154_t *)dev,
+                                          opt, value, max_len);
+    }
+}
+
+static int _set(netdev_t *dev, netopt_t opt,
+                const void *value, size_t value_len)
+{
+    assert(dev);
+
+#ifdef MODULE_NETOPT
+    DEBUG("[nrf802154] set: %s\n", netopt2str(opt));
+#else
+    DEBUG("[nrf802154] set: %d\n", opt);
+#endif
+
+    switch (opt) {
+        case NETOPT_CHANNEL:
+            assert(value_len == sizeof(uint16_t));
+            _set_chan(*((uint16_t *)value));
+            return sizeof(uint16_t);
+        case NETOPT_TX_POWER:
+            assert(value_len == sizeof(int16_t));
+            _set_txpower(*((int16_t *)value));
+            return sizeof(int16_t);
+
+        default:
+            return netdev_ieee802154_set((netdev_ieee802154_t *)dev,
+                                          opt, value, value_len);
+    }
+}
+
+void isr_radio(void)
+{
+    /* Clear flag */
+    if (NRF_RADIO->EVENTS_END) {
+        NRF_RADIO->EVENTS_END = 0;
+
+        /* did we just send or receive something? */
+        uint8_t state = (uint8_t)NRF_RADIO->STATE;
+        switch(state) {
+            case RADIO_STATE_STATE_RxIdle:
+                /* only process packet if event callback is set and CRC is valid */
+                if ((nrf802154_dev.netdev.event_callback) &&
+                    (NRF_RADIO->CRCSTATUS == 1) &&
+                    (netdev_ieee802154_dst_filter(&nrf802154_dev,
+                                                  &rxbuf[1]) == 0)) {
+                    _state |= RX_COMPLETE;
+                }
+                else {
+                    _reset_rx();
+                }
+                break;
+            case RADIO_STATE_STATE_Tx:
+            case RADIO_STATE_STATE_TxIdle:
+            case RADIO_STATE_STATE_TxDisable:
+                timer_start(NRF802154_TIMER);
+                DEBUG("[nrf802154] TX state: %x\n", (uint8_t)NRF_RADIO->STATE);
+                _state |= TX_COMPLETE;
+                _enable_rx();
+                break;
+            default:
+                DEBUG("[nrf802154] Unhandled state: %x\n", (uint8_t)NRF_RADIO->STATE);
+        }
+        if (_state) {
+            nrf802154_dev.netdev.event_callback(&nrf802154_dev.netdev, NETDEV_EVENT_ISR);
+        }
+    }
+    else {
+        DEBUG("[nrf802154] Unknown interrupt triggered\n");
+    }
+
+    cortexm_isr_end();
+}
+
+/**
+ * @brief   Export of the netdev interface
+ */
+static const netdev_driver_t nrf802154_netdev_driver = {
+    .send = _send,
+    .recv = _recv,
+    .init = _init,
+    .isr  = _isr,
+    .get  = _get,
+    .set  = _set
+};
diff --git a/drivers/include/net/netdev/ieee802154.h b/drivers/include/net/netdev/ieee802154.h
index d8eb260c185ee4f478d84fd7d3acccbbdf6667cd..70da2a0a5f30f1a43e0f81c115fc9ebf91ffad0e 100644
--- a/drivers/include/net/netdev/ieee802154.h
+++ b/drivers/include/net/netdev/ieee802154.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Freie Universität Berlin
+ * Copyright (C) 2016-2019 Freie Universität Berlin
  *
  * This file is subject to the terms and conditions of the GNU Lesser
  * General Public License v2.1. See the file LICENSE in the top level
@@ -177,6 +177,21 @@ int netdev_ieee802154_get(netdev_ieee802154_t *dev, netopt_t opt, void *value,
 int netdev_ieee802154_set(netdev_ieee802154_t *dev, netopt_t opt, const void *value,
                           size_t value_len);
 
+/**
+ * @brief  This funtion compares destination address and pan id with addresses
+ * and pan id of the device
+ *
+ * this funciton is meant top be used by drivers that do not support address
+ * filtering in hw
+ *
+ * @param[in] dev       network device descriptor
+ * @param[in] mhr       mac header
+ *
+ * @return 0            successfull if packet is for the device
+ * @return 1            fails if packet is not for the device or pan
+ */
+int netdev_ieee802154_dst_filter(netdev_ieee802154_t *dev, const uint8_t *mhr);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/drivers/netdev_ieee802154/netdev_ieee802154.c b/drivers/netdev_ieee802154/netdev_ieee802154.c
index d21e798e078079f8532fb9659018261ff74d73ab..623604f39027c0bb0847e7a0b65c214d1e3d9e9e 100644
--- a/drivers/netdev_ieee802154/netdev_ieee802154.c
+++ b/drivers/netdev_ieee802154/netdev_ieee802154.c
@@ -253,4 +253,30 @@ int netdev_ieee802154_set(netdev_ieee802154_t *dev, netopt_t opt, const void *va
     return res;
 }
 
+int netdev_ieee802154_dst_filter(netdev_ieee802154_t *dev, const uint8_t *mhr)
+{
+    uint8_t dst_addr[IEEE802154_LONG_ADDRESS_LEN];
+    le_uint16_t dst_pan;
+    uint8_t pan_bcast[] = IEEE802154_PANID_BCAST;
+
+    int addr_len = ieee802154_get_dst(mhr, dst_addr, &dst_pan);
+
+    /* filter PAN ID */
+    if ((memcmp(pan_bcast, dst_pan.u8, 2) != 0) &&
+        (memcmp(&dev->pan, dst_pan.u8, 2) != 0)) {
+        return 1;
+    }
+
+    /* check destination address */
+    if (((addr_len == IEEE802154_SHORT_ADDRESS_LEN) &&
+          (memcmp(dev->short_addr, dst_addr, addr_len) == 0 ||
+           memcmp(ieee802154_addr_bcast, dst_addr, addr_len) == 0)) ||
+        ((addr_len == IEEE802154_LONG_ADDRESS_LEN) &&
+          (memcmp(dev->long_addr, dst_addr, addr_len) == 0))) {
+        return 0;
+    }
+
+    return 1;
+}
+
 /** @} */
diff --git a/examples/default/Makefile b/examples/default/Makefile
index a8425efae8244706dd2662ed8f11a045e7445e3f..b9a2f75a02ee5cf4c4c1eab13e392f8607df3396 100644
--- a/examples/default/Makefile
+++ b/examples/default/Makefile
@@ -37,7 +37,7 @@ USEMODULE += ps
 USEMODULE += saul_default
 
 BOARD_PROVIDES_NETIF := acd52832 airfy-beacon b-l072z-lrwan1 cc2538dk fox iotlab-m3 iotlab-a8-m3 mulle \
-        microbit native nrf51dk nrf51dongle nrf52dk nrf6310 openmote-cc2538 pba-d-01-kw2x \
+        microbit native nrf51dk nrf51dongle nrf52dk nrf52840dk nrf6310 openmote-cc2538 pba-d-01-kw2x \
         remote-pa remote-reva samr21-xpro \
         spark-core telosb yunjia-nrf51822 z1
 
diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c
index 11e19163957f35405433379019b61785d6883304..aa66344aefa238aae9e55c5bbcb6964b843a8a9c 100644
--- a/sys/auto_init/auto_init.c
+++ b/sys/auto_init/auto_init.c
@@ -286,6 +286,11 @@ void auto_init(void)
     auto_init_sx127x();
 #endif
 
+#ifdef MODULE_NRF802154
+    extern void auto_init_nrf802154(void);
+    auto_init_nrf802154();
+#endif
+
 #endif /* MODULE_AUTO_INIT_GNRC_NETIF */
 
 #ifdef MODULE_GNRC_UHCPC
diff --git a/sys/auto_init/netif/auto_init_nrf802154.c b/sys/auto_init/netif/auto_init_nrf802154.c
new file mode 100644
index 0000000000000000000000000000000000000000..2733c2206c78c65ea5291f7eb9d0243f0d371c0c
--- /dev/null
+++ b/sys/auto_init/netif/auto_init_nrf802154.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 Freie Universität Berlin
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ *
+ */
+
+/*
+ * @ingroup sys_auto_init_gnrc_netif
+ * @{
+ *
+ * @file
+ * @brief   Auto initialization the nRF52840 radio in IEEE802.15.4 mode
+ *
+ * @author  Hauke Petersen <hauke.petersen@fu-berlin.de>
+ */
+
+#ifdef MODULE_NRF802154
+
+
+#include "log.h"
+#include "board.h"
+#include "nrf802154.h"
+#include "net/gnrc/netif/ieee802154.h"
+
+/**
+ * @brief   Define stack parameters for the MAC layer thread
+ * @{
+ */
+#ifndef NRF802154_MAC_STACKSIZE
+#define NRF802154_MAC_STACKSIZE     (THREAD_STACKSIZE_DEFAULT)
+#endif
+#ifndef NRF802154_MAC_PRIO
+#define NRF802154_MAC_PRIO          (GNRC_NETIF_PRIO)
+#endif
+/** @} */
+
+static char _stack[NRF802154_MAC_STACKSIZE];
+
+void auto_init_nrf802154(void)
+{
+    LOG_DEBUG("[auto_init_netif] initializing nrf802154\n");
+
+    gnrc_netif_ieee802154_create(_stack,
+                                 NRF802154_MAC_STACKSIZE,
+                                 NRF802154_MAC_PRIO, "nrf802154",
+                                 (netdev_t *)&nrf802154_dev);
+}
+#else
+typedef int dont_be_pedantic;
+#endif /* MODULE_NRF802154 */
+
+/** @} */
diff --git a/sys/include/net/ieee802154.h b/sys/include/net/ieee802154.h
index 69d4f6c4b2961c85770ea2e8e7d10a3e5d454f96..0f86442b50e8dfee50e473258ba78753dc923be9 100644
--- a/sys/include/net/ieee802154.h
+++ b/sys/include/net/ieee802154.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-16 Freie Universität Berlin
+ * Copyright (C) 2015-2019 Freie Universität Berlin
  *
  * This file is subject to the terms and conditions of the GNU Lesser
  * General Public License v2.1. See the file LICENSE in the top level
@@ -31,6 +31,11 @@
 extern "C" {
 #endif
 
+/**
+ * @brief   Default start frame delimiter
+ */
+#define IEEE802154_SFD                      (0xa7)
+
 /**
  * @brief IEEE 802.15.4 address lengths
  * @{
@@ -144,6 +149,13 @@ extern const uint8_t ieee802154_addr_bcast[IEEE802154_ADDR_BCAST_LEN];
 #define IEEE802154_DEFAULT_PANID            (0x0023U)
 #endif
 
+/**
+ * @brief IEEE802.15.4 Broadcast PANID
+ */
+#ifndef IEEE802154_PANID_BCAST
+#define IEEE802154_PANID_BCAST              { 0xff, 0xff }
+#endif
+
 /**
  * @brief IEEE802.15.4 default TX power (in dBm)
  */