diff --git a/drivers/at86rf2xx/at86rf2xx_getset.c b/drivers/at86rf2xx/at86rf2xx_getset.c
index e93e5f74e966f384fbd53abd260df2512319590a..761f9782520292836c2163d7b8067a1e6c8624e5 100644
--- a/drivers/at86rf2xx/at86rf2xx_getset.c
+++ b/drivers/at86rf2xx/at86rf2xx_getset.c
@@ -418,9 +418,19 @@ void at86rf2xx_set_option(at86rf2xx_t *dev, uint16_t option, bool state)
     }
 }
 
-static inline void _set_state(at86rf2xx_t *dev, uint8_t state)
+/**
+ * @brief Internal function to change state
+ * @details For all cases but AT86RF2XX_STATE_FORCE_TRX_OFF state and
+ *          cmd parameter are the same.
+ *
+ * @param dev       device to operate on
+ * @param state     target state
+ * @param cmd       command to initiate state transition
+ */
+
+static inline void _set_state(at86rf2xx_t *dev, uint8_t state, uint8_t cmd)
 {
-    at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_STATE, state);
+    at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_STATE, cmd);
 
     /* To prevent a possible race condition when changing to
      * RX_AACK_ON state the state doesn't get read back in that
@@ -438,6 +448,15 @@ void at86rf2xx_set_state(at86rf2xx_t *dev, uint8_t state)
 {
     uint8_t old_state = at86rf2xx_get_status(dev);
 
+    if (state == old_state) {
+        return;
+    }
+
+    if (state == AT86RF2XX_STATE_FORCE_TRX_OFF) {
+        _set_state(dev, AT86RF2XX_STATE_TRX_OFF, state);
+        return;
+    }
+
     /* make sure there is no ongoing transmission, or state transition already
      * in progress */
     while (old_state == AT86RF2XX_STATE_BUSY_RX_AACK ||
@@ -455,7 +474,7 @@ void at86rf2xx_set_state(at86rf2xx_t *dev, uint8_t state)
              state == AT86RF2XX_STATE_TX_ARET_ON) ||
         (old_state == AT86RF2XX_STATE_TX_ARET_ON &&
              state == AT86RF2XX_STATE_RX_AACK_ON)) {
-        _set_state(dev, AT86RF2XX_STATE_PLL_ON);
+        _set_state(dev, AT86RF2XX_STATE_PLL_ON, AT86RF2XX_STATE_PLL_ON);
     }
     /* check if we need to wake up from sleep mode */
     else if (old_state == AT86RF2XX_STATE_SLEEP) {
@@ -465,14 +484,14 @@ void at86rf2xx_set_state(at86rf2xx_t *dev, uint8_t state)
 
     if (state == AT86RF2XX_STATE_SLEEP) {
         /* First go to TRX_OFF */
-        at86rf2xx_force_trx_off(dev);
+        at86rf2xx_set_state(dev, AT86RF2XX_STATE_FORCE_TRX_OFF);
         /* Discard all IRQ flags, framebuffer is lost anyway */
         at86rf2xx_reg_read(dev, AT86RF2XX_REG__IRQ_STATUS);
         /* Go to SLEEP mode from TRX_OFF */
         gpio_set(dev->params.sleep_pin);
         dev->state = state;
     } else {
-        _set_state(dev, state);
+        _set_state(dev, state, state);
     }
 }
 
@@ -487,5 +506,5 @@ void at86rf2xx_reset_state_machine(at86rf2xx_t *dev)
         old_state = at86rf2xx_get_status(dev);
     } while (old_state == AT86RF2XX_STATE_IN_PROGRESS);
 
-    at86rf2xx_force_trx_off(dev);
+    at86rf2xx_set_state(dev, AT86RF2XX_STATE_FORCE_TRX_OFF);
 }
