diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-09-29 10:04:36 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-30 15:57:19 -0400 |
commit | c2c98fdeb5c897499644eb247285c8e3dacc6450 (patch) | |
tree | aaa9c0f8dd16ab896308470e21a0813041094670 /net | |
parent | deeaee197b0fa694ba6c8f02cdb57b3be7115b4f (diff) |
mac80211: optimise station flags
The flaglock in struct sta_info has long been
something that I wanted to get rid of, this
finally does the conversion to atomic bitops.
The conversion itself is straight-forward in
most places, a few things needed to change a
bit since we can no longer use multiple bits
at the same time.
On x86-64, this is a fairly significant code
size reduction:
text data bss dec hex
427861 23648 1008 452517 6e7a5 before
425383 23648 976 450007 6ddd7 after
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/agg-rx.c | 2 | ||||
-rw-r--r-- | net/mac80211/agg-tx.c | 2 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 44 | ||||
-rw-r--r-- | net/mac80211/debugfs_sta.c | 20 | ||||
-rw-r--r-- | net/mac80211/ht.c | 2 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 4 | ||||
-rw-r--r-- | net/mac80211/iface.c | 4 | ||||
-rw-r--r-- | net/mac80211/key.c | 4 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 8 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 22 | ||||
-rw-r--r-- | net/mac80211/pm.c | 2 | ||||
-rw-r--r-- | net/mac80211/rx.c | 28 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 35 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 104 | ||||
-rw-r--r-- | net/mac80211/status.c | 12 | ||||
-rw-r--r-- | net/mac80211/tx.c | 68 | ||||
-rw-r--r-- | net/mac80211/util.c | 2 | ||||
-rw-r--r-- | net/mac80211/wme.c | 4 |
18 files changed, 173 insertions, 194 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index e6cab51dceb0..0cde8df6828d 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -223,7 +223,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
223 | 223 | ||
224 | status = WLAN_STATUS_REQUEST_DECLINED; | 224 | status = WLAN_STATUS_REQUEST_DECLINED; |
225 | 225 | ||
226 | if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) { | 226 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { |
227 | #ifdef CONFIG_MAC80211_HT_DEBUG | 227 | #ifdef CONFIG_MAC80211_HT_DEBUG |
228 | printk(KERN_DEBUG "Suspend in progress. " | 228 | printk(KERN_DEBUG "Suspend in progress. " |
229 | "Denying ADDBA request\n"); | 229 | "Denying ADDBA request\n"); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 3cef5a7281cb..2ac033989e01 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -382,7 +382,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
382 | sdata->vif.type != NL80211_IFTYPE_AP) | 382 | sdata->vif.type != NL80211_IFTYPE_AP) |
383 | return -EINVAL; | 383 | return -EINVAL; |
384 | 384 | ||
385 | if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) { | 385 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { |
386 | #ifdef CONFIG_MAC80211_HT_DEBUG | 386 | #ifdef CONFIG_MAC80211_HT_DEBUG |
387 | printk(KERN_DEBUG "BA sessions blocked. " | 387 | printk(KERN_DEBUG "BA sessions blocked. " |
388 | "Denying BA session request\n"); | 388 | "Denying BA session request\n"); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index bdf9852eec5b..1309bb9c97be 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -668,7 +668,6 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
668 | struct sta_info *sta, | 668 | struct sta_info *sta, |
669 | struct station_parameters *params) | 669 | struct station_parameters *params) |
670 | { | 670 | { |
671 | unsigned long flags; | ||
672 | u32 rates; | 671 | u32 rates; |
673 | int i, j; | 672 | int i, j; |
674 | struct ieee80211_supported_band *sband; | 673 | struct ieee80211_supported_band *sband; |
@@ -677,49 +676,53 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
677 | 676 | ||
678 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | 677 | sband = local->hw.wiphy->bands[local->oper_channel->band]; |
679 | 678 | ||
680 | spin_lock_irqsave(&sta->flaglock, flags); | ||
681 | mask = params->sta_flags_mask; | 679 | mask = params->sta_flags_mask; |
682 | set = params->sta_flags_set; | 680 | set = params->sta_flags_set; |
683 | 681 | ||
684 | if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { | 682 | if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { |
685 | sta->flags &= ~WLAN_STA_AUTHORIZED; | ||
686 | if (set & BIT(NL80211_STA_FLAG_AUTHORIZED)) | 683 | if (set & BIT(NL80211_STA_FLAG_AUTHORIZED)) |
687 | sta->flags |= WLAN_STA_AUTHORIZED; | 684 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); |
685 | else | ||
686 | clear_sta_flag(sta, WLAN_STA_AUTHORIZED); | ||
688 | } | 687 | } |
689 | 688 | ||
690 | if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) { | 689 | if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) { |
691 | sta->flags &= ~WLAN_STA_SHORT_PREAMBLE; | ||
692 | if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) | 690 | if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) |
693 | sta->flags |= WLAN_STA_SHORT_PREAMBLE; | 691 | set_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE); |
692 | else | ||
693 | clear_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE); | ||
694 | } | 694 | } |
695 | 695 | ||
696 | if (mask & BIT(NL80211_STA_FLAG_WME)) { | 696 | if (mask & BIT(NL80211_STA_FLAG_WME)) { |
697 | sta->flags &= ~WLAN_STA_WME; | ||
698 | sta->sta.wme = false; | ||
699 | if (set & BIT(NL80211_STA_FLAG_WME)) { | 697 | if (set & BIT(NL80211_STA_FLAG_WME)) { |
700 | sta->flags |= WLAN_STA_WME; | 698 | set_sta_flag(sta, WLAN_STA_WME); |
701 | sta->sta.wme = true; | 699 | sta->sta.wme = true; |
700 | } else { | ||
701 | clear_sta_flag(sta, WLAN_STA_WME); | ||
702 | sta->sta.wme = false; | ||
702 | } | 703 | } |
703 | } | 704 | } |
704 | 705 | ||
705 | if (mask & BIT(NL80211_STA_FLAG_MFP)) { | 706 | if (mask & BIT(NL80211_STA_FLAG_MFP)) { |
706 | sta->flags &= ~WLAN_STA_MFP; | ||
707 | if (set & BIT(NL80211_STA_FLAG_MFP)) | 707 | if (set & BIT(NL80211_STA_FLAG_MFP)) |
708 | sta->flags |= WLAN_STA_MFP; | 708 | set_sta_flag(sta, WLAN_STA_MFP); |
709 | else | ||
710 | clear_sta_flag(sta, WLAN_STA_MFP); | ||
709 | } | 711 | } |
710 | 712 | ||
711 | if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) { | 713 | if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) { |
712 | sta->flags &= ~WLAN_STA_AUTH; | ||
713 | if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) | 714 | if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) |
714 | sta->flags |= WLAN_STA_AUTH; | 715 | set_sta_flag(sta, WLAN_STA_AUTH); |
716 | else | ||
717 | clear_sta_flag(sta, WLAN_STA_AUTH); | ||
715 | } | 718 | } |
716 | 719 | ||
717 | if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) { | 720 | if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) { |
718 | sta->flags &= ~WLAN_STA_TDLS_PEER; | ||
719 | if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) | 721 | if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) |
720 | sta->flags |= WLAN_STA_TDLS_PEER; | 722 | set_sta_flag(sta, WLAN_STA_TDLS_PEER); |
723 | else | ||
724 | clear_sta_flag(sta, WLAN_STA_TDLS_PEER); | ||
721 | } | 725 | } |
722 | spin_unlock_irqrestore(&sta->flaglock, flags); | ||
723 | 726 | ||
724 | if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD) { | 727 | if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD) { |
725 | sta->sta.uapsd_queues = params->uapsd_queues; | 728 | sta->sta.uapsd_queues = params->uapsd_queues; |
@@ -815,12 +818,13 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | |||
815 | if (!sta) | 818 | if (!sta) |
816 | return -ENOMEM; | 819 | return -ENOMEM; |
817 | 820 | ||
818 | sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC; | 821 | set_sta_flag(sta, WLAN_STA_AUTH); |
822 | set_sta_flag(sta, WLAN_STA_ASSOC); | ||
819 | 823 | ||
820 | sta_apply_parameters(local, sta, params); | 824 | sta_apply_parameters(local, sta, params); |
821 | 825 | ||
822 | /* Only TDLS-supporting stations can add TDLS peers */ | 826 | /* Only TDLS-supporting stations can add TDLS peers */ |
823 | if ((sta->flags & WLAN_STA_TDLS_PEER) && | 827 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && |
824 | !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) && | 828 | !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) && |
825 | sdata->vif.type == NL80211_IFTYPE_STATION)) | 829 | sdata->vif.type == NL80211_IFTYPE_STATION)) |
826 | return -ENOTSUPP; | 830 | return -ENOTSUPP; |
@@ -880,7 +884,7 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
880 | /* The TDLS bit cannot be toggled after the STA was added */ | 884 | /* The TDLS bit cannot be toggled after the STA was added */ |
881 | if ((params->sta_flags_mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) && | 885 | if ((params->sta_flags_mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) && |
882 | !!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) != | 886 | !!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) != |
883 | !!test_sta_flags(sta, WLAN_STA_TDLS_PEER)) { | 887 | !!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) { |
884 | rcu_read_unlock(); | 888 | rcu_read_unlock(); |
885 | return -EINVAL; | 889 | return -EINVAL; |
886 | } | 890 | } |
@@ -2449,7 +2453,7 @@ static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | |||
2449 | return -ENOLINK; | 2453 | return -ENOLINK; |
2450 | } | 2454 | } |
2451 | 2455 | ||
2452 | set_sta_flags(sta, WLAN_STA_TDLS_PEER_AUTH); | 2456 | set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH); |
2453 | rcu_read_unlock(); | 2457 | rcu_read_unlock(); |
2454 | break; | 2458 | break; |
2455 | case NL80211_TDLS_DISABLE_LINK: | 2459 | case NL80211_TDLS_DISABLE_LINK: |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 20ec2b0cb3c1..56bb68b9c42d 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -58,17 +58,17 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | |||
58 | { | 58 | { |
59 | char buf[100]; | 59 | char buf[100]; |
60 | struct sta_info *sta = file->private_data; | 60 | struct sta_info *sta = file->private_data; |
61 | u32 staflags = get_sta_flags(sta); | 61 | |
62 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s", | 62 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s", |
63 | staflags & WLAN_STA_AUTH ? "AUTH\n" : "", | 63 | test_sta_flag(sta, WLAN_STA_AUTH) ? "AUTH\n" : "", |
64 | staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "", | 64 | test_sta_flag(sta, WLAN_STA_ASSOC) ? "ASSOC\n" : "", |
65 | staflags & WLAN_STA_PS_STA ? "PS (sta)\n" : "", | 65 | test_sta_flag(sta, WLAN_STA_PS_STA) ? "PS (sta)\n" : "", |
66 | staflags & WLAN_STA_PS_DRIVER ? "PS (driver)\n" : "", | 66 | test_sta_flag(sta, WLAN_STA_PS_DRIVER) ? "PS (driver)\n" : "", |
67 | staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", | 67 | test_sta_flag(sta, WLAN_STA_AUTHORIZED) ? "AUTHORIZED\n" : "", |
68 | staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", | 68 | test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE) ? "SHORT PREAMBLE\n" : "", |
69 | staflags & WLAN_STA_WME ? "WME\n" : "", | 69 | test_sta_flag(sta, WLAN_STA_WME) ? "WME\n" : "", |
70 | staflags & WLAN_STA_WDS ? "WDS\n" : "", | 70 | test_sta_flag(sta, WLAN_STA_WDS) ? "WDS\n" : "", |
71 | staflags & WLAN_STA_MFP ? "MFP\n" : ""); | 71 | test_sta_flag(sta, WLAN_STA_MFP) ? "MFP\n" : ""); |
72 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | 72 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); |
73 | } | 73 | } |
74 | STA_OPS(flags); | 74 | STA_OPS(flags); |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 2b9b52c69569..f80a35c0d000 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -130,7 +130,7 @@ void ieee80211_ba_session_work(struct work_struct *work) | |||
130 | * down by the code that set the flag, so this | 130 | * down by the code that set the flag, so this |
131 | * need not run. | 131 | * need not run. |
132 | */ | 132 | */ |
133 | if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) | 133 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) |
134 | return; | 134 | return; |
135 | 135 | ||
136 | mutex_lock(&sta->ampdu_mlme.mtx); | 136 | mutex_lock(&sta->ampdu_mlme.mtx); |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 7809895df8b0..2da3040787a7 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -314,7 +314,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
314 | } | 314 | } |
315 | 315 | ||
316 | if (sta && elems->wmm_info) | 316 | if (sta && elems->wmm_info) |
317 | set_sta_flags(sta, WLAN_STA_WME); | 317 | set_sta_flag(sta, WLAN_STA_WME); |
318 | 318 | ||
319 | rcu_read_unlock(); | 319 | rcu_read_unlock(); |
320 | } | 320 | } |
@@ -452,7 +452,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
452 | return NULL; | 452 | return NULL; |
453 | 453 | ||
454 | sta->last_rx = jiffies; | 454 | sta->last_rx = jiffies; |
455 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); | 455 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); |
456 | 456 | ||
457 | /* make sure mandatory rates are always added */ | 457 | /* make sure mandatory rates are always added */ |
458 | sta->sta.supp_rates[band] = supp_rates | | 458 | sta->sta.supp_rates[band] = supp_rates | |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 4116a7542b6b..ef741e8dbedb 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -299,8 +299,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
299 | goto err_del_interface; | 299 | goto err_del_interface; |
300 | } | 300 | } |
301 | 301 | ||
302 | /* no locking required since STA is not live yet */ | 302 | /* no atomic bitop required since STA is not live yet */ |
303 | sta->flags |= WLAN_STA_AUTHORIZED; | 303 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); |
304 | 304 | ||
305 | res = sta_info_insert(sta); | 305 | res = sta_info_insert(sta); |
306 | if (res) { | 306 | if (res) { |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 5150c6d11b57..756b157c2edd 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -464,7 +464,7 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
464 | * some hardware cannot handle TKIP with QoS, so | 464 | * some hardware cannot handle TKIP with QoS, so |
465 | * we indicate whether QoS could be in use. | 465 | * we indicate whether QoS could be in use. |
466 | */ | 466 | */ |
467 | if (test_sta_flags(sta, WLAN_STA_WME)) | 467 | if (test_sta_flag(sta, WLAN_STA_WME)) |
468 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; | 468 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; |
469 | } else { | 469 | } else { |
470 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 470 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
@@ -478,7 +478,7 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
478 | /* same here, the AP could be using QoS */ | 478 | /* same here, the AP could be using QoS */ |
479 | ap = sta_info_get(key->sdata, key->sdata->u.mgd.bssid); | 479 | ap = sta_info_get(key->sdata, key->sdata->u.mgd.bssid); |
480 | if (ap) { | 480 | if (ap) { |
481 | if (test_sta_flags(ap, WLAN_STA_WME)) | 481 | if (test_sta_flag(ap, WLAN_STA_WME)) |
482 | key->conf.flags |= | 482 | key->conf.flags |= |
483 | IEEE80211_KEY_FLAG_WMM_STA; | 483 | IEEE80211_KEY_FLAG_WMM_STA; |
484 | } | 484 | } |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 9cc5029b3c46..7e57f5d07f66 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -92,7 +92,9 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
92 | if (!sta) | 92 | if (!sta) |
93 | return NULL; | 93 | return NULL; |
94 | 94 | ||
95 | sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH | WLAN_STA_WME; | 95 | set_sta_flag(sta, WLAN_STA_AUTH); |
96 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); | ||
97 | set_sta_flag(sta, WLAN_STA_WME); | ||
96 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; | 98 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; |
97 | rate_control_rate_init(sta); | 99 | rate_control_rate_init(sta); |
98 | 100 | ||
@@ -383,7 +385,7 @@ int mesh_plink_open(struct sta_info *sta) | |||
383 | __le16 llid; | 385 | __le16 llid; |
384 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 386 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
385 | 387 | ||
386 | if (!test_sta_flags(sta, WLAN_STA_AUTH)) | 388 | if (!test_sta_flag(sta, WLAN_STA_AUTH)) |
387 | return -EPERM; | 389 | return -EPERM; |
388 | 390 | ||
389 | spin_lock_bh(&sta->lock); | 391 | spin_lock_bh(&sta->lock); |
@@ -503,7 +505,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
503 | return; | 505 | return; |
504 | } | 506 | } |
505 | 507 | ||
506 | if (sta && !test_sta_flags(sta, WLAN_STA_AUTH)) { | 508 | if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { |
507 | mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); | 509 | mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); |
508 | rcu_read_unlock(); | 510 | rcu_read_unlock(); |
509 | return; | 511 | return; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b98c43a7f191..c4e8901c96f6 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -627,7 +627,7 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata) | |||
627 | { | 627 | { |
628 | struct ieee80211_if_managed *mgd = &sdata->u.mgd; | 628 | struct ieee80211_if_managed *mgd = &sdata->u.mgd; |
629 | struct sta_info *sta = NULL; | 629 | struct sta_info *sta = NULL; |
630 | u32 sta_flags = 0; | 630 | bool authorized = false; |
631 | 631 | ||
632 | if (!mgd->powersave) | 632 | if (!mgd->powersave) |
633 | return false; | 633 | return false; |
@@ -645,13 +645,10 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata) | |||
645 | rcu_read_lock(); | 645 | rcu_read_lock(); |
646 | sta = sta_info_get(sdata, mgd->bssid); | 646 | sta = sta_info_get(sdata, mgd->bssid); |
647 | if (sta) | 647 | if (sta) |
648 | sta_flags = get_sta_flags(sta); | 648 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); |
649 | rcu_read_unlock(); | 649 | rcu_read_unlock(); |
650 | 650 | ||
651 | if (!(sta_flags & WLAN_STA_AUTHORIZED)) | 651 | return authorized; |
652 | return false; | ||
653 | |||
654 | return true; | ||
655 | } | 652 | } |
656 | 653 | ||
657 | /* need to hold RTNL or interface lock */ | 654 | /* need to hold RTNL or interface lock */ |
@@ -1095,7 +1092,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1095 | mutex_lock(&local->sta_mtx); | 1092 | mutex_lock(&local->sta_mtx); |
1096 | sta = sta_info_get(sdata, bssid); | 1093 | sta = sta_info_get(sdata, bssid); |
1097 | if (sta) { | 1094 | if (sta) { |
1098 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); | 1095 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); |
1099 | ieee80211_sta_tear_down_BA_sessions(sta, tx); | 1096 | ieee80211_sta_tear_down_BA_sessions(sta, tx); |
1100 | } | 1097 | } |
1101 | mutex_unlock(&local->sta_mtx); | 1098 | mutex_unlock(&local->sta_mtx); |
@@ -1513,10 +1510,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1513 | return false; | 1510 | return false; |
1514 | } | 1511 | } |
1515 | 1512 | ||
1516 | set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | | 1513 | set_sta_flag(sta, WLAN_STA_AUTH); |
1517 | WLAN_STA_ASSOC_AP); | 1514 | set_sta_flag(sta, WLAN_STA_ASSOC); |
1515 | set_sta_flag(sta, WLAN_STA_ASSOC_AP); | ||
1518 | if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) | 1516 | if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) |
1519 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); | 1517 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); |
1520 | 1518 | ||
1521 | rates = 0; | 1519 | rates = 0; |
1522 | basic_rates = 0; | 1520 | basic_rates = 0; |
@@ -1575,10 +1573,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1575 | rate_control_rate_init(sta); | 1573 | rate_control_rate_init(sta); |
1576 | 1574 | ||
1577 | if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) | 1575 | if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) |
1578 | set_sta_flags(sta, WLAN_STA_MFP); | 1576 | set_sta_flag(sta, WLAN_STA_MFP); |
1579 | 1577 | ||
1580 | if (elems.wmm_param) | 1578 | if (elems.wmm_param) |
1581 | set_sta_flags(sta, WLAN_STA_WME); | 1579 | set_sta_flag(sta, WLAN_STA_WME); |
1582 | 1580 | ||
1583 | /* sta_info_reinsert will also unlock the mutex lock */ | 1581 | /* sta_info_reinsert will also unlock the mutex lock */ |
1584 | err = sta_info_reinsert(sta); | 1582 | err = sta_info_reinsert(sta); |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 6326d3439861..9ee7164b207c 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -42,7 +42,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
42 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { | 42 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { |
43 | mutex_lock(&local->sta_mtx); | 43 | mutex_lock(&local->sta_mtx); |
44 | list_for_each_entry(sta, &local->sta_list, list) { | 44 | list_for_each_entry(sta, &local->sta_list, list) { |
45 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); | 45 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); |
46 | ieee80211_sta_tear_down_BA_sessions(sta, true); | 46 | ieee80211_sta_tear_down_BA_sessions(sta, true); |
47 | } | 47 | } |
48 | mutex_unlock(&local->sta_mtx); | 48 | mutex_unlock(&local->sta_mtx); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 32c8ee43f720..b867bd55de7a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -841,7 +841,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
841 | ieee80211_is_pspoll(hdr->frame_control)) && | 841 | ieee80211_is_pspoll(hdr->frame_control)) && |
842 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && | 842 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && |
843 | rx->sdata->vif.type != NL80211_IFTYPE_WDS && | 843 | rx->sdata->vif.type != NL80211_IFTYPE_WDS && |
844 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { | 844 | (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) { |
845 | if (rx->sta && rx->sta->dummy && | 845 | if (rx->sta && rx->sta->dummy && |
846 | ieee80211_is_data_present(hdr->frame_control)) { | 846 | ieee80211_is_data_present(hdr->frame_control)) { |
847 | u16 ethertype; | 847 | u16 ethertype; |
@@ -1110,7 +1110,7 @@ static void ap_sta_ps_start(struct sta_info *sta) | |||
1110 | struct ieee80211_local *local = sdata->local; | 1110 | struct ieee80211_local *local = sdata->local; |
1111 | 1111 | ||
1112 | atomic_inc(&sdata->bss->num_sta_ps); | 1112 | atomic_inc(&sdata->bss->num_sta_ps); |
1113 | set_sta_flags(sta, WLAN_STA_PS_STA); | 1113 | set_sta_flag(sta, WLAN_STA_PS_STA); |
1114 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) | 1114 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) |
1115 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); | 1115 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); |
1116 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1116 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
@@ -1130,7 +1130,7 @@ static void ap_sta_ps_end(struct sta_info *sta) | |||
1130 | sdata->name, sta->sta.addr, sta->sta.aid); | 1130 | sdata->name, sta->sta.addr, sta->sta.aid); |
1131 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1131 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1132 | 1132 | ||
1133 | if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) { | 1133 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { |
1134 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1134 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
1135 | printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", | 1135 | printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", |
1136 | sdata->name, sta->sta.addr, sta->sta.aid); | 1136 | sdata->name, sta->sta.addr, sta->sta.aid); |
@@ -1149,7 +1149,7 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start) | |||
1149 | WARN_ON(!(sta_inf->local->hw.flags & IEEE80211_HW_AP_LINK_PS)); | 1149 | WARN_ON(!(sta_inf->local->hw.flags & IEEE80211_HW_AP_LINK_PS)); |
1150 | 1150 | ||
1151 | /* Don't let the same PS state be set twice */ | 1151 | /* Don't let the same PS state be set twice */ |
1152 | in_ps = test_sta_flags(sta_inf, WLAN_STA_PS_STA); | 1152 | in_ps = test_sta_flag(sta_inf, WLAN_STA_PS_STA); |
1153 | if ((start && in_ps) || (!start && !in_ps)) | 1153 | if ((start && in_ps) || (!start && !in_ps)) |
1154 | return -EINVAL; | 1154 | return -EINVAL; |
1155 | 1155 | ||
@@ -1190,15 +1190,15 @@ ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx) | |||
1190 | * the uAPSD case, the station will probably be marked asleep, | 1190 | * the uAPSD case, the station will probably be marked asleep, |
1191 | * in the PS-Poll case the station must be confused ... | 1191 | * in the PS-Poll case the station must be confused ... |
1192 | */ | 1192 | */ |
1193 | if (!test_sta_flags(rx->sta, WLAN_STA_PS_STA)) | 1193 | if (!test_sta_flag(rx->sta, WLAN_STA_PS_STA)) |
1194 | return RX_CONTINUE; | 1194 | return RX_CONTINUE; |
1195 | 1195 | ||
1196 | if (unlikely(ieee80211_is_pspoll(hdr->frame_control))) { | 1196 | if (unlikely(ieee80211_is_pspoll(hdr->frame_control))) { |
1197 | if (!test_sta_flags(rx->sta, WLAN_STA_SP)) { | 1197 | if (!test_sta_flag(rx->sta, WLAN_STA_SP)) { |
1198 | if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER)) | 1198 | if (!test_sta_flag(rx->sta, WLAN_STA_PS_DRIVER)) |
1199 | ieee80211_sta_ps_deliver_poll_response(rx->sta); | 1199 | ieee80211_sta_ps_deliver_poll_response(rx->sta); |
1200 | else | 1200 | else |
1201 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); | 1201 | set_sta_flag(rx->sta, WLAN_STA_PSPOLL); |
1202 | } | 1202 | } |
1203 | 1203 | ||
1204 | /* Free PS Poll skb here instead of returning RX_DROP that would | 1204 | /* Free PS Poll skb here instead of returning RX_DROP that would |
@@ -1225,13 +1225,13 @@ ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx) | |||
1225 | return RX_CONTINUE; | 1225 | return RX_CONTINUE; |
1226 | 1226 | ||
1227 | /* if we are in a service period, do nothing */ | 1227 | /* if we are in a service period, do nothing */ |
1228 | if (test_sta_flags(rx->sta, WLAN_STA_SP)) | 1228 | if (test_sta_flag(rx->sta, WLAN_STA_SP)) |
1229 | return RX_CONTINUE; | 1229 | return RX_CONTINUE; |
1230 | 1230 | ||
1231 | if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER)) | 1231 | if (!test_sta_flag(rx->sta, WLAN_STA_PS_DRIVER)) |
1232 | ieee80211_sta_ps_deliver_uapsd(rx->sta); | 1232 | ieee80211_sta_ps_deliver_uapsd(rx->sta); |
1233 | else | 1233 | else |
1234 | set_sta_flags(rx->sta, WLAN_STA_UAPSD); | 1234 | set_sta_flag(rx->sta, WLAN_STA_UAPSD); |
1235 | } | 1235 | } |
1236 | 1236 | ||
1237 | return RX_CONTINUE; | 1237 | return RX_CONTINUE; |
@@ -1295,7 +1295,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1295 | !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) && | 1295 | !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) && |
1296 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || | 1296 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || |
1297 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { | 1297 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { |
1298 | if (test_sta_flags(sta, WLAN_STA_PS_STA)) { | 1298 | if (test_sta_flag(sta, WLAN_STA_PS_STA)) { |
1299 | /* | 1299 | /* |
1300 | * Ignore doze->wake transitions that are | 1300 | * Ignore doze->wake transitions that are |
1301 | * indicated by non-data frames, the standard | 1301 | * indicated by non-data frames, the standard |
@@ -1570,7 +1570,7 @@ static int | |||
1570 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) | 1570 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) |
1571 | { | 1571 | { |
1572 | if (unlikely(!rx->sta || | 1572 | if (unlikely(!rx->sta || |
1573 | !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) | 1573 | !test_sta_flag(rx->sta, WLAN_STA_AUTHORIZED))) |
1574 | return -EACCES; | 1574 | return -EACCES; |
1575 | 1575 | ||
1576 | return 0; | 1576 | return 0; |
@@ -1613,7 +1613,7 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) | |||
1613 | if (status->flag & RX_FLAG_DECRYPTED) | 1613 | if (status->flag & RX_FLAG_DECRYPTED) |
1614 | return 0; | 1614 | return 0; |
1615 | 1615 | ||
1616 | if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) { | 1616 | if (rx->sta && test_sta_flag(rx->sta, WLAN_STA_MFP)) { |
1617 | if (unlikely(!ieee80211_has_protected(fc) && | 1617 | if (unlikely(!ieee80211_has_protected(fc) && |
1618 | ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && | 1618 | ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && |
1619 | rx->key)) { | 1619 | rx->key)) { |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 5732e4d0cc21..a00358224cd5 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -244,22 +244,22 @@ static void sta_unblock(struct work_struct *wk) | |||
244 | if (sta->dead) | 244 | if (sta->dead) |
245 | return; | 245 | return; |
246 | 246 | ||
247 | if (!test_sta_flags(sta, WLAN_STA_PS_STA)) | 247 | if (!test_sta_flag(sta, WLAN_STA_PS_STA)) |
248 | ieee80211_sta_ps_deliver_wakeup(sta); | 248 | ieee80211_sta_ps_deliver_wakeup(sta); |
249 | else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) { | 249 | else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL)) { |
250 | clear_sta_flags(sta, WLAN_STA_PS_DRIVER); | 250 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); |
251 | 251 | ||
252 | local_bh_disable(); | 252 | local_bh_disable(); |
253 | ieee80211_sta_ps_deliver_poll_response(sta); | 253 | ieee80211_sta_ps_deliver_poll_response(sta); |
254 | local_bh_enable(); | 254 | local_bh_enable(); |
255 | } else if (test_and_clear_sta_flags(sta, WLAN_STA_UAPSD)) { | 255 | } else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD)) { |
256 | clear_sta_flags(sta, WLAN_STA_PS_DRIVER); | 256 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); |
257 | 257 | ||
258 | local_bh_disable(); | 258 | local_bh_disable(); |
259 | ieee80211_sta_ps_deliver_uapsd(sta); | 259 | ieee80211_sta_ps_deliver_uapsd(sta); |
260 | local_bh_enable(); | 260 | local_bh_enable(); |
261 | } else | 261 | } else |
262 | clear_sta_flags(sta, WLAN_STA_PS_DRIVER); | 262 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); |
263 | } | 263 | } |
264 | 264 | ||
265 | static int sta_prepare_rate_control(struct ieee80211_local *local, | 265 | static int sta_prepare_rate_control(struct ieee80211_local *local, |
@@ -292,7 +292,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
292 | return NULL; | 292 | return NULL; |
293 | 293 | ||
294 | spin_lock_init(&sta->lock); | 294 | spin_lock_init(&sta->lock); |
295 | spin_lock_init(&sta->flaglock); | ||
296 | INIT_WORK(&sta->drv_unblock_wk, sta_unblock); | 295 | INIT_WORK(&sta->drv_unblock_wk, sta_unblock); |
297 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); | 296 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); |
298 | mutex_init(&sta->ampdu_mlme.mtx); | 297 | mutex_init(&sta->ampdu_mlme.mtx); |
@@ -871,7 +870,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
871 | * sessions -- block that to make sure the tear-down | 870 | * sessions -- block that to make sure the tear-down |
872 | * will be sufficient. | 871 | * will be sufficient. |
873 | */ | 872 | */ |
874 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); | 873 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); |
875 | ieee80211_sta_tear_down_BA_sessions(sta, true); | 874 | ieee80211_sta_tear_down_BA_sessions(sta, true); |
876 | 875 | ||
877 | spin_lock_irqsave(&local->sta_lock, flags); | 876 | spin_lock_irqsave(&local->sta_lock, flags); |
@@ -892,10 +891,13 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
892 | 891 | ||
893 | sta->dead = true; | 892 | sta->dead = true; |
894 | 893 | ||
895 | if (test_and_clear_sta_flags(sta, | 894 | if (test_sta_flag(sta, WLAN_STA_PS_STA) || |
896 | WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) { | 895 | test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { |
897 | BUG_ON(!sdata->bss); | 896 | BUG_ON(!sdata->bss); |
898 | 897 | ||
898 | clear_sta_flag(sta, WLAN_STA_PS_STA); | ||
899 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | ||
900 | |||
899 | atomic_dec(&sdata->bss->num_sta_ps); | 901 | atomic_dec(&sdata->bss->num_sta_ps); |
900 | sta_info_recalc_tim(sta); | 902 | sta_info_recalc_tim(sta); |
901 | } | 903 | } |
@@ -1116,7 +1118,8 @@ static void clear_sta_ps_flags(void *_sta) | |||
1116 | { | 1118 | { |
1117 | struct sta_info *sta = _sta; | 1119 | struct sta_info *sta = _sta; |
1118 | 1120 | ||
1119 | clear_sta_flags(sta, WLAN_STA_PS_DRIVER | WLAN_STA_PS_STA); | 1121 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); |
1122 | clear_sta_flag(sta, WLAN_STA_PS_STA); | ||
1120 | } | 1123 | } |
1121 | 1124 | ||
1122 | /* powersave support code */ | 1125 | /* powersave support code */ |
@@ -1127,7 +1130,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
1127 | struct sk_buff_head pending; | 1130 | struct sk_buff_head pending; |
1128 | int filtered = 0, buffered = 0, ac; | 1131 | int filtered = 0, buffered = 0, ac; |
1129 | 1132 | ||
1130 | clear_sta_flags(sta, WLAN_STA_SP); | 1133 | clear_sta_flag(sta, WLAN_STA_SP); |
1131 | 1134 | ||
1132 | BUILD_BUG_ON(BITS_TO_LONGS(STA_TID_NUM) > 1); | 1135 | BUILD_BUG_ON(BITS_TO_LONGS(STA_TID_NUM) > 1); |
1133 | sta->driver_buffered_tids = 0; | 1136 | sta->driver_buffered_tids = 0; |
@@ -1173,7 +1176,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | |||
1173 | struct sk_buff *skb; | 1176 | struct sk_buff *skb; |
1174 | int size = sizeof(*nullfunc); | 1177 | int size = sizeof(*nullfunc); |
1175 | __le16 fc; | 1178 | __le16 fc; |
1176 | bool qos = test_sta_flags(sta, WLAN_STA_WME); | 1179 | bool qos = test_sta_flag(sta, WLAN_STA_WME); |
1177 | struct ieee80211_tx_info *info; | 1180 | struct ieee80211_tx_info *info; |
1178 | 1181 | ||
1179 | if (qos) { | 1182 | if (qos) { |
@@ -1241,7 +1244,7 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1241 | struct sk_buff_head frames; | 1244 | struct sk_buff_head frames; |
1242 | 1245 | ||
1243 | /* Service or PS-Poll period starts */ | 1246 | /* Service or PS-Poll period starts */ |
1244 | set_sta_flags(sta, WLAN_STA_SP); | 1247 | set_sta_flag(sta, WLAN_STA_SP); |
1245 | 1248 | ||
1246 | __skb_queue_head_init(&frames); | 1249 | __skb_queue_head_init(&frames); |
1247 | 1250 | ||
@@ -1453,8 +1456,8 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw, | |||
1453 | trace_api_sta_block_awake(sta->local, pubsta, block); | 1456 | trace_api_sta_block_awake(sta->local, pubsta, block); |
1454 | 1457 | ||
1455 | if (block) | 1458 | if (block) |
1456 | set_sta_flags(sta, WLAN_STA_PS_DRIVER); | 1459 | set_sta_flag(sta, WLAN_STA_PS_DRIVER); |
1457 | else if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) | 1460 | else if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) |
1458 | ieee80211_queue_work(hw, &sta->drv_unblock_wk); | 1461 | ieee80211_queue_work(hw, &sta->drv_unblock_wk); |
1459 | } | 1462 | } |
1460 | EXPORT_SYMBOL(ieee80211_sta_block_awake); | 1463 | EXPORT_SYMBOL(ieee80211_sta_block_awake); |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 348847a32630..8c8ce05ad26f 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -19,7 +19,8 @@ | |||
19 | /** | 19 | /** |
20 | * enum ieee80211_sta_info_flags - Stations flags | 20 | * enum ieee80211_sta_info_flags - Stations flags |
21 | * | 21 | * |
22 | * These flags are used with &struct sta_info's @flags member. | 22 | * These flags are used with &struct sta_info's @flags member, but |
23 | * only indirectly with set_sta_flag() and friends. | ||
23 | * | 24 | * |
24 | * @WLAN_STA_AUTH: Station is authenticated. | 25 | * @WLAN_STA_AUTH: Station is authenticated. |
25 | * @WLAN_STA_ASSOC: Station is associated. | 26 | * @WLAN_STA_ASSOC: Station is associated. |
@@ -53,23 +54,23 @@ | |||
53 | * reply to other uAPSD trigger frames or PS-Poll. | 54 | * reply to other uAPSD trigger frames or PS-Poll. |
54 | */ | 55 | */ |
55 | enum ieee80211_sta_info_flags { | 56 | enum ieee80211_sta_info_flags { |
56 | WLAN_STA_AUTH = 1<<0, | 57 | WLAN_STA_AUTH, |
57 | WLAN_STA_ASSOC = 1<<1, | 58 | WLAN_STA_ASSOC, |
58 | WLAN_STA_PS_STA = 1<<2, | 59 | WLAN_STA_PS_STA, |
59 | WLAN_STA_AUTHORIZED = 1<<3, | 60 | WLAN_STA_AUTHORIZED, |
60 | WLAN_STA_SHORT_PREAMBLE = 1<<4, | 61 | WLAN_STA_SHORT_PREAMBLE, |
61 | WLAN_STA_ASSOC_AP = 1<<5, | 62 | WLAN_STA_ASSOC_AP, |
62 | WLAN_STA_WME = 1<<6, | 63 | WLAN_STA_WME, |
63 | WLAN_STA_WDS = 1<<7, | 64 | WLAN_STA_WDS, |
64 | WLAN_STA_CLEAR_PS_FILT = 1<<9, | 65 | WLAN_STA_CLEAR_PS_FILT, |
65 | WLAN_STA_MFP = 1<<10, | 66 | WLAN_STA_MFP, |
66 | WLAN_STA_BLOCK_BA = 1<<11, | 67 | WLAN_STA_BLOCK_BA, |
67 | WLAN_STA_PS_DRIVER = 1<<12, | 68 | WLAN_STA_PS_DRIVER, |
68 | WLAN_STA_PSPOLL = 1<<13, | 69 | WLAN_STA_PSPOLL, |
69 | WLAN_STA_TDLS_PEER = 1<<15, | 70 | WLAN_STA_TDLS_PEER, |
70 | WLAN_STA_TDLS_PEER_AUTH = 1<<16, | 71 | WLAN_STA_TDLS_PEER_AUTH, |
71 | WLAN_STA_UAPSD = 1<<17, | 72 | WLAN_STA_UAPSD, |
72 | WLAN_STA_SP = 1<<18, | 73 | WLAN_STA_SP, |
73 | }; | 74 | }; |
74 | 75 | ||
75 | #define STA_TID_NUM 16 | 76 | #define STA_TID_NUM 16 |
@@ -212,10 +213,9 @@ struct sta_ampdu_mlme { | |||
212 | * @last_rx_rate_flag: rx status flag of the last data packet | 213 | * @last_rx_rate_flag: rx status flag of the last data packet |
213 | * @lock: used for locking all fields that require locking, see comments | 214 | * @lock: used for locking all fields that require locking, see comments |
214 | * in the header file. | 215 | * in the header file. |
215 | * @flaglock: spinlock for flags accesses | ||
216 | * @drv_unblock_wk: used for driver PS unblocking | 216 | * @drv_unblock_wk: used for driver PS unblocking |
217 | * @listen_interval: listen interval of this station, when we're acting as AP | 217 | * @listen_interval: listen interval of this station, when we're acting as AP |
218 | * @flags: STA flags, see &enum ieee80211_sta_info_flags | 218 | * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly |
219 | * @ps_tx_buf: buffers (per AC) of frames to transmit to this station | 219 | * @ps_tx_buf: buffers (per AC) of frames to transmit to this station |
220 | * when it leaves power saving state or polls | 220 | * when it leaves power saving state or polls |
221 | * @tx_filtered: buffers (per AC) of frames we already tried to | 221 | * @tx_filtered: buffers (per AC) of frames we already tried to |
@@ -272,7 +272,6 @@ struct sta_info { | |||
272 | struct rate_control_ref *rate_ctrl; | 272 | struct rate_control_ref *rate_ctrl; |
273 | void *rate_ctrl_priv; | 273 | void *rate_ctrl_priv; |
274 | spinlock_t lock; | 274 | spinlock_t lock; |
275 | spinlock_t flaglock; | ||
276 | 275 | ||
277 | struct work_struct drv_unblock_wk; | 276 | struct work_struct drv_unblock_wk; |
278 | 277 | ||
@@ -282,11 +281,8 @@ struct sta_info { | |||
282 | 281 | ||
283 | bool uploaded; | 282 | bool uploaded; |
284 | 283 | ||
285 | /* | 284 | /* use the accessors defined below */ |
286 | * frequently updated, locked with own spinlock (flaglock), | 285 | unsigned long _flags; |
287 | * use the accessors defined below | ||
288 | */ | ||
289 | u32 flags; | ||
290 | 286 | ||
291 | /* | 287 | /* |
292 | * STA powersave frame queues, no more than the internal | 288 | * STA powersave frame queues, no more than the internal |
@@ -370,60 +366,28 @@ static inline enum nl80211_plink_state sta_plink_state(struct sta_info *sta) | |||
370 | return NL80211_PLINK_LISTEN; | 366 | return NL80211_PLINK_LISTEN; |
371 | } | 367 | } |
372 | 368 | ||
373 | static inline void set_sta_flags(struct sta_info *sta, const u32 flags) | 369 | static inline void set_sta_flag(struct sta_info *sta, |
370 | enum ieee80211_sta_info_flags flag) | ||
374 | { | 371 | { |
375 | unsigned long irqfl; | 372 | set_bit(flag, &sta->_flags); |
376 | |||
377 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
378 | sta->flags |= flags; | ||
379 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
380 | } | 373 | } |
381 | 374 | ||
382 | static inline void clear_sta_flags(struct sta_info *sta, const u32 flags) | 375 | static inline void clear_sta_flag(struct sta_info *sta, |
376 | enum ieee80211_sta_info_flags flag) | ||
383 | { | 377 | { |
384 | unsigned long irqfl; | 378 | clear_bit(flag, &sta->_flags); |
385 | |||
386 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
387 | sta->flags &= ~flags; | ||
388 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
389 | } | 379 | } |
390 | 380 | ||
391 | static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags) | 381 | static inline int test_sta_flag(struct sta_info *sta, |
382 | enum ieee80211_sta_info_flags flag) | ||
392 | { | 383 | { |
393 | u32 ret; | 384 | return test_bit(flag, &sta->_flags); |
394 | unsigned long irqfl; | ||
395 | |||
396 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
397 | ret = sta->flags & flags; | ||
398 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
399 | |||
400 | return ret; | ||
401 | } | 385 | } |
402 | 386 | ||
403 | static inline u32 test_and_clear_sta_flags(struct sta_info *sta, | 387 | static inline int test_and_clear_sta_flag(struct sta_info *sta, |
404 | const u32 flags) | 388 | enum ieee80211_sta_info_flags flag) |
405 | { | 389 | { |
406 | u32 ret; | 390 | return test_and_clear_bit(flag, &sta->_flags); |
407 | unsigned long irqfl; | ||
408 | |||
409 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
410 | ret = sta->flags & flags; | ||
411 | sta->flags &= ~flags; | ||
412 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
413 | |||
414 | return ret; | ||
415 | } | ||
416 | |||
417 | static inline u32 get_sta_flags(struct sta_info *sta) | ||
418 | { | ||
419 | u32 ret; | ||
420 | unsigned long irqfl; | ||
421 | |||
422 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
423 | ret = sta->flags; | ||
424 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
425 | |||
426 | return ret; | ||
427 | } | 391 | } |
428 | 392 | ||
429 | void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, | 393 | void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index b5df9be4d043..864a9c3bcf46 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -96,7 +96,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
96 | * packet. If the STA went to power save mode, this will happen | 96 | * packet. If the STA went to power save mode, this will happen |
97 | * when it wakes up for the next time. | 97 | * when it wakes up for the next time. |
98 | */ | 98 | */ |
99 | set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT); | 99 | set_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT); |
100 | 100 | ||
101 | /* | 101 | /* |
102 | * This code races in the following way: | 102 | * This code races in the following way: |
@@ -132,7 +132,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
132 | * changes before calling TX status events if ordering can be | 132 | * changes before calling TX status events if ordering can be |
133 | * unknown. | 133 | * unknown. |
134 | */ | 134 | */ |
135 | if (test_sta_flags(sta, WLAN_STA_PS_STA) && | 135 | if (test_sta_flag(sta, WLAN_STA_PS_STA) && |
136 | skb_queue_len(&sta->tx_filtered[ac]) < STA_MAX_TX_BUFFER) { | 136 | skb_queue_len(&sta->tx_filtered[ac]) < STA_MAX_TX_BUFFER) { |
137 | skb_queue_tail(&sta->tx_filtered[ac], skb); | 137 | skb_queue_tail(&sta->tx_filtered[ac], skb); |
138 | sta_info_recalc_tim(sta); | 138 | sta_info_recalc_tim(sta); |
@@ -144,7 +144,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
144 | return; | 144 | return; |
145 | } | 145 | } |
146 | 146 | ||
147 | if (!test_sta_flags(sta, WLAN_STA_PS_STA) && | 147 | if (!test_sta_flag(sta, WLAN_STA_PS_STA) && |
148 | !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { | 148 | !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { |
149 | /* Software retry the packet once */ | 149 | /* Software retry the packet once */ |
150 | info->flags |= IEEE80211_TX_INTFL_RETRIED; | 150 | info->flags |= IEEE80211_TX_INTFL_RETRIED; |
@@ -157,7 +157,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
157 | wiphy_debug(local->hw.wiphy, | 157 | wiphy_debug(local->hw.wiphy, |
158 | "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", | 158 | "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", |
159 | skb_queue_len(&sta->tx_filtered[ac]), | 159 | skb_queue_len(&sta->tx_filtered[ac]), |
160 | !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies); | 160 | !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies); |
161 | #endif | 161 | #endif |
162 | dev_kfree_skb(skb); | 162 | dev_kfree_skb(skb); |
163 | } | 163 | } |
@@ -285,10 +285,10 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
285 | continue; | 285 | continue; |
286 | 286 | ||
287 | if (info->flags & IEEE80211_TX_STATUS_EOSP) | 287 | if (info->flags & IEEE80211_TX_STATUS_EOSP) |
288 | clear_sta_flags(sta, WLAN_STA_SP); | 288 | clear_sta_flag(sta, WLAN_STA_SP); |
289 | 289 | ||
290 | acked = !!(info->flags & IEEE80211_TX_STAT_ACK); | 290 | acked = !!(info->flags & IEEE80211_TX_STAT_ACK); |
291 | if (!acked && test_sta_flags(sta, WLAN_STA_PS_STA)) { | 291 | if (!acked && test_sta_flag(sta, WLAN_STA_PS_STA)) { |
292 | /* | 292 | /* |
293 | * The STA is in power save mode, so assume | 293 | * The STA is in power save mode, so assume |
294 | * that this TX packet failed because of that. | 294 | * that this TX packet failed because of that. |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 5bf91c43c88c..7699e666457f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -253,7 +253,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
253 | 253 | ||
254 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 254 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
255 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 255 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
256 | u32 sta_flags; | 256 | bool assoc = false; |
257 | 257 | ||
258 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) | 258 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) |
259 | return TX_CONTINUE; | 259 | return TX_CONTINUE; |
@@ -284,10 +284,11 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
284 | if (tx->flags & IEEE80211_TX_PS_BUFFERED) | 284 | if (tx->flags & IEEE80211_TX_PS_BUFFERED) |
285 | return TX_CONTINUE; | 285 | return TX_CONTINUE; |
286 | 286 | ||
287 | sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0; | 287 | if (tx->sta) |
288 | assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC); | ||
288 | 289 | ||
289 | if (likely(tx->flags & IEEE80211_TX_UNICAST)) { | 290 | if (likely(tx->flags & IEEE80211_TX_UNICAST)) { |
290 | if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && | 291 | if (unlikely(!assoc && |
291 | tx->sdata->vif.type != NL80211_IFTYPE_ADHOC && | 292 | tx->sdata->vif.type != NL80211_IFTYPE_ADHOC && |
292 | ieee80211_is_data(hdr->frame_control))) { | 293 | ieee80211_is_data(hdr->frame_control))) { |
293 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 294 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
@@ -427,7 +428,7 @@ static int ieee80211_use_mfp(__le16 fc, struct sta_info *sta, | |||
427 | if (!ieee80211_is_mgmt(fc)) | 428 | if (!ieee80211_is_mgmt(fc)) |
428 | return 0; | 429 | return 0; |
429 | 430 | ||
430 | if (sta == NULL || !test_sta_flags(sta, WLAN_STA_MFP)) | 431 | if (sta == NULL || !test_sta_flag(sta, WLAN_STA_MFP)) |
431 | return 0; | 432 | return 0; |
432 | 433 | ||
433 | if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) | 434 | if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) |
@@ -444,7 +445,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
444 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 445 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
445 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 446 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
446 | struct ieee80211_local *local = tx->local; | 447 | struct ieee80211_local *local = tx->local; |
447 | u32 staflags; | ||
448 | 448 | ||
449 | if (unlikely(!sta || | 449 | if (unlikely(!sta || |
450 | ieee80211_is_probe_resp(hdr->frame_control) || | 450 | ieee80211_is_probe_resp(hdr->frame_control) || |
@@ -453,9 +453,8 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
453 | ieee80211_is_reassoc_resp(hdr->frame_control))) | 453 | ieee80211_is_reassoc_resp(hdr->frame_control))) |
454 | return TX_CONTINUE; | 454 | return TX_CONTINUE; |
455 | 455 | ||
456 | staflags = get_sta_flags(sta); | 456 | if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) || |
457 | 457 | test_sta_flag(sta, WLAN_STA_PS_DRIVER)) && | |
458 | if (unlikely((staflags & (WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) && | ||
459 | !(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE))) { | 458 | !(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE))) { |
460 | int ac = skb_get_queue_mapping(tx->skb); | 459 | int ac = skb_get_queue_mapping(tx->skb); |
461 | 460 | ||
@@ -496,7 +495,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
496 | return TX_QUEUED; | 495 | return TX_QUEUED; |
497 | } | 496 | } |
498 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 497 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
499 | else if (unlikely(staflags & WLAN_STA_PS_STA)) { | 498 | else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) { |
500 | printk(KERN_DEBUG | 499 | printk(KERN_DEBUG |
501 | "%s: STA %pM in PS mode, but polling/in SP -> send frame\n", | 500 | "%s: STA %pM in PS mode, but polling/in SP -> send frame\n", |
502 | tx->sdata->name, sta->sta.addr); | 501 | tx->sdata->name, sta->sta.addr); |
@@ -557,7 +556,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
557 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && | 556 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && |
558 | (!ieee80211_is_robust_mgmt_frame(hdr) || | 557 | (!ieee80211_is_robust_mgmt_frame(hdr) || |
559 | (ieee80211_is_action(hdr->frame_control) && | 558 | (ieee80211_is_action(hdr->frame_control) && |
560 | tx->sta && test_sta_flags(tx->sta, WLAN_STA_MFP)))) { | 559 | tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))) { |
561 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); | 560 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); |
562 | return TX_DROP; | 561 | return TX_DROP; |
563 | } else | 562 | } else |
@@ -616,7 +615,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
616 | u32 len; | 615 | u32 len; |
617 | bool inval = false, rts = false, short_preamble = false; | 616 | bool inval = false, rts = false, short_preamble = false; |
618 | struct ieee80211_tx_rate_control txrc; | 617 | struct ieee80211_tx_rate_control txrc; |
619 | u32 sta_flags; | 618 | bool assoc = false; |
620 | 619 | ||
621 | memset(&txrc, 0, sizeof(txrc)); | 620 | memset(&txrc, 0, sizeof(txrc)); |
622 | 621 | ||
@@ -652,17 +651,17 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
652 | */ | 651 | */ |
653 | if (tx->sdata->vif.bss_conf.use_short_preamble && | 652 | if (tx->sdata->vif.bss_conf.use_short_preamble && |
654 | (ieee80211_is_data(hdr->frame_control) || | 653 | (ieee80211_is_data(hdr->frame_control) || |
655 | (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) | 654 | (tx->sta && test_sta_flag(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) |
656 | txrc.short_preamble = short_preamble = true; | 655 | txrc.short_preamble = short_preamble = true; |
657 | 656 | ||
658 | sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0; | 657 | if (tx->sta) |
658 | assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC); | ||
659 | 659 | ||
660 | /* | 660 | /* |
661 | * Lets not bother rate control if we're associated and cannot | 661 | * Lets not bother rate control if we're associated and cannot |
662 | * talk to the sta. This should not happen. | 662 | * talk to the sta. This should not happen. |
663 | */ | 663 | */ |
664 | if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) && | 664 | if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) && assoc && |
665 | (sta_flags & WLAN_STA_ASSOC) && | ||
666 | !rate_usable_index_exists(sband, &tx->sta->sta), | 665 | !rate_usable_index_exists(sband, &tx->sta->sta), |
667 | "%s: Dropped data frame as no usable bitrate found while " | 666 | "%s: Dropped data frame as no usable bitrate found while " |
668 | "scanning and associated. Target station: " | 667 | "scanning and associated. Target station: " |
@@ -1278,7 +1277,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1278 | 1277 | ||
1279 | if (!tx->sta) | 1278 | if (!tx->sta) |
1280 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 1279 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
1281 | else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT)) | 1280 | else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT)) |
1282 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 1281 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
1283 | 1282 | ||
1284 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1283 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
@@ -1728,7 +1727,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1728 | int encaps_len, skip_header_bytes; | 1727 | int encaps_len, skip_header_bytes; |
1729 | int nh_pos, h_pos; | 1728 | int nh_pos, h_pos; |
1730 | struct sta_info *sta = NULL; | 1729 | struct sta_info *sta = NULL; |
1731 | u32 sta_flags = 0; | 1730 | bool wme_sta = false, authorized = false, tdls_auth = false; |
1732 | struct sk_buff *tmp_skb; | 1731 | struct sk_buff *tmp_skb; |
1733 | bool tdls_direct = false; | 1732 | bool tdls_direct = false; |
1734 | 1733 | ||
@@ -1754,7 +1753,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1754 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | 1753 | memcpy(hdr.addr3, skb->data, ETH_ALEN); |
1755 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); | 1754 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); |
1756 | hdrlen = 30; | 1755 | hdrlen = 30; |
1757 | sta_flags = get_sta_flags(sta); | 1756 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); |
1757 | wme_sta = test_sta_flag(sta, WLAN_STA_WME); | ||
1758 | } | 1758 | } |
1759 | rcu_read_unlock(); | 1759 | rcu_read_unlock(); |
1760 | if (sta) | 1760 | if (sta) |
@@ -1843,10 +1843,19 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1843 | #endif | 1843 | #endif |
1844 | case NL80211_IFTYPE_STATION: | 1844 | case NL80211_IFTYPE_STATION: |
1845 | if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) { | 1845 | if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) { |
1846 | bool tdls_peer = false; | ||
1847 | |||
1846 | rcu_read_lock(); | 1848 | rcu_read_lock(); |
1847 | sta = sta_info_get(sdata, skb->data); | 1849 | sta = sta_info_get(sdata, skb->data); |
1848 | if (sta) | 1850 | if (sta) { |
1849 | sta_flags = get_sta_flags(sta); | 1851 | authorized = test_sta_flag(sta, |
1852 | WLAN_STA_AUTHORIZED); | ||
1853 | wme_sta = test_sta_flag(sta, WLAN_STA_WME); | ||
1854 | tdls_peer = test_sta_flag(sta, | ||
1855 | WLAN_STA_TDLS_PEER); | ||
1856 | tdls_auth = test_sta_flag(sta, | ||
1857 | WLAN_STA_TDLS_PEER_AUTH); | ||
1858 | } | ||
1850 | rcu_read_unlock(); | 1859 | rcu_read_unlock(); |
1851 | 1860 | ||
1852 | /* | 1861 | /* |
@@ -1854,16 +1863,14 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1854 | * directly. Otherwise, allow TDLS setup frames | 1863 | * directly. Otherwise, allow TDLS setup frames |
1855 | * to be transmitted indirectly. | 1864 | * to be transmitted indirectly. |
1856 | */ | 1865 | */ |
1857 | tdls_direct = | 1866 | tdls_direct = tdls_peer && (tdls_auth || |
1858 | (sta_flags & WLAN_STA_TDLS_PEER) && | ||
1859 | ((sta_flags & WLAN_STA_TDLS_PEER_AUTH) || | ||
1860 | !(ethertype == ETH_P_TDLS && skb->len > 14 && | 1867 | !(ethertype == ETH_P_TDLS && skb->len > 14 && |
1861 | skb->data[14] == WLAN_TDLS_SNAP_RFTYPE)); | 1868 | skb->data[14] == WLAN_TDLS_SNAP_RFTYPE)); |
1862 | } | 1869 | } |
1863 | 1870 | ||
1864 | if (tdls_direct) { | 1871 | if (tdls_direct) { |
1865 | /* link during setup - throw out frames to peer */ | 1872 | /* link during setup - throw out frames to peer */ |
1866 | if (!(sta_flags & WLAN_STA_TDLS_PEER_AUTH)) { | 1873 | if (!tdls_auth) { |
1867 | ret = NETDEV_TX_OK; | 1874 | ret = NETDEV_TX_OK; |
1868 | goto fail; | 1875 | goto fail; |
1869 | } | 1876 | } |
@@ -1912,17 +1919,19 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1912 | if (!is_multicast_ether_addr(hdr.addr1)) { | 1919 | if (!is_multicast_ether_addr(hdr.addr1)) { |
1913 | rcu_read_lock(); | 1920 | rcu_read_lock(); |
1914 | sta = sta_info_get(sdata, hdr.addr1); | 1921 | sta = sta_info_get(sdata, hdr.addr1); |
1915 | if (sta) | 1922 | if (sta) { |
1916 | sta_flags = get_sta_flags(sta); | 1923 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); |
1924 | wme_sta = test_sta_flag(sta, WLAN_STA_WME); | ||
1925 | } | ||
1917 | rcu_read_unlock(); | 1926 | rcu_read_unlock(); |
1918 | } | 1927 | } |
1919 | 1928 | ||
1920 | /* For mesh, the use of the QoS header is mandatory */ | 1929 | /* For mesh, the use of the QoS header is mandatory */ |
1921 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 1930 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
1922 | sta_flags |= WLAN_STA_WME; | 1931 | wme_sta = true; |
1923 | 1932 | ||
1924 | /* receiver and we are QoS enabled, use a QoS type frame */ | 1933 | /* receiver and we are QoS enabled, use a QoS type frame */ |
1925 | if ((sta_flags & WLAN_STA_WME) && local->hw.queues >= 4) { | 1934 | if (wme_sta && local->hw.queues >= 4) { |
1926 | fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); | 1935 | fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); |
1927 | hdrlen += 2; | 1936 | hdrlen += 2; |
1928 | } | 1937 | } |
@@ -1932,8 +1941,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1932 | * EAPOL frames from the local station. | 1941 | * EAPOL frames from the local station. |
1933 | */ | 1942 | */ |
1934 | if (!ieee80211_vif_is_mesh(&sdata->vif) && | 1943 | if (!ieee80211_vif_is_mesh(&sdata->vif) && |
1935 | unlikely(!is_multicast_ether_addr(hdr.addr1) && | 1944 | unlikely(!is_multicast_ether_addr(hdr.addr1) && !authorized && |
1936 | !(sta_flags & WLAN_STA_AUTHORIZED) && | ||
1937 | !(cpu_to_be16(ethertype) == sdata->control_port_protocol && | 1945 | !(cpu_to_be16(ethertype) == sdata->control_port_protocol && |
1938 | compare_ether_addr(sdata->vif.addr, | 1946 | compare_ether_addr(sdata->vif.addr, |
1939 | skb->data + ETH_ALEN) == 0))) { | 1947 | skb->data + ETH_ALEN) == 0))) { |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 60dc600ab65b..7439d26bf5f9 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1122,7 +1122,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1122 | 1122 | ||
1123 | list_for_each_entry(sta, &local->sta_list, list) { | 1123 | list_for_each_entry(sta, &local->sta_list, list) { |
1124 | ieee80211_sta_tear_down_BA_sessions(sta, true); | 1124 | ieee80211_sta_tear_down_BA_sessions(sta, true); |
1125 | clear_sta_flags(sta, WLAN_STA_BLOCK_BA); | 1125 | clear_sta_flag(sta, WLAN_STA_BLOCK_BA); |
1126 | } | 1126 | } |
1127 | 1127 | ||
1128 | mutex_unlock(&local->sta_mtx); | 1128 | mutex_unlock(&local->sta_mtx); |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 971004c9b04f..fd52e695c071 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -72,7 +72,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
72 | case NL80211_IFTYPE_AP_VLAN: | 72 | case NL80211_IFTYPE_AP_VLAN: |
73 | sta = rcu_dereference(sdata->u.vlan.sta); | 73 | sta = rcu_dereference(sdata->u.vlan.sta); |
74 | if (sta) { | 74 | if (sta) { |
75 | qos = get_sta_flags(sta) & WLAN_STA_WME; | 75 | qos = test_sta_flag(sta, WLAN_STA_WME); |
76 | break; | 76 | break; |
77 | } | 77 | } |
78 | case NL80211_IFTYPE_AP: | 78 | case NL80211_IFTYPE_AP: |
@@ -99,7 +99,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
99 | if (!sta && ra && !is_multicast_ether_addr(ra)) { | 99 | if (!sta && ra && !is_multicast_ether_addr(ra)) { |
100 | sta = sta_info_get(sdata, ra); | 100 | sta = sta_info_get(sdata, ra); |
101 | if (sta) | 101 | if (sta) |
102 | qos = get_sta_flags(sta) & WLAN_STA_WME; | 102 | qos = test_sta_flag(sta, WLAN_STA_WME); |
103 | } | 103 | } |
104 | rcu_read_unlock(); | 104 | rcu_read_unlock(); |
105 | 105 | ||