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.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 77913a15f537..5695c94c49aa 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -913,7 +913,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
913 913
914 mutex_lock(&local->iflist_mtx); 914 mutex_lock(&local->iflist_mtx);
915 ieee80211_recalc_ps(local, -1); 915 ieee80211_recalc_ps(local, -1);
916 ieee80211_recalc_smps(local, sdata); 916 ieee80211_recalc_smps(local);
917 mutex_unlock(&local->iflist_mtx); 917 mutex_unlock(&local->iflist_mtx);
918 918
919 netif_tx_start_all_queues(sdata->dev); 919 netif_tx_start_all_queues(sdata->dev);
@@ -921,7 +921,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
921} 921}
922 922
923static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, 923static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
924 bool remove_sta) 924 bool remove_sta, bool tx)
925{ 925{
926 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 926 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
927 struct ieee80211_local *local = sdata->local; 927 struct ieee80211_local *local = sdata->local;
@@ -960,7 +960,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
960 sta = sta_info_get(sdata, bssid); 960 sta = sta_info_get(sdata, bssid);
961 if (sta) { 961 if (sta) {
962 set_sta_flags(sta, WLAN_STA_BLOCK_BA); 962 set_sta_flags(sta, WLAN_STA_BLOCK_BA);
963 ieee80211_sta_tear_down_BA_sessions(sta); 963 ieee80211_sta_tear_down_BA_sessions(sta, tx);
964 } 964 }
965 mutex_unlock(&local->sta_mtx); 965 mutex_unlock(&local->sta_mtx);
966 966
@@ -1124,7 +1124,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
1124 1124
1125 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); 1125 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);
1126 1126
1127 ieee80211_set_disassoc(sdata, true); 1127 ieee80211_set_disassoc(sdata, true, true);
1128 mutex_unlock(&ifmgd->mtx); 1128 mutex_unlock(&ifmgd->mtx);
1129 1129
1130 mutex_lock(&local->mtx); 1130 mutex_lock(&local->mtx);
@@ -1197,7 +1197,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1197 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", 1197 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
1198 sdata->name, bssid, reason_code); 1198 sdata->name, bssid, reason_code);
1199 1199
1200 ieee80211_set_disassoc(sdata, true); 1200 ieee80211_set_disassoc(sdata, true, false);
1201 mutex_lock(&sdata->local->mtx); 1201 mutex_lock(&sdata->local->mtx);
1202 ieee80211_recalc_idle(sdata->local); 1202 ieee80211_recalc_idle(sdata->local);
1203 mutex_unlock(&sdata->local->mtx); 1203 mutex_unlock(&sdata->local->mtx);
@@ -1229,7 +1229,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1229 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", 1229 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
1230 sdata->name, mgmt->sa, reason_code); 1230 sdata->name, mgmt->sa, reason_code);
1231 1231
1232 ieee80211_set_disassoc(sdata, true); 1232 ieee80211_set_disassoc(sdata, true, false);
1233 mutex_lock(&sdata->local->mtx); 1233 mutex_lock(&sdata->local->mtx);
1234 ieee80211_recalc_idle(sdata->local); 1234 ieee80211_recalc_idle(sdata->local);
1235 mutex_unlock(&sdata->local->mtx); 1235 mutex_unlock(&sdata->local->mtx);
@@ -1291,7 +1291,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1291 1291
1292 rates = 0; 1292 rates = 0;
1293 basic_rates = 0; 1293 basic_rates = 0;
1294 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1294 sband = local->hw.wiphy->bands[wk->chan->band];
1295 1295
1296 for (i = 0; i < elems.supp_rates_len; i++) { 1296 for (i = 0; i < elems.supp_rates_len; i++) {
1297 int rate = (elems.supp_rates[i] & 0x7f) * 5; 1297 int rate = (elems.supp_rates[i] & 0x7f) * 5;
@@ -1327,11 +1327,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1327 } 1327 }
1328 } 1328 }
1329 1329
1330 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 1330 sta->sta.supp_rates[wk->chan->band] = rates;
1331 sdata->vif.bss_conf.basic_rates = basic_rates; 1331 sdata->vif.bss_conf.basic_rates = basic_rates;
1332 1332
1333 /* cf. IEEE 802.11 9.2.12 */ 1333 /* cf. IEEE 802.11 9.2.12 */
1334 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && 1334 if (wk->chan->band == IEEE80211_BAND_2GHZ &&
1335 have_higher_than_11mbit) 1335 have_higher_than_11mbit)
1336 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; 1336 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
1337 else 1337 else
@@ -1639,7 +1639,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1639 directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, 1639 directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len,
1640 ifmgd->aid); 1640 ifmgd->aid);
1641 1641
1642 if (ncrc != ifmgd->beacon_crc) { 1642 if (ncrc != ifmgd->beacon_crc || !ifmgd->beacon_crc_valid) {
1643 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, 1643 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
1644 true); 1644 true);
1645 1645
@@ -1670,9 +1670,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1670 } 1670 }
1671 } 1671 }
1672 1672
1673 if (ncrc == ifmgd->beacon_crc) 1673 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
1674 return; 1674 return;
1675 ifmgd->beacon_crc = ncrc; 1675 ifmgd->beacon_crc = ncrc;
1676 ifmgd->beacon_crc_valid = true;
1676 1677
1677 if (elems.erp_info && elems.erp_info_len >= 1) { 1678 if (elems.erp_info && elems.erp_info_len >= 1) {
1678 erp_valid = true; 1679 erp_valid = true;
@@ -1879,7 +1880,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1879 printk(KERN_DEBUG "No probe response from AP %pM" 1880 printk(KERN_DEBUG "No probe response from AP %pM"
1880 " after %dms, disconnecting.\n", 1881 " after %dms, disconnecting.\n",
1881 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 1882 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
1882 ieee80211_set_disassoc(sdata, true); 1883 ieee80211_set_disassoc(sdata, true, true);
1883 mutex_unlock(&ifmgd->mtx); 1884 mutex_unlock(&ifmgd->mtx);
1884 mutex_lock(&local->mtx); 1885 mutex_lock(&local->mtx);
1885 ieee80211_recalc_idle(local); 1886 ieee80211_recalc_idle(local);
@@ -2203,7 +2204,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2203 } 2204 }
2204 2205
2205 /* Trying to reassociate - clear previous association state */ 2206 /* Trying to reassociate - clear previous association state */
2206 ieee80211_set_disassoc(sdata, true); 2207 ieee80211_set_disassoc(sdata, true, false);
2207 } 2208 }
2208 mutex_unlock(&ifmgd->mtx); 2209 mutex_unlock(&ifmgd->mtx);
2209 2210
@@ -2214,6 +2215,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2214 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; 2215 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
2215 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; 2216 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
2216 2217
2218 ifmgd->beacon_crc_valid = false;
2219
2217 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) 2220 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
2218 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || 2221 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
2219 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || 2222 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
@@ -2315,7 +2318,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2315 2318
2316 memcpy(bssid, req->bss->bssid, ETH_ALEN); 2319 memcpy(bssid, req->bss->bssid, ETH_ALEN);
2317 if (ifmgd->associated == req->bss) { 2320 if (ifmgd->associated == req->bss) {
2318 ieee80211_set_disassoc(sdata, false); 2321 ieee80211_set_disassoc(sdata, false, true);
2319 mutex_unlock(&ifmgd->mtx); 2322 mutex_unlock(&ifmgd->mtx);
2320 assoc_bss = true; 2323 assoc_bss = true;
2321 } else { 2324 } else {
@@ -2398,7 +2401,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2398 sdata->name, req->bss->bssid, req->reason_code); 2401 sdata->name, req->bss->bssid, req->reason_code);
2399 2402
2400 memcpy(bssid, req->bss->bssid, ETH_ALEN); 2403 memcpy(bssid, req->bss->bssid, ETH_ALEN);
2401 ieee80211_set_disassoc(sdata, false); 2404 ieee80211_set_disassoc(sdata, false, true);
2402 2405
2403 mutex_unlock(&ifmgd->mtx); 2406 mutex_unlock(&ifmgd->mtx);
2404 2407