diff --git a/drivers/at86rf2xx/at86rf2xx_internal.c b/drivers/at86rf2xx/at86rf2xx_internal.c
index 1ae45270ca330415ea63681f41a7f8a13d80ff3a..2c5a436aa58e6d91cb4a334aa372353219a6ed37 100644
--- a/drivers/at86rf2xx/at86rf2xx_internal.c
+++ b/drivers/at86rf2xx/at86rf2xx_internal.c
@@ -146,19 +146,10 @@ void at86rf2xx_hardware_reset(at86rf2xx_t *dev)
 
 void at86rf2xx_configure_phy(at86rf2xx_t *dev)
 {
-    /* make sure device is not sleeping */
-    at86rf2xx_assert_awake(dev);
-
-    uint8_t state;
-
-    /* make sure ongoing transmissions are finished */
-    do {
-        state = at86rf2xx_get_status(dev);
-    }
-    while ((state == AT86RF2XX_STATE_BUSY_TX_ARET) || (state == AT86RF2XX_STATE_BUSY_RX_AACK));
+    uint8_t state = at86rf2xx_get_status(dev);
 
     /* we must be in TRX_OFF before changing the PHY configuration */
-    at86rf2xx_force_trx_off(dev);
+    at86rf2xx_set_state(dev, AT86RF2XX_STATE_TRX_OFF);
 
 #ifdef MODULE_AT86RF212B
     /* The TX power register must be updated after changing the channel if
diff --git a/drivers/at86rf2xx/at86rf2xx_netdev.c b/drivers/at86rf2xx/at86rf2xx_netdev.c
index dd5cfbc00e17172ab000366c0e90ae1057581801..56c6d9376c7c94a55298ff1c3129a22db20bc807 100644
--- a/drivers/at86rf2xx/at86rf2xx_netdev.c
+++ b/drivers/at86rf2xx/at86rf2xx_netdev.c
@@ -234,24 +234,18 @@ static int _get(netdev2_t *netdev, netopt_t opt, void *val, size_t max_len)
     /* getting these options doesn't require the transceiver to be responsive */
     switch (opt) {
         case NETOPT_CHANNEL_PAGE:
-            if (max_len < sizeof(uint16_t)) {
-                return -EOVERFLOW;
-            }
+            assert(max_len >= sizeof(uint16_t));
             ((uint8_t *)val)[1] = 0;
             ((uint8_t *)val)[0] = at86rf2xx_get_page(dev);
             return sizeof(uint16_t);
 
         case NETOPT_MAX_PACKET_SIZE:
-            if (max_len < sizeof(int16_t)) {
-                return -EOVERFLOW;
-            }
+            assert(max_len >= sizeof(int16_t));
             *((uint16_t *)val) = AT86RF2XX_MAX_PKT_LENGTH - _MAX_MHR_OVERHEAD;
             return sizeof(uint16_t);
 
         case NETOPT_STATE:
-            if (max_len < sizeof(netopt_state_t)) {
-                return -EOVERFLOW;
-            }
+            assert(max_len >= sizeof(netopt_state_t));
             *((netopt_state_t *)val) = _get_state(dev);
             return sizeof(netopt_state_t);
 
@@ -321,43 +315,27 @@ static int _get(netdev2_t *netdev, netopt_t opt, void *val, size_t max_len)
     /* these options require the transceiver to be not sleeping*/
     switch (opt) {
         case NETOPT_TX_POWER:
-            if (max_len < sizeof(int16_t)) {
-                res = -EOVERFLOW;
-            }
-            else {
-                *((uint16_t *)val) = at86rf2xx_get_txpower(dev);
-                res = sizeof(uint16_t);
-            }
+            assert(max_len >= sizeof(int16_t));
+            *((uint16_t *)val) = at86rf2xx_get_txpower(dev);
+            res = sizeof(uint16_t);
             break;
 
         case NETOPT_RETRANS:
-            if (max_len < sizeof(uint8_t)) {
-                res = -EOVERFLOW;
-            }
-            else {
-                *((uint8_t *)val) = at86rf2xx_get_max_retries(dev);
-                res = sizeof(uint8_t);
-            }
+            assert(max_len >= sizeof(uint8_t));
+            *((uint8_t *)val) = at86rf2xx_get_max_retries(dev);
+            res = sizeof(uint8_t);
             break;
 
         case NETOPT_CSMA_RETRIES:
-            if (max_len < sizeof(uint8_t)) {
-                res = -EOVERFLOW;
-            }
-            else {
-                *((uint8_t *)val) = at86rf2xx_get_csma_max_retries(dev);
-                res = sizeof(uint8_t);
-            }
+            assert(max_len >= sizeof(uint8_t));
+            *((uint8_t *)val) = at86rf2xx_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) = at86rf2xx_get_cca_threshold(dev);
-                res = sizeof(int8_t);
-            }
+            assert(max_len >= sizeof(int8_t));
+            *((int8_t *)val) = at86rf2xx_get_cca_threshold(dev);
+            res = sizeof(int8_t);
             break;
 
         default:
@@ -389,94 +367,63 @@ static int _set(netdev2_t *netdev, netopt_t opt, void *val, size_t len)
 
     switch (opt) {
         case NETOPT_ADDRESS:
-            if (len > sizeof(uint16_t)) {
-                res = -EOVERFLOW;
-            }
-            else {
-                at86rf2xx_set_addr_short(dev, *((uint16_t *)val));
-                /* don't set res to set netdev2_ieee802154_t::short_addr */
-            }
+            assert(len <= sizeof(uint16_t));
+            at86rf2xx_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 {
-                at86rf2xx_set_addr_long(dev, *((uint64_t *)val));
-                /* don't set res to set netdev2_ieee802154_t::long_addr */
-            }
+            assert(len <= sizeof(uint64_t));
+            at86rf2xx_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 {
-                at86rf2xx_set_pan(dev, *((uint16_t *)val));
-                /* don't set res to set netdev2_ieee802154_t::pan */
-            }
+            assert(len <= sizeof(uint16_t));
+            at86rf2xx_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)) {
+            assert(len != sizeof(uint8_t));
+            uint8_t chan = ((uint8_t *)val)[0];
+            if (chan < AT86RF2XX_MIN_CHANNEL ||
+                chan > AT86RF2XX_MAX_CHANNEL) {
                 res = -EINVAL;
+                break;
             }
-            else {
-                uint8_t chan = ((uint8_t *)val)[0];
-                if ((chan < AT86RF2XX_MIN_CHANNEL) ||
-                    (chan > AT86RF2XX_MAX_CHANNEL)) {
-                    res = -EINVAL;
-                    break;
-                }
-                at86rf2xx_set_chan(dev, chan);
-                /* don't set res to set netdev2_ieee802154_t::chan */
-            }
+            at86rf2xx_set_chan(dev, chan);
+            /* don't set res to set netdev2_ieee802154_t::chan */
             break;
 
         case NETOPT_CHANNEL_PAGE:
-            if (len != sizeof(uint16_t)) {
+            assert(len != sizeof(uint8_t));
+            uint8_t page = ((uint8_t *)val)[0];
+#ifdef MODULE_AT86RF212B
+            if ((page != 0) && (page != 2)) {
                 res = -EINVAL;
             }
             else {
-                uint8_t page = ((uint8_t *)val)[0];
-#ifdef MODULE_AT86RF212B
-                if ((page != 0) && (page != 2)) {
-                    res = -EINVAL;
-                }
-                else {
-                    at86rf2xx_set_page(dev, page);
-                    res = sizeof(uint16_t);
-                }
+                at86rf2xx_set_page(dev, page);
+                res = sizeof(uint8_t);
+            }
 #else
-                /* rf23x only supports page 0, no need to configure anything in the driver. */
-                if (page != 0) {
-                    res = -EINVAL;
-                }
-                else {
-                    res = sizeof(uint16_t);
-                }
-#endif
+            /* rf23x only supports page 0, no need to configure anything in the driver. */
+            if (page != 0) {
+                res = -EINVAL;
             }
+            else {
+                res = sizeof(uint8_t);
+            }
+#endif
             break;
 
         case NETOPT_TX_POWER:
-            if (len > sizeof(int16_t)) {
-                res = -EOVERFLOW;
-            }
-            else {
-                at86rf2xx_set_txpower(dev, *((int16_t *)val));
-                res = sizeof(uint16_t);
-            }
+            assert(len <= sizeof(int16_t));
+            at86rf2xx_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));
-            }
+            assert(len <= sizeof(netopt_state_t));
+            res = _set_state(dev, *((netopt_state_t *)val));
             break;
 
         case NETOPT_AUTOACK:
