diff options
-rw-r--r-- | net/mac80211/agg-rx.c | 12 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 2 | ||||
-rw-r--r-- | net/mac80211/ht.c | 6 | ||||
-rw-r--r-- | net/mac80211/iface.c | 8 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 1 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 3 |
6 files changed, 21 insertions, 11 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index aa858a03951c..a843df26f384 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Copyright 2005-2006, Devicescape Software, Inc. | 6 | * Copyright 2005-2006, Devicescape Software, Inc. |
7 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 7 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> |
9 | * Copyright 2007-2008, Intel Corporation | 9 | * Copyright 2007-2010, Intel Corporation |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
@@ -38,7 +38,7 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
38 | struct ieee80211_local *local = sta->local; | 38 | struct ieee80211_local *local = sta->local; |
39 | struct tid_ampdu_rx *tid_rx; | 39 | struct tid_ampdu_rx *tid_rx; |
40 | 40 | ||
41 | lockdep_assert_held(&sta->lock); | 41 | lockdep_assert_held(&sta->ampdu_mlme.mtx); |
42 | 42 | ||
43 | tid_rx = sta->ampdu_mlme.tid_rx[tid]; | 43 | tid_rx = sta->ampdu_mlme.tid_rx[tid]; |
44 | 44 | ||
@@ -70,9 +70,9 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
70 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | 70 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, |
71 | u16 initiator, u16 reason) | 71 | u16 initiator, u16 reason) |
72 | { | 72 | { |
73 | spin_lock_bh(&sta->lock); | 73 | mutex_lock(&sta->ampdu_mlme.mtx); |
74 | ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason); | 74 | ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason); |
75 | spin_unlock_bh(&sta->lock); | 75 | mutex_unlock(&sta->ampdu_mlme.mtx); |
76 | } | 76 | } |
77 | 77 | ||
78 | /* | 78 | /* |
@@ -205,7 +205,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
205 | 205 | ||
206 | 206 | ||
207 | /* examine state machine */ | 207 | /* examine state machine */ |
208 | spin_lock_bh(&sta->lock); | 208 | mutex_lock(&sta->ampdu_mlme.mtx); |
209 | 209 | ||
210 | if (sta->ampdu_mlme.tid_rx[tid]) { | 210 | if (sta->ampdu_mlme.tid_rx[tid]) { |
211 | #ifdef CONFIG_MAC80211_HT_DEBUG | 211 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -279,7 +279,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
279 | mod_timer(&tid_agg_rx->session_timer, TU_TO_EXP_TIME(timeout)); | 279 | mod_timer(&tid_agg_rx->session_timer, TU_TO_EXP_TIME(timeout)); |
280 | 280 | ||
281 | end: | 281 | end: |
282 | spin_unlock_bh(&sta->lock); | 282 | mutex_unlock(&sta->ampdu_mlme.mtx); |
283 | 283 | ||
284 | end_no_lock: | 284 | end_no_lock: |
285 | ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid, | 285 | ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid, |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 7d18a3245e3d..e5e7ef175ca2 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -349,9 +349,11 @@ static inline int drv_ampdu_action(struct ieee80211_local *local, | |||
349 | u16 *ssn) | 349 | u16 *ssn) |
350 | { | 350 | { |
351 | int ret = -EOPNOTSUPP; | 351 | int ret = -EOPNOTSUPP; |
352 | local_bh_disable(); | ||
352 | if (local->ops->ampdu_action) | 353 | if (local->ops->ampdu_action) |
353 | ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action, | 354 | ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action, |
354 | sta, tid, ssn); | 355 | sta, tid, ssn); |
356 | local_bh_enable(); | ||
355 | trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, ret); | 357 | trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, ret); |
356 | return ret; | 358 | return ret; |
357 | } | 359 | } |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 730f8089678e..e29be64083c3 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -130,13 +130,17 @@ void ieee80211_ba_session_work(struct work_struct *work) | |||
130 | if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) | 130 | if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) |
131 | return; | 131 | return; |
132 | 132 | ||
133 | spin_lock_bh(&sta->lock); | 133 | mutex_lock(&sta->ampdu_mlme.mtx); |
134 | for (tid = 0; tid < STA_TID_NUM; tid++) { | 134 | for (tid = 0; tid < STA_TID_NUM; tid++) { |
135 | if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired)) | 135 | if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired)) |
136 | ___ieee80211_stop_rx_ba_session( | 136 | ___ieee80211_stop_rx_ba_session( |
137 | sta, tid, WLAN_BACK_RECIPIENT, | 137 | sta, tid, WLAN_BACK_RECIPIENT, |
138 | WLAN_REASON_QSTA_TIMEOUT); | 138 | WLAN_REASON_QSTA_TIMEOUT); |
139 | } | ||
140 | mutex_unlock(&sta->ampdu_mlme.mtx); | ||
139 | 141 | ||
142 | spin_lock_bh(&sta->lock); | ||
143 | for (tid = 0; tid < STA_TID_NUM; tid++) { | ||
140 | tid_tx = sta->ampdu_mlme.tid_tx[tid]; | 144 | tid_tx = sta->ampdu_mlme.tid_tx[tid]; |
141 | if (!tid_tx) | 145 | if (!tid_tx) |
142 | continue; | 146 | continue; |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 9f00d3f174e4..490be2f3af27 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -740,7 +740,7 @@ static void ieee80211_iface_work(struct work_struct *work) | |||
740 | mgmt->u.action.category == WLAN_CATEGORY_BACK) { | 740 | mgmt->u.action.category == WLAN_CATEGORY_BACK) { |
741 | int len = skb->len; | 741 | int len = skb->len; |
742 | 742 | ||
743 | rcu_read_lock(); | 743 | mutex_lock(&local->sta_mtx); |
744 | sta = sta_info_get(sdata, mgmt->sa); | 744 | sta = sta_info_get(sdata, mgmt->sa); |
745 | if (sta) { | 745 | if (sta) { |
746 | switch (mgmt->u.action.u.addba_req.action_code) { | 746 | switch (mgmt->u.action.u.addba_req.action_code) { |
@@ -761,7 +761,7 @@ static void ieee80211_iface_work(struct work_struct *work) | |||
761 | break; | 761 | break; |
762 | } | 762 | } |
763 | } | 763 | } |
764 | rcu_read_unlock(); | 764 | mutex_unlock(&local->sta_mtx); |
765 | } else if (ieee80211_is_data_qos(mgmt->frame_control)) { | 765 | } else if (ieee80211_is_data_qos(mgmt->frame_control)) { |
766 | struct ieee80211_hdr *hdr = (void *)mgmt; | 766 | struct ieee80211_hdr *hdr = (void *)mgmt; |
767 | /* | 767 | /* |
@@ -781,7 +781,7 @@ static void ieee80211_iface_work(struct work_struct *work) | |||
781 | * a block-ack session was active. That cannot be | 781 | * a block-ack session was active. That cannot be |
782 | * right, so terminate the session. | 782 | * right, so terminate the session. |
783 | */ | 783 | */ |
784 | rcu_read_lock(); | 784 | mutex_lock(&local->sta_mtx); |
785 | sta = sta_info_get(sdata, mgmt->sa); | 785 | sta = sta_info_get(sdata, mgmt->sa); |
786 | if (sta) { | 786 | if (sta) { |
787 | u16 tid = *ieee80211_get_qos_ctl(hdr) & | 787 | u16 tid = *ieee80211_get_qos_ctl(hdr) & |
@@ -791,7 +791,7 @@ static void ieee80211_iface_work(struct work_struct *work) | |||
791 | sta, tid, WLAN_BACK_RECIPIENT, | 791 | sta, tid, WLAN_BACK_RECIPIENT, |
792 | WLAN_REASON_QSTA_REQUIRE_SETUP); | 792 | WLAN_REASON_QSTA_REQUIRE_SETUP); |
793 | } | 793 | } |
794 | rcu_read_unlock(); | 794 | mutex_unlock(&local->sta_mtx); |
795 | } else switch (sdata->vif.type) { | 795 | } else switch (sdata->vif.type) { |
796 | case NL80211_IFTYPE_STATION: | 796 | case NL80211_IFTYPE_STATION: |
797 | ieee80211_sta_rx_queued_mgmt(sdata, skb); | 797 | ieee80211_sta_rx_queued_mgmt(sdata, skb); |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index bd726c6204df..f54d8ba7d788 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -236,6 +236,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
236 | spin_lock_init(&sta->flaglock); | 236 | spin_lock_init(&sta->flaglock); |
237 | INIT_WORK(&sta->drv_unblock_wk, sta_unblock); | 237 | INIT_WORK(&sta->drv_unblock_wk, sta_unblock); |
238 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); | 238 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); |
239 | mutex_init(&sta->ampdu_mlme.mtx); | ||
239 | 240 | ||
240 | memcpy(sta->sta.addr, addr, ETH_ALEN); | 241 | memcpy(sta->sta.addr, addr, ETH_ALEN); |
241 | sta->local = local; | 242 | sta->local = local; |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 500bafe0a0bb..10d0fcb417ae 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -142,8 +142,11 @@ struct tid_ampdu_rx { | |||
142 | * @work: work struct for starting/stopping aggregation | 142 | * @work: work struct for starting/stopping aggregation |
143 | * @tid_rx_timer_expired: bitmap indicating on which TIDs the | 143 | * @tid_rx_timer_expired: bitmap indicating on which TIDs the |
144 | * RX timer expired until the work for it runs | 144 | * RX timer expired until the work for it runs |
145 | * @mtx: mutex to protect all TX data (except non-NULL assignments | ||
146 | * to tid_tx[idx], which are protected by the sta spinlock) | ||
145 | */ | 147 | */ |
146 | struct sta_ampdu_mlme { | 148 | struct sta_ampdu_mlme { |
149 | struct mutex mtx; | ||
147 | /* rx */ | 150 | /* rx */ |
148 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; | 151 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; |
149 | unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)]; | 152 | unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)]; |