{
        struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
        struct ath11k *ar = arsta->arvif->ar;
+       s8 signal;
+       bool db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,
+                              ar->ab->wmi_ab.svc_map);
 
        sinfo->rx_duration = arsta->rx_duration;
        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION);
                ath11k_mac_put_chain_rssi(sinfo, arsta, "fw stats", true);
        }
 
-       /* TODO: Use real NF instead of default one. */
-       sinfo->signal = arsta->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR;
-       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
+       signal = arsta->rssi_comb;
+       if (!signal &&
+           arsta->arvif->vdev_type == WMI_VDEV_TYPE_STA &&
+           ar->ab->hw_params.supports_rssi_stats &&
+           !(ath11k_debugfs_get_fw_stats(ar, ar->pdev->pdev_id, 0,
+                                       WMI_REQUEST_VDEV_STAT)))
+               signal = arsta->rssi_beacon;
+
+       ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
+                  "mac sta statistics db2dbm %u rssi comb %d rssi beacon %d\n",
+                  db2dbm, arsta->rssi_comb, arsta->rssi_beacon);
+
+       if (signal) {
+               sinfo->signal = db2dbm ? signal : signal + ATH11K_DEFAULT_NOISE_FLOOR;
+               sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
+       }
 }
 
 static const struct ieee80211_ops ath11k_ops = {
 
 {
        struct ath11k_fw_stats *stats = parse->stats;
        const struct wmi_stats_event *ev = parse->ev;
-       int i;
+       struct ath11k *ar;
+       struct ath11k_vif *arvif;
+       struct ieee80211_sta *sta;
+       struct ath11k_sta *arsta;
+       int i, ret = 0;
        const void *data = ptr;
 
        if (!ev) {
 
        stats->stats_id = 0;
 
+       rcu_read_lock();
+
+       ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id);
+
        for (i = 0; i < ev->num_pdev_stats; i++) {
                const struct wmi_pdev_stats *src;
                struct ath11k_fw_stats_pdev *dst;
 
                src = data;
-               if (len < sizeof(*src))
-                       return -EPROTO;
+               if (len < sizeof(*src)) {
+                       ret = -EPROTO;
+                       goto exit;
+               }
 
                stats->stats_id = WMI_REQUEST_PDEV_STAT;
 
                struct ath11k_fw_stats_vdev *dst;
 
                src = data;
-               if (len < sizeof(*src))
-                       return -EPROTO;
+               if (len < sizeof(*src)) {
+                       ret = -EPROTO;
+                       goto exit;
+               }
 
                stats->stats_id = WMI_REQUEST_VDEV_STAT;
 
+               arvif = ath11k_mac_get_arvif(ar, src->vdev_id);
+               if (arvif) {
+                       sta = ieee80211_find_sta_by_ifaddr(ar->hw,
+                                                          arvif->bssid,
+                                                          NULL);
+                       if (sta) {
+                               arsta = (struct ath11k_sta *)sta->drv_priv;
+                               arsta->rssi_beacon = src->beacon_snr;
+                               ath11k_dbg(ab, ATH11K_DBG_WMI,
+                                          "wmi stats vdev id %d snr %d\n",
+                                          src->vdev_id, src->beacon_snr);
+                       } else {
+                               ath11k_warn(ab, "not found station for bssid %pM\n",
+                                           arvif->bssid);
+                       }
+               }
+
                data += sizeof(*src);
                len -= sizeof(*src);
 
                struct ath11k_fw_stats_bcn *dst;
 
                src = data;
-               if (len < sizeof(*src))
-                       return -EPROTO;
+               if (len < sizeof(*src)) {
+                       ret = -EPROTO;
+                       goto exit;
+               }
 
                stats->stats_id = WMI_REQUEST_BCN_STAT;
 
                list_add_tail(&dst->list, &stats->bcn);
        }
 
-       return 0;
+exit:
+       rcu_read_unlock();
+       return ret;
 }
 
 static int ath11k_wmi_tlv_fw_stats_parse(struct ath11k_base *ab,