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.c138
1 files changed, 111 insertions, 27 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 45fbb9e33746..64d92d5a7f40 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -28,8 +28,15 @@
28#include "rate.h" 28#include "rate.h"
29#include "led.h" 29#include "led.h"
30 30
31#define IEEE80211_MAX_NULLFUNC_TRIES 2 31static int max_nullfunc_tries = 2;
32#define IEEE80211_MAX_PROBE_TRIES 5 32module_param(max_nullfunc_tries, int, 0644);
33MODULE_PARM_DESC(max_nullfunc_tries,
34 "Maximum nullfunc tx tries before disconnecting (reason 4).");
35
36static int max_probe_tries = 5;
37module_param(max_probe_tries, int, 0644);
38MODULE_PARM_DESC(max_probe_tries,
39 "Maximum probe tries before disconnecting (reason 4).");
33 40
34/* 41/*
35 * Beacon loss timeout is calculated as N frames times the 42 * Beacon loss timeout is calculated as N frames times the
@@ -51,7 +58,11 @@
51 * a probe request because of beacon loss or for 58 * a probe request because of beacon loss or for
52 * checking the connection still works. 59 * checking the connection still works.
53 */ 60 */
54#define IEEE80211_PROBE_WAIT (HZ / 2) 61static int probe_wait_ms = 500;
62module_param(probe_wait_ms, int, 0644);
63MODULE_PARM_DESC(probe_wait_ms,
64 "Maximum time(ms) to wait for probe response"
65 " before disconnecting (reason 4).");
55 66
56/* 67/*
57 * Weight given to the latest Beacon frame when calculating average signal 68 * Weight given to the latest Beacon frame when calculating average signal
@@ -134,6 +145,9 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
134{ 145{
135 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 146 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
136 147
148 if (unlikely(!sdata->u.mgd.associated))
149 return;
150
137 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) 151 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
138 return; 152 return;
139 153
@@ -161,6 +175,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
161 struct ieee80211_supported_band *sband; 175 struct ieee80211_supported_band *sband;
162 struct sta_info *sta; 176 struct sta_info *sta;
163 u32 changed = 0; 177 u32 changed = 0;
178 int hti_cfreq;
164 u16 ht_opmode; 179 u16 ht_opmode;
165 bool enable_ht = true; 180 bool enable_ht = true;
166 enum nl80211_channel_type prev_chantype; 181 enum nl80211_channel_type prev_chantype;
@@ -174,10 +189,27 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
174 if (!sband->ht_cap.ht_supported) 189 if (!sband->ht_cap.ht_supported)
175 enable_ht = false; 190 enable_ht = false;
176 191
177 /* check that channel matches the right operating channel */ 192 if (enable_ht) {
178 if (local->hw.conf.channel->center_freq != 193 hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan,
179 ieee80211_channel_to_frequency(hti->control_chan)) 194 sband->band);
180 enable_ht = false; 195 /* check that channel matches the right operating channel */
196 if (local->hw.conf.channel->center_freq != hti_cfreq) {
197 /* Some APs mess this up, evidently.
198 * Netgear WNDR3700 sometimes reports 4 higher than
199 * the actual channel, for instance.
200 */
201 printk(KERN_DEBUG
202 "%s: Wrong control channel in association"
203 " response: configured center-freq: %d"
204 " hti-cfreq: %d hti->control_chan: %d"
205 " band: %d. Disabling HT.\n",
206 sdata->name,
207 local->hw.conf.channel->center_freq,
208 hti_cfreq, hti->control_chan,
209 sband->band);
210 enable_ht = false;
211 }
212 }
181 213
182 if (enable_ht) { 214 if (enable_ht) {
183 channel_type = NL80211_CHAN_HT20; 215 channel_type = NL80211_CHAN_HT20;
@@ -429,7 +461,8 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
429 container_of((void *)bss, struct cfg80211_bss, priv); 461 container_of((void *)bss, struct cfg80211_bss, priv);
430 struct ieee80211_channel *new_ch; 462 struct ieee80211_channel *new_ch;
431 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 463 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
432 int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num); 464 int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
465 cbss->channel->band);
433 466
434 ASSERT_MGD_MTX(ifmgd); 467 ASSERT_MGD_MTX(ifmgd);
435 468
@@ -580,6 +613,37 @@ static void ieee80211_change_ps(struct ieee80211_local *local)
580 } 613 }
581} 614}
582 615
616static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
617{
618 struct ieee80211_if_managed *mgd = &sdata->u.mgd;
619 struct sta_info *sta = NULL;
620 u32 sta_flags = 0;
621
622 if (!mgd->powersave)
623 return false;
624
625 if (!mgd->associated)
626 return false;
627
628 if (!mgd->associated->beacon_ies)
629 return false;
630
631 if (mgd->flags & (IEEE80211_STA_BEACON_POLL |
632 IEEE80211_STA_CONNECTION_POLL))
633 return false;
634
635 rcu_read_lock();
636 sta = sta_info_get(sdata, mgd->bssid);
637 if (sta)
638 sta_flags = get_sta_flags(sta);
639 rcu_read_unlock();
640
641 if (!(sta_flags & WLAN_STA_AUTHORIZED))
642 return false;
643
644 return true;
645}
646
583/* need to hold RTNL or interface lock */ 647/* need to hold RTNL or interface lock */
584void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) 648void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
585{ 649{
@@ -600,17 +664,21 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
600 list_for_each_entry(sdata, &local->interfaces, list) { 664 list_for_each_entry(sdata, &local->interfaces, list) {
601 if (!ieee80211_sdata_running(sdata)) 665 if (!ieee80211_sdata_running(sdata))
602 continue; 666 continue;
667 if (sdata->vif.type == NL80211_IFTYPE_AP) {
668 /* If an AP vif is found, then disable PS
669 * by setting the count to zero thereby setting
670 * ps_sdata to NULL.
671 */
672 count = 0;
673 break;
674 }
603 if (sdata->vif.type != NL80211_IFTYPE_STATION) 675 if (sdata->vif.type != NL80211_IFTYPE_STATION)
604 continue; 676 continue;
605 found = sdata; 677 found = sdata;
606 count++; 678 count++;
607 } 679 }
608 680
609 if (count == 1 && found->u.mgd.powersave && 681 if (count == 1 && ieee80211_powersave_allowed(found)) {
610 found->u.mgd.associated &&
611 found->u.mgd.associated->beacon_ies &&
612 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
613 IEEE80211_STA_CONNECTION_POLL))) {
614 struct ieee80211_conf *conf = &local->hw.conf; 682 struct ieee80211_conf *conf = &local->hw.conf;
615 s32 beaconint_us; 683 s32 beaconint_us;
616 684
@@ -700,9 +768,19 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
700 return; 768 return;
701 769
702 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && 770 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
703 (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) 771 (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) {
772 netif_tx_stop_all_queues(sdata->dev);
773 /*
774 * Flush all the frames queued in the driver before
775 * going to power save
776 */
777 drv_flush(local, false);
704 ieee80211_send_nullfunc(local, sdata, 1); 778 ieee80211_send_nullfunc(local, sdata, 1);
705 779
780 /* Flush once again to get the tx status of nullfunc frame */
781 drv_flush(local, false);
782 }
783
706 if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) && 784 if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
707 (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) || 785 (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) ||
708 (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) { 786 (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
@@ -710,6 +788,8 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
710 local->hw.conf.flags |= IEEE80211_CONF_PS; 788 local->hw.conf.flags |= IEEE80211_CONF_PS;
711 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 789 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
712 } 790 }
791
792 netif_tx_start_all_queues(sdata->dev);
713} 793}
714 794
715void ieee80211_dynamic_ps_timer(unsigned long data) 795void ieee80211_dynamic_ps_timer(unsigned long data)
@@ -1089,7 +1169,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1089 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1169 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1090 const u8 *ssid; 1170 const u8 *ssid;
1091 u8 *dst = ifmgd->associated->bssid; 1171 u8 *dst = ifmgd->associated->bssid;
1092 u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3); 1172 u8 unicast_limit = max(1, max_probe_tries - 3);
1093 1173
1094 /* 1174 /*
1095 * Try sending broadcast probe requests for the last three 1175 * Try sending broadcast probe requests for the last three
@@ -1115,7 +1195,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1115 } 1195 }
1116 1196
1117 ifmgd->probe_send_count++; 1197 ifmgd->probe_send_count++;
1118 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; 1198 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
1119 run_again(ifmgd, ifmgd->probe_timeout); 1199 run_again(ifmgd, ifmgd->probe_timeout);
1120} 1200}
1121 1201
@@ -1216,7 +1296,8 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
1216 1296
1217 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); 1297 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
1218 1298
1219 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); 1299 printk(KERN_DEBUG "%s: Connection to AP %pM lost.\n",
1300 sdata->name, bssid);
1220 1301
1221 ieee80211_set_disassoc(sdata, true, true); 1302 ieee80211_set_disassoc(sdata, true, true);
1222 mutex_unlock(&ifmgd->mtx); 1303 mutex_unlock(&ifmgd->mtx);
@@ -1519,7 +1600,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1519 } 1600 }
1520 1601
1521 if (elems->ds_params && elems->ds_params_len == 1) 1602 if (elems->ds_params && elems->ds_params_len == 1)
1522 freq = ieee80211_channel_to_frequency(elems->ds_params[0]); 1603 freq = ieee80211_channel_to_frequency(elems->ds_params[0],
1604 rx_status->band);
1523 else 1605 else
1524 freq = rx_status->freq; 1606 freq = rx_status->freq;
1525 1607
@@ -1960,9 +2042,9 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1960 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); 2042 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
1961 2043
1962 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) 2044 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
1963 max_tries = IEEE80211_MAX_NULLFUNC_TRIES; 2045 max_tries = max_nullfunc_tries;
1964 else 2046 else
1965 max_tries = IEEE80211_MAX_PROBE_TRIES; 2047 max_tries = max_probe_tries;
1966 2048
1967 /* ACK received for nullfunc probing frame */ 2049 /* ACK received for nullfunc probing frame */
1968 if (!ifmgd->probe_send_count) 2050 if (!ifmgd->probe_send_count)
@@ -1972,9 +2054,9 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1972#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 2054#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1973 wiphy_debug(local->hw.wiphy, 2055 wiphy_debug(local->hw.wiphy,
1974 "%s: No ack for nullfunc frame to" 2056 "%s: No ack for nullfunc frame to"
1975 " AP %pM, try %d\n", 2057 " AP %pM, try %d/%i\n",
1976 sdata->name, bssid, 2058 sdata->name, bssid,
1977 ifmgd->probe_send_count); 2059 ifmgd->probe_send_count, max_tries);
1978#endif 2060#endif
1979 ieee80211_mgd_probe_ap_send(sdata); 2061 ieee80211_mgd_probe_ap_send(sdata);
1980 } else { 2062 } else {
@@ -1994,17 +2076,17 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1994 "%s: Failed to send nullfunc to AP %pM" 2076 "%s: Failed to send nullfunc to AP %pM"
1995 " after %dms, disconnecting.\n", 2077 " after %dms, disconnecting.\n",
1996 sdata->name, 2078 sdata->name,
1997 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 2079 bssid, probe_wait_ms);
1998#endif 2080#endif
1999 ieee80211_sta_connection_lost(sdata, bssid); 2081 ieee80211_sta_connection_lost(sdata, bssid);
2000 } else if (ifmgd->probe_send_count < max_tries) { 2082 } else if (ifmgd->probe_send_count < max_tries) {
2001#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 2083#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2002 wiphy_debug(local->hw.wiphy, 2084 wiphy_debug(local->hw.wiphy,
2003 "%s: No probe response from AP %pM" 2085 "%s: No probe response from AP %pM"
2004 " after %dms, try %d\n", 2086 " after %dms, try %d/%i\n",
2005 sdata->name, 2087 sdata->name,
2006 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ, 2088 bssid, probe_wait_ms,
2007 ifmgd->probe_send_count); 2089 ifmgd->probe_send_count, max_tries);
2008#endif 2090#endif
2009 ieee80211_mgd_probe_ap_send(sdata); 2091 ieee80211_mgd_probe_ap_send(sdata);
2010 } else { 2092 } else {
@@ -2016,7 +2098,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2016 "%s: No probe response from AP %pM" 2098 "%s: No probe response from AP %pM"
2017 " after %dms, disconnecting.\n", 2099 " after %dms, disconnecting.\n",
2018 sdata->name, 2100 sdata->name,
2019 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 2101 bssid, probe_wait_ms);
2020 2102
2021 ieee80211_sta_connection_lost(sdata, bssid); 2103 ieee80211_sta_connection_lost(sdata, bssid);
2022 } 2104 }
@@ -2254,6 +2336,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2254 else 2336 else
2255 wk->type = IEEE80211_WORK_DIRECT_PROBE; 2337 wk->type = IEEE80211_WORK_DIRECT_PROBE;
2256 wk->chan = req->bss->channel; 2338 wk->chan = req->bss->channel;
2339 wk->chan_type = NL80211_CHAN_NO_HT;
2257 wk->sdata = sdata; 2340 wk->sdata = sdata;
2258 wk->done = ieee80211_probe_auth_done; 2341 wk->done = ieee80211_probe_auth_done;
2259 2342
@@ -2403,6 +2486,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2403 memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN); 2486 memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN);
2404 2487
2405 wk->chan = req->bss->channel; 2488 wk->chan = req->bss->channel;
2489 wk->chan_type = NL80211_CHAN_NO_HT;
2406 wk->sdata = sdata; 2490 wk->sdata = sdata;
2407 wk->done = ieee80211_assoc_done; 2491 wk->done = ieee80211_assoc_done;
2408 if (!bss->dtim_period && 2492 if (!bss->dtim_period &&