From: Avinash Bhatt Date: Fri, 20 Mar 2026 08:09:12 +0000 (+0200) Subject: wifi: iwlwifi: add CQM event support for per-link RSSI changes X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=454e9141ae96691ad380f7f3f7d11fe652a03cb5;p=thirdparty%2Flinux.git wifi: iwlwifi: add CQM event support for per-link RSSI changes Implement CQM RSSI threshold handling by tracking the last reported RSSI and issuing CQM low/high events when the RSSI crosses the configured threshold with the required hysteresis. This provides proper CQM support and enables userspace to receive per-link RSSI notifications. Signed-off-by: Avinash Bhatt Reviewed-by: Emmanuel Grumbach Reviewed-by: Johannes Berg Reviewed-by: Pagadala Yesu Anjaneyulu Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260320100746.08697e34bf66.Ic1a68537ef0d37be62c73c138efe9c5cf09bd24c@changeid --- diff --git a/drivers/net/wireless/intel/iwlwifi/mld/link.h b/drivers/net/wireless/intel/iwlwifi/mld/link.h index 9e4da8e4de93d..ca691259fc5e6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/link.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/link.h @@ -40,6 +40,7 @@ struct iwl_probe_resp_data { * @bcast_sta: station used for broadcast packets. Used in AP, GO and IBSS. * @mcast_sta: station used for multicast packets. Used in AP, GO and IBSS. * @mon_sta: station used for TX injection in monitor interface. + * @last_cqm_rssi_event: rssi of the last cqm rssi event * @average_beacon_energy: average beacon energy for beacons received during * client connections * @ap_early_keys: The firmware cannot install keys before bcast/mcast STAs, @@ -66,6 +67,7 @@ struct iwl_mld_link { struct iwl_mld_int_sta bcast_sta; struct iwl_mld_int_sta mcast_sta; struct iwl_mld_int_sta mon_sta; + int last_cqm_rssi_event; /* we can only have 2 GTK + 2 IGTK + 2 BIGTK active at a time */ struct ieee80211_key_conf *ap_early_keys[6]; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/stats.c b/drivers/net/wireless/intel/iwlwifi/mld/stats.c index 7b8709716324a..9b3149b9d2c22 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/stats.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/stats.c @@ -369,15 +369,39 @@ out: static void iwl_mld_update_link_sig(struct ieee80211_vif *vif, int sig, struct ieee80211_bss_conf *bss_conf) { + struct iwl_mld_link *link = iwl_mld_link_from_mac80211(bss_conf); struct iwl_mld *mld = iwl_mld_vif_from_mac80211(vif)->mld; int exit_emlsr_thresh; + int last_event; if (sig == 0) { IWL_DEBUG_RX(mld, "RSSI is 0 - skip signal based decision\n"); return; } - /* TODO: task=statistics handle CQM notifications */ + if (WARN_ON(!link)) + return; + + /* CQM Notification */ + if (vif->driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI) { + int thold = bss_conf->cqm_rssi_thold; + int hyst = bss_conf->cqm_rssi_hyst; + + last_event = link->last_cqm_rssi_event; + if (thold && sig < thold && + (last_event == 0 || sig < last_event - hyst)) { + link->last_cqm_rssi_event = sig; + ieee80211_cqm_rssi_notify(vif, + NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, + sig, GFP_KERNEL); + } else if (sig > thold && + (last_event == 0 || sig > last_event + hyst)) { + link->last_cqm_rssi_event = sig; + ieee80211_cqm_rssi_notify(vif, + NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, + sig, GFP_KERNEL); + } + } if (!iwl_mld_emlsr_active(vif)) { /* We're not in EMLSR and our signal is bad,