diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 77 | ||||
-rw-r--r-- | net/mac80211/rx.c | 6 |
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 | ||
1449 | static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | 1464 | static 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)) |