diff options
author | Samuel Ortiz <samuel.ortiz@intel.com> | 2009-06-15 15:59:52 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-10 14:57:51 -0400 |
commit | 13e0fe70960e95cdea89b71aa3d046ec71efac8c (patch) | |
tree | 3cb98cc48285bac0b368f5ff2f3a97bad15cefc4 /drivers/net/wireless/iwmc3200wifi/commands.c | |
parent | a70742f167424bab794ca74b9e99b598b358bb7d (diff) |
iwmc3200wifi: cfg80211 key hooks implemetation
This patch implements the new cfg80211 privacy related hooks: add/get/set_key
and the set_default_key one.
With this implementation we can now call the wext-compat *encode* routines and
reduce our own wext code.
Signed-off-by: Samuel Ortiz <samuel.ortiz@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwmc3200wifi/commands.c')
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/commands.c | 72 |
1 files changed, 25 insertions, 47 deletions
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c index 337a884f52df..145f6f5ae747 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.c +++ b/drivers/net/wireless/iwmc3200wifi/commands.c | |||
@@ -524,9 +524,6 @@ int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx) | |||
524 | { | 524 | { |
525 | struct iwm_umac_tx_key_id tx_key_id; | 525 | struct iwm_umac_tx_key_id tx_key_id; |
526 | 526 | ||
527 | if (!iwm->default_key || !iwm->default_key->in_use) | ||
528 | return -EINVAL; | ||
529 | |||
530 | tx_key_id.hdr.oid = UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID; | 527 | tx_key_id.hdr.oid = UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID; |
531 | tx_key_id.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_tx_key_id) - | 528 | tx_key_id.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_tx_key_id) - |
532 | sizeof(struct iwm_umac_wifi_if)); | 529 | sizeof(struct iwm_umac_wifi_if)); |
@@ -569,10 +566,9 @@ static int iwm_check_profile(struct iwm_priv *iwm) | |||
569 | return 0; | 566 | return 0; |
570 | } | 567 | } |
571 | 568 | ||
572 | int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | 569 | int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key) |
573 | struct iwm_key *key) | ||
574 | { | 570 | { |
575 | int ret; | 571 | int ret = 0; |
576 | u8 cmd[64], *sta_addr, *key_data, key_len; | 572 | u8 cmd[64], *sta_addr, *key_data, key_len; |
577 | s8 key_idx; | 573 | s8 key_idx; |
578 | u16 cmd_size = 0; | 574 | u16 cmd_size = 0; |
@@ -582,9 +578,6 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
582 | struct iwm_umac_key_tkip *tkip = (struct iwm_umac_key_tkip *)cmd; | 578 | struct iwm_umac_key_tkip *tkip = (struct iwm_umac_key_tkip *)cmd; |
583 | struct iwm_umac_key_ccmp *ccmp = (struct iwm_umac_key_ccmp *)cmd; | 579 | struct iwm_umac_key_ccmp *ccmp = (struct iwm_umac_key_ccmp *)cmd; |
584 | 580 | ||
585 | if (set_tx_key) | ||
586 | iwm->default_key = key; | ||
587 | |||
588 | /* | 581 | /* |
589 | * We check if our current profile is valid. | 582 | * We check if our current profile is valid. |
590 | * If not, we dont push the key, we just cache them, | 583 | * If not, we dont push the key, we just cache them, |
@@ -603,8 +596,7 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
603 | key_idx = key->hdr.key_idx; | 596 | key_idx = key->hdr.key_idx; |
604 | 597 | ||
605 | if (!remove) { | 598 | if (!remove) { |
606 | IWM_DBG_WEXT(iwm, DBG, "key_idx:%d set tx key:%d\n", | 599 | IWM_DBG_WEXT(iwm, DBG, "key_idx:%d\n", key_idx); |
607 | key_idx, set_tx_key); | ||
608 | IWM_DBG_WEXT(iwm, DBG, "key_len:%d\n", key_len); | 600 | IWM_DBG_WEXT(iwm, DBG, "key_len:%d\n", key_len); |
609 | IWM_DBG_WEXT(iwm, DBG, "MAC:%pM, idx:%d, multicast:%d\n", | 601 | IWM_DBG_WEXT(iwm, DBG, "MAC:%pM, idx:%d, multicast:%d\n", |
610 | key_hdr->mac, key_hdr->key_idx, key_hdr->multicast); | 602 | key_hdr->mac, key_hdr->key_idx, key_hdr->multicast); |
@@ -616,8 +608,8 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
616 | iwm->umac_profile->sec.auth_type, | 608 | iwm->umac_profile->sec.auth_type, |
617 | iwm->umac_profile->sec.flags); | 609 | iwm->umac_profile->sec.flags); |
618 | 610 | ||
619 | switch (key->alg) { | 611 | switch (key->cipher) { |
620 | case UMAC_CIPHER_TYPE_WEP_40: | 612 | case WLAN_CIPHER_SUITE_WEP40: |
621 | wep40->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP40_KEY; | 613 | wep40->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP40_KEY; |
622 | wep40->hdr.buf_size = | 614 | wep40->hdr.buf_size = |
623 | cpu_to_le16(sizeof(struct iwm_umac_key_wep40) - | 615 | cpu_to_le16(sizeof(struct iwm_umac_key_wep40) - |
@@ -631,7 +623,7 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
631 | cmd_size = sizeof(struct iwm_umac_key_wep40); | 623 | cmd_size = sizeof(struct iwm_umac_key_wep40); |
632 | break; | 624 | break; |
633 | 625 | ||
634 | case UMAC_CIPHER_TYPE_WEP_104: | 626 | case WLAN_CIPHER_SUITE_WEP104: |
635 | wep104->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP104_KEY; | 627 | wep104->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP104_KEY; |
636 | wep104->hdr.buf_size = | 628 | wep104->hdr.buf_size = |
637 | cpu_to_le16(sizeof(struct iwm_umac_key_wep104) - | 629 | cpu_to_le16(sizeof(struct iwm_umac_key_wep104) - |
@@ -645,7 +637,7 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
645 | cmd_size = sizeof(struct iwm_umac_key_wep104); | 637 | cmd_size = sizeof(struct iwm_umac_key_wep104); |
646 | break; | 638 | break; |
647 | 639 | ||
648 | case UMAC_CIPHER_TYPE_CCMP: | 640 | case WLAN_CIPHER_SUITE_CCMP: |
649 | key_hdr->key_idx++; | 641 | key_hdr->key_idx++; |
650 | ccmp->hdr.oid = UMAC_WIFI_IF_CMD_ADD_CCMP_KEY; | 642 | ccmp->hdr.oid = UMAC_WIFI_IF_CMD_ADD_CCMP_KEY; |
651 | ccmp->hdr.buf_size = | 643 | ccmp->hdr.buf_size = |
@@ -657,13 +649,13 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
657 | 649 | ||
658 | memcpy(ccmp->key, key_data, key_len); | 650 | memcpy(ccmp->key, key_data, key_len); |
659 | 651 | ||
660 | if (key->flags & IW_ENCODE_EXT_RX_SEQ_VALID) | 652 | if (key->seq_len) |
661 | memcpy(ccmp->iv_count, key->rx_seq, 6); | 653 | memcpy(ccmp->iv_count, key->seq, key->seq_len); |
662 | 654 | ||
663 | cmd_size = sizeof(struct iwm_umac_key_ccmp); | 655 | cmd_size = sizeof(struct iwm_umac_key_ccmp); |
664 | break; | 656 | break; |
665 | 657 | ||
666 | case UMAC_CIPHER_TYPE_TKIP: | 658 | case WLAN_CIPHER_SUITE_TKIP: |
667 | key_hdr->key_idx++; | 659 | key_hdr->key_idx++; |
668 | tkip->hdr.oid = UMAC_WIFI_IF_CMD_ADD_TKIP_KEY; | 660 | tkip->hdr.oid = UMAC_WIFI_IF_CMD_ADD_TKIP_KEY; |
669 | tkip->hdr.buf_size = | 661 | tkip->hdr.buf_size = |
@@ -680,8 +672,8 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
680 | key_data + IWM_TKIP_KEY_SIZE + IWM_TKIP_MIC_SIZE, | 672 | key_data + IWM_TKIP_KEY_SIZE + IWM_TKIP_MIC_SIZE, |
681 | IWM_TKIP_MIC_SIZE); | 673 | IWM_TKIP_MIC_SIZE); |
682 | 674 | ||
683 | if (key->flags & IW_ENCODE_EXT_RX_SEQ_VALID) | 675 | if (key->seq_len) |
684 | memcpy(ccmp->iv_count, key->rx_seq, 6); | 676 | memcpy(ccmp->iv_count, key->seq, key->seq_len); |
685 | 677 | ||
686 | cmd_size = sizeof(struct iwm_umac_key_tkip); | 678 | cmd_size = sizeof(struct iwm_umac_key_tkip); |
687 | break; | 679 | break; |
@@ -690,8 +682,8 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
690 | return -ENOTSUPP; | 682 | return -ENOTSUPP; |
691 | } | 683 | } |
692 | 684 | ||
693 | if ((key->alg == UMAC_CIPHER_TYPE_CCMP) || | 685 | if ((key->cipher == WLAN_CIPHER_SUITE_TKIP) || |
694 | (key->alg == UMAC_CIPHER_TYPE_TKIP)) | 686 | (key->cipher == WLAN_CIPHER_SUITE_CCMP)) |
695 | /* | 687 | /* |
696 | * UGLY_UGLY_UGLY | 688 | * UGLY_UGLY_UGLY |
697 | * Copied HACK from the MWG driver. | 689 | * Copied HACK from the MWG driver. |
@@ -702,23 +694,11 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
702 | schedule_timeout_interruptible(usecs_to_jiffies(300)); | 694 | schedule_timeout_interruptible(usecs_to_jiffies(300)); |
703 | 695 | ||
704 | ret = iwm_send_wifi_if_cmd(iwm, cmd, cmd_size, 1); | 696 | ret = iwm_send_wifi_if_cmd(iwm, cmd, cmd_size, 1); |
705 | if (ret < 0) | ||
706 | goto err; | ||
707 | |||
708 | /* | ||
709 | * We need a default key only if it is set and | ||
710 | * if we're doing WEP. | ||
711 | */ | ||
712 | if (iwm->default_key == key && | ||
713 | ((key->alg == UMAC_CIPHER_TYPE_WEP_40) || | ||
714 | (key->alg == UMAC_CIPHER_TYPE_WEP_104))) { | ||
715 | ret = iwm_set_tx_key(iwm, key_idx); | ||
716 | if (ret < 0) | ||
717 | goto err; | ||
718 | } | ||
719 | } else { | 697 | } else { |
720 | struct iwm_umac_key_remove key_remove; | 698 | struct iwm_umac_key_remove key_remove; |
721 | 699 | ||
700 | IWM_DBG_WEXT(iwm, ERR, "Removing key_idx:%d\n", key_idx); | ||
701 | |||
722 | key_remove.hdr.oid = UMAC_WIFI_IF_CMD_REMOVE_KEY; | 702 | key_remove.hdr.oid = UMAC_WIFI_IF_CMD_REMOVE_KEY; |
723 | key_remove.hdr.buf_size = | 703 | key_remove.hdr.buf_size = |
724 | cpu_to_le16(sizeof(struct iwm_umac_key_remove) - | 704 | cpu_to_le16(sizeof(struct iwm_umac_key_remove) - |
@@ -732,13 +712,9 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, | |||
732 | if (ret < 0) | 712 | if (ret < 0) |
733 | return ret; | 713 | return ret; |
734 | 714 | ||
735 | iwm->keys[key_idx].in_use = 0; | 715 | iwm->keys[key_idx].key_len = 0; |
736 | } | 716 | } |
737 | 717 | ||
738 | return 0; | ||
739 | |||
740 | err: | ||
741 | kfree(key); | ||
742 | return ret; | 718 | return ret; |
743 | } | 719 | } |
744 | 720 | ||
@@ -761,22 +737,24 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm) | |||
761 | } | 737 | } |
762 | 738 | ||
763 | for (i = 0; i < IWM_NUM_KEYS; i++) | 739 | for (i = 0; i < IWM_NUM_KEYS; i++) |
764 | if (iwm->keys[i].in_use) { | 740 | if (iwm->keys[i].key_len) { |
765 | int default_key = 0; | ||
766 | struct iwm_key *key = &iwm->keys[i]; | 741 | struct iwm_key *key = &iwm->keys[i]; |
767 | 742 | ||
768 | if (key == iwm->default_key) | ||
769 | default_key = 1; | ||
770 | |||
771 | /* Wait for the profile before sending the keys */ | 743 | /* Wait for the profile before sending the keys */ |
772 | wait_event_interruptible_timeout(iwm->mlme_queue, | 744 | wait_event_interruptible_timeout(iwm->mlme_queue, |
773 | (test_bit(IWM_STATUS_ASSOCIATING, &iwm->status) || | 745 | (test_bit(IWM_STATUS_ASSOCIATING, &iwm->status) || |
774 | test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)), | 746 | test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)), |
775 | 3 * HZ); | 747 | 3 * HZ); |
776 | 748 | ||
777 | ret = iwm_set_key(iwm, 0, default_key, key); | 749 | ret = iwm_set_key(iwm, 0, key); |
778 | if (ret < 0) | 750 | if (ret < 0) |
779 | return ret; | 751 | return ret; |
752 | |||
753 | if (iwm->default_key == i) { | ||
754 | ret = iwm_set_tx_key(iwm, i); | ||
755 | if (ret < 0) | ||
756 | return ret; | ||
757 | } | ||
780 | } | 758 | } |
781 | 759 | ||
782 | return 0; | 760 | return 0; |