diff mbox

[RFC,16/21] mac80211: defer RX agg session teardown to work

Message ID 20100607110202.012113320@sipsolutions.net (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Johannes Berg June 7, 2010, 11:01 a.m. UTC
None
diff mbox

Patch

--- wireless-testing.orig/net/mac80211/agg-rx.c	2010-06-06 15:30:23.000000000 +0200
+++ wireless-testing/net/mac80211/agg-rx.c	2010-06-06 15:43:50.000000000 +0200
@@ -32,21 +32,18 @@  static void ieee80211_free_tid_rx(struct
 	kfree(tid_rx);
 }
 
-static void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
-					    u16 initiator, u16 reason,
-					    bool from_timer)
+void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
+				     u16 initiator, u16 reason)
 {
 	struct ieee80211_local *local = sta->local;
 	struct tid_ampdu_rx *tid_rx;
 
-	spin_lock_bh(&sta->lock);
+	lockdep_assert_held(&sta->lock);
 
 	tid_rx = sta->ampdu_mlme.tid_rx[tid];
 
-	if (!tid_rx) {
-		spin_unlock_bh(&sta->lock);
+	if (!tid_rx)
 		return;
-	}
 
 	rcu_assign_pointer(sta->ampdu_mlme.tid_rx[tid], NULL);
 
@@ -65,10 +62,7 @@  static void ___ieee80211_stop_rx_ba_sess
 		ieee80211_send_delba(sta->sdata, sta->sta.addr,
 				     tid, 0, reason);
 
-	spin_unlock_bh(&sta->lock);
-
-	if (!from_timer)
-		del_timer_sync(&tid_rx->session_timer);
+	del_timer_sync(&tid_rx->session_timer);
 
 	call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx);
 }
@@ -76,7 +70,9 @@  static void ___ieee80211_stop_rx_ba_sess
 void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
 				    u16 initiator, u16 reason)
 {
-	___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, false);
+	spin_lock_bh(&sta->lock);
+	___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason);
+	spin_unlock_bh(&sta->lock);
 }
 
 /*
@@ -97,8 +93,8 @@  static void sta_rx_agg_session_timer_exp
 #ifdef CONFIG_MAC80211_HT_DEBUG
 	printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
 #endif
-	___ieee80211_stop_rx_ba_session(sta, *ptid, WLAN_BACK_RECIPIENT,
-					WLAN_REASON_QSTA_TIMEOUT, true);
+	set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired);
+	ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
 }
 
 static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
--- wireless-testing.orig/net/mac80211/ht.c	2010-06-06 15:30:23.000000000 +0200
+++ wireless-testing/net/mac80211/ht.c	2010-06-06 15:43:50.000000000 +0200
@@ -132,6 +132,11 @@  void ieee80211_ba_session_work(struct wo
 
 	spin_lock_bh(&sta->lock);
 	for (tid = 0; tid < STA_TID_NUM; tid++) {
+		if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired))
+			___ieee80211_stop_rx_ba_session(
+				sta, tid, WLAN_BACK_RECIPIENT,
+				WLAN_REASON_QSTA_TIMEOUT);
+
 		tid_tx = sta->ampdu_mlme.tid_tx[tid];
 		if (!tid_tx)
 			continue;
--- wireless-testing.orig/net/mac80211/sta_info.h	2010-06-06 15:30:23.000000000 +0200
+++ wireless-testing/net/mac80211/sta_info.h	2010-06-06 15:44:11.000000000 +0200
@@ -140,10 +140,13 @@  struct tid_ampdu_rx {
  * @addba_req_num: number of times addBA request has been sent.
  * @dialog_token_allocator: dialog token enumerator for each new session;
  * @work: work struct for starting/stopping aggregation
+ * @tid_rx_timer_expired: bitmap indicating on which TIDs the
+ *	RX timer expired until the work for it runs
  */
 struct sta_ampdu_mlme {
 	/* rx */
 	struct tid_ampdu_rx *tid_rx[STA_TID_NUM];
+	unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)];
 	/* tx */
 	struct work_struct work;
 	struct tid_ampdu_tx *tid_tx[STA_TID_NUM];
--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2010-06-06 15:30:23.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h	2010-06-06 15:43:49.000000000 +0200
@@ -1101,6 +1101,8 @@  int ieee80211_send_smps_action(struct ie
 			       enum ieee80211_smps_mode smps, const u8 *da,
 			       const u8 *bssid);
 
+void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
+				     u16 initiator, u16 reason);
 void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
 				    u16 initiator, u16 reason);
 void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta);