aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/assoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/assoc.c')
-rw-r--r--drivers/net/wireless/libertas/assoc.c345
1 files changed, 229 insertions, 116 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index c260bd1b3d46..ee82413b426d 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -2,6 +2,7 @@
2 2
3#include <linux/bitops.h> 3#include <linux/bitops.h>
4#include <net/ieee80211.h> 4#include <net/ieee80211.h>
5#include <linux/etherdevice.h>
5 6
6#include "assoc.h" 7#include "assoc.h"
7#include "join.h" 8#include "join.h"
@@ -13,59 +14,88 @@
13static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 14static 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 }; 15static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
15 16
17static void print_assoc_req(const char * extra, struct assoc_request * assoc_req)
18{
19 lbs_deb_assoc(
20 "#### Association Request: %s\n"
21 " flags: 0x%08lX\n"
22 " SSID: '%s'\n"
23 " channel: %d\n"
24 " band: %d\n"
25 " mode: %d\n"
26 " BSSID: " MAC_FMT "\n"
27 " Encryption:%s%s%s\n"
28 " auth: %d\n",
29 extra, assoc_req->flags,
30 escape_essid(assoc_req->ssid, assoc_req->ssid_len),
31 assoc_req->channel, assoc_req->band, assoc_req->mode,
32 MAC_ARG(assoc_req->bssid),
33 assoc_req->secinfo.WPAenabled ? " WPA" : "",
34 assoc_req->secinfo.WPA2enabled ? " WPA2" : "",
35 assoc_req->secinfo.wep_enabled ? " WEP" : "",
36 assoc_req->secinfo.auth_mode);
37}
38
39
16static int assoc_helper_essid(wlan_private *priv, 40static int assoc_helper_essid(wlan_private *priv,
17 struct assoc_request * assoc_req) 41 struct assoc_request * assoc_req)
18{ 42{
19 wlan_adapter *adapter = priv->adapter; 43 wlan_adapter *adapter = priv->adapter;
20 int ret = 0; 44 int ret = 0;
21 int i; 45 struct bss_descriptor * bss;
46 int channel = -1;
22 47
23 ENTER(); 48 lbs_deb_enter(LBS_DEB_ASSOC);
24 49
25 lbs_pr_debug(1, "New SSID requested: %s\n", assoc_req->ssid.ssid); 50 /* FIXME: take channel into account when picking SSIDs if a channel
51 * is set.
52 */
53
54 if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
55 channel = assoc_req->channel;
56
57 lbs_deb_assoc("New SSID requested: '%s'\n",
58 escape_essid(assoc_req->ssid, assoc_req->ssid_len));
26 if (assoc_req->mode == IW_MODE_INFRA) { 59 if (assoc_req->mode == IW_MODE_INFRA) {
27 if (adapter->prescan) { 60 if (adapter->prescan) {
28 libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 1); 61 libertas_send_specific_ssid_scan(priv, assoc_req->ssid,
62 assoc_req->ssid_len, 0);
29 } 63 }
30 64
31 i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, 65 bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid,
32 NULL, IW_MODE_INFRA); 66 assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
33 if (i >= 0) { 67 if (bss != NULL) {
34 lbs_pr_debug(1, 68 lbs_deb_assoc("SSID found in scan list, associating\n");
35 "SSID found in scan list ... associating...\n"); 69 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
36 70 ret = wlan_associate(priv, assoc_req);
37 ret = wlan_associate(priv, &adapter->scantable[i]);
38 if (ret == 0) {
39 memcpy(&assoc_req->bssid,
40 &adapter->scantable[i].macaddress,
41 ETH_ALEN);
42 }
43 } else { 71 } else {
44 lbs_pr_debug(1, "SSID '%s' not found; cannot associate\n", 72 lbs_deb_assoc("SSID not found; cannot associate\n");
45 assoc_req->ssid.ssid);
46 } 73 }
47 } else if (assoc_req->mode == IW_MODE_ADHOC) { 74 } else if (assoc_req->mode == IW_MODE_ADHOC) {
48 /* Scan for the network, do not save previous results. Stale 75 /* Scan for the network, do not save previous results. Stale
49 * scan data will cause us to join a non-existant adhoc network 76 * scan data will cause us to join a non-existant adhoc network
50 */ 77 */
51 libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 0); 78 libertas_send_specific_ssid_scan(priv, assoc_req->ssid,
79 assoc_req->ssid_len, 1);
52 80
53 /* Search for the requested SSID in the scan table */ 81 /* Search for the requested SSID in the scan table */
54 i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, NULL, 82 bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid,
55 IW_MODE_ADHOC); 83 assoc_req->ssid_len, NULL, IW_MODE_ADHOC, channel);
56 if (i >= 0) { 84 if (bss != NULL) {
57 lbs_pr_debug(1, "SSID found at %d in List, so join\n", ret); 85 lbs_deb_assoc("SSID found, will join\n");
58 libertas_join_adhoc_network(priv, &adapter->scantable[i]); 86 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
87 libertas_join_adhoc_network(priv, assoc_req);
59 } else { 88 } else {
60 /* else send START command */ 89 /* else send START command */
61 lbs_pr_debug(1, "SSID not found in list, so creating adhoc" 90 lbs_deb_assoc("SSID not found, creating adhoc network\n");
62 " with SSID '%s'\n", assoc_req->ssid.ssid); 91 memcpy(&assoc_req->bss.ssid, &assoc_req->ssid,
63 libertas_start_adhoc_network(priv, &assoc_req->ssid); 92 IW_ESSID_MAX_SIZE);
93 assoc_req->bss.ssid_len = assoc_req->ssid_len;
94 libertas_start_adhoc_network(priv, assoc_req);
64 } 95 }
65 memcpy(&assoc_req->bssid, &adapter->current_addr, ETH_ALEN);
66 } 96 }
67 97
68 LEAVE(); 98 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
69 return ret; 99 return ret;
70} 100}
71 101
@@ -74,33 +104,31 @@ static int assoc_helper_bssid(wlan_private *priv,
74 struct assoc_request * assoc_req) 104 struct assoc_request * assoc_req)
75{ 105{
76 wlan_adapter *adapter = priv->adapter; 106 wlan_adapter *adapter = priv->adapter;
77 int i, ret = 0; 107 int ret = 0;
78 108 struct bss_descriptor * bss;
79 ENTER();
80 109
81 lbs_pr_debug(1, "ASSOC: WAP: BSSID = " MAC_FMT "\n", 110 lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID " MAC_FMT,
82 MAC_ARG(assoc_req->bssid)); 111 MAC_ARG(assoc_req->bssid));
83 112
84 /* Search for index position in list for requested MAC */ 113 /* Search for index position in list for requested MAC */
85 i = libertas_find_BSSID_in_list(adapter, assoc_req->bssid, 114 bss = libertas_find_bssid_in_list(adapter, assoc_req->bssid,
86 assoc_req->mode); 115 assoc_req->mode);
87 if (i < 0) { 116 if (bss == NULL) {
88 lbs_pr_debug(1, "ASSOC: WAP: BSSID " MAC_FMT " not found, " 117 lbs_deb_assoc("ASSOC: WAP: BSSID " MAC_FMT " not found, "
89 "cannot associate.\n", MAC_ARG(assoc_req->bssid)); 118 "cannot associate.\n", MAC_ARG(assoc_req->bssid));
90 goto out; 119 goto out;
91 } 120 }
92 121
122 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
93 if (assoc_req->mode == IW_MODE_INFRA) { 123 if (assoc_req->mode == IW_MODE_INFRA) {
94 ret = wlan_associate(priv, &adapter->scantable[i]); 124 ret = wlan_associate(priv, assoc_req);
95 lbs_pr_debug(1, "ASSOC: return from wlan_associate(bssd) was %d\n", ret); 125 lbs_deb_assoc("ASSOC: wlan_associate(bssid) returned %d\n", ret);
96 } else if (assoc_req->mode == IW_MODE_ADHOC) { 126 } else if (assoc_req->mode == IW_MODE_ADHOC) {
97 libertas_join_adhoc_network(priv, &adapter->scantable[i]); 127 libertas_join_adhoc_network(priv, assoc_req);
98 } 128 }
99 memcpy(&assoc_req->ssid, &adapter->scantable[i].ssid,
100 sizeof(struct WLAN_802_11_SSID));
101 129
102out: 130out:
103 LEAVE(); 131 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
104 return ret; 132 return ret;
105} 133}
106 134
@@ -113,12 +141,12 @@ static int assoc_helper_associate(wlan_private *priv,
113 /* If we're given and 'any' BSSID, try associating based on SSID */ 141 /* If we're given and 'any' BSSID, try associating based on SSID */
114 142
115 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { 143 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
116 if (memcmp(bssid_any, assoc_req->bssid, ETH_ALEN) 144 if (compare_ether_addr(bssid_any, assoc_req->bssid)
117 && memcmp(bssid_off, assoc_req->bssid, ETH_ALEN)) { 145 && compare_ether_addr(bssid_off, assoc_req->bssid)) {
118 ret = assoc_helper_bssid(priv, assoc_req); 146 ret = assoc_helper_bssid(priv, assoc_req);
119 done = 1; 147 done = 1;
120 if (ret) { 148 if (ret) {
121 lbs_pr_debug(1, "ASSOC: bssid: ret = %d\n", ret); 149 lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret);
122 } 150 }
123 } 151 }
124 } 152 }
@@ -126,7 +154,7 @@ static int assoc_helper_associate(wlan_private *priv,
126 if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { 154 if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
127 ret = assoc_helper_essid(priv, assoc_req); 155 ret = assoc_helper_essid(priv, assoc_req);
128 if (ret) { 156 if (ret) {
129 lbs_pr_debug(1, "ASSOC: bssid: ret = %d\n", ret); 157 lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret);
130 } 158 }
131 } 159 }
132 160
@@ -140,12 +168,10 @@ static int assoc_helper_mode(wlan_private *priv,
140 wlan_adapter *adapter = priv->adapter; 168 wlan_adapter *adapter = priv->adapter;
141 int ret = 0; 169 int ret = 0;
142 170
143 ENTER(); 171 lbs_deb_enter(LBS_DEB_ASSOC);
144 172
145 if (assoc_req->mode == adapter->mode) { 173 if (assoc_req->mode == adapter->mode)
146 LEAVE(); 174 goto done;
147 return 0;
148 }
149 175
150 if (assoc_req->mode == IW_MODE_INFRA) { 176 if (assoc_req->mode == IW_MODE_INFRA) {
151 if (adapter->psstate != PS_STATE_FULL_POWER) 177 if (adapter->psstate != PS_STATE_FULL_POWER)
@@ -158,9 +184,73 @@ static int assoc_helper_mode(wlan_private *priv,
158 cmd_802_11_snmp_mib, 184 cmd_802_11_snmp_mib,
159 0, cmd_option_waitforrsp, 185 0, cmd_option_waitforrsp,
160 OID_802_11_INFRASTRUCTURE_MODE, 186 OID_802_11_INFRASTRUCTURE_MODE,
161 (void *) (size_t) assoc_req->mode); 187 /* Shoot me now */ (void *) (size_t) assoc_req->mode);
188
189done:
190 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
191 return ret;
192}
193
194
195static int update_channel(wlan_private * priv)
196{
197 /* the channel in f/w could be out of sync, get the current channel */
198 return libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
199 cmd_opt_802_11_rf_channel_get,
200 cmd_option_waitforrsp, 0, NULL);
201}
202
203static int assoc_helper_channel(wlan_private *priv,
204 struct assoc_request * assoc_req)
205{
206 wlan_adapter *adapter = priv->adapter;
207 int ret = 0;
208
209 lbs_deb_enter(LBS_DEB_ASSOC);
210
211 ret = update_channel(priv);
212 if (ret < 0) {
213 lbs_deb_assoc("ASSOC: channel: error getting channel.");
214 }
215
216 if (assoc_req->channel == adapter->curbssparams.channel)
217 goto done;
218
219 lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
220 adapter->curbssparams.channel, assoc_req->channel);
221
222 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
223 cmd_opt_802_11_rf_channel_set,
224 cmd_option_waitforrsp, 0, &assoc_req->channel);
225 if (ret < 0) {
226 lbs_deb_assoc("ASSOC: channel: error setting channel.");
227 }
228
229 ret = update_channel(priv);
230 if (ret < 0) {
231 lbs_deb_assoc("ASSOC: channel: error getting channel.");
232 }
233
234 if (assoc_req->channel != adapter->curbssparams.channel) {
235 lbs_deb_assoc("ASSOC: channel: failed to update channel to %d",
236 assoc_req->channel);
237 goto done;
238 }
239
240 if ( assoc_req->secinfo.wep_enabled
241 && (assoc_req->wep_keys[0].len
242 || assoc_req->wep_keys[1].len
243 || assoc_req->wep_keys[2].len
244 || assoc_req->wep_keys[3].len)) {
245 /* Make sure WEP keys are re-sent to firmware */
246 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
247 }
162 248
163 LEAVE(); 249 /* Must restart/rejoin adhoc networks after channel change */
250 set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
251
252done:
253 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
164 return ret; 254 return ret;
165} 255}
166 256
@@ -172,7 +262,7 @@ static int assoc_helper_wep_keys(wlan_private *priv,
172 int i; 262 int i;
173 int ret = 0; 263 int ret = 0;
174 264
175 ENTER(); 265 lbs_deb_enter(LBS_DEB_ASSOC);
176 266
177 /* Set or remove WEP keys */ 267 /* Set or remove WEP keys */
178 if ( assoc_req->wep_keys[0].len 268 if ( assoc_req->wep_keys[0].len
@@ -216,7 +306,7 @@ static int assoc_helper_wep_keys(wlan_private *priv,
216 mutex_unlock(&adapter->lock); 306 mutex_unlock(&adapter->lock);
217 307
218out: 308out:
219 LEAVE(); 309 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
220 return ret; 310 return ret;
221} 311}
222 312
@@ -226,14 +316,24 @@ static int assoc_helper_secinfo(wlan_private *priv,
226 wlan_adapter *adapter = priv->adapter; 316 wlan_adapter *adapter = priv->adapter;
227 int ret = 0; 317 int ret = 0;
228 318
229 ENTER(); 319 lbs_deb_enter(LBS_DEB_ASSOC);
230 320
231 memcpy(&adapter->secinfo, &assoc_req->secinfo, 321 memcpy(&adapter->secinfo, &assoc_req->secinfo,
232 sizeof(struct wlan_802_11_security)); 322 sizeof(struct wlan_802_11_security));
233 323
234 ret = libertas_set_mac_packet_filter(priv); 324 ret = libertas_set_mac_packet_filter(priv);
325 if (ret)
326 goto out;
327
328 /* enable/disable RSN */
329 ret = libertas_prepare_and_send_command(priv,
330 cmd_802_11_enable_rsn,
331 cmd_act_set,
332 cmd_option_waitforrsp,
333 0, assoc_req);
235 334
236 LEAVE(); 335out:
336 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
237 return ret; 337 return ret;
238} 338}
239 339
@@ -243,16 +343,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv,
243{ 343{
244 int ret = 0; 344 int ret = 0;
245 345
246 ENTER(); 346 lbs_deb_enter(LBS_DEB_ASSOC);
247
248 /* enable/Disable RSN */
249 ret = libertas_prepare_and_send_command(priv,
250 cmd_802_11_enable_rsn,
251 cmd_act_set,
252 cmd_option_waitforrsp,
253 0, assoc_req);
254 if (ret)
255 goto out;
256 347
257 ret = libertas_prepare_and_send_command(priv, 348 ret = libertas_prepare_and_send_command(priv,
258 cmd_802_11_key_material, 349 cmd_802_11_key_material,
@@ -260,8 +351,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv,
260 cmd_option_waitforrsp, 351 cmd_option_waitforrsp,
261 0, assoc_req); 352 0, assoc_req);
262 353
263out: 354 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
264 LEAVE();
265 return ret; 355 return ret;
266} 356}
267 357
@@ -272,7 +362,7 @@ static int assoc_helper_wpa_ie(wlan_private *priv,
272 wlan_adapter *adapter = priv->adapter; 362 wlan_adapter *adapter = priv->adapter;
273 int ret = 0; 363 int ret = 0;
274 364
275 ENTER(); 365 lbs_deb_enter(LBS_DEB_ASSOC);
276 366
277 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { 367 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
278 memcpy(&adapter->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len); 368 memcpy(&adapter->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len);
@@ -282,7 +372,7 @@ static int assoc_helper_wpa_ie(wlan_private *priv,
282 adapter->wpa_ie_len = 0; 372 adapter->wpa_ie_len = 0;
283 } 373 }
284 374
285 LEAVE(); 375 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
286 return ret; 376 return ret;
287} 377}
288 378
@@ -294,21 +384,21 @@ static int should_deauth_infrastructure(wlan_adapter *adapter,
294 return 0; 384 return 0;
295 385
296 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { 386 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
297 lbs_pr_debug(1, "Deauthenticating due to new SSID in " 387 lbs_deb_assoc("Deauthenticating due to new SSID in "
298 " configuration request.\n"); 388 " configuration request.\n");
299 return 1; 389 return 1;
300 } 390 }
301 391
302 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { 392 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
303 if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) { 393 if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) {
304 lbs_pr_debug(1, "Deauthenticating due to updated security " 394 lbs_deb_assoc("Deauthenticating due to updated security "
305 "info in configuration request.\n"); 395 "info in configuration request.\n");
306 return 1; 396 return 1;
307 } 397 }
308 } 398 }
309 399
310 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { 400 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
311 lbs_pr_debug(1, "Deauthenticating due to new BSSID in " 401 lbs_deb_assoc("Deauthenticating due to new BSSID in "
312 " configuration request.\n"); 402 " configuration request.\n");
313 return 1; 403 return 1;
314 } 404 }
@@ -329,10 +419,9 @@ static int should_stop_adhoc(wlan_adapter *adapter,
329 if (adapter->connect_status != libertas_connected) 419 if (adapter->connect_status != libertas_connected)
330 return 0; 420 return 0;
331 421
332 if (adapter->curbssparams.ssid.ssidlength != assoc_req->ssid.ssidlength) 422 if (libertas_ssid_cmp(adapter->curbssparams.ssid,
333 return 1; 423 adapter->curbssparams.ssid_len,
334 if (memcmp(adapter->curbssparams.ssid.ssid, assoc_req->ssid.ssid, 424 assoc_req->ssid, assoc_req->ssid_len) != 0)
335 adapter->curbssparams.ssid.ssidlength))
336 return 1; 425 return 1;
337 426
338 /* FIXME: deal with 'auto' mode somehow */ 427 /* FIXME: deal with 'auto' mode somehow */
@@ -341,11 +430,16 @@ static int should_stop_adhoc(wlan_adapter *adapter,
341 return 1; 430 return 1;
342 } 431 }
343 432
433 if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
434 if (assoc_req->channel != adapter->curbssparams.channel)
435 return 1;
436 }
437
344 return 0; 438 return 0;
345} 439}
346 440
347 441
348void wlan_association_worker(struct work_struct *work) 442void libertas_association_worker(struct work_struct *work)
349{ 443{
350 wlan_private *priv = container_of(work, wlan_private, assoc_work.work); 444 wlan_private *priv = container_of(work, wlan_private, assoc_work.work);
351 wlan_adapter *adapter = priv->adapter; 445 wlan_adapter *adapter = priv->adapter;
@@ -353,40 +447,38 @@ void wlan_association_worker(struct work_struct *work)
353 int ret = 0; 447 int ret = 0;
354 int find_any_ssid = 0; 448 int find_any_ssid = 0;
355 449
356 ENTER(); 450 lbs_deb_enter(LBS_DEB_ASSOC);
357 451
358 mutex_lock(&adapter->lock); 452 mutex_lock(&adapter->lock);
359 assoc_req = adapter->assoc_req; 453 assoc_req = adapter->pending_assoc_req;
360 adapter->assoc_req = NULL; 454 adapter->pending_assoc_req = NULL;
455 adapter->in_progress_assoc_req = assoc_req;
361 mutex_unlock(&adapter->lock); 456 mutex_unlock(&adapter->lock);
362 457
363 if (!assoc_req) { 458 if (!assoc_req)
364 LEAVE(); 459 goto done;
365 return;
366 }
367 460
368 lbs_pr_debug(1, "ASSOC: starting new association request: flags = 0x%lX\n", 461 print_assoc_req(__func__, assoc_req);
369 assoc_req->flags);
370 462
371 /* If 'any' SSID was specified, find an SSID to associate with */ 463 /* If 'any' SSID was specified, find an SSID to associate with */
372 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) 464 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)
373 && !assoc_req->ssid.ssidlength) 465 && !assoc_req->ssid_len)
374 find_any_ssid = 1; 466 find_any_ssid = 1;
375 467
376 /* But don't use 'any' SSID if there's a valid locked BSSID to use */ 468 /* But don't use 'any' SSID if there's a valid locked BSSID to use */
377 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { 469 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
378 if (memcmp(&assoc_req->bssid, bssid_any, ETH_ALEN) 470 if (compare_ether_addr(assoc_req->bssid, bssid_any)
379 && memcmp(&assoc_req->bssid, bssid_off, ETH_ALEN)) 471 && compare_ether_addr(assoc_req->bssid, bssid_off))
380 find_any_ssid = 0; 472 find_any_ssid = 0;
381 } 473 }
382 474
383 if (find_any_ssid) { 475 if (find_any_ssid) {
384 u8 new_mode; 476 u8 new_mode;
385 477
386 ret = libertas_find_best_network_SSID(priv, &assoc_req->ssid, 478 ret = libertas_find_best_network_ssid(priv, assoc_req->ssid,
387 assoc_req->mode, &new_mode); 479 &assoc_req->ssid_len, assoc_req->mode, &new_mode);
388 if (ret) { 480 if (ret) {
389 lbs_pr_debug(1, "Could not find best network\n"); 481 lbs_deb_assoc("Could not find best network\n");
390 ret = -ENETUNREACH; 482 ret = -ENETUNREACH;
391 goto out; 483 goto out;
392 } 484 }
@@ -406,7 +498,7 @@ void wlan_association_worker(struct work_struct *work)
406 if (should_deauth_infrastructure(adapter, assoc_req)) { 498 if (should_deauth_infrastructure(adapter, assoc_req)) {
407 ret = libertas_send_deauthentication(priv); 499 ret = libertas_send_deauthentication(priv);
408 if (ret) { 500 if (ret) {
409 lbs_pr_debug(1, "Deauthentication due to new " 501 lbs_deb_assoc("Deauthentication due to new "
410 "configuration request failed: %d\n", 502 "configuration request failed: %d\n",
411 ret); 503 ret);
412 } 504 }
@@ -415,7 +507,7 @@ void wlan_association_worker(struct work_struct *work)
415 if (should_stop_adhoc(adapter, assoc_req)) { 507 if (should_stop_adhoc(adapter, assoc_req)) {
416 ret = libertas_stop_adhoc_network(priv); 508 ret = libertas_stop_adhoc_network(priv);
417 if (ret) { 509 if (ret) {
418 lbs_pr_debug(1, "Teardown of AdHoc network due to " 510 lbs_deb_assoc("Teardown of AdHoc network due to "
419 "new configuration request failed: %d\n", 511 "new configuration request failed: %d\n",
420 ret); 512 ret);
421 } 513 }
@@ -427,7 +519,16 @@ void wlan_association_worker(struct work_struct *work)
427 if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { 519 if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
428 ret = assoc_helper_mode(priv, assoc_req); 520 ret = assoc_helper_mode(priv, assoc_req);
429 if (ret) { 521 if (ret) {
430lbs_pr_debug(1, "ASSOC(:%d) mode: ret = %d\n", __LINE__, ret); 522lbs_deb_assoc("ASSOC(:%d) mode: ret = %d\n", __LINE__, ret);
523 goto out;
524 }
525 }
526
527 if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
528 ret = assoc_helper_channel(priv, assoc_req);
529 if (ret) {
530 lbs_deb_assoc("ASSOC(:%d) channel: ret = %d\n",
531 __LINE__, ret);
431 goto out; 532 goto out;
432 } 533 }
433 } 534 }
@@ -436,7 +537,7 @@ lbs_pr_debug(1, "ASSOC(:%d) mode: ret = %d\n", __LINE__, ret);
436 || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { 537 || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
437 ret = assoc_helper_wep_keys(priv, assoc_req); 538 ret = assoc_helper_wep_keys(priv, assoc_req);
438 if (ret) { 539 if (ret) {
439lbs_pr_debug(1, "ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret); 540lbs_deb_assoc("ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret);
440 goto out; 541 goto out;
441 } 542 }
442 } 543 }
@@ -444,7 +545,7 @@ lbs_pr_debug(1, "ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret);
444 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { 545 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
445 ret = assoc_helper_secinfo(priv, assoc_req); 546 ret = assoc_helper_secinfo(priv, assoc_req);
446 if (ret) { 547 if (ret) {
447lbs_pr_debug(1, "ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret); 548lbs_deb_assoc("ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret);
448 goto out; 549 goto out;
449 } 550 }
450 } 551 }
@@ -452,7 +553,7 @@ lbs_pr_debug(1, "ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret);
452 if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) { 553 if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) {
453 ret = assoc_helper_wpa_ie(priv, assoc_req); 554 ret = assoc_helper_wpa_ie(priv, assoc_req);
454 if (ret) { 555 if (ret) {
455lbs_pr_debug(1, "ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret); 556lbs_deb_assoc("ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret);
456 goto out; 557 goto out;
457 } 558 }
458 } 559 }
@@ -461,7 +562,7 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret);
461 || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { 562 || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
462 ret = assoc_helper_wpa_keys(priv, assoc_req); 563 ret = assoc_helper_wpa_keys(priv, assoc_req);
463 if (ret) { 564 if (ret) {
464lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); 565lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret);
465 goto out; 566 goto out;
466 } 567 }
467 } 568 }
@@ -475,21 +576,23 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret);
475 576
476 ret = assoc_helper_associate(priv, assoc_req); 577 ret = assoc_helper_associate(priv, assoc_req);
477 if (ret) { 578 if (ret) {
478 lbs_pr_debug(1, "ASSOC: association attempt unsuccessful: %d\n", 579 lbs_deb_assoc("ASSOC: association attempt unsuccessful: %d\n",
479 ret); 580 ret);
480 success = 0; 581 success = 0;
481 } 582 }
482 583
483 if (adapter->connect_status != libertas_connected) { 584 if (adapter->connect_status != libertas_connected) {
484 lbs_pr_debug(1, "ASSOC: assoication attempt unsuccessful, " 585 lbs_deb_assoc("ASSOC: assoication attempt unsuccessful, "
485 "not connected.\n"); 586 "not connected.\n");
486 success = 0; 587 success = 0;
487 } 588 }
488 589
489 if (success) { 590 if (success) {
490 lbs_pr_debug(1, "ASSOC: association attempt successful. " 591 lbs_deb_assoc("ASSOC: association attempt successful. "
491 "Associated to '%s' (" MAC_FMT ")\n", 592 "Associated to '%s' (" MAC_FMT ")\n",
492 assoc_req->ssid.ssid, MAC_ARG(assoc_req->bssid)); 593 escape_essid(adapter->curbssparams.ssid,
594 adapter->curbssparams.ssid_len),
595 MAC_ARG(adapter->curbssparams.bssid));
493 libertas_prepare_and_send_command(priv, 596 libertas_prepare_and_send_command(priv,
494 cmd_802_11_rssi, 597 cmd_802_11_rssi,
495 0, cmd_option_waitforrsp, 0, NULL); 598 0, cmd_option_waitforrsp, 0, NULL);
@@ -498,18 +601,23 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret);
498 cmd_802_11_get_log, 601 cmd_802_11_get_log,
499 0, cmd_option_waitforrsp, 0, NULL); 602 0, cmd_option_waitforrsp, 0, NULL);
500 } else { 603 } else {
501
502 ret = -1; 604 ret = -1;
503 } 605 }
504 } 606 }
505 607
506out: 608out:
507 if (ret) { 609 if (ret) {
508 lbs_pr_debug(1, "ASSOC: reconfiguration attempt unsuccessful: %d\n", 610 lbs_deb_assoc("ASSOC: reconfiguration attempt unsuccessful: %d\n",
509 ret); 611 ret);
510 } 612 }
613
614 mutex_lock(&adapter->lock);
615 adapter->in_progress_assoc_req = NULL;
616 mutex_unlock(&adapter->lock);
511 kfree(assoc_req); 617 kfree(assoc_req);
512 LEAVE(); 618
619done:
620 lbs_deb_leave(LBS_DEB_ASSOC);
513} 621}
514 622
515 623
@@ -520,9 +628,10 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
520{ 628{
521 struct assoc_request * assoc_req; 629 struct assoc_request * assoc_req;
522 630
523 if (!adapter->assoc_req) { 631 if (!adapter->pending_assoc_req) {
524 adapter->assoc_req = kzalloc(sizeof(struct assoc_request), GFP_KERNEL); 632 adapter->pending_assoc_req = kzalloc(sizeof(struct assoc_request),
525 if (!adapter->assoc_req) { 633 GFP_KERNEL);
634 if (!adapter->pending_assoc_req) {
526 lbs_pr_info("Not enough memory to allocate association" 635 lbs_pr_info("Not enough memory to allocate association"
527 " request!\n"); 636 " request!\n");
528 return NULL; 637 return NULL;
@@ -532,15 +641,19 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
532 /* Copy current configuration attributes to the association request, 641 /* Copy current configuration attributes to the association request,
533 * but don't overwrite any that are already set. 642 * but don't overwrite any that are already set.
534 */ 643 */
535 assoc_req = adapter->assoc_req; 644 assoc_req = adapter->pending_assoc_req;
536 if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { 645 if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
537 memcpy(&assoc_req->ssid, adapter->curbssparams.ssid.ssid, 646 memcpy(&assoc_req->ssid, &adapter->curbssparams.ssid,
538 adapter->curbssparams.ssid.ssidlength); 647 IW_ESSID_MAX_SIZE);
648 assoc_req->ssid_len = adapter->curbssparams.ssid_len;
539 } 649 }
540 650
541 if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) 651 if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
542 assoc_req->channel = adapter->curbssparams.channel; 652 assoc_req->channel = adapter->curbssparams.channel;
543 653
654 if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags))
655 assoc_req->band = adapter->curbssparams.band;
656
544 if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) 657 if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags))
545 assoc_req->mode = adapter->mode; 658 assoc_req->mode = adapter->mode;
546 659
@@ -581,7 +694,7 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
581 assoc_req->wpa_ie_len = adapter->wpa_ie_len; 694 assoc_req->wpa_ie_len = adapter->wpa_ie_len;
582 } 695 }
583 696
697 print_assoc_req(__func__, assoc_req);
698
584 return assoc_req; 699 return assoc_req;
585} 700}
586
587