diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/mlme.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 898e9b02aaac..d779c57a8220 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -651,7 +651,8 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | |||
651 | } | 651 | } |
652 | 652 | ||
653 | if (count == 1 && found->u.mgd.powersave && | 653 | if (count == 1 && found->u.mgd.powersave && |
654 | (found->u.mgd.flags & IEEE80211_STA_ASSOCIATED)) { | 654 | (found->u.mgd.flags & IEEE80211_STA_ASSOCIATED) && |
655 | !(found->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL)) { | ||
655 | s32 beaconint_us; | 656 | s32 beaconint_us; |
656 | 657 | ||
657 | if (latency < 0) | 658 | if (latency < 0) |
@@ -1320,6 +1321,11 @@ void ieee80211_beacon_loss_work(struct work_struct *work) | |||
1320 | #endif | 1321 | #endif |
1321 | 1322 | ||
1322 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; | 1323 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; |
1324 | |||
1325 | mutex_lock(&sdata->local->iflist_mtx); | ||
1326 | ieee80211_recalc_ps(sdata->local, -1); | ||
1327 | mutex_unlock(&sdata->local->iflist_mtx); | ||
1328 | |||
1323 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, | 1329 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, |
1324 | ifmgd->ssid_len, NULL, 0); | 1330 | ifmgd->ssid_len, NULL, 0); |
1325 | 1331 | ||
@@ -1340,6 +1346,7 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) | |||
1340 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1346 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1341 | struct ieee80211_local *local = sdata->local; | 1347 | struct ieee80211_local *local = sdata->local; |
1342 | struct sta_info *sta; | 1348 | struct sta_info *sta; |
1349 | unsigned long last_rx; | ||
1343 | bool disassoc = false; | 1350 | bool disassoc = false; |
1344 | 1351 | ||
1345 | /* TODO: start monitoring current AP signal quality and number of | 1352 | /* TODO: start monitoring current AP signal quality and number of |
@@ -1356,17 +1363,21 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) | |||
1356 | printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", | 1363 | printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", |
1357 | sdata->dev->name, ifmgd->bssid); | 1364 | sdata->dev->name, ifmgd->bssid); |
1358 | disassoc = true; | 1365 | disassoc = true; |
1359 | goto unlock; | 1366 | rcu_read_unlock(); |
1367 | goto out; | ||
1360 | } | 1368 | } |
1361 | 1369 | ||
1370 | last_rx = sta->last_rx; | ||
1371 | rcu_read_unlock(); | ||
1372 | |||
1362 | if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) && | 1373 | if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) && |
1363 | time_after(jiffies, sta->last_rx + IEEE80211_PROBE_WAIT)) { | 1374 | time_after(jiffies, last_rx + IEEE80211_PROBE_WAIT)) { |
1364 | printk(KERN_DEBUG "%s: no probe response from AP %pM " | 1375 | printk(KERN_DEBUG "%s: no probe response from AP %pM " |
1365 | "- disassociating\n", | 1376 | "- disassociating\n", |
1366 | sdata->dev->name, ifmgd->bssid); | 1377 | sdata->dev->name, ifmgd->bssid); |
1367 | disassoc = true; | 1378 | disassoc = true; |
1368 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; | 1379 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; |
1369 | goto unlock; | 1380 | goto out; |
1370 | } | 1381 | } |
1371 | 1382 | ||
1372 | /* | 1383 | /* |
@@ -1385,26 +1396,29 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) | |||
1385 | } | 1396 | } |
1386 | #endif | 1397 | #endif |
1387 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; | 1398 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; |
1399 | mutex_lock(&local->iflist_mtx); | ||
1400 | ieee80211_recalc_ps(local, -1); | ||
1401 | mutex_unlock(&local->iflist_mtx); | ||
1388 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, | 1402 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, |
1389 | ifmgd->ssid_len, NULL, 0); | 1403 | ifmgd->ssid_len, NULL, 0); |
1390 | mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT); | 1404 | mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT); |
1391 | goto unlock; | 1405 | goto out; |
1392 | } | 1406 | } |
1393 | 1407 | ||
1394 | if (time_after(jiffies, sta->last_rx + IEEE80211_PROBE_IDLE_TIME)) { | 1408 | if (time_after(jiffies, last_rx + IEEE80211_PROBE_IDLE_TIME)) { |
1395 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; | 1409 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; |
1410 | mutex_lock(&local->iflist_mtx); | ||
1411 | ieee80211_recalc_ps(local, -1); | ||
1412 | mutex_unlock(&local->iflist_mtx); | ||
1396 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, | 1413 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, |
1397 | ifmgd->ssid_len, NULL, 0); | 1414 | ifmgd->ssid_len, NULL, 0); |
1398 | } | 1415 | } |
1399 | 1416 | ||
1417 | out: | ||
1400 | if (!disassoc) | 1418 | if (!disassoc) |
1401 | mod_timer(&ifmgd->timer, | 1419 | mod_timer(&ifmgd->timer, |
1402 | jiffies + IEEE80211_MONITORING_INTERVAL); | 1420 | jiffies + IEEE80211_MONITORING_INTERVAL); |
1403 | 1421 | else | |
1404 | unlock: | ||
1405 | rcu_read_unlock(); | ||
1406 | |||
1407 | if (disassoc) | ||
1408 | ieee80211_set_disassoc(sdata, true, true, | 1422 | ieee80211_set_disassoc(sdata, true, true, |
1409 | WLAN_REASON_PREV_AUTH_NOT_VALID); | 1423 | WLAN_REASON_PREV_AUTH_NOT_VALID); |
1410 | } | 1424 | } |
@@ -1887,8 +1901,12 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
1887 | ieee80211_authenticate(sdata); | 1901 | ieee80211_authenticate(sdata); |
1888 | } | 1902 | } |
1889 | 1903 | ||
1890 | if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) | 1904 | if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) { |
1891 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; | 1905 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; |
1906 | mutex_lock(&sdata->local->iflist_mtx); | ||
1907 | ieee80211_recalc_ps(sdata->local, -1); | ||
1908 | mutex_unlock(&sdata->local->iflist_mtx); | ||
1909 | } | ||
1892 | } | 1910 | } |
1893 | 1911 | ||
1894 | /* | 1912 | /* |
@@ -1946,6 +1964,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1946 | } | 1964 | } |
1947 | #endif | 1965 | #endif |
1948 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; | 1966 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; |
1967 | mutex_lock(&local->iflist_mtx); | ||
1968 | ieee80211_recalc_ps(local, -1); | ||
1969 | mutex_unlock(&local->iflist_mtx); | ||
1949 | } | 1970 | } |
1950 | 1971 | ||
1951 | ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); | 1972 | ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); |