switch (vif->type) {
case NL80211_IFTYPE_AP:
- /* Unless it's a CSA flow we have nothing to do here */
- if (vif->csa_active) {
+ /* only needed if we're switching chanctx (i.e. during CSA) */
+ if (switching_chanctx) {
mvmvif->ap_ibss_active = true;
break;
}
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
}
- if (vif->csa_active && vif->type == NL80211_IFTYPE_STATION) {
+ if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) {
struct iwl_mvm_sta *mvmsta;
mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct ieee80211_vif *disabled_vif = NULL;
- struct iwl_mvm_sta *mvmsta;
lockdep_assert_held(&mvm->mutex);
break;
case NL80211_IFTYPE_AP:
/* This part is triggered only during CSA */
- if (!vif->csa_active || !mvmvif->ap_ibss_active)
+ if (!switching_chanctx || !mvmvif->ap_ibss_active)
goto out;
mvmvif->csa_countdown = false;
disabled_vif = vif;
- mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
- mvmvif->ap_sta_id);
-
- if (!WARN_ON(!mvmsta))
- iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, true);
-
iwl_mvm_mac_ctxt_changed(mvm, vif, true, NULL);
break;
default:
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct ieee80211_vif *csa_vif;
- struct iwl_mvm_vif *mvmvif;
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ u32 apply_time;
int ret;
mutex_lock(&mvm->mutex);
rcu_assign_pointer(mvm->csa_vif, vif);
- mvmvif = iwl_mvm_vif_from_mac80211(vif);
if (WARN_ONCE(mvmvif->csa_countdown,
"Previous CSA countdown didn't complete")) {
ret = -EBUSY;
}
break;
+ case NL80211_IFTYPE_STATION:
+ apply_time = chsw->timestamp +
+ (vif->bss_conf.beacon_int * chsw->count * 1024);
+
+ if (chsw->block_tx)
+ iwl_mvm_csa_client_absent(mvm, vif);
+
+ iwl_mvm_schedule_csa_period(mvm, vif,
+ IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT,
+ apply_time);
+ break;
default:
break;
}
- ret = 0;
+ mvmvif->ps_disabled = true;
+
+ ret = iwl_mvm_power_update_ps(mvm);
+ if (ret)
+ goto out_unlock;
out_unlock:
mutex_unlock(&mvm->mutex);
return ret;
}
+static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+ int ret;
+
+ mutex_lock(&mvm->mutex);
+
+ mvmvif->ps_disabled = false;
+
+ ret = iwl_mvm_power_update_ps(mvm);
+
+ mutex_unlock(&mvm->mutex);
+
+ return ret;
+}
+
static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u32 queues, bool drop)
{
.set_tim = iwl_mvm_set_tim,
.pre_channel_switch = iwl_mvm_pre_channel_switch,
+ .post_channel_switch = iwl_mvm_post_channel_switch,
.tdls_channel_switch = iwl_mvm_tdls_channel_switch,
.tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch,