aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/sme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/sme.c')
-rw-r--r--net/wireless/sme.c55
1 files changed, 38 insertions, 17 deletions
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index d2b5d4ce0a00..8a7dcbf90602 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -13,6 +13,7 @@
13#include <net/cfg80211.h> 13#include <net/cfg80211.h>
14#include <net/rtnetlink.h> 14#include <net/rtnetlink.h>
15#include "nl80211.h" 15#include "nl80211.h"
16#include "reg.h"
16 17
17struct cfg80211_conn { 18struct cfg80211_conn {
18 struct cfg80211_connect_params params; 19 struct cfg80211_connect_params params;
@@ -182,7 +183,7 @@ void cfg80211_conn_work(struct work_struct *work)
182 wdev->conn->params.bssid, 183 wdev->conn->params.bssid,
183 NULL, 0, NULL, 0, 184 NULL, 0, NULL, 0,
184 WLAN_STATUS_UNSPECIFIED_FAILURE, 185 WLAN_STATUS_UNSPECIFIED_FAILURE,
185 false); 186 false, NULL);
186 wdev_unlock(wdev); 187 wdev_unlock(wdev);
187 } 188 }
188 189
@@ -247,7 +248,7 @@ static void __cfg80211_sme_scan_done(struct net_device *dev)
247 wdev->conn->params.bssid, 248 wdev->conn->params.bssid,
248 NULL, 0, NULL, 0, 249 NULL, 0, NULL, 0,
249 WLAN_STATUS_UNSPECIFIED_FAILURE, 250 WLAN_STATUS_UNSPECIFIED_FAILURE,
250 false); 251 false, NULL);
251 } 252 }
252} 253}
253 254
@@ -305,7 +306,7 @@ void cfg80211_sme_rx_auth(struct net_device *dev,
305 schedule_work(&rdev->conn_work); 306 schedule_work(&rdev->conn_work);
306 } else if (status_code != WLAN_STATUS_SUCCESS) { 307 } else if (status_code != WLAN_STATUS_SUCCESS) {
307 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, 308 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
308 status_code, false); 309 status_code, false, NULL);
309 } else if (wdev->sme_state == CFG80211_SME_CONNECTING && 310 } else if (wdev->sme_state == CFG80211_SME_CONNECTING &&
310 wdev->conn->state == CFG80211_CONN_AUTHENTICATING) { 311 wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
311 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT; 312 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
@@ -316,10 +317,11 @@ void cfg80211_sme_rx_auth(struct net_device *dev,
316void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 317void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
317 const u8 *req_ie, size_t req_ie_len, 318 const u8 *req_ie, size_t req_ie_len,
318 const u8 *resp_ie, size_t resp_ie_len, 319 const u8 *resp_ie, size_t resp_ie_len,
319 u16 status, bool wextev) 320 u16 status, bool wextev,
321 struct cfg80211_bss *bss)
320{ 322{
321 struct wireless_dev *wdev = dev->ieee80211_ptr; 323 struct wireless_dev *wdev = dev->ieee80211_ptr;
322 struct cfg80211_bss *bss; 324 u8 *country_ie;
323#ifdef CONFIG_WIRELESS_EXT 325#ifdef CONFIG_WIRELESS_EXT
324 union iwreq_data wrqu; 326 union iwreq_data wrqu;
325#endif 327#endif
@@ -361,6 +363,12 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
361 } 363 }
362#endif 364#endif
363 365
366 if (wdev->current_bss) {
367 cfg80211_unhold_bss(wdev->current_bss);
368 cfg80211_put_bss(&wdev->current_bss->pub);
369 wdev->current_bss = NULL;
370 }
371
364 if (status == WLAN_STATUS_SUCCESS && 372 if (status == WLAN_STATUS_SUCCESS &&
365 wdev->sme_state == CFG80211_SME_IDLE) 373 wdev->sme_state == CFG80211_SME_IDLE)
366 goto success; 374 goto success;
@@ -368,12 +376,6 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
368 if (wdev->sme_state != CFG80211_SME_CONNECTING) 376 if (wdev->sme_state != CFG80211_SME_CONNECTING)
369 return; 377 return;
370 378
371 if (wdev->current_bss) {
372 cfg80211_unhold_bss(wdev->current_bss);
373 cfg80211_put_bss(&wdev->current_bss->pub);
374 wdev->current_bss = NULL;
375 }
376
377 if (wdev->conn) 379 if (wdev->conn)
378 wdev->conn->state = CFG80211_CONN_IDLE; 380 wdev->conn->state = CFG80211_CONN_IDLE;
379 381
@@ -383,13 +385,16 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
383 wdev->conn = NULL; 385 wdev->conn = NULL;
384 kfree(wdev->connect_keys); 386 kfree(wdev->connect_keys);
385 wdev->connect_keys = NULL; 387 wdev->connect_keys = NULL;
388 wdev->ssid_len = 0;
386 return; 389 return;
387 } 390 }
388 391
389 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, 392 success:
390 wdev->ssid, wdev->ssid_len, 393 if (!bss)
391 WLAN_CAPABILITY_ESS, 394 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
392 WLAN_CAPABILITY_ESS); 395 wdev->ssid, wdev->ssid_len,
396 WLAN_CAPABILITY_ESS,
397 WLAN_CAPABILITY_ESS);
393 398
394 if (WARN_ON(!bss)) 399 if (WARN_ON(!bss))
395 return; 400 return;
@@ -397,9 +402,22 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
397 cfg80211_hold_bss(bss_from_pub(bss)); 402 cfg80211_hold_bss(bss_from_pub(bss));
398 wdev->current_bss = bss_from_pub(bss); 403 wdev->current_bss = bss_from_pub(bss);
399 404
400 success:
401 wdev->sme_state = CFG80211_SME_CONNECTED; 405 wdev->sme_state = CFG80211_SME_CONNECTED;
402 cfg80211_upload_connect_keys(wdev); 406 cfg80211_upload_connect_keys(wdev);
407
408 country_ie = (u8 *) ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
409
410 if (!country_ie)
411 return;
412
413 /*
414 * ieee80211_bss_get_ie() ensures we can access:
415 * - country_ie + 2, the start of the country ie data, and
416 * - and country_ie[1] which is the IE length
417 */
418 regulatory_hint_11d(wdev->wiphy,
419 country_ie + 2,
420 country_ie[1]);
403} 421}
404 422
405void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 423void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
@@ -549,6 +567,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
549 567
550 wdev->current_bss = NULL; 568 wdev->current_bss = NULL;
551 wdev->sme_state = CFG80211_SME_IDLE; 569 wdev->sme_state = CFG80211_SME_IDLE;
570 wdev->ssid_len = 0;
552 571
553 if (wdev->conn) { 572 if (wdev->conn) {
554 kfree(wdev->conn->ie); 573 kfree(wdev->conn->ie);
@@ -704,6 +723,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
704 wdev->conn = NULL; 723 wdev->conn = NULL;
705 wdev->sme_state = CFG80211_SME_IDLE; 724 wdev->sme_state = CFG80211_SME_IDLE;
706 wdev->connect_keys = NULL; 725 wdev->connect_keys = NULL;
726 wdev->ssid_len = 0;
707 } 727 }
708 728
709 return err; 729 return err;
@@ -768,6 +788,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
768 wdev->sme_state = CFG80211_SME_IDLE; 788 wdev->sme_state = CFG80211_SME_IDLE;
769 kfree(wdev->conn); 789 kfree(wdev->conn);
770 wdev->conn = NULL; 790 wdev->conn = NULL;
791 wdev->ssid_len = 0;
771 return 0; 792 return 0;
772 } 793 }
773 794
@@ -788,7 +809,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
788 else if (wdev->sme_state == CFG80211_SME_CONNECTING) 809 else if (wdev->sme_state == CFG80211_SME_CONNECTING)
789 __cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0, 810 __cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0,
790 WLAN_STATUS_UNSPECIFIED_FAILURE, 811 WLAN_STATUS_UNSPECIFIED_FAILURE,
791 wextev); 812 wextev, NULL);
792 813
793 return 0; 814 return 0;
794} 815}