diff options
Diffstat (limited to 'drivers/net/wireless/libertas/assoc.c')
-rw-r--r-- | drivers/net/wireless/libertas/assoc.c | 535 |
1 files changed, 457 insertions, 78 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index dd8732611ba9..12a2ef9dacea 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/etherdevice.h> | 4 | #include <linux/etherdevice.h> |
5 | #include <linux/ieee80211.h> | 5 | #include <linux/ieee80211.h> |
6 | #include <linux/if_arp.h> | 6 | #include <linux/if_arp.h> |
7 | #include <linux/slab.h> | ||
7 | #include <net/lib80211.h> | 8 | #include <net/lib80211.h> |
8 | 9 | ||
9 | #include "assoc.h" | 10 | #include "assoc.h" |
@@ -23,6 +24,13 @@ static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) = | |||
23 | */ | 24 | */ |
24 | #define CAPINFO_MASK (~(0xda00)) | 25 | #define CAPINFO_MASK (~(0xda00)) |
25 | 26 | ||
27 | /** | ||
28 | * 802.11b/g supported bitrates (in 500Kb/s units) | ||
29 | */ | ||
30 | u8 lbs_bg_rates[MAX_RATES] = | ||
31 | { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, | ||
32 | 0x00, 0x00 }; | ||
33 | |||
26 | 34 | ||
27 | /** | 35 | /** |
28 | * @brief This function finds common rates between rates and card rates. | 36 | * @brief This function finds common rates between rates and card rates. |
@@ -147,6 +155,395 @@ static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth | |||
147 | } | 155 | } |
148 | 156 | ||
149 | 157 | ||
158 | int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action, | ||
159 | struct assoc_request *assoc) | ||
160 | { | ||
161 | struct cmd_ds_802_11_set_wep cmd; | ||
162 | int ret = 0; | ||
163 | |||
164 | lbs_deb_enter(LBS_DEB_CMD); | ||
165 | |||
166 | memset(&cmd, 0, sizeof(cmd)); | ||
167 | cmd.hdr.command = cpu_to_le16(CMD_802_11_SET_WEP); | ||
168 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||
169 | |||
170 | cmd.action = cpu_to_le16(cmd_action); | ||
171 | |||
172 | if (cmd_action == CMD_ACT_ADD) { | ||
173 | int i; | ||
174 | |||
175 | /* default tx key index */ | ||
176 | cmd.keyindex = cpu_to_le16(assoc->wep_tx_keyidx & | ||
177 | CMD_WEP_KEY_INDEX_MASK); | ||
178 | |||
179 | /* Copy key types and material to host command structure */ | ||
180 | for (i = 0; i < 4; i++) { | ||
181 | struct enc_key *pkey = &assoc->wep_keys[i]; | ||
182 | |||
183 | switch (pkey->len) { | ||
184 | case KEY_LEN_WEP_40: | ||
185 | cmd.keytype[i] = CMD_TYPE_WEP_40_BIT; | ||
186 | memmove(cmd.keymaterial[i], pkey->key, pkey->len); | ||
187 | lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i); | ||
188 | break; | ||
189 | case KEY_LEN_WEP_104: | ||
190 | cmd.keytype[i] = CMD_TYPE_WEP_104_BIT; | ||
191 | memmove(cmd.keymaterial[i], pkey->key, pkey->len); | ||
192 | lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i); | ||
193 | break; | ||
194 | case 0: | ||
195 | break; | ||
196 | default: | ||
197 | lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n", | ||
198 | i, pkey->len); | ||
199 | ret = -1; | ||
200 | goto done; | ||
201 | break; | ||
202 | } | ||
203 | } | ||
204 | } else if (cmd_action == CMD_ACT_REMOVE) { | ||
205 | /* ACT_REMOVE clears _all_ WEP keys */ | ||
206 | |||
207 | /* default tx key index */ | ||
208 | cmd.keyindex = cpu_to_le16(priv->wep_tx_keyidx & | ||
209 | CMD_WEP_KEY_INDEX_MASK); | ||
210 | lbs_deb_cmd("SET_WEP: remove key %d\n", priv->wep_tx_keyidx); | ||
211 | } | ||
212 | |||
213 | ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd); | ||
214 | done: | ||
215 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
216 | return ret; | ||
217 | } | ||
218 | |||
219 | int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action, | ||
220 | uint16_t *enable) | ||
221 | { | ||
222 | struct cmd_ds_802_11_enable_rsn cmd; | ||
223 | int ret; | ||
224 | |||
225 | lbs_deb_enter(LBS_DEB_CMD); | ||
226 | |||
227 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||
228 | cmd.action = cpu_to_le16(cmd_action); | ||
229 | |||
230 | if (cmd_action == CMD_ACT_GET) | ||
231 | cmd.enable = 0; | ||
232 | else { | ||
233 | if (*enable) | ||
234 | cmd.enable = cpu_to_le16(CMD_ENABLE_RSN); | ||
235 | else | ||
236 | cmd.enable = cpu_to_le16(CMD_DISABLE_RSN); | ||
237 | lbs_deb_cmd("ENABLE_RSN: %d\n", *enable); | ||
238 | } | ||
239 | |||
240 | ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd); | ||
241 | if (!ret && cmd_action == CMD_ACT_GET) | ||
242 | *enable = le16_to_cpu(cmd.enable); | ||
243 | |||
244 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
245 | return ret; | ||
246 | } | ||
247 | |||
248 | static void set_one_wpa_key(struct MrvlIEtype_keyParamSet *keyparam, | ||
249 | struct enc_key *key) | ||
250 | { | ||
251 | lbs_deb_enter(LBS_DEB_CMD); | ||
252 | |||
253 | if (key->flags & KEY_INFO_WPA_ENABLED) | ||
254 | keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED); | ||
255 | if (key->flags & KEY_INFO_WPA_UNICAST) | ||
256 | keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST); | ||
257 | if (key->flags & KEY_INFO_WPA_MCAST) | ||
258 | keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST); | ||
259 | |||
260 | keyparam->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); | ||
261 | keyparam->keytypeid = cpu_to_le16(key->type); | ||
262 | keyparam->keylen = cpu_to_le16(key->len); | ||
263 | memcpy(keyparam->key, key->key, key->len); | ||
264 | |||
265 | /* Length field doesn't include the {type,length} header */ | ||
266 | keyparam->length = cpu_to_le16(sizeof(*keyparam) - 4); | ||
267 | lbs_deb_leave(LBS_DEB_CMD); | ||
268 | } | ||
269 | |||
270 | int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action, | ||
271 | struct assoc_request *assoc) | ||
272 | { | ||
273 | struct cmd_ds_802_11_key_material cmd; | ||
274 | int ret = 0; | ||
275 | int index = 0; | ||
276 | |||
277 | lbs_deb_enter(LBS_DEB_CMD); | ||
278 | |||
279 | cmd.action = cpu_to_le16(cmd_action); | ||
280 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||
281 | |||
282 | if (cmd_action == CMD_ACT_GET) { | ||
283 | cmd.hdr.size = cpu_to_le16(sizeof(struct cmd_header) + 2); | ||
284 | } else { | ||
285 | memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet)); | ||
286 | |||
287 | if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc->flags)) { | ||
288 | set_one_wpa_key(&cmd.keyParamSet[index], | ||
289 | &assoc->wpa_unicast_key); | ||
290 | index++; | ||
291 | } | ||
292 | |||
293 | if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc->flags)) { | ||
294 | set_one_wpa_key(&cmd.keyParamSet[index], | ||
295 | &assoc->wpa_mcast_key); | ||
296 | index++; | ||
297 | } | ||
298 | |||
299 | /* The common header and as many keys as we included */ | ||
300 | cmd.hdr.size = cpu_to_le16(offsetof(typeof(cmd), | ||
301 | keyParamSet[index])); | ||
302 | } | ||
303 | ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd); | ||
304 | /* Copy the returned key to driver private data */ | ||
305 | if (!ret && cmd_action == CMD_ACT_GET) { | ||
306 | void *buf_ptr = cmd.keyParamSet; | ||
307 | void *resp_end = &(&cmd)[1]; | ||
308 | |||
309 | while (buf_ptr < resp_end) { | ||
310 | struct MrvlIEtype_keyParamSet *keyparam = buf_ptr; | ||
311 | struct enc_key *key; | ||
312 | uint16_t param_set_len = le16_to_cpu(keyparam->length); | ||
313 | uint16_t key_len = le16_to_cpu(keyparam->keylen); | ||
314 | uint16_t key_flags = le16_to_cpu(keyparam->keyinfo); | ||
315 | uint16_t key_type = le16_to_cpu(keyparam->keytypeid); | ||
316 | void *end; | ||
317 | |||
318 | end = (void *)keyparam + sizeof(keyparam->type) | ||
319 | + sizeof(keyparam->length) + param_set_len; | ||
320 | |||
321 | /* Make sure we don't access past the end of the IEs */ | ||
322 | if (end > resp_end) | ||
323 | break; | ||
324 | |||
325 | if (key_flags & KEY_INFO_WPA_UNICAST) | ||
326 | key = &priv->wpa_unicast_key; | ||
327 | else if (key_flags & KEY_INFO_WPA_MCAST) | ||
328 | key = &priv->wpa_mcast_key; | ||
329 | else | ||
330 | break; | ||
331 | |||
332 | /* Copy returned key into driver */ | ||
333 | memset(key, 0, sizeof(struct enc_key)); | ||
334 | if (key_len > sizeof(key->key)) | ||
335 | break; | ||
336 | key->type = key_type; | ||
337 | key->flags = key_flags; | ||
338 | key->len = key_len; | ||
339 | memcpy(key->key, keyparam->key, key->len); | ||
340 | |||
341 | buf_ptr = end + 1; | ||
342 | } | ||
343 | } | ||
344 | |||
345 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
346 | return ret; | ||
347 | } | ||
348 | |||
349 | static __le16 lbs_rate_to_fw_bitmap(int rate, int lower_rates_ok) | ||
350 | { | ||
351 | /* Bit Rate | ||
352 | * 15:13 Reserved | ||
353 | * 12 54 Mbps | ||
354 | * 11 48 Mbps | ||
355 | * 10 36 Mbps | ||
356 | * 9 24 Mbps | ||
357 | * 8 18 Mbps | ||
358 | * 7 12 Mbps | ||
359 | * 6 9 Mbps | ||
360 | * 5 6 Mbps | ||
361 | * 4 Reserved | ||
362 | * 3 11 Mbps | ||
363 | * 2 5.5 Mbps | ||
364 | * 1 2 Mbps | ||
365 | * 0 1 Mbps | ||
366 | **/ | ||
367 | |||
368 | uint16_t ratemask; | ||
369 | int i = lbs_data_rate_to_fw_index(rate); | ||
370 | if (lower_rates_ok) | ||
371 | ratemask = (0x1fef >> (12 - i)); | ||
372 | else | ||
373 | ratemask = (1 << i); | ||
374 | return cpu_to_le16(ratemask); | ||
375 | } | ||
376 | |||
377 | int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv, | ||
378 | uint16_t cmd_action) | ||
379 | { | ||
380 | struct cmd_ds_802_11_rate_adapt_rateset cmd; | ||
381 | int ret; | ||
382 | |||
383 | lbs_deb_enter(LBS_DEB_CMD); | ||
384 | |||
385 | if (!priv->cur_rate && !priv->enablehwauto) | ||
386 | return -EINVAL; | ||
387 | |||
388 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||
389 | |||
390 | cmd.action = cpu_to_le16(cmd_action); | ||
391 | cmd.enablehwauto = cpu_to_le16(priv->enablehwauto); | ||
392 | cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto); | ||
393 | ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd); | ||
394 | if (!ret && cmd_action == CMD_ACT_GET) | ||
395 | priv->enablehwauto = le16_to_cpu(cmd.enablehwauto); | ||
396 | |||
397 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
398 | return ret; | ||
399 | } | ||
400 | |||
401 | /** | ||
402 | * @brief Set the data rate | ||
403 | * | ||
404 | * @param priv A pointer to struct lbs_private structure | ||
405 | * @param rate The desired data rate, or 0 to clear a locked rate | ||
406 | * | ||
407 | * @return 0 on success, error on failure | ||
408 | */ | ||
409 | int lbs_set_data_rate(struct lbs_private *priv, u8 rate) | ||
410 | { | ||
411 | struct cmd_ds_802_11_data_rate cmd; | ||
412 | int ret = 0; | ||
413 | |||
414 | lbs_deb_enter(LBS_DEB_CMD); | ||
415 | |||
416 | memset(&cmd, 0, sizeof(cmd)); | ||
417 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||
418 | |||
419 | if (rate > 0) { | ||
420 | cmd.action = cpu_to_le16(CMD_ACT_SET_TX_FIX_RATE); | ||
421 | cmd.rates[0] = lbs_data_rate_to_fw_index(rate); | ||
422 | if (cmd.rates[0] == 0) { | ||
423 | lbs_deb_cmd("DATA_RATE: invalid requested rate of" | ||
424 | " 0x%02X\n", rate); | ||
425 | ret = 0; | ||
426 | goto out; | ||
427 | } | ||
428 | lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", cmd.rates[0]); | ||
429 | } else { | ||
430 | cmd.action = cpu_to_le16(CMD_ACT_SET_TX_AUTO); | ||
431 | lbs_deb_cmd("DATA_RATE: setting auto\n"); | ||
432 | } | ||
433 | |||
434 | ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd); | ||
435 | if (ret) | ||
436 | goto out; | ||
437 | |||
438 | lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof(cmd)); | ||
439 | |||
440 | /* FIXME: get actual rates FW can do if this command actually returns | ||
441 | * all data rates supported. | ||
442 | */ | ||
443 | priv->cur_rate = lbs_fw_index_to_data_rate(cmd.rates[0]); | ||
444 | lbs_deb_cmd("DATA_RATE: current rate is 0x%02x\n", priv->cur_rate); | ||
445 | |||
446 | out: | ||
447 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
448 | return ret; | ||
449 | } | ||
450 | |||
451 | |||
452 | int lbs_cmd_802_11_rssi(struct lbs_private *priv, | ||
453 | struct cmd_ds_command *cmd) | ||
454 | { | ||
455 | |||
456 | lbs_deb_enter(LBS_DEB_CMD); | ||
457 | cmd->command = cpu_to_le16(CMD_802_11_RSSI); | ||
458 | cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + | ||
459 | sizeof(struct cmd_header)); | ||
460 | cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR); | ||
461 | |||
462 | /* reset Beacon SNR/NF/RSSI values */ | ||
463 | priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0; | ||
464 | priv->SNR[TYPE_BEACON][TYPE_AVG] = 0; | ||
465 | priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0; | ||
466 | priv->NF[TYPE_BEACON][TYPE_AVG] = 0; | ||
467 | priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0; | ||
468 | priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0; | ||
469 | |||
470 | lbs_deb_leave(LBS_DEB_CMD); | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | int lbs_ret_802_11_rssi(struct lbs_private *priv, | ||
475 | struct cmd_ds_command *resp) | ||
476 | { | ||
477 | struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp; | ||
478 | |||
479 | lbs_deb_enter(LBS_DEB_CMD); | ||
480 | |||
481 | /* store the non average value */ | ||
482 | priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR); | ||
483 | priv->NF[TYPE_BEACON][TYPE_NOAVG] = | ||
484 | get_unaligned_le16(&rssirsp->noisefloor); | ||
485 | |||
486 | priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR); | ||
487 | priv->NF[TYPE_BEACON][TYPE_AVG] = | ||
488 | get_unaligned_le16(&rssirsp->avgnoisefloor); | ||
489 | |||
490 | priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = | ||
491 | CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG], | ||
492 | priv->NF[TYPE_BEACON][TYPE_NOAVG]); | ||
493 | |||
494 | priv->RSSI[TYPE_BEACON][TYPE_AVG] = | ||
495 | CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE, | ||
496 | priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE); | ||
497 | |||
498 | lbs_deb_cmd("RSSI: beacon %d, avg %d\n", | ||
499 | priv->RSSI[TYPE_BEACON][TYPE_NOAVG], | ||
500 | priv->RSSI[TYPE_BEACON][TYPE_AVG]); | ||
501 | |||
502 | lbs_deb_leave(LBS_DEB_CMD); | ||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | |||
507 | int lbs_cmd_bcn_ctrl(struct lbs_private *priv, | ||
508 | struct cmd_ds_command *cmd, | ||
509 | u16 cmd_action) | ||
510 | { | ||
511 | struct cmd_ds_802_11_beacon_control | ||
512 | *bcn_ctrl = &cmd->params.bcn_ctrl; | ||
513 | |||
514 | lbs_deb_enter(LBS_DEB_CMD); | ||
515 | cmd->size = | ||
516 | cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control) | ||
517 | + sizeof(struct cmd_header)); | ||
518 | cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL); | ||
519 | |||
520 | bcn_ctrl->action = cpu_to_le16(cmd_action); | ||
521 | bcn_ctrl->beacon_enable = cpu_to_le16(priv->beacon_enable); | ||
522 | bcn_ctrl->beacon_period = cpu_to_le16(priv->beacon_period); | ||
523 | |||
524 | lbs_deb_leave(LBS_DEB_CMD); | ||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | int lbs_ret_802_11_bcn_ctrl(struct lbs_private *priv, | ||
529 | struct cmd_ds_command *resp) | ||
530 | { | ||
531 | struct cmd_ds_802_11_beacon_control *bcn_ctrl = | ||
532 | &resp->params.bcn_ctrl; | ||
533 | |||
534 | lbs_deb_enter(LBS_DEB_CMD); | ||
535 | |||
536 | if (bcn_ctrl->action == CMD_ACT_GET) { | ||
537 | priv->beacon_enable = (u8) le16_to_cpu(bcn_ctrl->beacon_enable); | ||
538 | priv->beacon_period = le16_to_cpu(bcn_ctrl->beacon_period); | ||
539 | } | ||
540 | |||
541 | lbs_deb_enter(LBS_DEB_CMD); | ||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | |||
546 | |||
150 | static int lbs_assoc_post(struct lbs_private *priv, | 547 | static int lbs_assoc_post(struct lbs_private *priv, |
151 | struct cmd_ds_802_11_associate_response *resp) | 548 | struct cmd_ds_802_11_associate_response *resp) |
152 | { | 549 | { |
@@ -226,7 +623,7 @@ static int lbs_assoc_post(struct lbs_private *priv, | |||
226 | priv->connect_status = LBS_CONNECTED; | 623 | priv->connect_status = LBS_CONNECTED; |
227 | 624 | ||
228 | /* Update current SSID and BSSID */ | 625 | /* Update current SSID and BSSID */ |
229 | memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE); | 626 | memcpy(&priv->curbssparams.ssid, &bss->ssid, IEEE80211_MAX_SSID_LEN); |
230 | priv->curbssparams.ssid_len = bss->ssid_len; | 627 | priv->curbssparams.ssid_len = bss->ssid_len; |
231 | memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN); | 628 | memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN); |
232 | 629 | ||
@@ -369,12 +766,7 @@ static int lbs_associate(struct lbs_private *priv, | |||
369 | (u16)(pos - (u8 *) &cmd.iebuf)); | 766 | (u16)(pos - (u8 *) &cmd.iebuf)); |
370 | 767 | ||
371 | /* update curbssparams */ | 768 | /* update curbssparams */ |
372 | priv->curbssparams.channel = bss->phy.ds.channel; | 769 | priv->channel = bss->phy.ds.channel; |
373 | |||
374 | if (lbs_parse_dnld_countryinfo_11d(priv, bss)) { | ||
375 | ret = -1; | ||
376 | goto done; | ||
377 | } | ||
378 | 770 | ||
379 | ret = lbs_cmd_with_response(priv, command, &cmd); | 771 | ret = lbs_cmd_with_response(priv, command, &cmd); |
380 | if (ret == 0) { | 772 | if (ret == 0) { |
@@ -414,8 +806,7 @@ static int lbs_try_associate(struct lbs_private *priv, | |||
414 | } | 806 | } |
415 | 807 | ||
416 | /* Use short preamble only when both the BSS and firmware support it */ | 808 | /* Use short preamble only when both the BSS and firmware support it */ |
417 | if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && | 809 | if (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) |
418 | (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) | ||
419 | preamble = RADIO_PREAMBLE_SHORT; | 810 | preamble = RADIO_PREAMBLE_SHORT; |
420 | 811 | ||
421 | ret = lbs_set_radio(priv, preamble, 1); | 812 | ret = lbs_set_radio(priv, preamble, 1); |
@@ -472,7 +863,7 @@ static int lbs_adhoc_post(struct lbs_private *priv, | |||
472 | memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN); | 863 | memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN); |
473 | 864 | ||
474 | /* Set the new SSID to current SSID */ | 865 | /* Set the new SSID to current SSID */ |
475 | memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE); | 866 | memcpy(&priv->curbssparams.ssid, &bss->ssid, IEEE80211_MAX_SSID_LEN); |
476 | priv->curbssparams.ssid_len = bss->ssid_len; | 867 | priv->curbssparams.ssid_len = bss->ssid_len; |
477 | 868 | ||
478 | netif_carrier_on(priv->dev); | 869 | netif_carrier_on(priv->dev); |
@@ -487,7 +878,7 @@ static int lbs_adhoc_post(struct lbs_private *priv, | |||
487 | lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n", | 878 | lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n", |
488 | print_ssid(ssid, bss->ssid, bss->ssid_len), | 879 | print_ssid(ssid, bss->ssid, bss->ssid_len), |
489 | priv->curbssparams.bssid, | 880 | priv->curbssparams.bssid, |
490 | priv->curbssparams.channel); | 881 | priv->channel); |
491 | 882 | ||
492 | done: | 883 | done: |
493 | lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); | 884 | lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); |
@@ -546,8 +937,7 @@ static int lbs_adhoc_join(struct lbs_private *priv, | |||
546 | } | 937 | } |
547 | 938 | ||
548 | /* Use short preamble only when both the BSS and firmware support it */ | 939 | /* Use short preamble only when both the BSS and firmware support it */ |
549 | if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && | 940 | if (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) { |
550 | (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) { | ||
551 | lbs_deb_join("AdhocJoin: Short preamble\n"); | 941 | lbs_deb_join("AdhocJoin: Short preamble\n"); |
552 | preamble = RADIO_PREAMBLE_SHORT; | 942 | preamble = RADIO_PREAMBLE_SHORT; |
553 | } | 943 | } |
@@ -560,7 +950,7 @@ static int lbs_adhoc_join(struct lbs_private *priv, | |||
560 | lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band); | 950 | lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band); |
561 | 951 | ||
562 | priv->adhoccreate = 0; | 952 | priv->adhoccreate = 0; |
563 | priv->curbssparams.channel = bss->channel; | 953 | priv->channel = bss->channel; |
564 | 954 | ||
565 | /* Build the join command */ | 955 | /* Build the join command */ |
566 | memset(&cmd, 0, sizeof(cmd)); | 956 | memset(&cmd, 0, sizeof(cmd)); |
@@ -633,11 +1023,6 @@ static int lbs_adhoc_join(struct lbs_private *priv, | |||
633 | } | 1023 | } |
634 | } | 1024 | } |
635 | 1025 | ||
636 | if (lbs_parse_dnld_countryinfo_11d(priv, bss)) { | ||
637 | ret = -1; | ||
638 | goto out; | ||
639 | } | ||
640 | |||
641 | ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd); | 1026 | ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd); |
642 | if (ret == 0) { | 1027 | if (ret == 0) { |
643 | ret = lbs_adhoc_post(priv, | 1028 | ret = lbs_adhoc_post(priv, |
@@ -661,7 +1046,7 @@ static int lbs_adhoc_start(struct lbs_private *priv, | |||
661 | struct assoc_request *assoc_req) | 1046 | struct assoc_request *assoc_req) |
662 | { | 1047 | { |
663 | struct cmd_ds_802_11_ad_hoc_start cmd; | 1048 | struct cmd_ds_802_11_ad_hoc_start cmd; |
664 | u8 preamble = RADIO_PREAMBLE_LONG; | 1049 | u8 preamble = RADIO_PREAMBLE_SHORT; |
665 | size_t ratesize = 0; | 1050 | size_t ratesize = 0; |
666 | u16 tmpcap = 0; | 1051 | u16 tmpcap = 0; |
667 | int ret = 0; | 1052 | int ret = 0; |
@@ -669,11 +1054,6 @@ static int lbs_adhoc_start(struct lbs_private *priv, | |||
669 | 1054 | ||
670 | lbs_deb_enter(LBS_DEB_ASSOC); | 1055 | lbs_deb_enter(LBS_DEB_ASSOC); |
671 | 1056 | ||
672 | if (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) { | ||
673 | lbs_deb_join("ADHOC_START: Will use short preamble\n"); | ||
674 | preamble = RADIO_PREAMBLE_SHORT; | ||
675 | } | ||
676 | |||
677 | ret = lbs_set_radio(priv, preamble, 1); | 1057 | ret = lbs_set_radio(priv, preamble, 1); |
678 | if (ret) | 1058 | if (ret) |
679 | goto out; | 1059 | goto out; |
@@ -737,12 +1117,6 @@ static int lbs_adhoc_start(struct lbs_private *priv, | |||
737 | lbs_deb_join("ADHOC_START: rates=%02x %02x %02x %02x\n", | 1117 | lbs_deb_join("ADHOC_START: rates=%02x %02x %02x %02x\n", |
738 | cmd.rates[0], cmd.rates[1], cmd.rates[2], cmd.rates[3]); | 1118 | cmd.rates[0], cmd.rates[1], cmd.rates[2], cmd.rates[3]); |
739 | 1119 | ||
740 | if (lbs_create_dnld_countryinfo_11d(priv)) { | ||
741 | lbs_deb_join("ADHOC_START: dnld_countryinfo_11d failed\n"); | ||
742 | ret = -1; | ||
743 | goto out; | ||
744 | } | ||
745 | |||
746 | lbs_deb_join("ADHOC_START: Starting Ad-Hoc BSS on channel %d, band %d\n", | 1120 | lbs_deb_join("ADHOC_START: Starting Ad-Hoc BSS on channel %d, band %d\n", |
747 | assoc_req->channel, assoc_req->band); | 1121 | assoc_req->channel, assoc_req->band); |
748 | 1122 | ||
@@ -787,11 +1161,11 @@ int lbs_adhoc_stop(struct lbs_private *priv) | |||
787 | static inline int match_bss_no_security(struct lbs_802_11_security *secinfo, | 1161 | static inline int match_bss_no_security(struct lbs_802_11_security *secinfo, |
788 | struct bss_descriptor *match_bss) | 1162 | struct bss_descriptor *match_bss) |
789 | { | 1163 | { |
790 | if (!secinfo->wep_enabled && !secinfo->WPAenabled | 1164 | if (!secinfo->wep_enabled && |
791 | && !secinfo->WPA2enabled | 1165 | !secinfo->WPAenabled && !secinfo->WPA2enabled && |
792 | && match_bss->wpa_ie[0] != WLAN_EID_GENERIC | 1166 | match_bss->wpa_ie[0] != WLAN_EID_GENERIC && |
793 | && match_bss->rsn_ie[0] != WLAN_EID_RSN | 1167 | match_bss->rsn_ie[0] != WLAN_EID_RSN && |
794 | && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) | 1168 | !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) |
795 | return 1; | 1169 | return 1; |
796 | else | 1170 | else |
797 | return 0; | 1171 | return 0; |
@@ -800,9 +1174,9 @@ static inline int match_bss_no_security(struct lbs_802_11_security *secinfo, | |||
800 | static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo, | 1174 | static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo, |
801 | struct bss_descriptor *match_bss) | 1175 | struct bss_descriptor *match_bss) |
802 | { | 1176 | { |
803 | if (secinfo->wep_enabled && !secinfo->WPAenabled | 1177 | if (secinfo->wep_enabled && |
804 | && !secinfo->WPA2enabled | 1178 | !secinfo->WPAenabled && !secinfo->WPA2enabled && |
805 | && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) | 1179 | (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) |
806 | return 1; | 1180 | return 1; |
807 | else | 1181 | else |
808 | return 0; | 1182 | return 0; |
@@ -811,8 +1185,8 @@ static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo, | |||
811 | static inline int match_bss_wpa(struct lbs_802_11_security *secinfo, | 1185 | static inline int match_bss_wpa(struct lbs_802_11_security *secinfo, |
812 | struct bss_descriptor *match_bss) | 1186 | struct bss_descriptor *match_bss) |
813 | { | 1187 | { |
814 | if (!secinfo->wep_enabled && secinfo->WPAenabled | 1188 | if (!secinfo->wep_enabled && secinfo->WPAenabled && |
815 | && (match_bss->wpa_ie[0] == WLAN_EID_GENERIC) | 1189 | (match_bss->wpa_ie[0] == WLAN_EID_GENERIC) |
816 | /* privacy bit may NOT be set in some APs like LinkSys WRT54G | 1190 | /* privacy bit may NOT be set in some APs like LinkSys WRT54G |
817 | && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */ | 1191 | && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */ |
818 | ) | 1192 | ) |
@@ -837,11 +1211,11 @@ static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo, | |||
837 | static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo, | 1211 | static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo, |
838 | struct bss_descriptor *match_bss) | 1212 | struct bss_descriptor *match_bss) |
839 | { | 1213 | { |
840 | if (!secinfo->wep_enabled && !secinfo->WPAenabled | 1214 | if (!secinfo->wep_enabled && |
841 | && !secinfo->WPA2enabled | 1215 | !secinfo->WPAenabled && !secinfo->WPA2enabled && |
842 | && (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) | 1216 | (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) && |
843 | && (match_bss->rsn_ie[0] != WLAN_EID_RSN) | 1217 | (match_bss->rsn_ie[0] != WLAN_EID_RSN) && |
844 | && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) | 1218 | (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) |
845 | return 1; | 1219 | return 1; |
846 | else | 1220 | else |
847 | return 0; | 1221 | return 0; |
@@ -1099,7 +1473,7 @@ static int assoc_helper_essid(struct lbs_private *priv, | |||
1099 | /* else send START command */ | 1473 | /* else send START command */ |
1100 | lbs_deb_assoc("SSID not found, creating adhoc network\n"); | 1474 | lbs_deb_assoc("SSID not found, creating adhoc network\n"); |
1101 | memcpy(&assoc_req->bss.ssid, &assoc_req->ssid, | 1475 | memcpy(&assoc_req->bss.ssid, &assoc_req->ssid, |
1102 | IW_ESSID_MAX_SIZE); | 1476 | IEEE80211_MAX_SSID_LEN); |
1103 | assoc_req->bss.ssid_len = assoc_req->ssid_len; | 1477 | assoc_req->bss.ssid_len = assoc_req->ssid_len; |
1104 | lbs_adhoc_start(priv, assoc_req); | 1478 | lbs_adhoc_start(priv, assoc_req); |
1105 | } | 1479 | } |
@@ -1152,8 +1526,8 @@ static int assoc_helper_associate(struct lbs_private *priv, | |||
1152 | /* If we're given and 'any' BSSID, try associating based on SSID */ | 1526 | /* If we're given and 'any' BSSID, try associating based on SSID */ |
1153 | 1527 | ||
1154 | if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { | 1528 | if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { |
1155 | if (compare_ether_addr(bssid_any, assoc_req->bssid) | 1529 | if (compare_ether_addr(bssid_any, assoc_req->bssid) && |
1156 | && compare_ether_addr(bssid_off, assoc_req->bssid)) { | 1530 | compare_ether_addr(bssid_off, assoc_req->bssid)) { |
1157 | ret = assoc_helper_bssid(priv, assoc_req); | 1531 | ret = assoc_helper_bssid(priv, assoc_req); |
1158 | done = 1; | 1532 | done = 1; |
1159 | } | 1533 | } |
@@ -1185,7 +1559,8 @@ static int assoc_helper_mode(struct lbs_private *priv, | |||
1185 | } | 1559 | } |
1186 | 1560 | ||
1187 | priv->mode = assoc_req->mode; | 1561 | priv->mode = assoc_req->mode; |
1188 | ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, assoc_req->mode); | 1562 | ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, |
1563 | assoc_req->mode == IW_MODE_ADHOC ? 2 : 1); | ||
1189 | 1564 | ||
1190 | done: | 1565 | done: |
1191 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | 1566 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
@@ -1205,7 +1580,7 @@ static int assoc_helper_channel(struct lbs_private *priv, | |||
1205 | goto done; | 1580 | goto done; |
1206 | } | 1581 | } |
1207 | 1582 | ||
1208 | if (assoc_req->channel == priv->curbssparams.channel) | 1583 | if (assoc_req->channel == priv->channel) |
1209 | goto done; | 1584 | goto done; |
1210 | 1585 | ||
1211 | if (priv->mesh_dev) { | 1586 | if (priv->mesh_dev) { |
@@ -1217,7 +1592,7 @@ static int assoc_helper_channel(struct lbs_private *priv, | |||
1217 | } | 1592 | } |
1218 | 1593 | ||
1219 | lbs_deb_assoc("ASSOC: channel: %d -> %d\n", | 1594 | lbs_deb_assoc("ASSOC: channel: %d -> %d\n", |
1220 | priv->curbssparams.channel, assoc_req->channel); | 1595 | priv->channel, assoc_req->channel); |
1221 | 1596 | ||
1222 | ret = lbs_set_channel(priv, assoc_req->channel); | 1597 | ret = lbs_set_channel(priv, assoc_req->channel); |
1223 | if (ret < 0) | 1598 | if (ret < 0) |
@@ -1232,17 +1607,15 @@ static int assoc_helper_channel(struct lbs_private *priv, | |||
1232 | goto done; | 1607 | goto done; |
1233 | } | 1608 | } |
1234 | 1609 | ||
1235 | if (assoc_req->channel != priv->curbssparams.channel) { | 1610 | if (assoc_req->channel != priv->channel) { |
1236 | lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n", | 1611 | lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n", |
1237 | assoc_req->channel); | 1612 | assoc_req->channel); |
1238 | goto restore_mesh; | 1613 | goto restore_mesh; |
1239 | } | 1614 | } |
1240 | 1615 | ||
1241 | if ( assoc_req->secinfo.wep_enabled | 1616 | if (assoc_req->secinfo.wep_enabled && |
1242 | && (assoc_req->wep_keys[0].len | 1617 | (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len || |
1243 | || assoc_req->wep_keys[1].len | 1618 | assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len)) { |
1244 | || assoc_req->wep_keys[2].len | ||
1245 | || assoc_req->wep_keys[3].len)) { | ||
1246 | /* Make sure WEP keys are re-sent to firmware */ | 1619 | /* Make sure WEP keys are re-sent to firmware */ |
1247 | set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); | 1620 | set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); |
1248 | } | 1621 | } |
@@ -1253,7 +1626,7 @@ static int assoc_helper_channel(struct lbs_private *priv, | |||
1253 | restore_mesh: | 1626 | restore_mesh: |
1254 | if (priv->mesh_dev) | 1627 | if (priv->mesh_dev) |
1255 | lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, | 1628 | lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, |
1256 | priv->curbssparams.channel); | 1629 | priv->channel); |
1257 | 1630 | ||
1258 | done: | 1631 | done: |
1259 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | 1632 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
@@ -1475,7 +1848,7 @@ static int should_stop_adhoc(struct lbs_private *priv, | |||
1475 | } | 1848 | } |
1476 | 1849 | ||
1477 | if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { | 1850 | if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { |
1478 | if (assoc_req->channel != priv->curbssparams.channel) | 1851 | if (assoc_req->channel != priv->channel) |
1479 | return 1; | 1852 | return 1; |
1480 | } | 1853 | } |
1481 | 1854 | ||
@@ -1557,7 +1930,7 @@ static int lbs_find_best_network_ssid(struct lbs_private *priv, | |||
1557 | 1930 | ||
1558 | found = lbs_find_best_ssid_in_list(priv, preferred_mode); | 1931 | found = lbs_find_best_ssid_in_list(priv, preferred_mode); |
1559 | if (found && (found->ssid_len > 0)) { | 1932 | if (found && (found->ssid_len > 0)) { |
1560 | memcpy(out_ssid, &found->ssid, IW_ESSID_MAX_SIZE); | 1933 | memcpy(out_ssid, &found->ssid, IEEE80211_MAX_SSID_LEN); |
1561 | *out_ssid_len = found->ssid_len; | 1934 | *out_ssid_len = found->ssid_len; |
1562 | *out_mode = found->mode; | 1935 | *out_mode = found->mode; |
1563 | ret = 0; | 1936 | ret = 0; |
@@ -1609,14 +1982,14 @@ void lbs_association_worker(struct work_struct *work) | |||
1609 | assoc_req->secinfo.auth_mode); | 1982 | assoc_req->secinfo.auth_mode); |
1610 | 1983 | ||
1611 | /* If 'any' SSID was specified, find an SSID to associate with */ | 1984 | /* If 'any' SSID was specified, find an SSID to associate with */ |
1612 | if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) | 1985 | if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) && |
1613 | && !assoc_req->ssid_len) | 1986 | !assoc_req->ssid_len) |
1614 | find_any_ssid = 1; | 1987 | find_any_ssid = 1; |
1615 | 1988 | ||
1616 | /* But don't use 'any' SSID if there's a valid locked BSSID to use */ | 1989 | /* But don't use 'any' SSID if there's a valid locked BSSID to use */ |
1617 | if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { | 1990 | if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { |
1618 | if (compare_ether_addr(assoc_req->bssid, bssid_any) | 1991 | if (compare_ether_addr(assoc_req->bssid, bssid_any) && |
1619 | && compare_ether_addr(assoc_req->bssid, bssid_off)) | 1992 | compare_ether_addr(assoc_req->bssid, bssid_off)) |
1620 | find_any_ssid = 0; | 1993 | find_any_ssid = 0; |
1621 | } | 1994 | } |
1622 | 1995 | ||
@@ -1678,13 +2051,6 @@ void lbs_association_worker(struct work_struct *work) | |||
1678 | goto out; | 2051 | goto out; |
1679 | } | 2052 | } |
1680 | 2053 | ||
1681 | if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) | ||
1682 | || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { | ||
1683 | ret = assoc_helper_wep_keys(priv, assoc_req); | ||
1684 | if (ret) | ||
1685 | goto out; | ||
1686 | } | ||
1687 | |||
1688 | if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { | 2054 | if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { |
1689 | ret = assoc_helper_secinfo(priv, assoc_req); | 2055 | ret = assoc_helper_secinfo(priv, assoc_req); |
1690 | if (ret) | 2056 | if (ret) |
@@ -1697,18 +2063,31 @@ void lbs_association_worker(struct work_struct *work) | |||
1697 | goto out; | 2063 | goto out; |
1698 | } | 2064 | } |
1699 | 2065 | ||
1700 | if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) | 2066 | /* |
1701 | || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { | 2067 | * v10 FW wants WPA keys to be set/cleared before WEP key operations, |
2068 | * otherwise it will fail to correctly associate to WEP networks. | ||
2069 | * Other firmware versions don't appear to care. | ||
2070 | */ | ||
2071 | if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) || | ||
2072 | test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { | ||
1702 | ret = assoc_helper_wpa_keys(priv, assoc_req); | 2073 | ret = assoc_helper_wpa_keys(priv, assoc_req); |
1703 | if (ret) | 2074 | if (ret) |
1704 | goto out; | 2075 | goto out; |
1705 | } | 2076 | } |
1706 | 2077 | ||
2078 | if (test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) || | ||
2079 | test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { | ||
2080 | ret = assoc_helper_wep_keys(priv, assoc_req); | ||
2081 | if (ret) | ||
2082 | goto out; | ||
2083 | } | ||
2084 | |||
2085 | |||
1707 | /* SSID/BSSID should be the _last_ config option set, because they | 2086 | /* SSID/BSSID should be the _last_ config option set, because they |
1708 | * trigger the association attempt. | 2087 | * trigger the association attempt. |
1709 | */ | 2088 | */ |
1710 | if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) | 2089 | if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) || |
1711 | || test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { | 2090 | test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { |
1712 | int success = 1; | 2091 | int success = 1; |
1713 | 2092 | ||
1714 | ret = assoc_helper_associate(priv, assoc_req); | 2093 | ret = assoc_helper_associate(priv, assoc_req); |
@@ -1775,12 +2154,12 @@ struct assoc_request *lbs_get_association_request(struct lbs_private *priv) | |||
1775 | assoc_req = priv->pending_assoc_req; | 2154 | assoc_req = priv->pending_assoc_req; |
1776 | if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { | 2155 | if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { |
1777 | memcpy(&assoc_req->ssid, &priv->curbssparams.ssid, | 2156 | memcpy(&assoc_req->ssid, &priv->curbssparams.ssid, |
1778 | IW_ESSID_MAX_SIZE); | 2157 | IEEE80211_MAX_SSID_LEN); |
1779 | assoc_req->ssid_len = priv->curbssparams.ssid_len; | 2158 | assoc_req->ssid_len = priv->curbssparams.ssid_len; |
1780 | } | 2159 | } |
1781 | 2160 | ||
1782 | if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) | 2161 | if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) |
1783 | assoc_req->channel = priv->curbssparams.channel; | 2162 | assoc_req->channel = priv->channel; |
1784 | 2163 | ||
1785 | if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags)) | 2164 | if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags)) |
1786 | assoc_req->band = priv->curbssparams.band; | 2165 | assoc_req->band = priv->curbssparams.band; |