summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2014-06-05 14:21:37 +0200
committerJohannes Berg <johannes.berg@intel.com>2014-06-23 14:22:16 +0200
commit10d78f278214bd7c8a15d09ce2304728114786e7 (patch)
tree71c4a711f9cfe08f68c0e3ac3a454287577c5278 /net
parentaf296bdb8da4d0a4284de10fc4a61497272ddf11 (diff)
downloadlinux-10d78f278214bd7c8a15d09ce2304728114786e7.tar.bz2
mac80211: use csa counter offsets instead of csa_active
vif->csa_active is protected by mutexes only. This means it is unreliable to depend on it on codeflow in non-sleepable beacon and CSA code. There was no guarantee to have vif->csa_active update be visible before beacons are updated on SMP systems. Using csa counter offsets which are embedded in beacon struct (and thus are protected with single RCU assignment) is much safer. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/tx.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ed56f0091663..d741b7369dc4 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2538,6 +2538,9 @@ bool ieee80211_csa_is_complete(struct ieee80211_vif *vif)
goto out;
}
+ if (!beacon->csa_counter_offsets[0])
+ goto out;
+
if (WARN_ON_ONCE(beacon->csa_counter_offsets[0] > beacon_data_len))
goto out;
@@ -2582,7 +2585,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
beacon = rcu_dereference(ap->beacon);
if (beacon) {
- if (sdata->vif.csa_active) {
+ if (beacon->csa_counter_offsets[0]) {
if (!is_template)
ieee80211_csa_update_counter(vif);
@@ -2628,7 +2631,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
if (!beacon)
goto out;
- if (sdata->vif.csa_active) {
+ if (beacon->csa_counter_offsets[0]) {
if (!is_template)
ieee80211_csa_update_counter(vif);
@@ -2653,7 +2656,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
if (!beacon)
goto out;
- if (sdata->vif.csa_active) {
+ if (beacon->csa_counter_offsets[0]) {
if (!is_template)
/* TODO: For mesh csa_counter is in TU, so
* decrementing it by one isn't correct, but