|
@@ -834,6 +834,34 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|
|
+ struct ieee80211_sta *sta, u16 tid)
|
|
|
+{
|
|
|
+ struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
|
|
|
+ struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
|
|
|
+ u16 txq_id;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * First set the agg state to OFF to avoid calling
|
|
|
+ * ieee80211_stop_tx_ba_cb in iwl_mvm_check_ratid_empty.
|
|
|
+ */
|
|
|
+ spin_lock_bh(&mvmsta->lock);
|
|
|
+ txq_id = tid_data->txq_id;
|
|
|
+ IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n",
|
|
|
+ mvmsta->sta_id, tid, txq_id, tid_data->state);
|
|
|
+ tid_data->state = IWL_AGG_OFF;
|
|
|
+ spin_unlock_bh(&mvmsta->lock);
|
|
|
+
|
|
|
+ if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
|
|
|
+ IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
|
|
|
+
|
|
|
+ iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
|
|
|
+ mvm->queue_to_mac80211[tid_data->txq_id] =
|
|
|
+ IWL_INVALID_MAC80211_QUEUE;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
|
|
|
{
|
|
|
int i;
|