diff --git a/cpu/cc2538/include/cc2538_rf.h b/cpu/cc2538/include/cc2538_rf.h
index afa798e4f118ea804ecbf8093613371a3770765b..93170113fa75faed5585d6ece5e6b0f158ff052e 100644
--- a/cpu/cc2538/include/cc2538_rf.h
+++ b/cpu/cc2538/include/cc2538_rf.h
@@ -70,6 +70,13 @@ extern "C" {
 #define OUTPUT_POWER_MAX            (7)    /**< Max output power in dBm */
 #define NUM_POWER_LEVELS            ( OUTPUT_POWER_MAX - OUTPUT_POWER_MIN + 1 )
 
+#define CC2538_CORR_VAL_MIN         (50U)
+#define CC2538_CORR_VAL_MAX         (110U)
+#define CC2538_CORR_VAL_MASK        (0x7F)
+
+#define CC2538_RSSI_OFFSET          (-73)  /**< Signal strength offset value */
+#define CC2538_RF_SENSITIVITY       (-97)  /**< dBm typical, normal conditions */
+
 #define RFCORE_ASSERT(expr) (void)( (expr) || RFCORE_ASSERT_failure(#expr, __FUNCTION__, __LINE__) )
 
 #if DEVELHELP
diff --git a/cpu/cc2538/radio/cc2538_rf_netdev.c b/cpu/cc2538/radio/cc2538_rf_netdev.c
index 008c396891ae197e653345205eb4ad0e64ccbaad..e9721632ef94d14b96207d30bf135cf7dabad5e7 100644
--- a/cpu/cc2538/radio/cc2538_rf_netdev.c
+++ b/cpu/cc2538/radio/cc2538_rf_netdev.c
@@ -293,6 +293,8 @@ 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)
 {
     cc2538_rf_t *dev = (cc2538_rf_t *) netdev;
+    uint8_t corr_val;
+    int8_t rssi_val;
     size_t pkt_len;
 
     mutex_lock(&dev->mutex);
@@ -331,17 +333,29 @@ static int _recv(netdev2_t *netdev, void *buf, size_t len, void *info)
 
     rfcore_read_fifo(buf, pkt_len);
 
-    if (info != NULL) {
+    if (info != NULL && RFCORE->XREG_RSSISTATbits.RSSI_VALID) {
         netdev2_ieee802154_rx_info_t *radio_info = info;
-        radio_info->rssi = rfcore_read_byte();
-
-        /* This is not strictly 802.15.4 compliant, since according to
-           the CC2538 documentation, this value will tend between ~50
-           for the lowest quality link detectable by the receiver, and
-           ~110 for the highest. The IEEE 802.15.4 spec mandates that
-           this value be between 0-255, with 0 as lowest quality and
-           255 as the highest. FIXME. */
-        radio_info->lqi = rfcore_read_byte() & 0x7F;
+        rssi_val = rfcore_read_byte() + CC2538_RSSI_OFFSET;
+
+        RFCORE_ASSERT(rssi_val > CC2538_RF_SENSITIVITY);
+
+        /* The number of dB above maximum sensitivity detected for the
+         * received packet */
+        radio_info->rssi = -CC2538_RF_SENSITIVITY + rssi_val;
+
+        corr_val = rfcore_read_byte() & CC2538_CORR_VAL_MASK;
+
+        if (corr_val < CC2538_CORR_VAL_MIN) {
+            corr_val = CC2538_CORR_VAL_MIN;
+        }
+        else if (corr_val > CC2538_CORR_VAL_MAX) {
+            corr_val = CC2538_CORR_VAL_MAX;
+        }
+
+        /* Interpolate the correlation value between 0 - 255
+         * to provide an LQI value */
+        radio_info->lqi = 255 * (corr_val - CC2538_CORR_VAL_MIN) /
+                          (CC2538_CORR_VAL_MAX - CC2538_CORR_VAL_MIN);
     }
 
     RFCORE_SFR_RFST = ISFLUSHRX;