diff options
Diffstat (limited to 'drivers/net/wireless/libertas/assoc.c')
-rw-r--r-- | drivers/net/wireless/libertas/assoc.c | 445 |
1 files changed, 414 insertions, 31 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index dd8732611ba9..751067369ba8 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c | |||
@@ -23,6 +23,13 @@ static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) = | |||
23 | */ | 23 | */ |
24 | #define CAPINFO_MASK (~(0xda00)) | 24 | #define CAPINFO_MASK (~(0xda00)) |
25 | 25 | ||
26 | /** | ||
27 | * 802.11b/g supported bitrates (in 500Kb/s units) | ||
28 | */ | ||
29 | u8 lbs_bg_rates[MAX_RATES] = | ||
30 | { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, | ||
31 | 0x00, 0x00 }; | ||
32 | |||
26 | 33 | ||
27 | /** | 34 | /** |
28 | * @brief This function finds common rates between rates and card rates. | 35 | * @brief This function finds common rates between rates and card rates. |
@@ -147,6 +154,397 @@ static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth | |||
147 | } | 154 | } |
148 | 155 | ||
149 | 156 | ||
157 | int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action, | ||
158 | struct assoc_request *assoc) | ||
159 | { | ||
160 | struct cmd_ds_802_11_set_wep cmd; | ||
161 | int ret = 0; | ||
162 | |||
163 | lbs_deb_enter(LBS_DEB_CMD); | ||
164 | |||
165 | memset(&cmd, 0, sizeof(cmd)); | ||
166 | cmd.hdr.command = cpu_to_le16(CMD_802_11_SET_WEP); | ||
167 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||
168 | |||
169 | cmd.action = cpu_to_le16(cmd_action); | ||
170 | |||
171 | if (cmd_action == CMD_ACT_ADD) { | ||
172 | int i; | ||
173 | |||
174 | /* default tx key index */ | ||
175 | cmd.keyindex = cpu_to_le16(assoc->wep_tx_keyidx & | ||
176 | CMD_WEP_KEY_INDEX_MASK); | ||
177 | |||
178 | /* Copy key types and material to host command structure */ | ||
179 | for (i = 0; i < 4; i++) { | ||
180 | struct enc_key *pkey = &assoc->wep_keys[i]; | ||
181 | |||
182 | switch (pkey->len) { | ||
183 | case KEY_LEN_WEP_40: | ||
184 | cmd.keytype[i] = CMD_TYPE_WEP_40_BIT; | ||
185 | memmove(cmd.keymaterial[i], pkey->key, pkey->len); | ||
186 | lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i); | ||
187 | break; | ||
188 | case KEY_LEN_WEP_104: | ||
189 | cmd.keytype[i] = CMD_TYPE_WEP_104_BIT; | ||
190 | memmove(cmd.keymaterial[i], pkey->key, pkey->len); | ||
191 | lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i); | ||
192 | break; | ||
193 | case 0: | ||
194 | break; | ||
195 | default: | ||
196 | lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n", | ||
197 | i, pkey->len); | ||
198 | ret = -1; | ||
199 | goto done; | ||
200 | break; | ||
201 | } | ||
202 | } | ||
203 | } else if (cmd_action == CMD_ACT_REMOVE) { | ||
204 | /* ACT_REMOVE clears _all_ WEP keys */ | ||
205 | |||
206 | /* default tx key index */ | ||
207 | cmd.keyindex = cpu_to_le16(priv->wep_tx_keyidx & | ||
208 | CMD_WEP_KEY_INDEX_MASK); | ||
209 | lbs_deb_cmd("SET_WEP: remove key %d\n", priv->wep_tx_keyidx); | ||
210 | } | ||
211 | |||
212 | ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd); | ||
213 | done: | ||
214 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
215 | return ret; | ||
216 | } | ||
217 | |||
218 | int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action, | ||
219 | uint16_t *enable) | ||
220 | { | ||
221 | struct cmd_ds_802_11_enable_rsn cmd; | ||
222 | int ret; | ||
223 | |||
224 | lbs_deb_enter(LBS_DEB_CMD); | ||
225 | |||
226 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||
227 | cmd.action = cpu_to_le16(cmd_action); | ||
228 | |||
229 | if (cmd_action == CMD_ACT_GET) | ||
230 | cmd.enable = 0; | ||
231 | else { | ||
232 | if (*enable) | ||
233 | cmd.enable = cpu_to_le16(CMD_ENABLE_RSN); | ||
234 | else | ||
235 | cmd.enable = cpu_to_le16(CMD_DISABLE_RSN); | ||
236 | lbs_deb_cmd("ENABLE_RSN: %d\n", *enable); | ||
237 | } | ||
238 | |||
239 | ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd); | ||
240 | if (!ret && cmd_action == CMD_ACT_GET) | ||
241 | *enable = le16_to_cpu(cmd.enable); | ||
242 | |||
243 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
244 | return ret; | ||
245 | } | ||
246 | |||
247 | static void set_one_wpa_key(struct MrvlIEtype_keyParamSet *keyparam, | ||
248 | struct enc_key *key) | ||
249 | { | ||
250 | lbs_deb_enter(LBS_DEB_CMD); | ||
251 | |||
252 | if (key->flags & KEY_INFO_WPA_ENABLED) | ||
253 | keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED); | ||
254 | if (key->flags & KEY_INFO_WPA_UNICAST) | ||
255 | keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST); | ||
256 | if (key->flags & KEY_INFO_WPA_MCAST) | ||
257 | keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST); | ||
258 | |||
259 | keyparam->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); | ||
260 | keyparam->keytypeid = cpu_to_le16(key->type); | ||
261 | keyparam->keylen = cpu_to_le16(key->len); | ||
262 | memcpy(keyparam->key, key->key, key->len); | ||
263 | |||
264 | /* Length field doesn't include the {type,length} header */ | ||
265 | keyparam->length = cpu_to_le16(sizeof(*keyparam) - 4); | ||
266 | lbs_deb_leave(LBS_DEB_CMD); | ||
267 | } | ||
268 | |||
269 | int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action, | ||
270 | struct assoc_request *assoc) | ||
271 | { | ||
272 | struct cmd_ds_802_11_key_material cmd; | ||
273 | int ret = 0; | ||
274 | int index = 0; | ||
275 | |||
276 | lbs_deb_enter(LBS_DEB_CMD); | ||
277 | |||
278 | cmd.action = cpu_to_le16(cmd_action); | ||
279 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||
280 | |||
281 | if (cmd_action == CMD_ACT_GET) { | ||
282 | cmd.hdr.size = cpu_to_le16(sizeof(struct cmd_header) + 2); | ||
283 | } else { | ||
284 | memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet)); | ||
285 | |||
286 | if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc->flags)) { | ||
287 | set_one_wpa_key(&cmd.keyParamSet[index], | ||
288 | &assoc->wpa_unicast_key); | ||
289 | index++; | ||
290 | } | ||
291 | |||
292 | if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc->flags)) { | ||
293 | set_one_wpa_key(&cmd.keyParamSet[index], | ||
294 | &assoc->wpa_mcast_key); | ||
295 | index++; | ||
296 | } | ||
297 | |||
298 | /* The common header and as many keys as we included */ | ||
299 | cmd.hdr.size = cpu_to_le16(offsetof(typeof(cmd), | ||
300 | keyParamSet[index])); | ||
301 | } | ||
302 | ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd); | ||
303 | /* Copy the returned key to driver private data */ | ||
304 | if (!ret && cmd_action == CMD_ACT_GET) { | ||
305 | void *buf_ptr = cmd.keyParamSet; | ||
306 | void *resp_end = &(&cmd)[1]; | ||
307 | |||
308 | while (buf_ptr < resp_end) { | ||
309 | struct MrvlIEtype_keyParamSet *keyparam = buf_ptr; | ||
310 | struct enc_key *key; | ||
311 | uint16_t param_set_len = le16_to_cpu(keyparam->length); | ||
312 | uint16_t key_len = le16_to_cpu(keyparam->keylen); | ||
313 | uint16_t key_flags = le16_to_cpu(keyparam->keyinfo); | ||
314 | uint16_t key_type = le16_to_cpu(keyparam->keytypeid); | ||
315 | void *end; | ||
316 | |||
317 | end = (void *)keyparam + sizeof(keyparam->type) | ||
318 | + sizeof(keyparam->length) + param_set_len; | ||
319 | |||
320 | /* Make sure we don't access past the end of the IEs */ | ||
321 | if (end > resp_end) | ||
322 | break; | ||
323 | |||
324 | if (key_flags & KEY_INFO_WPA_UNICAST) | ||
325 | key = &priv->wpa_unicast_key; | ||
326 | else if (key_flags & KEY_INFO_WPA_MCAST) | ||
327 | key = &priv->wpa_mcast_key; | ||
328 | else | ||
329 | break; | ||
330 | |||
331 | /* Copy returned key into driver */ | ||
332 | memset(key, 0, sizeof(struct enc_key)); | ||
333 | if (key_len > sizeof(key->key)) | ||
334 | break; | ||
335 | key->type = key_type; | ||
336 | key->flags = key_flags; | ||
337 | key->len = key_len; | ||
338 | memcpy(key->key, keyparam->key, key->len); | ||
339 | |||
340 | buf_ptr = end + 1; | ||
341 | } | ||
342 | } | ||
343 | |||
344 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
345 | return ret; | ||
346 | } | ||
347 | |||
348 | static __le16 lbs_rate_to_fw_bitmap(int rate, int lower_rates_ok) | ||
349 | { | ||
350 | /* Bit Rate | ||
351 | * 15:13 Reserved | ||
352 | * 12 54 Mbps | ||
353 | * 11 48 Mbps | ||
354 | * 10 36 Mbps | ||
355 | * 9 24 Mbps | ||
356 | * 8 18 Mbps | ||
357 | * 7 12 Mbps | ||
358 | * 6 9 Mbps | ||
359 | * 5 6 Mbps | ||
360 | * 4 Reserved | ||
361 | * 3 11 Mbps | ||
362 | * 2 5.5 Mbps | ||
363 | * 1 2 Mbps | ||
364 | * 0 1 Mbps | ||
365 | **/ | ||
366 | |||
367 | uint16_t ratemask; | ||
368 | int i = lbs_data_rate_to_fw_index(rate); | ||
369 | if (lower_rates_ok) | ||
370 | ratemask = (0x1fef >> (12 - i)); | ||
371 | else | ||
372 | ratemask = (1 << i); | ||
373 | return cpu_to_le16(ratemask); | ||
374 | } | ||
375 | |||
376 | int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv, | ||
377 | uint16_t cmd_action) | ||
378 | { | ||
379 | struct cmd_ds_802_11_rate_adapt_rateset cmd; | ||
380 | int ret; | ||
381 | |||
382 | lbs_deb_enter(LBS_DEB_CMD); | ||
383 | |||
384 | if (!priv->cur_rate && !priv->enablehwauto) | ||
385 | return -EINVAL; | ||
386 | |||
387 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||
388 | |||
389 | cmd.action = cpu_to_le16(cmd_action); | ||
390 | cmd.enablehwauto = cpu_to_le16(priv->enablehwauto); | ||
391 | cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto); | ||
392 | ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd); | ||
393 | if (!ret && cmd_action == CMD_ACT_GET) { | ||
394 | priv->ratebitmap = le16_to_cpu(cmd.bitmap); | ||
395 | priv->enablehwauto = le16_to_cpu(cmd.enablehwauto); | ||
396 | } | ||
397 | |||
398 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
399 | return ret; | ||
400 | } | ||
401 | |||
402 | /** | ||
403 | * @brief Set the data rate | ||
404 | * | ||
405 | * @param priv A pointer to struct lbs_private structure | ||
406 | * @param rate The desired data rate, or 0 to clear a locked rate | ||
407 | * | ||
408 | * @return 0 on success, error on failure | ||
409 | */ | ||
410 | int lbs_set_data_rate(struct lbs_private *priv, u8 rate) | ||
411 | { | ||
412 | struct cmd_ds_802_11_data_rate cmd; | ||
413 | int ret = 0; | ||
414 | |||
415 | lbs_deb_enter(LBS_DEB_CMD); | ||
416 | |||
417 | memset(&cmd, 0, sizeof(cmd)); | ||
418 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||
419 | |||
420 | if (rate > 0) { | ||
421 | cmd.action = cpu_to_le16(CMD_ACT_SET_TX_FIX_RATE); | ||
422 | cmd.rates[0] = lbs_data_rate_to_fw_index(rate); | ||
423 | if (cmd.rates[0] == 0) { | ||
424 | lbs_deb_cmd("DATA_RATE: invalid requested rate of" | ||
425 | " 0x%02X\n", rate); | ||
426 | ret = 0; | ||
427 | goto out; | ||
428 | } | ||
429 | lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", cmd.rates[0]); | ||
430 | } else { | ||
431 | cmd.action = cpu_to_le16(CMD_ACT_SET_TX_AUTO); | ||
432 | lbs_deb_cmd("DATA_RATE: setting auto\n"); | ||
433 | } | ||
434 | |||
435 | ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd); | ||
436 | if (ret) | ||
437 | goto out; | ||
438 | |||
439 | lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof(cmd)); | ||
440 | |||
441 | /* FIXME: get actual rates FW can do if this command actually returns | ||
442 | * all data rates supported. | ||
443 | */ | ||
444 | priv->cur_rate = lbs_fw_index_to_data_rate(cmd.rates[0]); | ||
445 | lbs_deb_cmd("DATA_RATE: current rate is 0x%02x\n", priv->cur_rate); | ||
446 | |||
447 | out: | ||
448 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
449 | return ret; | ||
450 | } | ||
451 | |||
452 | |||
453 | int lbs_cmd_802_11_rssi(struct lbs_private *priv, | ||
454 | struct cmd_ds_command *cmd) | ||
455 | { | ||
456 | |||
457 | lbs_deb_enter(LBS_DEB_CMD); | ||
458 | cmd->command = cpu_to_le16(CMD_802_11_RSSI); | ||
459 | cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + | ||
460 | sizeof(struct cmd_header)); | ||
461 | cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR); | ||
462 | |||
463 | /* reset Beacon SNR/NF/RSSI values */ | ||
464 | priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0; | ||
465 | priv->SNR[TYPE_BEACON][TYPE_AVG] = 0; | ||
466 | priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0; | ||
467 | priv->NF[TYPE_BEACON][TYPE_AVG] = 0; | ||
468 | priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0; | ||
469 | priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0; | ||
470 | |||
471 | lbs_deb_leave(LBS_DEB_CMD); | ||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | int lbs_ret_802_11_rssi(struct lbs_private *priv, | ||
476 | struct cmd_ds_command *resp) | ||
477 | { | ||
478 | struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp; | ||
479 | |||
480 | lbs_deb_enter(LBS_DEB_CMD); | ||
481 | |||
482 | /* store the non average value */ | ||
483 | priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR); | ||
484 | priv->NF[TYPE_BEACON][TYPE_NOAVG] = | ||
485 | get_unaligned_le16(&rssirsp->noisefloor); | ||
486 | |||
487 | priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR); | ||
488 | priv->NF[TYPE_BEACON][TYPE_AVG] = | ||
489 | get_unaligned_le16(&rssirsp->avgnoisefloor); | ||
490 | |||
491 | priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = | ||
492 | CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG], | ||
493 | priv->NF[TYPE_BEACON][TYPE_NOAVG]); | ||
494 | |||
495 | priv->RSSI[TYPE_BEACON][TYPE_AVG] = | ||
496 | CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE, | ||
497 | priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE); | ||
498 | |||
499 | lbs_deb_cmd("RSSI: beacon %d, avg %d\n", | ||
500 | priv->RSSI[TYPE_BEACON][TYPE_NOAVG], | ||
501 | priv->RSSI[TYPE_BEACON][TYPE_AVG]); | ||
502 | |||
503 | lbs_deb_leave(LBS_DEB_CMD); | ||
504 | return 0; | ||
505 | } | ||
506 | |||
507 | |||
508 | int lbs_cmd_bcn_ctrl(struct lbs_private *priv, | ||
509 | struct cmd_ds_command *cmd, | ||
510 | u16 cmd_action) | ||
511 | { | ||
512 | struct cmd_ds_802_11_beacon_control | ||
513 | *bcn_ctrl = &cmd->params.bcn_ctrl; | ||
514 | |||
515 | lbs_deb_enter(LBS_DEB_CMD); | ||
516 | cmd->size = | ||
517 | cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control) | ||
518 | + sizeof(struct cmd_header)); | ||
519 | cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL); | ||
520 | |||
521 | bcn_ctrl->action = cpu_to_le16(cmd_action); | ||
522 | bcn_ctrl->beacon_enable = cpu_to_le16(priv->beacon_enable); | ||
523 | bcn_ctrl->beacon_period = cpu_to_le16(priv->beacon_period); | ||
524 | |||
525 | lbs_deb_leave(LBS_DEB_CMD); | ||
526 | return 0; | ||
527 | } | ||
528 | |||
529 | int lbs_ret_802_11_bcn_ctrl(struct lbs_private *priv, | ||
530 | struct cmd_ds_command *resp) | ||
531 | { | ||
532 | struct cmd_ds_802_11_beacon_control *bcn_ctrl = | ||
533 | &resp->params.bcn_ctrl; | ||
534 | |||
535 | lbs_deb_enter(LBS_DEB_CMD); | ||
536 | |||
537 | if (bcn_ctrl->action == CMD_ACT_GET) { | ||
538 | priv->beacon_enable = (u8) le16_to_cpu(bcn_ctrl->beacon_enable); | ||
539 | priv->beacon_period = le16_to_cpu(bcn_ctrl->beacon_period); | ||
540 | } | ||
541 | |||
542 | lbs_deb_enter(LBS_DEB_CMD); | ||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | |||
547 | |||
150 | static int lbs_assoc_post(struct lbs_private *priv, | 548 | static int lbs_assoc_post(struct lbs_private *priv, |
151 | struct cmd_ds_802_11_associate_response *resp) | 549 | struct cmd_ds_802_11_associate_response *resp) |
152 | { | 550 | { |
@@ -226,7 +624,7 @@ static int lbs_assoc_post(struct lbs_private *priv, | |||
226 | priv->connect_status = LBS_CONNECTED; | 624 | priv->connect_status = LBS_CONNECTED; |
227 | 625 | ||
228 | /* Update current SSID and BSSID */ | 626 | /* Update current SSID and BSSID */ |
229 | memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE); | 627 | memcpy(&priv->curbssparams.ssid, &bss->ssid, IEEE80211_MAX_SSID_LEN); |
230 | priv->curbssparams.ssid_len = bss->ssid_len; | 628 | priv->curbssparams.ssid_len = bss->ssid_len; |
231 | memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN); | 629 | memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN); |
232 | 630 | ||
@@ -369,12 +767,7 @@ static int lbs_associate(struct lbs_private *priv, | |||
369 | (u16)(pos - (u8 *) &cmd.iebuf)); | 767 | (u16)(pos - (u8 *) &cmd.iebuf)); |
370 | 768 | ||
371 | /* update curbssparams */ | 769 | /* update curbssparams */ |
372 | priv->curbssparams.channel = bss->phy.ds.channel; | 770 | priv->channel = bss->phy.ds.channel; |
373 | |||
374 | if (lbs_parse_dnld_countryinfo_11d(priv, bss)) { | ||
375 | ret = -1; | ||
376 | goto done; | ||
377 | } | ||
378 | 771 | ||
379 | ret = lbs_cmd_with_response(priv, command, &cmd); | 772 | ret = lbs_cmd_with_response(priv, command, &cmd); |
380 | if (ret == 0) { | 773 | if (ret == 0) { |
@@ -472,7 +865,7 @@ static int lbs_adhoc_post(struct lbs_private *priv, | |||
472 | memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN); | 865 | memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN); |
473 | 866 | ||
474 | /* Set the new SSID to current SSID */ | 867 | /* Set the new SSID to current SSID */ |
475 | memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE); | 868 | memcpy(&priv->curbssparams.ssid, &bss->ssid, IEEE80211_MAX_SSID_LEN); |
476 | priv->curbssparams.ssid_len = bss->ssid_len; | 869 | priv->curbssparams.ssid_len = bss->ssid_len; |
477 | 870 | ||
478 | netif_carrier_on(priv->dev); | 871 | netif_carrier_on(priv->dev); |
@@ -487,7 +880,7 @@ static int lbs_adhoc_post(struct lbs_private *priv, | |||
487 | lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n", | 880 | lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n", |
488 | print_ssid(ssid, bss->ssid, bss->ssid_len), | 881 | print_ssid(ssid, bss->ssid, bss->ssid_len), |
489 | priv->curbssparams.bssid, | 882 | priv->curbssparams.bssid, |
490 | priv->curbssparams.channel); | 883 | priv->channel); |
491 | 884 | ||
492 | done: | 885 | done: |
493 | lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); | 886 | lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); |
@@ -560,7 +953,7 @@ static int lbs_adhoc_join(struct lbs_private *priv, | |||
560 | lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band); | 953 | lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band); |
561 | 954 | ||
562 | priv->adhoccreate = 0; | 955 | priv->adhoccreate = 0; |
563 | priv->curbssparams.channel = bss->channel; | 956 | priv->channel = bss->channel; |
564 | 957 | ||
565 | /* Build the join command */ | 958 | /* Build the join command */ |
566 | memset(&cmd, 0, sizeof(cmd)); | 959 | memset(&cmd, 0, sizeof(cmd)); |
@@ -633,11 +1026,6 @@ static int lbs_adhoc_join(struct lbs_private *priv, | |||
633 | } | 1026 | } |
634 | } | 1027 | } |
635 | 1028 | ||
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); | 1029 | ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd); |
642 | if (ret == 0) { | 1030 | if (ret == 0) { |
643 | ret = lbs_adhoc_post(priv, | 1031 | ret = lbs_adhoc_post(priv, |
@@ -737,12 +1125,6 @@ static int lbs_adhoc_start(struct lbs_private *priv, | |||
737 | lbs_deb_join("ADHOC_START: rates=%02x %02x %02x %02x\n", | 1125 | lbs_deb_join("ADHOC_START: rates=%02x %02x %02x %02x\n", |
738 | cmd.rates[0], cmd.rates[1], cmd.rates[2], cmd.rates[3]); | 1126 | cmd.rates[0], cmd.rates[1], cmd.rates[2], cmd.rates[3]); |
739 | 1127 | ||
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", | 1128 | lbs_deb_join("ADHOC_START: Starting Ad-Hoc BSS on channel %d, band %d\n", |
747 | assoc_req->channel, assoc_req->band); | 1129 | assoc_req->channel, assoc_req->band); |
748 | 1130 | ||
@@ -1099,7 +1481,7 @@ static int assoc_helper_essid(struct lbs_private *priv, | |||
1099 | /* else send START command */ | 1481 | /* else send START command */ |
1100 | lbs_deb_assoc("SSID not found, creating adhoc network\n"); | 1482 | lbs_deb_assoc("SSID not found, creating adhoc network\n"); |
1101 | memcpy(&assoc_req->bss.ssid, &assoc_req->ssid, | 1483 | memcpy(&assoc_req->bss.ssid, &assoc_req->ssid, |
1102 | IW_ESSID_MAX_SIZE); | 1484 | IEEE80211_MAX_SSID_LEN); |
1103 | assoc_req->bss.ssid_len = assoc_req->ssid_len; | 1485 | assoc_req->bss.ssid_len = assoc_req->ssid_len; |
1104 | lbs_adhoc_start(priv, assoc_req); | 1486 | lbs_adhoc_start(priv, assoc_req); |
1105 | } | 1487 | } |
@@ -1185,7 +1567,8 @@ static int assoc_helper_mode(struct lbs_private *priv, | |||
1185 | } | 1567 | } |
1186 | 1568 | ||
1187 | priv->mode = assoc_req->mode; | 1569 | priv->mode = assoc_req->mode; |
1188 | ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, assoc_req->mode); | 1570 | ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, |
1571 | assoc_req->mode == IW_MODE_ADHOC ? 2 : 1); | ||
1189 | 1572 | ||
1190 | done: | 1573 | done: |
1191 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | 1574 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
@@ -1205,7 +1588,7 @@ static int assoc_helper_channel(struct lbs_private *priv, | |||
1205 | goto done; | 1588 | goto done; |
1206 | } | 1589 | } |
1207 | 1590 | ||
1208 | if (assoc_req->channel == priv->curbssparams.channel) | 1591 | if (assoc_req->channel == priv->channel) |
1209 | goto done; | 1592 | goto done; |
1210 | 1593 | ||
1211 | if (priv->mesh_dev) { | 1594 | if (priv->mesh_dev) { |
@@ -1217,7 +1600,7 @@ static int assoc_helper_channel(struct lbs_private *priv, | |||
1217 | } | 1600 | } |
1218 | 1601 | ||
1219 | lbs_deb_assoc("ASSOC: channel: %d -> %d\n", | 1602 | lbs_deb_assoc("ASSOC: channel: %d -> %d\n", |
1220 | priv->curbssparams.channel, assoc_req->channel); | 1603 | priv->channel, assoc_req->channel); |
1221 | 1604 | ||
1222 | ret = lbs_set_channel(priv, assoc_req->channel); | 1605 | ret = lbs_set_channel(priv, assoc_req->channel); |
1223 | if (ret < 0) | 1606 | if (ret < 0) |
@@ -1232,7 +1615,7 @@ static int assoc_helper_channel(struct lbs_private *priv, | |||
1232 | goto done; | 1615 | goto done; |
1233 | } | 1616 | } |
1234 | 1617 | ||
1235 | if (assoc_req->channel != priv->curbssparams.channel) { | 1618 | if (assoc_req->channel != priv->channel) { |
1236 | lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n", | 1619 | lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n", |
1237 | assoc_req->channel); | 1620 | assoc_req->channel); |
1238 | goto restore_mesh; | 1621 | goto restore_mesh; |
@@ -1253,7 +1636,7 @@ static int assoc_helper_channel(struct lbs_private *priv, | |||
1253 | restore_mesh: | 1636 | restore_mesh: |
1254 | if (priv->mesh_dev) | 1637 | if (priv->mesh_dev) |
1255 | lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, | 1638 | lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, |
1256 | priv->curbssparams.channel); | 1639 | priv->channel); |
1257 | 1640 | ||
1258 | done: | 1641 | done: |
1259 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | 1642 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
@@ -1475,7 +1858,7 @@ static int should_stop_adhoc(struct lbs_private *priv, | |||
1475 | } | 1858 | } |
1476 | 1859 | ||
1477 | if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { | 1860 | if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { |
1478 | if (assoc_req->channel != priv->curbssparams.channel) | 1861 | if (assoc_req->channel != priv->channel) |
1479 | return 1; | 1862 | return 1; |
1480 | } | 1863 | } |
1481 | 1864 | ||
@@ -1557,7 +1940,7 @@ static int lbs_find_best_network_ssid(struct lbs_private *priv, | |||
1557 | 1940 | ||
1558 | found = lbs_find_best_ssid_in_list(priv, preferred_mode); | 1941 | found = lbs_find_best_ssid_in_list(priv, preferred_mode); |
1559 | if (found && (found->ssid_len > 0)) { | 1942 | if (found && (found->ssid_len > 0)) { |
1560 | memcpy(out_ssid, &found->ssid, IW_ESSID_MAX_SIZE); | 1943 | memcpy(out_ssid, &found->ssid, IEEE80211_MAX_SSID_LEN); |
1561 | *out_ssid_len = found->ssid_len; | 1944 | *out_ssid_len = found->ssid_len; |
1562 | *out_mode = found->mode; | 1945 | *out_mode = found->mode; |
1563 | ret = 0; | 1946 | ret = 0; |
@@ -1775,12 +2158,12 @@ struct assoc_request *lbs_get_association_request(struct lbs_private *priv) | |||
1775 | assoc_req = priv->pending_assoc_req; | 2158 | assoc_req = priv->pending_assoc_req; |
1776 | if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { | 2159 | if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { |
1777 | memcpy(&assoc_req->ssid, &priv->curbssparams.ssid, | 2160 | memcpy(&assoc_req->ssid, &priv->curbssparams.ssid, |
1778 | IW_ESSID_MAX_SIZE); | 2161 | IEEE80211_MAX_SSID_LEN); |
1779 | assoc_req->ssid_len = priv->curbssparams.ssid_len; | 2162 | assoc_req->ssid_len = priv->curbssparams.ssid_len; |
1780 | } | 2163 | } |
1781 | 2164 | ||
1782 | if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) | 2165 | if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) |
1783 | assoc_req->channel = priv->curbssparams.channel; | 2166 | assoc_req->channel = priv->channel; |
1784 | 2167 | ||
1785 | if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags)) | 2168 | if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags)) |
1786 | assoc_req->band = priv->curbssparams.band; | 2169 | assoc_req->band = priv->curbssparams.band; |