]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
iwlwifi: mvm: flush queue before deleting ROC
authorJohannes Berg <johannes.berg@intel.com>
Mon, 13 Nov 2017 16:26:09 +0000 (17:26 +0100)
committerLuca Coelho <luciano.coelho@intel.com>
Tue, 5 Dec 2017 14:23:29 +0000 (16:23 +0200)
Before deleting a time event (remain-on-channel instance), flush
the queue so that frames cannot get stuck on it. We already flush
the AUX STA queues, but a separate station is used for the P2P
Device queue.

Cc: stable@vger.kernel.org
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c

index 6a9a25beab3fcdc3f372a541274bfc0046374280..55ab5349dd40d8b886373df6cb0715e977650309 100644 (file)
@@ -1061,6 +1061,7 @@ struct iwl_mvm {
  * @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running
  * @IWL_MVM_STATUS_D3_RECONFIG: D3 reconfiguration is being done
  * @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running
+ * @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA
  */
 enum iwl_mvm_status {
        IWL_MVM_STATUS_HW_RFKILL,
@@ -1072,6 +1073,7 @@ enum iwl_mvm_status {
        IWL_MVM_STATUS_ROC_AUX_RUNNING,
        IWL_MVM_STATUS_D3_RECONFIG,
        IWL_MVM_STATUS_FIRMWARE_RUNNING,
+       IWL_MVM_STATUS_NEED_FLUSH_P2P,
 };
 
 /* Keep track of completed init configuration */
index 4d0314912e94794b7728af17707618cd72ad2908..e25cda9fbf6c34d951b7441b40574bfb9c0a67b7 100644 (file)
@@ -132,6 +132,24 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
         * executed, and a new time event means a new command.
         */
        iwl_mvm_flush_sta(mvm, &mvm->aux_sta, true, CMD_ASYNC);
+
+       /* Do the same for the P2P device queue (STA) */
+       if (test_and_clear_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status)) {
+               struct iwl_mvm_vif *mvmvif;
+
+               /*
+                * 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
+                * flush of this work in iwl_mvm_prepare_mac_removal() so it's
+                * not really racy.
+                */
+
+               if (!WARN_ON(!mvm->p2p_device_vif)) {
+                       mvmvif = iwl_mvm_vif_from_mac80211(mvm->p2p_device_vif);
+                       iwl_mvm_flush_sta(mvm, &mvmvif->bcast_sta, true,
+                                         CMD_ASYNC);
+               }
+       }
 }
 
 static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
@@ -855,10 +873,12 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm)
 
        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);
-       else
+               set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
+       } else {
                iwl_mvm_remove_aux_roc_te(mvm, mvmvif, te_data);
+       }
 
        iwl_mvm_roc_finished(mvm);
 }