diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index d4a3d9259150..c006d68a785e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -4545,6 +4545,46 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw, return ret; } +/* + * This function executes the common part for MLD and non-MLD modes. + * + * Returns if chanctx unassign chanctx is done + * (either on failure or success) + */ +static bool __iwl_mvm_unassign_vif_chanctx_common(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + bool switching_chanctx) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + + lockdep_assert_held(&mvm->mutex); + iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data); + + switch (vif->type) { + case NL80211_IFTYPE_ADHOC: + return true; + case NL80211_IFTYPE_MONITOR: + mvmvif->monitor_active = false; + mvmvif->ps_disabled = false; + break; + case NL80211_IFTYPE_AP: + /* This part is triggered only during CSA */ + if (!switching_chanctx || !mvmvif->ap_ibss_active) + return true; + + mvmvif->csa_countdown = false; + + /* Save blocked iface, the timeout is set on the next beacon */ + rcu_assign_pointer(mvm->csa_tx_blocked_vif, vif); + + mvmvif->ap_ibss_active = false; + break; + default: + break; + } + return false; +} + static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_chanctx_conf *ctx, @@ -4553,44 +4593,21 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct ieee80211_vif *disabled_vif = NULL; - lockdep_assert_held(&mvm->mutex); - iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data); - - switch (vif->type) { - case NL80211_IFTYPE_ADHOC: + if (__iwl_mvm_unassign_vif_chanctx_common(mvm, vif, switching_chanctx)) goto out; - case NL80211_IFTYPE_MONITOR: - mvmvif->monitor_active = false; - mvmvif->ps_disabled = false; + + if (vif->type == NL80211_IFTYPE_MONITOR) iwl_mvm_rm_snif_sta(mvm, vif); - break; - case NL80211_IFTYPE_AP: - /* This part is triggered only during CSA */ - if (!switching_chanctx || !mvmvif->ap_ibss_active) - goto out; - - mvmvif->csa_countdown = false; + if (vif->type == NL80211_IFTYPE_AP) /* Set CS bit on all the stations */ iwl_mvm_modify_all_sta_disable_tx(mvm, mvmvif, true); - /* Save blocked iface, the timeout is set on the next beacon */ - rcu_assign_pointer(mvm->csa_tx_blocked_vif, vif); - - mvmvif->ap_ibss_active = false; - break; - case NL80211_IFTYPE_STATION: - if (!switching_chanctx) - break; - + if (vif->type == NL80211_IFTYPE_STATION && switching_chanctx) { disabled_vif = vif; - if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) iwl_mvm_mac_ctxt_changed(mvm, vif, true, NULL); - break; - default: - break; } iwl_mvm_update_quotas(mvm, false, disabled_vif);