spin_unlock_bh(&dbr_data->lock);
 }
 
-static void ath11k_fw_stats_pdevs_free(struct list_head *head)
-{
-       struct ath11k_fw_stats_pdev *i, *tmp;
-
-       list_for_each_entry_safe(i, tmp, head, list) {
-               list_del(&i->list);
-               kfree(i);
-       }
-}
-
-static void ath11k_fw_stats_vdevs_free(struct list_head *head)
-{
-       struct ath11k_fw_stats_vdev *i, *tmp;
-
-       list_for_each_entry_safe(i, tmp, head, list) {
-               list_del(&i->list);
-               kfree(i);
-       }
-}
-
-static void ath11k_fw_stats_bcn_free(struct list_head *head)
-{
-       struct ath11k_fw_stats_bcn *i, *tmp;
-
-       list_for_each_entry_safe(i, tmp, head, list) {
-               list_del(&i->list);
-               kfree(i);
-       }
-}
-
 static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar)
 {
        spin_lock_bh(&ar->data_lock);
-       ar->debug.fw_stats_done = false;
-       ath11k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
-       ath11k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
+       ar->fw_stats_done = false;
+       ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
+       ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
        spin_unlock_bh(&ar->data_lock);
 }
 
-void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb)
+void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats)
 {
-       struct ath11k_fw_stats stats = {};
-       struct ath11k *ar;
+       struct ath11k_base *ab = ar->ab;
        struct ath11k_pdev *pdev;
        bool is_end;
        static unsigned int num_vdev, num_bcn;
        size_t total_vdevs_started = 0;
-       int i, ret;
-
-       INIT_LIST_HEAD(&stats.pdevs);
-       INIT_LIST_HEAD(&stats.vdevs);
-       INIT_LIST_HEAD(&stats.bcn);
-
-       ret = ath11k_wmi_pull_fw_stats(ab, skb, &stats);
-       if (ret) {
-               ath11k_warn(ab, "failed to pull fw stats: %d\n", ret);
-               goto free;
-       }
-
-       rcu_read_lock();
-       ar = ath11k_mac_get_ar_by_pdev_id(ab, stats.pdev_id);
-       if (!ar) {
-               rcu_read_unlock();
-               ath11k_warn(ab, "failed to get ar for pdev_id %d: %d\n",
-                           stats.pdev_id, ret);
-               goto free;
-       }
+       int i;
 
-       spin_lock_bh(&ar->data_lock);
+       /* WMI_REQUEST_PDEV_STAT request has been already processed */
 
-       if (stats.stats_id == WMI_REQUEST_PDEV_STAT) {
-               list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs);
-               ar->debug.fw_stats_done = true;
-               goto complete;
-       }
-
-       if (stats.stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
-               ar->debug.fw_stats_done = true;
-               goto complete;
+       if (stats->stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
+               ar->fw_stats_done = true;
+               return;
        }
 
-       if (stats.stats_id == WMI_REQUEST_VDEV_STAT) {
-               if (list_empty(&stats.vdevs)) {
+       if (stats->stats_id == WMI_REQUEST_VDEV_STAT) {
+               if (list_empty(&stats->vdevs)) {
                        ath11k_warn(ab, "empty vdev stats");
-                       goto complete;
+                       return;
                }
                /* FW sends all the active VDEV stats irrespective of PDEV,
                 * hence limit until the count of all VDEVs started
 
                is_end = ((++num_vdev) == total_vdevs_started);
 
-               list_splice_tail_init(&stats.vdevs,
-                                     &ar->debug.fw_stats.vdevs);
+               list_splice_tail_init(&stats->vdevs,
+                                     &ar->fw_stats.vdevs);
 
                if (is_end) {
-                       ar->debug.fw_stats_done = true;
+                       ar->fw_stats_done = true;
                        num_vdev = 0;
                }
-               goto complete;
+               return;
        }
 
-       if (stats.stats_id == WMI_REQUEST_BCN_STAT) {
-               if (list_empty(&stats.bcn)) {
+       if (stats->stats_id == WMI_REQUEST_BCN_STAT) {
+               if (list_empty(&stats->bcn)) {
                        ath11k_warn(ab, "empty bcn stats");
-                       goto complete;
+                       return;
                }
                /* Mark end until we reached the count of all started VDEVs
                 * within the PDEV
                 */
                is_end = ((++num_bcn) == ar->num_started_vdevs);
 
-               list_splice_tail_init(&stats.bcn,
-                                     &ar->debug.fw_stats.bcn);
+               list_splice_tail_init(&stats->bcn,
+                                     &ar->fw_stats.bcn);
 
                if (is_end) {
-                       ar->debug.fw_stats_done = true;
+                       ar->fw_stats_done = true;
                        num_bcn = 0;
                }
        }
-complete:
-       complete(&ar->debug.fw_stats_complete);
-       rcu_read_unlock();
-       spin_unlock_bh(&ar->data_lock);
-
-free:
-       ath11k_fw_stats_pdevs_free(&stats.pdevs);
-       ath11k_fw_stats_vdevs_free(&stats.vdevs);
-       ath11k_fw_stats_bcn_free(&stats.bcn);
 }
 
 static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
 
        ath11k_debugfs_fw_stats_reset(ar);
 
-       reinit_completion(&ar->debug.fw_stats_complete);
+       reinit_completion(&ar->fw_stats_complete);
 
        ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
 
                return ret;
        }
 
-       time_left =
-       wait_for_completion_timeout(&ar->debug.fw_stats_complete,
-                                   1 * HZ);
+       time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
+
        if (!time_left)
                return -ETIMEDOUT;
 
                        break;
 
                spin_lock_bh(&ar->data_lock);
-               if (ar->debug.fw_stats_done) {
+               if (ar->fw_stats_done) {
                        spin_unlock_bh(&ar->data_lock);
                        break;
                }
                goto err_free;
        }
 
-       ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
-                                buf);
+       ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
 
        file->private_data = buf;
 
                goto err_free;
        }
 
