return ret;
        }
 
+       /* WM CPU info record control */
+       mt76_clear(dev, MT_CPU_UTIL_CTRL, BIT(0));
+       mt76_wr(dev, MT_DIC_CMD_REG_CMD, BIT(2) | BIT(13) | !dev->fw_debug_wm);
+       mt76_wr(dev, MT_MCU_WM_CIRQ_IRQ_MASK_CLR_ADDR, BIT(5));
+       mt76_wr(dev, MT_MCU_WM_CIRQ_IRQ_SOFT_ADDR, BIT(5));
+
        return 0;
 }
 
 mt7915_fw_debug_wa_set(void *data, u64 val)
 {
        struct mt7915_dev *dev = data;
+       int ret;
 
        dev->fw_debug_wa = val ? MCU_FW_LOG_TO_HOST : 0;
 
-       return mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, dev->fw_debug_wa);
+       ret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, dev->fw_debug_wa);
+       if (ret)
+               return ret;
+
+       return mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET), MCU_WA_PARAM_PDMA_RX,
+                                !!dev->fw_debug_wa, 0);
 }
 
 static int
 DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_wa, mt7915_fw_debug_wa_get,
                         mt7915_fw_debug_wa_set, "%lld\n");
 
+static int
+mt7915_fw_util_wm_show(struct seq_file *file, void *data)
+{
+       struct mt7915_dev *dev = file->private;
+
+       if (dev->fw_debug_wm) {
+               seq_printf(file, "Busy: %u%%  Peak busy: %u%%\n",
+                          mt76_rr(dev, MT_CPU_UTIL_BUSY_PCT),
+                          mt76_rr(dev, MT_CPU_UTIL_PEAK_BUSY_PCT));
+               seq_printf(file, "Idle count: %u  Peak idle count: %u\n",
+                          mt76_rr(dev, MT_CPU_UTIL_IDLE_CNT),
+                          mt76_rr(dev, MT_CPU_UTIL_PEAK_IDLE_CNT));
+       }
+
+       return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(mt7915_fw_util_wm);
+
+static int
+mt7915_fw_util_wa_show(struct seq_file *file, void *data)
+{
+       struct mt7915_dev *dev = file->private;
+
+       if (dev->fw_debug_wa)
+               return mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(QUERY),
+                                        MCU_WA_PARAM_CPU_UTIL, 0, 0);
+
+       return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(mt7915_fw_util_wa);
+
 static void
 mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy,
                           struct seq_file *file)
        debugfs_create_file("tx_stats", 0400, dir, phy, &mt7915_tx_stats_fops);
        debugfs_create_file("fw_debug_wm", 0600, dir, dev, &fops_fw_debug_wm);
        debugfs_create_file("fw_debug_wa", 0600, dir, dev, &fops_fw_debug_wa);
+       debugfs_create_file("fw_util_wm", 0400, dir, dev,
+                           &mt7915_fw_util_wm_fops);
+       debugfs_create_file("fw_util_wa", 0400, dir, dev,
+                           &mt7915_fw_util_wa_fops);
        debugfs_create_file("implicit_txbf", 0600, dir, dev,
                            &fops_implicit_txbf);
        debugfs_create_file("txpower_sku", 0400, dir, phy,
 
 #define MT_HIF_REMAP_L2_BASE           GENMASK(31, 12)
 #define MT_HIF_REMAP_BASE_L2           0x00000
 
+#define MT_DIC_CMD_REG_BASE            0x41f000
+#define MT_DIC_CMD_REG(ofs)            (MT_DIC_CMD_REG_BASE + (ofs))
+#define MT_DIC_CMD_REG_CMD             MT_DIC_CMD_REG(0x10)
+
+#define MT_CPU_UTIL_BASE               0x41f030
+#define MT_CPU_UTIL(ofs)               (MT_CPU_UTIL_BASE + (ofs))
+#define MT_CPU_UTIL_BUSY_PCT           MT_CPU_UTIL(0x00)
+#define MT_CPU_UTIL_PEAK_BUSY_PCT      MT_CPU_UTIL(0x04)
+#define MT_CPU_UTIL_IDLE_CNT           MT_CPU_UTIL(0x08)
+#define MT_CPU_UTIL_PEAK_IDLE_CNT      MT_CPU_UTIL(0x0c)
+#define MT_CPU_UTIL_CTRL               MT_CPU_UTIL(0x1c)
+
 #define MT_SWDEF_BASE                  0x41f200
 #define MT_SWDEF(ofs)                  (MT_SWDEF_BASE + (ofs))
 #define MT_SWDEF_MODE                  MT_SWDEF(0x3c)
 #define MT_WF_PHY_RXTD12_IRPI_SW_CLR_ONLY      BIT(18)
 #define MT_WF_PHY_RXTD12_IRPI_SW_CLR   BIT(29)
 
+#define MT_MCU_WM_CIRQ_BASE                    0x89010000
+#define MT_MCU_WM_CIRQ(ofs)                    (MT_MCU_WM_CIRQ_BASE + (ofs))
+#define MT_MCU_WM_CIRQ_IRQ_MASK_CLR_ADDR       MT_MCU_WM_CIRQ(0x80)
+#define MT_MCU_WM_CIRQ_IRQ_SOFT_ADDR           MT_MCU_WM_CIRQ(0xc0)
+
 #endif