aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-07-18 08:12:44 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-01-03 07:01:41 -0500
commitfaec12ee2dd92edc09f75aab3d8c5085102052c5 (patch)
tree81c5ed9cfc5778d6e34928de2ec8c7909295b2b3 /net
parentc82c4a80bbb9c8ffa1d783070a8caa37f2db45b6 (diff)
mac80211: split out aggregation TX removal
Create the function ieee80211_remove_tid_tx to call it from ___ieee80211_stop_tx_ba_session later. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/agg-tx.c48
1 files changed, 30 insertions, 18 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index e0656d77b313..101bbfba9c8d 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -713,6 +713,35 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
713} 713}
714EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); 714EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
715 715
716static void ieee80211_remove_tid_tx(struct sta_info *sta, int tid)
717{
718 struct tid_ampdu_tx *tid_tx;
719
720 lockdep_assert_held(&sta->ampdu_mlme.mtx);
721 lockdep_assert_held(&sta->lock);
722
723 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
724
725 /*
726 * When we get here, the TX path will not be lockless any more wrt.
727 * aggregation, since the OPERATIONAL bit has long been cleared.
728 * Thus it will block on getting the lock, if it occurs. So if we
729 * stop the queue now, we will not get any more packets, and any
730 * that might be being processed will wait for us here, thereby
731 * guaranteeing that no packets go to the tid_tx pending queue any
732 * more.
733 */
734
735 ieee80211_agg_splice_packets(sta->sdata, tid_tx, tid);
736
737 /* future packets must not find the tid_tx struct any more */
738 ieee80211_assign_tid_tx(sta, tid, NULL);
739
740 ieee80211_agg_splice_finish(sta->sdata, tid);
741
742 kfree_rcu(tid_tx, rcu_head);
743}
744
716void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) 745void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
717{ 746{
718 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 747 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
@@ -751,24 +780,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
751 ieee80211_send_delba(sta->sdata, ra, tid, 780 ieee80211_send_delba(sta->sdata, ra, tid,
752 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); 781 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
753 782
754 /* 783 ieee80211_remove_tid_tx(sta, tid);
755 * When we get here, the TX path will not be lockless any more wrt.
756 * aggregation, since the OPERATIONAL bit has long been cleared.
757 * Thus it will block on getting the lock, if it occurs. So if we
758 * stop the queue now, we will not get any more packets, and any
759 * that might be being processed will wait for us here, thereby
760 * guaranteeing that no packets go to the tid_tx pending queue any
761 * more.
762 */
763
764 ieee80211_agg_splice_packets(sta->sdata, tid_tx, tid);
765
766 /* future packets must not find the tid_tx struct any more */
767 ieee80211_assign_tid_tx(sta, tid, NULL);
768
769 ieee80211_agg_splice_finish(sta->sdata, tid);
770
771 kfree_rcu(tid_tx, rcu_head);
772 784
773 unlock_sta: 785 unlock_sta:
774 spin_unlock_bh(&sta->lock); 786 spin_unlock_bh(&sta->lock);