diff options
Diffstat (limited to 'drivers/net/wireless/iwmc3200wifi/commands.c')
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/commands.c | 195 |
1 files changed, 87 insertions, 108 deletions
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c index e2334d123599..a68a2aff3c1e 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.c +++ b/drivers/net/wireless/iwmc3200wifi/commands.c | |||
@@ -70,14 +70,27 @@ static int iwm_send_lmac_ptrough_cmd(struct iwm_priv *iwm, | |||
70 | int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size, | 70 | int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size, |
71 | bool resp) | 71 | bool resp) |
72 | { | 72 | { |
73 | struct iwm_umac_wifi_if *hdr = (struct iwm_umac_wifi_if *)payload; | ||
73 | struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT; | 74 | struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT; |
74 | struct iwm_umac_cmd umac_cmd; | 75 | struct iwm_umac_cmd umac_cmd; |
76 | int ret; | ||
77 | u8 oid = hdr->oid; | ||
75 | 78 | ||
76 | umac_cmd.id = UMAC_CMD_OPCODE_WIFI_IF_WRAPPER; | 79 | umac_cmd.id = UMAC_CMD_OPCODE_WIFI_IF_WRAPPER; |
77 | umac_cmd.resp = resp; | 80 | umac_cmd.resp = resp; |
78 | 81 | ||
79 | return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, | 82 | ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, |
80 | payload, payload_size); | 83 | payload, payload_size); |
84 | |||
85 | if (resp) { | ||
86 | ret = wait_event_interruptible_timeout(iwm->wifi_ntfy_queue, | ||
87 | test_and_clear_bit(oid, &iwm->wifi_ntfy[0]), | ||
88 | 3 * HZ); | ||
89 | |||
90 | return ret ? 0 : -EBUSY; | ||
91 | } | ||
92 | |||
93 | return ret; | ||
81 | } | 94 | } |
82 | 95 | ||
83 | static struct coex_event iwm_sta_xor_prio_tbl[COEX_EVENTS_NUM] = | 96 | static struct coex_event iwm_sta_xor_prio_tbl[COEX_EVENTS_NUM] = |
@@ -106,7 +119,7 @@ static struct coex_event iwm_sta_cm_prio_tbl[COEX_EVENTS_NUM] = | |||
106 | {4, 3, 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS}, | 119 | {4, 3, 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS}, |
107 | {3, 3, 0, COEX_UNASSOC_AUTO_SCAN_FLAGS}, | 120 | {3, 3, 0, COEX_UNASSOC_AUTO_SCAN_FLAGS}, |
108 | {5, 5, 0, COEX_CALIBRATION_FLAGS}, | 121 | {5, 5, 0, COEX_CALIBRATION_FLAGS}, |
109 | {4, 4, 0, COEX_PERIODIC_CALIBRATION_FLAGS}, | 122 | {3, 3, 0, COEX_PERIODIC_CALIBRATION_FLAGS}, |
110 | {5, 4, 0, COEX_CONNECTION_ESTAB_FLAGS}, | 123 | {5, 4, 0, COEX_CONNECTION_ESTAB_FLAGS}, |
111 | {4, 4, 0, COEX_ASSOCIATED_IDLE_FLAGS}, | 124 | {4, 4, 0, COEX_ASSOCIATED_IDLE_FLAGS}, |
112 | {4, 4, 0, COEX_ASSOC_MANUAL_SCAN_FLAGS}, | 125 | {4, 4, 0, COEX_ASSOC_MANUAL_SCAN_FLAGS}, |
@@ -332,8 +345,7 @@ int iwm_umac_set_config_var(struct iwm_priv *iwm, u16 key, | |||
332 | return ret; | 345 | return ret; |
333 | } | 346 | } |
334 | 347 | ||
335 | int iwm_send_umac_config(struct iwm_priv *iwm, | 348 | int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags) |
336 | __le32 reset_flags) | ||
337 | { | 349 | { |
338 | int ret; | 350 | int ret; |
339 | 351 | ||
@@ -361,6 +373,12 @@ int iwm_send_umac_config(struct iwm_priv *iwm, | |||
361 | return ret; | 373 | return ret; |
362 | 374 | ||
363 | ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, | 375 | ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, |
376 | CFG_WIRELESS_MODE, | ||
377 | iwm->conf.wireless_mode); | ||
378 | if (ret < 0) | ||
379 | return ret; | ||
380 | |||
381 | ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, | ||
364 | CFG_COEX_MODE, iwm->conf.coexist_mode); | 382 | CFG_COEX_MODE, iwm->conf.coexist_mode); |
365 | if (ret < 0) | 383 | if (ret < 0) |
366 | return ret; | 384 | return ret; |
@@ -402,7 +420,7 @@ int iwm_send_umac_config(struct iwm_priv *iwm, | |||
402 | return ret; | 420 | return ret; |
403 | 421 | ||
404 | ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, | 422 | ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, |
405 | CFG_PM_CTRL_FLAGS, 0x30001); | 423 | CFG_PM_CTRL_FLAGS, 0x1); |
406 | if (ret < 0) | 424 | if (ret < 0) |
407 | return ret; | 425 | return ret; |
408 | 426 | ||
@@ -462,8 +480,10 @@ static int iwm_target_read(struct iwm_priv *iwm, __le32 address, | |||
462 | target_cmd.eop = 1; | 480 | target_cmd.eop = 1; |
463 | 481 | ||
464 | ret = iwm_hal_send_target_cmd(iwm, &target_cmd, NULL); | 482 | ret = iwm_hal_send_target_cmd(iwm, &target_cmd, NULL); |
465 | if (ret < 0) | 483 | if (ret < 0) { |
466 | IWM_ERR(iwm, "Couldn't send READ command\n"); | 484 | IWM_ERR(iwm, "Couldn't send READ command\n"); |
485 | return ret; | ||
486 | } | ||
467 | 487 | ||
468 | /* When succeding, the send_target routine returns the seq number */ | 488 | /* When succeding, the send_target routine returns the seq number */ |
469 | seq_num = ret; | 489 | seq_num = ret; |
@@ -483,7 +503,7 @@ static int iwm_target_read(struct iwm_priv *iwm, __le32 address, | |||
483 | 503 | ||
484 | kfree(cmd); | 504 | kfree(cmd); |
485 | 505 | ||
486 | return ret; | 506 | return 0; |
487 | } | 507 | } |
488 | 508 | ||
489 | int iwm_read_mac(struct iwm_priv *iwm, u8 *mac) | 509 | int iwm_read_mac(struct iwm_priv *iwm, u8 *mac) |
@@ -493,7 +513,7 @@ int iwm_read_mac(struct iwm_priv *iwm, u8 *mac) | |||
493 | 513 | ||
494 | ret = iwm_target_read(iwm, cpu_to_le32(WICO_MAC_ADDRESS_ADDR), | 514 | ret = iwm_target_read(iwm, cpu_to_le32(WICO_MAC_ADDRESS_ADDR), |
495 | mac_align, sizeof(mac_align)); | 515 | mac_align, sizeof(mac_align)); |
496 | if (ret < 0) | 516 | if (ret) |
497 | return ret; | 517 | return ret; |
498 | 518 | ||
499 | if (is_valid_ether_addr(mac_align)) | 519 | if (is_valid_ether_addr(mac_align)) |
@@ -507,22 +527,6 @@ int iwm_read_mac(struct iwm_priv *iwm, u8 *mac) | |||
507 | return 0; | 527 | return 0; |
508 | } | 528 | } |
509 | 529 | ||
510 | int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx) | ||
511 | { | ||
512 | struct iwm_umac_tx_key_id tx_key_id; | ||
513 | |||
514 | if (!iwm->default_key || !iwm->default_key->in_use) | ||
515 | return -EINVAL; | ||
516 | |||
517 | tx_key_id.hdr.oid = UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID; | ||
518 | tx_key_id.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_tx_key_id) - | ||
519 | sizeof(struct iwm_umac_wifi_if)); | ||
520 | |||
521 | tx_key_id.key_idx = key_idx; | ||
522 | |||
523 | return iwm_send_wifi_if_cmd(iwm, &tx_key_id, sizeof(tx_key_id), 1); | ||
524 | } | ||
525 | |||
526 | static int iwm_check_profile(struct iwm_priv *iwm) | 530 | static int iwm_check_profile(struct iwm_priv *iwm) |
527 | { | 531 | { |
528 | if (!iwm->umac_profile_active) | 532 | if (!iwm->umac_profile_active) |
@@ -556,10 +560,35 @@ static int iwm_check_profile(struct iwm_priv *iwm) | |||
556 | return 0; | 560 | return 0; |
557 | } | 561 | } |
558 | 562 | ||
559 | int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | 563 | int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx) |
560 | struct iwm_key *key) | ||
561 | { | 564 | { |
565 | struct iwm_umac_tx_key_id tx_key_id; | ||
562 | int ret; | 566 | int ret; |
567 | |||
568 | ret = iwm_check_profile(iwm); | ||
569 | if (ret < 0) | ||
570 | return ret; | ||
571 | |||
572 | /* UMAC only allows to set default key for WEP and auth type is | ||
573 | * NOT 802.1X or RSNA. */ | ||
574 | if ((iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_40 && | ||
575 | iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_104) || | ||
576 | iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_8021X || | ||
577 | iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_RSNA_PSK) | ||
578 | return 0; | ||
579 | |||
580 | tx_key_id.hdr.oid = UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID; | ||
581 | tx_key_id.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_tx_key_id) - | ||
582 | sizeof(struct iwm_umac_wifi_if)); | ||
583 | |||
584 | tx_key_id.key_idx = key_idx; | ||
585 | |||
586 | return iwm_send_wifi_if_cmd(iwm, &tx_key_id, sizeof(tx_key_id), 1); | ||
587 | } | ||
588 | |||
589 | int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key) | ||
590 | { | ||
591 | int ret = 0; | ||
563 | u8 cmd[64], *sta_addr, *key_data, key_len; | 592 | u8 cmd[64], *sta_addr, *key_data, key_len; |
564 | s8 key_idx; | 593 | s8 key_idx; |
565 | u16 cmd_size = 0; | 594 | u16 cmd_size = 0; |
@@ -569,15 +598,6 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
569 | struct iwm_umac_key_tkip *tkip = (struct iwm_umac_key_tkip *)cmd; | 598 | struct iwm_umac_key_tkip *tkip = (struct iwm_umac_key_tkip *)cmd; |
570 | struct iwm_umac_key_ccmp *ccmp = (struct iwm_umac_key_ccmp *)cmd; | 599 | struct iwm_umac_key_ccmp *ccmp = (struct iwm_umac_key_ccmp *)cmd; |
571 | 600 | ||
572 | if (set_tx_key) | ||
573 | iwm->default_key = key; | ||
574 | |||
575 | /* | ||
576 | * We check if our current profile is valid. | ||
577 | * If not, we dont push the key, we just cache them, | ||
578 | * so that with the next siwsessid call, the keys | ||
579 | * will be actually pushed. | ||
580 | */ | ||
581 | if (!remove) { | 601 | if (!remove) { |
582 | ret = iwm_check_profile(iwm); | 602 | ret = iwm_check_profile(iwm); |
583 | if (ret < 0) | 603 | if (ret < 0) |
@@ -590,8 +610,9 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
590 | key_idx = key->hdr.key_idx; | 610 | key_idx = key->hdr.key_idx; |
591 | 611 | ||
592 | if (!remove) { | 612 | if (!remove) { |
593 | IWM_DBG_WEXT(iwm, DBG, "key_idx:%d set tx key:%d\n", | 613 | u8 auth_type = iwm->umac_profile->sec.auth_type; |
594 | key_idx, set_tx_key); | 614 | |
615 | IWM_DBG_WEXT(iwm, DBG, "key_idx:%d\n", key_idx); | ||
595 | IWM_DBG_WEXT(iwm, DBG, "key_len:%d\n", key_len); | 616 | IWM_DBG_WEXT(iwm, DBG, "key_len:%d\n", key_len); |
596 | IWM_DBG_WEXT(iwm, DBG, "MAC:%pM, idx:%d, multicast:%d\n", | 617 | IWM_DBG_WEXT(iwm, DBG, "MAC:%pM, idx:%d, multicast:%d\n", |
597 | key_hdr->mac, key_hdr->key_idx, key_hdr->multicast); | 618 | key_hdr->mac, key_hdr->key_idx, key_hdr->multicast); |
@@ -603,8 +624,8 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
603 | iwm->umac_profile->sec.auth_type, | 624 | iwm->umac_profile->sec.auth_type, |
604 | iwm->umac_profile->sec.flags); | 625 | iwm->umac_profile->sec.flags); |
605 | 626 | ||
606 | switch (key->alg) { | 627 | switch (key->cipher) { |
607 | case UMAC_CIPHER_TYPE_WEP_40: | 628 | case WLAN_CIPHER_SUITE_WEP40: |
608 | wep40->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP40_KEY; | 629 | wep40->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP40_KEY; |
609 | wep40->hdr.buf_size = | 630 | wep40->hdr.buf_size = |
610 | cpu_to_le16(sizeof(struct iwm_umac_key_wep40) - | 631 | cpu_to_le16(sizeof(struct iwm_umac_key_wep40) - |
@@ -613,12 +634,14 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
613 | memcpy(&wep40->key_hdr, key_hdr, | 634 | memcpy(&wep40->key_hdr, key_hdr, |
614 | sizeof(struct iwm_umac_key_hdr)); | 635 | sizeof(struct iwm_umac_key_hdr)); |
615 | memcpy(wep40->key, key_data, key_len); | 636 | memcpy(wep40->key, key_data, key_len); |
616 | wep40->static_key = 1; | 637 | wep40->static_key = |
638 | !!((auth_type != UMAC_AUTH_TYPE_8021X) && | ||
639 | (auth_type != UMAC_AUTH_TYPE_RSNA_PSK)); | ||
617 | 640 | ||
618 | cmd_size = sizeof(struct iwm_umac_key_wep40); | 641 | cmd_size = sizeof(struct iwm_umac_key_wep40); |
619 | break; | 642 | break; |
620 | 643 | ||
621 | case UMAC_CIPHER_TYPE_WEP_104: | 644 | case WLAN_CIPHER_SUITE_WEP104: |
622 | wep104->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP104_KEY; | 645 | wep104->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP104_KEY; |
623 | wep104->hdr.buf_size = | 646 | wep104->hdr.buf_size = |
624 | cpu_to_le16(sizeof(struct iwm_umac_key_wep104) - | 647 | cpu_to_le16(sizeof(struct iwm_umac_key_wep104) - |
@@ -627,12 +650,14 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
627 | memcpy(&wep104->key_hdr, key_hdr, | 650 | memcpy(&wep104->key_hdr, key_hdr, |
628 | sizeof(struct iwm_umac_key_hdr)); | 651 | sizeof(struct iwm_umac_key_hdr)); |
629 | memcpy(wep104->key, key_data, key_len); | 652 | memcpy(wep104->key, key_data, key_len); |
630 | wep104->static_key = 1; | 653 | wep104->static_key = |
654 | !!((auth_type != UMAC_AUTH_TYPE_8021X) && | ||
655 | (auth_type != UMAC_AUTH_TYPE_RSNA_PSK)); | ||
631 | 656 | ||
632 | cmd_size = sizeof(struct iwm_umac_key_wep104); | 657 | cmd_size = sizeof(struct iwm_umac_key_wep104); |
633 | break; | 658 | break; |
634 | 659 | ||
635 | case UMAC_CIPHER_TYPE_CCMP: | 660 | case WLAN_CIPHER_SUITE_CCMP: |
636 | key_hdr->key_idx++; | 661 | key_hdr->key_idx++; |
637 | ccmp->hdr.oid = UMAC_WIFI_IF_CMD_ADD_CCMP_KEY; | 662 | ccmp->hdr.oid = UMAC_WIFI_IF_CMD_ADD_CCMP_KEY; |
638 | ccmp->hdr.buf_size = | 663 | ccmp->hdr.buf_size = |
@@ -644,13 +669,13 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
644 | 669 | ||
645 | memcpy(ccmp->key, key_data, key_len); | 670 | memcpy(ccmp->key, key_data, key_len); |
646 | 671 | ||
647 | if (key->flags & IW_ENCODE_EXT_RX_SEQ_VALID) | 672 | if (key->seq_len) |
648 | memcpy(ccmp->iv_count, key->rx_seq, 6); | 673 | memcpy(ccmp->iv_count, key->seq, key->seq_len); |
649 | 674 | ||
650 | cmd_size = sizeof(struct iwm_umac_key_ccmp); | 675 | cmd_size = sizeof(struct iwm_umac_key_ccmp); |
651 | break; | 676 | break; |
652 | 677 | ||
653 | case UMAC_CIPHER_TYPE_TKIP: | 678 | case WLAN_CIPHER_SUITE_TKIP: |
654 | key_hdr->key_idx++; | 679 | key_hdr->key_idx++; |
655 | tkip->hdr.oid = UMAC_WIFI_IF_CMD_ADD_TKIP_KEY; | 680 | tkip->hdr.oid = UMAC_WIFI_IF_CMD_ADD_TKIP_KEY; |
656 | tkip->hdr.buf_size = | 681 | tkip->hdr.buf_size = |
@@ -667,8 +692,8 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
667 | key_data + IWM_TKIP_KEY_SIZE + IWM_TKIP_MIC_SIZE, | 692 | key_data + IWM_TKIP_KEY_SIZE + IWM_TKIP_MIC_SIZE, |
668 | IWM_TKIP_MIC_SIZE); | 693 | IWM_TKIP_MIC_SIZE); |
669 | 694 | ||
670 | if (key->flags & IW_ENCODE_EXT_RX_SEQ_VALID) | 695 | if (key->seq_len) |
671 | memcpy(ccmp->iv_count, key->rx_seq, 6); | 696 | memcpy(ccmp->iv_count, key->seq, key->seq_len); |
672 | 697 | ||
673 | cmd_size = sizeof(struct iwm_umac_key_tkip); | 698 | cmd_size = sizeof(struct iwm_umac_key_tkip); |
674 | break; | 699 | break; |
@@ -677,8 +702,8 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
677 | return -ENOTSUPP; | 702 | return -ENOTSUPP; |
678 | } | 703 | } |
679 | 704 | ||
680 | if ((key->alg == UMAC_CIPHER_TYPE_CCMP) || | 705 | if ((key->cipher == WLAN_CIPHER_SUITE_TKIP) || |
681 | (key->alg == UMAC_CIPHER_TYPE_TKIP)) | 706 | (key->cipher == WLAN_CIPHER_SUITE_CCMP)) |
682 | /* | 707 | /* |
683 | * UGLY_UGLY_UGLY | 708 | * UGLY_UGLY_UGLY |
684 | * Copied HACK from the MWG driver. | 709 | * Copied HACK from the MWG driver. |
@@ -689,23 +714,11 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
689 | schedule_timeout_interruptible(usecs_to_jiffies(300)); | 714 | schedule_timeout_interruptible(usecs_to_jiffies(300)); |
690 | 715 | ||
691 | ret = iwm_send_wifi_if_cmd(iwm, cmd, cmd_size, 1); | 716 | ret = iwm_send_wifi_if_cmd(iwm, cmd, cmd_size, 1); |
692 | if (ret < 0) | ||
693 | goto err; | ||
694 | |||
695 | /* | ||
696 | * We need a default key only if it is set and | ||
697 | * if we're doing WEP. | ||
698 | */ | ||
699 | if (iwm->default_key == key && | ||
700 | ((key->alg == UMAC_CIPHER_TYPE_WEP_40) || | ||
701 | (key->alg == UMAC_CIPHER_TYPE_WEP_104))) { | ||
702 | ret = iwm_set_tx_key(iwm, key_idx); | ||
703 | if (ret < 0) | ||
704 | goto err; | ||
705 | } | ||
706 | } else { | 717 | } else { |
707 | struct iwm_umac_key_remove key_remove; | 718 | struct iwm_umac_key_remove key_remove; |
708 | 719 | ||
720 | IWM_DBG_WEXT(iwm, ERR, "Removing key_idx:%d\n", key_idx); | ||
721 | |||
709 | key_remove.hdr.oid = UMAC_WIFI_IF_CMD_REMOVE_KEY; | 722 | key_remove.hdr.oid = UMAC_WIFI_IF_CMD_REMOVE_KEY; |
710 | key_remove.hdr.buf_size = | 723 | key_remove.hdr.buf_size = |
711 | cpu_to_le16(sizeof(struct iwm_umac_key_remove) - | 724 | cpu_to_le16(sizeof(struct iwm_umac_key_remove) - |
@@ -716,23 +729,19 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
716 | ret = iwm_send_wifi_if_cmd(iwm, &key_remove, | 729 | ret = iwm_send_wifi_if_cmd(iwm, &key_remove, |
717 | sizeof(struct iwm_umac_key_remove), | 730 | sizeof(struct iwm_umac_key_remove), |
718 | 1); | 731 | 1); |
719 | if (ret < 0) | 732 | if (ret) |
720 | return ret; | 733 | return ret; |
721 | 734 | ||
722 | iwm->keys[key_idx].in_use = 0; | 735 | iwm->keys[key_idx].key_len = 0; |
723 | } | 736 | } |
724 | 737 | ||
725 | return 0; | ||
726 | |||
727 | err: | ||
728 | kfree(key); | ||
729 | return ret; | 738 | return ret; |
730 | } | 739 | } |
731 | 740 | ||
732 | 741 | ||
733 | int iwm_send_mlme_profile(struct iwm_priv *iwm) | 742 | int iwm_send_mlme_profile(struct iwm_priv *iwm) |
734 | { | 743 | { |
735 | int ret, i; | 744 | int ret; |
736 | struct iwm_umac_profile profile; | 745 | struct iwm_umac_profile profile; |
737 | 746 | ||
738 | memcpy(&profile, iwm->umac_profile, sizeof(profile)); | 747 | memcpy(&profile, iwm->umac_profile, sizeof(profile)); |
@@ -742,45 +751,18 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm) | |||
742 | sizeof(struct iwm_umac_wifi_if)); | 751 | sizeof(struct iwm_umac_wifi_if)); |
743 | 752 | ||
744 | ret = iwm_send_wifi_if_cmd(iwm, &profile, sizeof(profile), 1); | 753 | ret = iwm_send_wifi_if_cmd(iwm, &profile, sizeof(profile), 1); |
745 | if (ret < 0) { | 754 | if (ret) { |
746 | IWM_ERR(iwm, "Send profile command failed\n"); | 755 | IWM_ERR(iwm, "Send profile command failed\n"); |
747 | return ret; | 756 | return ret; |
748 | } | 757 | } |
749 | 758 | ||
750 | /* Wait for the profile to be active */ | ||
751 | ret = wait_event_interruptible_timeout(iwm->mlme_queue, | ||
752 | iwm->umac_profile_active == 1, | ||
753 | 3 * HZ); | ||
754 | if (!ret) | ||
755 | return -EBUSY; | ||
756 | |||
757 | |||
758 | for (i = 0; i < IWM_NUM_KEYS; i++) | ||
759 | if (iwm->keys[i].in_use) { | ||
760 | int default_key = 0; | ||
761 | struct iwm_key *key = &iwm->keys[i]; | ||
762 | |||
763 | if (key == iwm->default_key) | ||
764 | default_key = 1; | ||
765 | |||
766 | /* Wait for the profile before sending the keys */ | ||
767 | wait_event_interruptible_timeout(iwm->mlme_queue, | ||
768 | (test_bit(IWM_STATUS_ASSOCIATING, &iwm->status) || | ||
769 | test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)), | ||
770 | 3 * HZ); | ||
771 | |||
772 | ret = iwm_set_key(iwm, 0, default_key, key); | ||
773 | if (ret < 0) | ||
774 | return ret; | ||
775 | } | ||
776 | |||
777 | return 0; | 759 | return 0; |
778 | } | 760 | } |
779 | 761 | ||
780 | int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) | 762 | int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) |
781 | { | 763 | { |
782 | int ret; | ||
783 | struct iwm_umac_invalidate_profile invalid; | 764 | struct iwm_umac_invalidate_profile invalid; |
765 | int ret; | ||
784 | 766 | ||
785 | invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE; | 767 | invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE; |
786 | invalid.hdr.buf_size = | 768 | invalid.hdr.buf_size = |
@@ -790,16 +772,13 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) | |||
790 | invalid.reason = WLAN_REASON_UNSPECIFIED; | 772 | invalid.reason = WLAN_REASON_UNSPECIFIED; |
791 | 773 | ||
792 | ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1); | 774 | ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1); |
793 | if (ret < 0) | 775 | if (ret) |
794 | return ret; | 776 | return ret; |
795 | 777 | ||
796 | ret = wait_event_interruptible_timeout(iwm->mlme_queue, | 778 | ret = wait_event_interruptible_timeout(iwm->mlme_queue, |
797 | (iwm->umac_profile_active == 0), | 779 | (iwm->umac_profile_active == 0), 2 * HZ); |
798 | 2 * HZ); | ||
799 | if (!ret) | ||
800 | return -EBUSY; | ||
801 | 780 | ||
802 | return 0; | 781 | return ret ? 0 : -EBUSY; |
803 | } | 782 | } |
804 | 783 | ||
805 | int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags) | 784 | int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags) |
@@ -882,7 +861,7 @@ int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids, | |||
882 | } | 861 | } |
883 | 862 | ||
884 | ret = iwm_send_wifi_if_cmd(iwm, &req, sizeof(req), 0); | 863 | ret = iwm_send_wifi_if_cmd(iwm, &req, sizeof(req), 0); |
885 | if (ret < 0) { | 864 | if (ret) { |
886 | IWM_ERR(iwm, "Couldn't send scan request\n"); | 865 | IWM_ERR(iwm, "Couldn't send scan request\n"); |
887 | return ret; | 866 | return ret; |
888 | } | 867 | } |