aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/mlme.c45
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);