wifi: iwlwifi: mvm: remove IWL_MVM_STATUS_NEED_FLUSH_P2P
This is set when a P2P ROC ends, and uses as an indication inside iwl_mvm_roc_done_wk that the resources used for this ROC (sta/link) needs to be flushed/deactivated (respectively). But we also have IWL_MVM_STATUS_ROC_RUNNING, which is set whenever P2P ROC starts, and is not even used in iwl_mvm_roc_done_wk. Use IWL_MVM_STATUS_ROC_RUNNING as an indicator, and remove the redundant bit. While at it, add a call to synchronize_net also for the AUX ROC case, which is missing in the existing code. Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://msgid.link/20240205211151.0494f75de311.Ic4aacacf7581a5c9046c4f1df87cbb67470853e7@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
cd882e2fb2
commit
35c1bbd93c
@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2012-2014, 2018-2023 Intel Corporation
|
* Copyright (C) 2012-2014, 2018-2024 Intel Corporation
|
||||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||||
*/
|
*/
|
||||||
@ -1221,7 +1221,6 @@ struct iwl_mvm {
|
|||||||
* @IWL_MVM_STATUS_IN_HW_RESTART: HW restart is active
|
* @IWL_MVM_STATUS_IN_HW_RESTART: HW restart is active
|
||||||
* @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running
|
* @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running
|
||||||
* @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running
|
* @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running
|
||||||
* @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA
|
|
||||||
* @IWL_MVM_STATUS_IN_D3: in D3 (or at least about to go into it)
|
* @IWL_MVM_STATUS_IN_D3: in D3 (or at least about to go into it)
|
||||||
* @IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE: suppress one error log
|
* @IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE: suppress one error log
|
||||||
* if this is set, when intentionally triggered
|
* if this is set, when intentionally triggered
|
||||||
@ -1236,7 +1235,6 @@ enum iwl_mvm_status {
|
|||||||
IWL_MVM_STATUS_IN_HW_RESTART,
|
IWL_MVM_STATUS_IN_HW_RESTART,
|
||||||
IWL_MVM_STATUS_ROC_AUX_RUNNING,
|
IWL_MVM_STATUS_ROC_AUX_RUNNING,
|
||||||
IWL_MVM_STATUS_FIRMWARE_RUNNING,
|
IWL_MVM_STATUS_FIRMWARE_RUNNING,
|
||||||
IWL_MVM_STATUS_NEED_FLUSH_P2P,
|
|
||||||
IWL_MVM_STATUS_IN_D3,
|
IWL_MVM_STATUS_IN_D3,
|
||||||
IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE,
|
IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE,
|
||||||
IWL_MVM_STATUS_STARTING,
|
IWL_MVM_STATUS_STARTING,
|
||||||
|
@ -45,32 +45,24 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
|
|||||||
te_data->link_id = -1;
|
te_data->link_id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iwl_mvm_roc_done_wk(struct work_struct *wk)
|
static void iwl_mvm_cleanup_roc(struct iwl_mvm *mvm)
|
||||||
{
|
{
|
||||||
struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, roc_done_wk);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear the ROC_RUNNING status bit.
|
* Clear the ROC_RUNNING status bit.
|
||||||
* This will cause the TX path to drop offchannel transmissions.
|
* This will cause the TX path to drop offchannel transmissions.
|
||||||
* That would also be done by mac80211, but it is racy, in particular
|
* That would also be done by mac80211, but it is racy, in particular
|
||||||
* in the case that the time event actually completed in the firmware
|
* in the case that the time event actually completed in the firmware.
|
||||||
* (which is handled in iwl_mvm_te_handle_notif).
|
*
|
||||||
*/
|
* Also flush the offchannel queue -- this is called when the time
|
||||||
clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
|
|
||||||
|
|
||||||
synchronize_net();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Flush the offchannel queue -- this is called when the time
|
|
||||||
* event finishes or is canceled, so that frames queued for it
|
* event finishes or is canceled, so that frames queued for it
|
||||||
* won't get stuck on the queue and be transmitted in the next
|
* won't get stuck on the queue and be transmitted in the next
|
||||||
* time event.
|
* time event.
|
||||||
*/
|
*/
|
||||||
|
if (test_and_clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status)) {
|
||||||
mutex_lock(&mvm->mutex);
|
|
||||||
if (test_and_clear_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status)) {
|
|
||||||
struct iwl_mvm_vif *mvmvif;
|
struct iwl_mvm_vif *mvmvif;
|
||||||
|
|
||||||
|
synchronize_net();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NB: access to this pointer would be racy, but the flush bit
|
* NB: access to this pointer would be racy, but the flush bit
|
||||||
* can only be set when we had a P2P-Device VIF, and we have a
|
* can only be set when we had a P2P-Device VIF, and we have a
|
||||||
@ -105,21 +97,16 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Do the same for AUX ROC */
|
||||||
* Clear the ROC_AUX_RUNNING status bit.
|
|
||||||
* This will cause the TX path to drop offchannel transmissions.
|
|
||||||
* That would also be done by mac80211, but it is racy, in particular
|
|
||||||
* in the case that the time event actually completed in the firmware
|
|
||||||
* (which is handled in iwl_mvm_te_handle_notif).
|
|
||||||
*/
|
|
||||||
if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status)) {
|
if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status)) {
|
||||||
/* do the same in case of hot spot 2.0 */
|
synchronize_net();
|
||||||
|
|
||||||
iwl_mvm_flush_sta(mvm, mvm->aux_sta.sta_id,
|
iwl_mvm_flush_sta(mvm, mvm->aux_sta.sta_id,
|
||||||
mvm->aux_sta.tfd_queue_msk);
|
mvm->aux_sta.tfd_queue_msk);
|
||||||
|
|
||||||
if (mvm->mld_api_is_used) {
|
if (mvm->mld_api_is_used) {
|
||||||
iwl_mvm_mld_rm_aux_sta(mvm);
|
iwl_mvm_mld_rm_aux_sta(mvm);
|
||||||
goto out_unlock;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In newer version of this command an aux station is added only
|
/* In newer version of this command an aux station is added only
|
||||||
@ -128,8 +115,14 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
|
|||||||
if (iwl_mvm_has_new_station_api(mvm->fw))
|
if (iwl_mvm_has_new_station_api(mvm->fw))
|
||||||
iwl_mvm_rm_aux_sta(mvm);
|
iwl_mvm_rm_aux_sta(mvm);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out_unlock:
|
void iwl_mvm_roc_done_wk(struct work_struct *wk)
|
||||||
|
{
|
||||||
|
struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, roc_done_wk);
|
||||||
|
|
||||||
|
mutex_lock(&mvm->mutex);
|
||||||
|
iwl_mvm_cleanup_roc(mvm);
|
||||||
mutex_unlock(&mvm->mutex);
|
mutex_unlock(&mvm->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,18 +287,6 @@ static void iwl_mvm_te_check_trigger(struct iwl_mvm *mvm,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwl_mvm_p2p_roc_finished(struct iwl_mvm *mvm)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If the IWL_MVM_STATUS_NEED_FLUSH_P2P is already set, then the
|
|
||||||
* roc_done_wk is already scheduled or running, so don't schedule it
|
|
||||||
* again to avoid a race where the roc_done_wk clears this bit after
|
|
||||||
* it is set here, affecting the next run of the roc_done_wk.
|
|
||||||
*/
|
|
||||||
if (!test_and_set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status))
|
|
||||||
iwl_mvm_roc_finished(mvm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handles a FW notification for an event that is known to the driver.
|
* Handles a FW notification for an event that is known to the driver.
|
||||||
*
|
*
|
||||||
@ -357,7 +338,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
|
|||||||
switch (te_data->vif->type) {
|
switch (te_data->vif->type) {
|
||||||
case NL80211_IFTYPE_P2P_DEVICE:
|
case NL80211_IFTYPE_P2P_DEVICE:
|
||||||
ieee80211_remain_on_channel_expired(mvm->hw);
|
ieee80211_remain_on_channel_expired(mvm->hw);
|
||||||
iwl_mvm_p2p_roc_finished(mvm);
|
iwl_mvm_roc_finished(mvm);
|
||||||
break;
|
break;
|
||||||
case NL80211_IFTYPE_STATION:
|
case NL80211_IFTYPE_STATION:
|
||||||
/*
|
/*
|
||||||
@ -782,7 +763,7 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
|
|||||||
iwl_mvm_cancel_session_protection(mvm, vif, id,
|
iwl_mvm_cancel_session_protection(mvm, vif, id,
|
||||||
link_id);
|
link_id);
|
||||||
if (iftype == NL80211_IFTYPE_P2P_DEVICE) {
|
if (iftype == NL80211_IFTYPE_P2P_DEVICE) {
|
||||||
iwl_mvm_p2p_roc_finished(mvm);
|
iwl_mvm_roc_finished(mvm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -972,7 +953,7 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,
|
|||||||
/* End TE, notify mac80211 */
|
/* End TE, notify mac80211 */
|
||||||
mvmvif->time_event_data.id = SESSION_PROTECT_CONF_MAX_ID;
|
mvmvif->time_event_data.id = SESSION_PROTECT_CONF_MAX_ID;
|
||||||
mvmvif->time_event_data.link_id = -1;
|
mvmvif->time_event_data.link_id = -1;
|
||||||
iwl_mvm_p2p_roc_finished(mvm);
|
iwl_mvm_roc_finished(mvm);
|
||||||
ieee80211_remain_on_channel_expired(mvm->hw);
|
ieee80211_remain_on_channel_expired(mvm->hw);
|
||||||
} else if (le32_to_cpu(notif->start)) {
|
} else if (le32_to_cpu(notif->start)) {
|
||||||
if (WARN_ON(mvmvif->time_event_data.id !=
|
if (WARN_ON(mvmvif->time_event_data.id !=
|
||||||
@ -1244,17 +1225,13 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||||||
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) {
|
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) {
|
||||||
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, vif,
|
iwl_mvm_cancel_session_protection(mvm, vif,
|
||||||
mvmvif->time_event_data.id,
|
mvmvif->time_event_data.id,
|
||||||
mvmvif->time_event_data.link_id);
|
mvmvif->time_event_data.link_id);
|
||||||
iwl_mvm_p2p_roc_finished(mvm);
|
else
|
||||||
} else {
|
|
||||||
iwl_mvm_roc_station_remove(mvm, mvmvif);
|
iwl_mvm_roc_station_remove(mvm, mvmvif);
|
||||||
iwl_mvm_roc_finished(mvm);
|
goto cleanup_roc;
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
te_data = iwl_mvm_get_roc_te(mvm);
|
te_data = iwl_mvm_get_roc_te(mvm);
|
||||||
@ -1265,13 +1242,21 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||||||
|
|
||||||
mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
|
mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
|
||||||
|
|
||||||
if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
|
if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE)
|
||||||
iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
|
iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
|
||||||
iwl_mvm_p2p_roc_finished(mvm);
|
else
|
||||||
} else {
|
|
||||||
iwl_mvm_remove_aux_roc_te(mvm, mvmvif, te_data);
|
iwl_mvm_remove_aux_roc_te(mvm, mvmvif, te_data);
|
||||||
iwl_mvm_roc_finished(mvm);
|
|
||||||
}
|
cleanup_roc:
|
||||||
|
/*
|
||||||
|
* In case we get here before the ROC event started,
|
||||||
|
* (so the status bit isn't set) set it here so iwl_mvm_cleanup_roc will
|
||||||
|
* cleanup things properly
|
||||||
|
*/
|
||||||
|
set_bit(vif->type == NL80211_IFTYPE_P2P_DEVICE ?
|
||||||
|
IWL_MVM_STATUS_ROC_RUNNING : IWL_MVM_STATUS_ROC_AUX_RUNNING,
|
||||||
|
&mvm->status);
|
||||||
|
iwl_mvm_cleanup_roc(mvm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iwl_mvm_remove_csa_period(struct iwl_mvm *mvm,
|
void iwl_mvm_remove_csa_period(struct iwl_mvm *mvm,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user