MCU_EVENT_CH_PRIVILEGE = 0x18,
        MCU_EVENT_SCHED_SCAN_DONE = 0x23,
        MCU_EVENT_DBG_MSG = 0x27,
+       MCU_EVENT_RSSI_NOTIFY = 0x96,
        MCU_EVENT_TXPWR = 0xd0,
        MCU_EVENT_EXT = 0xed,
        MCU_EVENT_RESTART_DL = 0xef,
        MCU_CE_CMD_SCHED_SCAN_ENABLE = 0x61,
        MCU_CE_CMD_SCHED_SCAN_REQ = 0x62,
        MCU_CE_CMD_GET_NIC_CAPAB = 0x8a,
+       MCU_CE_CMD_RSSI_MONITOR = 0xa1,
        MCU_CE_CMD_SET_MU_EDCA_PARMS = 0xb0,
        MCU_CE_CMD_REG_WRITE = 0xc0,
        MCU_CE_CMD_REG_READ = 0xc0,
        u8 pad[2];
 } __packed;
 
+struct mt76_connac_rssi_notify_event {
+       __le32 rssi[4];
+} __packed;
+
 struct mt76_connac_mcu_bss_event {
        u8 bss_idx;
        u8 is_absent;
 
        }
 
        vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+       if (phy->chip_cap & MT792x_CHIP_CAP_RSSI_NOTIFY_EVT_EN)
+               vif->driver_flags |= IEEE80211_VIF_SUPPORTS_CQM_RSSI;
 out:
        mt792x_mutex_release(dev);
 
        if (changed & BSS_CHANGED_PS)
                mt7921_mcu_uni_bss_ps(dev, vif);
 
+       if (changed & BSS_CHANGED_CQM)
+               mt7921_mcu_set_rssimonitor(dev, vif);
+
        if (changed & BSS_CHANGED_ASSOC) {
                mt7921_mcu_sta_update(dev, NULL, vif, true,
                                      MT76_STA_INFO_STATE_ASSOC);
 
        mt7921_mac_add_txs(dev, event->txs);
 }
 
+static void
+mt7921_mcu_rssi_monitor_iter(void *priv, u8 *mac,
+                            struct ieee80211_vif *vif)
+{
+       struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
+       struct mt76_connac_rssi_notify_event *event = priv;
+       enum nl80211_cqm_rssi_threshold_event nl_event;
+       s32 rssi = le32_to_cpu(event->rssi[mvif->mt76.idx]);
+
+       if (!rssi)
+               return;
+
+       if (!(vif->driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI))
+               return;
+
+       if (rssi > vif->bss_conf.cqm_rssi_thold)
+               nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
+       else
+               nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
+
+       ieee80211_cqm_rssi_notify(vif, nl_event, rssi, GFP_KERNEL);
+}
+
+static void
+mt7921_mcu_rssi_monitor_event(struct mt792x_dev *dev, struct sk_buff *skb)
+{
+       struct mt76_connac_rssi_notify_event *event;
+
+       skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
+       event = (struct mt76_connac_rssi_notify_event *)skb->data;
+
+       ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
+                                                  IEEE80211_IFACE_ITER_RESUME_ALL,
+                                                  mt7921_mcu_rssi_monitor_iter, event);
+}
+
 static void
 mt7921_mcu_rx_unsolicited_event(struct mt792x_dev *dev, struct sk_buff *skb)
 {
        case MCU_EVENT_TX_DONE:
                mt7921_mcu_tx_done_event(dev, skb);
                break;
+       case MCU_EVENT_RSSI_NOTIFY:
+               mt7921_mcu_rssi_monitor_event(dev, skb);
+               break;
        default:
                break;
        }
        if (rxd->ext_eid == MCU_EXT_EVENT_RATE_REPORT ||
            rxd->eid == MCU_EVENT_BSS_BEACON_LOSS ||
            rxd->eid == MCU_EVENT_SCHED_SCAN_DONE ||
+           rxd->eid == MCU_EVENT_RSSI_NOTIFY ||
            rxd->eid == MCU_EVENT_SCAN_DONE ||
            rxd->eid == MCU_EVENT_TX_DONE ||
            rxd->eid == MCU_EVENT_DBG_MSG ||
        return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_RX_FILTER),
                                 &data, sizeof(data), false);
 }
+
+int mt7921_mcu_set_rssimonitor(struct mt792x_dev *dev, struct ieee80211_vif *vif)
+{
+       struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
+       struct {
+               u8 enable;
+               s8 cqm_rssi_high;
+               s8 cqm_rssi_low;
+               u8 bss_idx;
+               u16 duration;
+               u8 rsv2[2];
+       } __packed data = {
+               .enable = vif->cfg.assoc,
+               .cqm_rssi_high = vif->bss_conf.cqm_rssi_thold + vif->bss_conf.cqm_rssi_hyst,
+               .cqm_rssi_low = vif->bss_conf.cqm_rssi_thold - vif->bss_conf.cqm_rssi_hyst,
+               .bss_idx = mvif->mt76.idx,
+       };
+
+       return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(RSSI_MONITOR),
+                                &data, sizeof(data), false);
+}