aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-06-10 09:16:52 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-06-10 13:28:41 -0400
commit4e751843d406a4d0471c207872b9e24957de8357 (patch)
tree0f3aec11337d37d45215a8a498bd5ce6b6edc507 /net/mac80211
parent43f7853180ed522944b3b1d4979cdb9f2b103ca3 (diff)
mac80211: disable PS while probing AP
When associated, but probing the AP because we detected beacon loss, we need to disable powersave to be able to receive the probe response. Change the code to do that by checking whether we're trying to probe when determining the possibility of going into PS, and recalculate the PS ability at the necessary spots. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-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 898e9b02aaa..d779c57a822 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);