aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/agg-rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-06-10 04:21:44 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-14 15:39:28 -0400
commit7c3b1dd8f483bf4bcb9776cd9cd3b37dd327d7ea (patch)
treeb5e42cc6f18b80c1036d0b9e5590d171fa84d074 /net/mac80211/agg-rx.c
parent67c282c00c9c06733aae229662d209957f6d23a7 (diff)
mac80211: defer RX agg session teardown to work
Since we want the code to be able to sleep in the future, it must not be called from the timer directly. To prepare, move it out into the aggregation work. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/agg-rx.c')
-rw-r--r--net/mac80211/agg-rx.c24
1 files changed, 10 insertions, 14 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index bbf36d980232..1c4320b01e3c 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -32,21 +32,18 @@ static void ieee80211_free_tid_rx(struct rcu_head *h)
32 kfree(tid_rx); 32 kfree(tid_rx);
33} 33}
34 34
35static void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 35void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
36 u16 initiator, u16 reason, 36 u16 initiator, u16 reason)
37 bool from_timer)
38{ 37{
39 struct ieee80211_local *local = sta->local; 38 struct ieee80211_local *local = sta->local;
40 struct tid_ampdu_rx *tid_rx; 39 struct tid_ampdu_rx *tid_rx;
41 40
42 spin_lock_bh(&sta->lock); 41 lockdep_assert_held(&sta->lock);
43 42
44 tid_rx = sta->ampdu_mlme.tid_rx[tid]; 43 tid_rx = sta->ampdu_mlme.tid_rx[tid];
45 44
46 if (!tid_rx) { 45 if (!tid_rx)
47 spin_unlock_bh(&sta->lock);
48 return; 46 return;
49 }
50 47
51 rcu_assign_pointer(sta->ampdu_mlme.tid_rx[tid], NULL); 48 rcu_assign_pointer(sta->ampdu_mlme.tid_rx[tid], NULL);
52 49
@@ -65,10 +62,7 @@ static void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
65 ieee80211_send_delba(sta->sdata, sta->sta.addr, 62 ieee80211_send_delba(sta->sdata, sta->sta.addr,
66 tid, 0, reason); 63 tid, 0, reason);
67 64
68 spin_unlock_bh(&sta->lock); 65 del_timer_sync(&tid_rx->session_timer);
69
70 if (!from_timer)
71 del_timer_sync(&tid_rx->session_timer);
72 66
73 call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx); 67 call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx);
74} 68}
@@ -76,7 +70,9 @@ static void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
76void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 70void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
77 u16 initiator, u16 reason) 71 u16 initiator, u16 reason)
78{ 72{
79 ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, false); 73 spin_lock_bh(&sta->lock);
74 ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason);
75 spin_unlock_bh(&sta->lock);
80} 76}
81 77
82/* 78/*
@@ -97,8 +93,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
97#ifdef CONFIG_MAC80211_HT_DEBUG 93#ifdef CONFIG_MAC80211_HT_DEBUG
98 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); 94 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
99#endif 95#endif
100 ___ieee80211_stop_rx_ba_session(sta, *ptid, WLAN_BACK_RECIPIENT, 96 set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired);
101 WLAN_REASON_QSTA_TIMEOUT, true); 97 ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
102} 98}
103 99
104static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, 100static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,