diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 33 |
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 | ||
923 | static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | 923 | static 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 | ||