mirror of https://gitee.com/openkylin/linux.git
iwlwifi: mvm: remove session protection to allow channel switch
If a time event is already scheduled when trying to schedule one for channel switch, the code assumes the channel switch is already scheduled and no further action is required. However, it is possible that the scheduled time event is actually for session protection (e.g. when the first beacon after association contains the CSA IE). In this case the channel switch will not be scheduled which will finally lead to disconnection. Fix this by removing the old time event and schduling a new one for the channel switch. Signed-off-by: Avraham Stern <avraham.stern@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
parent
f9cd3e0871
commit
3edfb5f44b
|
@ -2023,8 +2023,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
|||
* We received a beacon from the associated AP so
|
||||
* remove the session protection.
|
||||
*/
|
||||
iwl_mvm_remove_time_event(mvm, mvmvif,
|
||||
&mvmvif->time_event_data);
|
||||
iwl_mvm_stop_session_protection(mvm, vif);
|
||||
|
||||
iwl_mvm_sf_update(mvm, vif, false);
|
||||
WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -33,6 +34,7 @@
|
|||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -726,8 +728,21 @@ void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
|
|||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
|
||||
u32 id;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
spin_lock_bh(&mvm->time_event_lock);
|
||||
id = te_data->id;
|
||||
spin_unlock_bh(&mvm->time_event_lock);
|
||||
|
||||
if (id != TE_BSS_STA_AGGRESSIVE_ASSOC) {
|
||||
IWL_DEBUG_TE(mvm,
|
||||
"don't remove TE with id=%u (not session protection)\n",
|
||||
id);
|
||||
return;
|
||||
}
|
||||
|
||||
iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
|
||||
}
|
||||
|
||||
|
@ -859,8 +874,23 @@ int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
|
|||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
if (te_data->running) {
|
||||
IWL_DEBUG_TE(mvm, "CS period is already scheduled\n");
|
||||
return -EBUSY;
|
||||
u32 id;
|
||||
|
||||
spin_lock_bh(&mvm->time_event_lock);
|
||||
id = te_data->id;
|
||||
spin_unlock_bh(&mvm->time_event_lock);
|
||||
|
||||
if (id == TE_CHANNEL_SWITCH_PERIOD) {
|
||||
IWL_DEBUG_TE(mvm, "CS period is already scheduled\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the session protection time event to allow the
|
||||
* channel switch. If we got here, we just heard a beacon so
|
||||
* the session protection is not needed anymore anyway.
|
||||
*/
|
||||
iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
|
||||
}
|
||||
|
||||
time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
|
||||
|
|
Loading…
Reference in New Issue