diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 104 |
1 files changed, 73 insertions, 31 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 794807914940..45fbb9e33746 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -625,11 +625,12 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | |||
625 | /* | 625 | /* |
626 | * Go to full PSM if the user configures a very low | 626 | * Go to full PSM if the user configures a very low |
627 | * latency requirement. | 627 | * latency requirement. |
628 | * The 2 second value is there for compatibility until | 628 | * The 2000 second value is there for compatibility |
629 | * the PM_QOS_NETWORK_LATENCY is configured with real | 629 | * until the PM_QOS_NETWORK_LATENCY is configured |
630 | * values. | 630 | * with real values. |
631 | */ | 631 | */ |
632 | if (latency > 1900000000 && latency != 2000000000) | 632 | if (latency > (1900 * USEC_PER_MSEC) && |
633 | latency != (2000 * USEC_PER_SEC)) | ||
633 | timeout = 0; | 634 | timeout = 0; |
634 | else | 635 | else |
635 | timeout = 100; | 636 | timeout = 100; |
@@ -1065,17 +1066,20 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) | |||
1065 | } | 1066 | } |
1066 | 1067 | ||
1067 | void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, | 1068 | void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, |
1068 | struct ieee80211_hdr *hdr) | 1069 | struct ieee80211_hdr *hdr, bool ack) |
1069 | { | 1070 | { |
1070 | if (!ieee80211_is_data(hdr->frame_control) && | 1071 | if (!ieee80211_is_data(hdr->frame_control)) |
1071 | !ieee80211_is_nullfunc(hdr->frame_control)) | ||
1072 | return; | 1072 | return; |
1073 | 1073 | ||
1074 | ieee80211_sta_reset_conn_monitor(sdata); | 1074 | if (ack) |
1075 | ieee80211_sta_reset_conn_monitor(sdata); | ||
1075 | 1076 | ||
1076 | if (ieee80211_is_nullfunc(hdr->frame_control) && | 1077 | if (ieee80211_is_nullfunc(hdr->frame_control) && |
1077 | sdata->u.mgd.probe_send_count > 0) { | 1078 | sdata->u.mgd.probe_send_count > 0) { |
1078 | sdata->u.mgd.probe_send_count = 0; | 1079 | if (ack) |
1080 | sdata->u.mgd.probe_send_count = 0; | ||
1081 | else | ||
1082 | sdata->u.mgd.nullfunc_failed = true; | ||
1079 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); | 1083 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); |
1080 | } | 1084 | } |
1081 | } | 1085 | } |
@@ -1102,9 +1106,10 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | |||
1102 | * anymore. The timeout will be reset if the frame is ACKed by | 1106 | * anymore. The timeout will be reset if the frame is ACKed by |
1103 | * the AP. | 1107 | * the AP. |
1104 | */ | 1108 | */ |
1105 | if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | 1109 | if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { |
1110 | ifmgd->nullfunc_failed = false; | ||
1106 | ieee80211_send_nullfunc(sdata->local, sdata, 0); | 1111 | ieee80211_send_nullfunc(sdata->local, sdata, 0); |
1107 | else { | 1112 | } else { |
1108 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); | 1113 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); |
1109 | ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0); | 1114 | ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0); |
1110 | } | 1115 | } |
@@ -1913,6 +1918,31 @@ static void ieee80211_sta_timer(unsigned long data) | |||
1913 | ieee80211_queue_work(&local->hw, &sdata->work); | 1918 | ieee80211_queue_work(&local->hw, &sdata->work); |
1914 | } | 1919 | } |
1915 | 1920 | ||
1921 | static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | ||
1922 | u8 *bssid) | ||
1923 | { | ||
1924 | struct ieee80211_local *local = sdata->local; | ||
1925 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
1926 | |||
1927 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | ||
1928 | IEEE80211_STA_BEACON_POLL); | ||
1929 | |||
1930 | ieee80211_set_disassoc(sdata, true, true); | ||
1931 | mutex_unlock(&ifmgd->mtx); | ||
1932 | mutex_lock(&local->mtx); | ||
1933 | ieee80211_recalc_idle(local); | ||
1934 | mutex_unlock(&local->mtx); | ||
1935 | /* | ||
1936 | * must be outside lock due to cfg80211, | ||
1937 | * but that's not a problem. | ||
1938 | */ | ||
1939 | ieee80211_send_deauth_disassoc(sdata, bssid, | ||
1940 | IEEE80211_STYPE_DEAUTH, | ||
1941 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, | ||
1942 | NULL, true); | ||
1943 | mutex_lock(&ifmgd->mtx); | ||
1944 | } | ||
1945 | |||
1916 | void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | 1946 | void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) |
1917 | { | 1947 | { |
1918 | struct ieee80211_local *local = sdata->local; | 1948 | struct ieee80211_local *local = sdata->local; |
@@ -1937,11 +1967,37 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
1937 | /* ACK received for nullfunc probing frame */ | 1967 | /* ACK received for nullfunc probing frame */ |
1938 | if (!ifmgd->probe_send_count) | 1968 | if (!ifmgd->probe_send_count) |
1939 | ieee80211_reset_ap_probe(sdata); | 1969 | ieee80211_reset_ap_probe(sdata); |
1940 | 1970 | else if (ifmgd->nullfunc_failed) { | |
1941 | else if (time_is_after_jiffies(ifmgd->probe_timeout)) | 1971 | if (ifmgd->probe_send_count < max_tries) { |
1972 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
1973 | wiphy_debug(local->hw.wiphy, | ||
1974 | "%s: No ack for nullfunc frame to" | ||
1975 | " AP %pM, try %d\n", | ||
1976 | sdata->name, bssid, | ||
1977 | ifmgd->probe_send_count); | ||
1978 | #endif | ||
1979 | ieee80211_mgd_probe_ap_send(sdata); | ||
1980 | } else { | ||
1981 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
1982 | wiphy_debug(local->hw.wiphy, | ||
1983 | "%s: No ack for nullfunc frame to" | ||
1984 | " AP %pM, disconnecting.\n", | ||
1985 | sdata->name, bssid); | ||
1986 | #endif | ||
1987 | ieee80211_sta_connection_lost(sdata, bssid); | ||
1988 | } | ||
1989 | } else if (time_is_after_jiffies(ifmgd->probe_timeout)) | ||
1942 | run_again(ifmgd, ifmgd->probe_timeout); | 1990 | run_again(ifmgd, ifmgd->probe_timeout); |
1943 | 1991 | else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { | |
1944 | 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) { | ||
1945 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 2001 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1946 | wiphy_debug(local->hw.wiphy, | 2002 | wiphy_debug(local->hw.wiphy, |
1947 | "%s: No probe response from AP %pM" | 2003 | "%s: No probe response from AP %pM" |
@@ -1956,27 +2012,13 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
1956 | * We actually lost the connection ... or did we? | 2012 | * We actually lost the connection ... or did we? |
1957 | * Let's make sure! | 2013 | * Let's make sure! |
1958 | */ | 2014 | */ |
1959 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | ||
1960 | IEEE80211_STA_BEACON_POLL); | ||
1961 | wiphy_debug(local->hw.wiphy, | 2015 | wiphy_debug(local->hw.wiphy, |
1962 | "%s: No probe response from AP %pM" | 2016 | "%s: No probe response from AP %pM" |
1963 | " after %dms, disconnecting.\n", | 2017 | " after %dms, disconnecting.\n", |
1964 | sdata->name, | 2018 | sdata->name, |
1965 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); | 2019 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); |
1966 | ieee80211_set_disassoc(sdata, true, true); | 2020 | |
1967 | mutex_unlock(&ifmgd->mtx); | 2021 | ieee80211_sta_connection_lost(sdata, bssid); |
1968 | mutex_lock(&local->mtx); | ||
1969 | ieee80211_recalc_idle(local); | ||
1970 | mutex_unlock(&local->mtx); | ||
1971 | /* | ||
1972 | * must be outside lock due to cfg80211, | ||
1973 | * but that's not a problem. | ||
1974 | */ | ||
1975 | ieee80211_send_deauth_disassoc(sdata, bssid, | ||
1976 | IEEE80211_STYPE_DEAUTH, | ||
1977 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, | ||
1978 | NULL, true); | ||
1979 | mutex_lock(&ifmgd->mtx); | ||
1980 | } | 2022 | } |
1981 | } | 2023 | } |
1982 | 2024 | ||