aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwmc3200wifi/commands.c
diff options
context:
space:
mode:
authorSamuel Ortiz <samuel.ortiz@intel.com>2009-06-15 15:59:52 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 14:57:51 -0400
commit13e0fe70960e95cdea89b71aa3d046ec71efac8c (patch)
tree3cb98cc48285bac0b368f5ff2f3a97bad15cefc4 /drivers/net/wireless/iwmc3200wifi/commands.c
parenta70742f167424bab794ca74b9e99b598b358bb7d (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.c72
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
572int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, 569int 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;