aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxim Levitsky <maximlevitsky@gmail.com>2009-07-31 11:54:12 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-04 16:44:20 -0400
commita43abf293965230c93a4b74e5d10b9d60b153ab4 (patch)
tree8b80f5af8cbb04eeb502dafababe1098a5c6ae59
parent75e6c3b72b3ab01c47629f3fbd0fed4e6550bf3a (diff)
mac80211: Retry probe request few times
Retry 5 times (chosen arbitary ), before assuming that station is out of range. Fixes frequent disassociations while connected to weak, and sometimes even strong access points. Signed-off-by: Maxim Levitky <maximlevitsky@gmail.com> Acked-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/mlme.c42
2 files changed, 31 insertions, 12 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 316825be2019..8d790e40f3e9 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -280,6 +280,7 @@ struct ieee80211_if_managed {
280 struct work_struct beacon_loss_work; 280 struct work_struct beacon_loss_work;
281 281
282 unsigned long probe_timeout; 282 unsigned long probe_timeout;
283 int probe_send_count;
283 284
284 struct mutex mtx; 285 struct mutex mtx;
285 struct ieee80211_bss *associated; 286 struct ieee80211_bss *associated;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c9e4091cd2bb..ccd5c7a1749f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -31,6 +31,7 @@
31#define IEEE80211_AUTH_MAX_TRIES 3 31#define IEEE80211_AUTH_MAX_TRIES 3
32#define IEEE80211_ASSOC_TIMEOUT (HZ / 5) 32#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
33#define IEEE80211_ASSOC_MAX_TRIES 3 33#define IEEE80211_ASSOC_MAX_TRIES 3
34#define IEEE80211_MAX_PROBE_TRIES 5
34 35
35/* 36/*
36 * beacon loss detection timeout 37 * beacon loss detection timeout
@@ -1153,11 +1154,24 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1153 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); 1154 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
1154} 1155}
1155 1156
1157static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1158{
1159 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1160 const u8 *ssid;
1161
1162 ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID);
1163 ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid,
1164 ssid + 2, ssid[1], NULL, 0);
1165
1166 ifmgd->probe_send_count++;
1167 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
1168 run_again(ifmgd, ifmgd->probe_timeout);
1169}
1170
1156static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, 1171static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
1157 bool beacon) 1172 bool beacon)
1158{ 1173{
1159 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1174 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1160 const u8 *ssid;
1161 bool already = false; 1175 bool already = false;
1162 1176
1163 if (!netif_running(sdata->dev)) 1177 if (!netif_running(sdata->dev))
@@ -1200,18 +1214,12 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
1200 if (already) 1214 if (already)
1201 goto out; 1215 goto out;
1202 1216
1203 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
1204
1205 mutex_lock(&sdata->local->iflist_mtx); 1217 mutex_lock(&sdata->local->iflist_mtx);
1206 ieee80211_recalc_ps(sdata->local, -1); 1218 ieee80211_recalc_ps(sdata->local, -1);
1207 mutex_unlock(&sdata->local->iflist_mtx); 1219 mutex_unlock(&sdata->local->iflist_mtx);
1208 1220
1209 ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID); 1221 ifmgd->probe_send_count = 0;
1210 ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid, 1222 ieee80211_mgd_probe_ap_send(sdata);
1211 ssid + 2, ssid[1], NULL, 0);
1212
1213 run_again(ifmgd, ifmgd->probe_timeout);
1214
1215 out: 1223 out:
1216 mutex_unlock(&ifmgd->mtx); 1224 mutex_unlock(&ifmgd->mtx);
1217} 1225}
@@ -2064,17 +2072,27 @@ static void ieee80211_sta_work(struct work_struct *work)
2064 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 2072 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
2065 IEEE80211_STA_CONNECTION_POLL) && 2073 IEEE80211_STA_CONNECTION_POLL) &&
2066 ifmgd->associated) { 2074 ifmgd->associated) {
2075 u8 bssid[ETH_ALEN];
2076
2077 memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN);
2067 if (time_is_after_jiffies(ifmgd->probe_timeout)) 2078 if (time_is_after_jiffies(ifmgd->probe_timeout))
2068 run_again(ifmgd, ifmgd->probe_timeout); 2079 run_again(ifmgd, ifmgd->probe_timeout);
2069 else { 2080
2070 u8 bssid[ETH_ALEN]; 2081 else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
2082#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2083 printk(KERN_DEBUG "No probe response from AP %pM"
2084 " after %dms, try %d\n", bssid,
2085 (1000 * IEEE80211_PROBE_WAIT)/HZ,
2086 ifmgd->probe_send_count);
2087#endif
2088 ieee80211_mgd_probe_ap_send(sdata);
2089 } else {
2071 /* 2090 /*
2072 * We actually lost the connection ... or did we? 2091 * We actually lost the connection ... or did we?
2073 * Let's make sure! 2092 * Let's make sure!
2074 */ 2093 */
2075 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | 2094 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
2076 IEEE80211_STA_BEACON_POLL); 2095 IEEE80211_STA_BEACON_POLL);
2077 memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN);
2078 printk(KERN_DEBUG "No probe response from AP %pM" 2096 printk(KERN_DEBUG "No probe response from AP %pM"
2079 " after %dms, disconnecting.\n", 2097 " after %dms, disconnecting.\n",
2080 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 2098 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);