aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/mlme.c31
2 files changed, 23 insertions, 9 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 630a438180fd..989591787aee 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -284,6 +284,7 @@ struct ieee80211_if_managed {
284 284
285 struct mutex mtx; 285 struct mutex mtx;
286 struct ieee80211_bss *associated; 286 struct ieee80211_bss *associated;
287 struct ieee80211_mgd_work *old_associate_work;
287 struct list_head work_list; 288 struct list_head work_list;
288 289
289 u8 bssid[ETH_ALEN]; 290 u8 bssid[ETH_ALEN];
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 6d5a1ee0445f..c374d2d73fa4 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -880,10 +880,11 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
880} 880}
881 881
882static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, 882static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
883 struct ieee80211_bss *bss, 883 struct ieee80211_mgd_work *wk,
884 u32 bss_info_changed) 884 u32 bss_info_changed)
885{ 885{
886 struct ieee80211_local *local = sdata->local; 886 struct ieee80211_local *local = sdata->local;
887 struct ieee80211_bss *bss = wk->bss;
887 888
888 bss_info_changed |= BSS_CHANGED_ASSOC; 889 bss_info_changed |= BSS_CHANGED_ASSOC;
889 /* set timing information */ 890 /* set timing information */
@@ -896,6 +897,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
896 bss->cbss.capability, bss->has_erp_value, bss->erp_value); 897 bss->cbss.capability, bss->has_erp_value, bss->erp_value);
897 898
898 sdata->u.mgd.associated = bss; 899 sdata->u.mgd.associated = bss;
900 sdata->u.mgd.old_associate_work = wk;
899 memcpy(sdata->u.mgd.bssid, bss->cbss.bssid, ETH_ALEN); 901 memcpy(sdata->u.mgd.bssid, bss->cbss.bssid, ETH_ALEN);
900 902
901 /* just to be sure */ 903 /* just to be sure */
@@ -1010,7 +1012,8 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
1010 return RX_MGMT_NONE; 1012 return RX_MGMT_NONE;
1011} 1013}
1012 1014
1013static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata) 1015static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1016 bool deauth)
1014{ 1017{
1015 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1018 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1016 struct ieee80211_local *local = sdata->local; 1019 struct ieee80211_local *local = sdata->local;
@@ -1028,6 +1031,16 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
1028 ifmgd->associated = NULL; 1031 ifmgd->associated = NULL;
1029 memset(ifmgd->bssid, 0, ETH_ALEN); 1032 memset(ifmgd->bssid, 0, ETH_ALEN);
1030 1033
1034 if (deauth) {
1035 kfree(ifmgd->old_associate_work);
1036 ifmgd->old_associate_work = NULL;
1037 } else {
1038 struct ieee80211_mgd_work *wk = ifmgd->old_associate_work;
1039
1040 wk->state = IEEE80211_MGD_STATE_IDLE;
1041 list_add(&wk->list, &ifmgd->work_list);
1042 }
1043
1031 /* 1044 /*
1032 * we need to commit the associated = NULL change because the 1045 * we need to commit the associated = NULL change because the
1033 * scan code uses that to determine whether this iface should 1046 * scan code uses that to determine whether this iface should
@@ -1345,7 +1358,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1345 sdata->dev->name, bssid, reason_code); 1358 sdata->dev->name, bssid, reason_code);
1346 1359
1347 if (!wk) { 1360 if (!wk) {
1348 ieee80211_set_disassoc(sdata); 1361 ieee80211_set_disassoc(sdata, true);
1349 } else { 1362 } else {
1350 list_del(&wk->list); 1363 list_del(&wk->list);
1351 kfree(wk); 1364 kfree(wk);
@@ -1378,7 +1391,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1378 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n", 1391 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n",
1379 sdata->dev->name, reason_code); 1392 sdata->dev->name, reason_code);
1380 1393
1381 ieee80211_set_disassoc(sdata); 1394 ieee80211_set_disassoc(sdata, false);
1382 return RX_MGMT_CFG80211_DISASSOC; 1395 return RX_MGMT_CFG80211_DISASSOC;
1383} 1396}
1384 1397
@@ -1581,7 +1594,8 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1581 * ieee80211_set_associated() will tell the driver */ 1594 * ieee80211_set_associated() will tell the driver */
1582 bss_conf->aid = aid; 1595 bss_conf->aid = aid;
1583 bss_conf->assoc_capability = capab_info; 1596 bss_conf->assoc_capability = capab_info;
1584 ieee80211_set_associated(sdata, wk->bss, changed); 1597 /* this will take ownership of wk */
1598 ieee80211_set_associated(sdata, wk, changed);
1585 1599
1586 /* 1600 /*
1587 * Start timer to probe the connection to the AP now. 1601 * Start timer to probe the connection to the AP now.
@@ -1590,7 +1604,6 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1590 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); 1604 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
1591 mod_beacon_timer(sdata); 1605 mod_beacon_timer(sdata);
1592 1606
1593 kfree(wk);
1594 return RX_MGMT_CFG80211_ASSOC; 1607 return RX_MGMT_CFG80211_ASSOC;
1595} 1608}
1596 1609
@@ -2096,7 +2109,7 @@ static void ieee80211_sta_work(struct work_struct *work)
2096 printk(KERN_DEBUG "No probe response from AP %pM" 2109 printk(KERN_DEBUG "No probe response from AP %pM"
2097 " after %dms, disconnecting.\n", 2110 " after %dms, disconnecting.\n",
2098 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 2111 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
2099 ieee80211_set_disassoc(sdata); 2112 ieee80211_set_disassoc(sdata, true);
2100 mutex_unlock(&ifmgd->mtx); 2113 mutex_unlock(&ifmgd->mtx);
2101 /* 2114 /*
2102 * must be outside lock due to cfg80211, 2115 * must be outside lock due to cfg80211,
@@ -2500,7 +2513,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2500 2513
2501 if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) { 2514 if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) {
2502 bssid = req->bss->bssid; 2515 bssid = req->bss->bssid;
2503 ieee80211_set_disassoc(sdata); 2516 ieee80211_set_disassoc(sdata, true);
2504 } else list_for_each_entry(wk, &ifmgd->work_list, list) { 2517 } else list_for_each_entry(wk, &ifmgd->work_list, list) {
2505 if (&wk->bss->cbss == req->bss) { 2518 if (&wk->bss->cbss == req->bss) {
2506 bssid = req->bss->bssid; 2519 bssid = req->bss->bssid;
@@ -2552,7 +2565,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2552 return -ENOLINK; 2565 return -ENOLINK;
2553 } 2566 }
2554 2567
2555 ieee80211_set_disassoc(sdata); 2568 ieee80211_set_disassoc(sdata, false);
2556 2569
2557 mutex_unlock(&ifmgd->mtx); 2570 mutex_unlock(&ifmgd->mtx);
2558 2571