diff options
Diffstat (limited to 'drivers/net/wireless/libertas/assoc.c')
-rw-r--r-- | drivers/net/wireless/libertas/assoc.c | 106 |
1 files changed, 83 insertions, 23 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 3f2dfaf879c5..b18464224b95 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c | |||
@@ -13,6 +13,56 @@ | |||
13 | static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 13 | static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
14 | static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | 14 | static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
15 | 15 | ||
16 | /* From ieee80211_module.c */ | ||
17 | static const char *libertas_escape_essid(const char *essid, u8 essid_len) | ||
18 | { | ||
19 | static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | ||
20 | const char *s = essid; | ||
21 | char *d = escaped; | ||
22 | |||
23 | if (ieee80211_is_empty_essid(essid, essid_len)) | ||
24 | return ""; | ||
25 | |||
26 | essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE); | ||
27 | while (essid_len--) { | ||
28 | if (*s == '\0') { | ||
29 | *d++ = '\\'; | ||
30 | *d++ = '0'; | ||
31 | s++; | ||
32 | } else { | ||
33 | *d++ = *s++; | ||
34 | } | ||
35 | } | ||
36 | *d = '\0'; | ||
37 | return escaped; | ||
38 | } | ||
39 | |||
40 | static void print_assoc_req(const char * extra, struct assoc_request * assoc_req) | ||
41 | { | ||
42 | lbs_deb_assoc( | ||
43 | "#### Association Request: %s\n" | ||
44 | " flags: 0x%08lX\n" | ||
45 | " SSID: '%s'\n" | ||
46 | " channel: %d\n" | ||
47 | " band: %d\n" | ||
48 | " mode: %d\n" | ||
49 | " BSSID: " MAC_FMT "\n" | ||
50 | " WPA: %d\n" | ||
51 | " WPA2: %d\n" | ||
52 | " WEP status: %d\n" | ||
53 | " auth: %d\n" | ||
54 | " auth_alg: %d\n" | ||
55 | " encmode: %d\n", | ||
56 | extra, assoc_req->flags, | ||
57 | libertas_escape_essid(assoc_req->ssid.ssid, assoc_req->ssid.ssidlength), | ||
58 | assoc_req->channel, assoc_req->band, assoc_req->mode, | ||
59 | MAC_ARG(assoc_req->bssid), assoc_req->secinfo.WPAenabled, | ||
60 | assoc_req->secinfo.WPA2enabled, assoc_req->secinfo.WEPstatus, | ||
61 | assoc_req->secinfo.authmode, assoc_req->secinfo.auth1xalg, | ||
62 | assoc_req->secinfo.Encryptionmode); | ||
63 | } | ||
64 | |||
65 | |||
16 | static int assoc_helper_essid(wlan_private *priv, | 66 | static int assoc_helper_essid(wlan_private *priv, |
17 | struct assoc_request * assoc_req) | 67 | struct assoc_request * assoc_req) |
18 | { | 68 | { |
@@ -36,10 +86,8 @@ static int assoc_helper_essid(wlan_private *priv, | |||
36 | NULL, IW_MODE_INFRA); | 86 | NULL, IW_MODE_INFRA); |
37 | if (bss != NULL) { | 87 | if (bss != NULL) { |
38 | lbs_deb_assoc("SSID found in scan list, associating\n"); | 88 | lbs_deb_assoc("SSID found in scan list, associating\n"); |
39 | ret = wlan_associate(priv, bss); | 89 | memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); |
40 | if (ret == 0) { | 90 | ret = wlan_associate(priv, assoc_req); |
41 | memcpy(&assoc_req->bssid, bss->bssid, ETH_ALEN); | ||
42 | } | ||
43 | } else { | 91 | } else { |
44 | lbs_deb_assoc("SSID '%s' not found; cannot associate\n", | 92 | lbs_deb_assoc("SSID '%s' not found; cannot associate\n", |
45 | assoc_req->ssid.ssid); | 93 | assoc_req->ssid.ssid); |
@@ -55,14 +103,16 @@ static int assoc_helper_essid(wlan_private *priv, | |||
55 | IW_MODE_ADHOC); | 103 | IW_MODE_ADHOC); |
56 | if (bss != NULL) { | 104 | if (bss != NULL) { |
57 | lbs_deb_assoc("SSID found joining\n"); | 105 | lbs_deb_assoc("SSID found joining\n"); |
58 | libertas_join_adhoc_network(priv, bss); | 106 | memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); |
107 | libertas_join_adhoc_network(priv, assoc_req); | ||
59 | } else { | 108 | } else { |
60 | /* else send START command */ | 109 | /* else send START command */ |
61 | lbs_deb_assoc("SSID not found in list, so creating adhoc" | 110 | lbs_deb_assoc("SSID not found in list, so creating adhoc" |
62 | " with SSID '%s'\n", assoc_req->ssid.ssid); | 111 | " with SSID '%s'\n", assoc_req->ssid.ssid); |
63 | libertas_start_adhoc_network(priv, &assoc_req->ssid); | 112 | memcpy(&assoc_req->bss.ssid, &assoc_req->ssid, |
113 | sizeof(struct WLAN_802_11_SSID)); | ||
114 | libertas_start_adhoc_network(priv, assoc_req); | ||
64 | } | 115 | } |
65 | memcpy(&assoc_req->bssid, &adapter->current_addr, ETH_ALEN); | ||
66 | } | 116 | } |
67 | 117 | ||
68 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | 118 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
@@ -89,13 +139,13 @@ static int assoc_helper_bssid(wlan_private *priv, | |||
89 | goto out; | 139 | goto out; |
90 | } | 140 | } |
91 | 141 | ||
142 | memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); | ||
92 | if (assoc_req->mode == IW_MODE_INFRA) { | 143 | if (assoc_req->mode == IW_MODE_INFRA) { |
93 | ret = wlan_associate(priv, bss); | 144 | ret = wlan_associate(priv, assoc_req); |
94 | lbs_deb_assoc("ASSOC: wlan_associate(bssid) returned %d\n", ret); | 145 | lbs_deb_assoc("ASSOC: wlan_associate(bssid) returned %d\n", ret); |
95 | } else if (assoc_req->mode == IW_MODE_ADHOC) { | 146 | } else if (assoc_req->mode == IW_MODE_ADHOC) { |
96 | libertas_join_adhoc_network(priv, bss); | 147 | libertas_join_adhoc_network(priv, assoc_req); |
97 | } | 148 | } |
98 | memcpy(&assoc_req->ssid, &bss->ssid, sizeof(struct WLAN_802_11_SSID)); | ||
99 | 149 | ||
100 | out: | 150 | out: |
101 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | 151 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
@@ -421,15 +471,15 @@ void libertas_association_worker(struct work_struct *work) | |||
421 | lbs_deb_enter(LBS_DEB_ASSOC); | 471 | lbs_deb_enter(LBS_DEB_ASSOC); |
422 | 472 | ||
423 | mutex_lock(&adapter->lock); | 473 | mutex_lock(&adapter->lock); |
424 | assoc_req = adapter->assoc_req; | 474 | assoc_req = adapter->pending_assoc_req; |
425 | adapter->assoc_req = NULL; | 475 | adapter->pending_assoc_req = NULL; |
476 | adapter->in_progress_assoc_req = assoc_req; | ||
426 | mutex_unlock(&adapter->lock); | 477 | mutex_unlock(&adapter->lock); |
427 | 478 | ||
428 | if (!assoc_req) | 479 | if (!assoc_req) |
429 | goto done; | 480 | goto done; |
430 | 481 | ||
431 | lbs_deb_assoc("ASSOC: starting new association request: flags = 0x%lX\n", | 482 | print_assoc_req(__func__, assoc_req); |
432 | assoc_req->flags); | ||
433 | 483 | ||
434 | /* If 'any' SSID was specified, find an SSID to associate with */ | 484 | /* If 'any' SSID was specified, find an SSID to associate with */ |
435 | if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) | 485 | if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) |
@@ -561,7 +611,9 @@ lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); | |||
561 | if (success) { | 611 | if (success) { |
562 | lbs_deb_assoc("ASSOC: association attempt successful. " | 612 | lbs_deb_assoc("ASSOC: association attempt successful. " |
563 | "Associated to '%s' (" MAC_FMT ")\n", | 613 | "Associated to '%s' (" MAC_FMT ")\n", |
564 | assoc_req->ssid.ssid, MAC_ARG(assoc_req->bssid)); | 614 | libertas_escape_essid(adapter->curbssparams.ssid.ssid, |
615 | adapter->curbssparams.ssid.ssidlength), | ||
616 | MAC_ARG(adapter->curbssparams.bssid)); | ||
565 | libertas_prepare_and_send_command(priv, | 617 | libertas_prepare_and_send_command(priv, |
566 | cmd_802_11_rssi, | 618 | cmd_802_11_rssi, |
567 | 0, cmd_option_waitforrsp, 0, NULL); | 619 | 0, cmd_option_waitforrsp, 0, NULL); |
@@ -580,6 +632,10 @@ out: | |||
580 | lbs_deb_assoc("ASSOC: reconfiguration attempt unsuccessful: %d\n", | 632 | lbs_deb_assoc("ASSOC: reconfiguration attempt unsuccessful: %d\n", |
581 | ret); | 633 | ret); |
582 | } | 634 | } |
635 | |||
636 | mutex_lock(&adapter->lock); | ||
637 | adapter->in_progress_assoc_req = NULL; | ||
638 | mutex_unlock(&adapter->lock); | ||
583 | kfree(assoc_req); | 639 | kfree(assoc_req); |
584 | 640 | ||
585 | done: | 641 | done: |
@@ -594,9 +650,10 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) | |||
594 | { | 650 | { |
595 | struct assoc_request * assoc_req; | 651 | struct assoc_request * assoc_req; |
596 | 652 | ||
597 | if (!adapter->assoc_req) { | 653 | if (!adapter->pending_assoc_req) { |
598 | adapter->assoc_req = kzalloc(sizeof(struct assoc_request), GFP_KERNEL); | 654 | adapter->pending_assoc_req = kzalloc(sizeof(struct assoc_request), |
599 | if (!adapter->assoc_req) { | 655 | GFP_KERNEL); |
656 | if (!adapter->pending_assoc_req) { | ||
600 | lbs_pr_info("Not enough memory to allocate association" | 657 | lbs_pr_info("Not enough memory to allocate association" |
601 | " request!\n"); | 658 | " request!\n"); |
602 | return NULL; | 659 | return NULL; |
@@ -606,15 +663,18 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) | |||
606 | /* Copy current configuration attributes to the association request, | 663 | /* Copy current configuration attributes to the association request, |
607 | * but don't overwrite any that are already set. | 664 | * but don't overwrite any that are already set. |
608 | */ | 665 | */ |
609 | assoc_req = adapter->assoc_req; | 666 | assoc_req = adapter->pending_assoc_req; |
610 | if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { | 667 | if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { |
611 | memcpy(&assoc_req->ssid, adapter->curbssparams.ssid.ssid, | 668 | memcpy(&assoc_req->ssid, &adapter->curbssparams.ssid, |
612 | adapter->curbssparams.ssid.ssidlength); | 669 | sizeof(struct WLAN_802_11_SSID)); |
613 | } | 670 | } |
614 | 671 | ||
615 | if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) | 672 | if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) |
616 | assoc_req->channel = adapter->curbssparams.channel; | 673 | assoc_req->channel = adapter->curbssparams.channel; |
617 | 674 | ||
675 | if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags)) | ||
676 | assoc_req->band = adapter->curbssparams.band; | ||
677 | |||
618 | if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) | 678 | if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) |
619 | assoc_req->mode = adapter->mode; | 679 | assoc_req->mode = adapter->mode; |
620 | 680 | ||
@@ -655,7 +715,7 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) | |||
655 | assoc_req->wpa_ie_len = adapter->wpa_ie_len; | 715 | assoc_req->wpa_ie_len = adapter->wpa_ie_len; |
656 | } | 716 | } |
657 | 717 | ||
718 | print_assoc_req(__func__, assoc_req); | ||
719 | |||
658 | return assoc_req; | 720 | return assoc_req; |
659 | } | 721 | } |
660 | |||
661 | |||