summaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 6b75cb6c630..a5e5c31c23a 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2248,10 +2248,13 @@ static void ieee80211_rx_bss_put(struct net_device *dev,
struct ieee80211_sta_bss *bss)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
- if (!atomic_dec_and_test(&bss->users))
+
+ local_bh_disable();
+ if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) {
+ local_bh_enable();
return;
+ }
- spin_lock_bh(&local->sta_bss_lock);
__ieee80211_rx_bss_hash_del(dev, bss);
list_del(&bss->list);
spin_unlock_bh(&local->sta_bss_lock);
@@ -2709,7 +2712,26 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
bss->wmm_ie_len = elems.wmm_param_len + 2;
} else
bss->wmm_ie_len = 0;
- } else if (!elems.wmm_param && bss->wmm_ie) {
+ } else if (elems.wmm_info &&
+ (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_info_len ||
+ memcmp(bss->wmm_ie, elems.wmm_info, elems.wmm_info_len))) {
+ /* As for certain AP's Fifth bit is not set in WMM IE in
+ * beacon frames.So while parsing the beacon frame the
+ * wmm_info structure is used instead of wmm_param.
+ * wmm_info structure was never used to set bss->wmm_ie.
+ * This code fixes this problem by copying the WME
+ * information from wmm_info to bss->wmm_ie and enabling
+ * n-band association.
+ */
+ kfree(bss->wmm_ie);
+ bss->wmm_ie = kmalloc(elems.wmm_info_len + 2, GFP_ATOMIC);
+ if (bss->wmm_ie) {
+ memcpy(bss->wmm_ie, elems.wmm_info - 2,
+ elems.wmm_info_len + 2);
+ bss->wmm_ie_len = elems.wmm_info_len + 2;
+ } else
+ bss->wmm_ie_len = 0;
+ } else if (!elems.wmm_param && !elems.wmm_info && bss->wmm_ie) {
kfree(bss->wmm_ie);
bss->wmm_ie = NULL;
bss->wmm_ie_len = 0;