aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/mlme.c77
-rw-r--r--net/mac80211/rx.c6
3 files changed, 52 insertions, 32 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 055bb776408c..8a617a7fc090 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -308,6 +308,7 @@ struct ieee80211_if_managed {
308 unsigned long request; 308 unsigned long request;
309 309
310 unsigned long last_probe; 310 unsigned long last_probe;
311 unsigned long last_beacon;
311 312
312 unsigned int flags; 313 unsigned int flags;
313 314
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 209abb073dfb..8f30f4d19da0 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -30,7 +30,7 @@
30#define IEEE80211_ASSOC_TIMEOUT (HZ / 5) 30#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
31#define IEEE80211_ASSOC_MAX_TRIES 3 31#define IEEE80211_ASSOC_MAX_TRIES 3
32#define IEEE80211_MONITORING_INTERVAL (2 * HZ) 32#define IEEE80211_MONITORING_INTERVAL (2 * HZ)
33#define IEEE80211_PROBE_INTERVAL (60 * HZ) 33#define IEEE80211_PROBE_IDLE_TIME (60 * HZ)
34#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ) 34#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ)
35 35
36/* utils */ 36/* utils */
@@ -930,7 +930,7 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
930 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 930 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
931 struct ieee80211_local *local = sdata->local; 931 struct ieee80211_local *local = sdata->local;
932 struct sta_info *sta; 932 struct sta_info *sta;
933 int disassoc; 933 bool disassoc = false;
934 934
935 /* TODO: start monitoring current AP signal quality and number of 935 /* TODO: start monitoring current AP signal quality and number of
936 * missed beacons. Scan other channels every now and then and search 936 * missed beacons. Scan other channels every now and then and search
@@ -945,36 +945,39 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
945 if (!sta) { 945 if (!sta) {
946 printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", 946 printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n",
947 sdata->dev->name, ifmgd->bssid); 947 sdata->dev->name, ifmgd->bssid);
948 disassoc = 1; 948 disassoc = true;
949 } else { 949 goto unlock;
950 disassoc = 0; 950 }
951 if (time_after(jiffies, 951
952 sta->last_rx + IEEE80211_MONITORING_INTERVAL)) { 952 if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) &&
953 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) { 953 time_after(jiffies, sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
954 printk(KERN_DEBUG "%s: No ProbeResp from " 954 printk(KERN_DEBUG "%s: no probe response from AP %pM "
955 "current AP %pM - assume out of " 955 "- disassociating\n",
956 "range\n", 956 sdata->dev->name, ifmgd->bssid);
957 sdata->dev->name, ifmgd->bssid); 957 disassoc = true;
958 disassoc = 1; 958 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
959 } else 959 goto unlock;
960 ieee80211_send_probe_req(sdata, ifmgd->bssid, 960 }
961 ifmgd->ssid, 961
962 ifmgd->ssid_len, 962 if (time_after(jiffies,
963 NULL, 0); 963 ifmgd->last_beacon + IEEE80211_MONITORING_INTERVAL)) {
964 ifmgd->flags ^= IEEE80211_STA_PROBEREQ_POLL; 964 printk(KERN_DEBUG "%s: beacon loss from AP %pM "
965 } else { 965 "- sending probe request\n",
966 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; 966 sdata->dev->name, ifmgd->bssid);
967 if (time_after(jiffies, ifmgd->last_probe + 967 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
968 IEEE80211_PROBE_INTERVAL)) { 968 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
969 ifmgd->last_probe = jiffies; 969 ifmgd->ssid_len, NULL, 0);
970 ieee80211_send_probe_req(sdata, ifmgd->bssid, 970 goto unlock;
971 ifmgd->ssid, 971
972 ifmgd->ssid_len, 972 }
973 NULL, 0); 973
974 } 974 if (time_after(jiffies, sta->last_rx + IEEE80211_PROBE_IDLE_TIME)) {
975 } 975 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
976 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
977 ifmgd->ssid_len, NULL, 0);
976 } 978 }
977 979
980 unlock:
978 rcu_read_unlock(); 981 rcu_read_unlock();
979 982
980 if (disassoc) 983 if (disassoc)
@@ -1374,6 +1377,12 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1374 bss_conf->assoc_capability = capab_info; 1377 bss_conf->assoc_capability = capab_info;
1375 ieee80211_set_associated(sdata, changed); 1378 ieee80211_set_associated(sdata, changed);
1376 1379
1380 /*
1381 * initialise the time of last beacon to be the association time,
1382 * otherwise beacon loss check will trigger immediately
1383 */
1384 ifmgd->last_beacon = jiffies;
1385
1377 ieee80211_associated(sdata); 1386 ieee80211_associated(sdata);
1378 cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len); 1387 cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len);
1379} 1388}
@@ -1422,9 +1431,12 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1422 size_t len, 1431 size_t len,
1423 struct ieee80211_rx_status *rx_status) 1432 struct ieee80211_rx_status *rx_status)
1424{ 1433{
1434 struct ieee80211_if_managed *ifmgd;
1425 size_t baselen; 1435 size_t baselen;
1426 struct ieee802_11_elems elems; 1436 struct ieee802_11_elems elems;
1427 1437
1438 ifmgd = &sdata->u.mgd;
1439
1428 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN)) 1440 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
1429 return; /* ignore ProbeResp to foreign address */ 1441 return; /* ignore ProbeResp to foreign address */
1430 1442
@@ -1439,11 +1451,14 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1439 1451
1440 /* direct probe may be part of the association flow */ 1452 /* direct probe may be part of the association flow */
1441 if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE, 1453 if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE,
1442 &sdata->u.mgd.request)) { 1454 &ifmgd->request)) {
1443 printk(KERN_DEBUG "%s direct probe responded\n", 1455 printk(KERN_DEBUG "%s direct probe responded\n",
1444 sdata->dev->name); 1456 sdata->dev->name);
1445 ieee80211_authenticate(sdata); 1457 ieee80211_authenticate(sdata);
1446 } 1458 }
1459
1460 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL)
1461 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
1447} 1462}
1448 1463
1449static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, 1464static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index dbfb28465354..eff59f36e8eb 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -850,7 +850,11 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
850 * Mesh beacons will update last_rx when if they are found to 850 * Mesh beacons will update last_rx when if they are found to
851 * match the current local configuration when processed. 851 * match the current local configuration when processed.
852 */ 852 */
853 sta->last_rx = jiffies; 853 if (rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
854 ieee80211_is_beacon(hdr->frame_control)) {
855 rx->sdata->u.mgd.last_beacon = jiffies;
856 } else
857 sta->last_rx = jiffies;
854 } 858 }
855 859
856 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 860 if (!(rx->flags & IEEE80211_RX_RA_MATCH))