* @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,
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];
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,