aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-12-02 15:01:08 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-12-06 15:58:44 -0500
commit04ac3c0ee2c773c321ec472d892635a20556f34d (patch)
treee9a3bf81d8feec787fa5b4c5c156652de5313c83 /net/mac80211/mlme.c
parent75706d0e9d19601534446982b70102bb9327169b (diff)
mac80211: speed up AP probing using nullfunc frames
If the nullfunc frame used to probe the AP was not acked, there is no point in waiting for the probe timeout, so advance to the next try (or disconnect) immediately. If we do reach the probe timeout without having received a tx status, the connection is probably really bad and worth disconnecting. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c93
1 files changed, 68 insertions, 25 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f570801514f1..3a1dde3c7956 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1065,16 +1065,20 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
1065} 1065}
1066 1066
1067void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, 1067void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
1068 struct ieee80211_hdr *hdr) 1068 struct ieee80211_hdr *hdr, bool ack)
1069{ 1069{
1070 if (!ieee80211_is_data(hdr->frame_control)) 1070 if (!ieee80211_is_data(hdr->frame_control))
1071 return; 1071 return;
1072 1072
1073 ieee80211_sta_reset_conn_monitor(sdata); 1073 if (ack)
1074 ieee80211_sta_reset_conn_monitor(sdata);
1074 1075
1075 if (ieee80211_is_nullfunc(hdr->frame_control) && 1076 if (ieee80211_is_nullfunc(hdr->frame_control) &&
1076 sdata->u.mgd.probe_send_count > 0) { 1077 sdata->u.mgd.probe_send_count > 0) {
1077 sdata->u.mgd.probe_send_count = 0; 1078 if (ack)
1079 sdata->u.mgd.probe_send_count = 0;
1080 else
1081 sdata->u.mgd.nullfunc_failed = true;
1078 ieee80211_queue_work(&sdata->local->hw, &sdata->work); 1082 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
1079 } 1083 }
1080} 1084}
@@ -1101,9 +1105,10 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1101 * anymore. The timeout will be reset if the frame is ACKed by 1105 * anymore. The timeout will be reset if the frame is ACKed by
1102 * the AP. 1106 * the AP.
1103 */ 1107 */
1104 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) 1108 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
1109 ifmgd->nullfunc_failed = false;
1105 ieee80211_send_nullfunc(sdata->local, sdata, 0); 1110 ieee80211_send_nullfunc(sdata->local, sdata, 0);
1106 else { 1111 } else {
1107 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); 1112 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
1108 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0); 1113 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0);
1109 } 1114 }
@@ -1912,6 +1917,31 @@ static void ieee80211_sta_timer(unsigned long data)
1912 ieee80211_queue_work(&local->hw, &sdata->work); 1917 ieee80211_queue_work(&local->hw, &sdata->work);
1913} 1918}
1914 1919
1920static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
1921 u8 *bssid)
1922{
1923 struct ieee80211_local *local = sdata->local;
1924 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1925
1926 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
1927 IEEE80211_STA_BEACON_POLL);
1928
1929 ieee80211_set_disassoc(sdata, true, true);
1930 mutex_unlock(&ifmgd->mtx);
1931 mutex_lock(&local->mtx);
1932 ieee80211_recalc_idle(local);
1933 mutex_unlock(&local->mtx);
1934 /*
1935 * must be outside lock due to cfg80211,
1936 * but that's not a problem.
1937 */
1938 ieee80211_send_deauth_disassoc(sdata, bssid,
1939 IEEE80211_STYPE_DEAUTH,
1940 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
1941 NULL, true);
1942 mutex_lock(&ifmgd->mtx);
1943}
1944
1915void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) 1945void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1916{ 1946{
1917 struct ieee80211_local *local = sdata->local; 1947 struct ieee80211_local *local = sdata->local;
@@ -1936,11 +1966,38 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1936 /* ACK received for nullfunc probing frame */ 1966 /* ACK received for nullfunc probing frame */
1937 if (!ifmgd->probe_send_count) 1967 if (!ifmgd->probe_send_count)
1938 ieee80211_reset_ap_probe(sdata); 1968 ieee80211_reset_ap_probe(sdata);
1939 1969 else if (ifmgd->nullfunc_failed) {
1940 else if (time_is_after_jiffies(ifmgd->probe_timeout)) 1970 if (ifmgd->probe_send_count < max_tries) {
1971#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1972 wiphy_debug(local->hw.wiphy,
1973 "%s: No ack for nullfunc frame to"
1974 " AP %pM, try %d\n",
1975 sdata->name, bssid,
1976 ifmgd->probe_send_count);
1977#endif
1978 ieee80211_mgd_probe_ap_send(sdata);
1979 } else {
1980#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1981 wiphy_debug(local->hw.wiphy,
1982 "%s: No ack for nullfunc frame to"
1983 " AP %pM, disconnecting.\n",
1984 sdata->name, bssid,
1985 ifmgd->probe_send_count);
1986#endif
1987 ieee80211_sta_connection_lost(sdata, bssid);
1988 }
1989 } else if (time_is_after_jiffies(ifmgd->probe_timeout))
1941 run_again(ifmgd, ifmgd->probe_timeout); 1990 run_again(ifmgd, ifmgd->probe_timeout);
1942 1991 else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
1943 else if (ifmgd->probe_send_count < max_tries) { 1992#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1993 wiphy_debug(local->hw.wiphy,
1994 "%s: Failed to send nullfunc to AP %pM"
1995 " after %dms, disconnecting.\n",
1996 sdata->name,
1997 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
1998#endif
1999 ieee80211_sta_connection_lost(sdata, bssid);
2000 } else if (ifmgd->probe_send_count < max_tries) {
1944#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 2001#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1945 wiphy_debug(local->hw.wiphy, 2002 wiphy_debug(local->hw.wiphy,
1946 "%s: No probe response from AP %pM" 2003 "%s: No probe response from AP %pM"
@@ -1955,27 +2012,13 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1955 * We actually lost the connection ... or did we? 2012 * We actually lost the connection ... or did we?
1956 * Let's make sure! 2013 * Let's make sure!
1957 */ 2014 */
1958 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
1959 IEEE80211_STA_BEACON_POLL);
1960 wiphy_debug(local->hw.wiphy, 2015 wiphy_debug(local->hw.wiphy,
1961 "%s: No probe response from AP %pM" 2016 "%s: No probe response from AP %pM"
1962 " after %dms, disconnecting.\n", 2017 " after %dms, disconnecting.\n",
1963 sdata->name, 2018 sdata->name,
1964 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 2019 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
1965 ieee80211_set_disassoc(sdata, true, true); 2020
1966 mutex_unlock(&ifmgd->mtx); 2021 ieee80211_sta_connection_lost(sdata, bssid);
1967 mutex_lock(&local->mtx);
1968 ieee80211_recalc_idle(local);
1969 mutex_unlock(&local->mtx);
1970 /*
1971 * must be outside lock due to cfg80211,
1972 * but that's not a problem.
1973 */
1974 ieee80211_send_deauth_disassoc(sdata, bssid,
1975 IEEE80211_STYPE_DEAUTH,
1976 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
1977 NULL, true);
1978 mutex_lock(&ifmgd->mtx);
1979 } 2022 }
1980 } 2023 }
1981 2024