iwlwifi: mvm: implement mac80211's flush callback
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 24 Mar 2014 10:08:53 +0000 (12:08 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Tue, 6 May 2014 20:32:47 +0000 (23:32 +0300)
This allows mac80211 to flush the Tx queues before it sends
critical management frames.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/mvm/mac80211.c

index 3462624..6713b87 100644 (file)
@@ -2400,6 +2400,34 @@ out_unlock:
        mutex_unlock(&mvm->mutex);
 }
 
+static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
+                             struct ieee80211_vif *vif, u32 queues, bool drop)
+{
+       struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+       struct iwl_mvm_vif *mvmvif;
+       struct iwl_mvm_sta *mvmsta;
+
+       if (!vif || vif->type != NL80211_IFTYPE_STATION)
+               return;
+
+       mutex_lock(&mvm->mutex);
+       mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       mvmsta = iwl_mvm_sta_from_staid_protected(mvm, mvmvif->ap_sta_id);
+
+       if (WARN_ON_ONCE(!mvmsta))
+               goto done;
+
+       if (drop) {
+               if (iwl_mvm_flush_tx_path(mvm, mvmsta->tfd_queue_msk, true))
+                       IWL_ERR(mvm, "flush request fail\n");
+       } else {
+               iwl_trans_wait_tx_queue_empty(mvm->trans,
+                                             mvmsta->tfd_queue_msk);
+       }
+done:
+       mutex_unlock(&mvm->mutex);
+}
+
 const struct ieee80211_ops iwl_mvm_hw_ops = {
        .tx = iwl_mvm_mac_tx,
        .ampdu_action = iwl_mvm_mac_ampdu_action,
@@ -2423,6 +2451,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
        .sta_rc_update = iwl_mvm_sta_rc_update,
        .conf_tx = iwl_mvm_mac_conf_tx,
        .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
+       .flush = iwl_mvm_mac_flush,
        .sched_scan_start = iwl_mvm_mac_sched_scan_start,
        .sched_scan_stop = iwl_mvm_mac_sched_scan_stop,
        .set_key = iwl_mvm_mac_set_key,