aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/libertas/11d.c6
-rw-r--r--drivers/net/wireless/libertas/11d.h4
-rw-r--r--drivers/net/wireless/libertas/assoc.c106
-rw-r--r--drivers/net/wireless/libertas/assoc.h6
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c18
-rw-r--r--drivers/net/wireless/libertas/dev.h27
-rw-r--r--drivers/net/wireless/libertas/fw.c4
-rw-r--r--drivers/net/wireless/libertas/join.c224
-rw-r--r--drivers/net/wireless/libertas/join.h10
-rw-r--r--drivers/net/wireless/libertas/scan.c21
10 files changed, 215 insertions, 211 deletions
diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c
index ab76798df0eb..261bbd55e94f 100644
--- a/drivers/net/wireless/libertas/11d.c
+++ b/drivers/net/wireless/libertas/11d.c
@@ -654,7 +654,8 @@ int libertas_ret_802_11d_domain_info(wlan_private * priv,
654 * @param priv pointer to wlan_private 654 * @param priv pointer to wlan_private
655 * @return 0; -1 655 * @return 0; -1
656 */ 656 */
657int libertas_parse_dnld_countryinfo_11d(wlan_private * priv) 657int libertas_parse_dnld_countryinfo_11d(wlan_private * priv,
658 struct bss_descriptor * bss)
658{ 659{
659 int ret; 660 int ret;
660 wlan_adapter *adapter = priv->adapter; 661 wlan_adapter *adapter = priv->adapter;
@@ -663,8 +664,7 @@ int libertas_parse_dnld_countryinfo_11d(wlan_private * priv)
663 if (priv->adapter->enable11d) { 664 if (priv->adapter->enable11d) {
664 memset(&adapter->parsed_region_chan, 0, 665 memset(&adapter->parsed_region_chan, 0,
665 sizeof(struct parsed_region_chan_11d)); 666 sizeof(struct parsed_region_chan_11d));
666 ret = parse_domain_info_11d(&adapter->pattemptedbssdesc-> 667 ret = parse_domain_info_11d(&bss->countryinfo, 0,
667 countryinfo, 0,
668 &adapter->parsed_region_chan); 668 &adapter->parsed_region_chan);
669 669
670 if (ret == -1) { 670 if (ret == -1) {
diff --git a/drivers/net/wireless/libertas/11d.h b/drivers/net/wireless/libertas/11d.h
index db2ebea9f231..982d7929eed7 100644
--- a/drivers/net/wireless/libertas/11d.h
+++ b/drivers/net/wireless/libertas/11d.h
@@ -98,7 +98,9 @@ int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq);
98int libertas_ret_802_11d_domain_info(wlan_private * priv, 98int libertas_ret_802_11d_domain_info(wlan_private * priv,
99 struct cmd_ds_command *resp); 99 struct cmd_ds_command *resp);
100 100
101int libertas_parse_dnld_countryinfo_11d(wlan_private * priv); 101struct bss_descriptor;
102int libertas_parse_dnld_countryinfo_11d(wlan_private * priv,
103 struct bss_descriptor * bss);
102 104
103int libertas_create_dnld_countryinfo_11d(wlan_private * priv); 105int libertas_create_dnld_countryinfo_11d(wlan_private * priv);
104 106
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 @@
13static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 13static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
14static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 14static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
15 15
16/* From ieee80211_module.c */
17static 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
40static 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
16static int assoc_helper_essid(wlan_private *priv, 66static 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
100out: 150out:
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
585done: 641done:
@@ -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
diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h
index f9b2ad47ee6e..b5eddf8d3b39 100644
--- a/drivers/net/wireless/libertas/assoc.h
+++ b/drivers/net/wireless/libertas/assoc.h
@@ -21,9 +21,9 @@ static inline void wlan_postpone_association_work(wlan_private *priv)
21static inline void wlan_cancel_association_work(wlan_private *priv) 21static inline void wlan_cancel_association_work(wlan_private *priv)
22{ 22{
23 cancel_delayed_work(&priv->assoc_work); 23 cancel_delayed_work(&priv->assoc_work);
24 if (priv->adapter->assoc_req) { 24 if (priv->adapter->pending_assoc_req) {
25 kfree(priv->adapter->assoc_req); 25 kfree(priv->adapter->pending_assoc_req);
26 priv->adapter->assoc_req = NULL; 26 priv->adapter->pending_assoc_req = NULL;
27 } 27 }
28} 28}
29 29
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 45459d4ba684..6bf50c1eeb93 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -67,25 +67,19 @@ void libertas_mac_event_disconnected(wlan_private * priv)
67 lbs_deb_cmd("Previous SSID=%s, ssid length=%u\n", 67 lbs_deb_cmd("Previous SSID=%s, ssid length=%u\n",
68 adapter->previousssid.ssid, adapter->previousssid.ssidlength); 68 adapter->previousssid.ssid, adapter->previousssid.ssidlength);
69 69
70 /* reset internal flags */
71 adapter->secinfo.WPAenabled = 0;
72 adapter->secinfo.WPA2enabled = 0;
73 adapter->wpa_ie_len = 0;
74
75 adapter->connect_status = libertas_disconnected; 70 adapter->connect_status = libertas_disconnected;
76 71
77 /* 72 /* Save previous SSID and BSSID for possible reassociation */
78 * memorize the previous SSID and BSSID
79 * it could be used for re-assoc
80 */
81 memcpy(&adapter->previousssid, 73 memcpy(&adapter->previousssid,
82 &adapter->curbssparams.ssid, sizeof(struct WLAN_802_11_SSID)); 74 &adapter->curbssparams.ssid, sizeof(struct WLAN_802_11_SSID));
83 memcpy(adapter->previousbssid, 75 memcpy(adapter->previousbssid,
84 adapter->curbssparams.bssid, ETH_ALEN); 76 adapter->curbssparams.bssid, ETH_ALEN);
85 77
86 /* need to erase the current SSID and BSSID info */ 78 /* Clear out associated SSID and BSSID since connection is
87 adapter->pattemptedbssdesc = NULL; 79 * no longer valid.
88 memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams)); 80 */
81 memset(&adapter->curbssparams.bssid, 0, ETH_ALEN);
82 memset(&adapter->curbssparams.ssid, 0, sizeof(struct WLAN_802_11_SSID));
89 83
90 if (adapter->psstate != PS_STATE_FULL_POWER) { 84 if (adapter->psstate != PS_STATE_FULL_POWER) {
91 /* make firmware to exit PS mode */ 85 /* make firmware to exit PS mode */
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 4ca60d9323b4..797a1249bcaf 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -63,7 +63,6 @@ struct wlan_802_11_security {
63 63
64/** Current Basic Service Set State Structure */ 64/** Current Basic Service Set State Structure */
65struct current_bss_params { 65struct current_bss_params {
66 struct bss_descriptor bssdescriptor;
67 /** bssid */ 66 /** bssid */
68 u8 bssid[ETH_ALEN]; 67 u8 bssid[ETH_ALEN];
69 /** ssid */ 68 /** ssid */
@@ -168,18 +167,20 @@ struct _wlan_private {
168struct assoc_request { 167struct assoc_request {
169#define ASSOC_FLAG_SSID 1 168#define ASSOC_FLAG_SSID 1
170#define ASSOC_FLAG_CHANNEL 2 169#define ASSOC_FLAG_CHANNEL 2
171#define ASSOC_FLAG_MODE 3 170#define ASSOC_FLAG_BAND 3
172#define ASSOC_FLAG_BSSID 4 171#define ASSOC_FLAG_MODE 4
173#define ASSOC_FLAG_WEP_KEYS 5 172#define ASSOC_FLAG_BSSID 5
174#define ASSOC_FLAG_WEP_TX_KEYIDX 6 173#define ASSOC_FLAG_WEP_KEYS 6
175#define ASSOC_FLAG_WPA_MCAST_KEY 7 174#define ASSOC_FLAG_WEP_TX_KEYIDX 7
176#define ASSOC_FLAG_WPA_UCAST_KEY 8 175#define ASSOC_FLAG_WPA_MCAST_KEY 8
177#define ASSOC_FLAG_SECINFO 9 176#define ASSOC_FLAG_WPA_UCAST_KEY 9
178#define ASSOC_FLAG_WPA_IE 10 177#define ASSOC_FLAG_SECINFO 10
178#define ASSOC_FLAG_WPA_IE 11
179 unsigned long flags; 179 unsigned long flags;
180 180
181 struct WLAN_802_11_SSID ssid; 181 struct WLAN_802_11_SSID ssid;
182 u8 channel; 182 u8 channel;
183 u8 band;
183 u8 mode; 184 u8 mode;
184 u8 bssid[ETH_ALEN]; 185 u8 bssid[ETH_ALEN];
185 186
@@ -196,6 +197,9 @@ struct assoc_request {
196 /** WPA Information Elements*/ 197 /** WPA Information Elements*/
197 u8 wpa_ie[MAX_WPA_IE_LEN]; 198 u8 wpa_ie[MAX_WPA_IE_LEN];
198 u8 wpa_ie_len; 199 u8 wpa_ie_len;
200
201 /* BSS to associate with for infrastructure of Ad-Hoc join */
202 struct bss_descriptor bss;
199}; 203};
200 204
201/** Wlan adapter data structure*/ 205/** Wlan adapter data structure*/
@@ -252,8 +256,6 @@ struct _wlan_adapter {
252 /* IW_MODE_* */ 256 /* IW_MODE_* */
253 u8 mode; 257 u8 mode;
254 258
255 struct bss_descriptor *pattemptedbssdesc;
256
257 struct WLAN_802_11_SSID previousssid; 259 struct WLAN_802_11_SSID previousssid;
258 u8 previousbssid[ETH_ALEN]; 260 u8 previousbssid[ETH_ALEN];
259 261
@@ -322,7 +324,8 @@ struct _wlan_adapter {
322 u16 locallisteninterval; 324 u16 locallisteninterval;
323 u16 nullpktinterval; 325 u16 nullpktinterval;
324 326
325 struct assoc_request * assoc_req; 327 struct assoc_request * pending_assoc_req;
328 struct assoc_request * in_progress_assoc_req;
326 329
327 /** Encryption parameter */ 330 /** Encryption parameter */
328 struct wlan_802_11_security secinfo; 331 struct wlan_802_11_security secinfo;
diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c
index 2e535ef7e803..eea18725bb90 100644
--- a/drivers/net/wireless/libertas/fw.c
+++ b/drivers/net/wireless/libertas/fw.c
@@ -185,7 +185,8 @@ static void wlan_init_adapter(wlan_private * priv)
185 adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 185 adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
186 adapter->mode = IW_MODE_INFRA; 186 adapter->mode = IW_MODE_INFRA;
187 187
188 adapter->assoc_req = NULL; 188 adapter->pending_assoc_req = NULL;
189 adapter->in_progress_assoc_req = NULL;
189 190
190 /* Initialize scan result lists */ 191 /* Initialize scan result lists */
191 INIT_LIST_HEAD(&adapter->network_free_list); 192 INIT_LIST_HEAD(&adapter->network_free_list);
@@ -195,7 +196,6 @@ static void wlan_init_adapter(wlan_private * priv)
195 &adapter->network_free_list); 196 &adapter->network_free_list);
196 } 197 }
197 198
198 adapter->pattemptedbssdesc = NULL;
199 mutex_init(&adapter->lock); 199 mutex_init(&adapter->lock);
200 200
201 adapter->prescan = 1; 201 adapter->prescan = 1;
diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c
index a11ce3a6f611..65777b40d57b 100644
--- a/drivers/net/wireless/libertas/join.c
+++ b/drivers/net/wireless/libertas/join.c
@@ -7,6 +7,7 @@
7#include <linux/netdevice.h> 7#include <linux/netdevice.h>
8#include <linux/if_arp.h> 8#include <linux/if_arp.h>
9#include <linux/wireless.h> 9#include <linux/wireless.h>
10#include <linux/etherdevice.h>
10 11
11#include <net/iw_handler.h> 12#include <net/iw_handler.h>
12 13
@@ -14,6 +15,7 @@
14#include "decl.h" 15#include "decl.h"
15#include "join.h" 16#include "join.h"
16#include "dev.h" 17#include "dev.h"
18#include "assoc.h"
17 19
18#define AD_HOC_CAP_PRIVACY_ON 1 20#define AD_HOC_CAP_PRIVACY_ON 1
19 21
@@ -104,7 +106,7 @@ int libertas_send_deauth(wlan_private * priv)
104 * 106 *
105 * @return 0-success, otherwise fail 107 * @return 0-success, otherwise fail
106 */ 108 */
107int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc) 109int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req)
108{ 110{
109 wlan_adapter *adapter = priv->adapter; 111 wlan_adapter *adapter = priv->adapter;
110 int ret; 112 int ret;
@@ -113,13 +115,13 @@ int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc)
113 115
114 ret = libertas_prepare_and_send_command(priv, cmd_802_11_authenticate, 116 ret = libertas_prepare_and_send_command(priv, cmd_802_11_authenticate,
115 0, cmd_option_waitforrsp, 117 0, cmd_option_waitforrsp,
116 0, pbssdesc->bssid); 118 0, assoc_req->bss.bssid);
117 119
118 if (ret) 120 if (ret)
119 goto done; 121 goto done;
120 122
121 /* set preamble to firmware */ 123 /* set preamble to firmware */
122 if (adapter->capinfo.shortpreamble && pbssdesc->cap.shortpreamble) 124 if (adapter->capinfo.shortpreamble && assoc_req->bss.cap.shortpreamble)
123 adapter->preamble = cmd_type_short_preamble; 125 adapter->preamble = cmd_type_short_preamble;
124 else 126 else
125 adapter->preamble = cmd_type_long_preamble; 127 adapter->preamble = cmd_type_long_preamble;
@@ -127,7 +129,7 @@ int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc)
127 libertas_set_radio_control(priv); 129 libertas_set_radio_control(priv);
128 130
129 ret = libertas_prepare_and_send_command(priv, cmd_802_11_associate, 131 ret = libertas_prepare_and_send_command(priv, cmd_802_11_associate,
130 0, cmd_option_waitforrsp, 0, pbssdesc); 132 0, cmd_option_waitforrsp, 0, assoc_req);
131 133
132done: 134done:
133 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); 135 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
@@ -141,7 +143,7 @@ done:
141 * @param adhocssid The ssid of the Adhoc Network 143 * @param adhocssid The ssid of the Adhoc Network
142 * @return 0--success, -1--fail 144 * @return 0--success, -1--fail
143 */ 145 */
144int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *adhocssid) 146int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req)
145{ 147{
146 wlan_adapter *adapter = priv->adapter; 148 wlan_adapter *adapter = priv->adapter;
147 int ret = 0; 149 int ret = 0;
@@ -158,12 +160,11 @@ int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *a
158 160
159 libertas_set_radio_control(priv); 161 libertas_set_radio_control(priv);
160 162
161 lbs_deb_join("curbssparams.channel = %d\n", 163 lbs_deb_join("AdhocStart: channel = %d\n", assoc_req->channel);
162 adapter->curbssparams.channel); 164 lbs_deb_join("AdhocStart: band = %d\n", assoc_req->band);
163 lbs_deb_join("curbssparams.band = %d\n", adapter->curbssparams.band);
164 165
165 ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_start, 166 ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_start,
166 0, cmd_option_waitforrsp, 0, adhocssid); 167 0, cmd_option_waitforrsp, 0, assoc_req);
167 168
168 return ret; 169 return ret;
169} 170}
@@ -177,34 +178,34 @@ int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *a
177 * 178 *
178 * @return 0--success, -1--fail 179 * @return 0--success, -1--fail
179 */ 180 */
180int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor * pbssdesc) 181int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req)
181{ 182{
182 wlan_adapter *adapter = priv->adapter; 183 wlan_adapter *adapter = priv->adapter;
184 struct bss_descriptor * bss = &assoc_req->bss;
183 int ret = 0; 185 int ret = 0;
184 186
185 lbs_deb_join("libertas_join_adhoc_network: CurBss.ssid =%s\n", 187 lbs_deb_join("libertas_join_adhoc_network: CurBss.ssid =%s\n",
186 adapter->curbssparams.ssid.ssid); 188 adapter->curbssparams.ssid.ssid);
187 lbs_deb_join("libertas_join_adhoc_network: CurBss.ssid_len =%u\n", 189 lbs_deb_join("libertas_join_adhoc_network: CurBss.ssid_len =%u\n",
188 adapter->curbssparams.ssid.ssidlength); 190 adapter->curbssparams.ssid.ssidlength);
189 lbs_deb_join("libertas_join_adhoc_network: ssid =%s\n", pbssdesc->ssid.ssid); 191 lbs_deb_join("libertas_join_adhoc_network: ssid = '%s'\n",
190 lbs_deb_join("libertas_join_adhoc_network: ssid len =%u\n", 192 bss->ssid.ssid);
191 pbssdesc->ssid.ssidlength); 193 lbs_deb_join("libertas_join_adhoc_network: ssid len = %u\n",
194 bss->ssid.ssidlength);
192 195
193 /* check if the requested SSID is already joined */ 196 /* check if the requested SSID is already joined */
194 if (adapter->curbssparams.ssid.ssidlength 197 if (adapter->curbssparams.ssid.ssidlength
195 && !libertas_SSID_cmp(&pbssdesc->ssid, &adapter->curbssparams.ssid) 198 && !libertas_SSID_cmp(&bss->ssid, &adapter->curbssparams.ssid)
196 && (adapter->mode == IW_MODE_ADHOC)) { 199 && (adapter->mode == IW_MODE_ADHOC)) {
197 200 lbs_deb_join(
198 lbs_deb_join(
199 "ADHOC_J_CMD: New ad-hoc SSID is the same as current, " 201 "ADHOC_J_CMD: New ad-hoc SSID is the same as current, "
200 "not attempting to re-join"); 202 "not attempting to re-join");
201
202 return -1; 203 return -1;
203 } 204 }
204 205
205 /*Use shortpreamble only when both creator and card supports 206 /*Use shortpreamble only when both creator and card supports
206 short preamble */ 207 short preamble */
207 if (!pbssdesc->cap.shortpreamble || !adapter->capinfo.shortpreamble) { 208 if (!bss->cap.shortpreamble || !adapter->capinfo.shortpreamble) {
208 lbs_deb_join("AdhocJoin: Long preamble\n"); 209 lbs_deb_join("AdhocJoin: Long preamble\n");
209 adapter->preamble = cmd_type_long_preamble; 210 adapter->preamble = cmd_type_long_preamble;
210 } else { 211 } else {
@@ -214,15 +215,14 @@ int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor * pbs
214 215
215 libertas_set_radio_control(priv); 216 libertas_set_radio_control(priv);
216 217
217 lbs_deb_join("curbssparams.channel = %d\n", 218 lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel);
218 adapter->curbssparams.channel); 219 lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band);
219 lbs_deb_join("curbssparams.band = %c\n", adapter->curbssparams.band);
220 220
221 adapter->adhoccreate = 0; 221 adapter->adhoccreate = 0;
222 222
223 ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_join, 223 ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_join,
224 0, cmd_option_waitforrsp, 224 0, cmd_option_waitforrsp,
225 OID_802_11_SSID, pbssdesc); 225 OID_802_11_SSID, assoc_req);
226 226
227 return ret; 227 return ret;
228} 228}
@@ -325,7 +325,8 @@ int libertas_cmd_80211_associate(wlan_private * priv,
325 wlan_adapter *adapter = priv->adapter; 325 wlan_adapter *adapter = priv->adapter;
326 struct cmd_ds_802_11_associate *passo = &cmd->params.associate; 326 struct cmd_ds_802_11_associate *passo = &cmd->params.associate;
327 int ret = 0; 327 int ret = 0;
328 struct bss_descriptor *pbssdesc; 328 struct assoc_request * assoc_req = pdata_buf;
329 struct bss_descriptor * bss = &assoc_req->bss;
329 u8 *card_rates; 330 u8 *card_rates;
330 u8 *pos; 331 u8 *pos;
331 int card_rates_size; 332 int card_rates_size;
@@ -338,7 +339,6 @@ int libertas_cmd_80211_associate(wlan_private * priv,
338 339
339 lbs_deb_enter(LBS_DEB_JOIN); 340 lbs_deb_enter(LBS_DEB_JOIN);
340 341
341 pbssdesc = pdata_buf;
342 pos = (u8 *) passo; 342 pos = (u8 *) passo;
343 343
344 if (!adapter) { 344 if (!adapter) {
@@ -348,11 +348,7 @@ int libertas_cmd_80211_associate(wlan_private * priv,
348 348
349 cmd->command = cpu_to_le16(cmd_802_11_associate); 349 cmd->command = cpu_to_le16(cmd_802_11_associate);
350 350
351 /* Save so we know which BSS Desc to use in the response handler */ 351 memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr));
352 adapter->pattemptedbssdesc = pbssdesc;
353
354 memcpy(passo->peerstaaddr,
355 pbssdesc->bssid, sizeof(passo->peerstaaddr));
356 pos += sizeof(passo->peerstaaddr); 352 pos += sizeof(passo->peerstaaddr);
357 353
358 /* set the listen interval */ 354 /* set the listen interval */
@@ -365,8 +361,8 @@ int libertas_cmd_80211_associate(wlan_private * priv,
365 361
366 ssid = (struct mrvlietypes_ssidparamset *) pos; 362 ssid = (struct mrvlietypes_ssidparamset *) pos;
367 ssid->header.type = cpu_to_le16(TLV_TYPE_SSID); 363 ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
368 ssid->header.len = pbssdesc->ssid.ssidlength; 364 ssid->header.len = bss->ssid.ssidlength;
369 memcpy(ssid->ssid, pbssdesc->ssid.ssid, ssid->header.len); 365 memcpy(ssid->ssid, bss->ssid.ssid, ssid->header.len);
370 pos += sizeof(ssid->header) + ssid->header.len; 366 pos += sizeof(ssid->header) + ssid->header.len;
371 ssid->header.len = cpu_to_le16(ssid->header.len); 367 ssid->header.len = cpu_to_le16(ssid->header.len);
372 368
@@ -374,7 +370,7 @@ int libertas_cmd_80211_associate(wlan_private * priv,
374 phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS); 370 phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
375 phy->header.len = sizeof(phy->fh_ds.dsparamset); 371 phy->header.len = sizeof(phy->fh_ds.dsparamset);
376 memcpy(&phy->fh_ds.dsparamset, 372 memcpy(&phy->fh_ds.dsparamset,
377 &pbssdesc->phyparamset.dsparamset.currentchan, 373 &bss->phyparamset.dsparamset.currentchan,
378 sizeof(phy->fh_ds.dsparamset)); 374 sizeof(phy->fh_ds.dsparamset));
379 pos += sizeof(phy->header) + phy->header.len; 375 pos += sizeof(phy->header) + phy->header.len;
380 phy->header.len = cpu_to_le16(phy->header.len); 376 phy->header.len = cpu_to_le16(phy->header.len);
@@ -388,7 +384,7 @@ int libertas_cmd_80211_associate(wlan_private * priv,
388 rates = (struct mrvlietypes_ratesparamset *) pos; 384 rates = (struct mrvlietypes_ratesparamset *) pos;
389 rates->header.type = cpu_to_le16(TLV_TYPE_RATES); 385 rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
390 386
391 memcpy(&rates->rates, &pbssdesc->libertas_supported_rates, WLAN_SUPPORTED_RATES); 387 memcpy(&rates->rates, &bss->libertas_supported_rates, WLAN_SUPPORTED_RATES);
392 388
393 card_rates = libertas_supported_rates; 389 card_rates = libertas_supported_rates;
394 card_rates_size = sizeof(libertas_supported_rates); 390 card_rates_size = sizeof(libertas_supported_rates);
@@ -405,12 +401,12 @@ int libertas_cmd_80211_associate(wlan_private * priv,
405 pos += sizeof(rates->header) + rates->header.len; 401 pos += sizeof(rates->header) + rates->header.len;
406 rates->header.len = cpu_to_le16(rates->header.len); 402 rates->header.len = cpu_to_le16(rates->header.len);
407 403
408 if (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) { 404 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
409 rsn = (struct mrvlietypes_rsnparamset *) pos; 405 rsn = (struct mrvlietypes_rsnparamset *) pos;
410 rsn->header.type = (u16) adapter->wpa_ie[0]; /* WPA_IE or WPA2_IE */ 406 rsn->header.type = (u16) assoc_req->wpa_ie[0]; /* WPA_IE or WPA2_IE */
411 rsn->header.type = cpu_to_le16(rsn->header.type); 407 rsn->header.type = cpu_to_le16(rsn->header.type);
412 rsn->header.len = (u16) adapter->wpa_ie[1]; 408 rsn->header.len = (u16) assoc_req->wpa_ie[1];
413 memcpy(rsn->rsnie, &adapter->wpa_ie[2], rsn->header.len); 409 memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], rsn->header.len);
414 lbs_dbg_hex("ASSOC_CMD: RSN IE", (u8 *) rsn, 410 lbs_dbg_hex("ASSOC_CMD: RSN IE", (u8 *) rsn,
415 sizeof(rsn->header) + rsn->header.len); 411 sizeof(rsn->header) + rsn->header.len);
416 pos += sizeof(rsn->header) + rsn->header.len; 412 pos += sizeof(rsn->header) + rsn->header.len;
@@ -419,7 +415,7 @@ int libertas_cmd_80211_associate(wlan_private * priv,
419 415
420 /* update curbssparams */ 416 /* update curbssparams */
421 adapter->curbssparams.channel = 417 adapter->curbssparams.channel =
422 (pbssdesc->phyparamset.dsparamset.currentchan); 418 (bss->phyparamset.dsparamset.currentchan);
423 419
424 /* Copy the infra. association rates into Current BSS state structure */ 420 /* Copy the infra. association rates into Current BSS state structure */
425 memcpy(&adapter->curbssparams.datarates, &rates->rates, 421 memcpy(&adapter->curbssparams.datarates, &rates->rates,
@@ -428,12 +424,12 @@ int libertas_cmd_80211_associate(wlan_private * priv,
428 lbs_deb_join("ASSOC_CMD: rates->header.len = %d\n", rates->header.len); 424 lbs_deb_join("ASSOC_CMD: rates->header.len = %d\n", rates->header.len);
429 425
430 /* set IBSS field */ 426 /* set IBSS field */
431 if (pbssdesc->mode == IW_MODE_INFRA) { 427 if (bss->mode == IW_MODE_INFRA) {
432#define CAPINFO_ESS_MODE 1 428#define CAPINFO_ESS_MODE 1
433 passo->capinfo.ess = CAPINFO_ESS_MODE; 429 passo->capinfo.ess = CAPINFO_ESS_MODE;
434 } 430 }
435 431
436 if (libertas_parse_dnld_countryinfo_11d(priv)) { 432 if (libertas_parse_dnld_countryinfo_11d(priv, bss)) {
437 ret = -1; 433 ret = -1;
438 goto done; 434 goto done;
439 } 435 }
@@ -441,7 +437,7 @@ int libertas_cmd_80211_associate(wlan_private * priv,
441 cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN); 437 cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN);
442 438
443 /* set the capability info at last */ 439 /* set the capability info at last */
444 memcpy(&tmpcap, &pbssdesc->cap, sizeof(passo->capinfo)); 440 memcpy(&tmpcap, &bss->cap, sizeof(passo->capinfo));
445 tmpcap &= CAPINFO_MASK; 441 tmpcap &= CAPINFO_MASK;
446 lbs_deb_join("ASSOC_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", 442 lbs_deb_join("ASSOC_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
447 tmpcap, CAPINFO_MASK); 443 tmpcap, CAPINFO_MASK);
@@ -454,7 +450,7 @@ done:
454} 450}
455 451
456int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, 452int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
457 struct cmd_ds_command *cmd, void *pssid) 453 struct cmd_ds_command *cmd, void *pdata_buf)
458{ 454{
459 wlan_adapter *adapter = priv->adapter; 455 wlan_adapter *adapter = priv->adapter;
460 struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads; 456 struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads;
@@ -462,8 +458,7 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
462 int cmdappendsize = 0; 458 int cmdappendsize = 0;
463 int i; 459 int i;
464 u16 tmpcap; 460 u16 tmpcap;
465 struct bss_descriptor *pbssdesc; 461 struct assoc_request * assoc_req = pdata_buf;
466 struct WLAN_802_11_SSID *ssid = pssid;
467 462
468 lbs_deb_enter(LBS_DEB_JOIN); 463 lbs_deb_enter(LBS_DEB_JOIN);
469 464
@@ -474,9 +469,6 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
474 469
475 cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_start); 470 cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_start);
476 471
477 pbssdesc = &adapter->curbssparams.bssdescriptor;
478 adapter->pattemptedbssdesc = pbssdesc;
479
480 /* 472 /*
481 * Fill in the parameters for 2 data structures: 473 * Fill in the parameters for 2 data structures:
482 * 1. cmd_ds_802_11_ad_hoc_start command 474 * 1. cmd_ds_802_11_ad_hoc_start command
@@ -490,19 +482,13 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
490 */ 482 */
491 483
492 memset(adhs->SSID, 0, IW_ESSID_MAX_SIZE); 484 memset(adhs->SSID, 0, IW_ESSID_MAX_SIZE);
493 485 memcpy(adhs->SSID, assoc_req->ssid.ssid, assoc_req->ssid.ssidlength);
494 memcpy(adhs->SSID, ssid->ssid, ssid->ssidlength);
495 486
496 lbs_deb_join("ADHOC_S_CMD: SSID = %s\n", adhs->SSID); 487 lbs_deb_join("ADHOC_S_CMD: SSID = %s\n", adhs->SSID);
497 488
498 memset(pbssdesc->ssid.ssid, 0, IW_ESSID_MAX_SIZE);
499 memcpy(pbssdesc->ssid.ssid, ssid->ssid, ssid->ssidlength);
500
501 pbssdesc->ssid.ssidlength = ssid->ssidlength;
502
503 /* set the BSS type */ 489 /* set the BSS type */
504 adhs->bsstype = cmd_bss_type_ibss; 490 adhs->bsstype = cmd_bss_type_ibss;
505 pbssdesc->mode = IW_MODE_ADHOC; 491 adapter->mode = IW_MODE_ADHOC;
506 adhs->beaconperiod = adapter->beaconperiod; 492 adhs->beaconperiod = adapter->beaconperiod;
507 493
508 /* set Physical param set */ 494 /* set Physical param set */
@@ -512,16 +498,12 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
512 adhs->phyparamset.dsparamset.elementid = DS_PARA_IE_ID; 498 adhs->phyparamset.dsparamset.elementid = DS_PARA_IE_ID;
513 adhs->phyparamset.dsparamset.len = DS_PARA_IE_LEN; 499 adhs->phyparamset.dsparamset.len = DS_PARA_IE_LEN;
514 500
515 WARN_ON(!adapter->curbssparams.channel); 501 WARN_ON(!assoc_req->channel);
516 502
517 lbs_deb_join("ADHOC_S_CMD: Creating ADHOC on channel %d\n", 503 lbs_deb_join("ADHOC_S_CMD: Creating ADHOC on channel %d\n",
518 adapter->curbssparams.channel); 504 assoc_req->channel);
519 505
520 pbssdesc->channel = adapter->curbssparams.channel; 506 adhs->phyparamset.dsparamset.currentchan = assoc_req->channel;
521 adhs->phyparamset.dsparamset.currentchan = adapter->curbssparams.channel;
522
523 memcpy(&pbssdesc->phyparamset,
524 &adhs->phyparamset, sizeof(union ieeetypes_phyparamset));
525 507
526 /* set IBSS param set */ 508 /* set IBSS param set */
527#define IBSS_PARA_IE_ID 6 509#define IBSS_PARA_IE_ID 6
@@ -530,25 +512,20 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
530 adhs->ssparamset.ibssparamset.elementid = IBSS_PARA_IE_ID; 512 adhs->ssparamset.ibssparamset.elementid = IBSS_PARA_IE_ID;
531 adhs->ssparamset.ibssparamset.len = IBSS_PARA_IE_LEN; 513 adhs->ssparamset.ibssparamset.len = IBSS_PARA_IE_LEN;
532 adhs->ssparamset.ibssparamset.atimwindow = adapter->atimwindow; 514 adhs->ssparamset.ibssparamset.atimwindow = adapter->atimwindow;
533 memcpy(&pbssdesc->ssparamset,
534 &adhs->ssparamset, sizeof(union IEEEtypes_ssparamset));
535 515
536 /* set capability info */ 516 /* set capability info */
537 adhs->cap.ess = 0; 517 adhs->cap.ess = 0;
538 adhs->cap.ibss = 1; 518 adhs->cap.ibss = 1;
539 pbssdesc->cap.ibss = 1;
540 519
541 /* probedelay */ 520 /* probedelay */
542 adhs->probedelay = cpu_to_le16(cmd_scan_probe_delay_time); 521 adhs->probedelay = cpu_to_le16(cmd_scan_probe_delay_time);
543 522
544 /* set up privacy in adapter->scantable[i] */ 523 /* set up privacy in adapter->scantable[i] */
545 if (adapter->secinfo.wep_enabled) { 524 if (assoc_req->secinfo.wep_enabled) {
546 lbs_deb_join("ADHOC_S_CMD: WEP enabled, setting privacy on\n"); 525 lbs_deb_join("ADHOC_S_CMD: WEP enabled, setting privacy on\n");
547 pbssdesc->privacy = wlan802_11privfilter8021xWEP;
548 adhs->cap.privacy = AD_HOC_CAP_PRIVACY_ON; 526 adhs->cap.privacy = AD_HOC_CAP_PRIVACY_ON;
549 } else { 527 } else {
550 lbs_deb_join("ADHOC_S_CMD: WEP disabled, setting privacy off\n"); 528 lbs_deb_join("ADHOC_S_CMD: WEP disabled, setting privacy off\n");
551 pbssdesc->privacy = wlan802_11privfilteracceptall;
552 } 529 }
553 530
554 memset(adhs->datarate, 0, sizeof(adhs->datarate)); 531 memset(adhs->datarate, 0, sizeof(adhs->datarate));
@@ -610,7 +587,8 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
610{ 587{
611 wlan_adapter *adapter = priv->adapter; 588 wlan_adapter *adapter = priv->adapter;
612 struct cmd_ds_802_11_ad_hoc_join *padhocjoin = &cmd->params.adj; 589 struct cmd_ds_802_11_ad_hoc_join *padhocjoin = &cmd->params.adj;
613 struct bss_descriptor *pbssdesc = pdata_buf; 590 struct assoc_request * assoc_req = pdata_buf;
591 struct bss_descriptor *bss = &assoc_req->bss;
614 int cmdappendsize = 0; 592 int cmdappendsize = 0;
615 int ret = 0; 593 int ret = 0;
616 u8 *card_rates; 594 u8 *card_rates;
@@ -620,27 +598,22 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
620 598
621 lbs_deb_enter(LBS_DEB_JOIN); 599 lbs_deb_enter(LBS_DEB_JOIN);
622 600
623 adapter->pattemptedbssdesc = pbssdesc;
624
625 cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_join); 601 cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_join);
626 602
627 padhocjoin->bssdescriptor.bsstype = cmd_bss_type_ibss; 603 padhocjoin->bssdescriptor.bsstype = cmd_bss_type_ibss;
628 604
629 padhocjoin->bssdescriptor.beaconperiod = pbssdesc->beaconperiod; 605 padhocjoin->bssdescriptor.beaconperiod = bss->beaconperiod;
630 606
631 memcpy(&padhocjoin->bssdescriptor.BSSID, 607 memcpy(&padhocjoin->bssdescriptor.BSSID, &bss->bssid, ETH_ALEN);
632 &pbssdesc->bssid, ETH_ALEN); 608 memcpy(&padhocjoin->bssdescriptor.SSID, &bss->ssid.ssid, bss->ssid.ssidlength);
633
634 memcpy(&padhocjoin->bssdescriptor.SSID,
635 &pbssdesc->ssid.ssid, pbssdesc->ssid.ssidlength);
636 609
637 memcpy(&padhocjoin->bssdescriptor.phyparamset, 610 memcpy(&padhocjoin->bssdescriptor.phyparamset,
638 &pbssdesc->phyparamset, sizeof(union ieeetypes_phyparamset)); 611 &bss->phyparamset, sizeof(union ieeetypes_phyparamset));
639 612
640 memcpy(&padhocjoin->bssdescriptor.ssparamset, 613 memcpy(&padhocjoin->bssdescriptor.ssparamset,
641 &pbssdesc->ssparamset, sizeof(union IEEEtypes_ssparamset)); 614 &bss->ssparamset, sizeof(union IEEEtypes_ssparamset));
642 615
643 memcpy(&tmpcap, &pbssdesc->cap, sizeof(struct ieeetypes_capinfo)); 616 memcpy(&tmpcap, &bss->cap, sizeof(struct ieeetypes_capinfo));
644 tmpcap &= CAPINFO_MASK; 617 tmpcap &= CAPINFO_MASK;
645 618
646 lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", 619 lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
@@ -649,14 +622,9 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
649 sizeof(struct ieeetypes_capinfo)); 622 sizeof(struct ieeetypes_capinfo));
650 623
651 /* information on BSSID descriptor passed to FW */ 624 /* information on BSSID descriptor passed to FW */
652 lbs_deb_join( 625 lbs_deb_join(
653 "ADHOC_J_CMD: BSSID = %2x-%2x-%2x-%2x-%2x-%2x, SSID = %s\n", 626 "ADHOC_J_CMD: BSSID = " MAC_FMT ", SSID = '%s'\n",
654 padhocjoin->bssdescriptor.BSSID[0], 627 MAC_ARG(padhocjoin->bssdescriptor.BSSID),
655 padhocjoin->bssdescriptor.BSSID[1],
656 padhocjoin->bssdescriptor.BSSID[2],
657 padhocjoin->bssdescriptor.BSSID[3],
658 padhocjoin->bssdescriptor.BSSID[4],
659 padhocjoin->bssdescriptor.BSSID[5],
660 padhocjoin->bssdescriptor.SSID); 628 padhocjoin->bssdescriptor.SSID);
661 629
662 /* failtimeout */ 630 /* failtimeout */
@@ -669,14 +637,14 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
669 /* Copy Data rates from the rates recorded in scan response */ 637 /* Copy Data rates from the rates recorded in scan response */
670 memset(padhocjoin->bssdescriptor.datarates, 0, 638 memset(padhocjoin->bssdescriptor.datarates, 0,
671 sizeof(padhocjoin->bssdescriptor.datarates)); 639 sizeof(padhocjoin->bssdescriptor.datarates));
672 memcpy(padhocjoin->bssdescriptor.datarates, pbssdesc->datarates, 640 memcpy(padhocjoin->bssdescriptor.datarates, bss->datarates,
673 min(sizeof(padhocjoin->bssdescriptor.datarates), 641 min(sizeof(padhocjoin->bssdescriptor.datarates),
674 sizeof(pbssdesc->datarates))); 642 sizeof(bss->datarates)));
675 643
676 card_rates = libertas_supported_rates; 644 card_rates = libertas_supported_rates;
677 card_rates_size = sizeof(libertas_supported_rates); 645 card_rates_size = sizeof(libertas_supported_rates);
678 646
679 adapter->curbssparams.channel = pbssdesc->channel; 647 adapter->curbssparams.channel = bss->channel;
680 648
681 if (get_common_rates(adapter, padhocjoin->bssdescriptor.datarates, 649 if (get_common_rates(adapter, padhocjoin->bssdescriptor.datarates,
682 sizeof(padhocjoin->bssdescriptor.datarates), 650 sizeof(padhocjoin->bssdescriptor.datarates),
@@ -700,9 +668,9 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
700 adapter->curbssparams.numofrates); 668 adapter->curbssparams.numofrates);
701 669
702 padhocjoin->bssdescriptor.ssparamset.ibssparamset.atimwindow = 670 padhocjoin->bssdescriptor.ssparamset.ibssparamset.atimwindow =
703 cpu_to_le16(pbssdesc->atimwindow); 671 cpu_to_le16(bss->atimwindow);
704 672
705 if (adapter->secinfo.wep_enabled) { 673 if (assoc_req->secinfo.wep_enabled) {
706 padhocjoin->bssdescriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON; 674 padhocjoin->bssdescriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON;
707 } 675 }
708 676
@@ -722,7 +690,7 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
722 } 690 }
723 } 691 }
724 692
725 if (libertas_parse_dnld_countryinfo_11d(priv)) { 693 if (libertas_parse_dnld_countryinfo_11d(priv, bss)) {
726 ret = -1; 694 ret = -1;
727 goto done; 695 goto done;
728 } 696 }
@@ -750,17 +718,23 @@ int libertas_ret_80211_associate(wlan_private * priv,
750 int ret = 0; 718 int ret = 0;
751 union iwreq_data wrqu; 719 union iwreq_data wrqu;
752 struct ieeetypes_assocrsp *passocrsp; 720 struct ieeetypes_assocrsp *passocrsp;
753 struct bss_descriptor *pbssdesc; 721 struct bss_descriptor * bss;
754 722
755 lbs_deb_enter(LBS_DEB_JOIN); 723 lbs_deb_enter(LBS_DEB_JOIN);
756 724
725 if (!adapter->in_progress_assoc_req) {
726 lbs_deb_join("ASSOC_RESP: no in-progress association request\n");
727 ret = -1;
728 goto done;
729 }
730 bss = &adapter->in_progress_assoc_req->bss;
731
757 passocrsp = (struct ieeetypes_assocrsp *) & resp->params; 732 passocrsp = (struct ieeetypes_assocrsp *) & resp->params;
758 733
759 if (passocrsp->statuscode) { 734 if (passocrsp->statuscode) {
760
761 libertas_mac_event_disconnected(priv); 735 libertas_mac_event_disconnected(priv);
762 736
763 lbs_deb_join("ASSOC_RESP: Association failed, status code = %d\n", 737 lbs_deb_join("ASSOC_RESP: Association failed, status code = %d\n",
764 passocrsp->statuscode); 738 passocrsp->statuscode);
765 739
766 ret = -1; 740 ret = -1;
@@ -773,22 +747,12 @@ int libertas_ret_80211_associate(wlan_private * priv,
773 /* Send a Media Connected event, according to the Spec */ 747 /* Send a Media Connected event, according to the Spec */
774 adapter->connect_status = libertas_connected; 748 adapter->connect_status = libertas_connected;
775 749
776 /* Set the attempted BSSID Index to current */ 750 lbs_deb_join("ASSOC_RESP: %s\n", bss->ssid.ssid);
777 pbssdesc = adapter->pattemptedbssdesc;
778
779 lbs_deb_join("ASSOC_RESP: %s\n", pbssdesc->ssid.ssid);
780 751
781 /* Set the new SSID to current SSID */ 752 /* Update current SSID and BSSID */
782 memcpy(&adapter->curbssparams.ssid, 753 memcpy(&adapter->curbssparams.ssid,
783 &pbssdesc->ssid, sizeof(struct WLAN_802_11_SSID)); 754 &bss->ssid, sizeof(struct WLAN_802_11_SSID));
784 755 memcpy(adapter->curbssparams.bssid, bss->bssid, ETH_ALEN);
785 /* Set the new BSSID (AP's MAC address) to current BSSID */
786 memcpy(adapter->curbssparams.bssid,
787 pbssdesc->bssid, ETH_ALEN);
788
789 /* Make a copy of current BSSID descriptor */
790 memcpy(&adapter->curbssparams.bssdescriptor,
791 pbssdesc, sizeof(struct bss_descriptor));
792 756
793 lbs_deb_join("ASSOC_RESP: currentpacketfilter is %x\n", 757 lbs_deb_join("ASSOC_RESP: currentpacketfilter is %x\n",
794 adapter->currentpacketfilter); 758 adapter->currentpacketfilter);
@@ -838,30 +802,31 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
838 u16 result = le16_to_cpu(resp->result); 802 u16 result = le16_to_cpu(resp->result);
839 struct cmd_ds_802_11_ad_hoc_result *padhocresult; 803 struct cmd_ds_802_11_ad_hoc_result *padhocresult;
840 union iwreq_data wrqu; 804 union iwreq_data wrqu;
841 struct bss_descriptor *pbssdesc; 805 struct bss_descriptor *bss;
842 806
843 lbs_deb_enter(LBS_DEB_JOIN); 807 lbs_deb_enter(LBS_DEB_JOIN);
844 808
845 padhocresult = &resp->params.result; 809 padhocresult = &resp->params.result;
846 810
847 lbs_deb_join("ADHOC_S_RESP: size = %d\n", le16_to_cpu(resp->size)); 811 lbs_deb_join("ADHOC_RESP: size = %d\n", le16_to_cpu(resp->size));
848 lbs_deb_join("ADHOC_S_RESP: command = %x\n", command); 812 lbs_deb_join("ADHOC_RESP: command = %x\n", command);
849 lbs_deb_join("ADHOC_S_RESP: result = %x\n", result); 813 lbs_deb_join("ADHOC_RESP: result = %x\n", result);
850 814
851 pbssdesc = adapter->pattemptedbssdesc; 815 if (!adapter->in_progress_assoc_req) {
816 lbs_deb_join("ADHOC_RESP: no in-progress association request\n");
817 ret = -1;
818 goto done;
819 }
820 bss = &adapter->in_progress_assoc_req->bss;
852 821
853 /* 822 /*
854 * Join result code 0 --> SUCCESS 823 * Join result code 0 --> SUCCESS
855 */ 824 */
856 if (result) { 825 if (result) {
857 lbs_deb_join("ADHOC_RESP failed\n"); 826 lbs_deb_join("ADHOC_RESP: failed\n");
858 if (adapter->connect_status == libertas_connected) { 827 if (adapter->connect_status == libertas_connected) {
859 libertas_mac_event_disconnected(priv); 828 libertas_mac_event_disconnected(priv);
860 } 829 }
861
862 memset(&adapter->curbssparams.bssdescriptor,
863 0x00, sizeof(adapter->curbssparams.bssdescriptor));
864
865 ret = -1; 830 ret = -1;
866 goto done; 831 goto done;
867 } 832 }
@@ -870,29 +835,22 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
870 * Now the join cmd should be successful 835 * Now the join cmd should be successful
871 * If BSSID has changed use SSID to compare instead of BSSID 836 * If BSSID has changed use SSID to compare instead of BSSID
872 */ 837 */
873 lbs_deb_join("ADHOC_J_RESP %s\n", pbssdesc->ssid.ssid); 838 lbs_deb_join("ADHOC_RESP: %s\n", bss->ssid.ssid);
874 839
875 /* Send a Media Connected event, according to the Spec */ 840 /* Send a Media Connected event, according to the Spec */
876 adapter->connect_status = libertas_connected; 841 adapter->connect_status = libertas_connected;
877 842
878 if (command == cmd_ret_802_11_ad_hoc_start) { 843 if (command == cmd_ret_802_11_ad_hoc_start) {
879 /* Update the created network descriptor with the new BSSID */ 844 /* Update the created network descriptor with the new BSSID */
880 memcpy(pbssdesc->bssid, padhocresult->BSSID, ETH_ALEN); 845 memcpy(bss->bssid, padhocresult->BSSID, ETH_ALEN);
881 } else {
882
883 /* Make a copy of current BSSID descriptor, only needed for join since
884 * the current descriptor is already being used for adhoc start
885 */
886 memmove(&adapter->curbssparams.bssdescriptor,
887 pbssdesc, sizeof(struct bss_descriptor));
888 } 846 }
889 847
890 /* Set the BSSID from the joined/started descriptor */ 848 /* Set the BSSID from the joined/started descriptor */
891 memcpy(&adapter->curbssparams.bssid, pbssdesc->bssid, ETH_ALEN); 849 memcpy(&adapter->curbssparams.bssid, bss->bssid, ETH_ALEN);
892 850
893 /* Set the new SSID to current SSID */ 851 /* Set the new SSID to current SSID */
894 memcpy(&adapter->curbssparams.ssid, 852 memcpy(&adapter->curbssparams.ssid, &bss->ssid,
895 &pbssdesc->ssid, sizeof(struct WLAN_802_11_SSID)); 853 sizeof(struct WLAN_802_11_SSID));
896 854
897 netif_carrier_on(priv->dev); 855 netif_carrier_on(priv->dev);
898 netif_wake_queue(priv->dev); 856 netif_wake_queue(priv->dev);
diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h
index 115f5a8ba346..c84e33cf8752 100644
--- a/drivers/net/wireless/libertas/join.h
+++ b/drivers/net/wireless/libertas/join.h
@@ -9,6 +9,7 @@
9#define _WLAN_JOIN_H 9#define _WLAN_JOIN_H
10 10
11#include "defs.h" 11#include "defs.h"
12#include "dev.h"
12 13
13struct cmd_ds_command; 14struct cmd_ds_command;
14extern int libertas_cmd_80211_authenticate(wlan_private * priv, 15extern int libertas_cmd_80211_authenticate(wlan_private * priv,
@@ -21,7 +22,7 @@ extern int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv,
21 struct cmd_ds_command *cmd); 22 struct cmd_ds_command *cmd);
22extern int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, 23extern int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
23 struct cmd_ds_command *cmd, 24 struct cmd_ds_command *cmd,
24 void *pssid); 25 void *pdata_buf);
25extern int libertas_cmd_80211_deauthenticate(wlan_private * priv, 26extern int libertas_cmd_80211_deauthenticate(wlan_private * priv,
26 struct cmd_ds_command *cmd); 27 struct cmd_ds_command *cmd);
27extern int libertas_cmd_80211_associate(wlan_private * priv, 28extern int libertas_cmd_80211_associate(wlan_private * priv,
@@ -43,8 +44,9 @@ struct WLAN_802_11_SSID;
43struct bss_descriptor; 44struct bss_descriptor;
44 45
45extern int libertas_start_adhoc_network(wlan_private * priv, 46extern int libertas_start_adhoc_network(wlan_private * priv,
46 struct WLAN_802_11_SSID *adhocssid); 47 struct assoc_request * assoc_req);
47extern int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor *pbssdesc); 48extern int libertas_join_adhoc_network(wlan_private * priv,
49 struct assoc_request * assoc_req);
48extern int libertas_stop_adhoc_network(wlan_private * priv); 50extern int libertas_stop_adhoc_network(wlan_private * priv);
49 51
50extern int libertas_send_deauthentication(wlan_private * priv); 52extern int libertas_send_deauthentication(wlan_private * priv);
@@ -52,6 +54,6 @@ extern int libertas_send_deauth(wlan_private * priv);
52 54
53extern int libertas_do_adhocstop_ioctl(wlan_private * priv); 55extern int libertas_do_adhocstop_ioctl(wlan_private * priv);
54 56
55int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc); 57int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req);
56 58
57#endif 59#endif
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 437a1e98671f..334da0c5c5a1 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -235,24 +235,10 @@ static void wlan_scan_process_results(wlan_private * priv)
235 wlan_adapter *adapter = priv->adapter; 235 wlan_adapter *adapter = priv->adapter;
236 struct bss_descriptor * iter_bss; 236 struct bss_descriptor * iter_bss;
237 237
238 mutex_lock(&adapter->lock); 238 if (adapter->connect_status == libertas_connected)
239 239 return;
240 if (adapter->connect_status != libertas_connected)
241 goto debug_print;
242
243 /* try to find the current BSSID in the scan list */
244 list_for_each_entry (iter_bss, &adapter->network_list, list) {
245 if (libertas_SSID_cmp(&iter_bss->ssid, &adapter->curbssparams.ssid))
246 continue;
247 if (memcmp(adapter->curbssparams.bssid, iter_bss->bssid, ETH_ALEN))
248 continue;
249 /* Make a copy of current BSSID descriptor */
250 memcpy(&adapter->curbssparams.bssdescriptor, iter_bss,
251 sizeof(struct bss_descriptor));
252 break;
253 }
254 240
255debug_print: 241 mutex_lock(&adapter->lock);
256 list_for_each_entry (iter_bss, &adapter->network_list, list) { 242 list_for_each_entry (iter_bss, &adapter->network_list, list) {
257 lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n", 243 lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n",
258 i++, 244 i++,
@@ -260,7 +246,6 @@ debug_print:
260 iter_bss->bssid[3], iter_bss->bssid[4], iter_bss->bssid[5], 246 iter_bss->bssid[3], iter_bss->bssid[4], iter_bss->bssid[5],
261 (s32) iter_bss->rssi, iter_bss->ssid.ssid); 247 (s32) iter_bss->rssi, iter_bss->ssid.ssid);
262 } 248 }
263
264 mutex_unlock(&adapter->lock); 249 mutex_unlock(&adapter->lock);
265} 250}
266 251