wifi: iwlwifi: mvm: Block EMLSR when a p2p/softAP vif is active
When there's an active link in a non-station vif, the station vif is not allowed to enter EMLSR Note that blocking EMLSR by calling iwl_mvm_block_esr() we will schedule an exit from EMLSR worker, but the worker cannot run before the activation of the non-BSS link, as ieee80211_remain_on_channel already holds the wiphy mutex. Handle that by explicitly calling ieee80211_set_active_links() to leave EMLSR, and then doing iwl_mvm_block_esr() only for consistency and to avoid re-entering it before ready. Note that a call to ieee80211_set_active_links requires to release the mvm mutex, but that's ok since we still hold the wiphy lock. The only thing that might race here is the ESR_MODE_NOTIF, so this changes its handler to run under the wiphy lock. Signed-off-by: Yedidya Benshimol <yedidya.ben.shimol@intel.com> Co-developed-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://msgid.link/20240505091420.916193759f8a.Idf3a3caf5cdc3e69c81710b7ceb57e87f2de87e4@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
eead359109
commit
a1efeb8230
7 changed files with 133 additions and 19 deletions
|
@ -1243,7 +1243,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
|
||||||
.data[0] = &d3_cfg_cmd_data,
|
.data[0] = &d3_cfg_cmd_data,
|
||||||
.len[0] = sizeof(d3_cfg_cmd_data),
|
.len[0] = sizeof(d3_cfg_cmd_data),
|
||||||
};
|
};
|
||||||
int ret, primary_link;
|
int ret;
|
||||||
int len __maybe_unused;
|
int len __maybe_unused;
|
||||||
bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
|
bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
|
||||||
IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
|
IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
|
||||||
|
@ -1261,18 +1261,11 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
|
||||||
if (IS_ERR_OR_NULL(vif))
|
if (IS_ERR_OR_NULL(vif))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
primary_link = iwl_mvm_get_primary_link(vif);
|
ret = iwl_mvm_block_esr_sync(mvm, vif, IWL_MVM_ESR_BLOCKED_WOWLAN);
|
||||||
|
if (ret)
|
||||||
/* leave ESR immediately, not only async with iwl_mvm_block_esr() */
|
return ret;
|
||||||
if (ieee80211_vif_is_mld(vif)) {
|
|
||||||
ret = ieee80211_set_active_links(vif, BIT(primary_link));
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&mvm->mutex);
|
mutex_lock(&mvm->mutex);
|
||||||
/* only additionally block for consistency and to avoid concurrency */
|
|
||||||
iwl_mvm_block_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_WOWLAN, primary_link);
|
|
||||||
|
|
||||||
set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
|
set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
|
||||||
|
|
||||||
|
@ -1280,7 +1273,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
|
||||||
|
|
||||||
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||||
|
|
||||||
mvm_link = mvmvif->link[primary_link];
|
mvm_link = mvmvif->link[iwl_mvm_get_primary_link(vif)];
|
||||||
if (WARN_ON_ONCE(!mvm_link)) {
|
if (WARN_ON_ONCE(!mvm_link)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out_noreset;
|
goto out_noreset;
|
||||||
|
|
|
@ -108,6 +108,65 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
return iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_ADD);
|
return iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_ADD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct iwl_mvm_esr_iter_data {
|
||||||
|
struct ieee80211_vif *vif;
|
||||||
|
unsigned int link_id;
|
||||||
|
bool lift_block;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void iwl_mvm_esr_vif_iterator(void *_data, u8 *mac,
|
||||||
|
struct ieee80211_vif *vif)
|
||||||
|
{
|
||||||
|
struct iwl_mvm_esr_iter_data *data = _data;
|
||||||
|
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||||
|
int link_id;
|
||||||
|
|
||||||
|
if (ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_STATION)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for_each_mvm_vif_valid_link(mvmvif, link_id) {
|
||||||
|
struct iwl_mvm_vif_link_info *link_info =
|
||||||
|
mvmvif->link[link_id];
|
||||||
|
if (vif == data->vif && link_id == data->link_id)
|
||||||
|
continue;
|
||||||
|
if (link_info->active)
|
||||||
|
data->lift_block = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int iwl_mvm_esr_non_bss_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
|
unsigned int link_id, bool active)
|
||||||
|
{
|
||||||
|
/* An active link of a non-station vif blocks EMLSR. Upon activation
|
||||||
|
* block EMLSR on the bss vif. Upon deactivation, check if this link
|
||||||
|
* was the last non-station link active, and if so unblock the bss vif
|
||||||
|
*/
|
||||||
|
struct ieee80211_vif *bss_vif = iwl_mvm_get_bss_vif(mvm);
|
||||||
|
struct iwl_mvm_esr_iter_data data = {
|
||||||
|
.vif = vif,
|
||||||
|
.link_id = link_id,
|
||||||
|
.lift_block = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (IS_ERR_OR_NULL(bss_vif))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (active)
|
||||||
|
return iwl_mvm_block_esr_sync(mvm, bss_vif,
|
||||||
|
IWL_MVM_ESR_BLOCKED_NON_BSS);
|
||||||
|
|
||||||
|
ieee80211_iterate_active_interfaces(mvm->hw,
|
||||||
|
IEEE80211_IFACE_ITER_NORMAL,
|
||||||
|
iwl_mvm_esr_vif_iterator, &data);
|
||||||
|
if (data.lift_block) {
|
||||||
|
mutex_lock(&mvm->mutex);
|
||||||
|
iwl_mvm_unblock_esr(mvm, bss_vif, IWL_MVM_ESR_BLOCKED_NON_BSS);
|
||||||
|
mutex_unlock(&mvm->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
struct ieee80211_bss_conf *link_conf,
|
struct ieee80211_bss_conf *link_conf,
|
||||||
u32 changes, bool active)
|
u32 changes, bool active)
|
||||||
|
@ -924,6 +983,32 @@ void iwl_mvm_block_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
iwl_mvm_exit_esr(mvm, vif, reason, link_to_keep);
|
iwl_mvm_exit_esr(mvm, vif, reason, link_to_keep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iwl_mvm_block_esr_sync(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
|
enum iwl_mvm_esr_state reason)
|
||||||
|
{
|
||||||
|
int primary_link = iwl_mvm_get_primary_link(vif);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!IWL_MVM_AUTO_EML_ENABLE || !ieee80211_vif_is_mld(vif))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* This should be called only with blocking reasons */
|
||||||
|
if (WARN_ON(!(reason & IWL_MVM_BLOCK_ESR_REASONS)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* leave ESR immediately, not only async with iwl_mvm_block_esr() */
|
||||||
|
ret = ieee80211_set_active_links(vif, BIT(primary_link));
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
mutex_lock(&mvm->mutex);
|
||||||
|
/* only additionally block for consistency and to avoid concurrency */
|
||||||
|
iwl_mvm_block_esr(mvm, vif, reason, primary_link);
|
||||||
|
mutex_unlock(&mvm->mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void iwl_mvm_esr_unblocked(struct iwl_mvm *mvm,
|
static void iwl_mvm_esr_unblocked(struct iwl_mvm *mvm,
|
||||||
struct ieee80211_vif *vif)
|
struct ieee80211_vif *vif)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4830,6 +4830,10 @@ int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||||
*/
|
*/
|
||||||
flush_work(&mvm->roc_done_wk);
|
flush_work(&mvm->roc_done_wk);
|
||||||
|
|
||||||
|
ret = iwl_mvm_esr_non_bss_link(mvm, vif, 0, true);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
mutex_lock(&mvm->mutex);
|
mutex_lock(&mvm->mutex);
|
||||||
|
|
||||||
switch (vif->type) {
|
switch (vif->type) {
|
||||||
|
@ -4873,9 +4877,7 @@ int iwl_mvm_cancel_roc(struct ieee80211_hw *hw,
|
||||||
|
|
||||||
IWL_DEBUG_MAC80211(mvm, "enter\n");
|
IWL_DEBUG_MAC80211(mvm, "enter\n");
|
||||||
|
|
||||||
mutex_lock(&mvm->mutex);
|
|
||||||
iwl_mvm_stop_roc(mvm, vif);
|
iwl_mvm_stop_roc(mvm, vif);
|
||||||
mutex_unlock(&mvm->mutex);
|
|
||||||
|
|
||||||
IWL_DEBUG_MAC80211(mvm, "leave\n");
|
IWL_DEBUG_MAC80211(mvm, "leave\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -391,6 +391,18 @@ static int iwl_mvm_mld_assign_vif_chanctx(struct ieee80211_hw *hw,
|
||||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* update EMLSR mode */
|
||||||
|
if (ieee80211_vif_type_p2p(vif) != NL80211_IFTYPE_STATION) {
|
||||||
|
ret = iwl_mvm_esr_non_bss_link(mvm, vif, link_conf->link_id,
|
||||||
|
true);
|
||||||
|
/*
|
||||||
|
* Don't activate this link if failed to exit EMLSR in
|
||||||
|
* the BSS interface
|
||||||
|
*/
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_lock(&mvm->mutex);
|
mutex_lock(&mvm->mutex);
|
||||||
ret = __iwl_mvm_mld_assign_vif_chanctx(mvm, vif, link_conf, ctx, false);
|
ret = __iwl_mvm_mld_assign_vif_chanctx(mvm, vif, link_conf, ctx, false);
|
||||||
mutex_unlock(&mvm->mutex);
|
mutex_unlock(&mvm->mutex);
|
||||||
|
@ -514,6 +526,10 @@ static void iwl_mvm_mld_unassign_vif_chanctx(struct ieee80211_hw *hw,
|
||||||
iwl_mvm_add_link(mvm, vif, link_conf);
|
iwl_mvm_add_link(mvm, vif, link_conf);
|
||||||
}
|
}
|
||||||
mutex_unlock(&mvm->mutex);
|
mutex_unlock(&mvm->mutex);
|
||||||
|
|
||||||
|
/* update EMLSR mode */
|
||||||
|
if (ieee80211_vif_type_p2p(vif) != NL80211_IFTYPE_STATION)
|
||||||
|
iwl_mvm_esr_non_bss_link(mvm, vif, link_conf->link_id, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -358,6 +358,7 @@ struct iwl_mvm_vif_link_info {
|
||||||
* @IWL_MVM_ESR_BLOCKED_WOWLAN: WOWLAN is preventing the enablement of EMLSR
|
* @IWL_MVM_ESR_BLOCKED_WOWLAN: WOWLAN is preventing the enablement of EMLSR
|
||||||
* @IWL_MVM_ESR_BLOCKED_TPT: block EMLSR when there is not enough traffic
|
* @IWL_MVM_ESR_BLOCKED_TPT: block EMLSR when there is not enough traffic
|
||||||
* @IWL_MVM_ESR_BLOCKED_FW: FW didn't recommended/forced exit from EMLSR
|
* @IWL_MVM_ESR_BLOCKED_FW: FW didn't recommended/forced exit from EMLSR
|
||||||
|
* @IWL_MVM_ESR_BLOCKED_NON_BSS: An active non-bssid link's preventing EMLSR
|
||||||
* @IWL_MVM_ESR_EXIT_MISSED_BEACON: exited EMLSR due to missed beacons
|
* @IWL_MVM_ESR_EXIT_MISSED_BEACON: exited EMLSR due to missed beacons
|
||||||
* @IWL_MVM_ESR_EXIT_LOW_RSSI: link is deactivated/not allowed for EMLSR
|
* @IWL_MVM_ESR_EXIT_LOW_RSSI: link is deactivated/not allowed for EMLSR
|
||||||
* due to low RSSI.
|
* due to low RSSI.
|
||||||
|
@ -372,6 +373,7 @@ enum iwl_mvm_esr_state {
|
||||||
IWL_MVM_ESR_BLOCKED_WOWLAN = 0x2,
|
IWL_MVM_ESR_BLOCKED_WOWLAN = 0x2,
|
||||||
IWL_MVM_ESR_BLOCKED_TPT = 0x4,
|
IWL_MVM_ESR_BLOCKED_TPT = 0x4,
|
||||||
IWL_MVM_ESR_BLOCKED_FW = 0x8,
|
IWL_MVM_ESR_BLOCKED_FW = 0x8,
|
||||||
|
IWL_MVM_ESR_BLOCKED_NON_BSS = 0x10,
|
||||||
IWL_MVM_ESR_EXIT_MISSED_BEACON = 0x10000,
|
IWL_MVM_ESR_EXIT_MISSED_BEACON = 0x10000,
|
||||||
IWL_MVM_ESR_EXIT_LOW_RSSI = 0x20000,
|
IWL_MVM_ESR_EXIT_LOW_RSSI = 0x20000,
|
||||||
IWL_MVM_ESR_EXIT_COEX = 0x40000,
|
IWL_MVM_ESR_EXIT_COEX = 0x40000,
|
||||||
|
@ -2888,6 +2890,8 @@ bool iwl_mvm_vif_has_esr_cap(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||||
void iwl_mvm_block_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
void iwl_mvm_block_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
enum iwl_mvm_esr_state reason,
|
enum iwl_mvm_esr_state reason,
|
||||||
u8 link_to_keep);
|
u8 link_to_keep);
|
||||||
|
int iwl_mvm_block_esr_sync(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
|
enum iwl_mvm_esr_state reason);
|
||||||
void iwl_mvm_unblock_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
void iwl_mvm_unblock_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
enum iwl_mvm_esr_state reason);
|
enum iwl_mvm_esr_state reason);
|
||||||
void iwl_mvm_exit_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
void iwl_mvm_exit_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
|
@ -2904,4 +2908,6 @@ iwl_mvm_bt_coex_calculate_esr_mode(struct iwl_mvm *mvm,
|
||||||
struct ieee80211_vif *vif,
|
struct ieee80211_vif *vif,
|
||||||
s32 link_rssi,
|
s32 link_rssi,
|
||||||
bool primary);
|
bool primary);
|
||||||
|
int iwl_mvm_esr_non_bss_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
|
unsigned int link_id, bool active);
|
||||||
#endif /* __IWL_MVM_H__ */
|
#endif /* __IWL_MVM_H__ */
|
||||||
|
|
|
@ -445,7 +445,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
|
||||||
struct iwl_channel_switch_error_notif),
|
struct iwl_channel_switch_error_notif),
|
||||||
|
|
||||||
RX_HANDLER_GRP(DATA_PATH_GROUP, ESR_MODE_NOTIF,
|
RX_HANDLER_GRP(DATA_PATH_GROUP, ESR_MODE_NOTIF,
|
||||||
iwl_mvm_rx_esr_mode_notif, RX_HANDLER_ASYNC_LOCKED,
|
iwl_mvm_rx_esr_mode_notif,
|
||||||
|
RX_HANDLER_ASYNC_LOCKED_WIPHY,
|
||||||
struct iwl_mvm_esr_mode_notif),
|
struct iwl_mvm_esr_mode_notif),
|
||||||
|
|
||||||
RX_HANDLER_GRP(DATA_PATH_GROUP, MONITOR_NOTIF,
|
RX_HANDLER_GRP(DATA_PATH_GROUP, MONITOR_NOTIF,
|
||||||
|
|
|
@ -47,6 +47,10 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
|
||||||
|
|
||||||
static void iwl_mvm_cleanup_roc(struct iwl_mvm *mvm)
|
static void iwl_mvm_cleanup_roc(struct iwl_mvm *mvm)
|
||||||
{
|
{
|
||||||
|
struct ieee80211_vif *vif = mvm->p2p_device_vif;
|
||||||
|
|
||||||
|
lockdep_assert_held(&mvm->mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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.
|
||||||
|
@ -70,9 +74,7 @@ static void iwl_mvm_cleanup_roc(struct iwl_mvm *mvm)
|
||||||
* not really racy.
|
* not really racy.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!WARN_ON(!mvm->p2p_device_vif)) {
|
if (!WARN_ON(!vif)) {
|
||||||
struct ieee80211_vif *vif = mvm->p2p_device_vif;
|
|
||||||
|
|
||||||
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||||
iwl_mvm_flush_sta(mvm, mvmvif->deflink.bcast_sta.sta_id,
|
iwl_mvm_flush_sta(mvm, mvmvif->deflink.bcast_sta.sta_id,
|
||||||
mvmvif->deflink.bcast_sta.tfd_queue_msk);
|
mvmvif->deflink.bcast_sta.tfd_queue_msk);
|
||||||
|
@ -106,6 +108,7 @@ static void iwl_mvm_cleanup_roc(struct iwl_mvm *mvm)
|
||||||
|
|
||||||
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);
|
||||||
|
mutex_unlock(&mvm->mutex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +118,10 @@ static void iwl_mvm_cleanup_roc(struct iwl_mvm *mvm)
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&mvm->mutex);
|
||||||
|
if (vif)
|
||||||
|
iwl_mvm_esr_non_bss_link(mvm, vif, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iwl_mvm_roc_done_wk(struct work_struct *wk)
|
void iwl_mvm_roc_done_wk(struct work_struct *wk)
|
||||||
|
@ -122,8 +129,8 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
|
||||||
struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, roc_done_wk);
|
struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, roc_done_wk);
|
||||||
|
|
||||||
mutex_lock(&mvm->mutex);
|
mutex_lock(&mvm->mutex);
|
||||||
|
/* Mutex is released inside */
|
||||||
iwl_mvm_cleanup_roc(mvm);
|
iwl_mvm_cleanup_roc(mvm);
|
||||||
mutex_unlock(&mvm->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
|
static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
|
||||||
|
@ -1220,6 +1227,8 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||||
struct iwl_mvm_vif *mvmvif;
|
struct iwl_mvm_vif *mvmvif;
|
||||||
struct iwl_mvm_time_event_data *te_data;
|
struct iwl_mvm_time_event_data *te_data;
|
||||||
|
|
||||||
|
mutex_lock(&mvm->mutex);
|
||||||
|
|
||||||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||||
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);
|
||||||
|
@ -1263,6 +1272,8 @@ cleanup_roc:
|
||||||
set_bit(vif->type == NL80211_IFTYPE_P2P_DEVICE ?
|
set_bit(vif->type == NL80211_IFTYPE_P2P_DEVICE ?
|
||||||
IWL_MVM_STATUS_ROC_RUNNING : IWL_MVM_STATUS_ROC_AUX_RUNNING,
|
IWL_MVM_STATUS_ROC_RUNNING : IWL_MVM_STATUS_ROC_AUX_RUNNING,
|
||||||
&mvm->status);
|
&mvm->status);
|
||||||
|
|
||||||
|
/* Mutex is released inside this function */
|
||||||
iwl_mvm_cleanup_roc(mvm);
|
iwl_mvm_cleanup_roc(mvm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue