diff options
author | Maxim Levitsky <maximlevitsky@gmail.com> | 2009-07-31 18:54:12 +0300 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-04 16:44:20 -0400 |
commit | a43abf293965230c93a4b74e5d10b9d60b153ab4 (patch) | |
tree | 8b80f5af8cbb04eeb502dafababe1098a5c6ae59 /net/mac80211 | |
parent | 75e6c3b72b3ab01c47629f3fbd0fed4e6550bf3a (diff) | |
download | op-kernel-dev-a43abf293965230c93a4b74e5d10b9d60b153ab4.zip op-kernel-dev-a43abf293965230c93a4b74e5d10b9d60b153ab4.tar.gz |
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 316825b..8d790e4 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -280,6 +280,7 @@ struct ieee80211_if_managed { struct work_struct beacon_loss_work; unsigned long probe_timeout; + int probe_send_count; struct mutex mtx; struct ieee80211_bss *associated; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c9e4091..ccd5c7a 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -31,6 +31,7 @@ #define IEEE80211_AUTH_MAX_TRIES 3 #define IEEE80211_ASSOC_TIMEOUT (HZ / 5) #define IEEE80211_ASSOC_MAX_TRIES 3 +#define IEEE80211_MAX_PROBE_TRIES 5 /* * beacon loss detection timeout @@ -1153,11 +1154,24 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); } +static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + const u8 *ssid; + + ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID); + ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid, + ssid + 2, ssid[1], NULL, 0); + + ifmgd->probe_send_count++; + ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; + run_again(ifmgd, ifmgd->probe_timeout); +} + static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, bool beacon) { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; - const u8 *ssid; bool already = false; if (!netif_running(sdata->dev)) @@ -1200,18 +1214,12 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, if (already) goto out; - ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; - mutex_lock(&sdata->local->iflist_mtx); ieee80211_recalc_ps(sdata->local, -1); mutex_unlock(&sdata->local->iflist_mtx); - ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID); - ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid, - ssid + 2, ssid[1], NULL, 0); - - run_again(ifmgd, ifmgd->probe_timeout); - + ifmgd->probe_send_count = 0; + ieee80211_mgd_probe_ap_send(sdata); out: mutex_unlock(&ifmgd->mtx); } @@ -2064,17 +2072,27 @@ static void ieee80211_sta_work(struct work_struct *work) if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | IEEE80211_STA_CONNECTION_POLL) && ifmgd->associated) { + u8 bssid[ETH_ALEN]; + + memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN); if (time_is_after_jiffies(ifmgd->probe_timeout)) run_again(ifmgd, ifmgd->probe_timeout); - else { - u8 bssid[ETH_ALEN]; + + else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + printk(KERN_DEBUG "No probe response from AP %pM" + " after %dms, try %d\n", bssid, + (1000 * IEEE80211_PROBE_WAIT)/HZ, + ifmgd->probe_send_count); +#endif + ieee80211_mgd_probe_ap_send(sdata); + } else { /* * We actually lost the connection ... or did we? * Let's make sure! */ ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | IEEE80211_STA_BEACON_POLL); - memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN); printk(KERN_DEBUG "No probe response from AP %pM" " after %dms, disconnecting.\n", bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); |