aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 509469cb9265..d779c57a8220 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -621,9 +621,6 @@ static void ieee80211_change_ps(struct ieee80211_local *local)
621 struct ieee80211_conf *conf = &local->hw.conf; 621 struct ieee80211_conf *conf = &local->hw.conf;
622 622
623 if (local->ps_sdata) { 623 if (local->ps_sdata) {
624 if (!(local->ps_sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED))
625 return;
626
627 ieee80211_enable_ps(local, local->ps_sdata); 624 ieee80211_enable_ps(local, local->ps_sdata);
628 } else if (conf->flags & IEEE80211_CONF_PS) { 625 } else if (conf->flags & IEEE80211_CONF_PS) {
629 conf->flags &= ~IEEE80211_CONF_PS; 626 conf->flags &= ~IEEE80211_CONF_PS;
@@ -653,7 +650,9 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
653 count++; 650 count++;
654 } 651 }
655 652
656 if (count == 1 && found->u.mgd.powersave) { 653 if (count == 1 && found->u.mgd.powersave &&
654 (found->u.mgd.flags & IEEE80211_STA_ASSOCIATED) &&
655 !(found->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL)) {
657 s32 beaconint_us; 656 s32 beaconint_us;
658 657
659 if (latency < 0) 658 if (latency < 0)
@@ -793,13 +792,13 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
793#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 792#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
794 printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " 793 printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d "
795 "cWmin=%d cWmax=%d txop=%d\n", 794 "cWmin=%d cWmax=%d txop=%d\n",
796 local->mdev->name, queue, aci, acm, params.aifs, params.cw_min, 795 wiphy_name(local->hw.wiphy), queue, aci, acm,
797 params.cw_max, params.txop); 796 params.aifs, params.cw_min, params.cw_max, params.txop);
798#endif 797#endif
799 if (drv_conf_tx(local, queue, &params) && local->ops->conf_tx) 798 if (drv_conf_tx(local, queue, &params) && local->ops->conf_tx)
800 printk(KERN_DEBUG "%s: failed to set TX queue " 799 printk(KERN_DEBUG "%s: failed to set TX queue "
801 "parameters for queue %d\n", local->mdev->name, 800 "parameters for queue %d\n",
802 queue); 801 wiphy_name(local->hw.wiphy), queue);
803 } 802 }
804} 803}
805 804
@@ -1322,6 +1321,11 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
1322#endif 1321#endif
1323 1322
1324 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
1325 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, 1329 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
1326 ifmgd->ssid_len, NULL, 0); 1330 ifmgd->ssid_len, NULL, 0);
1327 1331
@@ -1342,6 +1346,7 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
1342 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1346 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1343 struct ieee80211_local *local = sdata->local; 1347 struct ieee80211_local *local = sdata->local;
1344 struct sta_info *sta; 1348 struct sta_info *sta;
1349 unsigned long last_rx;
1345 bool disassoc = false; 1350 bool disassoc = false;
1346 1351
1347 /* TODO: start monitoring current AP signal quality and number of 1352 /* TODO: start monitoring current AP signal quality and number of
@@ -1358,17 +1363,21 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
1358 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",
1359 sdata->dev->name, ifmgd->bssid); 1364 sdata->dev->name, ifmgd->bssid);
1360 disassoc = true; 1365 disassoc = true;
1361 goto unlock; 1366 rcu_read_unlock();
1367 goto out;
1362 } 1368 }
1363 1369
1370 last_rx = sta->last_rx;
1371 rcu_read_unlock();
1372
1364 if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) && 1373 if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) &&
1365 time_after(jiffies, sta->last_rx + IEEE80211_PROBE_WAIT)) { 1374 time_after(jiffies, last_rx + IEEE80211_PROBE_WAIT)) {
1366 printk(KERN_DEBUG "%s: no probe response from AP %pM " 1375 printk(KERN_DEBUG "%s: no probe response from AP %pM "
1367 "- disassociating\n", 1376 "- disassociating\n",
1368 sdata->dev->name, ifmgd->bssid); 1377 sdata->dev->name, ifmgd->bssid);
1369 disassoc = true; 1378 disassoc = true;
1370 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; 1379 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
1371 goto unlock; 1380 goto out;
1372 } 1381 }
1373 1382
1374 /* 1383 /*
@@ -1387,26 +1396,29 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
1387 } 1396 }
1388#endif 1397#endif
1389 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);
1390 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, 1402 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
1391 ifmgd->ssid_len, NULL, 0); 1403 ifmgd->ssid_len, NULL, 0);
1392 mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT); 1404 mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT);
1393 goto unlock; 1405 goto out;
1394 } 1406 }
1395 1407
1396 if (time_after(jiffies, sta->last_rx + IEEE80211_PROBE_IDLE_TIME)) { 1408 if (time_after(jiffies, last_rx + IEEE80211_PROBE_IDLE_TIME)) {
1397 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);
1398 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, 1413 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
1399 ifmgd->ssid_len, NULL, 0); 1414 ifmgd->ssid_len, NULL, 0);
1400 } 1415 }
1401 1416
1417 out:
1402 if (!disassoc) 1418 if (!disassoc)
1403 mod_timer(&ifmgd->timer, 1419 mod_timer(&ifmgd->timer,
1404 jiffies + IEEE80211_MONITORING_INTERVAL); 1420 jiffies + IEEE80211_MONITORING_INTERVAL);
1405 1421 else
1406 unlock:
1407 rcu_read_unlock();
1408
1409 if (disassoc)
1410 ieee80211_set_disassoc(sdata, true, true, 1422 ieee80211_set_disassoc(sdata, true, true,
1411 WLAN_REASON_PREV_AUTH_NOT_VALID); 1423 WLAN_REASON_PREV_AUTH_NOT_VALID);
1412} 1424}
@@ -1889,8 +1901,12 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1889 ieee80211_authenticate(sdata); 1901 ieee80211_authenticate(sdata);
1890 } 1902 }
1891 1903
1892 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) 1904 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) {
1893 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 }
1894} 1910}
1895 1911
1896/* 1912/*
@@ -1948,6 +1964,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1948 } 1964 }
1949#endif 1965#endif
1950 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);
1951 } 1970 }
1952 1971
1953 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); 1972 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);