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, 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
1223static 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
1232static 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
1223static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, 1239static 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));
1479out: 1494out:
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;