iwlwifi: mvm: Explicitly stop session protection before unbinding
In case of unbinding, the FW would remove the session protection time events without sending a notification, so explicitly cancel the session protection, so future requests for mgd_prepare_tx() would not assume that the session protection is running. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Link: https://lore.kernel.org/r/iwlwifi.20210618105614.7c30f85ed241.Ibc19fdbefca7135f2c4ea83d0aef6b81b5033dcd@changeid Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
parent
54b4fda5a7
commit
7b3954a1d6
2 changed files with 30 additions and 12 deletions
|
@ -4223,7 +4223,6 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
|
||||||
struct ieee80211_vif *disabled_vif = NULL;
|
struct ieee80211_vif *disabled_vif = NULL;
|
||||||
|
|
||||||
lockdep_assert_held(&mvm->mutex);
|
lockdep_assert_held(&mvm->mutex);
|
||||||
|
|
||||||
iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
|
iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
|
||||||
|
|
||||||
switch (vif->type) {
|
switch (vif->type) {
|
||||||
|
|
|
@ -31,6 +31,13 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
list_del(&te_data->list);
|
list_del(&te_data->list);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the list is only used for AUX ROC events so make sure it is always
|
||||||
|
* initialized
|
||||||
|
*/
|
||||||
|
INIT_LIST_HEAD(&te_data->list);
|
||||||
|
|
||||||
te_data->running = false;
|
te_data->running = false;
|
||||||
te_data->uid = 0;
|
te_data->uid = 0;
|
||||||
te_data->id = TE_MAX;
|
te_data->id = TE_MAX;
|
||||||
|
@ -609,14 +616,15 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwl_mvm_cancel_session_protection(struct iwl_mvm *mvm,
|
static void iwl_mvm_cancel_session_protection(struct iwl_mvm *mvm,
|
||||||
struct iwl_mvm_vif *mvmvif)
|
struct iwl_mvm_vif *mvmvif,
|
||||||
|
u32 id)
|
||||||
{
|
{
|
||||||
struct iwl_mvm_session_prot_cmd cmd = {
|
struct iwl_mvm_session_prot_cmd cmd = {
|
||||||
.id_and_color =
|
.id_and_color =
|
||||||
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
|
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
|
||||||
mvmvif->color)),
|
mvmvif->color)),
|
||||||
.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),
|
.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),
|
||||||
.conf_id = cpu_to_le32(mvmvif->time_event_data.id),
|
.conf_id = cpu_to_le32(id),
|
||||||
};
|
};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -634,6 +642,12 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
|
||||||
{
|
{
|
||||||
u32 id;
|
u32 id;
|
||||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
|
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
|
||||||
|
enum nl80211_iftype iftype;
|
||||||
|
|
||||||
|
if (!te_data->vif)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
iftype = te_data->vif->type;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It is possible that by the time we got to this point the time
|
* It is possible that by the time we got to this point the time
|
||||||
|
@ -658,8 +672,8 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
|
||||||
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) {
|
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) {
|
||||||
if (mvmvif && id < SESSION_PROTECT_CONF_MAX_ID) {
|
if (mvmvif && id < SESSION_PROTECT_CONF_MAX_ID) {
|
||||||
/* Session protection is still ongoing. Cancel it */
|
/* Session protection is still ongoing. Cancel it */
|
||||||
iwl_mvm_cancel_session_protection(mvm, mvmvif);
|
iwl_mvm_cancel_session_protection(mvm, mvmvif, id);
|
||||||
if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
|
if (iftype == NL80211_IFTYPE_P2P_DEVICE) {
|
||||||
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
|
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
|
||||||
iwl_mvm_roc_finished(mvm);
|
iwl_mvm_roc_finished(mvm);
|
||||||
}
|
}
|
||||||
|
@ -740,11 +754,6 @@ void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
|
||||||
IWL_ERR(mvm, "Couldn't remove the time event\n");
|
IWL_ERR(mvm, "Couldn't remove the time event\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* When the firmware supports the session protection API,
|
|
||||||
* this is not needed since it'll automatically remove the
|
|
||||||
* session protection after association + beacon reception.
|
|
||||||
*/
|
|
||||||
void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
|
void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
|
||||||
struct ieee80211_vif *vif)
|
struct ieee80211_vif *vif)
|
||||||
{
|
{
|
||||||
|
@ -758,7 +767,15 @@ void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
|
||||||
id = te_data->id;
|
id = te_data->id;
|
||||||
spin_unlock_bh(&mvm->time_event_lock);
|
spin_unlock_bh(&mvm->time_event_lock);
|
||||||
|
|
||||||
if (id != TE_BSS_STA_AGGRESSIVE_ASSOC) {
|
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||||
|
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) {
|
||||||
|
if (id != SESSION_PROTECT_CONF_ASSOC) {
|
||||||
|
IWL_DEBUG_TE(mvm,
|
||||||
|
"don't remove session protection id=%u\n",
|
||||||
|
id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (id != TE_BSS_STA_AGGRESSIVE_ASSOC) {
|
||||||
IWL_DEBUG_TE(mvm,
|
IWL_DEBUG_TE(mvm,
|
||||||
"don't remove TE with id=%u (not session protection)\n",
|
"don't remove TE with id=%u (not session protection)\n",
|
||||||
id);
|
id);
|
||||||
|
@ -985,7 +1002,8 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||||
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||||
|
|
||||||
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
|
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
|
||||||
iwl_mvm_cancel_session_protection(mvm, mvmvif);
|
iwl_mvm_cancel_session_protection(mvm, mvmvif,
|
||||||
|
mvmvif->time_event_data.id);
|
||||||
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
|
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
|
||||||
} else {
|
} else {
|
||||||
iwl_mvm_remove_aux_roc_te(mvm, mvmvif,
|
iwl_mvm_remove_aux_roc_te(mvm, mvmvif,
|
||||||
|
@ -1145,6 +1163,7 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
|
||||||
|
|
||||||
iwl_mvm_te_clear_data(mvm, te_data);
|
iwl_mvm_te_clear_data(mvm, te_data);
|
||||||
te_data->duration = le32_to_cpu(cmd.duration_tu);
|
te_data->duration = le32_to_cpu(cmd.duration_tu);
|
||||||
|
te_data->vif = vif;
|
||||||
spin_unlock_bh(&mvm->time_event_lock);
|
spin_unlock_bh(&mvm->time_event_lock);
|
||||||
|
|
||||||
IWL_DEBUG_TE(mvm, "Add new session protection, duration %d TU\n",
|
IWL_DEBUG_TE(mvm, "Add new session protection, duration %d TU\n",
|
||||||
|
|
Loading…
Add table
Reference in a new issue