void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
        void (*rxd_refill)(void *rxd, dma_addr_t addr, int len);
        int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status,
-                          __le16 *qos);
+                          __le16 *qos, s8 *noise);
 };
 
 struct mwl8k_device_info {
 
        /* Tasklet to perform RX.  */
        struct tasklet_struct poll_rx_task;
+
+       /* Most recently reported noise in dBm */
+       s8 noise;
 };
 
 /* Per interface specific private data */
 
 static int
 mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
-                         __le16 *qos)
+                         __le16 *qos, s8 *noise)
 {
        struct mwl8k_rxd_8366_ap *rxd = _rxd;
 
        memset(status, 0, sizeof(*status));
 
        status->signal = -rxd->rssi;
+       *noise = -rxd->noise_floor;
 
        if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) {
                status->flag |= RX_FLAG_HT;
 
 static int
 mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
-                      __le16 *qos)
+                      __le16 *qos, s8 *noise)
 {
        struct mwl8k_rxd_sta *rxd = _rxd;
        u16 rate_info;
        memset(status, 0, sizeof(*status));
 
        status->signal = -rxd->rssi;
+       *noise = -rxd->noise_level;
        status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info);
        status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info);
 
 
                rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size);
 
-               pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos);
+               pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos,
+                                                       &priv->noise);
                if (pkt_len < 0)
                        break;
 
        return mwl8k_cmd_get_stat(hw, stats);
 }
 
+static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx,
+                               struct survey_info *survey)
+{
+       struct mwl8k_priv *priv = hw->priv;
+       struct ieee80211_conf *conf = &hw->conf;
+
+       if (idx != 0)
+               return -ENOENT;
+
+       survey->channel = conf->channel;
+       survey->filled = SURVEY_INFO_NOISE_DBM;
+       survey->noise = priv->noise;
+
+       return 0;
+}
+
 static int
 mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                   enum ieee80211_ampdu_mlme_action action,
        .sta_remove             = mwl8k_sta_remove,
        .conf_tx                = mwl8k_conf_tx,
        .get_stats              = mwl8k_get_stats,
+       .get_survey             = mwl8k_get_survey,
        .ampdu_action           = mwl8k_ampdu_action,
 };