diff options
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c | 89 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 9 |
2 files changed, 56 insertions, 42 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c index 25d98ea6db44..797c088ea0c8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c @@ -652,10 +652,49 @@ struct iwl_mvm_link_sel_data { bool active; }; -static bool iwl_mvm_mld_valid_link_pair(struct iwl_mvm_link_sel_data *a, +static bool iwl_mvm_mld_valid_link_pair(struct ieee80211_vif *vif, + struct iwl_mvm_link_sel_data *a, struct iwl_mvm_link_sel_data *b) { - return a->band != b->band; + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + + if (a->band == b->band) + return false; + + /* BT Coex effects eSR mode only if one of the link is on LB */ + if (a->band == NL80211_BAND_2GHZ || b->band == NL80211_BAND_2GHZ) + return !(mvmvif->esr_disable_reason & IWL_MVM_ESR_DISABLE_COEX); + + return true; +} + +static u8 +iwl_mvm_set_link_selection_data(struct ieee80211_vif *vif, + struct iwl_mvm_link_sel_data *data, + unsigned long usable_links) +{ + u8 n_data = 0; + unsigned long link_id; + + rcu_read_lock(); + + for_each_set_bit(link_id, &usable_links, IEEE80211_MLD_MAX_NUM_LINKS) { + struct ieee80211_bss_conf *link_conf = + rcu_dereference(vif->link_conf[link_id]); + + if (WARN_ON_ONCE(!link_conf)) + continue; + + data[n_data].link_id = link_id; + data[n_data].band = link_conf->chanreq.oper.chan->band; + data[n_data].width = link_conf->chanreq.oper.width; + data[n_data].active = vif->active_links & BIT(link_id); + n_data++; + } + + rcu_read_unlock(); + + return n_data; } void iwl_mvm_mld_select_links(struct iwl_mvm *mvm, struct ieee80211_vif *vif, @@ -665,7 +704,7 @@ void iwl_mvm_mld_select_links(struct iwl_mvm *mvm, struct ieee80211_vif *vif, unsigned long usable_links = ieee80211_vif_usable_links(vif); u32 max_active_links = iwl_mvm_max_active_links(mvm, vif); u16 new_active_links; - u8 link_id, n_data = 0, i, j; + u8 n_data, i, j; if (!IWL_MVM_AUTO_EML_ENABLE) return; @@ -690,23 +729,7 @@ void iwl_mvm_mld_select_links(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (hweight16(vif->active_links) == max_active_links) return; - rcu_read_lock(); - - for_each_set_bit(link_id, &usable_links, IEEE80211_MLD_MAX_NUM_LINKS) { - struct ieee80211_bss_conf *link_conf = - rcu_dereference(vif->link_conf[link_id]); - - if (WARN_ON_ONCE(!link_conf)) - continue; - - data[n_data].link_id = link_id; - data[n_data].band = link_conf->chanreq.oper.chan->band; - data[n_data].width = link_conf->chanreq.oper.width; - data[n_data].active = vif->active_links & BIT(link_id); - n_data++; - } - - rcu_read_unlock(); + n_data = iwl_mvm_set_link_selection_data(vif, data, usable_links); /* this is expected to be the current active link */ if (n_data == 1) @@ -730,7 +753,8 @@ void iwl_mvm_mld_select_links(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (i == j) continue; - if (iwl_mvm_mld_valid_link_pair(&data[i], &data[j])) + if (iwl_mvm_mld_valid_link_pair(vif, &data[i], + &data[j])) break; } @@ -746,7 +770,7 @@ void iwl_mvm_mld_select_links(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (i == j) continue; - if (iwl_mvm_mld_valid_link_pair(&data[i], + if (iwl_mvm_mld_valid_link_pair(vif, &data[i], &data[j])) break; } @@ -1343,11 +1367,10 @@ static bool iwl_mvm_can_enter_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif, unsigned long desired_links) { - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); u16 usable_links = ieee80211_vif_usable_links(vif); + struct iwl_mvm_link_sel_data data[IEEE80211_MLD_MAX_NUM_LINKS]; const struct wiphy_iftype_ext_capab *ext_capa; - bool ret = true; - int link_id; + u8 n_data; if (!ieee80211_vif_is_mld(vif) || !vif->cfg.assoc || hweight16(usable_links) <= 1) @@ -1362,21 +1385,13 @@ static bool iwl_mvm_can_enter_esr(struct iwl_mvm *mvm, !(ext_capa->eml_capabilities & IEEE80211_EML_CAP_EMLSR_SUPP)) return false; - for_each_set_bit(link_id, &desired_links, IEEE80211_MLD_MAX_NUM_LINKS) { - struct ieee80211_bss_conf *link_conf = - link_conf_dereference_protected(vif, link_id); - - if (WARN_ON_ONCE(!link_conf)) - continue; + n_data = iwl_mvm_set_link_selection_data(vif, data, desired_links); - /* BT Coex effects eSR mode only if one of the link is on LB */ - if (link_conf->chanreq.oper.chan->band != NL80211_BAND_2GHZ) - continue; + if (n_data != 2) + return false; - return !(mvmvif->esr_disable_reason & IWL_MVM_ESR_DISABLE_COEX); - } - return ret; + return iwl_mvm_mld_valid_link_pair(vif, &data[0], &data[1]); } static bool iwl_mvm_mld_can_activate_links(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 77786c1a7528..6ac20d42a09c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1589,15 +1589,14 @@ static inline int iwl_mvm_max_active_links(struct iwl_mvm *mvm, struct iwl_trans *trans = mvm->fwrt.trans; struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - lockdep_assert_held(&mvm->mutex); - if (vif->type == NL80211_IFTYPE_AP) return mvm->fw->ucode_capa.num_beacons; + /* Check if HW supports eSR or STR */ if ((iwl_mvm_is_esr_supported(trans) && - !mvmvif->esr_disable_reason) || - ((CSR_HW_RFID_TYPE(trans->hw_rf_id) == IWL_CFG_RF_TYPE_FM && - CSR_HW_RFID_IS_CDB(trans->hw_rf_id)))) + !(mvmvif->esr_disable_reason & ~IWL_MVM_ESR_DISABLE_COEX)) || + (CSR_HW_RFID_TYPE(trans->hw_rf_id) == IWL_CFG_RF_TYPE_FM && + CSR_HW_RFID_IS_CDB(trans->hw_rf_id))) return IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM; return 1; |