-       ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
-                                buf);
+       ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
 
        file->private_data = buf;
 
                }
        }
 
-       ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
-                                buf);
+       ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
 
        /* since beacon stats request is looped for all active VDEVs, saved fw
         * stats is not freed for each request until done for all active VDEVs
         */
        spin_lock_bh(&ar->data_lock);
-       ath11k_fw_stats_bcn_free(&ar->debug.fw_stats.bcn);
+       ath11k_fw_stats_bcn_free(&ar->fw_stats.bcn);
        spin_unlock_bh(&ar->data_lock);
 
        file->private_data = buf;
        struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
                                                        ar->debug.debugfs_pdev);
 
-       ar->debug.fw_stats.debugfs_fwstats = fwstats_dir;
+       ar->fw_stats.debugfs_fwstats = fwstats_dir;
 
        /* all stats debugfs files created are under "fw_stats" directory
         * created per PDEV
                            &fops_vdev_stats);
        debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
                            &fops_bcn_stats);
-
-       INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
-       INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
-       INIT_LIST_HEAD(&ar->debug.fw_stats.bcn);
-
-       init_completion(&ar->debug.fw_stats_complete);
 }
 
 static ssize_t ath11k_write_pktlog_filter(struct file *file,
 
 
 static void ath11k_update_stats_event(struct ath11k_base *ab, struct sk_buff *skb)
 {
-       ath11k_debugfs_fw_stats_process(ab, skb);
+       struct ath11k_fw_stats stats = {};
+       struct ath11k *ar;
+       int ret;
+
+       INIT_LIST_HEAD(&stats.pdevs);
+       INIT_LIST_HEAD(&stats.vdevs);
+       INIT_LIST_HEAD(&stats.bcn);
+
+       ret = ath11k_wmi_pull_fw_stats(ab, skb, &stats);
+       if (ret) {
+               ath11k_warn(ab, "failed to pull fw stats: %d\n", ret);
+               goto free;
+       }
+
+       rcu_read_lock();
+       ar = ath11k_mac_get_ar_by_pdev_id(ab, stats.pdev_id);
+       if (!ar) {
+               rcu_read_unlock();
+               ath11k_warn(ab, "failed to get ar for pdev_id %d: %d\n",
+                           stats.pdev_id, ret);
+               goto free;
+       }
+
+       spin_lock_bh(&ar->data_lock);
+
+       /* WMI_REQUEST_PDEV_STAT can be requested via .get_txpower mac ops or via
+        * debugfs fw stats. Therefore, processing it separately.
+        */
+       if (stats.stats_id == WMI_REQUEST_PDEV_STAT) {
+               list_splice_tail_init(&stats.pdevs, &ar->fw_stats.pdevs);
+               ar->fw_stats_done = true;
+               goto complete;
+       }
+
+       /* WMI_REQUEST_VDEV_STAT, WMI_REQUEST_BCN_STAT and WMI_REQUEST_RSSI_PER_CHAIN_STAT
+        * are currently requested only via debugfs fw stats. Hence, processing these
+        * in debugfs context
+        */
+       ath11k_debugfs_fw_stats_process(ar, &stats);
+
+complete:
+       complete(&ar->fw_stats_complete);
+       rcu_read_unlock();
+       spin_unlock_bh(&ar->data_lock);
+
+free:
+       ath11k_fw_stats_free(&stats);
 }
 
 /* PDEV_CTL_FAILSAFE_CHECK_EVENT is received from FW when the frequency scanned