diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep
index e511c53a5b315bb5818cf99c57bc577d4af2dbc2..2a70c0e1717117a113ebd3be0012f3d730bd4742 100644
--- a/drivers/Makefile.dep
+++ b/drivers/Makefile.dep
@@ -19,6 +19,19 @@ ifneq (,$(filter at86rf2%,$(USEMODULE)))
   endif
 endif
 
+ifneq (,$(filter mrf24j40,$(USEMODULE)))
+  USEMODULE += xtimer
+  USEMODULE += uuid
+  USEMODULE += netif
+  USEMODULE += ieee802154
+  USEMODULE += netdev2_ieee802154
+  ifneq (,$(filter gnrc_netdev_default,$(USEMODULE)))
+	# XXX: this can be modelled as a dependency for gnrc_netdev_default as soon
+	# as all drivers are ported to netdev2
+    USEMODULE += gnrc_netdev2
+  endif
+endif
+
 ifneq (,$(filter bh1750fvi,$(USEMODULE)))
   USEMODULE += xtimer
   FEATURES_REQUIRED += periph_i2c
diff --git a/drivers/Makefile.include b/drivers/Makefile.include
index d1ba0fb1eb46154e84603e4e7575143073177725..f0e9712f620c2a7ff8abb31804d517906570bcd5 100644
--- a/drivers/Makefile.include
+++ b/drivers/Makefile.include
@@ -4,6 +4,9 @@ endif
 ifneq (,$(filter at86rf2xx,$(USEMODULE)))
     USEMODULE_INCLUDES += $(RIOTBASE)/drivers/at86rf2xx/include
 endif
+ifneq (,$(filter mrf24j40,$(USEMODULE)))
+    USEMODULE_INCLUDES += $(RIOTBASE)/drivers/mrf24j40/include
+endif
 ifneq (,$(filter cc110x,$(USEMODULE)))
     USEMODULE_INCLUDES += $(RIOTBASE)/drivers/cc110x/include
 endif
