diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 57 |
1 files changed, 36 insertions, 21 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 04c306308987..0db5d34a06b6 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1220,6 +1220,22 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
1220 | sdata->vif.bss_conf.qos = true; | 1220 | sdata->vif.bss_conf.qos = true; |
1221 | } | 1221 | } |
1222 | 1222 | ||
1223 | static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata) | ||
1224 | { | ||
1225 | lockdep_assert_held(&sdata->local->mtx); | ||
1226 | |||
1227 | sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | | ||
1228 | IEEE80211_STA_BEACON_POLL); | ||
1229 | ieee80211_run_deferred_scan(sdata->local); | ||
1230 | } | ||
1231 | |||
1232 | static void ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata) | ||
1233 | { | ||
1234 | mutex_lock(&sdata->local->mtx); | ||
1235 | __ieee80211_stop_poll(sdata); | ||
1236 | mutex_unlock(&sdata->local->mtx); | ||
1237 | } | ||
1238 | |||
1223 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, | 1239 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, |
1224 | u16 capab, bool erp_valid, u8 erp) | 1240 | u16 capab, bool erp_valid, u8 erp) |
1225 | { | 1241 | { |
@@ -1285,8 +1301,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
1285 | sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; | 1301 | sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; |
1286 | 1302 | ||
1287 | /* just to be sure */ | 1303 | /* just to be sure */ |
1288 | sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 1304 | ieee80211_stop_poll(sdata); |
1289 | IEEE80211_STA_BEACON_POLL); | ||
1290 | 1305 | ||
1291 | ieee80211_led_assoc(local, 1); | 1306 | ieee80211_led_assoc(local, 1); |
1292 | 1307 | ||
@@ -1327,7 +1342,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1327 | struct ieee80211_local *local = sdata->local; | 1342 | struct ieee80211_local *local = sdata->local; |
1328 | struct sta_info *sta; | 1343 | struct sta_info *sta; |
1329 | u32 changed = 0; | 1344 | u32 changed = 0; |
1330 | u8 bssid[ETH_ALEN]; | ||
1331 | 1345 | ||
1332 | ASSERT_MGD_MTX(ifmgd); | 1346 | ASSERT_MGD_MTX(ifmgd); |
1333 | 1347 | ||
@@ -1337,10 +1351,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1337 | if (WARN_ON(!ifmgd->associated)) | 1351 | if (WARN_ON(!ifmgd->associated)) |
1338 | return; | 1352 | return; |
1339 | 1353 | ||
1340 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); | 1354 | ieee80211_stop_poll(sdata); |
1341 | 1355 | ||
1342 | ifmgd->associated = NULL; | 1356 | ifmgd->associated = NULL; |
1343 | memset(ifmgd->bssid, 0, ETH_ALEN); | ||
1344 | 1357 | ||
1345 | /* | 1358 | /* |
1346 | * we need to commit the associated = NULL change because the | 1359 | * we need to commit the associated = NULL change because the |
@@ -1360,7 +1373,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1360 | netif_carrier_off(sdata->dev); | 1373 | netif_carrier_off(sdata->dev); |
1361 | 1374 | ||
1362 | mutex_lock(&local->sta_mtx); | 1375 | mutex_lock(&local->sta_mtx); |
1363 | sta = sta_info_get(sdata, bssid); | 1376 | sta = sta_info_get(sdata, ifmgd->bssid); |
1364 | if (sta) { | 1377 | if (sta) { |
1365 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); | 1378 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); |
1366 | ieee80211_sta_tear_down_BA_sessions(sta, tx); | 1379 | ieee80211_sta_tear_down_BA_sessions(sta, tx); |
@@ -1369,13 +1382,16 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1369 | 1382 | ||
1370 | /* deauthenticate/disassociate now */ | 1383 | /* deauthenticate/disassociate now */ |
1371 | if (tx || frame_buf) | 1384 | if (tx || frame_buf) |
1372 | ieee80211_send_deauth_disassoc(sdata, bssid, stype, reason, | 1385 | ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, |
1373 | tx, frame_buf); | 1386 | reason, tx, frame_buf); |
1374 | 1387 | ||
1375 | /* flush out frame */ | 1388 | /* flush out frame */ |
1376 | if (tx) | 1389 | if (tx) |
1377 | drv_flush(local, false); | 1390 | drv_flush(local, false); |
1378 | 1391 | ||
1392 | /* clear bssid only after building the needed mgmt frames */ | ||
1393 | memset(ifmgd->bssid, 0, ETH_ALEN); | ||
1394 | |||
1379 | /* remove AP and TDLS peers */ | 1395 | /* remove AP and TDLS peers */ |
1380 | sta_info_flush(local, sdata); | 1396 | sta_info_flush(local, sdata); |
1381 | 1397 | ||
@@ -1456,8 +1472,7 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) | |||
1456 | return; | 1472 | return; |
1457 | } | 1473 | } |
1458 | 1474 | ||
1459 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 1475 | __ieee80211_stop_poll(sdata); |
1460 | IEEE80211_STA_BEACON_POLL); | ||
1461 | 1476 | ||
1462 | mutex_lock(&local->iflist_mtx); | 1477 | mutex_lock(&local->iflist_mtx); |
1463 | ieee80211_recalc_ps(local, -1); | 1478 | ieee80211_recalc_ps(local, -1); |
@@ -1477,7 +1492,6 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) | |||
1477 | round_jiffies_up(jiffies + | 1492 | round_jiffies_up(jiffies + |
1478 | IEEE80211_CONNECTION_IDLE_TIME)); | 1493 | IEEE80211_CONNECTION_IDLE_TIME)); |
1479 | out: | 1494 | out: |
1480 | ieee80211_run_deferred_scan(local); | ||
1481 | mutex_unlock(&local->mtx); | 1495 | mutex_unlock(&local->mtx); |
1482 | } | 1496 | } |
1483 | 1497 | ||
@@ -2160,15 +2174,13 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2160 | sdata->name, mgmt->sa, status_code); | 2174 | sdata->name, mgmt->sa, status_code); |
2161 | ieee80211_destroy_assoc_data(sdata, false); | 2175 | ieee80211_destroy_assoc_data(sdata, false); |
2162 | } else { | 2176 | } else { |
2163 | printk(KERN_DEBUG "%s: associated\n", sdata->name); | ||
2164 | |||
2165 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { | 2177 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { |
2166 | /* oops -- internal error -- send timeout for now */ | 2178 | /* oops -- internal error -- send timeout for now */ |
2167 | ieee80211_destroy_assoc_data(sdata, true); | 2179 | ieee80211_destroy_assoc_data(sdata, false); |
2168 | sta_info_destroy_addr(sdata, mgmt->bssid); | ||
2169 | cfg80211_put_bss(*bss); | 2180 | cfg80211_put_bss(*bss); |
2170 | return RX_MGMT_CFG80211_ASSOC_TIMEOUT; | 2181 | return RX_MGMT_CFG80211_ASSOC_TIMEOUT; |
2171 | } | 2182 | } |
2183 | printk(KERN_DEBUG "%s: associated\n", sdata->name); | ||
2172 | 2184 | ||
2173 | /* | 2185 | /* |
2174 | * destroy assoc_data afterwards, as otherwise an idle | 2186 | * destroy assoc_data afterwards, as otherwise an idle |
@@ -2408,7 +2420,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2408 | net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n", | 2420 | net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n", |
2409 | sdata->name); | 2421 | sdata->name); |
2410 | #endif | 2422 | #endif |
2423 | mutex_lock(&local->mtx); | ||
2411 | ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; | 2424 | ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; |
2425 | ieee80211_run_deferred_scan(local); | ||
2426 | mutex_unlock(&local->mtx); | ||
2427 | |||
2412 | mutex_lock(&local->iflist_mtx); | 2428 | mutex_lock(&local->iflist_mtx); |
2413 | ieee80211_recalc_ps(local, -1); | 2429 | ieee80211_recalc_ps(local, -1); |
2414 | mutex_unlock(&local->iflist_mtx); | 2430 | mutex_unlock(&local->iflist_mtx); |
@@ -2595,9 +2611,6 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | |||
2595 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2611 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2596 | u8 frame_buf[DEAUTH_DISASSOC_LEN]; | 2612 | u8 frame_buf[DEAUTH_DISASSOC_LEN]; |
2597 | 2613 | ||
2598 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | ||
2599 | IEEE80211_STA_BEACON_POLL); | ||
2600 | |||
2601 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, | 2614 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, |
2602 | false, frame_buf); | 2615 | false, frame_buf); |
2603 | mutex_unlock(&ifmgd->mtx); | 2616 | mutex_unlock(&ifmgd->mtx); |
@@ -2874,8 +2887,7 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) | |||
2874 | u32 flags; | 2887 | u32 flags; |
2875 | 2888 | ||
2876 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 2889 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
2877 | sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL | | 2890 | __ieee80211_stop_poll(sdata); |
2878 | IEEE80211_STA_CONNECTION_POLL); | ||
2879 | 2891 | ||
2880 | /* let's probe the connection once */ | 2892 | /* let's probe the connection once */ |
2881 | flags = sdata->local->hw.flags; | 2893 | flags = sdata->local->hw.flags; |
@@ -2944,7 +2956,10 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) | |||
2944 | if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) | 2956 | if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) |
2945 | add_timer(&ifmgd->chswitch_timer); | 2957 | add_timer(&ifmgd->chswitch_timer); |
2946 | ieee80211_sta_reset_beacon_monitor(sdata); | 2958 | ieee80211_sta_reset_beacon_monitor(sdata); |
2959 | |||
2960 | mutex_lock(&sdata->local->mtx); | ||
2947 | ieee80211_restart_sta_timer(sdata); | 2961 | ieee80211_restart_sta_timer(sdata); |
2962 | mutex_unlock(&sdata->local->mtx); | ||
2948 | } | 2963 | } |
2949 | #endif | 2964 | #endif |
2950 | 2965 | ||
@@ -3106,7 +3121,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3106 | } | 3121 | } |
3107 | 3122 | ||
3108 | local->oper_channel = cbss->channel; | 3123 | local->oper_channel = cbss->channel; |
3109 | ieee80211_hw_config(local, 0); | 3124 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
3110 | 3125 | ||
3111 | if (!have_sta) { | 3126 | if (!have_sta) { |
3112 | u32 rates = 0, basic_rates = 0; | 3127 | u32 rates = 0, basic_rates = 0; |