@@ -486,13 +433,9 @@ static int _set(netdev2_t *netdev, netopt_t opt, void *val, size_t len)
             break;
 
         case NETOPT_RETRANS:
-            if (len > sizeof(uint8_t)) {
-                res = -EOVERFLOW;
-            }
-            else {
-                at86rf2xx_set_max_retries(dev, *((uint8_t *)val));
-                res = sizeof(uint8_t);
-            }
+            assert(len <= sizeof(uint8_t));
+            at86rf2xx_set_max_retries(dev, *((uint8_t *)val));
+            res = sizeof(uint8_t);
             break;
 
         case NETOPT_PRELOADING:
@@ -538,25 +481,22 @@ static int _set(netdev2_t *netdev, netopt_t opt, void *val, size_t len)
             break;
 
         case NETOPT_CSMA_RETRIES:
-            if ((len > sizeof(uint8_t)) ||
-                (*((uint8_t *)val) > 5)) {
-                res = -EOVERFLOW;
+            assert(len <= sizeof(uint8_t));
+            if( !(dev->netdev.flags & AT86RF2XX_OPT_CSMA ||
+                (*((uint8_t *)val) > 5)) ) {
+                /* If CSMA is disabled, don't allow setting retries */
+                res = -EINVAL;
             }
-            else if (dev->netdev.flags & AT86RF2XX_OPT_CSMA) {
-                /* only set if CSMA is enabled */
+            else {
                 at86rf2xx_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 {
-                at86rf2xx_set_cca_threshold(dev, *((int8_t *)val));
-                res = sizeof(int8_t);
-            }
+            assert(len <= sizeof(int8_t));
+            at86rf2xx_set_cca_threshold(dev, *((int8_t *)val));
+            res = sizeof(int8_t);
             break;
 
         default:
diff --git a/drivers/at86rf2xx/include/at86rf2xx_internal.h b/drivers/at86rf2xx/include/at86rf2xx_internal.h
index ef65570c4911802ca9105415f9db202e8cdbeae8..0979285c07de352f57956ba58134102f7b85d535 100644
--- a/drivers/at86rf2xx/include/at86rf2xx_internal.h
+++ b/drivers/at86rf2xx/include/at86rf2xx_internal.h
@@ -125,13 +125,6 @@ void at86rf2xx_fb_read(const at86rf2xx_t *dev,
  */
 void at86rf2xx_fb_stop(const at86rf2xx_t *dev);
 
-/**
- * @brief   Cancel ongoing transactions and switch to TRX_OFF state
- *
- * @param[in] dev       device to manipulate
- */
-void at86rf2xx_force_trx_off(const at86rf2xx_t *dev);
-
 /**
  * @brief   Convenience function for reading the status of the given device
  *
diff --git a/drivers/include/at86rf2xx.h b/drivers/include/at86rf2xx.h
index 2f2696fd6d66ae8292c33b703af3727156341d10..627e7d636807f765242414a007575a0f741d7f53 100644
--- a/drivers/include/at86rf2xx.h
+++ b/drivers/include/at86rf2xx.h
@@ -95,14 +95,15 @@ extern "C" {
  * @brief   Flags for device internal states (see datasheet)
  * @{
  */
-#define AT86RF2XX_STATE_TRX_OFF      (0x08)     /**< idle */
-#define AT86RF2XX_STATE_PLL_ON       (0x09)     /**< ready to transmit */
-#define AT86RF2XX_STATE_SLEEP        (0x0f)     /**< sleep mode */
-#define AT86RF2XX_STATE_BUSY_RX_AACK (0x11)     /**< busy receiving data */
-#define AT86RF2XX_STATE_BUSY_TX_ARET (0x12)     /**< busy transmitting data */
-#define AT86RF2XX_STATE_RX_AACK_ON   (0x16)     /**< wait for incoming data */
-#define AT86RF2XX_STATE_TX_ARET_ON   (0x19)     /**< ready for sending data */
-#define AT86RF2XX_STATE_IN_PROGRESS  (0x1f)     /**< ongoing state conversion */
+#define AT86RF2XX_STATE_FORCE_TRX_OFF  (0x03)     /**< force transition to idle */
+#define AT86RF2XX_STATE_TRX_OFF        (0x08)     /**< idle */
+#define AT86RF2XX_STATE_PLL_ON         (0x09)     /**< ready to transmit */
+#define AT86RF2XX_STATE_SLEEP          (0x0f)     /**< sleep mode */
+#define AT86RF2XX_STATE_BUSY_RX_AACK   (0x11)     /**< busy receiving data */
+#define AT86RF2XX_STATE_BUSY_TX_ARET   (0x12)     /**< busy transmitting data */
+#define AT86RF2XX_STATE_RX_AACK_ON     (0x16)     /**< wait for incoming data */
+#define AT86RF2XX_STATE_TX_ARET_ON     (0x19)     /**< ready for sending data */
+#define AT86RF2XX_STATE_IN_PROGRESS    (0x1f)     /**< ongoing state conversion */
 /** @} */
 
 /**