aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-05-02 19:02:02 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-14 16:29:34 -0400
commit07346f81e87d6e4cca7ae9adfa711d0c61c87b56 (patch)
tree237450c49843e0e19afc79356240a891da64d9fa
parent3434fbd39862d471c92b66c28cd449deea8e9f90 (diff)
mac80211: proper STA info locking
As discussed earlier, we can unify locking in struct sta_info and use just a single spinlock protecting all members of the structure that need protection. Many don't, but one of the especially bad ones is the 'flags' member that can currently be clobbered when RX and TX is being processed on different CPUs at the same time. Because having four spinlocks for different, mostly exclusive parts of a single structure is overkill, this patch also kills the ampdu and mesh plink spinlocks and uses just a single one for everything. Because none of the spinlocks are nested, this is safe. It remains to be seen whether or not we should make the sta flags use atomic bit operations instead, for now though this is a safe thing and using atomic operations instead will be very simple using the new static inline functions this patch introduces for accessing sta->flags. Since spin_lock_bh() is used with this lock, there shouldn't be any contention even if aggregation is enabled at around the same time as both requires frame transmission/reception which is in a bh context. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Cc: Tomas Winkler <tomasw@gmail.com> Cc: Ron Rindjunsky <ron.rindjunsky@intel.com> Cc: Luis Carlos Cobo <luisca@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.c4
-rw-r--r--net/mac80211/cfg.c2
-rw-r--r--net/mac80211/debugfs_sta.c15
-rw-r--r--net/mac80211/key.c4
-rw-r--r--net/mac80211/main.c31
-rw-r--r--net/mac80211/mesh_plink.c88
-rw-r--r--net/mac80211/mlme.c38
-rw-r--r--net/mac80211/rx.c17
-rw-r--r--net/mac80211/sta_info.c14
-rw-r--r--net/mac80211/sta_info.h72
-rw-r--r--net/mac80211/tx.c21
11 files changed, 181 insertions, 125 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 67356d9a0c59..e3444c4ea1a5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -360,9 +360,9 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
360 unsigned long state; 360 unsigned long state;
361 DECLARE_MAC_BUF(mac); 361 DECLARE_MAC_BUF(mac);
362 362
363 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 363 spin_lock_bh(&sta->lock);
364 state = sta->ampdu_mlme.tid_state_tx[tid]; 364 state = sta->ampdu_mlme.tid_state_tx[tid];
365 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 365 spin_unlock_bh(&sta->lock);
366 366
367 if (state == HT_AGG_STATE_IDLE && 367 if (state == HT_AGG_STATE_IDLE &&
368 rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { 368 rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 699d97b8de5e..3cef80dcd0e5 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -602,6 +602,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
602 */ 602 */
603 603
604 if (params->station_flags & STATION_FLAG_CHANGED) { 604 if (params->station_flags & STATION_FLAG_CHANGED) {
605 spin_lock_bh(&sta->lock);
605 sta->flags &= ~WLAN_STA_AUTHORIZED; 606 sta->flags &= ~WLAN_STA_AUTHORIZED;
606 if (params->station_flags & STATION_FLAG_AUTHORIZED) 607 if (params->station_flags & STATION_FLAG_AUTHORIZED)
607 sta->flags |= WLAN_STA_AUTHORIZED; 608 sta->flags |= WLAN_STA_AUTHORIZED;
@@ -613,6 +614,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
613 sta->flags &= ~WLAN_STA_WME; 614 sta->flags &= ~WLAN_STA_WME;
614 if (params->station_flags & STATION_FLAG_WME) 615 if (params->station_flags & STATION_FLAG_WME)
615 sta->flags |= WLAN_STA_WME; 616 sta->flags |= WLAN_STA_WME;
617 spin_unlock_bh(&sta->lock);
616 } 618 }
617 619
618 /* 620 /*
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 676a93202ff9..1f00273d99c2 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -74,14 +74,15 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
74{ 74{
75 char buf[100]; 75 char buf[100];
76 struct sta_info *sta = file->private_data; 76 struct sta_info *sta = file->private_data;
77 u32 staflags = get_sta_flags(sta);
77 int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s", 78 int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s",
78 sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "", 79 staflags & WLAN_STA_AUTH ? "AUTH\n" : "",
79 sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "", 80 staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
80 sta->flags & WLAN_STA_PS ? "PS\n" : "", 81 staflags & WLAN_STA_PS ? "PS\n" : "",
81 sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", 82 staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
82 sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", 83 staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
83 sta->flags & WLAN_STA_WME ? "WME\n" : "", 84 staflags & WLAN_STA_WME ? "WME\n" : "",
84 sta->flags & WLAN_STA_WDS ? "WDS\n" : ""); 85 staflags & WLAN_STA_WDS ? "WDS\n" : "");
85 return simple_read_from_buffer(userbuf, count, ppos, buf, res); 86 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
86} 87}
87STA_OPS(flags); 88STA_OPS(flags);
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 88b211af7c1f..d4893bd17754 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -321,7 +321,7 @@ void ieee80211_key_link(struct ieee80211_key *key,
321 * some hardware cannot handle TKIP with QoS, so 321 * some hardware cannot handle TKIP with QoS, so
322 * we indicate whether QoS could be in use. 322 * we indicate whether QoS could be in use.
323 */ 323 */
324 if (sta->flags & WLAN_STA_WME) 324 if (test_sta_flags(sta, WLAN_STA_WME))
325 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; 325 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
326 326
327 /* 327 /*
@@ -342,7 +342,7 @@ void ieee80211_key_link(struct ieee80211_key *key,
342 /* same here, the AP could be using QoS */ 342 /* same here, the AP could be using QoS */
343 ap = sta_info_get(key->local, key->sdata->u.sta.bssid); 343 ap = sta_info_get(key->local, key->sdata->u.sta.bssid);
344 if (ap) { 344 if (ap) {
345 if (ap->flags & WLAN_STA_WME) 345 if (test_sta_flags(ap, WLAN_STA_WME))
346 key->conf.flags |= 346 key->conf.flags |=
347 IEEE80211_KEY_FLAG_WMM_STA; 347 IEEE80211_KEY_FLAG_WMM_STA;
348 } 348 }
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 55e76117da9e..f277407f0f5a 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -346,6 +346,7 @@ static int ieee80211_open(struct net_device *dev)
346 goto err_del_interface; 346 goto err_del_interface;
347 } 347 }
348 348
349 /* no locking required since STA is not live yet */
349 sta->flags |= WLAN_STA_AUTHORIZED; 350 sta->flags |= WLAN_STA_AUTHORIZED;
350 351
351 res = sta_info_insert(sta); 352 res = sta_info_insert(sta);
@@ -588,7 +589,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
588 return -ENOENT; 589 return -ENOENT;
589 } 590 }
590 591
591 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 592 spin_lock_bh(&sta->lock);
592 593
593 /* we have tried too many times, receiver does not want A-MPDU */ 594 /* we have tried too many times, receiver does not want A-MPDU */
594 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { 595 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
@@ -691,7 +692,7 @@ start_ba_err:
691 spin_unlock_bh(&local->mdev->queue_lock); 692 spin_unlock_bh(&local->mdev->queue_lock);
692 ret = -EBUSY; 693 ret = -EBUSY;
693start_ba_exit: 694start_ba_exit:
694 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 695 spin_unlock_bh(&sta->lock);
695 rcu_read_unlock(); 696 rcu_read_unlock();
696 return ret; 697 return ret;
697} 698}
@@ -719,7 +720,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
719 720
720 /* check if the TID is in aggregation */ 721 /* check if the TID is in aggregation */
721 state = &sta->ampdu_mlme.tid_state_tx[tid]; 722 state = &sta->ampdu_mlme.tid_state_tx[tid];
722 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 723 spin_lock_bh(&sta->lock);
723 724
724 if (*state != HT_AGG_STATE_OPERATIONAL) { 725 if (*state != HT_AGG_STATE_OPERATIONAL) {
725 ret = -ENOENT; 726 ret = -ENOENT;
@@ -749,7 +750,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
749 } 750 }
750 751
751stop_BA_exit: 752stop_BA_exit:
752 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 753 spin_unlock_bh(&sta->lock);
753 rcu_read_unlock(); 754 rcu_read_unlock();
754 return ret; 755 return ret;
755} 756}
@@ -778,12 +779,12 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
778 } 779 }
779 780
780 state = &sta->ampdu_mlme.tid_state_tx[tid]; 781 state = &sta->ampdu_mlme.tid_state_tx[tid];
781 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 782 spin_lock_bh(&sta->lock);
782 783
783 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 784 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
784 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", 785 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
785 *state); 786 *state);
786 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 787 spin_unlock_bh(&sta->lock);
787 rcu_read_unlock(); 788 rcu_read_unlock();
788 return; 789 return;
789 } 790 }
@@ -796,7 +797,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
796 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); 797 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
797 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 798 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
798 } 799 }
799 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 800 spin_unlock_bh(&sta->lock);
800 rcu_read_unlock(); 801 rcu_read_unlock();
801} 802}
802EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); 803EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
@@ -830,10 +831,10 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
830 } 831 }
831 state = &sta->ampdu_mlme.tid_state_tx[tid]; 832 state = &sta->ampdu_mlme.tid_state_tx[tid];
832 833
833 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 834 spin_lock_bh(&sta->lock);
834 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { 835 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
835 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); 836 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
836 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 837 spin_unlock_bh(&sta->lock);
837 rcu_read_unlock(); 838 rcu_read_unlock();
838 return; 839 return;
839 } 840 }
@@ -860,7 +861,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
860 sta->ampdu_mlme.addba_req_num[tid] = 0; 861 sta->ampdu_mlme.addba_req_num[tid] = 0;
861 kfree(sta->ampdu_mlme.tid_tx[tid]); 862 kfree(sta->ampdu_mlme.tid_tx[tid]);
862 sta->ampdu_mlme.tid_tx[tid] = NULL; 863 sta->ampdu_mlme.tid_tx[tid] = NULL;
863 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 864 spin_unlock_bh(&sta->lock);
864 865
865 rcu_read_unlock(); 866 rcu_read_unlock();
866} 867}
@@ -1315,7 +1316,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
1315 * packet. If the STA went to power save mode, this will happen 1316 * packet. If the STA went to power save mode, this will happen
1316 * happen when it wakes up for the next time. 1317 * happen when it wakes up for the next time.
1317 */ 1318 */
1318 sta->flags |= WLAN_STA_CLEAR_PS_FILT; 1319 set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT);
1319 1320
1320 /* 1321 /*
1321 * This code races in the following way: 1322 * This code races in the following way:
@@ -1347,7 +1348,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
1347 * can be unknown, for example with different interrupt status 1348 * can be unknown, for example with different interrupt status
1348 * bits. 1349 * bits.
1349 */ 1350 */
1350 if (sta->flags & WLAN_STA_PS && 1351 if (test_sta_flags(sta, WLAN_STA_PS) &&
1351 skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { 1352 skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) {
1352 ieee80211_remove_tx_extra(local, sta->key, skb, 1353 ieee80211_remove_tx_extra(local, sta->key, skb,
1353 &status->control); 1354 &status->control);
@@ -1355,7 +1356,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
1355 return; 1356 return;
1356 } 1357 }
1357 1358
1358 if (!(sta->flags & WLAN_STA_PS) && 1359 if (!test_sta_flags(sta, WLAN_STA_PS) &&
1359 !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { 1360 !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) {
1360 /* Software retry the packet once */ 1361 /* Software retry the packet once */
1361 status->control.flags |= IEEE80211_TXCTL_REQUEUE; 1362 status->control.flags |= IEEE80211_TXCTL_REQUEUE;
@@ -1370,7 +1371,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
1370 "queue_len=%d PS=%d @%lu\n", 1371 "queue_len=%d PS=%d @%lu\n",
1371 wiphy_name(local->hw.wiphy), 1372 wiphy_name(local->hw.wiphy),
1372 skb_queue_len(&sta->tx_filtered), 1373 skb_queue_len(&sta->tx_filtered),
1373 !!(sta->flags & WLAN_STA_PS), jiffies); 1374 !!test_sta_flags(sta, WLAN_STA_PS), jiffies);
1374 dev_kfree_skb(skb); 1375 dev_kfree_skb(skb);
1375} 1376}
1376 1377
@@ -1399,7 +1400,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
1399 struct sta_info *sta; 1400 struct sta_info *sta;
1400 sta = sta_info_get(local, hdr->addr1); 1401 sta = sta_info_get(local, hdr->addr1);
1401 if (sta) { 1402 if (sta) {
1402 if (sta->flags & WLAN_STA_PS) { 1403 if (test_sta_flags(sta, WLAN_STA_PS)) {
1403 /* 1404 /*
1404 * The STA is in power save mode, so assume 1405 * The STA is in power save mode, so assume
1405 * that this TX packet failed because of that. 1406 * that this TX packet failed because of that.
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 37f0c2b94ae7..9efeb1f07025 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -79,7 +79,7 @@ void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
79 * 79 *
80 * @sta: mes peer link to restart 80 * @sta: mes peer link to restart
81 * 81 *
82 * Locking: this function must be called holding sta->plink_lock 82 * Locking: this function must be called holding sta->lock
83 */ 83 */
84static inline void mesh_plink_fsm_restart(struct sta_info *sta) 84static inline void mesh_plink_fsm_restart(struct sta_info *sta)
85{ 85{
@@ -105,7 +105,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
105 if (!sta) 105 if (!sta)
106 return NULL; 106 return NULL;
107 107
108 sta->flags |= WLAN_STA_AUTHORIZED; 108 sta->flags = WLAN_STA_AUTHORIZED;
109 sta->supp_rates[local->hw.conf.channel->band] = rates; 109 sta->supp_rates[local->hw.conf.channel->band] = rates;
110 110
111 return sta; 111 return sta;
@@ -118,7 +118,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
118 * 118 *
119 * All mesh paths with this peer as next hop will be flushed 119 * All mesh paths with this peer as next hop will be flushed
120 * 120 *
121 * Locking: the caller must hold sta->plink_lock 121 * Locking: the caller must hold sta->lock
122 */ 122 */
123static void __mesh_plink_deactivate(struct sta_info *sta) 123static void __mesh_plink_deactivate(struct sta_info *sta)
124{ 124{
@@ -139,9 +139,9 @@ static void __mesh_plink_deactivate(struct sta_info *sta)
139 */ 139 */
140void mesh_plink_deactivate(struct sta_info *sta) 140void mesh_plink_deactivate(struct sta_info *sta)
141{ 141{
142 spin_lock_bh(&sta->plink_lock); 142 spin_lock_bh(&sta->lock);
143 __mesh_plink_deactivate(sta); 143 __mesh_plink_deactivate(sta);
144 spin_unlock_bh(&sta->plink_lock); 144 spin_unlock_bh(&sta->lock);
145} 145}
146 146
147static int mesh_plink_frame_tx(struct net_device *dev, 147static int mesh_plink_frame_tx(struct net_device *dev,
@@ -270,10 +270,10 @@ static void mesh_plink_timer(unsigned long data)
270 */ 270 */
271 sta = (struct sta_info *) data; 271 sta = (struct sta_info *) data;
272 272
273 spin_lock_bh(&sta->plink_lock); 273 spin_lock_bh(&sta->lock);
274 if (sta->ignore_plink_timer) { 274 if (sta->ignore_plink_timer) {
275 sta->ignore_plink_timer = false; 275 sta->ignore_plink_timer = false;
276 spin_unlock_bh(&sta->plink_lock); 276 spin_unlock_bh(&sta->lock);
277 return; 277 return;
278 } 278 }
279 mpl_dbg("Mesh plink timer for %s fired on state %d\n", 279 mpl_dbg("Mesh plink timer for %s fired on state %d\n",
@@ -298,7 +298,7 @@ static void mesh_plink_timer(unsigned long data)
298 rand % sta->plink_timeout; 298 rand % sta->plink_timeout;
299 ++sta->plink_retries; 299 ++sta->plink_retries;
300 mod_plink_timer(sta, sta->plink_timeout); 300 mod_plink_timer(sta, sta->plink_timeout);
301 spin_unlock_bh(&sta->plink_lock); 301 spin_unlock_bh(&sta->lock);
302 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, 302 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
303 0, 0); 303 0, 0);
304 break; 304 break;
@@ -311,7 +311,7 @@ static void mesh_plink_timer(unsigned long data)
311 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); 311 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
312 sta->plink_state = PLINK_HOLDING; 312 sta->plink_state = PLINK_HOLDING;
313 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 313 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
314 spin_unlock_bh(&sta->plink_lock); 314 spin_unlock_bh(&sta->lock);
315 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid, 315 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid,
316 reason); 316 reason);
317 break; 317 break;
@@ -319,10 +319,10 @@ static void mesh_plink_timer(unsigned long data)
319 /* holding timer */ 319 /* holding timer */
320 del_timer(&sta->plink_timer); 320 del_timer(&sta->plink_timer);
321 mesh_plink_fsm_restart(sta); 321 mesh_plink_fsm_restart(sta);
322 spin_unlock_bh(&sta->plink_lock); 322 spin_unlock_bh(&sta->lock);
323 break; 323 break;
324 default: 324 default:
325 spin_unlock_bh(&sta->plink_lock); 325 spin_unlock_bh(&sta->lock);
326 break; 326 break;
327 } 327 }
328} 328}
@@ -344,16 +344,16 @@ int mesh_plink_open(struct sta_info *sta)
344 DECLARE_MAC_BUF(mac); 344 DECLARE_MAC_BUF(mac);
345#endif 345#endif
346 346
347 spin_lock_bh(&sta->plink_lock); 347 spin_lock_bh(&sta->lock);
348 get_random_bytes(&llid, 2); 348 get_random_bytes(&llid, 2);
349 sta->llid = llid; 349 sta->llid = llid;
350 if (sta->plink_state != PLINK_LISTEN) { 350 if (sta->plink_state != PLINK_LISTEN) {
351 spin_unlock_bh(&sta->plink_lock); 351 spin_unlock_bh(&sta->lock);
352 return -EBUSY; 352 return -EBUSY;
353 } 353 }
354 sta->plink_state = PLINK_OPN_SNT; 354 sta->plink_state = PLINK_OPN_SNT;
355 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 355 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
356 spin_unlock_bh(&sta->plink_lock); 356 spin_unlock_bh(&sta->lock);
357 mpl_dbg("Mesh plink: starting establishment with %s\n", 357 mpl_dbg("Mesh plink: starting establishment with %s\n",
358 print_mac(mac, sta->addr)); 358 print_mac(mac, sta->addr));
359 359
@@ -367,10 +367,10 @@ void mesh_plink_block(struct sta_info *sta)
367 DECLARE_MAC_BUF(mac); 367 DECLARE_MAC_BUF(mac);
368#endif 368#endif
369 369
370 spin_lock_bh(&sta->plink_lock); 370 spin_lock_bh(&sta->lock);
371 __mesh_plink_deactivate(sta); 371 __mesh_plink_deactivate(sta);
372 sta->plink_state = PLINK_BLOCKED; 372 sta->plink_state = PLINK_BLOCKED;
373 spin_unlock_bh(&sta->plink_lock); 373 spin_unlock_bh(&sta->lock);
374} 374}
375 375
376int mesh_plink_close(struct sta_info *sta) 376int mesh_plink_close(struct sta_info *sta)
@@ -383,14 +383,14 @@ int mesh_plink_close(struct sta_info *sta)
383 383
384 mpl_dbg("Mesh plink: closing link with %s\n", 384 mpl_dbg("Mesh plink: closing link with %s\n",
385 print_mac(mac, sta->addr)); 385 print_mac(mac, sta->addr));
386 spin_lock_bh(&sta->plink_lock); 386 spin_lock_bh(&sta->lock);
387 sta->reason = cpu_to_le16(MESH_LINK_CANCELLED); 387 sta->reason = cpu_to_le16(MESH_LINK_CANCELLED);
388 reason = sta->reason; 388 reason = sta->reason;
389 389
390 if (sta->plink_state == PLINK_LISTEN || 390 if (sta->plink_state == PLINK_LISTEN ||
391 sta->plink_state == PLINK_BLOCKED) { 391 sta->plink_state == PLINK_BLOCKED) {
392 mesh_plink_fsm_restart(sta); 392 mesh_plink_fsm_restart(sta);
393 spin_unlock_bh(&sta->plink_lock); 393 spin_unlock_bh(&sta->lock);
394 return 0; 394 return 0;
395 } else if (sta->plink_state == PLINK_ESTAB) { 395 } else if (sta->plink_state == PLINK_ESTAB) {
396 __mesh_plink_deactivate(sta); 396 __mesh_plink_deactivate(sta);
@@ -402,7 +402,7 @@ int mesh_plink_close(struct sta_info *sta)
402 sta->plink_state = PLINK_HOLDING; 402 sta->plink_state = PLINK_HOLDING;
403 llid = sta->llid; 403 llid = sta->llid;
404 plid = sta->plid; 404 plid = sta->plid;
405 spin_unlock_bh(&sta->plink_lock); 405 spin_unlock_bh(&sta->lock);
406 mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid, 406 mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid,
407 plid, reason); 407 plid, reason);
408 return 0; 408 return 0;
@@ -490,7 +490,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
490 /* avoid warning */ 490 /* avoid warning */
491 break; 491 break;
492 } 492 }
493 spin_lock_bh(&sta->plink_lock); 493 spin_lock_bh(&sta->lock);
494 } else if (!sta) { 494 } else if (!sta) {
495 /* ftype == PLINK_OPEN */ 495 /* ftype == PLINK_OPEN */
496 u64 rates; 496 u64 rates;
@@ -512,9 +512,9 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
512 return; 512 return;
513 } 513 }
514 event = OPN_ACPT; 514 event = OPN_ACPT;
515 spin_lock_bh(&sta->plink_lock); 515 spin_lock_bh(&sta->lock);
516 } else { 516 } else {
517 spin_lock_bh(&sta->plink_lock); 517 spin_lock_bh(&sta->lock);
518 switch (ftype) { 518 switch (ftype) {
519 case PLINK_OPEN: 519 case PLINK_OPEN:
520 if (!mesh_plink_free_count(sdata) || 520 if (!mesh_plink_free_count(sdata) ||
@@ -551,7 +551,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
551 break; 551 break;
552 default: 552 default:
553 mpl_dbg("Mesh plink: unknown frame subtype\n"); 553 mpl_dbg("Mesh plink: unknown frame subtype\n");
554 spin_unlock_bh(&sta->plink_lock); 554 spin_unlock_bh(&sta->lock);
555 rcu_read_unlock(); 555 rcu_read_unlock();
556 return; 556 return;
557 } 557 }
@@ -568,7 +568,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
568 switch (event) { 568 switch (event) {
569 case CLS_ACPT: 569 case CLS_ACPT:
570 mesh_plink_fsm_restart(sta); 570 mesh_plink_fsm_restart(sta);
571 spin_unlock_bh(&sta->plink_lock); 571 spin_unlock_bh(&sta->lock);
572 break; 572 break;
573 case OPN_ACPT: 573 case OPN_ACPT:
574 sta->plink_state = PLINK_OPN_RCVD; 574 sta->plink_state = PLINK_OPN_RCVD;
@@ -576,14 +576,14 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
576 get_random_bytes(&llid, 2); 576 get_random_bytes(&llid, 2);
577 sta->llid = llid; 577 sta->llid = llid;
578 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 578 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
579 spin_unlock_bh(&sta->plink_lock); 579 spin_unlock_bh(&sta->lock);
580 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, 580 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
581 0, 0); 581 0, 0);
582 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, 582 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr,
583 llid, plid, 0); 583 llid, plid, 0);
584 break; 584 break;
585 default: 585 default:
586 spin_unlock_bh(&sta->plink_lock); 586 spin_unlock_bh(&sta->lock);
587 break; 587 break;
588 } 588 }
589 break; 589 break;
@@ -603,7 +603,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
603 sta->ignore_plink_timer = true; 603 sta->ignore_plink_timer = true;
604 604
605 llid = sta->llid; 605 llid = sta->llid;
606 spin_unlock_bh(&sta->plink_lock); 606 spin_unlock_bh(&sta->lock);
607 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 607 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
608 plid, reason); 608 plid, reason);
609 break; 609 break;
@@ -612,7 +612,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
612 sta->plink_state = PLINK_OPN_RCVD; 612 sta->plink_state = PLINK_OPN_RCVD;
613 sta->plid = plid; 613 sta->plid = plid;
614 llid = sta->llid; 614 llid = sta->llid;
615 spin_unlock_bh(&sta->plink_lock); 615 spin_unlock_bh(&sta->lock);
616 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, 616 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
617 plid, 0); 617 plid, 0);
618 break; 618 break;
@@ -622,10 +622,10 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
622 dot11MeshConfirmTimeout(sdata))) 622 dot11MeshConfirmTimeout(sdata)))
623 sta->ignore_plink_timer = true; 623 sta->ignore_plink_timer = true;
624 624
625 spin_unlock_bh(&sta->plink_lock); 625 spin_unlock_bh(&sta->lock);
626 break; 626 break;
627 default: 627 default:
628 spin_unlock_bh(&sta->plink_lock); 628 spin_unlock_bh(&sta->lock);
629 break; 629 break;
630 } 630 }
631 break; 631 break;
@@ -645,13 +645,13 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
645 sta->ignore_plink_timer = true; 645 sta->ignore_plink_timer = true;
646 646
647 llid = sta->llid; 647 llid = sta->llid;
648 spin_unlock_bh(&sta->plink_lock); 648 spin_unlock_bh(&sta->lock);
649 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 649 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
650 plid, reason); 650 plid, reason);
651 break; 651 break;
652 case OPN_ACPT: 652 case OPN_ACPT:
653 llid = sta->llid; 653 llid = sta->llid;
654 spin_unlock_bh(&sta->plink_lock); 654 spin_unlock_bh(&sta->lock);
655 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, 655 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
656 plid, 0); 656 plid, 0);
657 break; 657 break;
@@ -659,12 +659,12 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
659 del_timer(&sta->plink_timer); 659 del_timer(&sta->plink_timer);
660 sta->plink_state = PLINK_ESTAB; 660 sta->plink_state = PLINK_ESTAB;
661 mesh_plink_inc_estab_count(sdata); 661 mesh_plink_inc_estab_count(sdata);
662 spin_unlock_bh(&sta->plink_lock); 662 spin_unlock_bh(&sta->lock);
663 mpl_dbg("Mesh plink with %s ESTABLISHED\n", 663 mpl_dbg("Mesh plink with %s ESTABLISHED\n",
664 print_mac(mac, sta->addr)); 664 print_mac(mac, sta->addr));
665 break; 665 break;
666 default: 666 default:
667 spin_unlock_bh(&sta->plink_lock); 667 spin_unlock_bh(&sta->lock);
668 break; 668 break;
669 } 669 }
670 break; 670 break;
@@ -684,7 +684,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
684 sta->ignore_plink_timer = true; 684 sta->ignore_plink_timer = true;
685 685
686 llid = sta->llid; 686 llid = sta->llid;
687 spin_unlock_bh(&sta->plink_lock); 687 spin_unlock_bh(&sta->lock);
688 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 688 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
689 plid, reason); 689 plid, reason);
690 break; 690 break;
@@ -692,14 +692,14 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
692 del_timer(&sta->plink_timer); 692 del_timer(&sta->plink_timer);
693 sta->plink_state = PLINK_ESTAB; 693 sta->plink_state = PLINK_ESTAB;
694 mesh_plink_inc_estab_count(sdata); 694 mesh_plink_inc_estab_count(sdata);
695 spin_unlock_bh(&sta->plink_lock); 695 spin_unlock_bh(&sta->lock);
696 mpl_dbg("Mesh plink with %s ESTABLISHED\n", 696 mpl_dbg("Mesh plink with %s ESTABLISHED\n",
697 print_mac(mac, sta->addr)); 697 print_mac(mac, sta->addr));
698 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, 698 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
699 plid, 0); 699 plid, 0);
700 break; 700 break;
701 default: 701 default:
702 spin_unlock_bh(&sta->plink_lock); 702 spin_unlock_bh(&sta->lock);
703 break; 703 break;
704 } 704 }
705 break; 705 break;
@@ -713,18 +713,18 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
713 sta->plink_state = PLINK_HOLDING; 713 sta->plink_state = PLINK_HOLDING;
714 llid = sta->llid; 714 llid = sta->llid;
715 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 715 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
716 spin_unlock_bh(&sta->plink_lock); 716 spin_unlock_bh(&sta->lock);
717 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 717 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
718 plid, reason); 718 plid, reason);
719 break; 719 break;
720 case OPN_ACPT: 720 case OPN_ACPT:
721 llid = sta->llid; 721 llid = sta->llid;
722 spin_unlock_bh(&sta->plink_lock); 722 spin_unlock_bh(&sta->lock);
723 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, 723 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
724 plid, 0); 724 plid, 0);
725 break; 725 break;
726 default: 726 default:
727 spin_unlock_bh(&sta->plink_lock); 727 spin_unlock_bh(&sta->lock);
728 break; 728 break;
729 } 729 }
730 break; 730 break;
@@ -734,7 +734,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
734 if (del_timer(&sta->plink_timer)) 734 if (del_timer(&sta->plink_timer))
735 sta->ignore_plink_timer = 1; 735 sta->ignore_plink_timer = 1;
736 mesh_plink_fsm_restart(sta); 736 mesh_plink_fsm_restart(sta);
737 spin_unlock_bh(&sta->plink_lock); 737 spin_unlock_bh(&sta->lock);
738 break; 738 break;
739 case OPN_ACPT: 739 case OPN_ACPT:
740 case CNF_ACPT: 740 case CNF_ACPT:
@@ -742,19 +742,19 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
742 case CNF_RJCT: 742 case CNF_RJCT:
743 llid = sta->llid; 743 llid = sta->llid;
744 reason = sta->reason; 744 reason = sta->reason;
745 spin_unlock_bh(&sta->plink_lock); 745 spin_unlock_bh(&sta->lock);
746 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 746 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
747 plid, reason); 747 plid, reason);
748 break; 748 break;
749 default: 749 default:
750 spin_unlock_bh(&sta->plink_lock); 750 spin_unlock_bh(&sta->lock);
751 } 751 }
752 break; 752 break;
753 default: 753 default:
754 /* should not get here, PLINK_BLOCKED is dealt with at the 754 /* should not get here, PLINK_BLOCKED is dealt with at the
755 * beggining of the function 755 * beggining of the function
756 */ 756 */
757 spin_unlock_bh(&sta->plink_lock); 757 spin_unlock_bh(&sta->lock);
758 break; 758 break;
759 } 759 }
760 760
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 108c6fc42fe2..6c4b27be35da 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1241,7 +1241,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
1241 1241
1242 1242
1243 /* examine state machine */ 1243 /* examine state machine */
1244 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); 1244 spin_lock_bh(&sta->lock);
1245 1245
1246 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { 1246 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
1247#ifdef CONFIG_MAC80211_HT_DEBUG 1247#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -1308,7 +1308,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
1308 tid_agg_rx->stored_mpdu_num = 0; 1308 tid_agg_rx->stored_mpdu_num = 0;
1309 status = WLAN_STATUS_SUCCESS; 1309 status = WLAN_STATUS_SUCCESS;
1310end: 1310end:
1311 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 1311 spin_unlock_bh(&sta->lock);
1312 1312
1313end_no_lock: 1313end_no_lock:
1314 ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid, 1314 ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid,
@@ -1340,10 +1340,10 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1340 1340
1341 state = &sta->ampdu_mlme.tid_state_tx[tid]; 1341 state = &sta->ampdu_mlme.tid_state_tx[tid];
1342 1342
1343 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 1343 spin_lock_bh(&sta->lock);
1344 1344
1345 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 1345 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1346 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1346 spin_unlock_bh(&sta->lock);
1347 printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:" 1347 printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:"
1348 "%d\n", *state); 1348 "%d\n", *state);
1349 goto addba_resp_exit; 1349 goto addba_resp_exit;
@@ -1351,7 +1351,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1351 1351
1352 if (mgmt->u.action.u.addba_resp.dialog_token != 1352 if (mgmt->u.action.u.addba_resp.dialog_token !=
1353 sta->ampdu_mlme.tid_tx[tid]->dialog_token) { 1353 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
1354 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1354 spin_unlock_bh(&sta->lock);
1355#ifdef CONFIG_MAC80211_HT_DEBUG 1355#ifdef CONFIG_MAC80211_HT_DEBUG
1356 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); 1356 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
1357#endif /* CONFIG_MAC80211_HT_DEBUG */ 1357#endif /* CONFIG_MAC80211_HT_DEBUG */
@@ -1375,7 +1375,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1375 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 1375 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
1376 } 1376 }
1377 1377
1378 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1378 spin_unlock_bh(&sta->lock);
1379 printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid); 1379 printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid);
1380 } else { 1380 } else {
1381 printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid); 1381 printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid);
@@ -1383,7 +1383,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1383 sta->ampdu_mlme.addba_req_num[tid]++; 1383 sta->ampdu_mlme.addba_req_num[tid]++;
1384 /* this will allow the state check in stop_BA_session */ 1384 /* this will allow the state check in stop_BA_session */
1385 *state = HT_AGG_STATE_OPERATIONAL; 1385 *state = HT_AGG_STATE_OPERATIONAL;
1386 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1386 spin_unlock_bh(&sta->lock);
1387 ieee80211_stop_tx_ba_session(hw, sta->addr, tid, 1387 ieee80211_stop_tx_ba_session(hw, sta->addr, tid,
1388 WLAN_BACK_INITIATOR); 1388 WLAN_BACK_INITIATOR);
1389 } 1389 }
@@ -1453,17 +1453,17 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid,
1453 } 1453 }
1454 1454
1455 /* check if TID is in operational state */ 1455 /* check if TID is in operational state */
1456 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); 1456 spin_lock_bh(&sta->lock);
1457 if (sta->ampdu_mlme.tid_state_rx[tid] 1457 if (sta->ampdu_mlme.tid_state_rx[tid]
1458 != HT_AGG_STATE_OPERATIONAL) { 1458 != HT_AGG_STATE_OPERATIONAL) {
1459 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 1459 spin_unlock_bh(&sta->lock);
1460 rcu_read_unlock(); 1460 rcu_read_unlock();
1461 return; 1461 return;
1462 } 1462 }
1463 sta->ampdu_mlme.tid_state_rx[tid] = 1463 sta->ampdu_mlme.tid_state_rx[tid] =
1464 HT_AGG_STATE_REQ_STOP_BA_MSK | 1464 HT_AGG_STATE_REQ_STOP_BA_MSK |
1465 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 1465 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
1466 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 1466 spin_unlock_bh(&sta->lock);
1467 1467
1468 /* stop HW Rx aggregation. ampdu_action existence 1468 /* stop HW Rx aggregation. ampdu_action existence
1469 * already verified in session init so we add the BUG_ON */ 1469 * already verified in session init so we add the BUG_ON */
@@ -1540,10 +1540,10 @@ static void ieee80211_sta_process_delba(struct net_device *dev,
1540 ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid, 1540 ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid,
1541 WLAN_BACK_INITIATOR, 0); 1541 WLAN_BACK_INITIATOR, 0);
1542 else { /* WLAN_BACK_RECIPIENT */ 1542 else { /* WLAN_BACK_RECIPIENT */
1543 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 1543 spin_lock_bh(&sta->lock);
1544 sta->ampdu_mlme.tid_state_tx[tid] = 1544 sta->ampdu_mlme.tid_state_tx[tid] =
1545 HT_AGG_STATE_OPERATIONAL; 1545 HT_AGG_STATE_OPERATIONAL;
1546 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1546 spin_unlock_bh(&sta->lock);
1547 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, 1547 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
1548 WLAN_BACK_RECIPIENT); 1548 WLAN_BACK_RECIPIENT);
1549 } 1549 }
@@ -1580,9 +1580,9 @@ void sta_addba_resp_timer_expired(unsigned long data)
1580 1580
1581 state = &sta->ampdu_mlme.tid_state_tx[tid]; 1581 state = &sta->ampdu_mlme.tid_state_tx[tid];
1582 /* check if the TID waits for addBA response */ 1582 /* check if the TID waits for addBA response */
1583 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 1583 spin_lock_bh(&sta->lock);
1584 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 1584 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1585 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1585 spin_unlock_bh(&sta->lock);
1586 *state = HT_AGG_STATE_IDLE; 1586 *state = HT_AGG_STATE_IDLE;
1587 printk(KERN_DEBUG "timer expired on tid %d but we are not " 1587 printk(KERN_DEBUG "timer expired on tid %d but we are not "
1588 "expecting addBA response there", tid); 1588 "expecting addBA response there", tid);
@@ -1593,7 +1593,7 @@ void sta_addba_resp_timer_expired(unsigned long data)
1593 1593
1594 /* go through the state check in stop_BA_session */ 1594 /* go through the state check in stop_BA_session */
1595 *state = HT_AGG_STATE_OPERATIONAL; 1595 *state = HT_AGG_STATE_OPERATIONAL;
1596 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1596 spin_unlock_bh(&sta->lock);
1597 ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid, 1597 ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid,
1598 WLAN_BACK_INITIATOR); 1598 WLAN_BACK_INITIATOR);
1599 1599
@@ -1984,8 +1984,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1984 * to between the sta_info_alloc() and sta_info_insert() above. 1984 * to between the sta_info_alloc() and sta_info_insert() above.
1985 */ 1985 */
1986 1986
1987 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | 1987 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
1988 WLAN_STA_AUTHORIZED; 1988 WLAN_STA_AUTHORIZED);
1989 1989
1990 rates = 0; 1990 rates = 0;
1991 basic_rates = 0; 1991 basic_rates = 0;
@@ -2044,7 +2044,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2044 rate_control_rate_init(sta, local); 2044 rate_control_rate_init(sta, local);
2045 2045
2046 if (elems.wmm_param) { 2046 if (elems.wmm_param) {
2047 sta->flags |= WLAN_STA_WME; 2047 set_sta_flags(sta, WLAN_STA_WME);
2048 rcu_read_unlock(); 2048 rcu_read_unlock();
2049 ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, 2049 ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param,
2050 elems.wmm_param_len); 2050 elems.wmm_param_len);
@@ -4237,7 +4237,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev,
4237 if (!sta) 4237 if (!sta)
4238 return NULL; 4238 return NULL;
4239 4239
4240 sta->flags |= WLAN_STA_AUTHORIZED; 4240 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
4241 4241
4242 sta->supp_rates[local->hw.conf.channel->band] = 4242 sta->supp_rates[local->hw.conf.channel->band] =
4243 sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band]; 4243 sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band];
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index e8b89c89e875..b399e09ec7aa 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -479,7 +479,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
479 ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && 479 ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL &&
480 (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) && 480 (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) &&
481 rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 481 rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
482 (!rx->sta || !(rx->sta->flags & WLAN_STA_ASSOC)))) { 482 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) {
483 if ((!(rx->fc & IEEE80211_FCTL_FROMDS) && 483 if ((!(rx->fc & IEEE80211_FCTL_FROMDS) &&
484 !(rx->fc & IEEE80211_FCTL_TODS) && 484 !(rx->fc & IEEE80211_FCTL_TODS) &&
485 (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) 485 (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
@@ -630,8 +630,7 @@ static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta)
630 630
631 if (sdata->bss) 631 if (sdata->bss)
632 atomic_inc(&sdata->bss->num_sta_ps); 632 atomic_inc(&sdata->bss->num_sta_ps);
633 sta->flags |= WLAN_STA_PS; 633 set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
634 sta->flags &= ~WLAN_STA_PSPOLL;
635#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 634#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
636 printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", 635 printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n",
637 dev->name, print_mac(mac, sta->addr), sta->aid); 636 dev->name, print_mac(mac, sta->addr), sta->aid);
@@ -652,7 +651,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
652 if (sdata->bss) 651 if (sdata->bss)
653 atomic_dec(&sdata->bss->num_sta_ps); 652 atomic_dec(&sdata->bss->num_sta_ps);
654 653
655 sta->flags &= ~(WLAN_STA_PS | WLAN_STA_PSPOLL); 654 clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
656 655
657 if (!skb_queue_empty(&sta->ps_tx_buf)) 656 if (!skb_queue_empty(&sta->ps_tx_buf))
658 sta_info_clear_tim_bit(sta); 657 sta_info_clear_tim_bit(sta);
@@ -727,9 +726,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
727 if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) { 726 if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) {
728 /* Change STA power saving mode only in the end of a frame 727 /* Change STA power saving mode only in the end of a frame
729 * exchange sequence */ 728 * exchange sequence */
730 if ((sta->flags & WLAN_STA_PS) && !(rx->fc & IEEE80211_FCTL_PM)) 729 if (test_sta_flags(sta, WLAN_STA_PS) &&
730 !(rx->fc & IEEE80211_FCTL_PM))
731 rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); 731 rx->sent_ps_buffered += ap_sta_ps_end(dev, sta);
732 else if (!(sta->flags & WLAN_STA_PS) && 732 else if (!test_sta_flags(sta, WLAN_STA_PS) &&
733 (rx->fc & IEEE80211_FCTL_PM)) 733 (rx->fc & IEEE80211_FCTL_PM))
734 ap_sta_ps_start(dev, sta); 734 ap_sta_ps_start(dev, sta);
735 } 735 }
@@ -983,7 +983,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
983 * Tell TX path to send one frame even though the STA may 983 * Tell TX path to send one frame even though the STA may
984 * still remain is PS mode after this frame exchange. 984 * still remain is PS mode after this frame exchange.
985 */ 985 */
986 rx->sta->flags |= WLAN_STA_PSPOLL; 986 set_sta_flags(rx->sta, WLAN_STA_PSPOLL);
987 987
988#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 988#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
989 printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", 989 printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n",
@@ -1046,7 +1046,8 @@ ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx)
1046static int 1046static int
1047ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) 1047ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx)
1048{ 1048{
1049 if (unlikely(!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED))) { 1049 if (unlikely(!rx->sta ||
1050 !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) {
1050#ifdef CONFIG_MAC80211_DEBUG 1051#ifdef CONFIG_MAC80211_DEBUG
1051 if (net_ratelimit()) 1052 if (net_ratelimit())
1052 printk(KERN_DEBUG "%s: dropped frame " 1053 printk(KERN_DEBUG "%s: dropped frame "
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 631943e8af8b..baf5e4746884 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -202,14 +202,12 @@ void sta_info_destroy(struct sta_info *sta)
202 dev_kfree_skb_any(skb); 202 dev_kfree_skb_any(skb);
203 203
204 for (i = 0; i < STA_TID_NUM; i++) { 204 for (i = 0; i < STA_TID_NUM; i++) {
205 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); 205 spin_lock_bh(&sta->lock);
206 if (sta->ampdu_mlme.tid_rx[i]) 206 if (sta->ampdu_mlme.tid_rx[i])
207 del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); 207 del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer);
208 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
209 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
210 if (sta->ampdu_mlme.tid_tx[i]) 208 if (sta->ampdu_mlme.tid_tx[i])
211 del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); 209 del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer);
212 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 210 spin_unlock_bh(&sta->lock);
213 } 211 }
214 212
215 __sta_info_free(local, sta); 213 __sta_info_free(local, sta);
@@ -236,6 +234,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
236 if (!sta) 234 if (!sta)
237 return NULL; 235 return NULL;
238 236
237 spin_lock_init(&sta->lock);
238
239 memcpy(sta->addr, addr, ETH_ALEN); 239 memcpy(sta->addr, addr, ETH_ALEN);
240 sta->local = local; 240 sta->local = local;
241 sta->sdata = sdata; 241 sta->sdata = sdata;
@@ -249,8 +249,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
249 return NULL; 249 return NULL;
250 } 250 }
251 251
252 spin_lock_init(&sta->ampdu_mlme.ampdu_rx);
253 spin_lock_init(&sta->ampdu_mlme.ampdu_tx);
254 for (i = 0; i < STA_TID_NUM; i++) { 252 for (i = 0; i < STA_TID_NUM; i++) {
255 /* timer_to_tid must be initialized with identity mapping to 253 /* timer_to_tid must be initialized with identity mapping to
256 * enable session_timer's data differentiation. refer to 254 * enable session_timer's data differentiation. refer to
@@ -276,7 +274,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
276 274
277#ifdef CONFIG_MAC80211_MESH 275#ifdef CONFIG_MAC80211_MESH
278 sta->plink_state = PLINK_LISTEN; 276 sta->plink_state = PLINK_LISTEN;
279 spin_lock_init(&sta->plink_lock);
280 init_timer(&sta->plink_timer); 277 init_timer(&sta->plink_timer);
281#endif 278#endif
282 279
@@ -437,8 +434,7 @@ void __sta_info_unlink(struct sta_info **sta)
437 434
438 list_del(&(*sta)->list); 435 list_del(&(*sta)->list);
439 436
440 if ((*sta)->flags & WLAN_STA_PS) { 437 if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) {
441 (*sta)->flags &= ~WLAN_STA_PS;
442 if (sdata->bss) 438 if (sdata->bss)
443 atomic_dec(&sdata->bss->num_sta_ps); 439 atomic_dec(&sdata->bss->num_sta_ps);
444 __sta_info_clear_tim_bit(sdata->bss, *sta); 440 __sta_info_clear_tim_bit(sdata->bss, *sta);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index f8c95bc9659c..97a61c39ad90 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -129,23 +129,19 @@ enum plink_state {
129 * 129 *
130 * @tid_state_rx: TID's state in Rx session state machine. 130 * @tid_state_rx: TID's state in Rx session state machine.
131 * @tid_rx: aggregation info for Rx per TID 131 * @tid_rx: aggregation info for Rx per TID
132 * @ampdu_rx: for locking sections in aggregation Rx flow
133 * @tid_state_tx: TID's state in Tx session state machine. 132 * @tid_state_tx: TID's state in Tx session state machine.
134 * @tid_tx: aggregation info for Tx per TID 133 * @tid_tx: aggregation info for Tx per TID
135 * @addba_req_num: number of times addBA request has been sent. 134 * @addba_req_num: number of times addBA request has been sent.
136 * @ampdu_tx: for locking sectionsi in aggregation Tx flow
137 * @dialog_token_allocator: dialog token enumerator for each new session; 135 * @dialog_token_allocator: dialog token enumerator for each new session;
138 */ 136 */
139struct sta_ampdu_mlme { 137struct sta_ampdu_mlme {
140 /* rx */ 138 /* rx */
141 u8 tid_state_rx[STA_TID_NUM]; 139 u8 tid_state_rx[STA_TID_NUM];
142 struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; 140 struct tid_ampdu_rx *tid_rx[STA_TID_NUM];
143 spinlock_t ampdu_rx;
144 /* tx */ 141 /* tx */
145 u8 tid_state_tx[STA_TID_NUM]; 142 u8 tid_state_tx[STA_TID_NUM];
146 struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; 143 struct tid_ampdu_tx *tid_tx[STA_TID_NUM];
147 u8 addba_req_num[STA_TID_NUM]; 144 u8 addba_req_num[STA_TID_NUM];
148 spinlock_t ampdu_tx;
149 u8 dialog_token_allocator; 145 u8 dialog_token_allocator;
150}; 146};
151 147
@@ -177,6 +173,8 @@ struct sta_ampdu_mlme {
177 * @rx_bytes: Number of bytes received from this STA 173 * @rx_bytes: Number of bytes received from this STA
178 * @supp_rates: Bitmap of supported rates (per band) 174 * @supp_rates: Bitmap of supported rates (per band)
179 * @ht_info: HT capabilities of this STA 175 * @ht_info: HT capabilities of this STA
176 * @lock: used for locking all fields that require locking, see comments
177 * in the header file.
180 */ 178 */
181struct sta_info { 179struct sta_info {
182 /* General information, mostly static */ 180 /* General information, mostly static */
@@ -187,6 +185,7 @@ struct sta_info {
187 struct ieee80211_key *key; 185 struct ieee80211_key *key;
188 struct rate_control_ref *rate_ctrl; 186 struct rate_control_ref *rate_ctrl;
189 void *rate_ctrl_priv; 187 void *rate_ctrl_priv;
188 spinlock_t lock;
190 struct ieee80211_ht_info ht_info; 189 struct ieee80211_ht_info ht_info;
191 u64 supp_rates[IEEE80211_NUM_BANDS]; 190 u64 supp_rates[IEEE80211_NUM_BANDS];
192 u8 addr[ETH_ALEN]; 191 u8 addr[ETH_ALEN];
@@ -199,7 +198,7 @@ struct sta_info {
199 */ 198 */
200 u8 pin_status; 199 u8 pin_status;
201 200
202 /* frequently updated information, needs locking? */ 201 /* frequently updated information, locked with lock spinlock */
203 u32 flags; 202 u32 flags;
204 203
205 /* 204 /*
@@ -251,7 +250,7 @@ struct sta_info {
251 int channel_use_raw; 250 int channel_use_raw;
252 251
253 /* 252 /*
254 * Aggregation information, comes with own locking. 253 * Aggregation information, locked with lock.
255 */ 254 */
256 struct sta_ampdu_mlme ampdu_mlme; 255 struct sta_ampdu_mlme ampdu_mlme;
257 u8 timer_to_tid[STA_TID_NUM]; /* identity mapping to ID timers */ 256 u8 timer_to_tid[STA_TID_NUM]; /* identity mapping to ID timers */
@@ -270,9 +269,6 @@ struct sta_info {
270 enum plink_state plink_state; 269 enum plink_state plink_state;
271 u32 plink_timeout; 270 u32 plink_timeout;
272 struct timer_list plink_timer; 271 struct timer_list plink_timer;
273 spinlock_t plink_lock; /* For peer_state reads / updates and other
274 updates in the structure. Ensures robust
275 transitions for the peerlink FSM */
276#endif 272#endif
277 273
278#ifdef CONFIG_MAC80211_DEBUGFS 274#ifdef CONFIG_MAC80211_DEBUGFS
@@ -299,6 +295,64 @@ static inline enum plink_state sta_plink_state(struct sta_info *sta)
299 return PLINK_LISTEN; 295 return PLINK_LISTEN;
300} 296}
301 297
298static inline void set_sta_flags(struct sta_info *sta, const u32 flags)
299{
300 spin_lock_bh(&sta->lock);
301 sta->flags |= flags;
302 spin_unlock_bh(&sta->lock);
303}
304
305static inline void clear_sta_flags(struct sta_info *sta, const u32 flags)
306{
307 spin_lock_bh(&sta->lock);
308 sta->flags &= ~flags;
309 spin_unlock_bh(&sta->lock);
310}
311
312static inline void set_and_clear_sta_flags(struct sta_info *sta,
313 const u32 set, const u32 clear)
314{
315 spin_lock_bh(&sta->lock);
316 sta->flags |= set;
317 sta->flags &= ~clear;
318 spin_unlock_bh(&sta->lock);
319}
320
321static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags)
322{
323 u32 ret;
324
325 spin_lock_bh(&sta->lock);
326 ret = sta->flags & flags;
327 spin_unlock_bh(&sta->lock);
328
329 return ret;
330}
331
332static inline u32 test_and_clear_sta_flags(struct sta_info *sta,
333 const u32 flags)
334{
335 u32 ret;
336
337 spin_lock_bh(&sta->lock);
338 ret = sta->flags & flags;
339 sta->flags &= ~flags;
340 spin_unlock_bh(&sta->lock);
341
342 return ret;
343}
344
345static inline u32 get_sta_flags(struct sta_info *sta)
346{
347 u32 ret;
348
349 spin_lock_bh(&sta->lock);
350 ret = sta->flags;
351 spin_unlock_bh(&sta->lock);
352
353 return ret;
354}
355
302 356
303/* Maximum number of concurrently registered stations */ 357/* Maximum number of concurrently registered stations */
304#define MAX_STA_COUNT 2007 358#define MAX_STA_COUNT 2007
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3a03d7807c39..5f31a6233e13 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -256,7 +256,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
256 if (tx->flags & IEEE80211_TX_PS_BUFFERED) 256 if (tx->flags & IEEE80211_TX_PS_BUFFERED)
257 return TX_CONTINUE; 257 return TX_CONTINUE;
258 258
259 sta_flags = tx->sta ? tx->sta->flags : 0; 259 sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0;
260 260
261 if (likely(tx->flags & IEEE80211_TX_UNICAST)) { 261 if (likely(tx->flags & IEEE80211_TX_UNICAST)) {
262 if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && 262 if (unlikely(!(sta_flags & WLAN_STA_ASSOC) &&
@@ -391,6 +391,7 @@ static ieee80211_tx_result
391ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) 391ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
392{ 392{
393 struct sta_info *sta = tx->sta; 393 struct sta_info *sta = tx->sta;
394 u32 staflags;
394 DECLARE_MAC_BUF(mac); 395 DECLARE_MAC_BUF(mac);
395 396
396 if (unlikely(!sta || 397 if (unlikely(!sta ||
@@ -398,8 +399,10 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
398 (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP))) 399 (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)))
399 return TX_CONTINUE; 400 return TX_CONTINUE;
400 401
401 if (unlikely((sta->flags & WLAN_STA_PS) && 402 staflags = get_sta_flags(sta);
402 !(sta->flags & WLAN_STA_PSPOLL))) { 403
404 if (unlikely((staflags & WLAN_STA_PS) &&
405 !(staflags & WLAN_STA_PSPOLL))) {
403 struct ieee80211_tx_packet_data *pkt_data; 406 struct ieee80211_tx_packet_data *pkt_data;
404#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 407#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
405 printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " 408 printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries "
@@ -430,13 +433,13 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
430 return TX_QUEUED; 433 return TX_QUEUED;
431 } 434 }
432#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 435#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
433 else if (unlikely(sta->flags & WLAN_STA_PS)) { 436 else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) {
434 printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll " 437 printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll "
435 "set -> send frame\n", tx->dev->name, 438 "set -> send frame\n", tx->dev->name,
436 print_mac(mac, sta->addr)); 439 print_mac(mac, sta->addr));
437 } 440 }
438#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 441#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
439 sta->flags &= ~WLAN_STA_PSPOLL; 442 clear_sta_flags(sta, WLAN_STA_PSPOLL);
440 443
441 return TX_CONTINUE; 444 return TX_CONTINUE;
442} 445}
@@ -697,7 +700,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
697 if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && 700 if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
698 (tx->rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) && 701 (tx->rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
699 tx->sdata->bss_conf.use_short_preamble && 702 tx->sdata->bss_conf.use_short_preamble &&
700 (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) { 703 (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) {
701 tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; 704 tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
702 } 705 }
703 706
@@ -1025,10 +1028,8 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1025 1028
1026 if (!tx->sta) 1029 if (!tx->sta)
1027 control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; 1030 control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT;
1028 else if (tx->sta->flags & WLAN_STA_CLEAR_PS_FILT) { 1031 else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT))
1029 control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; 1032 control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT;
1030 tx->sta->flags &= ~WLAN_STA_CLEAR_PS_FILT;
1031 }
1032 1033
1033 hdrlen = ieee80211_get_hdrlen(tx->fc); 1034 hdrlen = ieee80211_get_hdrlen(tx->fc);
1034 if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { 1035 if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) {
@@ -1486,7 +1487,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1486 rcu_read_lock(); 1487 rcu_read_lock();
1487 sta = sta_info_get(local, hdr.addr1); 1488 sta = sta_info_get(local, hdr.addr1);
1488 if (sta) 1489 if (sta)
1489 sta_flags = sta->flags; 1490 sta_flags = get_sta_flags(sta);
1490 rcu_read_unlock(); 1491 rcu_read_unlock();
1491 } 1492 }
1492 1493