aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/mlme.c93
-rw-r--r--net/mac80211/status.c18
3 files changed, 79 insertions, 35 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 66b0b52b828d..e7c880725639 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -357,6 +357,7 @@ struct ieee80211_if_managed {
357 unsigned long beacon_timeout; 357 unsigned long beacon_timeout;
358 unsigned long probe_timeout; 358 unsigned long probe_timeout;
359 int probe_send_count; 359 int probe_send_count;
360 bool nullfunc_failed;
360 361
361 struct mutex mtx; 362 struct mutex mtx;
362 struct cfg80211_bss *associated; 363 struct cfg80211_bss *associated;
@@ -1271,7 +1272,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
1271void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1272void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1272 struct ieee80211_hdr *hdr); 1273 struct ieee80211_hdr *hdr);
1273void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, 1274void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
1274 struct ieee80211_hdr *hdr); 1275 struct ieee80211_hdr *hdr, bool ack);
1275void ieee80211_beacon_connection_loss_work(struct work_struct *work); 1276void ieee80211_beacon_connection_loss_work(struct work_struct *work);
1276 1277
1277void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 1278void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
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
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 4958710a7d92..38a797217a91 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -155,10 +155,6 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
155 155
156 ieee80211_queue_work(&local->hw, &local->recalc_smps); 156 ieee80211_queue_work(&local->hw, &local->recalc_smps);
157 } 157 }
158
159 if ((sdata->vif.type == NL80211_IFTYPE_STATION) &&
160 (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
161 ieee80211_sta_tx_notify(sdata, (void *) skb->data);
162} 158}
163 159
164/* 160/*
@@ -186,6 +182,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
186 int retry_count = -1, i; 182 int retry_count = -1, i;
187 int rates_idx = -1; 183 int rates_idx = -1;
188 bool send_to_cooked; 184 bool send_to_cooked;
185 bool acked;
189 186
190 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 187 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
191 /* the HW cannot have attempted that rate */ 188 /* the HW cannot have attempted that rate */
@@ -211,8 +208,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
211 if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN)) 208 if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN))
212 continue; 209 continue;
213 210
214 if (!(info->flags & IEEE80211_TX_STAT_ACK) && 211 acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
215 test_sta_flags(sta, WLAN_STA_PS_STA)) { 212 if (!acked && test_sta_flags(sta, WLAN_STA_PS_STA)) {
216 /* 213 /*
217 * The STA is in power save mode, so assume 214 * The STA is in power save mode, so assume
218 * that this TX packet failed because of that. 215 * that this TX packet failed because of that.
@@ -244,7 +241,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
244 rcu_read_unlock(); 241 rcu_read_unlock();
245 return; 242 return;
246 } else { 243 } else {
247 if (!(info->flags & IEEE80211_TX_STAT_ACK)) 244 if (!acked)
248 sta->tx_retry_failed++; 245 sta->tx_retry_failed++;
249 sta->tx_retry_count += retry_count; 246 sta->tx_retry_count += retry_count;
250 } 247 }
@@ -253,10 +250,13 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
253 if (ieee80211_vif_is_mesh(&sta->sdata->vif)) 250 if (ieee80211_vif_is_mesh(&sta->sdata->vif))
254 ieee80211s_update_metric(local, sta, skb); 251 ieee80211s_update_metric(local, sta, skb);
255 252
256 if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && 253 if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && acked)
257 (info->flags & IEEE80211_TX_STAT_ACK))
258 ieee80211_frame_acked(sta, skb); 254 ieee80211_frame_acked(sta, skb);
259 255
256 if ((sta->sdata->vif.type == NL80211_IFTYPE_STATION) &&
257 (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
258 ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, acked);
259
260 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { 260 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
261 if (info->flags & IEEE80211_TX_STAT_ACK) { 261 if (info->flags & IEEE80211_TX_STAT_ACK) {
262 if (sta->lost_packets) 262 if (sta->lost_packets)