aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c60
1 files changed, 33 insertions, 27 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 86c6ad1b058d..bfc4a5070013 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -27,10 +27,6 @@
27#include "rate.h" 27#include "rate.h"
28#include "led.h" 28#include "led.h"
29 29
30#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
31#define IEEE80211_AUTH_MAX_TRIES 3
32#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
33#define IEEE80211_ASSOC_MAX_TRIES 3
34#define IEEE80211_MAX_PROBE_TRIES 5 30#define IEEE80211_MAX_PROBE_TRIES 5
35 31
36/* 32/*
@@ -438,8 +434,11 @@ static void ieee80211_enable_ps(struct ieee80211_local *local,
438 } else { 434 } else {
439 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) 435 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
440 ieee80211_send_nullfunc(local, sdata, 1); 436 ieee80211_send_nullfunc(local, sdata, 1);
441 conf->flags |= IEEE80211_CONF_PS; 437
442 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 438 if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
439 conf->flags |= IEEE80211_CONF_PS;
440 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
441 }
443 } 442 }
444} 443}
445 444
@@ -545,6 +544,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
545 container_of(work, struct ieee80211_local, 544 container_of(work, struct ieee80211_local,
546 dynamic_ps_enable_work); 545 dynamic_ps_enable_work);
547 struct ieee80211_sub_if_data *sdata = local->ps_sdata; 546 struct ieee80211_sub_if_data *sdata = local->ps_sdata;
547 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
548 548
549 /* can only happen when PS was just disabled anyway */ 549 /* can only happen when PS was just disabled anyway */
550 if (!sdata) 550 if (!sdata)
@@ -553,11 +553,16 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
553 if (local->hw.conf.flags & IEEE80211_CONF_PS) 553 if (local->hw.conf.flags & IEEE80211_CONF_PS)
554 return; 554 return;
555 555
556 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) 556 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
557 (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)))
557 ieee80211_send_nullfunc(local, sdata, 1); 558 ieee80211_send_nullfunc(local, sdata, 1);
558 559
559 local->hw.conf.flags |= IEEE80211_CONF_PS; 560 if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) ||
560 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 561 (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
562 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
563 local->hw.conf.flags |= IEEE80211_CONF_PS;
564 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
565 }
561} 566}
562 567
563void ieee80211_dynamic_ps_timer(unsigned long data) 568void ieee80211_dynamic_ps_timer(unsigned long data)
@@ -792,8 +797,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
792 797
793 rcu_read_lock(); 798 rcu_read_lock();
794 sta = sta_info_get(sdata, bssid); 799 sta = sta_info_get(sdata, bssid);
795 if (sta) 800 if (sta) {
801 set_sta_flags(sta, WLAN_STA_DISASSOC);
796 ieee80211_sta_tear_down_BA_sessions(sta); 802 ieee80211_sta_tear_down_BA_sessions(sta);
803 }
797 rcu_read_unlock(); 804 rcu_read_unlock();
798 805
799 changed |= ieee80211_reset_erp_info(sdata); 806 changed |= ieee80211_reset_erp_info(sdata);
@@ -826,19 +833,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
826 changed |= BSS_CHANGED_BSSID; 833 changed |= BSS_CHANGED_BSSID;
827 ieee80211_bss_info_change_notify(sdata, changed); 834 ieee80211_bss_info_change_notify(sdata, changed);
828 835
829 rcu_read_lock(); 836 sta_info_destroy_addr(sdata, bssid);
830
831 sta = sta_info_get(sdata, bssid);
832 if (!sta) {
833 rcu_read_unlock();
834 return;
835 }
836
837 sta_info_unlink(&sta);
838
839 rcu_read_unlock();
840
841 sta_info_destroy(sta);
842} 837}
843 838
844void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 839void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -1844,7 +1839,11 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
1844 wk->probe_auth.algorithm = auth_alg; 1839 wk->probe_auth.algorithm = auth_alg;
1845 wk->probe_auth.privacy = req->bss->capability & WLAN_CAPABILITY_PRIVACY; 1840 wk->probe_auth.privacy = req->bss->capability & WLAN_CAPABILITY_PRIVACY;
1846 1841
1847 wk->type = IEEE80211_WORK_DIRECT_PROBE; 1842 /* if we already have a probe, don't probe again */
1843 if (req->bss->proberesp_ies)
1844 wk->type = IEEE80211_WORK_AUTH;
1845 else
1846 wk->type = IEEE80211_WORK_DIRECT_PROBE;
1848 wk->chan = req->bss->channel; 1847 wk->chan = req->bss->channel;
1849 wk->sdata = sdata; 1848 wk->sdata = sdata;
1850 wk->done = ieee80211_probe_auth_done; 1849 wk->done = ieee80211_probe_auth_done;
@@ -1904,6 +1903,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
1904 return -ENOMEM; 1903 return -ENOMEM;
1905 1904
1906 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; 1905 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
1906 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
1907 1907
1908 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) 1908 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
1909 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || 1909 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
@@ -2007,12 +2007,18 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2007 2007
2008 mutex_lock(&local->work_mtx); 2008 mutex_lock(&local->work_mtx);
2009 list_for_each_entry(wk, &local->work_list, list) { 2009 list_for_each_entry(wk, &local->work_list, list) {
2010 if (wk->type != IEEE80211_WORK_DIRECT_PROBE) 2010 if (wk->sdata != sdata)
2011 continue;
2012
2013 if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
2014 wk->type != IEEE80211_WORK_AUTH)
2011 continue; 2015 continue;
2016
2012 if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) 2017 if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
2013 continue; 2018 continue;
2014 not_auth_yet = true; 2019
2015 list_del(&wk->list); 2020 not_auth_yet = wk->type == IEEE80211_WORK_DIRECT_PROBE;
2021 list_del_rcu(&wk->list);
2016 free_work(wk); 2022 free_work(wk);
2017 break; 2023 break;
2018 } 2024 }