diff options
author | Maxim Levitsky <maximlevitsky@gmail.com> | 2009-07-31 11:54:12 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-04 16:44:20 -0400 |
commit | a43abf293965230c93a4b74e5d10b9d60b153ab4 (patch) | |
tree | 8b80f5af8cbb04eeb502dafababe1098a5c6ae59 /net/mac80211 | |
parent | 75e6c3b72b3ab01c47629f3fbd0fed4e6550bf3a (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>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 42 |
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 | ||
1157 | static 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 | |||
1156 | static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | 1171 | static 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); |