aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/main.c
diff options
context:
space:
mode:
authorKalle Valo <kalle.valo@nokia.com>2009-06-12 07:14:19 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 14:57:41 -0400
commitff25839bf0c99e828c26864a24417a36a6b6a31e (patch)
treee5891ed357f4285f788056e270df7664b4d5aa13 /drivers/net/wireless/wl12xx/main.c
parentc4f9f16b309b65f9f578ec4ba78b3efa106cf65d (diff)
wl12xx: cmd and acx interface rework
Rework cmd and acx interfaces, it was just too confusing earlier. Now all commands need to contain all the needed headers, either just cmd headers or both cmd and acx headers. This accomplish to remove the extra copy done for each command. The interfaces are now properly documented as well. Also try to make all commands safe for DMA transfers. I might have missed some, but most of them should be fixed now. And this is not all! As a free bonus you will also get some cosmetic cleanups and code reorganisation. Order today! Signed-off-by: Kalle Valo <kalle.valo@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/main.c')
-rw-r--r--drivers/net/wireless/wl12xx/main.c87
1 files changed, 53 insertions, 34 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 603d6114882e..c6a454439711 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -618,7 +618,8 @@ static void wl12xx_op_configure_filter(struct ieee80211_hw *hw,
618} 618}
619 619
620/* HW encryption */ 620/* HW encryption */
621static int wl12xx_set_key_type(struct wl12xx *wl, struct acx_set_key *key, 621static int wl12xx_set_key_type(struct wl12xx *wl,
622 struct wl12xx_cmd_set_keys *key,
622 enum set_key_cmd cmd, 623 enum set_key_cmd cmd,
623 struct ieee80211_key_conf *mac80211_key, 624 struct ieee80211_key_conf *mac80211_key,
624 const u8 *addr) 625 const u8 *addr)
@@ -661,7 +662,7 @@ static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
661 struct ieee80211_key_conf *key) 662 struct ieee80211_key_conf *key)
662{ 663{
663 struct wl12xx *wl = hw->priv; 664 struct wl12xx *wl = hw->priv;
664 struct acx_set_key wl_key; 665 struct wl12xx_cmd_set_keys *wl_cmd;
665 const u8 *addr; 666 const u8 *addr;
666 int ret; 667 int ret;
667 668
@@ -670,7 +671,11 @@ static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
670 671
671 wl12xx_debug(DEBUG_MAC80211, "mac80211 set key"); 672 wl12xx_debug(DEBUG_MAC80211, "mac80211 set key");
672 673
673 memset(&wl_key, 0, sizeof(wl_key)); 674 wl_cmd = kzalloc(sizeof(*wl_cmd), GFP_KERNEL);
675 if (!wl_cmd) {
676 ret = -ENOMEM;
677 goto out;
678 }
674 679
675 addr = sta ? sta->addr : bcast_addr; 680 addr = sta ? sta->addr : bcast_addr;
676 681
@@ -680,59 +685,69 @@ static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
680 key->alg, key->keyidx, key->keylen, key->flags); 685 key->alg, key->keyidx, key->keylen, key->flags);
681 wl12xx_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen); 686 wl12xx_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
682 687
688 if (is_zero_ether_addr(addr)) {
689 /* We dont support TX only encryption */
690 ret = -EOPNOTSUPP;
691 goto out;
692 }
693
683 mutex_lock(&wl->mutex); 694 mutex_lock(&wl->mutex);
684 695
685 switch (cmd) { 696 switch (cmd) {
686 case SET_KEY: 697 case SET_KEY:
687 wl_key.key_action = KEY_ADD_OR_REPLACE; 698 wl_cmd->key_action = KEY_ADD_OR_REPLACE;
688 break; 699 break;
689 case DISABLE_KEY: 700 case DISABLE_KEY:
690 wl_key.key_action = KEY_REMOVE; 701 wl_cmd->key_action = KEY_REMOVE;
691 break; 702 break;
692 default: 703 default:
693 wl12xx_error("Unsupported key cmd 0x%x", cmd); 704 wl12xx_error("Unsupported key cmd 0x%x", cmd);
694 break; 705 break;
695 } 706 }
696 707
697 ret = wl12xx_set_key_type(wl, &wl_key, cmd, key, addr); 708 ret = wl12xx_set_key_type(wl, wl_cmd, cmd, key, addr);
698 if (ret < 0) { 709 if (ret < 0) {
699 wl12xx_error("Set KEY type failed"); 710 wl12xx_error("Set KEY type failed");
700 goto out; 711 goto out_unlock;
701 } 712 }
702 713
703 if (wl_key.key_type != KEY_WEP_DEFAULT) 714 if (wl_cmd->key_type != KEY_WEP_DEFAULT)
704 memcpy(wl_key.addr, addr, ETH_ALEN); 715 memcpy(wl_cmd->addr, addr, ETH_ALEN);
705 716
706 if ((wl_key.key_type == KEY_TKIP_MIC_GROUP) || 717 if ((wl_cmd->key_type == KEY_TKIP_MIC_GROUP) ||
707 (wl_key.key_type == KEY_TKIP_MIC_PAIRWISE)) { 718 (wl_cmd->key_type == KEY_TKIP_MIC_PAIRWISE)) {
708 /* 719 /*
709 * We get the key in the following form: 720 * We get the key in the following form:
710 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes) 721 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
711 * but the target is expecting: 722 * but the target is expecting:
712 * TKIP - RX MIC - TX MIC 723 * TKIP - RX MIC - TX MIC
713 */ 724 */
714 memcpy(wl_key.key, key->key, 16); 725 memcpy(wl_cmd->key, key->key, 16);
715 memcpy(wl_key.key + 16, key->key + 24, 8); 726 memcpy(wl_cmd->key + 16, key->key + 24, 8);
716 memcpy(wl_key.key + 24, key->key + 16, 8); 727 memcpy(wl_cmd->key + 24, key->key + 16, 8);
717 728
718 } else { 729 } else {
719 memcpy(wl_key.key, key->key, key->keylen); 730 memcpy(wl_cmd->key, key->key, key->keylen);
720 } 731 }
721 wl_key.key_size = key->keylen; 732 wl_cmd->key_size = key->keylen;
722 733
723 wl_key.id = key->keyidx; 734 wl_cmd->id = key->keyidx;
724 wl_key.ssid_profile = 0; 735 wl_cmd->ssid_profile = 0;
725 736
726 wl12xx_dump(DEBUG_CRYPT, "TARGET KEY: ", &wl_key, sizeof(wl_key)); 737 wl12xx_dump(DEBUG_CRYPT, "TARGET KEY: ", wl_cmd, sizeof(*wl_cmd));
727 738
728 if (wl12xx_cmd_send(wl, CMD_SET_KEYS, &wl_key, sizeof(wl_key)) < 0) { 739 ret = wl12xx_cmd_send(wl, CMD_SET_KEYS, wl_cmd, sizeof(*wl_cmd));
729 wl12xx_error("Set KEY failed"); 740 if (ret < 0) {
730 ret = -EOPNOTSUPP; 741 wl12xx_warning("could not set keys");
731 goto out; 742 goto out_unlock;
732 } 743 }
733 744
734out: 745out_unlock:
735 mutex_unlock(&wl->mutex); 746 mutex_unlock(&wl->mutex);
747
748out:
749 kfree(wl_cmd);
750
736 return ret; 751 return ret;
737} 752}
738 753
@@ -812,11 +827,10 @@ static int wl12xx_hw_scan(struct wl12xx *wl, u8 *ssid, size_t len,
812 u8 active_scan, u8 high_prio, u8 num_channels, 827 u8 active_scan, u8 high_prio, u8 num_channels,
813 u8 probe_requests) 828 u8 probe_requests)
814{ 829{
830 struct wl12xx_cmd_trigger_scan_to *trigger = NULL;
831 struct cmd_scan *params = NULL;
815 int i, ret; 832 int i, ret;
816 u32 split_scan = 0;
817 u16 scan_options = 0; 833 u16 scan_options = 0;
818 struct cmd_scan *params;
819 struct wl12xx_command *cmd_answer;
820 834
821 if (wl->scanning) 835 if (wl->scanning)
822 return -EINVAL; 836 return -EINVAL;
@@ -870,10 +884,16 @@ static int wl12xx_hw_scan(struct wl12xx *wl, u8 *ssid, size_t len,
870 goto out; 884 goto out;
871 } 885 }
872 886
873 ret = wl12xx_cmd_send(wl, CMD_TRIGGER_SCAN_TO, &split_scan, 887 trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
874 sizeof(u32)); 888 if (!trigger)
889 goto out;
890
891 trigger->timeout = 0;
892
893 ret = wl12xx_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
894 sizeof(*trigger));
875 if (ret < 0) { 895 if (ret < 0) {
876 wl12xx_error("Split SCAN failed"); 896 wl12xx_error("trigger scan to failed for hw scan");
877 goto out; 897 goto out;
878 } 898 }
879 899
@@ -887,10 +907,9 @@ static int wl12xx_hw_scan(struct wl12xx *wl, u8 *ssid, size_t len,
887 907
888 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params)); 908 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
889 909
890 cmd_answer = (struct wl12xx_command *) params; 910 if (params->header.status != CMD_STATUS_SUCCESS) {
891 if (cmd_answer->status != CMD_STATUS_SUCCESS) {
892 wl12xx_error("TEST command answer error: %d", 911 wl12xx_error("TEST command answer error: %d",
893 cmd_answer->status); 912 params->header.status);
894 wl->scanning = false; 913 wl->scanning = false;
895 ret = -EIO; 914 ret = -EIO;
896 goto out; 915 goto out;
@@ -942,7 +961,7 @@ static void wl12xx_op_bss_info_changed(struct ieee80211_hw *hw,
942 struct ieee80211_bss_conf *bss_conf, 961 struct ieee80211_bss_conf *bss_conf,
943 u32 changed) 962 u32 changed)
944{ 963{
945 enum acx_ps_mode mode; 964 enum wl12xx_cmd_ps_mode mode;
946 struct wl12xx *wl = hw->priv; 965 struct wl12xx *wl = hw->priv;
947 struct sk_buff *beacon; 966 struct sk_buff *beacon;
948 int ret; 967 int ret;