Skip to content

Commit

Permalink
iwlwifi: mvm: simplify the channel switch flow for newer firmware
Browse files Browse the repository at this point in the history
Any firmware that supports the new channel switch flow is
able to close / re-open the queues when needed. It takes
into account the channel switch mode etc...
Don't open / close the queues or enable / disable beacon
abort before and after the channel switch in case the
firmware is able to do this by itself.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
  • Loading branch information
Emmanuel Grumbach authored and Luca Coelho committed Sep 6, 2019
1 parent 2d46f7a commit 0202bcf
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 31 deletions.
4 changes: 3 additions & 1 deletion drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1594,7 +1594,9 @@ void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm,
RCU_INIT_POINTER(mvm->csa_vif, NULL);
return;
case NL80211_IFTYPE_STATION:
iwl_mvm_csa_client_absent(mvm, vif);
if (!fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
iwl_mvm_csa_client_absent(mvm, vif);
cancel_delayed_work(&mvmvif->csa_work);
ieee80211_chswitch_done(vif, true);
break;
Expand Down
81 changes: 51 additions & 30 deletions drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1326,15 +1326,20 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
goto out_unlock;
}

iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
if (!fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);

iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);

ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
if (ret)
goto out_unlock;
if (!fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
if (ret)
goto out_unlock;

iwl_mvm_stop_session_protection(mvm, vif);
iwl_mvm_stop_session_protection(mvm, vif);
}
}

mvmvif->ps_disabled = false;
Expand Down Expand Up @@ -4421,6 +4426,42 @@ static int iwl_mvm_schedule_client_csa(struct iwl_mvm *mvm,
0, sizeof(cmd), &cmd);
}

static int iwl_mvm_old_pre_chan_sw_sta(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_channel_switch *chsw)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
u32 apply_time;

/* Schedule the time event to a bit before beacon 1,
* to make sure we're in the new channel when the
* GO/AP arrives. In case count <= 1 immediately schedule the
* TE (this might result with some packet loss or connection
* loss).
*/
if (chsw->count <= 1)
apply_time = 0;
else
apply_time = chsw->device_timestamp +
((vif->bss_conf.beacon_int * (chsw->count - 1) -
IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);

if (chsw->block_tx)
iwl_mvm_csa_client_absent(mvm, vif);

if (mvmvif->bf_data.bf_enabled) {
int ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);

if (ret)
return ret;
}

iwl_mvm_schedule_csa_period(mvm, vif, vif->bss_conf.beacon_int,
apply_time);

return 0;
}

#define IWL_MAX_CSA_BLOCK_TX 1500
static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
Expand All @@ -4429,7 +4470,6 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct ieee80211_vif *csa_vif;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
u32 apply_time;
int ret;

mutex_lock(&mvm->mutex);
Expand Down Expand Up @@ -4473,21 +4513,7 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,

break;
case NL80211_IFTYPE_STATION:
/* Schedule the time event to a bit before beacon 1,
* to make sure we're in the new channel when the
* GO/AP arrives. In case count <= 1 immediately schedule the
* TE (this might result with some packet loss or connection
* loss).
*/
if (chsw->count <= 1)
apply_time = 0;
else
apply_time = chsw->device_timestamp +
((vif->bss_conf.beacon_int * (chsw->count - 1) -
IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);

if (chsw->block_tx) {
iwl_mvm_csa_client_absent(mvm, vif);
/*
* In case of undetermined / long time with immediate
* quiet monitor status to gracefully disconnect
Expand All @@ -4499,19 +4525,14 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
msecs_to_jiffies(IWL_MAX_CSA_BLOCK_TX));
}

if (mvmvif->bf_data.bf_enabled) {
ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
if (!fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
ret = iwl_mvm_old_pre_chan_sw_sta(mvm, vif, chsw);
if (ret)
goto out_unlock;
}

if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
} else {
iwl_mvm_schedule_client_csa(mvm, vif, chsw);
else
iwl_mvm_schedule_csa_period(mvm, vif,
vif->bss_conf.beacon_int,
apply_time);
}

mvmvif->csa_count = chsw->count;
mvmvif->csa_misbehave = false;
Expand Down

0 comments on commit 0202bcf

Please sign in to comment.