@@ -256,6 +256,18 @@ 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.
*
@@ -307,8 +319,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
switch (te_data->vif->type) {
case NL80211_IFTYPE_P2P_DEVICE:
ieee80211_remain_on_channel_expired(mvm->hw);
- set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
- iwl_mvm_roc_finished(mvm);
+ iwl_mvm_p2p_roc_finished(mvm);
break;
case NL80211_IFTYPE_STATION:
/*
@@ -684,8 +695,7 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
/* Session protection is still ongoing. Cancel it */
iwl_mvm_cancel_session_protection(mvm, mvmvif, id);
if (iftype == NL80211_IFTYPE_P2P_DEVICE) {
- set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
- iwl_mvm_roc_finished(mvm);
+ iwl_mvm_p2p_roc_finished(mvm);
}
}
return false;
@@ -852,8 +862,7 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,
/* End TE, notify mac80211 */
mvmvif->time_event_data.id = SESSION_PROTECT_CONF_MAX_ID;
ieee80211_remain_on_channel_expired(mvm->hw);
- set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
- iwl_mvm_roc_finished(mvm);
+ iwl_mvm_p2p_roc_finished(mvm);
} else if (le32_to_cpu(notif->start)) {
if (WARN_ON(mvmvif->time_event_data.id !=
le32_to_cpu(notif->conf_id)))
@@ -1014,14 +1023,13 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
iwl_mvm_cancel_session_protection(mvm, mvmvif,
mvmvif->time_event_data.id);
- set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
+ iwl_mvm_p2p_roc_finished(mvm);
} else {
iwl_mvm_remove_aux_roc_te(mvm, mvmvif,
&mvmvif->time_event_data);
+ iwl_mvm_roc_finished(mvm);
}
- iwl_mvm_roc_finished(mvm);
-
return;
}
@@ -1035,12 +1043,11 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
- set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
+ iwl_mvm_p2p_roc_finished(mvm);
} else {
iwl_mvm_remove_aux_roc_te(mvm, mvmvif, te_data);
+ iwl_mvm_roc_finished(mvm);
}
-
- iwl_mvm_roc_finished(mvm);
}
void iwl_mvm_remove_csa_period(struct iwl_mvm *mvm,