diff --git a/drivers/include/mrf24j40.h b/drivers/include/mrf24j40.h
new file mode 100644
index 0000000000000000000000000000000000000000..6a3281a301cd2535ed0dee9d6a0f2ec4067e0aac
--- /dev/null
+++ b/drivers/include/mrf24j40.h
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
+ * Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
+ *
+ * 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_mrf24j40 MRF24J40 based drivers
+ * @ingroup     drivers_netdev_netdev2
+ *
+ * This module contains drivers for radio devices in Microchip MRF24J40 series.
+ * The driver is aimed to work with all devices of this series.
+ *
+ * @{
+ *
+ * @file
+ * @brief       Interface definition for MRF24J40 based drivers
+ *
+ * @author      Neo Nenaco <neo@nenaco.de>
+ * @author      Koen Zandberg <koen@bergzand.net>
+ */
+
+#ifndef MRF24J40_H
+#define MRF24J40_H
+
+#include <stdint.h>
+
+#include "board.h"
+#include "periph/spi.h"
+#include "periph/gpio.h"
+#include "net/netdev2.h"
+#include "net/netdev2/ieee802154.h"
+#include "net/gnrc/nettype.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   Default TX power (0dBm)
+ *  0 -> -36dB
+ *  1 -> -35dB
+ *  2 -> -34dB
+ *  3 -> -33dB
+ *  4 -> -32dB
+ *  5 -> -31dB
+ *  6 -> -30dB
+ *  7 -> -30dB
+ *  8 -> -26dB
+ *  9 -> -25dB
+ *  10 -> -24dB
+ *  11 -> -23dB
+ *  12 -> -22dB
+ *  13 -> -21dB
+ *  14 -> -20dB
+ *  15 -> -20dB
+ *  16 -> -16dB
+ *  17 -> -15dB
+ *  18 -> -14dB
+ *  19 -> -13dB
+ *  20 -> -12dB
+ *  21 -> -11dB
+ *  22 -> -10dB
+ *  23 -> -10dB
+ *  24 -> -6dB
+ *  25 -> -5dB
+ *  26 -> -4dB
+ *  27 -> -3dB
+ *  28 -> -2dB
+ *  29 -> -1dB
+ *  30 -> -0dB
+ *  31 -> -0dB
+ */
+
+/**
+ * @brief   Base (minimal) RSSI value in dBm
+ */
+#define RSSI_BASE_VAL                   (-91)
+
+/**
+ * @brief   Flags for PSEUDO DEVICE INTERNAL STATES
+ * @{
+ */
+#define MRF24J40_PSEUDO_STATE_IDLE      (0x01)      /**< Idle, ready to transmit or receive */
+#define MRF24J40_PSEUDO_STATE_SLEEP     (0x02)      /**< sleep mode, registers functional, but no RF */
+#define MRF24J40_PSEUDO_STATE_RESET     (0x04)      /**< Reset device, next state is idle */
+/** @} */
+
+/**
+ * @brief   Internal device option flags
+ *
+ * `0x00ff` is reserved for general IEEE 802.15.4 flags
+ * (see @ref netdev2_ieee802154_t)
+ *
+ * @{
+ */
+#define MRF24J40_OPT_CSMA               (0x0100)    /**< CSMA active */
+#define MRF24J40_OPT_PROMISCUOUS        (0x0200)    /**< promiscuous mode
+                                                     *   active */
+#define MRF24J40_OPT_PRELOADING         (0x0400)    /**< preloading enabled */
+#define MRF24J40_OPT_TELL_TX_START      (0x0800)    /**< notify MAC layer on TX
+                                                     *   start */
+#define MRF24J40_OPT_TELL_TX_END        (0x1000)    /**< notify MAC layer on TX
+                                                     *   finished */
+#define MRF24J40_OPT_TELL_RX_START      (0x2000)    /**< notify MAC layer on RX
+                                                     *   start */
+#define MRF24J40_OPT_TELL_RX_END        (0x4000)    /**< notify MAC layer on RX
+                                                     *   finished */
+#define MRF24J40_OPT_REQ_AUTO_ACK       (0x8000)    /**< notify MAC layer on RX
+                                                     *   finished */
+/** @} */
+
+
+#define MRF24J40_TASK_TX_DONE           (0x01)      /**< TX operation is done */
+#define MRF24J40_TASK_TX_READY          (0x02)      /**< TX operation results ready for processing */
+#define MRF24J40_TASK_RX_READY          (0x04)      /**< RX processing needed */
+
+#define MRF24J40_MAX_FRAME_RETRIES      (3U)        /**< Number of frame retries (fixed) */
+
+/**
+ * @brief struct holding all params needed for device initialization
+ */
+typedef struct mrf24j40_params {
+    spi_t spi;              /**< SPI bus the device is connected to */
+    spi_clk_t spi_clk;  /**< SPI speed to use */
+    spi_cs_t cs_pin;          /**< GPIO pin connected to chip select */
+    gpio_t int_pin;         /**< GPIO pin connected to the interrupt pin */
+    gpio_t reset_pin;       /**< GPIO pin connected to the reset pin */
+} mrf24j40_params_t;
+
+/**
+ * @brief   Device descriptor for MRF24J40 radio devices
+ */
+typedef struct {
+    netdev2_ieee802154_t netdev;            /**< netdev2 parent struct */
+    /**
+     * @brief   device specific fields
+     * @{
+     */
+    mrf24j40_params_t params;               /**< parameters for initialization */
+    uint8_t state;                          /**< current state of the radio */
+    uint8_t idle_state;                     /**< state to return to after sending */
+    uint8_t tx_frame_len;                   /**< length of the current TX frame */
+    uint8_t header_len;
+    uint8_t pending;                        /**< Flags for pending tasks */
+    uint8_t irq_flag;
+} mrf24j40_t;
+
+/**
+ * @brief   Setup an MRF24J40 based device state
+ *
+ * @param[out] dev          device descriptor
+ * @param[in]  params       parameters for device initialization
+ */
+void mrf24j40_setup(mrf24j40_t *dev, const mrf24j40_params_t *params);
+
+/**
+ * @brief   Trigger a hardware reset and configure radio with default values
+ *
+ * @param[in] dev           device to reset
+ */
+void mrf24j40_reset(mrf24j40_t *dev);
+
+/**
+ * @brief   Trigger a clear channel assessment
+ *
+ * @param[in] dev           device to use
+ *
+ * @return                  true if channel is clear
+ * @return                  false if channel is busy
+ */
+bool mrf24j40_cca(mrf24j40_t *dev);
+
+/**
+ * @brief   Get the short address of the given device
+ *
+ * @param[in] dev           device to read from
+ *
+ * @return                  the currently set (2-byte) short address
+ */
+uint16_t mrf24j40_get_addr_short(mrf24j40_t *dev);
+
+/**
+ * @brief   Set the short address of the given device
+ *
+ * @param[in] dev           device to write to
+ * @param[in] addr          (2-byte) short address to set
+ */
+void mrf24j40_set_addr_short(mrf24j40_t *dev, uint16_t addr);
+
+/**
+ * @brief   Get the configured long address of the given device
+ *
+ * @param[in] dev           device to read from
+ *
+ * @return                  the currently set (8-byte) long address
+ */
+uint64_t mrf24j40_get_addr_long(mrf24j40_t *dev);
+
+/**
+ * @brief   Set the long address of the given device
+ *
+ * @param[in] dev           device to write to
+ * @param[in] addr          (8-byte) long address to set
+ */
+void mrf24j40_set_addr_long(mrf24j40_t *dev, uint64_t addr);
+
+/**
+ * @brief   Get the configured channel number of the given device
+ *
+ * @param[in] dev           device to read from
+ *
+ * @return                  the currently set channel number
+ */
+uint8_t mrf24j40_get_chan(mrf24j40_t *dev);
+
+/**
+ * @brief   Set the channel number of the given device
+ *
+ * @param[in] dev           device to write to
+ * @param[in] chan          channel number to set
+ */
+void mrf24j40_set_chan(mrf24j40_t *dev, uint8_t chan);
+
+/**
+ * @brief   Get the configured PAN ID of the given device
+ *
+ * @param[in] dev           device to read from
+ *
+ * @return                  the currently set PAN ID
+ */
+uint16_t mrf24j40_get_pan(mrf24j40_t *dev);
+
+/**
+ * @brief   Set the PAN ID of the given device
+ *
+ * @param[in] dev           device to write to
+ * @param[in] pan           PAN ID to set
+ */
+void mrf24j40_set_pan(mrf24j40_t *dev, uint16_t pan);
+
+/**
+ * @brief   Get the configured transmission power of the given device [in dBm]
+ *
+ * @param[in] dev           device to read from
+ *
+ * @return                  configured transmission power in dBm
+ */
+int16_t mrf24j40_get_txpower(mrf24j40_t *dev);
+
+/**
+ * @brief   Set the transmission power of the given device [in dBm]
+ *
+ * If the device does not support the exact dBm value given, it will set a value
+ * as close as possible to the given value. If the given value is larger or
+ * lower then the maximal or minimal possible value, the min or max value is
+ * set, respectively.
+ *
+ * @param[in] dev           device to write to
+ * @param[in] txpower       transmission power in dBm
+ */
+void mrf24j40_set_txpower(mrf24j40_t *dev, int16_t txpower);
+
+/**
+ * @brief   Get the maximum number of channel access attempts per frame (CSMA)
+ *
+ * @param[in] dev           device to read from
+ *
+ * @return                  configured number of retries
+ */
+uint8_t mrf24j40_get_csma_max_retries(mrf24j40_t *dev);
+
+/**
+ * @brief   Set the maximum number of channel access attempts per frame (CSMA)
+ *
+ * This setting specifies the number of attempts to access the channel to
+ * transmit a frame. If the channel is busy @p retries times, then frame
+ * transmission fails.
+ * Valid values: 0 to 5, -1 means CSMA disabled
+ *
+ * @param[in] dev           device to write to
+ * @param[in] retries       the maximum number of retries
+ */
+void mrf24j40_set_csma_max_retries(mrf24j40_t *dev, int8_t retries);
+
+/**
+ * @brief   Set the min and max backoff exponent for CSMA/CA
+ *
+ * - Maximum BE: 0 - 8
+ * - Minimum BE: 0 - [max]
+ *
+ * @param[in] dev           device to write to
+ * @param[in] min           the minimum BE
+ * @param[in] max           the maximum BE
+ */
+void mrf24j40_set_csma_backoff_exp(mrf24j40_t *dev, uint8_t min, uint8_t max);
+
+/**
+ * @brief   Get the CCA threshold value
+ *
+ * @param[in] dev           device to read value from
+ *
+ * @return                  the current CCA threshold value
+ */
+int8_t mrf24j40_get_cca_threshold(mrf24j40_t *dev);
+
+/**
+ * @brief   Set the CCA threshold value
+ *
+ * @param[in] dev           device to write to
+ * @param[in] value         the new CCA threshold value
+ */
+void mrf24j40_set_cca_threshold(mrf24j40_t *dev, int8_t value);
+
+/**
+ * @brief   Enable or disable driver specific options
+ *
+ * @param[in] dev           device to set/clear option flag for
+ * @param[in] option        option to enable/disable
+ * @param[in] state         true for enable, false for disable
+ */
+void mrf24j40_set_option(mrf24j40_t *dev, uint16_t option, bool state);
+
+/**
+ * @brief   Set the state of the given device (trigger a state change)
+ *
+ * @param[in] dev           device to change state of
+ * @param[in] state         the targeted new state
+ */
+void mrf24j40_set_state(mrf24j40_t *dev, uint8_t state);
+
+/**
+ * @brief   Put in sleep mode
+ *
+ * @param[in] dev       device to put to sleep
+ */
+void mrf24j40_sleep(mrf24j40_t *dev);
+
+/**
+ * @brief   Put in sleep mode if idle_state is sleep
+ *
+ * @param[in] dev       device to put to sleep
+ */
+void mrf24j40_assert_sleep(mrf24j40_t *dev);
+
+/**
+ * @brief   Wake up from sleep mode
+ *
+ * @param[in] dev       device to eventually wake up
+ */
+void mrf24j40_assert_awake(mrf24j40_t *dev);
+
+/**
+ * @brief   Reset the internal state machine to TRX_OFF mode.
+ *
+ * This will force a transition to TRX_OFF regardless of whether the transceiver
+ * is currently busy sending or receiving. This function is used to get back to
+ * a known state during driver initialization.
+ *
+ * @param[in] dev           device to operate on
+ */
+void mrf24j40_reset_state_machine(mrf24j40_t *dev);
+
+/**
+ * @brief   Software Reset.
+ *
+ * This will force the power management circuitry, the baseband circuitry and the MAC circuitry
+ * to be reset
+ *
+ * @param[in] dev           device to operate on
+ */
+void mrf24j40_software_reset(mrf24j40_t *dev);
+
+/**
+ * @brief   Prepare for sending of data
+ *
+ * This function puts the given device into the TX state, so no receiving of
+ * data is possible after it was called.
+ *
+ * @param[in] dev            device to prepare for sending
+ */
+void mrf24j40_tx_prepare(mrf24j40_t *dev);
+
+/**
+ * @brief   Load chunks of data into the transmit buffer of the given device
+ *
+ * @param[in] dev           device to write data to
+ * @param[in] data          buffer containing the data to load
+ * @param[in] len           number of bytes in @p buffer
+ * @param[in] offset        offset used when writing data to internal buffer
+ *
+ * @return                  offset + number of bytes written
+ */
+size_t mrf24j40_tx_load(mrf24j40_t *dev, uint8_t *data, size_t len,
+                        size_t offset);
+
+/**
+ * @brief   Trigger sending of data previously loaded into transmit buffer
+ *
+ * @param[in] dev           device to trigger
+ */
+void mrf24j40_tx_exec(mrf24j40_t *dev);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MRF24J40_H */
+/** @} */
diff --git a/drivers/mrf24j40/Makefile b/drivers/mrf24j40/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..48422e909a47d7cd428d10fa73825060ccc8d8c2
--- /dev/null
+++ b/drivers/mrf24j40/Makefile
@@ -0,0 +1 @@
+include $(RIOTBASE)/Makefile.base
diff --git a/drivers/mrf24j40/include/mrf24j40_internal.h b/drivers/mrf24j40/include/mrf24j40_internal.h
new file mode 100644
index 0000000000000000000000000000000000000000..3254e0b8c7b5c7df6899539d75a6bcdaeb2e4aff
--- /dev/null
+++ b/drivers/mrf24j40/include/mrf24j40_internal.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
+ * Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
+ *
+ * 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_mrf24j40
+ * @{
+ *
+ * @file
+ * @brief Internal interfaces for MRF24J40 drivers
+ *
+ * @author      Neo Nenaco <neo@nenaco.de>
+ * @author      Koen Zandberg <koen@bergzand.net>
+ */
+
+#ifndef MRF24J40_INTERNAL_H
+#define MRF24J40_INTERNAL_H
+
+#include <stdint.h>
+
+#include "mrf24j40.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief initialization as decribed in datasheet
+ */
+void mrf24j40_init(mrf24j40_t *dev);
+
+/**
+ * @brief Read from a register with a  at address `addr` from device `dev`. Register with 8bit address
+ *
+ * @param[in] dev device to read from
+ * @param[in] addr address of the register to read
+ *
+ * @return the value of the specified register
+ */
+uint8_t mrf24j40_reg_read_short(mrf24j40_t *dev, const uint8_t addr);
+
+/**
+ * @brief Write to a register at address `addr` from device `dev`. Register with 8bit address
+ *
+ * @param[in] dev device to write to
+ * @param[in] addr address of the register to write
+ * @param[in] value value to write to the given register
+ */
+void mrf24j40_reg_write_short(mrf24j40_t *dev, const uint8_t addr, const uint8_t value);
+
+/**
+ * @brief Read from a register with a  at address `addr` from device `dev`. Register with 10bit address
+ *
+ * @param[in] dev device to read from
+ * @param[in] addr address of the register to read
+ *
+ * @return the value of the specified register
+ */
+uint8_t mrf24j40_reg_read_long(mrf24j40_t *dev, const uint16_t addr);
+
+/**
+ * @brief Write to a register at address `addr` from device `dev`. Register with 10bit address
+ *
+ * @param[in] dev device to write to
+ * @param[in] addr address of the register to write
+ * @param[in] value value to write to the given register
+ */
+void mrf24j40_reg_write_long(mrf24j40_t *dev, const uint16_t addr, const uint8_t value);
+
+/**
+ * @brief   Read a chunk of data from the TX Normal FIFO area of the given device
+ *
+ * @param[in]  dev      device to read from
+ * @param[in]  offset   starting address to read from [valid 0x00-0x1ff]
+ * @param[out] data     buffer to read data into
+ * @param[in]  len      number of bytes to read from FIFO
+ */
+void mrf24j40_tx_normal_fifo_read(mrf24j40_t *dev, const uint16_t offset, uint8_t *data, const size_t len);
+
+/**
+ * @brief   Write a chunk of data into the TX Normal FIFO area of the given device
+ *
+ * @param[in] dev       device to write to
+ * @param[in] offset    address in the TX Normal FIFO to write to [valid 0x00-0x1ff]
+ * @param[in] data      data to copy into FIFO
+ * @param[in] len       number of bytes to write to FIFO
+ */
+void mrf24j40_tx_normal_fifo_write(mrf24j40_t *dev, const uint16_t offset, const uint8_t *data, const size_t len);
+
+/**
+ * @brief   Read a chunk of data from the RX_FIFO area of the given device
+ *
+ * @param[in]  dev      device to read from
+ * @param[in]  offset   starting address to read from [valid 0x00-0x1ff]
+ * @param[out] data     buffer to read data into
+ * @param[in]  len      number of bytes to read from FIFO
+ */
+void mrf24j40_rx_fifo_read(mrf24j40_t *dev, const uint16_t offset, uint8_t *data, const size_t len);
+
+/**
+ * @brief   Write a chunk of data into the RX_FIFO area of the given device
+ *
+ * @param[in] dev       device to write to
+ * @param[in] offset    address in the RX FIFO to write to [valid 0x00-0x1ff]
+ * @param[in] data      data to copy into FIFO
+ * @param[in] len       number of bytes to write to FIFO
+ */
+void mrf24j40_rx_fifo_write(mrf24j40_t *dev, const uint16_t offset, const uint8_t *data, const size_t len);
+
+/**
+ * @brief   Reset the pending task list of a device
+ *
+ * @param[in] dev       device to reset tasks of
+ */
+void mrf24j40_reset_tasks(mrf24j40_t *dev);
+
+/**
+ * @brief   Check for pending interrupts and update task list
+ *
+ * @param[in] dev       device to read
+ */
+void mrf24j40_update_tasks(mrf24j40_t *dev);
+
+/**
+ * @brief   Trigger a hardware reset
+ *
+ * @param[in] dev       device to reset
+ */
+void mrf24j40_hardware_reset(mrf24j40_t *dev);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MRF24J40_INTERNAL_H */
+/** @} */
diff --git a/drivers/mrf24j40/include/mrf24j40_netdev.h b/drivers/mrf24j40/include/mrf24j40_netdev.h
new file mode 100644
index 0000000000000000000000000000000000000000..eb95d20cd27422a1fe1a56e368024eb302404705
--- /dev/null
+++ b/drivers/mrf24j40/include/mrf24j40_netdev.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
+ * Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
+ *
+ * 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_mrf24j40
+ * @{
+ *
+ * @file
+ * @brief       Netdev interface to MRF24J40 drivers
+ *
+ * @author      Neo Nenaco <neo@nenaco.de>
+ * @author      Koen Zandberg <koen@bergzand.net>
+ */
+
+#ifndef MRF24J40_NETDEV_H
+#define MRF24J40_NETDEV_H
+
+#include "net/netdev2.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   Reference to the netdev device driver struct
+ */
+extern const netdev2_driver_t mrf24j40_driver;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MRF24J40_NETDEV_H */
+/** @} */
diff --git a/drivers/mrf24j40/include/mrf24j40_params.h b/drivers/mrf24j40/include/mrf24j40_params.h
new file mode 100644
index 0000000000000000000000000000000000000000..01a715d9f5e4e96339af65e03f2c5843dd6e75e0
--- /dev/null
+++ b/drivers/mrf24j40/include/mrf24j40_params.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
+ * Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
+ *
+ * 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_mrf24j40
+ *
+ * @{
+ * @file
+ * @brief       Default configuration for the MRF24J40 driver
+ *
+ * @author      Neo Nenaco <neo@nenaco.de>
+ * @author      Koen Zandberg <koen@bergzand.net>
+ */
+
+#ifndef MRF24J40_PARAMS_H
+#define MRF24J40_PARAMS_H
+
+#include "board.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   Set default configuration parameters for the MRF24J40 driver
+ * @{
+ */
+#ifndef MRF24J40_PARAM_SPI
+#define MRF24J40_PARAM_SPI          (SPI_DEV(0))
+#endif
+#ifndef MRF24J40_PARAM_SPI_CLK
+#define MRF24J40_PARAM_SPI_CLK      (SPI_CLK_5MHZ)
+#endif
+#ifndef MRF24J40_PARAM_CS
+#define MRF24J40_PARAM_CS           (GPIO_PIN(0, 0))
+#endif
+#ifndef MRF24J40_PARAM_INT
+#define MRF24J40_PARAM_INT          (GPIO_PIN(0, 1))
+#endif
+#ifndef MRF24J40_PARAM_RESET
+#define MRF24J40_PARAM_RESET        (GPIO_PIN(0, 3))
+#endif
+
+#define MRF24J40_PARAMS_DEFAULT     { .spi = MRF24J40_PARAM_SPI, \
+                                      .spi_clk = MRF24J40_PARAM_SPI_CLK, \
+                                      .cs_pin = MRF24J40_PARAM_CS, \
+                                      .int_pin = MRF24J40_PARAM_INT, \
+                                      .reset_pin = MRF24J40_PARAM_RESET }
+/**@}*/
+
+/**
+ * @brief   MRF24J40 configuration
+ */
+static const mrf24j40_params_t mrf24j40_params[] =
+{
+#ifdef MRF24J40_PARAMS_BOARD
+    MRF24J40_PARAMS_BOARD,
+#else
+    MRF24J40_PARAMS_DEFAULT,
+#endif
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MRF24J40_PARAMS_H */
+/** @} */
diff --git a/drivers/mrf24j40/include/mrf24j40_registers.h b/drivers/mrf24j40/include/mrf24j40_registers.h
new file mode 100644
index 0000000000000000000000000000000000000000..6aea886166d3aa0e79cdb73582f65050b12a5011
--- /dev/null
+++ b/drivers/mrf24j40/include/mrf24j40_registers.h
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
+ * Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
+ *
+ * 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_mrf24j40
+ * @{
+ *
+ * @file
+ * @brief Register and command definitions for MRF24J40 devices
+ *
+ * @author      Neo Nenaco <neo@nenaco.de>
+ * @author      Koen Zandberg <koen@bergzand.net>
+ */
+
+#ifndef MRF24J40_REGISTERS_H
+#define MRF24J40_REGISTERS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief SPI access specifiers
+ * @{
+ */
+#define MRF24J40_SHORT_ADDR_TRANS       (0x00)
+#define MRF24J40_LONG_ADDR_TRANS        (0x80)
+#define MRF24J40_ACCESS_READ            (0x00)
+#define MRF24J40_ACCESS_WRITE           (0x01)
+#define MRF24J40_ACCESS_WRITE_LNG       (0x10)
+#define MRF24J40_ADDR_OFFSET            (0x01)
+/** @} */
+
+/**
+ * @brief FIFO-Address-Map
+ ****@{
+ */
+#define MRF24J40_TX_NORMAL_FIFO         (0x000)
+#define MRF24J40_TX_BEACON_FIFO         (0x080)
+#define MRF24J40_TX_GTS1_FIFO           (0x100)
+#define MRF24J40_TX_GTS2_FIFO           (0x180)
+#define MRF24J40_RX_FIFO                (0x300)
+/** @} */
+
+/**
+ * @brief Short-Register addresses
+ * @{
+ */
+#define MRF24J40_REG_RXMCR              (0x00)
+#define MRF24J40_REG_PANIDL             (0x01)
+#define MRF24J40_REG_PANIDH             (0x02)
+#define MRF24J40_REG_SADRL              (0x03)
+#define MRF24J40_REG_SADRH              (0x04)
+#define MRF24J40_REG_EADR0              (0x05)
+#define MRF24J40_REG_EADR1              (0x06)
+#define MRF24J40_REG_EADR2              (0x07)
+#define MRF24J40_REG_EADR3              (0x08)
+#define MRF24J40_REG_EADR4              (0x09)
+#define MRF24J40_REG_EADR5              (0x0A)
+#define MRF24J40_REG_EADR6              (0x0B)
+#define MRF24J40_REG_EADR7              (0x0C)
+#define MRF24J40_REG_RXFLUSH            (0x0D)
+#define MRF24J40_REG_ORDER              (0x10)
+#define MRF24J40_REG_TXMCR              (0x11)
+#define MRF24J40_REG_ACKTMOUT           (0x12)
+#define MRF24J40_REG_ESLOTG1            (0x13)
+#define MRF24J40_REG_SYMTICKL           (0x14)
+#define MRF24J40_REG_SYMTICKH           (0x15)
+#define MRF24J40_REG_PACON0             (0x16)
+#define MRF24J40_REG_PACON1             (0x17)
+#define MRF24J40_REG_PACON2             (0x18)
+#define MRF24J40_REG_TXBCON0            (0x1A)
+#define MRF24J40_REG_TXNCON             (0x1B)
+#define MRF24J40_REG_TXG1CON            (0x1C)
+#define MRF24J40_REG_TXG2CON            (0x1D)
+#define MRF24J40_REG_ESLOTG23           (0x1E)
+#define MRF24J40_REG_ESLOTG45           (0x1F)
+#define MRF24J40_REG_ESLOTG67           (0x20)
+#define MRF24J40_REG_TXPEND             (0x21)
+#define MRF24J40_REG_WAKECON            (0x22)
+#define MRF24J40_REG_FRMOFFSET          (0x23)
+#define MRF24J40_REG_TXSTAT             (0x24)
+#define MRF24J40_REG_TXBCON1            (0x25)
+#define MRF24J40_REG_GATECLK            (0x26)
+#define MRF24J40_REG_TXTIME             (0x27)
+#define MRF24J40_REG_HSYMTMRL           (0x28)
+#define MRF24J40_REG_HSYMTMRH           (0x29)
+#define MRF24J40_REG_SOFTRST            (0x2A)
+#define MRF24J40_REG_SECCON0            (0x2C)
+#define MRF24J40_REG_SECCON1            (0x2D)
+#define MRF24J40_REG_TXSTBL             (0x2E)
+#define MRF24J40_REG_RXSR               (0x30)
+#define MRF24J40_REG_INTSTAT            (0x31)
+#define MRF24J40_REG_INTCON             (0x32)
+#define MRF24J40_REG_GPIO               (0x33)
+#define MRF24J40_REG_TRISGPIO           (0x34)
+#define MRF24J40_REG_SLPACK             (0x35)
+#define MRF24J40_REG_RFCTL              (0x36)
+#define MRF24J40_REG_SECCR2             (0x37)
+#define MRF24J40_REG_BBREG0             (0x38)
+#define MRF24J40_REG_BBREG1             (0x39)
+#define MRF24J40_REG_BBREG2             (0x3A)
+#define MRF24J40_REG_BBREG3             (0x3B)
+#define MRF24J40_REG_BBREG4             (0x3C)
+#define MRF24J40_REG_BBREG6             (0x3E)
+#define MRF24J40_REG_CCAEDTH            (0x3F)
+/** @} */
+
+/**
+ * @brief Long-Register addresses
+ * @{
+ */
+#define MRF24J40_REG_RFCON0             (0x200)
+#define MRF24J40_REG_RFCON1             (0x201)
+#define MRF24J40_REG_RFCON2             (0x202)
+#define MRF24J40_REG_RFCON3             (0x203)
+#define MRF24J40_REG_RFCON5             (0x205)
+#define MRF24J40_REG_RFCON6             (0x206)
+#define MRF24J40_REG_RFCON7             (0x207)
+#define MRF24J40_REG_RFCON8             (0x208)
+#define MRF24J40_REG_SLPCAL0            (0x209)
+#define MRF24J40_REG_SLPCAL1            (0x20A)
+#define MRF24J40_REG_SLPCAL2            (0x20B)
+#define MRF24J40_REG_RFSTATE            (0x20F)
+#define MRF24J40_REG_RSSI               (0x210)
+#define MRF24J40_REG_SLPCON0            (0x211)
+#define MRF24J40_REG_SLPCON1            (0x220)
+#define MRF24J40_REG_WAKETIMEL          (0x222)
+#define MRF24J40_REG_WAKETIMEH          (0x223)
+#define MRF24J40_REG_REMCNTL            (0x224)
+#define MRF24J40_REG_REMCNTH            (0x225)
+#define MRF24J40_REG_MAINCNT0           (0x226)
+#define MRF24J40_REG_MAINCNT1           (0x227)
+#define MRF24J40_REG_MAINCNT2           (0x228)
+#define MRF24J40_REG_MAINCNT3           (0x229)
+#define MRF24J40_REG_TESTMODE           (0x22F)
+#define MRF24J40_REG_ASSOEADR0          (0x230)
+#define MRF24J40_REG_ASSOEADR1          (0x231)
+#define MRF24J40_REG_ASSOEADR2          (0x232)
+#define MRF24J40_REG_ASSOEADR3          (0x233)
+#define MRF24J40_REG_ASSOEADR4          (0x234)
+#define MRF24J40_REG_ASSOEADR5          (0x235)
+#define MRF24J40_REG_ASSOEADR6          (0x236)
+#define MRF24J40_REG_ASSOEADR7          (0x237)
+#define MRF24J40_REG_ASSOSADR0          (0x238)
+#define MRF24J40_REG_ASSOSADR1          (0x239)
+#define MRF24J40_REG_UPNONCE0           (0x240)
+#define MRF24J40_REG_UPNONCE1           (0x241)
+#define MRF24J40_REG_UPNONCE2           (0x242)
+#define MRF24J40_REG_UPNONCE3           (0x243)
+#define MRF24J40_REG_UPNONCE4           (0x244)
+#define MRF24J40_REG_UPNONCE5           (0x245)
+#define MRF24J40_REG_UPNONCE6           (0x246)
+#define MRF24J40_REG_UPNONCE7           (0x247)
+#define MRF24J40_REG_UPNONCE8           (0x248)
+#define MRF24J40_REG_UPNONCE9           (0x249)
+#define MRF24J40_REG_UPNONCE10          (0x24A)
+#define MRF24J40_REG_UPNONCE11          (0x24B)
+#define MRF24J40_REG_UPNONCE12          (0x24C)
+/** @} */
+
+/**
+ * @brief   Timing definition for the mrf24j40.
+ * @{
+ */
+#define MRF24J40_RESET_DELAY                    (2000U)     /* Datasheet MRF24J40 ~2ms */
+#define MRF24J40_RESET_PULSE_WIDTH              (20000U)    /* 20ms (estimated */
+
+#define MRF24J40_WAKEUP_DELAY                   (2000U)
+/** Undocumented delay. Probably needed because the bit has to be sampled by the low speed sleep clock */
+#define MRF24J40_DELAY_SLEEP_TOGGLE             (50U)
+#define MRF24J40_STATE_RESET_DELAY              (200U)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the RXMCR register (0x00)
+ * @{
+ */
+#define MRF24J40_RXMCR_NOACKRSP                 (0b00100000)
+#define MRF24J40_RXMCR_PANCOORD                 (0b00001000)
+#define MRF24J40_RXMCR_COORD                    (0b00000100)
+#define MRF24J40_RXMCR_ERRPKT                   (0b00000010)
+#define MRF24J40_RXMCR_PROMI                    (0b00000001)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the RXFLUSH register (0x0D)
+ * @{
+ */
+#define MRF24J40_RXFLUSH_WAKEPOL                (0b01000000)
+#define MRF24J40_RXFLUSH_WAKEPAD                (0b00100000)
+#define MRF24J40_RXFLUSH_CMDONLY                (0b00001000)
+#define MRF24J40_RXFLUSH_DATAONLY               (0b00000100)
+#define MRF24J40_RXFLUSH_BCNONLY                (0b00000010)
+#define MRF24J40_RXFLUSH_RXFLUSH                (0b00000001)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the TXMCR register (0x11)
+ * @{
+ */
+#define MRF24J40_TXMCR_CSMA_BACKOFF_MASK        (0x07)
+
+#define MRF24J40_TXMCR_MACMINBE                 (0b00011000)
+#define MRF24J40_TXMCR_NOCSMA                   (0b10000000)
+#define MRF24J40_TXMCR_BATLIFEXT                (0b01000000)
+#define MRF24J40_TXMCR_SLOTTED                  (0b00100000)
+#define MRF24J40_TXMCR_MACMINBE1                (0b00010000)
+#define MRF24J40_TXMCR_MACMINBE0                (0b00001000)
+#define MRF24J40_TXMCR_CSMABF2                  (0b00000100)
+#define MRF24J40_TXMCR_CSMABF1                  (0b00000010)
+#define MRF24J40_TXMCR_CSMABF0                  (0b00000001)
+
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the PACON2 register (0x18)
+ * @{
+ */
+#define MRF24J40_PACON2_FIFOEN                  (0b10000000)
+#define MRF24J40_PACON2_TXONTS3                 (0b00100000)
+#define MRF24J40_PACON2_TXONTS2                 (0b00010000)
+#define MRF24J40_PACON2_TXONTS1                 (0b00001000)
+#define MRF24J40_PACON2_TXONTS0                 (0b00000100)
+#define MRF24J40_PACON2_TXONT8                  (0b00000010)
+#define MRF24J40_PACON2_TXONT7                  (0b00000001)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the TXNCON register (0x1B)
+ * @{
+ */
+#define MRF24J40_TXNCON_FPSTAT            (0x10)
+#define MRF24J40_TXNCON_INDIRECT          (0x08)
+#define MRF24J40_TXNCON_TXNACKREQ         (0x04)
+#define MRF24J40_TXNCON_TXNSECEN          (0x02)
+#define MRF24J40_TXNCON_TXNTRIG           (0x01)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the WAKECON register (0x22)
+ * @{
+ */
+#define MRF24J40_WAKECON_IMMWAKE                (0b10000000)
+#define MRF24J40_WAKECON_REGWAKE                (0b01000000)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the TXSTAT register (0x24)
+ * @{
+ */
+#define MRF24J40_TXSTAT_MAX_FRAME_RETRIES       (0b11000000)
+#define MRF24J40_TXSTAT_TXNRETRY1               (0b10000000)
+#define MRF24J40_TXSTAT_TXNRETRY0               (0b01000000)
+#define MRF24J40_TXSTAT_CCAFAIL                 (0b00100000)
+#define MRF24J40_TXSTAT_TXG2FNT                 (0b00010000)
+#define MRF24J40_TXSTAT_TXG1FNT                 (0b00001000)
+#define MRF24J40_TXSTAT_TXG2STAT                (0b00000100)
+#define MRF24J40_TXSTAT_TXG1STAT                (0b00000010)
+#define MRF24J40_TXSTAT_TXNSTAT                 (0b00000001)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the SOFTRST register (0x2A)
+ * @{
+ */
+#define MRF24J40_SOFTRST_RSTPWR                 (0b00000100)
+#define MRF24J40_SOFTRST_RSTBB                  (0b00000010)
+#define MRF24J40_SOFTRST_RSTMAC                 (0b00000001)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the TXSTBL register (0x2E)
+ * @{
+ */
+#define MRF24J40_TXSTBL_RFSTBL3        (0x80)
+#define MRF24J40_TXSTBL_RFSTBL2        (0x40)
+#define MRF24J40_TXSTBL_RFSTBL1        (0x20)
+#define MRF24J40_TXSTBL_RFSTBL0        (0x10)
+#define MRF24J40_TXSTBL_MSIFS3         (0x08)
+#define MRF24J40_TXSTBL_MSIFS2         (0x04)
+#define MRF24J40_TXSTBL_MSIFS1         (0x02)
+#define MRF24J40_TXSTBL_MSIFS0         (0x01)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the INTSTAT register (0x31)
+ * @{
+ */
+#define MRF24J40_INTSTAT_SLPIF          (0x80)
+#define MRF24J40_INTSTAT_WAKEIF         (0x40)
+#define MRF24J40_INTSTAT_HSYMTMRIF      (0x20)
+#define MRF24J40_INTSTAT_SECIF          (0x10)
+#define MRF24J40_INTSTAT_RXIF           (0x08)
+#define MRF24J40_INTSTAT_TXG2IF         (0x04)
+#define MRF24J40_INTSTAT_TXG1IF         (0x02)
+#define MRF24J40_INTSTAT_TXNIF          (0x01)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the INTCON register (0x32)
+ * @{
+ */
+#define MRF24J40_INTCON_SLPIE           (0x80)
+#define MRF24J40_INTCON_WAKEIE          (0x40)
+#define MRF24J40_INTCON_HSYMTMRIE       (0x20)
+#define MRF24J40_INTCON_SECIE           (0x10)
+#define MRF24J40_INTCON_RXIE            (0x08)
+#define MRF24J40_INTCON_TXG2IE          (0x04)
+#define MRF24J40_INTCON_TXG1IE          (0x02)
+#define MRF24J40_INTCON_TXNIE           (0x01)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the SLPACK register (0x35)
+ * @{
+ */
+#define MRF24J40_SLPACK_SLPACK                  (0b10000000)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the RFCTL register (0x36)
+ * @{
+ */
+#define MRF24J40_RFCTL_WAKECNT8         (0x10)
+#define MRF24J40_RFCTL_WAKECNT7         (0x08)
+#define MRF24J40_RFCTL_RFRST            (0x04)
+#define MRF24J40_RFCTL_RFTXMODE         (0x02)
+#define MRF24J40_RFCTL_RFRXMODE         (0x01)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the BBREG1 register (0x39)
+ * @{
+ */
+#define MRF24J40_BBREG1_RXDECINV                (0b00000100)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the BBREG2 register (0x3A)
+ * @{
+ */
+#define MRF24J40_BBREG2_CCAMODE3                (0b11000000)
+#define MRF25J40_BBREG2_CCAMODE1                (0b10000000)
+#define MRF24J40_BBREG2_CCAMODE2                (0b01000000)
+
+#define MRF24J40_BBREG2_CCACSTH                 (0b00111100)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the BBREG6 register (0x3E)
+ * @{
+ */
+#define MRF24J40_BBREG6_RSSIMODE1               (0b10000000)
+#define MRF24J40_BBREG6_RSSIMODE2               (0b01000000)
+#define MRF24J40_BBREG2_RSSIRDY                 (0b00000001)
+
+#define MRF24J40_BBREG2_CCACSTH                 (0b00111100)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the RFCON1 register (0x201)
+ * @{
+ */
+#define MRF24J40_RFCON1_VCOOPT7         (0x80)
+#define MRF24J40_RFCON1_VCOOPT6         (0x40)
+#define MRF24J40_RFCON1_VCOOPT5         (0x20)
+#define MRF24J40_RFCON1_VCOOPT4         (0x10)
+#define MRF24J40_RFCON1_VCOOPT3         (0x08)
+#define MRF24J40_RFCON1_VCOOPT2         (0x04)
+#define MRF24J40_RFCON1_VCOOPT1         (0x02)
+#define MRF24J40_RFCON1_VCOOPT0         (0x01)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the RFCON2 register (0x202)
+ * @{
+ */
+#define MRF24J40_RFCON2_PLLEN           (0x80)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the RFCON6 register (0x206)
+ * @{
+ */
+#define MRF24J40_RFCON6_TXFIL           (0x80)
+#define MRF24J40_RFCON6_20MRECVR        (0x10)
+#define MRF24J40_RFCON6_BATEN           (0x08)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the RFCON7 register (0x207)
+ * @{
+ */
+#define MRF24J40_RFCON7_SLPCLKSEL1      (0x80)
+#define MRF24J40_RFCON7_SLPCLKSEL2      (0x40)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the RFCON8 register (0x208)
+ * @{
+ */
+#define MRF24J40_RFCON8_RFVCO           (0x10)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the RFSTATE register (0x20F)
+ * @{
+ */
+#define MRF24J40_RFSTATE_MASK           (0xA0)
+#define MRF24J40_RFSTATE_RTSEL2         (0xE0)
+#define MRF24J40_RFSTATE_RTSEL1         (0xC0)
+#define MRF24J40_RFSTATE_RX             (0xA0)
+#define MRF24J40_RFSTATE_TX             (0x80)
+#define MRF24J40_RFSTATE_CALVCO         (0x60)
+#define MRF24J40_RFSTATE_SLEEP          (0x40)
+#define MRF24J40_RFSTATE_CALFIL         (0x20)
+#define MRF24J40_RFSTATE_RESET          (0x00)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the SLPCON1 register (0x211)
+ * @{
+ */
+#define MRF24J40_SLPCON0_INTEDGE        (0x02)
+#define MRF24J40_SLPCON0_SLPCLKEN       (0x01)
+/** @} */
+
+/**
+ * @brief   Bitfield definitions for the SLPCON1 register (0x212)
+ * @{
+ */
+#define MRF24J40_SLPCON1_CLKOUTEN       (0x20)
+#define MRF24J40_SLPCON1_SLPCLKDIV4     (0x10)
+#define MRF24J40_SLPCON1_SLPCLKDIV3     (0x08)
+#define MRF24J40_SLPCON1_SLPCLKDIV2     (0x04)
+#define MRF24J40_SLPCON1_SLPCLKDIV1     (0x02)
+#define MRF24J40_SLPCON1_SLPCLKDIV0     (0x01)
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MRF24J40_REGISTERS_H */
+/** @} */
diff --git a/drivers/mrf24j40/mrf24j40.c b/drivers/mrf24j40/mrf24j40.c
new file mode 100644
index 0000000000000000000000000000000000000000..8a26a02ab97947521a08e6d9513753dc5dc481e9
--- /dev/null
+++ b/drivers/mrf24j40/mrf24j40.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
+ * Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
+ *
+ * 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_mrf24j40
+ * @{
+ *
+ * @file
+ * @brief       Implementation of public functions for MRF24J40 drivers
+ *
+ * @author      Koen Zandberg <koen@bergzand.net>
+ * @author      Neo Nenaco <neo@nenaco.de>
+ *
+ * @}
+ */
+
+#include "uuid.h"
+#include "byteorder.h"
+#include "net/gnrc.h"
+#include "mrf24j40_registers.h"
+#include "mrf24j40_internal.h"
+#include "mrf24j40_netdev.h"
+#include "xtimer.h"
+
+#define ENABLE_DEBUG (0)
+#include "debug.h"
+
+void mrf24j40_setup(mrf24j40_t *dev, const mrf24j40_params_t *params)
+{
+    netdev2_t *netdev = (netdev2_t *)dev;
+
+    netdev->driver = &mrf24j40_driver;
+    /* initialize device descriptor */
+    memcpy(&dev->params, params, sizeof(mrf24j40_params_t));
+}
+
+void mrf24j40_reset(mrf24j40_t *dev)
+{
+    eui64_t addr_long;
+
+    mrf24j40_init(dev);
+
+    /* reset options and sequence number */
+    dev->netdev.seq = 0;
+    dev->netdev.flags = 0;
+
+    /* get an 8-byte unique ID to use as hardware address */
+    uuid_get(addr_long.uint8, IEEE802154_LONG_ADDRESS_LEN);
+    addr_long.uint8[0] &= ~(0x01);
+    addr_long.uint8[0] |=  (0x02);
+    /* set short and long address */
+    mrf24j40_set_addr_long(dev, NTOHLL(addr_long.uint64.u64));
+    mrf24j40_set_addr_short(dev, NTOHS(addr_long.uint16[0].u16));
+
+    /* set default PAN id */
+    mrf24j40_set_pan(dev, IEEE802154_DEFAULT_PANID);
+    mrf24j40_set_chan(dev, IEEE802154_DEFAULT_CHANNEL);
+
+    /* configure Immediate Sleep and Wake-Up mode */
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_WAKECON, MRF24J40_WAKECON_IMMWAKE);
+
+    /* set default options */
+    mrf24j40_set_option(dev, IEEE802154_FCF_PAN_COMP, true);
+    mrf24j40_set_option(dev, NETDEV2_IEEE802154_SRC_MODE_LONG, true);
+    mrf24j40_set_option(dev, NETDEV2_IEEE802154_ACK_REQ, true);
+    mrf24j40_set_option(dev, MRF24J40_OPT_CSMA, true);
+    mrf24j40_set_option(dev, MRF24J40_OPT_TELL_RX_START, false);
+    mrf24j40_set_option(dev, MRF24J40_OPT_TELL_RX_END, true);
+#ifdef MODULE_NETSTATS_L2
+    mrf24j40_set_option(dev, MRF24J40_OPT_TELL_TX_END, true);
+#endif
+
+    /* set default protocol */
+#ifdef MODULE_GNRC_SIXLOWPAN
+    dev->netdev.proto = GNRC_NETTYPE_SIXLOWPAN;
+#elif MODULE_GNRC
+    dev->netdev.proto = GNRC_NETTYPE_UNDEF;
+#endif
+
+    /* go into RX state */
+    mrf24j40_reset_tasks(dev);
+    dev->state = 0;
+    mrf24j40_set_state(dev, MRF24J40_PSEUDO_STATE_IDLE);
+    DEBUG("mrf24j40_reset(): reset complete.\n");
+}
+
+bool mrf24j40_cca(mrf24j40_t *dev)
+{
+    uint8_t tmp_ccaedth;
+    uint8_t status;
+    uint8_t tmp_rssi;
+
+    mrf24j40_assert_awake(dev);
+
+    /* trigger CCA measurment */
+    /* take a look onto datasheet chapter 3.6.1 */
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG6, MRF24J40_BBREG6_RSSIMODE1);
+    /* wait for result to be ready */
+    do {
+        status = mrf24j40_reg_read_short(dev, MRF24J40_REG_BBREG6);
+    } while (!(status & MRF24J40_BBREG2_RSSIRDY));
+    mrf24j40_assert_sleep(dev);
+    /* return according to measurement */
+    tmp_ccaedth = mrf24j40_reg_read_short(dev, MRF24J40_REG_CCAEDTH);       /* Energy detection threshold */
+    tmp_rssi = mrf24j40_reg_read_long(dev, MRF24J40_REG_RSSI);
+    if (tmp_rssi < tmp_ccaedth) {
+        /* channel is clear */
+        return true;            /* idle */
+    }
+    else {
+        /* channel is busy */
+        return false;
+    }
+}
+
+void mrf24j40_tx_prepare(mrf24j40_t *dev)
+{
+    DEBUG("[mrf24j40] TX_Prepare, Current state: %x\n", dev->state);
+    do {
+        mrf24j40_update_tasks(dev);
+    } while (!(dev->pending & MRF24J40_TASK_TX_DONE));
+    mrf24j40_assert_awake(dev);
+    dev->pending &= ~(MRF24J40_TASK_TX_DONE);
+    dev->tx_frame_len = IEEE802154_FCS_LEN;
+}
+
+size_t mrf24j40_tx_load(mrf24j40_t *dev, uint8_t *data, size_t len, size_t offset)
+{
+
+    DEBUG("[mrf24j40] TX_load, Current state: %x\n", dev->state);
+    dev->tx_frame_len += (uint8_t)len;
+
+    mrf24j40_tx_normal_fifo_write(dev, MRF24J40_TX_NORMAL_FIFO + offset + 2, data, len);
+    return offset + len;
+}
+
+void mrf24j40_tx_exec(mrf24j40_t *dev)
+{
+    netdev2_t *netdev = (netdev2_t *)dev;
+
+
+    dev->tx_frame_len = dev->tx_frame_len - IEEE802154_FCS_LEN;
+    /* write frame length field in FIFO */
+    mrf24j40_tx_normal_fifo_write(dev, MRF24J40_TX_NORMAL_FIFO + 1, &(dev->tx_frame_len), 1);
+
+    /* write header length to FIFO address 0x00 */
+    /* from figure 3-11 datasheet: header length =      2 Bytes Frame Control
+     *                                              +	1 Byte Seq. No.
+     *                                              +	4 to 20 Bytes Addressing Fields
+     */
+    mrf24j40_reg_write_long(dev, MRF24J40_TX_NORMAL_FIFO, dev->header_len);
+
+    if (dev->netdev.flags & NETDEV2_IEEE802154_ACK_REQ) {
+        mrf24j40_reg_write_short(dev, MRF24J40_REG_TXNCON, MRF24J40_TXNCON_TXNACKREQ | MRF24J40_TXNCON_TXNTRIG);
+    }
+    else {
+        mrf24j40_reg_write_short(dev, MRF24J40_REG_TXNCON, MRF24J40_TXNCON_TXNTRIG);
+    }
+    if (netdev->event_callback && (dev->netdev.flags & MRF24J40_OPT_TELL_TX_START)) {
+        netdev->event_callback(netdev, NETDEV2_EVENT_TX_STARTED);
+    }
+}
diff --git a/drivers/mrf24j40/mrf24j40_getset.c b/drivers/mrf24j40/mrf24j40_getset.c
new file mode 100644
index 0000000000000000000000000000000000000000..9da3b8fd67712b74946abbfe3bb666cdd844d38a
--- /dev/null
+++ b/drivers/mrf24j40/mrf24j40_getset.c
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
+ * Copyright (C) 2016 Koen Zandberg <koen@bergzand.net>
+ *
+ * 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_mrf24j40
+ * @{
+ *
+ * @file
+ * @brief       Getter and setter functions for the MRF24J40 drivers
+ *
+ * @author      Koen Zandberg <koen@bergzand.net>
+ * @author      Neo Nenaco <neo@nenaco.de>
+ *
+ * @}
+ */
+
+#include "mrf24j40.h"
+#include "mrf24j40_internal.h"
+#include "mrf24j40_registers.h"
+#include "xtimer.h"
+
+#define ENABLE_DEBUG (0)
+#include "debug.h"
+
+/* Values of RFCON3 - Address: 0x203
+ * 0b00000000 -> 0dB	-> 0
+ * 0b00001000 -> -0.5dB -> 0
+ * 0b00010000 -> -1.2dB -> -1
+ * 0b00011000 -> -1.9dB -> -2
+ * 0b00100000 -> -2.8dB -> -3
+ * 0b00101000 -> -3.7dB -> -4
+ * 0b00110000 -> -4.9dB -> -5
+ * 0b00111000 -> -6.3dB -> -6
+ * 0b01000000 -> -10dB  -> -10
+ * 0b01001000 -> -10.5dB-> -10
+ * 0b01010000 -> -11.2dB-> -11
+ * 0b01011000 -> -11.9dB-> -12
+ * 0b01100000 -> -12.8dB-> -13
+ * 0b01101000 -> -13.7dB-> -14
+ * 0b01110000 -> -14.9dB-> -15
+ * 0b01111000 -> -16.3dB-> -16
+ * 0b10000000 -> -20dB  -> -20
+ * 0b10001000 -> -20.5dB-> -20
+ * 0b10010000 -> -21.2dB-> -21
+ * 0b10011000 -> -21.9dB-> -22
+ * 0b10100000 -> -22.8dB-> -23
+ * 0b10101000 -> -23.7dB-> -24
+ * 0b10110000 -> -24.9dB-> -25
+ * 0b10111000 -> -26.3dB-> -26
+ * 0b11000000 -> -30dB  -> -30
+ * 0b11001000 -> -30.5dB-> -30
+ * 0b11010000 -> -31.2dB-> -31
+ * 0b11011000 -> -31.9dB-> -32
+ * 0b11100000 -> -32.8dB-> -33
+ * 0b11101000 -> -33.7dB-> -34
+ * 0b11110000 -> -34.9dB-> -35
+ * 0b11111000 -> -36.3dB-> -36
+ */
+
+static const int16_t tx_pow_to_dbm[] = { 0, 0, -1, -2, -3, -4, -5, -6,
+                                         -10, -10, -11, -12, -13, -14, -15, -16,
+                                         -20, -20, -21, -22, -23, -24, -25, -26,
+                                         -30, -30, -31, -32, -33, -34, -35, -36 };
+
+static const uint8_t dbm_to_tx_pow[] = { 0x00, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, 0x38, 0x38, 0x40,
+                                         0x40, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78, 0x78, 0x78, 0x80,
+                                         0x80, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8, 0xb8, 0xb8, 0xc0,
+                                         0xc0, 0xd0, 0xd8, 0xe0, 0xe8, 0xf0, 0xf8 };
+
+/* take a look onto datasheet table 3-8 */
+static const int8_t dBm_value[] = {  95, 89, 88, 88, 87, 87, 87, 87, \
+                                     86, 86, 86, 86, 85, 85, 85, 85, \
+                                     84, 84, 84, 84, 84, 84, 83, 83, \
+                                     83, 83, 82, 82, 82, 82, 81, 81, \
+                                     81, 81, 81, 80, 80, 80, 80, 80, \
+                                     80, 79, 79, 79, 79, 79, 78, 78, \
+                                     78, 78, 78, 77, 77, 77, 77, 77, \
+                                     76, 76, 76, 76, 76, 75, 75, 75, \
+                                     75, 75, 75, 74, 74, 74, 74, 73, \
+                                     73, 73, 73, 73, 72, 72, 72, 72, \
+                                     72, 71, 71, 71, 71, 71, 70, 70, \
+                                     70, 70, 70, 70, 70, 69, 69, 69, \
+                                     69, 69, 68, 68, 68, 68, 68, 68, \
+                                     68, 67, 67, 67, 67, 66, 66, 66, \
+                                     66, 66, 66, 65, 65, 65, 65, 65, \
+                                     64, 64, 64, 64, 63, 63, 63, 63, \
+                                     62, 62, 62, 62, 61, 61, 61, 61, \
+                                     60, 60, 60, 60, 60, 59, 59, 59, \
+                                     59, 59, 58, 58, 58, 58, 58, 57, \
+                                     57, 57, 57, 57, 57, 56, 56, 56, \
+                                     56, 56, 56, 56, 55, 55, 55, 55, \
+                                     54, 54, 54, 54, 54, 54, 53, 53, \
+                                     53, 53, 53, 53, 53, 52, 52, 52, \
+                                     52, 52, 52, 51, 51, 51, 51, 51, \
+                                     50, 50, 50, 50, 50, 49, 49, 49, \
+                                     49, 49, 48, 48, 48, 48, 47, 47, \
+                                     47, 47, 47, 46, 46, 46, 46, 45, \
+                                     45, 45, 45, 44, 44, 44, 44, 44, \
+                                     43, 43, 43, 42, 42, 42, 42, 41, \
+                                     41, 41, 41, 41, 41, 40, 40, 40, \
+                                     40, 40, 39, 39, 39, 39, 39, 38, \
+                                     38, 38, 38, 37, 37, 37, 36, 30 };
+
+/* take a look onto datasheet table 3-8 */
+static const uint8_t RSSI_value[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
+                                      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
+                                      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
+                                      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfd, 0xfa, 0xf5, \
+                                      0xef, 0xe9, 0xe4, 0xe1, 0xdd, 0xd8, 0xd4, 0xcf, 0xcb, 0xc6, \
+                                      0xc1, 0xbc, 0xb7, 0xb0, 0xaa, 0xa5, 0x9f, 0x99, 0x94, 0x8f, \
+                                      0x8a, 0x85, 0x81, 0x7d, 0x79, 0x75, 0x6f, 0x6b, 0x64, 0x5f, \
+                                      0x59, 0x53, 0x4e, 0x49, 0x44, 0x3f, 0x3a, 0x35, 0x30, 0x2b, \
+                                      0x25, 0x20, 0x1b, 0x17, 0x12, 0x0d, 0x09, 0x05, 0x02, 0x01, \
+                                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+
+uint16_t mrf24j40_get_addr_short(mrf24j40_t *dev)
+{
+    return (dev->netdev.short_addr[0] << 8) | dev->netdev.short_addr[1];
+}
+
+void mrf24j40_set_addr_short(mrf24j40_t *dev, uint16_t addr)
+{
+#ifdef MODULE_SIXLOWPAN
+    /* https://tools.ietf.org/html/rfc4944#section-12 requires the first bit to
+     * 0 for unicast addresses */
+    dev->netdev.short_addr[0] &= 0x7F;
+#endif
+    dev->netdev.short_addr[0] = (uint8_t)(addr);
+    dev->netdev.short_addr[1] = (uint8_t)(addr >> 8);
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_SADRL,
+                             dev->netdev.short_addr[1]);
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_SADRH,
+                             dev->netdev.short_addr[0]);
+}
+
+uint64_t mrf24j40_get_addr_long(mrf24j40_t *dev)
+{
+    uint64_t addr;
+
+    uint8_t *ap = (uint8_t *)(&addr);
+
+    for (int i = 0; i < 8; i++) {
+        ap[i] = dev->netdev.long_addr[i];
+    }
+    return addr;
+}
+
+void mrf24j40_set_addr_long(mrf24j40_t *dev, uint64_t addr)
+{
+    for (int i = 0; i < 8; i++) {
+        dev->netdev.long_addr[i] = (uint8_t)(addr >> (i * 8));
+        mrf24j40_reg_write_short(dev, (MRF24J40_REG_EADR0 + i),
+                                 (addr >> ((7 - i) * 8)));
+    }
+}
+
+uint8_t mrf24j40_get_chan(mrf24j40_t *dev)
+{
+    return dev->netdev.chan;
+}
+
+
+void mrf24j40_set_chan(mrf24j40_t *dev, uint8_t channel)
+{
+    uint8_t channel_value;
+
+    if ((channel < IEEE802154_CHANNEL_MIN) ||
+        (channel > IEEE802154_CHANNEL_MAX)) {
+        return;
+    }
+
+    dev->netdev.chan = channel;
+
+    /* Channel settings
+     * 11 -> Value = 0x03
+     * 12 -> Value = 0x13
+     * 13 -> Value = 0x23
+     * 14 -> Value = 0x33
+     * 15 -> Value = 0x43
+     * 16 -> Value = 0x53
+     * 17 -> Value = 0x63
+     * 18 -> Value = 0x73
+     * 19 -> Value = 0x83
+     * 20 -> Value = 0x93
+     * 21 -> Value = 0xA3
+     * 22 -> Value = 0xB3
+     * 23 -> Value = 0xC3
+     * 24 -> Value = 0xD3
+     * 25 -> Value = 0xE3
+     * 26 -> Value = 0xF3
+     */
+    /* not using an array here because it's not starting at zero */
+    switch (channel) {
+        case 11:    channel_value = 0x03;
+            break;
+        case 12:    channel_value = 0x13;
+            break;
+        case 13:    channel_value = 0x23;
+            break;
+        case 14:    channel_value = 0x33;
+            break;
+        case 15:    channel_value = 0x43;
+            break;
+        case 16:    channel_value = 0x53;
+            break;
+        case 17:    channel_value = 0x63;
+            break;
+        case 18:    channel_value = 0x73;
+            break;
+        case 19:    channel_value = 0x83;
+            break;
+        case 20:    channel_value = 0x93;
+            break;
+        case 21:    channel_value = 0xa3;
+            break;
+        case 22:    channel_value = 0xb3;
+            break;
+        case 23:    channel_value = 0xc3;
+            break;
+        case 24:    channel_value = 0xd3;
+            break;
+        case 25:    channel_value = 0xe3;
+            break;
+        case 26:    channel_value = 0xf3;
+            break;
+        default:
+            return;
+    }
+
+    mrf24j40_reg_write_long(dev, MRF24J40_REG_RFCON0, channel_value);
+    /*
+     * Note:Perform an RF State Machine Reset (see Section 3.1 �Reset�)
+     * after a channel frequency change. Then, delay at least 192 us after
+     * the RF State Machine Reset, to allow the RF circuitry to calibrate.
+     */
+    mrf24j40_reset_state_machine(dev);
+}
+
+uint16_t mrf24j40_get_pan(mrf24j40_t *dev)
+{
+    return dev->netdev.pan;
+}
+
+void mrf24j40_set_pan(mrf24j40_t *dev, uint16_t pan)
+{
+    le_uint16_t le_pan = byteorder_btols(byteorder_htons(pan));
+
+    dev->netdev.pan = pan;
+    DEBUG("pan0: %u, pan1: %u\n", le_pan.u8[0], le_pan.u8[1]);
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_PANIDL, le_pan.u8[0]);
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_PANIDH, le_pan.u8[1]);
+}
+
+
+int16_t mrf24j40_get_txpower(mrf24j40_t *dev)
+{
+    uint8_t txpower;
+
+    txpower = (mrf24j40_reg_read_long(dev, MRF24J40_REG_RFCON3) >> 3) & 0x1F;
+    return tx_pow_to_dbm[txpower];
+}
+
+void mrf24j40_set_txpower(mrf24j40_t *dev, int16_t txpower)
+{
+    uint8_t txpower_reg_value;
+
+    /* positive values are better with a conversion array */
+    txpower = (txpower < 0) ? -1 * txpower : txpower;
+    txpower = (txpower > 36) ? 36 : txpower;
+    txpower_reg_value = dbm_to_tx_pow[txpower];
+
+    mrf24j40_reg_write_long(dev, MRF24J40_REG_RFCON3, txpower_reg_value);
+
+}
+
+uint8_t mrf24j40_get_csma_max_retries(mrf24j40_t *dev)
+{
+    uint8_t tmp;
+
+    tmp  = mrf24j40_reg_read_short(dev, MRF24J40_REG_TXMCR);
+    tmp  &= MRF24J40_TXMCR_CSMA_BACKOFF_MASK;
+    return tmp;
+}
+
+void mrf24j40_set_csma_max_retries(mrf24j40_t *dev, int8_t retries)
+{
+    uint8_t tmp;
+
+    /* get current register settings */
+    tmp  = mrf24j40_reg_read_short(dev, MRF24J40_REG_TXMCR);
+    /* clear csma bits */
+    tmp  &= ~(MRF24J40_TXMCR_CSMA_BACKOFF_MASK);
+    /* apply new settings */
+    tmp  |= (retries & MRF24J40_TXMCR_CSMA_BACKOFF_MASK);
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_TXMCR, tmp);
+}
+
+int8_t mrf24j40_get_cca_threshold(mrf24j40_t *dev)
+{
+    int8_t tmp;
+
+    tmp = mrf24j40_reg_read_short(dev, MRF24J40_REG_CCAEDTH);   /* Energy detection threshold */
+
+    return(dBm_value[tmp]);                                     /* in dBm */
+}
+
+void mrf24j40_set_cca_threshold(mrf24j40_t *dev, int8_t value)
+{
+    /* ensure the given value is negative, since a CCA threshold > 0 is
+       just impossible: thus, any positive value given is considered
+       to be the absolute value of the actually wanted threshold */
+    if (value < 0) {
+        value = -value;
+    }
+
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_CCAEDTH, RSSI_value[value]);
+}
+
+void mrf24j40_set_option(mrf24j40_t *dev, uint16_t option, bool state)
+{
+    uint8_t tmp;
+
+    DEBUG("set option %i to %i\n", option, state);
+
+    /* set option field */
+    if (state) {
+        dev->netdev.flags |= option;
+        /* trigger option specific actions */
+        switch (option) {
+            case MRF24J40_OPT_CSMA:
+                DEBUG("[mrf24j40] opt: enabling CSMA mode (4 retries, macMinBE: 3 max BE: 5)\n");
+                /* Initialize CSMA seed with hardware address */
+                tmp = mrf24j40_reg_read_short(dev, MRF24J40_REG_TXMCR);
+                tmp &= ~MRF24J40_TXMCR_NOCSMA;
+                mrf24j40_reg_write_short(dev, MRF24J40_REG_TXMCR, tmp);
+                break;
+            case MRF24J40_OPT_PROMISCUOUS:
+                DEBUG("[mrf24j40] opt: enabling PROMISCUOUS mode\n");
+                /* disable auto ACKs in promiscuous mode */
+                tmp = mrf24j40_reg_read_short(dev, MRF24J40_REG_RXMCR);
+                tmp |= MRF24J40_RXMCR_NOACKRSP;
+                /* enable promiscuous mode */
+                tmp |= MRF24J40_RXMCR_PROMI;
+                tmp &= ~MRF24J40_RXMCR_ERRPKT;
+                mrf24j40_reg_write_short(dev, MRF24J40_REG_RXMCR, tmp);
+                break;
+            case NETDEV2_IEEE802154_ACK_REQ:
+                DEBUG("[mrf24j40] opt: enabling auto ACKs\n");
+                tmp = mrf24j40_reg_read_short(dev, MRF24J40_REG_RXMCR);
+                tmp &= ~MRF24J40_RXMCR_NOACKRSP;
+                mrf24j40_reg_write_short(dev, MRF24J40_REG_RXMCR, tmp);
+                break;
+            default:
+                /* do nothing */
+                break;
+        }
+    }
+    /* clear option field */
+    else {
+        dev->netdev.flags &= ~(option);
+        /* trigger option specific actions */
+        switch (option) {
+            case MRF24J40_OPT_CSMA:
+                DEBUG("[mrf24j40] opt: disabling CSMA mode\n");
+                tmp = mrf24j40_reg_read_short(dev, MRF24J40_REG_TXMCR);
+                tmp |= MRF24J40_TXMCR_NOCSMA;
+                /* MACMINBE<1:0>: The minimum value of the backoff exponent
+                 * in the CSMA-CA algorithm. Note that if this value is set
+                 * to �0�, collision avoidance is disabled. */
+                mrf24j40_reg_write_short(dev, MRF24J40_REG_TXMCR, tmp);
+                break;
+            case MRF24J40_OPT_PROMISCUOUS:
+                DEBUG("[mrf24j40] opt: disabling PROMISCUOUS mode\n");
+                /* disable promiscuous mode */
+                tmp = mrf24j40_reg_read_short(dev, MRF24J40_REG_RXMCR);
+                tmp &= ~MRF24J40_RXMCR_PROMI;
+                tmp &= ~MRF24J40_RXMCR_ERRPKT;
+                /* re-enable AUTOACK only if the option is set */
+                if (dev->netdev.flags & NETDEV2_IEEE802154_ACK_REQ) {
+                    tmp &= ~(MRF24J40_RXMCR_NOACKRSP);
+                    mrf24j40_reg_write_short(dev, MRF24J40_REG_RXMCR, tmp);
+                }
+                break;
+            case NETDEV2_IEEE802154_ACK_REQ:
+                DEBUG("[mrf24j40] opt: disabling auto ACKs\n");
+                tmp = mrf24j40_reg_read_short(dev, MRF24J40_REG_RXMCR);
+                tmp |= MRF24J40_RXMCR_NOACKRSP;
+                mrf24j40_reg_write_short(dev, MRF24J40_REG_RXMCR, tmp);
+                break;
+            default:
+                /* do nothing */
+                break;
+        }
+    }
+}
+
+
+void mrf24j40_set_state(mrf24j40_t *dev, uint8_t state)
+{
+    uint8_t old_state;
+
+    old_state = dev->state;
+
+
+    if (state == old_state) {
+        return;
+    }
+    /* check if asked to wake up from sleep mode */
+    if (old_state == MRF24J40_PSEUDO_STATE_SLEEP) {
+        mrf24j40_assert_awake(dev);
+    }
+    if (state == MRF24J40_PSEUDO_STATE_SLEEP) {
+        mrf24j40_sleep(dev);
+    }
+    if (state == MRF24J40_PSEUDO_STATE_IDLE) {
+        dev->state = state;
+    }
+    dev->idle_state = state;
+}
+
+void mrf24j40_sleep(mrf24j40_t *dev)
+{
+    DEBUG("[mrf24j40] Putting into sleep mode\n");
+    /* Datasheet chapter 3.15.2 IMMEDIATE SLEEP AND WAKE-UP MODE */
+    /* First force a Power Management Reset */
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_SOFTRST, MRF24J40_SOFTRST_RSTPWR);
+    /* Go to SLEEP mode */
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_SLPACK, MRF24J40_SLPACK_SLPACK);
+    dev->state = MRF24J40_PSEUDO_STATE_SLEEP;
+}
+
+void mrf24j40_assert_sleep(mrf24j40_t *dev)
+{
+    if (dev->idle_state == MRF24J40_PSEUDO_STATE_SLEEP) {
+        mrf24j40_sleep(dev);
+    }
+}
+
+void mrf24j40_assert_awake(mrf24j40_t *dev)
+{
+    if (dev->state == MRF24J40_PSEUDO_STATE_SLEEP) {
+        DEBUG("[mrf24j40] Waking up from sleep mode\n");
+        /* Wake mrf up */
+        mrf24j40_reg_write_short(dev, MRF24J40_REG_WAKECON, MRF24J40_WAKECON_IMMWAKE | MRF24J40_WAKECON_REGWAKE);
+        /* undocumented delay, needed for stable wakeup */
+        xtimer_usleep(MRF24J40_DELAY_SLEEP_TOGGLE);
+        mrf24j40_reg_write_short(dev, MRF24J40_REG_WAKECON, MRF24J40_WAKECON_IMMWAKE);
+        /* reset state machine */
+        mrf24j40_reg_write_short(dev, MRF24J40_REG_RFCTL, MRF24J40_RFCTL_RFRST);
+        mrf24j40_reg_write_short(dev, MRF24J40_REG_RFCTL, 0x00);
+        /* After wake-up, delay at least 2 ms to allow 20 MHz main
+         * oscillator time to stabilize before transmitting or receiving.
+         */
+        xtimer_usleep(MRF24J40_WAKEUP_DELAY);
+        /* reset interrupts */
+        mrf24j40_reg_read_short(dev, MRF24J40_REG_INTSTAT);
+        dev->state = MRF24J40_PSEUDO_STATE_IDLE;
+    }
+}
+
+void mrf24j40_reset_state_machine(mrf24j40_t *dev)
+{
+    uint8_t rfstate;
+
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_RFCTL, MRF24J40_RFCTL_RFRST);
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_RFCTL, 0x00);
+    xtimer_usleep(MRF24J40_STATE_RESET_DELAY);             /* Delay at least 192us */
+    do {
+        rfstate = mrf24j40_reg_read_long(dev, MRF24J40_REG_RFSTATE);
+    } while ((rfstate & MRF24J40_RFSTATE_MASK) != MRF24J40_RFSTATE_RX);
+}
+
+void mrf24j40_software_reset(mrf24j40_t *dev)
+{
+    uint8_t softrst;
+
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_SOFTRST, MRF24J40_SOFTRST_RSTPWR |
+                                                        MRF24J40_SOFTRST_RSTBB  |
+                                                        MRF24J40_SOFTRST_RSTMAC );
+    do {
+        softrst = mrf24j40_reg_read_short(dev, MRF24J40_REG_SOFTRST);
+    } while (softrst != 0);        /* wait until soft-reset has finished */
+}
diff --git a/drivers/mrf24j40/mrf24j40_internal.c b/drivers/mrf24j40/mrf24j40_internal.c
new file mode 100644
index 0000000000000000000000000000000000000000..2e540123a68644599b6f905193f1fb76a191a6f9
--- /dev/null
+++ b/drivers/mrf24j40/mrf24j40_internal.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
+ * Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
+ *
+ * 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_mrf24j40
+ * @{
+ *
+ * @file
+ * @brief       Implementation of driver internal functions
+ *
+ * @author      Koen Zandberg <koen@bergzand.net>
+ * @author      Neo Nenaco <neo@nenaco.de>
+ *
+ * @}
+ */
+#include "periph/spi.h"
+#include "periph/gpio.h"
+#include "xtimer.h"
+#include "mrf24j40_internal.h"
+#include "mrf24j40_registers.h"
+
+#define ENABLE_DEBUG (0)
+#include "debug.h"
+
+#define SPIDEV          (dev->params.spi)
+#define CSPIN           (dev->params.cs_pin)
+
+static inline void getbus(mrf24j40_t *dev)
+{
+    spi_acquire(SPIDEV, CSPIN, SPI_MODE_0, dev->params.spi_clk);
+}
+
+void mrf24j40_init(mrf24j40_t *dev)
+{
+
+    mrf24j40_hardware_reset(dev);
+
+#if ENABLE_DEBUG
+    /* Check if MRF24J40 is available */
+    uint8_t txmcr = mrf24j40_reg_read_short(dev, MRF24J40_REG_TXMCR);
+    if ((txmcr == 0xFF) || (txmcr == 0x00)) {
+        /* Write default value to TXMCR register */
+        mrf24j40_reg_write_short(dev, MRF24J40_REG_TXMCR, MRF24J40_TXMCR_MACMINBE1 |
+                                                          MRF24J40_TXMCR_MACMINBE0 |
+                                                          MRF24J40_TXMCR_CSMABF2);
+        txmcr = mrf24j40_reg_read_short(dev, MRF24J40_REG_TXMCR);
+        if (txmcr != (MRF24J40_TXMCR_MACMINBE1 |
+                      MRF24J40_TXMCR_MACMINBE0 |
+                      MRF24J40_TXMCR_CSMABF2)) {
+            DEBUG("[mrf24j40] Initialization failure, SPI interface communication failed\n");
+            /* Return to prevents hangup later in the initialization */
+            return;
+        }
+    }
+#endif
+
+    /* do a soft reset */
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_SOFTRST, MRF24J40_SOFTRST_RSTPWR |
+                                                        MRF24J40_SOFTRST_RSTBB  |
+                                                        MRF24J40_SOFTRST_RSTMAC );
+
+    /* flush RX FIFO */
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_RXFLUSH, MRF24J40_RXFLUSH_RXFLUSH);
+
+    /* Here starts init-process as described on MRF24J40 Manual Chap. 3.2 */
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_PACON2,  (MRF24J40_PACON2_TXONTS2 |
+                                                         MRF24J40_PACON2_TXONTS1 |
+                                                         MRF24J40_PACON2_FIFOEN));
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_TXSTBL, (MRF24J40_TXSTBL_RFSTBL3 |
+                                                        MRF24J40_TXSTBL_RFSTBL0 |
+                                                        MRF24J40_TXSTBL_MSIFS2  |
+                                                        MRF24J40_TXSTBL_MSIFS0));
+    mrf24j40_reg_write_long(dev, MRF24J40_REG_RFCON1, MRF24J40_RFCON1_VCOOPT1);
+    mrf24j40_reg_write_long(dev, MRF24J40_REG_RFCON2, MRF24J40_RFCON2_PLLEN);
+    mrf24j40_reg_write_long(dev, MRF24J40_REG_RFCON6, (MRF24J40_RFCON6_TXFIL |
+                                                       MRF24J40_RFCON6_20MRECVR));
+    mrf24j40_reg_write_long(dev, MRF24J40_REG_RFCON7, MRF24J40_RFCON7_SLPCLKSEL1 );
+    mrf24j40_reg_write_long(dev, MRF24J40_REG_RFCON8, MRF24J40_RFCON8_RFVCO );
+    mrf24j40_reg_write_long(dev, MRF24J40_REG_SLPCON1, (MRF24J40_SLPCON1_CLKOUTEN |
+                                                        MRF24J40_SLPCON1_SLPCLKDIV0));
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG2, MRF25J40_BBREG2_CCAMODE1 );
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_CCAEDTH, 0x60);
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG6, MRF24J40_BBREG6_RSSIMODE2 );
+
+    /* Enable immediate sleep mode */
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_WAKECON, MRF24J40_WAKECON_IMMWAKE);
+
+    /* set interrupt pin polarity, rising edge */
+    mrf24j40_reg_write_long(dev, MRF24J40_REG_SLPCON0, MRF24J40_SLPCON0_INTEDGE );
+    /* reset RF state machine */
+    mrf24j40_reset_state_machine(dev);
+
+    /* clear interrupts */
+    mrf24j40_reg_read_short(dev, MRF24J40_REG_INTSTAT);
+
+    /* mrf24j40_set_interrupts */
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_INTCON, ~(MRF24J40_INTCON_RXIE | MRF24J40_INTCON_TXNIE));
+}
+
+uint8_t mrf24j40_reg_read_short(mrf24j40_t *dev, const uint8_t addr)
+{
+    char value;
+
+    getbus(dev);
+    value = spi_transfer_reg(SPIDEV, CSPIN, MRF24J40_SHORT_ADDR_TRANS |
+                                            (addr << MRF24J40_ADDR_OFFSET) |
+                                            MRF24J40_ACCESS_READ, 0);
+    spi_release(SPIDEV);
+    return (uint8_t)value;
+}
+
+void mrf24j40_reg_write_short(mrf24j40_t *dev, const uint8_t addr, const uint8_t value)
+{
+    getbus(dev);
+    spi_transfer_reg(SPIDEV, CSPIN , MRF24J40_SHORT_ADDR_TRANS |
+                                     (addr << MRF24J40_ADDR_OFFSET) |
+                                     MRF24J40_ACCESS_WRITE, value);
+    spi_release(SPIDEV);
+}
+
+uint8_t mrf24j40_reg_read_long(mrf24j40_t *dev, const uint16_t addr)
+{
+    uint8_t reg1, reg2;
+
+    reg1 = MRF24J40_LONG_ADDR_TRANS | (addr >> 3);
+    reg2 = (addr << 5) | MRF24J40_ACCESS_READ;
+    char value;
+    getbus(dev);
+    spi_transfer_byte(SPIDEV, CSPIN, true, reg1);
+    spi_transfer_byte(SPIDEV, CSPIN, true, reg2);
+    value = spi_transfer_byte(SPIDEV, CSPIN, false, 0);
+    spi_release(SPIDEV);
+
+    return (uint8_t)value;
+}
+
+void mrf24j40_reg_write_long(mrf24j40_t *dev, const uint16_t addr, const uint8_t value)
+{
+    uint8_t reg1, reg2;
+
+    reg1 = MRF24J40_LONG_ADDR_TRANS | (addr >> 3);
+    reg2 = (addr << 5) | MRF24J40_ACCESS_WRITE_LNG;
+    getbus(dev);
+    spi_transfer_byte(SPIDEV, CSPIN, true, reg1);
+    spi_transfer_byte(SPIDEV, CSPIN, true, reg2);
+    spi_transfer_byte(SPIDEV, CSPIN, false, value);
+    spi_release(SPIDEV);
+}
+
+void mrf24j40_tx_normal_fifo_read(mrf24j40_t *dev, const uint16_t offset, uint8_t *data, const size_t len)
+{
+    uint8_t reg1, reg2;
+
+    reg1 = MRF24J40_LONG_ADDR_TRANS | (offset >> 3);
+    reg2 = (offset << 5) | MRF24J40_ACCESS_READ;
+    getbus(dev);
+    spi_transfer_byte(SPIDEV, CSPIN, true, reg1);
+    spi_transfer_byte(SPIDEV, CSPIN, true, reg2);
+    spi_transfer_bytes(SPIDEV, CSPIN, false, NULL, (char *)data, len);
+    spi_release(SPIDEV);
+}
+
+void mrf24j40_tx_normal_fifo_write(mrf24j40_t *dev,
+                                   const uint16_t offset,
+                                   const uint8_t *data,
+                                   const size_t len)
+{
+    uint16_t addr;
+    uint8_t reg1;
+    uint8_t reg2;
+
+    addr = offset;
+
+    reg1 = MRF24J40_LONG_ADDR_TRANS | (addr >> 3);
+    reg2 = (addr << 5) | MRF24J40_ACCESS_WRITE_LNG;
+
+    getbus(dev);
+    spi_transfer_byte(SPIDEV, CSPIN, true, reg1);
+    spi_transfer_byte(SPIDEV, CSPIN, true, reg2);
+    spi_transfer_bytes(SPIDEV, CSPIN, false, (char *)data, NULL, len);
+    spi_release(SPIDEV);
+}
+
+void mrf24j40_rx_fifo_read(mrf24j40_t *dev, const uint16_t offset, uint8_t *data, const size_t len)
+{
+    uint16_t rx_addr;
+
+    rx_addr = MRF24J40_RX_FIFO + offset;
+
+    uint8_t reg1, reg2;
+    reg1 = MRF24J40_LONG_ADDR_TRANS | (rx_addr >> 3);
+    reg2 = (rx_addr << 5) | MRF24J40_ACCESS_READ;
+    getbus(dev);
+    spi_transfer_byte(SPIDEV, CSPIN, true, reg1);
+    spi_transfer_byte(SPIDEV, CSPIN, true, reg2);
+    spi_transfer_bytes(SPIDEV, CSPIN, false, NULL, (char *)data, len);
+    spi_release(SPIDEV);
+}
+
+void mrf24j40_rx_fifo_write(mrf24j40_t *dev, const uint16_t offset, const uint8_t *data, const size_t len)
+{
+    uint16_t i;
+
+    for (i = 0; i < len; i++) {
+        mrf24j40_reg_write_long(dev, i, data[i]);
+    }
+}
+
+void mrf24j40_reset_tasks(mrf24j40_t *dev)
+{
+    dev->pending = MRF24J40_TASK_TX_DONE;
+}
+
+void mrf24j40_update_tasks(mrf24j40_t *dev)
+{
+    if (dev->irq_flag) {
+        uint8_t newpending = 0;
+        uint8_t instat = 0;
+
+        dev->irq_flag = 0;
+        instat = mrf24j40_reg_read_short(dev, MRF24J40_REG_INTSTAT);
+        /* check if TX done */
+        if (instat & MRF24J40_INTSTAT_TXNIF) {
+            newpending |= MRF24J40_TASK_TX_DONE | MRF24J40_TASK_TX_READY;
+            /* transmit done, returning to configured idle state */
+            mrf24j40_assert_sleep(dev);
+        }
+        if (instat & MRF24J40_INTSTAT_RXIF) {
+            newpending |= MRF24J40_TASK_RX_READY;
+        }
+        /* check if RX pending */
+        dev->pending |= newpending;
+    }
+}
+
+
+void mrf24j40_hardware_reset(mrf24j40_t *dev)
+{
+    /* wake up from sleep in case radio is sleeping */
+    mrf24j40_assert_awake(dev);
+
+    /* trigger hardware reset */
+    gpio_clear(dev->params.reset_pin);
+    /* Datasheet - Not specified */
+    xtimer_usleep(MRF24J40_RESET_PULSE_WIDTH);
+    gpio_set(dev->params.reset_pin);
+    /* Datasheet - MRF24J40 ~2ms */
+    xtimer_usleep(MRF24J40_RESET_DELAY);
+}
diff --git a/drivers/mrf24j40/mrf24j40_netdev.c b/drivers/mrf24j40/mrf24j40_netdev.c
new file mode 100644
index 0000000000000000000000000000000000000000..7573950cc629ed0c1b9258c90eec668de20ab514
--- /dev/null
+++ b/drivers/mrf24j40/mrf24j40_netdev.c
@@ -0,0 +1,569 @@
+/*
+ * Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
+ * Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
+ *
+ * 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_mrf24j40
+ * @{
+ *
+ * @file
+ * @brief       Netdev adaption for the MRF24J40 drivers
+ *
+ * @author      Koen Zandberg <koen@bergzand.net>
+ * @author      Neo Nenaco <neo@nenaco.de>
+ *
+ * @}
+ */
+
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "net/eui64.h"
+#include "net/ieee802154.h"
+#include "net/netdev2.h"
+#include "net/netdev2/ieee802154.h"
+
+#include "mrf24j40.h"
+#include "mrf24j40_netdev.h"
+#include "mrf24j40_internal.h"
+#include "mrf24j40_registers.h"
+
+#define ENABLE_DEBUG (0)
+#include "debug.h"
+
+#define _MAX_MHR_OVERHEAD   (25)
+
+static int _send(netdev2_t *netdev, const struct iovec *vector, unsigned count);
+static int _recv(netdev2_t *netdev, void *buf, size_t len, void *info);
+static int _init(netdev2_t *netdev);
+static void _isr(netdev2_t *netdev);
+static int _get(netdev2_t *netdev, netopt_t opt, void *val, size_t max_len);
+static int _set(netdev2_t *netdev, netopt_t opt, void *val, size_t len);
+
+const netdev2_driver_t mrf24j40_driver = {
+    .send = _send,
+    .recv = _recv,
+    .init = _init,
+    .isr = _isr,
+    .get = _get,
+    .set = _set,
+};
+
+static void _irq_handler(void *arg)
+{
+    netdev2_t *dev = (netdev2_t *) arg;
+
+    if (dev->event_callback) {
+        dev->event_callback(dev, NETDEV2_EVENT_ISR);
+    }
+    ((mrf24j40_t *)arg)->irq_flag = 1;
+}
+
+static int _init(netdev2_t *netdev)
+{
+    mrf24j40_t *dev = (mrf24j40_t *)netdev;
+
+    /* initialise GPIOs */
+    spi_init_cs(dev->params.spi, dev->params.cs_pin);
+    gpio_init(dev->params.reset_pin, GPIO_OUT);
+    gpio_set(dev->params.reset_pin);
+    gpio_init_int(dev->params.int_pin, GPIO_IN, GPIO_RISING, _irq_handler, dev);
+
+#ifdef MODULE_NETSTATS_L2
+    memset(&netdev->stats, 0, sizeof(netstats_t));
+#endif
+    /* reset device to default values and put it into RX state */
+    mrf24j40_reset(dev);
+    return 0;
+}
+
+static int _send(netdev2_t *netdev, const struct iovec *vector, unsigned count)
+{
+    mrf24j40_t *dev = (mrf24j40_t *)netdev;
+    const struct iovec *ptr = vector;
+    size_t len = 0;
+
+    mrf24j40_tx_prepare(dev);
+
+    /* load packet data into FIFO */
+    for (int i = 0; i < count; i++, ptr++) {
+        /* current packet data + FCS too long */
+        if ((len + ptr->iov_len + 2) > IEEE802154_FRAME_LEN_MAX) {
+            DEBUG("[mrf24j40] error: packet too large (%u byte) to be send\n",
+                  (unsigned)len + 2);
+            return -EOVERFLOW;
+        }
+
+#ifdef MODULE_NETSTATS_L2
+        netdev->stats.tx_bytes += len;
+#endif
+        len = mrf24j40_tx_load(dev, ptr->iov_base, ptr->iov_len, len);
+        if (i == 0) {
+            dev->header_len = len;
+        }
+
+    }
+
+    /* send data out directly if pre-loading is disabled */
+    if (!(dev->netdev.flags & MRF24J40_OPT_PRELOADING)) {
+        mrf24j40_tx_exec(dev);
+    }
+    /* return the number of bytes that were actually send out */
+    return (int)len;
+
+}
+
+static int _recv(netdev2_t *netdev, void *buf, size_t len, void *info)
+{
+    mrf24j40_t *dev = (mrf24j40_t *)netdev;
+    uint8_t phr;
+    size_t pkt_len;
+
+    /* Disable receiving while reading the RX fifo (datasheet sec. 3.11.4) */
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG1, MRF24J40_BBREG1_RXDECINV );
+
+    /* get the size of the received packet */
+    phr = mrf24j40_reg_read_long(dev, MRF24J40_RX_FIFO);
+
+    pkt_len = (phr & 0x7f) - 2;
+
+    /* just return length when buf == NULL */
+    if (buf == NULL) {
+        return pkt_len;
+    }
+#ifdef MODULE_NETSTATS_L2
+    netdev->stats.rx_count++;
+    netdev->stats.rx_bytes += pkt_len;
+#endif
+    /* not enough space in buf */
+    if (pkt_len > len) {
+        DEBUG("[mrf24j40] No space in receive buffers\n");
+        mrf24j40_reg_write_short(dev, MRF24J40_REG_RXFLUSH, MRF24J40_RXFLUSH_RXFLUSH);
+        /* Turn on reception of packets off the air */
+        mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG1, 0x00);
+        return -ENOBUFS;
+    }
+    /* copy payload */
+    mrf24j40_rx_fifo_read(dev, 1, (uint8_t *)buf, pkt_len);
+
+    if (info != NULL) {
+        netdev2_ieee802154_rx_info_t *radio_info = info;
+        /* Read LQI and RSSI values from the RX fifo */
+        mrf24j40_rx_fifo_read(dev, phr + 1, &(radio_info->lqi), 1);
+        mrf24j40_rx_fifo_read(dev, phr + 2, &(radio_info->rssi), 1);
+    }
+
+    /* Turn on reception of packets off the air */
+    mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG1, 0x00);
+    return pkt_len;
+}
+
+static netopt_state_t _get_state(mrf24j40_t *dev)
+{
+    if (!(dev->pending & MRF24J40_TASK_TX_DONE)) {
+        return NETOPT_STATE_TX;
+    }
+    if (dev->pending & MRF24J40_TASK_RX_READY) {
+        return NETOPT_STATE_RX;
+    }
+    switch (dev->state) {
+        case MRF24J40_PSEUDO_STATE_SLEEP:
+            return NETOPT_STATE_SLEEP;
+    }
+    return NETOPT_STATE_IDLE;
+}
+
+static int _get(netdev2_t *netdev, netopt_t opt, void *val, size_t max_len)
+{
+    mrf24j40_t *dev = (mrf24j40_t *) netdev;
+
+    if (netdev == NULL) {
+        return -ENODEV;
+    }
+
+    int res;
+    switch (opt) {
+        case NETOPT_CHANNEL_PAGE:
+            if (max_len < sizeof(uint16_t)) {
+                res = -EOVERFLOW;
+            }
+            else {
+                ((uint8_t *)val)[1] = 0;
+                ((uint8_t *)val)[0] = 0;
+                res = sizeof(uint16_t);
+            }
+            break;
+
+        case NETOPT_MAX_PACKET_SIZE:
+            if (max_len < sizeof(int16_t)) {
+                res = -EOVERFLOW;
+            }
+            else {
+                *((uint16_t *)val) = IEEE802154_FRAME_LEN_MAX - _MAX_MHR_OVERHEAD;
+                res = sizeof(uint16_t);
+            }
+            break;
+
+        case NETOPT_STATE:
+            if (max_len < sizeof(netopt_state_t)) {
+                res = -EOVERFLOW;
+            }
+            else {
+                *((netopt_state_t *)val) = _get_state(dev);
+                res = sizeof(netopt_state_t);
+            }
+            break;
+
+        case NETOPT_PRELOADING:
+            if (dev->netdev.flags & MRF24J40_OPT_PRELOADING) {
+                *((netopt_enable_t *)val) = NETOPT_ENABLE;
+            }
+            else {
+                *((netopt_enable_t *)val) = NETOPT_DISABLE;
+            }
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_PROMISCUOUSMODE:
+            if (dev->netdev.flags & MRF24J40_OPT_PROMISCUOUS) {
+                *((netopt_enable_t *)val) = NETOPT_ENABLE;
+            }
+            else {
+                *((netopt_enable_t *)val) = NETOPT_DISABLE;
+            }
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_RX_START_IRQ:
+            *((netopt_enable_t *)val) =
+                !!(dev->netdev.flags & MRF24J40_OPT_TELL_RX_START);
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_RX_END_IRQ:
+            *((netopt_enable_t *)val) =
+                !!(dev->netdev.flags & MRF24J40_OPT_TELL_RX_END);
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_TX_START_IRQ:
+            *((netopt_enable_t *)val) =
+                !!(dev->netdev.flags & MRF24J40_OPT_TELL_TX_START);
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_TX_END_IRQ:
+            *((netopt_enable_t *)val) =
+                !!(dev->netdev.flags & MRF24J40_OPT_TELL_TX_END);
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_CSMA:
+            *((netopt_enable_t *)val) =
+                !!(dev->netdev.flags & MRF24J40_OPT_CSMA);
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_TX_POWER:
+            if (max_len < sizeof(int16_t)) {
+                res = -EOVERFLOW;
+            }
+            else {
+                *((uint16_t *)val) = mrf24j40_get_txpower(dev);
+                res = sizeof(uint16_t);
+            }
+            break;
+
+        case NETOPT_RETRANS:
+            if (max_len < sizeof(uint8_t)) {
+                res = -EOVERFLOW;
+            }
+            else {
+                *((uint8_t *)val) = MRF24J40_MAX_FRAME_RETRIES;
+                res = sizeof(uint8_t);
+            }
+            break;
+
+        case NETOPT_IS_CHANNEL_CLR:
+            if (mrf24j40_cca(dev)) {
+                *((netopt_enable_t *)val) = NETOPT_ENABLE;
+            }
+            else {
+                *((netopt_enable_t *)val) = NETOPT_DISABLE;
+            }
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_CSMA_RETRIES:
+            if (max_len < sizeof(uint8_t)) {
+                res = -EOVERFLOW;
+            }
+            else {
+                *((uint8_t *)val) = mrf24j40_get_csma_max_retries(dev);
+                res = sizeof(uint8_t);
+            }
+            break;
+
+        case NETOPT_CCA_THRESHOLD:
+            if (max_len < sizeof(int8_t)) {
+                res = -EOVERFLOW;
+            }
+            else {
+                *((int8_t *)val) = mrf24j40_get_cca_threshold(dev);
+                res = sizeof(int8_t);
+            }
+            break;
+
+        default:
+            /* try netdev2 settings */
+            res = netdev2_ieee802154_get((netdev2_ieee802154_t *)netdev, opt,
+                                         val, max_len);
+    }
+    return res;
+}
+
+static int _set_state(mrf24j40_t *dev, netopt_state_t state)
+{
+    switch (state) {
+        case NETOPT_STATE_SLEEP:
+            mrf24j40_set_state(dev, MRF24J40_PSEUDO_STATE_SLEEP);
+            break;
+        case NETOPT_STATE_IDLE:
+            mrf24j40_set_state(dev, MRF24J40_PSEUDO_STATE_IDLE);
+            break;
+        case NETOPT_STATE_TX:
+            if (dev->netdev.flags & MRF24J40_OPT_PRELOADING) {
+                mrf24j40_tx_exec(dev);
+            }
+            break;
+        case NETOPT_STATE_RESET:
+            mrf24j40_reset(dev);
+            break;
+        default:
+            return -ENOTSUP;
+    }
+    return sizeof(netopt_state_t);
+}
+
+static int _set(netdev2_t *netdev, netopt_t opt, void *val, size_t len)
+{
+    mrf24j40_t *dev = (mrf24j40_t *) netdev;
+    int res = -ENOTSUP;
+
+    if (dev == NULL) {
+        return -ENODEV;
+    }
+
+    switch (opt) {
+        case NETOPT_ADDRESS:
+            if (len > sizeof(uint16_t)) {
+                res = -EOVERFLOW;
+            }
+            else {
+                mrf24j40_set_addr_short(dev, *((uint16_t *)val));
+                /* don't set res to set netdev2_ieee802154_t::short_addr */
+            }
+            break;
+
+        case NETOPT_ADDRESS_LONG:
+            if (len > sizeof(uint64_t)) {
+                res = -EOVERFLOW;
+            }
+            else {
+                mrf24j40_set_addr_long(dev, *((uint64_t *)val));
+                /* don't set res to set netdev2_ieee802154_t::long_addr */
+            }
+            break;
+
+        case NETOPT_NID:
+            if (len > sizeof(uint16_t)) {
+                res = -EOVERFLOW;
+            }
+            else {
+                mrf24j40_set_pan(dev, *((uint16_t *)val));
+                /* don't set res to set netdev2_ieee802154_t::pan */
+            }
+            break;
+
+        case NETOPT_CHANNEL:
+            if (len != sizeof(uint16_t)) {
+                res = -EINVAL;
+            }
+            else {
+                uint8_t chan = ((uint8_t *)val)[0];
+                if (chan < IEEE802154_CHANNEL_MIN ||
+                    chan > IEEE802154_CHANNEL_MAX ||
+                    dev->netdev.chan == chan) {
+                    res = -EINVAL;
+                    break;
+                }
+                mrf24j40_set_chan(dev, chan);
+                /* don't set res to set netdev2_ieee802154_t::chan */
+            }
+            break;
+
+        case NETOPT_CHANNEL_PAGE:
+            if (len != sizeof(uint16_t)) {
+                res = -EINVAL;
+            }
+            else {
+                uint8_t page = ((uint8_t *)val)[0];
+
+                /* mrf24j40 only supports page 0, no need to configure anything in the driver. */
+                if (page != 0) {
+                    res = -EINVAL;
+                }
+                else {
+                    res = sizeof(uint16_t);
+                }
+            }
+            break;
+
+        case NETOPT_TX_POWER:
+            if (len > sizeof(int16_t)) {
+                res = -EOVERFLOW;
+            }
+            else {
+                mrf24j40_set_txpower(dev, *((int16_t *)val));
+                res = sizeof(uint16_t);
+            }
+            break;
+
+        case NETOPT_STATE:
+            if (len > sizeof(netopt_state_t)) {
+                res = -EOVERFLOW;
+            }
+            else {
+                res = _set_state(dev, *((netopt_state_t *)val));
+            }
+            break;
+
+        case NETOPT_AUTOACK:
+            mrf24j40_set_option(dev, NETDEV2_IEEE802154_ACK_REQ,
+                                ((bool *)val)[0]);
+            /* don't set res to set netdev2_ieee802154_t::flags */
+            break;
+
+        case NETOPT_PRELOADING:
+            mrf24j40_set_option(dev, MRF24J40_OPT_PRELOADING,
+                                ((bool *)val)[0]);
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_PROMISCUOUSMODE:
+            mrf24j40_set_option(dev, MRF24J40_OPT_PROMISCUOUS,
+                                ((bool *)val)[0]);
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_RX_START_IRQ:
+            mrf24j40_set_option(dev, MRF24J40_OPT_TELL_RX_START,
+                                ((bool *)val)[0]);
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_RX_END_IRQ:
+            mrf24j40_set_option(dev, MRF24J40_OPT_TELL_RX_END,
+                                ((bool *)val)[0]);
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_TX_START_IRQ:
+            mrf24j40_set_option(dev, MRF24J40_OPT_TELL_TX_START,
+                                ((bool *)val)[0]);
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_TX_END_IRQ:
+            mrf24j40_set_option(dev, MRF24J40_OPT_TELL_TX_END,
+                                ((bool *)val)[0]);
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_CSMA:
+            mrf24j40_set_option(dev, MRF24J40_OPT_CSMA,
+                                ((bool *)val)[0]);
+            res = sizeof(netopt_enable_t);
+            break;
+
+        case NETOPT_CSMA_RETRIES:
+            if ((len > sizeof(uint8_t)) ||
+                (*((uint8_t *)val) > 5)) {
+                res = -EOVERFLOW;
+            }
+            else if (dev->netdev.flags & MRF24J40_OPT_CSMA) {
+                /* only set if CSMA is enabled */
+                mrf24j40_set_csma_max_retries(dev, *((uint8_t *)val));
+                res = sizeof(uint8_t);
+            }
+            break;
+
+        case NETOPT_CCA_THRESHOLD:
+            if (len > sizeof(int8_t)) {
+                res = -EOVERFLOW;
+            }
+            else {
+                mrf24j40_set_cca_threshold(dev, *((int8_t *)val));
+                res = sizeof(int8_t);
+            }
+            break;
+
+        default:
+            break;
+    }
+    /* try netdev2 building flags */
+    if (res == -ENOTSUP) {
+        res = netdev2_ieee802154_set((netdev2_ieee802154_t *)netdev, opt,
+                                     val, len);
+    }
+    return res;
+}
+
+static void _isr(netdev2_t *netdev)
+{
+    mrf24j40_t *dev = (mrf24j40_t *) netdev;
+    /* update pending bits */
+    mrf24j40_update_tasks(dev);
+    DEBUG("[mrf24j40] INTERRUPT (pending: %x),\n", dev->pending);
+    /* Transmit interrupt occured */
+    if (dev->pending & MRF24J40_TASK_TX_READY) {
+        dev->pending &= ~(MRF24J40_TASK_TX_READY);
+        DEBUG("[mrf24j40] EVT - TX_END\n");
+#ifdef MODULE_NETSTATS_L2
+        if (netdev->event_callback && (dev->netdev.flags & MRF24J40_OPT_TELL_TX_END)) {
+            uint8_t txstat = mrf24j40_reg_read_short(dev, MRF24J40_REG_TXSTAT);
+            /* transmision failed */
+            if (txstat & MRF24J40_TXSTAT_TXNSTAT) {
+                /* TX_NOACK - CCAFAIL */
+                if (txstat & MRF24J40_TXSTAT_CCAFAIL) {
+                    netdev->event_callback(netdev, NETDEV2_EVENT_TX_MEDIUM_BUSY);
+                    DEBUG("[mrf24j40] TX_CHANNEL_ACCESS_FAILURE\n");
+                }
+                /* check max retries */
+                else if (txstat & MRF24J40_TXSTAT_MAX_FRAME_RETRIES) {
+                    netdev->event_callback(netdev, NETDEV2_EVENT_TX_NOACK);
+                    DEBUG("[mrf24j40] TX NO_ACK\n");
+                }
+            }
+            else {
+                netdev->event_callback(netdev, NETDEV2_EVENT_TX_COMPLETE);
+            }
+        }
+#endif
+    }
+    /* Receive interrupt occured */
+    if (dev->pending & MRF24J40_TASK_RX_READY) {
+        DEBUG("[mrf24j40] EVT - RX_END\n");
+        if ((dev->netdev.flags & MRF24J40_OPT_TELL_RX_END)) {
+            netdev->event_callback(netdev, NETDEV2_EVENT_RX_COMPLETE);
+        }
+        dev->pending &= ~(MRF24J40_TASK_RX_READY);
+    }
+    DEBUG("[mrf24j40] END IRQ\n");
+}
diff --git a/pkg/lwip/contrib/lwip.c b/pkg/lwip/contrib/lwip.c
index aa45c1eb508911523f1c03c0d576c80b797da1bb..88584c00eb36f2eda9fd031a2754fa2078652fcd 100644
--- a/pkg/lwip/contrib/lwip.c
+++ b/pkg/lwip/contrib/lwip.c
@@ -28,6 +28,11 @@
 #include "at86rf2xx_params.h"
 #endif
 
+#ifdef MODULE_MRF24J40
+#include "mrf24j40.h"
+#include "mrf24j40_params.h"
+#endif
+
 #include "lwip.h"
 
 #define ENABLE_DEBUG    (0)
@@ -41,6 +46,10 @@
 #define LWIP_NETIF_NUMOF        (sizeof(at86rf2xx_params) / sizeof(at86rf2xx_params[0]))
 #endif
 
+#ifdef MODULE_MRF24J40     /* is mutual exclusive with above ifdef */
+#define LWIP_NETIF_NUMOF        (sizeof(mrf24j40_params) / sizeof(mrf24j40_params[0]))
+#endif
+
 #ifdef LWIP_NETIF_NUMOF
 static struct netif netif[LWIP_NETIF_NUMOF];
 #endif
@@ -53,6 +62,10 @@ static netdev2_tap_t netdev2_taps[LWIP_NETIF_NUMOF];
 static at86rf2xx_t at86rf2xx_devs[LWIP_NETIF_NUMOF];
 #endif
 
+#ifdef MODULE_MRF24J40
+static mrf24j40_t mrf24j40_devs[LWIP_NETIF_NUMOF];
+#endif
+
 void lwip_bootstrap(void)
 {
     /* TODO: do for every eligable netdev2 */
@@ -66,6 +79,15 @@ void lwip_bootstrap(void)
             return;
         }
     }
+#elif defined(MODULE_MRF24J40)
+    for (int i = 0; i < LWIP_NETIF_NUMOF; i++) {
+        mrf24j40_setup(&mrf24j40_devs[i], &mrf24j40_params[i]);
+        if (netif_add(&netif[i], &mrf24j40_devs[i], lwip_netdev2_init,
+                      tcpip_6lowpan_input) == NULL) {
+            DEBUG("Could not add mrf24j40 device\n");
+            return;
+        }
+    }
 #elif defined(MODULE_AT86RF2XX)
     for (int i = 0; i < LWIP_NETIF_NUMOF; i++) {
         at86rf2xx_setup(&at86rf2xx_devs[i], &at86rf2xx_params[i]);
diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c
index dccd57f5d5b1ecac2de5f60a59606e6720f92c22..f09d7192edb57ce6fe89378f3fec8a1efccd8199 100644
--- a/sys/auto_init/auto_init.c
+++ b/sys/auto_init/auto_init.c
@@ -182,6 +182,11 @@ void auto_init(void)
     auto_init_at86rf2xx();
 #endif
 
+#ifdef MODULE_MRF24J40
+    extern void auto_init_mrf24j40(void);
+    auto_init_mrf24j40();
+#endif
+
 #ifdef MODULE_CC2420
     extern void auto_init_cc2420(void);
     auto_init_cc2420();
diff --git a/sys/auto_init/netif/auto_init_mrf24j40.c b/sys/auto_init/netif/auto_init_mrf24j40.c
new file mode 100644
index 0000000000000000000000000000000000000000..4b1db6c39a6a996ca6190451fca390cb20155e36
--- /dev/null
+++ b/sys/auto_init/netif/auto_init_mrf24j40.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ *
+ */
+
+/*
+ * @ingroup auto_init_gnrc_netif
+ * @{
+ *
+ * @file
+ * @brief   Auto initialization for mrf24j40 network interfaces
+ *
+ * @author  Neo Nenaco <neo@nenaco.de>
+ */
+
+#ifdef MODULE_MRF24J40
+
+#include "board.h"
+#include "net/gnrc/netdev2.h"
+#include "net/gnrc/netdev2/ieee802154.h"
+#include "net/gnrc.h"
+
+#include "mrf24j40.h"
+#include "mrf24j40_params.h"
+
+#define ENABLE_DEBUG (0)
+#include "debug.h"
+
+/**
+ * @brief   Define stack parameters for the MAC layer thread
+ * @{
+ */
+#define MRF24J40_MAC_STACKSIZE     (THREAD_STACKSIZE_DEFAULT)
+#ifndef MRF24J40_MAC_PRIO
+#define MRF24J40_MAC_PRIO          (GNRC_NETDEV2_MAC_PRIO)
+#endif
+
+#define MRF24J40_NUM (sizeof(mrf24j40_params) / sizeof(mrf24j40_params[0]))
+
+static mrf24j40_t mrf24j40_devs[MRF24J40_NUM];
+static gnrc_netdev2_t gnrc_adpt[MRF24J40_NUM];
+static char _mrf24j40_stacks[MRF24J40_NUM][MRF24J40_MAC_STACKSIZE];
+
+void auto_init_mrf24j40(void)
+{
+    for (unsigned i = 0; i < MRF24J40_NUM; i++) {
+        const mrf24j40_params_t *p = &mrf24j40_params[i];
+        int res;
+
+        DEBUG("Initializing MRF24J40 radio at SPI_%i\n", p->spi);
+        mrf24j40_setup(&mrf24j40_devs[i], (mrf24j40_params_t *) p);
+        res = gnrc_netdev2_ieee802154_init(&gnrc_adpt[i],
+                                           (netdev2_ieee802154_t *)&mrf24j40_devs[i]);
+
+        if (res < 0) {
+            DEBUG("Error initializing MRF24J40 radio device!\n");
+        }
+        else {
+            gnrc_netdev2_init(_mrf24j40_stacks[i],
+                              MRF24J40_MAC_STACKSIZE,
+                              MRF24J40_MAC_PRIO,
+                              "mrf24j40",
+                              &gnrc_adpt[i]);
+        }
+    }
+}
+#else
+typedef int dont_be_pedantic;
+#endif /* MODULE_MRF24J40 */
+
+/** @} */