Lines Matching +full:data +full:- +full:active

1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2022 - 2024 Intel Corporation
6 #include "time-event.h"
58 cmd->action = cpu_to_le32(action); in iwl_mvm_link_cmd_send()
73 mvmvif->link[link_conf->link_id]; in iwl_mvm_set_link_fw_id()
75 if (link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID) in iwl_mvm_set_link_fw_id()
76 link_info->fw_link_id = mvmvif->id; in iwl_mvm_set_link_fw_id()
83 unsigned int link_id = link_conf->link_id; in iwl_mvm_add_link()
84 struct iwl_mvm_vif_link_info *link_info = mvmvif->link[link_id]; in iwl_mvm_add_link()
87 u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 1); in iwl_mvm_add_link()
90 return -EINVAL; in iwl_mvm_add_link()
94 /* Update SF - Disable if needed. if this fails, SF might still be on in iwl_mvm_add_link()
95 * while many macs are bound, which is forbidden - so fail the binding. in iwl_mvm_add_link()
98 return -EINVAL; in iwl_mvm_add_link()
100 cmd.link_id = cpu_to_le32(link_info->fw_link_id); in iwl_mvm_add_link()
101 cmd.mac_id = cpu_to_le32(mvmvif->id); in iwl_mvm_add_link()
102 cmd.spec_link_id = link_conf->link_id; in iwl_mvm_add_link()
103 WARN_ON_ONCE(link_info->phy_ctxt); in iwl_mvm_add_link()
106 memcpy(cmd.local_link_addr, link_conf->addr, ETH_ALEN); in iwl_mvm_add_link()
108 if (vif->type == NL80211_IFTYPE_ADHOC && link_conf->bssid) in iwl_mvm_add_link()
109 memcpy(cmd.ibss_bssid_addr, link_conf->bssid, ETH_ALEN); in iwl_mvm_add_link()
112 cmd.listen_lmac = cpu_to_le32(link_info->listen_lmac); in iwl_mvm_add_link()
126 struct iwl_mvm_esr_iter_data *data = _data; in iwl_mvm_esr_vif_iterator() local
135 mvmvif->link[link_id]; in iwl_mvm_esr_vif_iterator()
136 if (vif == data->vif && link_id == data->link_id) in iwl_mvm_esr_vif_iterator()
138 if (link_info->active) in iwl_mvm_esr_vif_iterator()
139 data->lift_block = false; in iwl_mvm_esr_vif_iterator()
144 unsigned int link_id, bool active) in iwl_mvm_esr_non_bss_link() argument
146 /* An active link of a non-station vif blocks EMLSR. Upon activation in iwl_mvm_esr_non_bss_link()
148 * was the last non-station link active, and if so unblock the bss vif in iwl_mvm_esr_non_bss_link()
151 struct iwl_mvm_esr_iter_data data = { in iwl_mvm_esr_non_bss_link() local
160 if (active) in iwl_mvm_esr_non_bss_link()
164 ieee80211_iterate_active_interfaces(mvm->hw, in iwl_mvm_esr_non_bss_link()
166 iwl_mvm_esr_vif_iterator, &data); in iwl_mvm_esr_non_bss_link()
167 if (data.lift_block) { in iwl_mvm_esr_non_bss_link()
168 mutex_lock(&mvm->mutex); in iwl_mvm_esr_non_bss_link()
170 mutex_unlock(&mvm->mutex); in iwl_mvm_esr_non_bss_link()
178 u32 changes, bool active) in iwl_mvm_link_changed() argument
181 unsigned int link_id = link_conf->link_id; in iwl_mvm_link_changed()
182 struct iwl_mvm_vif_link_info *link_info = mvmvif->link[link_id]; in iwl_mvm_link_changed()
188 u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 1); in iwl_mvm_link_changed()
191 link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID)) in iwl_mvm_link_changed()
192 return -EINVAL; in iwl_mvm_link_changed()
197 * the link was active before. So, do nothing in this case. in iwl_mvm_link_changed()
201 if (!link_info->phy_ctxt) in iwl_mvm_link_changed()
207 WARN_ON_ONCE(active == link_info->active); in iwl_mvm_link_changed()
212 if (!active && vif->type == NL80211_IFTYPE_STATION) { in iwl_mvm_link_changed()
214 if (link_info->csa_block_tx) { in iwl_mvm_link_changed()
216 link_info->csa_block_tx = false; in iwl_mvm_link_changed()
221 cmd.link_id = cpu_to_le32(link_info->fw_link_id); in iwl_mvm_link_changed()
224 * the link becomes active, otherwise they will be ignored. in iwl_mvm_link_changed()
226 phyctxt = link_info->phy_ctxt; in iwl_mvm_link_changed()
228 cmd.phy_id = cpu_to_le32(phyctxt->id); in iwl_mvm_link_changed()
231 cmd.mac_id = cpu_to_le32(mvmvif->id); in iwl_mvm_link_changed()
233 memcpy(cmd.local_link_addr, link_conf->addr, ETH_ALEN); in iwl_mvm_link_changed()
235 cmd.active = cpu_to_le32(active); in iwl_mvm_link_changed()
237 if (vif->type == NL80211_IFTYPE_ADHOC && link_conf->bssid) in iwl_mvm_link_changed()
238 memcpy(cmd.ibss_bssid_addr, link_conf->bssid, ETH_ALEN); in iwl_mvm_link_changed()
243 cmd.cck_short_preamble = cpu_to_le32(link_conf->use_short_preamble); in iwl_mvm_link_changed()
244 cmd.short_slot = cpu_to_le32(link_conf->use_short_slot); in iwl_mvm_link_changed()
256 cmd.bi = cpu_to_le32(link_conf->beacon_int); in iwl_mvm_link_changed()
257 cmd.dtim_interval = cpu_to_le32(link_conf->beacon_int * in iwl_mvm_link_changed()
258 link_conf->dtim_period); in iwl_mvm_link_changed()
260 if (!link_conf->he_support || iwlwifi_mod_params.disable_11ax || in iwl_mvm_link_changed()
261 (vif->type == NL80211_IFTYPE_STATION && !vif->cfg.assoc)) { in iwl_mvm_link_changed()
266 cmd.htc_trig_based_pkt_ext = link_conf->htc_trig_based_pkt_ext; in iwl_mvm_link_changed()
268 if (link_conf->uora_exists) { in iwl_mvm_link_changed()
270 link_conf->uora_ocw_range & 0x7; in iwl_mvm_link_changed()
272 (link_conf->uora_ocw_range >> 3) & 0x7; in iwl_mvm_link_changed()
276 if (changes & LINK_CONTEXT_MODIFY_HE_PARAMS && mvmvif->ap_sta) { in iwl_mvm_link_changed()
278 link_sta_dereference_check(mvmvif->ap_sta, link_id); in iwl_mvm_link_changed()
280 if (!WARN_ON(!link_sta) && link_sta->he_cap.has_he && in iwl_mvm_link_changed()
281 link_sta->he_cap.he_cap_elem.mac_cap_info[5] & in iwl_mvm_link_changed()
288 if (iwl_mvm_set_fw_mu_edca_params(mvm, mvmvif->link[link_id], in iwl_mvm_link_changed()
299 ctx = rcu_dereference(link_conf->chanctx_conf); in iwl_mvm_link_changed()
304 !link_conf->eht_support || !def || in iwl_mvm_link_changed()
305 iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1) >= 6) in iwl_mvm_link_changed()
308 cmd.puncture_mask = cpu_to_le16(def->punctured); in iwl_mvm_link_changed()
312 cmd.bss_color = link_conf->he_bss_color.color; in iwl_mvm_link_changed()
314 if (!link_conf->he_bss_color.enabled) { in iwl_mvm_link_changed()
319 cmd.frame_time_rts_th = cpu_to_le16(link_conf->frame_time_rts_th); in iwl_mvm_link_changed()
321 /* Block 26-tone RU OFDMA transmissions */ in iwl_mvm_link_changed()
322 if (link_info->he_ru_2mhz_block) { in iwl_mvm_link_changed()
327 if (link_conf->nontransmitted) { in iwl_mvm_link_changed()
329 link_conf->transmitter_bssid); in iwl_mvm_link_changed()
330 cmd.bssid_index = link_conf->bssid_index; in iwl_mvm_link_changed()
338 cmd.spec_link_id = link_conf->link_id; in iwl_mvm_link_changed()
340 cmd.listen_lmac = cpu_to_le32(link_info->listen_lmac); in iwl_mvm_link_changed()
344 link_info->active = active; in iwl_mvm_link_changed()
353 unsigned int link_id = link_conf->link_id; in iwl_mvm_remove_link()
354 struct iwl_mvm_vif_link_info *link_info = mvmvif->link[link_id]; in iwl_mvm_remove_link()
358 cmd.link_id = cpu_to_le32(link_info->fw_link_id); in iwl_mvm_remove_link()
359 link_info->fw_link_id = IWL_MVM_FW_LINK_ID_INVALID; in iwl_mvm_remove_link()
360 cmd.spec_link_id = link_conf->link_id; in iwl_mvm_remove_link()
404 * The grades are actually estimated throughput, represented as fixed-point
408 RSSI_TO_GRADE_LINE(-85, -89, 177),
409 RSSI_TO_GRADE_LINE(-83, -86, 344),
410 RSSI_TO_GRADE_LINE(-82, -85, 516),
411 RSSI_TO_GRADE_LINE(-80, -83, 688),
412 RSSI_TO_GRADE_LINE(-77, -79, 1032),
413 RSSI_TO_GRADE_LINE(-73, -76, 1376),
414 RSSI_TO_GRADE_LINE(-70, -74, 1548),
415 RSSI_TO_GRADE_LINE(-69, -72, 1750),
416 RSSI_TO_GRADE_LINE(-65, -68, 2064),
417 RSSI_TO_GRADE_LINE(-61, -66, 2294),
418 RSSI_TO_GRADE_LINE(-58, -61, 2580),
419 RSSI_TO_GRADE_LINE(-55, -58, 2868),
420 RSSI_TO_GRADE_LINE(-46, -55, 3098),
421 RSSI_TO_GRADE_LINE(-43, -54, 3442)
424 #define MAX_GRADE (rssi_to_grade_map[ARRAY_SIZE(rssi_to_grade_map) - 1].grade)
430 /* Factors calculation is done with fixed-point with a scaling factor of 1/256 */
440 link_conf->chanreq.oper.width; in iwl_mvm_get_puncturing_factor()
455 n_punctured = hweight16(link_conf->chanreq.oper.punctured); in iwl_mvm_get_puncturing_factor()
458 return SCALE_FACTOR - puncturing_penalty; in iwl_mvm_get_puncturing_factor()
464 struct ieee80211_vif *vif = link_conf->vif; in iwl_mvm_get_chan_load()
466 iwl_mvm_vif_from_mac80211(link_conf->vif)->link[link_conf->link_id]; in iwl_mvm_get_chan_load()
469 enum nl80211_band band = link_conf->chanreq.oper.chan->band; in iwl_mvm_get_chan_load()
475 if (ieee80211_vif_link_active(vif, link_conf->link_id)) in iwl_mvm_get_chan_load()
476 ies = rcu_dereference(link_conf->bss->beacon_ies); in iwl_mvm_get_chan_load()
478 ies = rcu_dereference(link_conf->bss->ies); in iwl_mvm_get_chan_load()
482 ies->data, ies->len); in iwl_mvm_get_chan_load()
488 bss_load_elem->datalen != sizeof(*bss_load)) { in iwl_mvm_get_chan_load()
508 bss_load = (const void *)bss_load_elem->data; in iwl_mvm_get_chan_load()
509 /* Channel util is in range 0-255 */ in iwl_mvm_get_chan_load()
510 chan_load = bss_load->channel_util; in iwl_mvm_get_chan_load()
513 if (!mvm_link || !mvm_link->active) in iwl_mvm_get_chan_load()
516 if (WARN_ONCE(!mvm_link->phy_ctxt, in iwl_mvm_get_chan_load()
517 "Active link (%u) without phy ctxt assigned!\n", in iwl_mvm_get_chan_load()
518 link_conf->link_id)) in iwl_mvm_get_chan_load()
523 NORMALIZE_PERCENT_TO_255(mvm_link->phy_ctxt->channel_load_by_us); in iwl_mvm_get_chan_load()
527 chan_load -= chan_load_by_us; in iwl_mvm_get_chan_load()
535 return SCALE_FACTOR - iwl_mvm_get_chan_load(link_conf); in iwl_mvm_get_chan_load_factor()
550 band = link_conf->chanreq.oper.chan->band; in iwl_mvm_get_link_grade()
557 link_rssi = MBM_TO_DBM(link_conf->bss->signal); in iwl_mvm_get_link_grade()
560 * the RSSI of the data. in iwl_mvm_get_link_grade()
567 /* No valid RSSI - take the lowest grade */ in iwl_mvm_get_link_grade()
576 if (link_rssi > line->rssi[rssi_idx]) in iwl_mvm_get_link_grade()
578 grade = line->grade; in iwl_mvm_get_link_grade()
591 struct iwl_mvm_link_sel_data *data, in iwl_mvm_set_link_selection_data() argument
607 data[n_data].link_id = link_id; in iwl_mvm_set_link_selection_data()
608 data[n_data].chandef = &link_conf->chanreq.oper; in iwl_mvm_set_link_selection_data()
609 data[n_data].signal = link_conf->bss->signal / 100; in iwl_mvm_set_link_selection_data()
610 data[n_data].grade = iwl_mvm_get_link_grade(link_conf); in iwl_mvm_set_link_selection_data()
612 if (data[n_data].grade > max_grade) { in iwl_mvm_set_link_selection_data()
613 max_grade = data[n_data].grade; in iwl_mvm_set_link_selection_data()
647 if (WARN_ON(chandef->chan->band != NL80211_BAND_2GHZ && in iwl_mvm_get_esr_rssi_thresh()
648 chandef->chan->band != NL80211_BAND_5GHZ && in iwl_mvm_get_esr_rssi_thresh()
649 chandef->chan->band != NL80211_BAND_6GHZ)) in iwl_mvm_get_esr_rssi_thresh()
658 return low ? threshs->low : threshs->high; in iwl_mvm_get_esr_rssi_thresh()
667 struct wiphy *wiphy = mvm->hw->wiphy; in iwl_mvm_esr_disallowed_with_link()
672 conf = wiphy_dereference(wiphy, vif->link_conf[link->link_id]); in iwl_mvm_esr_disallowed_with_link()
677 if (link->chandef->chan->band == NL80211_BAND_2GHZ && in iwl_mvm_esr_disallowed_with_link()
678 (!iwl_mvm_bt_coex_calculate_esr_mode(mvm, vif, link->signal, in iwl_mvm_esr_disallowed_with_link()
682 thresh = iwl_mvm_get_esr_rssi_thresh(mvm, link->chandef, in iwl_mvm_esr_disallowed_with_link()
685 if (link->signal < thresh) in iwl_mvm_esr_disallowed_with_link()
688 if (conf->csa_active) in iwl_mvm_esr_disallowed_with_link()
694 link->link_id); in iwl_mvm_esr_disallowed_with_link()
706 struct iwl_mvm *mvm = mvmvif->mvm; in iwl_mvm_mld_valid_link_pair()
709 /* Per-link considerations */ in iwl_mvm_mld_valid_link_pair()
714 if (a->chandef->chan->band == b->chandef->chan->band || in iwl_mvm_mld_valid_link_pair()
715 a->chandef->width != b->chandef->width) in iwl_mvm_mld_valid_link_pair()
721 a->link_id, b->link_id); in iwl_mvm_mld_valid_link_pair()
742 struct wiphy *wiphy = ieee80211_vif_to_wdev(vif)->wiphy; in iwl_mvm_get_esr_grade()
748 if (b->grade > a->grade) in iwl_mvm_get_esr_grade()
751 *primary_id = a->link_id; in iwl_mvm_get_esr_grade()
756 primary_conf = wiphy_dereference(wiphy, vif->link_conf[*primary_id]); in iwl_mvm_get_esr_grade()
763 return a->grade + in iwl_mvm_get_esr_grade()
764 ((b->grade * primary_load) / SCALE_FACTOR); in iwl_mvm_get_esr_grade()
769 struct iwl_mvm_link_sel_data data[IEEE80211_MLD_MAX_NUM_LINKS]; in iwl_mvm_select_links() local
777 lockdep_assert_wiphy(mvm->hw->wiphy); in iwl_mvm_select_links()
779 if (!mvmvif->authorized || !ieee80211_vif_is_mld(vif)) in iwl_mvm_select_links()
790 n_data = iwl_mvm_set_link_selection_data(vif, data, usable_links, in iwl_mvm_select_links()
796 best_link = &data[best]; in iwl_mvm_select_links()
797 primary_link = best_link->link_id; in iwl_mvm_select_links()
798 new_active_links = BIT(best_link->link_id); in iwl_mvm_select_links()
802 mvmvif->esr_disable_reason || n_data == 1) in iwl_mvm_select_links()
807 u16 esr_grade = iwl_mvm_get_esr_grade(vif, &data[a], in iwl_mvm_select_links()
808 &data[b], in iwl_mvm_select_links()
816 new_active_links = BIT(data[a].link_id) | in iwl_mvm_select_links()
817 BIT(data[b].link_id); in iwl_mvm_select_links()
824 /* For equal grade - prefer EMLSR */ in iwl_mvm_select_links()
825 if (best_link->grade > max_esr_grade) { in iwl_mvm_select_links()
826 primary_link = best_link->link_id; in iwl_mvm_select_links()
827 new_active_links = BIT(best_link->link_id); in iwl_mvm_select_links()
833 mvmvif->link_selection_res = new_active_links; in iwl_mvm_select_links()
834 mvmvif->link_selection_primary = primary_link; in iwl_mvm_select_links()
841 /* relevant data is written with both locks held, so read with either */ in iwl_mvm_get_primary_link()
842 lockdep_assert(lockdep_is_held(&mvmvif->mvm->mutex) || in iwl_mvm_get_primary_link()
843 lockdep_is_held(&mvmvif->mvm->hw->wiphy->mtx)); in iwl_mvm_get_primary_link()
849 if (vif->type == NL80211_IFTYPE_AP) in iwl_mvm_get_primary_link()
850 return __ffs(vif->active_links); in iwl_mvm_get_primary_link()
852 if (mvmvif->esr_active && in iwl_mvm_get_primary_link()
853 !WARN_ON(!(BIT(mvmvif->primary_link) & vif->active_links))) in iwl_mvm_get_primary_link()
854 return mvmvif->primary_link; in iwl_mvm_get_primary_link()
856 return __ffs(vif->active_links); in iwl_mvm_get_primary_link()
860 * For non-MLO/single link, this will return the deflink/single active link,
865 switch (hweight16(vif->active_links)) { in iwl_mvm_get_other_link()
872 return __ffs(vif->active_links); in iwl_mvm_get_other_link()
874 return __ffs(vif->active_links & ~BIT(link_id)); in iwl_mvm_get_other_link()
889 mvmvif->last_esr_exit.ts + in iwl_mvm_check_esr_prevention()
893 lockdep_assert_held(&mvm->mutex); in iwl_mvm_check_esr_prevention()
904 if (timeout_expired || mvmvif->last_esr_exit.reason != reason) { in iwl_mvm_check_esr_prevention()
905 mvmvif->exit_same_reason_count = 1; in iwl_mvm_check_esr_prevention()
909 mvmvif->exit_same_reason_count++; in iwl_mvm_check_esr_prevention()
910 if (WARN_ON(mvmvif->exit_same_reason_count < 2 || in iwl_mvm_check_esr_prevention()
911 mvmvif->exit_same_reason_count > 3)) in iwl_mvm_check_esr_prevention()
914 mvmvif->esr_disable_reason |= IWL_MVM_ESR_BLOCKED_PREVENTION; in iwl_mvm_check_esr_prevention()
920 delay = mvmvif->exit_same_reason_count == 2 ? in iwl_mvm_check_esr_prevention()
926 delay / HZ, mvmvif->exit_same_reason_count, in iwl_mvm_check_esr_prevention()
929 wiphy_delayed_work_queue(mvm->hw->wiphy, in iwl_mvm_check_esr_prevention()
930 &mvmvif->prevent_esr_done_wk, delay); in iwl_mvm_check_esr_prevention()
945 lockdep_assert_held(&mvm->mutex); in iwl_mvm_exit_esr()
951 if (!mvmvif->esr_active) in iwl_mvm_exit_esr()
954 if (WARN_ON(!ieee80211_vif_is_mld(vif) || !mvmvif->authorized)) in iwl_mvm_exit_esr()
957 if (WARN_ON(!(vif->active_links & BIT(link_to_keep)))) in iwl_mvm_exit_esr()
958 link_to_keep = __ffs(vif->active_links); in iwl_mvm_exit_esr()
962 "Exiting EMLSR. reason = %s (0x%x). Current active links=0x%x, new active links = 0x%x\n", in iwl_mvm_exit_esr()
964 vif->active_links, new_active_links); in iwl_mvm_exit_esr()
972 mvmvif->last_esr_exit.ts = jiffies; in iwl_mvm_exit_esr()
973 mvmvif->last_esr_exit.reason = reason; in iwl_mvm_exit_esr()
976 * If EMLSR is prevented now - don't try to get back to EMLSR. in iwl_mvm_exit_esr()
983 /* If EMLSR is not blocked - try enabling it again in 30 seconds */ in iwl_mvm_exit_esr()
984 wiphy_delayed_work_queue(mvm->hw->wiphy, in iwl_mvm_exit_esr()
985 &mvmvif->mlo_int_scan_wk, in iwl_mvm_exit_esr()
995 lockdep_assert_held(&mvm->mutex); in iwl_mvm_block_esr()
1004 if (mvmvif->esr_disable_reason & reason) in iwl_mvm_block_esr()
1011 mvmvif->esr_disable_reason |= reason; in iwl_mvm_block_esr()
1013 iwl_mvm_print_esr_state(mvm, mvmvif->esr_disable_reason); in iwl_mvm_block_esr()
1036 mutex_lock(&mvm->mutex); in iwl_mvm_block_esr_sync()
1039 mutex_unlock(&mvm->mutex); in iwl_mvm_block_esr_sync()
1048 bool need_new_sel = time_after(jiffies, mvmvif->last_esr_exit.ts + in iwl_mvm_esr_unblocked()
1051 lockdep_assert_held(&mvm->mutex); in iwl_mvm_esr_unblocked()
1053 if (!ieee80211_vif_is_mld(vif) || !mvmvif->authorized || in iwl_mvm_esr_unblocked()
1054 mvmvif->esr_active) in iwl_mvm_esr_unblocked()
1063 !(mvmvif->last_esr_exit.reason & IWL_MVM_BLOCK_ESR_REASONS)) { in iwl_mvm_esr_unblocked()
1072 if (need_new_sel || hweight16(mvmvif->link_selection_res) < 2) { in iwl_mvm_esr_unblocked()
1074 wiphy_delayed_work_queue(mvm->hw->wiphy, in iwl_mvm_esr_unblocked()
1075 &mvmvif->mlo_int_scan_wk, 0); in iwl_mvm_esr_unblocked()
1084 mvmvif->link_selection_res); in iwl_mvm_esr_unblocked()
1086 mvmvif->link_selection_res); in iwl_mvm_esr_unblocked()
1095 lockdep_assert_held(&mvm->mutex); in iwl_mvm_unblock_esr()
1105 if (!(mvmvif->esr_disable_reason & reason)) in iwl_mvm_unblock_esr()
1108 mvmvif->esr_disable_reason &= ~reason; in iwl_mvm_unblock_esr()
1113 iwl_mvm_print_esr_state(mvm, mvmvif->esr_disable_reason); in iwl_mvm_unblock_esr()
1115 if (!mvmvif->esr_disable_reason) in iwl_mvm_unblock_esr()
1121 link->bcast_sta.sta_id = IWL_INVALID_STA; in iwl_mvm_init_link()
1122 link->mcast_sta.sta_id = IWL_INVALID_STA; in iwl_mvm_init_link()
1123 link->ap_sta_id = IWL_INVALID_STA; in iwl_mvm_init_link()
1126 link->smps_requests[r] = in iwl_mvm_init_link()