diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index dfa752e5520b..f77adf1a520e 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 | 31 | static int max_nullfunc_tries = 2; |
32 | #define IEEE80211_MAX_PROBE_TRIES 5 | 32 | module_param(max_nullfunc_tries, int, 0644); |
33 | MODULE_PARM_DESC(max_nullfunc_tries, | ||
34 | "Maximum nullfunc tx tries before disconnecting (reason 4)."); | ||
35 | |||
36 | static int max_probe_tries = 5; | ||
37 | module_param(max_probe_tries, int, 0644); | ||
38 | MODULE_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) | 61 | static int probe_wait_ms = 500; |
62 | module_param(probe_wait_ms, int, 0644); | ||
63 | MODULE_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 |
@@ -161,6 +172,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
161 | struct ieee80211_supported_band *sband; | 172 | struct ieee80211_supported_band *sband; |
162 | struct sta_info *sta; | 173 | struct sta_info *sta; |
163 | u32 changed = 0; | 174 | u32 changed = 0; |
175 | int hti_cfreq; | ||
164 | u16 ht_opmode; | 176 | u16 ht_opmode; |
165 | bool enable_ht = true; | 177 | bool enable_ht = true; |
166 | enum nl80211_channel_type prev_chantype; | 178 | enum nl80211_channel_type prev_chantype; |
@@ -174,10 +186,27 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
174 | if (!sband->ht_cap.ht_supported) | 186 | if (!sband->ht_cap.ht_supported) |
175 | enable_ht = false; | 187 | enable_ht = false; |
176 | 188 | ||
177 | /* check that channel matches the right operating channel */ | 189 | if (enable_ht) { |
178 | if (local->hw.conf.channel->center_freq != | 190 | hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan, |
179 | ieee80211_channel_to_frequency(hti->control_chan, sband->band)) | 191 | sband->band); |
180 | enable_ht = false; | 192 | /* check that channel matches the right operating channel */ |
193 | if (local->hw.conf.channel->center_freq != hti_cfreq) { | ||
194 | /* Some APs mess this up, evidently. | ||
195 | * Netgear WNDR3700 sometimes reports 4 higher than | ||
196 | * the actual channel, for instance. | ||
197 | */ | ||
198 | printk(KERN_DEBUG | ||
199 | "%s: Wrong control channel in association" | ||
200 | " response: configured center-freq: %d" | ||
201 | " hti-cfreq: %d hti->control_chan: %d" | ||
202 | " band: %d. Disabling HT.\n", | ||
203 | sdata->name, | ||
204 | local->hw.conf.channel->center_freq, | ||
205 | hti_cfreq, hti->control_chan, | ||
206 | sband->band); | ||
207 | enable_ht = false; | ||
208 | } | ||
209 | } | ||
181 | 210 | ||
182 | if (enable_ht) { | 211 | if (enable_ht) { |
183 | channel_type = NL80211_CHAN_HT20; | 212 | channel_type = NL80211_CHAN_HT20; |
@@ -1098,7 +1127,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | |||
1098 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1127 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1099 | const u8 *ssid; | 1128 | const u8 *ssid; |
1100 | u8 *dst = ifmgd->associated->bssid; | 1129 | u8 *dst = ifmgd->associated->bssid; |
1101 | u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3); | 1130 | u8 unicast_limit = max(1, max_probe_tries - 3); |
1102 | 1131 | ||
1103 | /* | 1132 | /* |
1104 | * Try sending broadcast probe requests for the last three | 1133 | * Try sending broadcast probe requests for the last three |
@@ -1124,7 +1153,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | |||
1124 | } | 1153 | } |
1125 | 1154 | ||
1126 | ifmgd->probe_send_count++; | 1155 | ifmgd->probe_send_count++; |
1127 | ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; | 1156 | ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); |
1128 | run_again(ifmgd, ifmgd->probe_timeout); | 1157 | run_again(ifmgd, ifmgd->probe_timeout); |
1129 | } | 1158 | } |
1130 | 1159 | ||
@@ -1225,7 +1254,8 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) | |||
1225 | 1254 | ||
1226 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); | 1255 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); |
1227 | 1256 | ||
1228 | printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); | 1257 | printk(KERN_DEBUG "%s: Connection to AP %pM lost.\n", |
1258 | sdata->name, bssid); | ||
1229 | 1259 | ||
1230 | ieee80211_set_disassoc(sdata, true, true); | 1260 | ieee80211_set_disassoc(sdata, true, true); |
1231 | mutex_unlock(&ifmgd->mtx); | 1261 | mutex_unlock(&ifmgd->mtx); |
@@ -1970,9 +2000,9 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
1970 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); | 2000 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); |
1971 | 2001 | ||
1972 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | 2002 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) |
1973 | max_tries = IEEE80211_MAX_NULLFUNC_TRIES; | 2003 | max_tries = max_nullfunc_tries; |
1974 | else | 2004 | else |
1975 | max_tries = IEEE80211_MAX_PROBE_TRIES; | 2005 | max_tries = max_probe_tries; |
1976 | 2006 | ||
1977 | /* ACK received for nullfunc probing frame */ | 2007 | /* ACK received for nullfunc probing frame */ |
1978 | if (!ifmgd->probe_send_count) | 2008 | if (!ifmgd->probe_send_count) |
@@ -2004,7 +2034,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
2004 | "%s: Failed to send nullfunc to AP %pM" | 2034 | "%s: Failed to send nullfunc to AP %pM" |
2005 | " after %dms, disconnecting.\n", | 2035 | " after %dms, disconnecting.\n", |
2006 | sdata->name, | 2036 | sdata->name, |
2007 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); | 2037 | bssid, probe_wait_ms); |
2008 | #endif | 2038 | #endif |
2009 | ieee80211_sta_connection_lost(sdata, bssid); | 2039 | ieee80211_sta_connection_lost(sdata, bssid); |
2010 | } else if (ifmgd->probe_send_count < max_tries) { | 2040 | } else if (ifmgd->probe_send_count < max_tries) { |
@@ -2013,7 +2043,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
2013 | "%s: No probe response from AP %pM" | 2043 | "%s: No probe response from AP %pM" |
2014 | " after %dms, try %d/%i\n", | 2044 | " after %dms, try %d/%i\n", |
2015 | sdata->name, | 2045 | sdata->name, |
2016 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ, | 2046 | bssid, probe_wait_ms, |
2017 | ifmgd->probe_send_count, max_tries); | 2047 | ifmgd->probe_send_count, max_tries); |
2018 | #endif | 2048 | #endif |
2019 | ieee80211_mgd_probe_ap_send(sdata); | 2049 | ieee80211_mgd_probe_ap_send(sdata); |
@@ -2026,7 +2056,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
2026 | "%s: No probe response from AP %pM" | 2056 | "%s: No probe response from AP %pM" |
2027 | " after %dms, disconnecting.\n", | 2057 | " after %dms, disconnecting.\n", |
2028 | sdata->name, | 2058 | sdata->name, |
2029 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); | 2059 | bssid, probe_wait_ms); |
2030 | 2060 | ||
2031 | ieee80211_sta_connection_lost(sdata, bssid); | 2061 | ieee80211_sta_connection_lost(sdata, bssid); |
2032 | } | 2062 | } |