diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 60 |
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 | ||
563 | void ieee80211_dynamic_ps_timer(unsigned long data) | 568 | void 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 | ||
844 | void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | 839 | void 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 | } |