aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath6kl/Kconfig25
-rw-r--r--drivers/net/wireless/ath/ath6kl/Makefile30
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.c10
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c606
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.h12
-rw-r--r--drivers/net/wireless/ath/ath6kl/common.h3
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.c316
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h107
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.c114
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.h28
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.c15
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc.c11
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c472
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c182
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c140
-rw-r--r--drivers/net/wireless/ath/ath6kl/testmode.c102
-rw-r--r--drivers/net/wireless/ath/ath6kl/testmode.h6
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c534
-rw-r--r--drivers/net/wireless/ath/ath6kl/usb.c431
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c148
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h67
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c2
23 files changed, 2439 insertions, 924 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig
index 3d5f8be20eac..d755a5e7ed20 100644
--- a/drivers/net/wireless/ath/ath6kl/Kconfig
+++ b/drivers/net/wireless/ath/ath6kl/Kconfig
@@ -1,12 +1,29 @@
1config ATH6KL 1config ATH6KL
2 tristate "Atheros ath6kl support" 2 tristate "Atheros mobile chipsets support"
3
4config ATH6KL_SDIO
5 tristate "Atheros ath6kl SDIO support"
6 depends on ATH6KL
3 depends on MMC 7 depends on MMC
4 depends on CFG80211 8 depends on CFG80211
5 ---help--- 9 ---help---
6 This module adds support for wireless adapters based on 10 This module adds support for wireless adapters based on
7 Atheros AR6003 chipset running over SDIO. If you choose to 11 Atheros AR6003 and AR6004 chipsets running over SDIO. If you
8 build it as a module, it will be called ath6kl. Pls note 12 choose to build it as a module, it will be called ath6kl_sdio.
9 that AR6002 and AR6001 are not supported by this driver. 13 Please note that AR6002 and AR6001 are not supported by this
14 driver.
15
16config ATH6KL_USB
17 tristate "Atheros ath6kl USB support"
18 depends on ATH6KL
19 depends on USB
20 depends on CFG80211
21 depends on EXPERIMENTAL
22 ---help---
23 This module adds support for wireless adapters based on
24 Atheros AR6004 chipset running over USB. This is still under
25 implementation and it isn't functional. If you choose to
26 build it as a module, it will be called ath6kl_usb.
10 27
11config ATH6KL_DEBUG 28config ATH6KL_DEBUG
12 bool "Atheros ath6kl debugging" 29 bool "Atheros ath6kl debugging"
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile
index 707069303550..9ba42fa04962 100644
--- a/drivers/net/wireless/ath/ath6kl/Makefile
+++ b/drivers/net/wireless/ath/ath6kl/Makefile
@@ -21,17 +21,21 @@
21# Author(s): ="Atheros" 21# Author(s): ="Atheros"
22#------------------------------------------------------------------------------ 22#------------------------------------------------------------------------------
23 23
24obj-$(CONFIG_ATH6KL) := ath6kl.o 24obj-$(CONFIG_ATH6KL) += ath6kl_core.o
25ath6kl-y += debug.o 25ath6kl_core-y += debug.o
26ath6kl-y += hif.o 26ath6kl_core-y += hif.o
27ath6kl-y += htc.o 27ath6kl_core-y += htc.o
28ath6kl-y += bmi.o 28ath6kl_core-y += bmi.o
29ath6kl-y += cfg80211.o 29ath6kl_core-y += cfg80211.o
30ath6kl-y += init.o 30ath6kl_core-y += init.o
31ath6kl-y += main.o 31ath6kl_core-y += main.o
32ath6kl-y += txrx.o 32ath6kl_core-y += txrx.o
33ath6kl-y += wmi.o 33ath6kl_core-y += wmi.o
34ath6kl-y += sdio.o 34ath6kl_core-y += core.o
35ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o 35ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
36 36
37ccflags-y += -D__CHECK_ENDIAN__ 37obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o
38ath6kl_sdio-y += sdio.o
39
40obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o
41ath6kl_usb-y += usb.o
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
index bce3575c310a..aef00d5a1438 100644
--- a/drivers/net/wireless/ath/ath6kl/bmi.c
+++ b/drivers/net/wireless/ath/ath6kl/bmi.c
@@ -57,8 +57,14 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
57 return ret; 57 return ret;
58 } 58 }
59 59
60 ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version, 60 if (ar->hif_type == ATH6KL_HIF_TYPE_USB) {
61 sizeof(targ_info->version)); 61 ret = ath6kl_hif_bmi_read(ar, (u8 *)targ_info,
62 sizeof(*targ_info));
63 } else {
64 ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version,
65 sizeof(targ_info->version));
66 }
67
62 if (ret) { 68 if (ret) {
63 ath6kl_err("Unable to recv target info: %d\n", ret); 69 ath6kl_err("Unable to recv target info: %d\n", ret);
64 return ret; 70 return ret;
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 6c59a217b1a1..d1922d8eb3bb 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -15,6 +15,8 @@
15 */ 15 */
16 16
17#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
18#include <linux/inetdevice.h>
19#include <linux/export.h>
18 20
19#include "core.h" 21#include "core.h"
20#include "cfg80211.h" 22#include "cfg80211.h"
@@ -22,10 +24,6 @@
22#include "hif-ops.h" 24#include "hif-ops.h"
23#include "testmode.h" 25#include "testmode.h"
24 26
25static unsigned int ath6kl_p2p;
26
27module_param(ath6kl_p2p, uint, 0644);
28
29#define RATETAB_ENT(_rate, _rateid, _flags) { \ 27#define RATETAB_ENT(_rate, _rateid, _flags) { \
30 .bitrate = (_rate), \ 28 .bitrate = (_rate), \
31 .flags = (_flags), \ 29 .flags = (_flags), \
@@ -196,7 +194,7 @@ static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
196 break; 194 break;
197 195
198 default: 196 default:
199 ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type); 197 ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type);
200 return -ENOTSUPP; 198 return -ENOTSUPP;
201 } 199 }
202 200
@@ -461,13 +459,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
461 } 459 }
462 } 460 }
463 461
464 if (sme->ie && (sme->ie_len > 0)) { 462 status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
465 status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len); 463 if (status) {
466 if (status) { 464 up(&ar->sem);
467 up(&ar->sem); 465 return status;
468 return status; 466 }
469 } 467
470 } else 468 if (sme->ie == NULL || sme->ie_len == 0)
471 ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG; 469 ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
472 470
473 if (test_bit(CONNECTED, &vif->flags) && 471 if (test_bit(CONNECTED, &vif->flags) &&
@@ -523,8 +521,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
523 (vif->prwise_crypto == WEP_CRYPT)) { 521 (vif->prwise_crypto == WEP_CRYPT)) {
524 struct ath6kl_key *key = NULL; 522 struct ath6kl_key *key = NULL;
525 523
526 if (sme->key_idx < WMI_MIN_KEY_INDEX || 524 if (sme->key_idx > WMI_MAX_KEY_INDEX) {
527 sme->key_idx > WMI_MAX_KEY_INDEX) {
528 ath6kl_err("key index %d out of bounds\n", 525 ath6kl_err("key index %d out of bounds\n",
529 sme->key_idx); 526 sme->key_idx);
530 up(&ar->sem); 527 up(&ar->sem);
@@ -605,11 +602,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
605 return 0; 602 return 0;
606} 603}
607 604
608static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, 605static struct cfg80211_bss *
609 enum network_type nw_type, 606ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
610 const u8 *bssid, 607 enum network_type nw_type,
611 struct ieee80211_channel *chan, 608 const u8 *bssid,
612 const u8 *beacon_ie, size_t beacon_ie_len) 609 struct ieee80211_channel *chan,
610 const u8 *beacon_ie,
611 size_t beacon_ie_len)
613{ 612{
614 struct ath6kl *ar = vif->ar; 613 struct ath6kl *ar = vif->ar;
615 struct cfg80211_bss *bss; 614 struct cfg80211_bss *bss;
@@ -638,7 +637,7 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
638 */ 637 */
639 ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL); 638 ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
640 if (ie == NULL) 639 if (ie == NULL)
641 return -ENOMEM; 640 return NULL;
642 ie[0] = WLAN_EID_SSID; 641 ie[0] = WLAN_EID_SSID;
643 ie[1] = vif->ssid_len; 642 ie[1] = vif->ssid_len;
644 memcpy(ie + 2, vif->ssid, vif->ssid_len); 643 memcpy(ie + 2, vif->ssid, vif->ssid_len);
@@ -652,15 +651,9 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
652 "cfg80211\n", bssid); 651 "cfg80211\n", bssid);
653 kfree(ie); 652 kfree(ie);
654 } else 653 } else
655 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss " 654 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
656 "entry\n");
657
658 if (bss == NULL)
659 return -ENOMEM;
660 655
661 cfg80211_put_bss(bss); 656 return bss;
662
663 return 0;
664} 657}
665 658
666void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, 659void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
@@ -672,6 +665,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
672{ 665{
673 struct ieee80211_channel *chan; 666 struct ieee80211_channel *chan;
674 struct ath6kl *ar = vif->ar; 667 struct ath6kl *ar = vif->ar;
668 struct cfg80211_bss *bss;
675 669
676 /* capinfo + listen interval */ 670 /* capinfo + listen interval */
677 u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16); 671 u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
@@ -712,8 +706,9 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
712 706
713 chan = ieee80211_get_channel(ar->wiphy, (int) channel); 707 chan = ieee80211_get_channel(ar->wiphy, (int) channel);
714 708
715 if (ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan, assoc_info, 709 bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan,
716 beacon_ie_len) < 0) { 710 assoc_info, beacon_ie_len);
711 if (!bss) {
717 ath6kl_err("could not add cfg80211 bss entry\n"); 712 ath6kl_err("could not add cfg80211 bss entry\n");
718 return; 713 return;
719 } 714 }
@@ -722,6 +717,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
722 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n", 717 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
723 nw_type & ADHOC_CREATOR ? "creator" : "joiner"); 718 nw_type & ADHOC_CREATOR ? "creator" : "joiner");
724 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); 719 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
720 cfg80211_put_bss(bss);
725 return; 721 return;
726 } 722 }
727 723
@@ -732,11 +728,11 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
732 assoc_req_ie, assoc_req_len, 728 assoc_req_ie, assoc_req_len,
733 assoc_resp_ie, assoc_resp_len, 729 assoc_resp_ie, assoc_resp_len,
734 WLAN_STATUS_SUCCESS, GFP_KERNEL); 730 WLAN_STATUS_SUCCESS, GFP_KERNEL);
731 cfg80211_put_bss(bss);
735 } else if (vif->sme_state == SME_CONNECTED) { 732 } else if (vif->sme_state == SME_CONNECTED) {
736 /* inform roam event to cfg80211 */ 733 /* inform roam event to cfg80211 */
737 cfg80211_roamed(vif->ndev, chan, bssid, 734 cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
738 assoc_req_ie, assoc_req_len, 735 assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
739 assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
740 } 736 }
741} 737}
742 738
@@ -984,6 +980,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
984 struct ath6kl *ar = ath6kl_priv(ndev); 980 struct ath6kl *ar = ath6kl_priv(ndev);
985 struct ath6kl_vif *vif = netdev_priv(ndev); 981 struct ath6kl_vif *vif = netdev_priv(ndev);
986 struct ath6kl_key *key = NULL; 982 struct ath6kl_key *key = NULL;
983 int seq_len;
987 u8 key_usage; 984 u8 key_usage;
988 u8 key_type; 985 u8 key_type;
989 986
@@ -997,7 +994,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
997 params->key); 994 params->key);
998 } 995 }
999 996
1000 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { 997 if (key_index > WMI_MAX_KEY_INDEX) {
1001 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, 998 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1002 "%s: key index %d out of bounds\n", __func__, 999 "%s: key index %d out of bounds\n", __func__,
1003 key_index); 1000 key_index);
@@ -1012,23 +1009,21 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1012 else 1009 else
1013 key_usage = GROUP_USAGE; 1010 key_usage = GROUP_USAGE;
1014 1011
1015 if (params) { 1012 seq_len = params->seq_len;
1016 int seq_len = params->seq_len; 1013 if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
1017 if (params->cipher == WLAN_CIPHER_SUITE_SMS4 && 1014 seq_len > ATH6KL_KEY_SEQ_LEN) {
1018 seq_len > ATH6KL_KEY_SEQ_LEN) { 1015 /* Only first half of the WPI PN is configured */
1019 /* Only first half of the WPI PN is configured */ 1016 seq_len = ATH6KL_KEY_SEQ_LEN;
1020 seq_len = ATH6KL_KEY_SEQ_LEN;
1021 }
1022 if (params->key_len > WLAN_MAX_KEY_LEN ||
1023 seq_len > sizeof(key->seq))
1024 return -EINVAL;
1025
1026 key->key_len = params->key_len;
1027 memcpy(key->key, params->key, key->key_len);
1028 key->seq_len = seq_len;
1029 memcpy(key->seq, params->seq, key->seq_len);
1030 key->cipher = params->cipher;
1031 } 1017 }
1018 if (params->key_len > WLAN_MAX_KEY_LEN ||
1019 seq_len > sizeof(key->seq))
1020 return -EINVAL;
1021
1022 key->key_len = params->key_len;
1023 memcpy(key->key, params->key, key->key_len);
1024 key->seq_len = seq_len;
1025 memcpy(key->seq, params->seq, key->seq_len);
1026 key->cipher = params->cipher;
1032 1027
1033 switch (key->cipher) { 1028 switch (key->cipher) {
1034 case WLAN_CIPHER_SUITE_WEP40: 1029 case WLAN_CIPHER_SUITE_WEP40:
@@ -1115,7 +1110,7 @@ static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1115 if (!ath6kl_cfg80211_ready(vif)) 1110 if (!ath6kl_cfg80211_ready(vif))
1116 return -EIO; 1111 return -EIO;
1117 1112
1118 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { 1113 if (key_index > WMI_MAX_KEY_INDEX) {
1119 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, 1114 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1120 "%s: key index %d out of bounds\n", __func__, 1115 "%s: key index %d out of bounds\n", __func__,
1121 key_index); 1116 key_index);
@@ -1148,7 +1143,7 @@ static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1148 if (!ath6kl_cfg80211_ready(vif)) 1143 if (!ath6kl_cfg80211_ready(vif))
1149 return -EIO; 1144 return -EIO;
1150 1145
1151 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { 1146 if (key_index > WMI_MAX_KEY_INDEX) {
1152 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, 1147 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1153 "%s: key index %d out of bounds\n", __func__, 1148 "%s: key index %d out of bounds\n", __func__,
1154 key_index); 1149 key_index);
@@ -1184,7 +1179,7 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1184 if (!ath6kl_cfg80211_ready(vif)) 1179 if (!ath6kl_cfg80211_ready(vif))
1185 return -EIO; 1180 return -EIO;
1186 1181
1187 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { 1182 if (key_index > WMI_MAX_KEY_INDEX) {
1188 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, 1183 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1189 "%s: key index %d out of bounds\n", 1184 "%s: key index %d out of bounds\n",
1190 __func__, key_index); 1185 __func__, key_index);
@@ -1403,7 +1398,7 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
1403 1398
1404 ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag)); 1399 ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
1405 1400
1406 ath6kl_deinit_if_data(vif); 1401 ath6kl_cfg80211_vif_cleanup(vif);
1407 1402
1408 return 0; 1403 return 0;
1409} 1404}
@@ -1728,29 +1723,14 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1728 return 0; 1723 return 0;
1729} 1724}
1730 1725
1731static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) 1726static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
1727 struct cfg80211_wowlan *wow, u32 *filter)
1732{ 1728{
1733 struct ath6kl_vif *vif; 1729 int ret, pos;
1734 int ret, pos, left;
1735 u32 filter = 0;
1736 u16 i;
1737 u8 mask[WOW_MASK_SIZE]; 1730 u8 mask[WOW_MASK_SIZE];
1731 u16 i;
1738 1732
1739 vif = ath6kl_vif_first(ar); 1733 /* Configure the patterns that we received from the user. */
1740 if (!vif)
1741 return -EIO;
1742
1743 if (!ath6kl_cfg80211_ready(vif))
1744 return -EIO;
1745
1746 if (!test_bit(CONNECTED, &vif->flags))
1747 return -EINVAL;
1748
1749 /* Clear existing WOW patterns */
1750 for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
1751 ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
1752 WOW_LIST_ID, i);
1753 /* Configure new WOW patterns */
1754 for (i = 0; i < wow->n_patterns; i++) { 1734 for (i = 0; i < wow->n_patterns; i++) {
1755 1735
1756 /* 1736 /*
@@ -1773,29 +1753,221 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
1773 * matched from the first byte of received pkt in the firmware. 1753 * matched from the first byte of received pkt in the firmware.
1774 */ 1754 */
1775 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, 1755 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1776 vif->fw_vif_idx, WOW_LIST_ID, 1756 vif->fw_vif_idx, WOW_LIST_ID,
1777 wow->patterns[i].pattern_len, 1757 wow->patterns[i].pattern_len,
1778 0 /* pattern offset */, 1758 0 /* pattern offset */,
1779 wow->patterns[i].pattern, mask); 1759 wow->patterns[i].pattern, mask);
1780 if (ret) 1760 if (ret)
1781 return ret; 1761 return ret;
1782 } 1762 }
1783 1763
1784 if (wow->disconnect) 1764 if (wow->disconnect)
1785 filter |= WOW_FILTER_OPTION_NWK_DISASSOC; 1765 *filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
1786 1766
1787 if (wow->magic_pkt) 1767 if (wow->magic_pkt)
1788 filter |= WOW_FILTER_OPTION_MAGIC_PACKET; 1768 *filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
1789 1769
1790 if (wow->gtk_rekey_failure) 1770 if (wow->gtk_rekey_failure)
1791 filter |= WOW_FILTER_OPTION_GTK_ERROR; 1771 *filter |= WOW_FILTER_OPTION_GTK_ERROR;
1792 1772
1793 if (wow->eap_identity_req) 1773 if (wow->eap_identity_req)
1794 filter |= WOW_FILTER_OPTION_EAP_REQ; 1774 *filter |= WOW_FILTER_OPTION_EAP_REQ;
1795 1775
1796 if (wow->four_way_handshake) 1776 if (wow->four_way_handshake)
1797 filter |= WOW_FILTER_OPTION_8021X_4WAYHS; 1777 *filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
1778
1779 return 0;
1780}
1781
1782static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif)
1783{
1784 static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00,
1785 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1786 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1787 0x00, 0x08 };
1788 static const u8 unicst_mask[] = { 0x01, 0x00, 0x00,
1789 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1790 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1791 0x00, 0x7f };
1792 u8 unicst_offset = 0;
1793 static const u8 arp_pattern[] = { 0x08, 0x06 };
1794 static const u8 arp_mask[] = { 0xff, 0xff };
1795 u8 arp_offset = 20;
1796 static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
1797 static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
1798 u8 discvr_offset = 38;
1799 static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
1800 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1801 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
1802 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1803 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1804 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
1805 static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
1806 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
1811 u8 dhcp_offset = 0;
1812 int ret;
1813
1814 /* Setup unicast IP, EAPOL-like and ARP pkt pattern */
1815 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1816 vif->fw_vif_idx, WOW_LIST_ID,
1817 sizeof(unicst_pattern), unicst_offset,
1818 unicst_pattern, unicst_mask);
1819 if (ret) {
1820 ath6kl_err("failed to add WOW unicast IP pattern\n");
1821 return ret;
1822 }
1823
1824 /* Setup all ARP pkt pattern */
1825 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1826 vif->fw_vif_idx, WOW_LIST_ID,
1827 sizeof(arp_pattern), arp_offset,
1828 arp_pattern, arp_mask);
1829 if (ret) {
1830 ath6kl_err("failed to add WOW ARP pattern\n");
1831 return ret;
1832 }
1798 1833
1834 /*
1835 * Setup multicast pattern for mDNS 224.0.0.251,
1836 * SSDP 239.255.255.250 and LLMNR 224.0.0.252
1837 */
1838 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1839 vif->fw_vif_idx, WOW_LIST_ID,
1840 sizeof(discvr_pattern), discvr_offset,
1841 discvr_pattern, discvr_mask);
1842 if (ret) {
1843 ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
1844 return ret;
1845 }
1846
1847 /* Setup all DHCP broadcast pkt pattern */
1848 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1849 vif->fw_vif_idx, WOW_LIST_ID,
1850 sizeof(dhcp_pattern), dhcp_offset,
1851 dhcp_pattern, dhcp_mask);
1852 if (ret) {
1853 ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
1854 return ret;
1855 }
1856
1857 return 0;
1858}
1859
1860static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
1861{
1862 struct net_device *ndev = vif->ndev;
1863 static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
1864 static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
1865 u8 discvr_offset = 38;
1866 u8 mac_mask[ETH_ALEN];
1867 int ret;
1868
1869 /* Setup unicast pkt pattern */
1870 memset(mac_mask, 0xff, ETH_ALEN);
1871 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1872 vif->fw_vif_idx, WOW_LIST_ID,
1873 ETH_ALEN, 0, ndev->dev_addr,
1874 mac_mask);
1875 if (ret) {
1876 ath6kl_err("failed to add WOW unicast pattern\n");
1877 return ret;
1878 }
1879
1880 /*
1881 * Setup multicast pattern for mDNS 224.0.0.251,
1882 * SSDP 239.255.255.250 and LLMNR 224.0.0.252
1883 */
1884 if ((ndev->flags & IFF_ALLMULTI) ||
1885 (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
1886 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1887 vif->fw_vif_idx, WOW_LIST_ID,
1888 sizeof(discvr_pattern), discvr_offset,
1889 discvr_pattern, discvr_mask);
1890 if (ret) {
1891 ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR "
1892 "pattern\n");
1893 return ret;
1894 }
1895 }
1896
1897 return 0;
1898}
1899
1900static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
1901{
1902 struct in_device *in_dev;
1903 struct in_ifaddr *ifa;
1904 struct ath6kl_vif *vif;
1905 int ret, left;
1906 u32 filter = 0;
1907 u16 i;
1908 u8 index = 0;
1909 __be32 ips[MAX_IP_ADDRS];
1910
1911 vif = ath6kl_vif_first(ar);
1912 if (!vif)
1913 return -EIO;
1914
1915 if (!ath6kl_cfg80211_ready(vif))
1916 return -EIO;
1917
1918 if (!test_bit(CONNECTED, &vif->flags))
1919 return -ENOTCONN;
1920
1921 if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
1922 return -EINVAL;
1923
1924 /* Clear existing WOW patterns */
1925 for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
1926 ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
1927 WOW_LIST_ID, i);
1928
1929 /*
1930 * Skip the default WOW pattern configuration
1931 * if the driver receives any WOW patterns from
1932 * the user.
1933 */
1934 if (wow)
1935 ret = ath6kl_wow_usr(ar, vif, wow, &filter);
1936 else if (vif->nw_type == AP_NETWORK)
1937 ret = ath6kl_wow_ap(ar, vif);
1938 else
1939 ret = ath6kl_wow_sta(ar, vif);
1940
1941 if (ret)
1942 return ret;
1943
1944 /* Setup own IP addr for ARP agent. */
1945 in_dev = __in_dev_get_rtnl(vif->ndev);
1946 if (!in_dev)
1947 goto skip_arp;
1948
1949 ifa = in_dev->ifa_list;
1950 memset(&ips, 0, sizeof(ips));
1951
1952 /* Configure IP addr only if IP address count < MAX_IP_ADDRS */
1953 while (index < MAX_IP_ADDRS && ifa) {
1954 ips[index] = ifa->ifa_local;
1955 ifa = ifa->ifa_next;
1956 index++;
1957 }
1958
1959 if (ifa) {
1960 ath6kl_err("total IP addr count is exceeding fw limit\n");
1961 return -EINVAL;
1962 }
1963
1964 ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]);
1965 if (ret) {
1966 ath6kl_err("fail to setup ip for arp agent\n");
1967 return ret;
1968 }
1969
1970skip_arp:
1799 ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, 1971 ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
1800 ATH6KL_WOW_MODE_ENABLE, 1972 ATH6KL_WOW_MODE_ENABLE,
1801 filter, 1973 filter,
@@ -1803,11 +1975,26 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
1803 if (ret) 1975 if (ret)
1804 return ret; 1976 return ret;
1805 1977
1978 clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
1979
1806 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, 1980 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
1807 ATH6KL_HOST_MODE_ASLEEP); 1981 ATH6KL_HOST_MODE_ASLEEP);
1808 if (ret) 1982 if (ret)
1809 return ret; 1983 return ret;
1810 1984
1985 left = wait_event_interruptible_timeout(ar->event_wq,
1986 test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags),
1987 WMI_TIMEOUT);
1988 if (left == 0) {
1989 ath6kl_warn("timeout, didn't get host sleep cmd "
1990 "processed event\n");
1991 ret = -ETIMEDOUT;
1992 } else if (left < 0) {
1993 ath6kl_warn("error while waiting for host sleep cmd "
1994 "processed event %d\n", left);
1995 ret = left;
1996 }
1997
1811 if (ar->tx_pending[ar->ctrl_ep]) { 1998 if (ar->tx_pending[ar->ctrl_ep]) {
1812 left = wait_event_interruptible_timeout(ar->event_wq, 1999 left = wait_event_interruptible_timeout(ar->event_wq,
1813 ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT); 2000 ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT);
@@ -1911,6 +2098,7 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
1911 2098
1912 return 0; 2099 return 0;
1913} 2100}
2101EXPORT_SYMBOL(ath6kl_cfg80211_suspend);
1914 2102
1915int ath6kl_cfg80211_resume(struct ath6kl *ar) 2103int ath6kl_cfg80211_resume(struct ath6kl *ar)
1916{ 2104{
@@ -1962,6 +2150,7 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar)
1962 2150
1963 return 0; 2151 return 0;
1964} 2152}
2153EXPORT_SYMBOL(ath6kl_cfg80211_resume);
1965 2154
1966#ifdef CONFIG_PM 2155#ifdef CONFIG_PM
1967 2156
@@ -2014,7 +2203,18 @@ static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
2014 struct ieee80211_channel *chan, 2203 struct ieee80211_channel *chan,
2015 enum nl80211_channel_type channel_type) 2204 enum nl80211_channel_type channel_type)
2016{ 2205{
2017 struct ath6kl_vif *vif = netdev_priv(dev); 2206 struct ath6kl_vif *vif;
2207
2208 /*
2209 * 'dev' could be NULL if a channel change is required for the hardware
2210 * device itself, instead of a particular VIF.
2211 *
2212 * FIXME: To be handled properly when monitor mode is supported.
2213 */
2214 if (!dev)
2215 return -EBUSY;
2216
2217 vif = netdev_priv(dev);
2018 2218
2019 if (!ath6kl_cfg80211_ready(vif)) 2219 if (!ath6kl_cfg80211_ready(vif))
2020 return -EIO; 2220 return -EIO;
@@ -2214,6 +2414,11 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
2214 p.dot11_auth_mode = vif->dot11_auth_mode; 2414 p.dot11_auth_mode = vif->dot11_auth_mode;
2215 p.ch = cpu_to_le16(vif->next_chan); 2415 p.ch = cpu_to_le16(vif->next_chan);
2216 2416
2417 /* Enable uAPSD support by default */
2418 res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
2419 if (res < 0)
2420 return res;
2421
2217 if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) { 2422 if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
2218 p.nw_subtype = SUBTYPE_P2PGO; 2423 p.nw_subtype = SUBTYPE_P2PGO;
2219 } else { 2424 } else {
@@ -2259,6 +2464,19 @@ static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
2259 return 0; 2464 return 0;
2260} 2465}
2261 2466
2467static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2468
2469static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
2470 u8 *mac)
2471{
2472 struct ath6kl *ar = ath6kl_priv(dev);
2473 struct ath6kl_vif *vif = netdev_priv(dev);
2474 const u8 *addr = mac ? mac : bcast_addr;
2475
2476 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
2477 addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
2478}
2479
2262static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev, 2480static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
2263 u8 *mac, struct station_parameters *params) 2481 u8 *mac, struct station_parameters *params)
2264{ 2482{
@@ -2518,6 +2736,12 @@ ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
2518 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | 2736 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2519 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) 2737 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2520 }, 2738 },
2739 [NL80211_IFTYPE_AP] = {
2740 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2741 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2742 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2743 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2744 },
2521 [NL80211_IFTYPE_P2P_CLIENT] = { 2745 [NL80211_IFTYPE_P2P_CLIENT] = {
2522 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | 2746 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2523 BIT(IEEE80211_STYPE_PROBE_RESP >> 4), 2747 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
@@ -2562,6 +2786,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
2562 .add_beacon = ath6kl_add_beacon, 2786 .add_beacon = ath6kl_add_beacon,
2563 .set_beacon = ath6kl_set_beacon, 2787 .set_beacon = ath6kl_set_beacon,
2564 .del_beacon = ath6kl_del_beacon, 2788 .del_beacon = ath6kl_del_beacon,
2789 .del_station = ath6kl_del_station,
2565 .change_station = ath6kl_change_station, 2790 .change_station = ath6kl_change_station,
2566 .remain_on_channel = ath6kl_remain_on_channel, 2791 .remain_on_channel = ath6kl_remain_on_channel,
2567 .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel, 2792 .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
@@ -2629,122 +2854,9 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
2629 ath6kl_cfg80211_stop(vif); 2854 ath6kl_cfg80211_stop(vif);
2630} 2855}
2631 2856
2632struct ath6kl *ath6kl_core_alloc(struct device *dev) 2857static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
2633{
2634 struct ath6kl *ar;
2635 struct wiphy *wiphy;
2636 u8 ctr;
2637
2638 /* create a new wiphy for use with cfg80211 */
2639 wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
2640
2641 if (!wiphy) {
2642 ath6kl_err("couldn't allocate wiphy device\n");
2643 return NULL;
2644 }
2645
2646 ar = wiphy_priv(wiphy);
2647 ar->p2p = !!ath6kl_p2p;
2648 ar->wiphy = wiphy;
2649 ar->dev = dev;
2650
2651 ar->vif_max = 1;
2652
2653 ar->max_norm_iface = 1;
2654
2655 spin_lock_init(&ar->lock);
2656 spin_lock_init(&ar->mcastpsq_lock);
2657 spin_lock_init(&ar->list_lock);
2658
2659 init_waitqueue_head(&ar->event_wq);
2660 sema_init(&ar->sem, 1);
2661
2662 INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
2663 INIT_LIST_HEAD(&ar->vif_list);
2664
2665 clear_bit(WMI_ENABLED, &ar->flag);
2666 clear_bit(SKIP_SCAN, &ar->flag);
2667 clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
2668
2669 ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL;
2670 ar->listen_intvl_b = 0;
2671 ar->tx_pwr = 0;
2672
2673 ar->intra_bss = 1;
2674 ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
2675
2676 ar->state = ATH6KL_STATE_OFF;
2677
2678 memset((u8 *)ar->sta_list, 0,
2679 AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
2680
2681 /* Init the PS queues */
2682 for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
2683 spin_lock_init(&ar->sta_list[ctr].psq_lock);
2684 skb_queue_head_init(&ar->sta_list[ctr].psq);
2685 }
2686
2687 skb_queue_head_init(&ar->mcastpsq);
2688
2689 memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
2690
2691 return ar;
2692}
2693
2694int ath6kl_register_ieee80211_hw(struct ath6kl *ar)
2695{
2696 struct wiphy *wiphy = ar->wiphy;
2697 int ret;
2698
2699 wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
2700
2701 wiphy->max_remain_on_channel_duration = 5000;
2702
2703 /* set device pointer for wiphy */
2704 set_wiphy_dev(wiphy, ar->dev);
2705
2706 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2707 BIT(NL80211_IFTYPE_ADHOC) |
2708 BIT(NL80211_IFTYPE_AP);
2709 if (ar->p2p) {
2710 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
2711 BIT(NL80211_IFTYPE_P2P_CLIENT);
2712 }
2713
2714 /* max num of ssids that can be probed during scanning */
2715 wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
2716 wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
2717 wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
2718 wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
2719 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2720
2721 wiphy->cipher_suites = cipher_suites;
2722 wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2723
2724 wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
2725 WIPHY_WOWLAN_DISCONNECT |
2726 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
2727 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
2728 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
2729 WIPHY_WOWLAN_4WAY_HANDSHAKE;
2730 wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
2731 wiphy->wowlan.pattern_min_len = 1;
2732 wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
2733
2734 wiphy->max_sched_scan_ssids = 10;
2735
2736 ret = wiphy_register(wiphy);
2737 if (ret < 0) {
2738 ath6kl_err("couldn't register wiphy device\n");
2739 return ret;
2740 }
2741
2742 return 0;
2743}
2744
2745static int ath6kl_init_if_data(struct ath6kl_vif *vif)
2746{ 2858{
2747 vif->aggr_cntxt = aggr_init(vif->ndev); 2859 vif->aggr_cntxt = aggr_init(vif);
2748 if (!vif->aggr_cntxt) { 2860 if (!vif->aggr_cntxt) {
2749 ath6kl_err("failed to initialize aggr\n"); 2861 ath6kl_err("failed to initialize aggr\n");
2750 return -ENOMEM; 2862 return -ENOMEM;
@@ -2758,12 +2870,15 @@ static int ath6kl_init_if_data(struct ath6kl_vif *vif)
2758 set_bit(WMM_ENABLED, &vif->flags); 2870 set_bit(WMM_ENABLED, &vif->flags);
2759 spin_lock_init(&vif->if_lock); 2871 spin_lock_init(&vif->if_lock);
2760 2872
2873 INIT_LIST_HEAD(&vif->mc_filter);
2874
2761 return 0; 2875 return 0;
2762} 2876}
2763 2877
2764void ath6kl_deinit_if_data(struct ath6kl_vif *vif) 2878void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
2765{ 2879{
2766 struct ath6kl *ar = vif->ar; 2880 struct ath6kl *ar = vif->ar;
2881 struct ath6kl_mc_filter *mc_filter, *tmp;
2767 2882
2768 aggr_module_destroy(vif->aggr_cntxt); 2883 aggr_module_destroy(vif->aggr_cntxt);
2769 2884
@@ -2772,6 +2887,11 @@ void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
2772 if (vif->nw_type == ADHOC_NETWORK) 2887 if (vif->nw_type == ADHOC_NETWORK)
2773 ar->ibss_if_active = false; 2888 ar->ibss_if_active = false;
2774 2889
2890 list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
2891 list_del(&mc_filter->list);
2892 kfree(mc_filter);
2893 }
2894
2775 unregister_netdevice(vif->ndev); 2895 unregister_netdevice(vif->ndev);
2776 2896
2777 ar->num_vif--; 2897 ar->num_vif--;
@@ -2808,8 +2928,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
2808 2928
2809 ath6kl_init_control_info(vif); 2929 ath6kl_init_control_info(vif);
2810 2930
2811 /* TODO: Pass interface specific pointer instead of ar */ 2931 if (ath6kl_cfg80211_vif_init(vif))
2812 if (ath6kl_init_if_data(vif))
2813 goto err; 2932 goto err;
2814 2933
2815 if (register_netdevice(ndev)) 2934 if (register_netdevice(ndev))
@@ -2836,8 +2955,89 @@ err:
2836 return NULL; 2955 return NULL;
2837} 2956}
2838 2957
2839void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar) 2958int ath6kl_cfg80211_init(struct ath6kl *ar)
2959{
2960 struct wiphy *wiphy = ar->wiphy;
2961 int ret;
2962
2963 wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
2964
2965 wiphy->max_remain_on_channel_duration = 5000;
2966
2967 /* set device pointer for wiphy */
2968 set_wiphy_dev(wiphy, ar->dev);
2969
2970 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2971 BIT(NL80211_IFTYPE_ADHOC) |
2972 BIT(NL80211_IFTYPE_AP);
2973 if (ar->p2p) {
2974 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
2975 BIT(NL80211_IFTYPE_P2P_CLIENT);
2976 }
2977
2978 /* max num of ssids that can be probed during scanning */
2979 wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
2980 wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
2981 wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
2982 wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
2983 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2984
2985 wiphy->cipher_suites = cipher_suites;
2986 wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2987
2988 wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
2989 WIPHY_WOWLAN_DISCONNECT |
2990 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
2991 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
2992 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
2993 WIPHY_WOWLAN_4WAY_HANDSHAKE;
2994 wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
2995 wiphy->wowlan.pattern_min_len = 1;
2996 wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
2997
2998 wiphy->max_sched_scan_ssids = 10;
2999
3000 ret = wiphy_register(wiphy);
3001 if (ret < 0) {
3002 ath6kl_err("couldn't register wiphy device\n");
3003 return ret;
3004 }
3005
3006 return 0;
3007}
3008
3009void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
2840{ 3010{
2841 wiphy_unregister(ar->wiphy); 3011 wiphy_unregister(ar->wiphy);
3012}
3013
3014struct ath6kl *ath6kl_cfg80211_create(void)
3015{
3016 struct ath6kl *ar;
3017 struct wiphy *wiphy;
3018
3019 /* create a new wiphy for use with cfg80211 */
3020 wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
3021
3022 if (!wiphy) {
3023 ath6kl_err("couldn't allocate wiphy device\n");
3024 return NULL;
3025 }
3026
3027 ar = wiphy_priv(wiphy);
3028 ar->wiphy = wiphy;
3029
3030 return ar;
3031}
3032
3033/* Note: ar variable must not be accessed after calling this! */
3034void ath6kl_cfg80211_destroy(struct ath6kl *ar)
3035{
3036 int i;
3037
3038 for (i = 0; i < AP_MAX_NUM_STA; i++)
3039 kfree(ar->sta_list[i].aggr_conn);
3040
2842 wiphy_free(ar->wiphy); 3041 wiphy_free(ar->wiphy);
2843} 3042}
3043
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h
index 81f20a572315..3c693b7c0efd 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.h
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h
@@ -27,10 +27,6 @@ enum ath6kl_cfg_suspend_mode {
27struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, 27struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
28 enum nl80211_iftype type, 28 enum nl80211_iftype type,
29 u8 fw_vif_idx, u8 nw_type); 29 u8 fw_vif_idx, u8 nw_type);
30int ath6kl_register_ieee80211_hw(struct ath6kl *ar);
31struct ath6kl *ath6kl_core_alloc(struct device *dev);
32void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar);
33
34void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); 30void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted);
35 31
36void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, 32void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
@@ -53,7 +49,15 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
53 49
54int ath6kl_cfg80211_resume(struct ath6kl *ar); 50int ath6kl_cfg80211_resume(struct ath6kl *ar);
55 51
52void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif);
53
56void ath6kl_cfg80211_stop(struct ath6kl_vif *vif); 54void ath6kl_cfg80211_stop(struct ath6kl_vif *vif);
57void ath6kl_cfg80211_stop_all(struct ath6kl *ar); 55void ath6kl_cfg80211_stop_all(struct ath6kl *ar);
58 56
57int ath6kl_cfg80211_init(struct ath6kl *ar);
58void ath6kl_cfg80211_cleanup(struct ath6kl *ar);
59
60struct ath6kl *ath6kl_cfg80211_create(void);
61void ath6kl_cfg80211_destroy(struct ath6kl *ar);
62
59#endif /* ATH6KL_CFG80211_H */ 63#endif /* ATH6KL_CFG80211_H */
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
index bfd6597763da..f89f1e180da3 100644
--- a/drivers/net/wireless/ath/ath6kl/common.h
+++ b/drivers/net/wireless/ath/ath6kl/common.h
@@ -79,8 +79,5 @@ struct ath6kl;
79enum htc_credit_dist_reason; 79enum htc_credit_dist_reason;
80struct ath6kl_htc_credit_info; 80struct ath6kl_htc_credit_info;
81 81
82struct ath6kl *ath6kl_core_alloc(struct device *sdev);
83int ath6kl_core_init(struct ath6kl *ar);
84void ath6kl_core_cleanup(struct ath6kl *ar);
85struct sk_buff *ath6kl_buf_alloc(int size); 82struct sk_buff *ath6kl_buf_alloc(int size);
86#endif /* COMMON_H */ 83#endif /* COMMON_H */
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c
new file mode 100644
index 000000000000..722ca59b88ce
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/core.c
@@ -0,0 +1,316 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "core.h"
18
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/export.h>
22
23#include "debug.h"
24#include "hif-ops.h"
25#include "cfg80211.h"
26
27unsigned int debug_mask;
28static unsigned int suspend_mode;
29static unsigned int uart_debug;
30static unsigned int ath6kl_p2p;
31static unsigned int testmode;
32
33module_param(debug_mask, uint, 0644);
34module_param(suspend_mode, uint, 0644);
35module_param(uart_debug, uint, 0644);
36module_param(ath6kl_p2p, uint, 0644);
37module_param(testmode, uint, 0644);
38
39int ath6kl_core_init(struct ath6kl *ar)
40{
41 struct ath6kl_bmi_target_info targ_info;
42 struct net_device *ndev;
43 int ret = 0, i;
44
45 ar->ath6kl_wq = create_singlethread_workqueue("ath6kl");
46 if (!ar->ath6kl_wq)
47 return -ENOMEM;
48
49 ret = ath6kl_bmi_init(ar);
50 if (ret)
51 goto err_wq;
52
53 /*
54 * Turn on power to get hardware (target) version and leave power
55 * on delibrately as we will boot the hardware anyway within few
56 * seconds.
57 */
58 ret = ath6kl_hif_power_on(ar);
59 if (ret)
60 goto err_bmi_cleanup;
61
62 ret = ath6kl_bmi_get_target_info(ar, &targ_info);
63 if (ret)
64 goto err_power_off;
65
66 ar->version.target_ver = le32_to_cpu(targ_info.version);
67 ar->target_type = le32_to_cpu(targ_info.type);
68 ar->wiphy->hw_version = le32_to_cpu(targ_info.version);
69
70 ret = ath6kl_init_hw_params(ar);
71 if (ret)
72 goto err_power_off;
73
74 ar->htc_target = ath6kl_htc_create(ar);
75
76 if (!ar->htc_target) {
77 ret = -ENOMEM;
78 goto err_power_off;
79 }
80
81 ar->testmode = testmode;
82
83 ret = ath6kl_init_fetch_firmwares(ar);
84 if (ret)
85 goto err_htc_cleanup;
86
87 /* FIXME: we should free all firmwares in the error cases below */
88
89 /* Indicate that WMI is enabled (although not ready yet) */
90 set_bit(WMI_ENABLED, &ar->flag);
91 ar->wmi = ath6kl_wmi_init(ar);
92 if (!ar->wmi) {
93 ath6kl_err("failed to initialize wmi\n");
94 ret = -EIO;
95 goto err_htc_cleanup;
96 }
97
98 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
99
100 ret = ath6kl_cfg80211_init(ar);
101 if (ret)
102 goto err_node_cleanup;
103
104 ret = ath6kl_debug_init(ar);
105 if (ret) {
106 wiphy_unregister(ar->wiphy);
107 goto err_node_cleanup;
108 }
109
110 for (i = 0; i < ar->vif_max; i++)
111 ar->avail_idx_map |= BIT(i);
112
113 rtnl_lock();
114
115 /* Add an initial station interface */
116 ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0,
117 INFRA_NETWORK);
118
119 rtnl_unlock();
120
121 if (!ndev) {
122 ath6kl_err("Failed to instantiate a network device\n");
123 ret = -ENOMEM;
124 wiphy_unregister(ar->wiphy);
125 goto err_debug_init;
126 }
127
128
129 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
130 __func__, ndev->name, ndev, ar);
131
132 /* setup access class priority mappings */
133 ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */
134 ar->ac_stream_pri_map[WMM_AC_BE] = 1;
135 ar->ac_stream_pri_map[WMM_AC_VI] = 2;
136 ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */
137
138 /* give our connected endpoints some buffers */
139 ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep);
140 ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]);
141
142 /* allocate some buffers that handle larger AMSDU frames */
143 ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
144
145 ath6kl_cookie_init(ar);
146
147 ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
148 ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
149
150 if (suspend_mode &&
151 suspend_mode >= WLAN_POWER_STATE_CUT_PWR &&
152 suspend_mode <= WLAN_POWER_STATE_WOW)
153 ar->suspend_mode = suspend_mode;
154 else
155 ar->suspend_mode = 0;
156
157 if (uart_debug)
158 ar->conf_flags |= ATH6KL_CONF_UART_DEBUG;
159
160 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
161 WIPHY_FLAG_HAVE_AP_SME |
162 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
163 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
164
165 if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
166 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
167
168 ar->wiphy->probe_resp_offload =
169 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
170 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
171 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
172 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
173
174 set_bit(FIRST_BOOT, &ar->flag);
175
176 ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
177
178 ret = ath6kl_init_hw_start(ar);
179 if (ret) {
180 ath6kl_err("Failed to start hardware: %d\n", ret);
181 goto err_rxbuf_cleanup;
182 }
183
184 /*
185 * Set mac address which is received in ready event
186 * FIXME: Move to ath6kl_interface_add()
187 */
188 memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
189
190 return ret;
191
192err_rxbuf_cleanup:
193 ath6kl_htc_flush_rx_buf(ar->htc_target);
194 ath6kl_cleanup_amsdu_rxbufs(ar);
195 rtnl_lock();
196 ath6kl_cfg80211_vif_cleanup(netdev_priv(ndev));
197 rtnl_unlock();
198 wiphy_unregister(ar->wiphy);
199err_debug_init:
200 ath6kl_debug_cleanup(ar);
201err_node_cleanup:
202 ath6kl_wmi_shutdown(ar->wmi);
203 clear_bit(WMI_ENABLED, &ar->flag);
204 ar->wmi = NULL;
205err_htc_cleanup:
206 ath6kl_htc_cleanup(ar->htc_target);
207err_power_off:
208 ath6kl_hif_power_off(ar);
209err_bmi_cleanup:
210 ath6kl_bmi_cleanup(ar);
211err_wq:
212 destroy_workqueue(ar->ath6kl_wq);
213
214 return ret;
215}
216EXPORT_SYMBOL(ath6kl_core_init);
217
218struct ath6kl *ath6kl_core_create(struct device *dev)
219{
220 struct ath6kl *ar;
221 u8 ctr;
222
223 ar = ath6kl_cfg80211_create();
224 if (!ar)
225 return NULL;
226
227 ar->p2p = !!ath6kl_p2p;
228 ar->dev = dev;
229
230 ar->vif_max = 1;
231
232 ar->max_norm_iface = 1;
233
234 spin_lock_init(&ar->lock);
235 spin_lock_init(&ar->mcastpsq_lock);
236 spin_lock_init(&ar->list_lock);
237
238 init_waitqueue_head(&ar->event_wq);
239 sema_init(&ar->sem, 1);
240
241 INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
242 INIT_LIST_HEAD(&ar->vif_list);
243
244 clear_bit(WMI_ENABLED, &ar->flag);
245 clear_bit(SKIP_SCAN, &ar->flag);
246 clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
247
248 ar->listen_intvl_b = A_DEFAULT_LISTEN_INTERVAL;
249 ar->tx_pwr = 0;
250
251 ar->intra_bss = 1;
252 ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
253
254 ar->state = ATH6KL_STATE_OFF;
255
256 memset((u8 *)ar->sta_list, 0,
257 AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
258
259 /* Init the PS queues */
260 for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
261 spin_lock_init(&ar->sta_list[ctr].psq_lock);
262 skb_queue_head_init(&ar->sta_list[ctr].psq);
263 skb_queue_head_init(&ar->sta_list[ctr].apsdq);
264 ar->sta_list[ctr].aggr_conn =
265 kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL);
266 if (!ar->sta_list[ctr].aggr_conn) {
267 ath6kl_err("Failed to allocate memory for sta aggregation information\n");
268 ath6kl_core_destroy(ar);
269 return NULL;
270 }
271 }
272
273 skb_queue_head_init(&ar->mcastpsq);
274
275 memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
276
277 return ar;
278}
279EXPORT_SYMBOL(ath6kl_core_create);
280
281void ath6kl_core_cleanup(struct ath6kl *ar)
282{
283 ath6kl_hif_power_off(ar);
284
285 destroy_workqueue(ar->ath6kl_wq);
286
287 if (ar->htc_target)
288 ath6kl_htc_cleanup(ar->htc_target);
289
290 ath6kl_cookie_cleanup(ar);
291
292 ath6kl_cleanup_amsdu_rxbufs(ar);
293
294 ath6kl_bmi_cleanup(ar);
295
296 ath6kl_debug_cleanup(ar);
297
298 kfree(ar->fw_board);
299 kfree(ar->fw_otp);
300 kfree(ar->fw);
301 kfree(ar->fw_patch);
302 kfree(ar->fw_testscript);
303
304 ath6kl_cfg80211_cleanup(ar);
305}
306EXPORT_SYMBOL(ath6kl_core_cleanup);
307
308void ath6kl_core_destroy(struct ath6kl *ar)
309{
310 ath6kl_cfg80211_destroy(ar);
311}
312EXPORT_SYMBOL(ath6kl_core_destroy);
313
314MODULE_AUTHOR("Qualcomm Atheros");
315MODULE_DESCRIPTION("Core module for AR600x SDIO and USB devices.");
316MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index c863a28f2e0c..c4d66e066dc9 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -44,6 +44,10 @@
44#define ATH6KL_MAX_ENDPOINTS 4 44#define ATH6KL_MAX_ENDPOINTS 4
45#define MAX_NODE_NUM 15 45#define MAX_NODE_NUM 15
46 46
47#define ATH6KL_APSD_ALL_FRAME 0xFFFF
48#define ATH6KL_APSD_NUM_OF_AC 0x4
49#define ATH6KL_APSD_FRAME_MASK 0xF
50
47/* Extra bytes for htc header alignment */ 51/* Extra bytes for htc header alignment */
48#define ATH6KL_HTC_ALIGN_BYTES 3 52#define ATH6KL_HTC_ALIGN_BYTES 3
49 53
@@ -55,7 +59,7 @@
55#define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC) 59#define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC)
56 60
57#define DISCON_TIMER_INTVAL 10000 /* in msec */ 61#define DISCON_TIMER_INTVAL 10000 /* in msec */
58#define A_DEFAULT_LISTEN_INTERVAL 100 62#define A_DEFAULT_LISTEN_INTERVAL 1 /* beacon intervals */
59#define A_MAX_WOW_LISTEN_INTERVAL 1000 63#define A_MAX_WOW_LISTEN_INTERVAL 1000
60 64
61/* includes also the null byte */ 65/* includes also the null byte */
@@ -97,45 +101,49 @@ struct ath6kl_fw_ie {
97 u8 data[0]; 101 u8 data[0];
98}; 102};
99 103
104#define ATH6KL_FW_API2_FILE "fw-2.bin"
105#define ATH6KL_FW_API3_FILE "fw-3.bin"
106
100/* AR6003 1.0 definitions */ 107/* AR6003 1.0 definitions */
101#define AR6003_HW_1_0_VERSION 0x300002ba 108#define AR6003_HW_1_0_VERSION 0x300002ba
102 109
103/* AR6003 2.0 definitions */ 110/* AR6003 2.0 definitions */
104#define AR6003_HW_2_0_VERSION 0x30000384 111#define AR6003_HW_2_0_VERSION 0x30000384
105#define AR6003_HW_2_0_PATCH_DOWNLOAD_ADDRESS 0x57e910 112#define AR6003_HW_2_0_PATCH_DOWNLOAD_ADDRESS 0x57e910
106#define AR6003_HW_2_0_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77" 113#define AR6003_HW_2_0_FW_DIR "ath6k/AR6003/hw2.0"
107#define AR6003_HW_2_0_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77" 114#define AR6003_HW_2_0_OTP_FILE "otp.bin.z77"
108#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin" 115#define AR6003_HW_2_0_FIRMWARE_FILE "athwlan.bin.z77"
109#define AR6003_HW_2_0_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin" 116#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "athtcmd_ram.bin"
110#define AR6003_HW_2_0_FIRMWARE_2_FILE "ath6k/AR6003/hw2.0/fw-2.bin" 117#define AR6003_HW_2_0_PATCH_FILE "data.patch.bin"
111#define AR6003_HW_2_0_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin" 118#define AR6003_HW_2_0_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin"
112#define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \ 119#define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \
113 "ath6k/AR6003/hw2.0/bdata.SD31.bin" 120 "ath6k/AR6003/hw2.0/bdata.SD31.bin"
114 121
115/* AR6003 3.0 definitions */ 122/* AR6003 3.0 definitions */
116#define AR6003_HW_2_1_1_VERSION 0x30000582 123#define AR6003_HW_2_1_1_VERSION 0x30000582
117#define AR6003_HW_2_1_1_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin" 124#define AR6003_HW_2_1_1_FW_DIR "ath6k/AR6003/hw2.1.1"
118#define AR6003_HW_2_1_1_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin" 125#define AR6003_HW_2_1_1_OTP_FILE "otp.bin"
119#define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE \ 126#define AR6003_HW_2_1_1_FIRMWARE_FILE "athwlan.bin"
120 "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin" 127#define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE "athtcmd_ram.bin"
121#define AR6003_HW_2_1_1_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin" 128#define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE "utf.bin"
122#define AR6003_HW_2_1_1_FIRMWARE_2_FILE "ath6k/AR6003/hw2.1.1/fw-2.bin" 129#define AR6003_HW_2_1_1_TESTSCRIPT_FILE "nullTestFlow.bin"
130#define AR6003_HW_2_1_1_PATCH_FILE "data.patch.bin"
123#define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin" 131#define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin"
124#define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \ 132#define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \
125 "ath6k/AR6003/hw2.1.1/bdata.SD31.bin" 133 "ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
126 134
127/* AR6004 1.0 definitions */ 135/* AR6004 1.0 definitions */
128#define AR6004_HW_1_0_VERSION 0x30000623 136#define AR6004_HW_1_0_VERSION 0x30000623
129#define AR6004_HW_1_0_FIRMWARE_2_FILE "ath6k/AR6004/hw1.0/fw-2.bin" 137#define AR6004_HW_1_0_FW_DIR "ath6k/AR6004/hw1.0"
130#define AR6004_HW_1_0_FIRMWARE_FILE "ath6k/AR6004/hw1.0/fw.ram.bin" 138#define AR6004_HW_1_0_FIRMWARE_FILE "fw.ram.bin"
131#define AR6004_HW_1_0_BOARD_DATA_FILE "ath6k/AR6004/hw1.0/bdata.bin" 139#define AR6004_HW_1_0_BOARD_DATA_FILE "ath6k/AR6004/hw1.0/bdata.bin"
132#define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \ 140#define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \
133 "ath6k/AR6004/hw1.0/bdata.DB132.bin" 141 "ath6k/AR6004/hw1.0/bdata.DB132.bin"
134 142
135/* AR6004 1.1 definitions */ 143/* AR6004 1.1 definitions */
136#define AR6004_HW_1_1_VERSION 0x30000001 144#define AR6004_HW_1_1_VERSION 0x30000001
137#define AR6004_HW_1_1_FIRMWARE_2_FILE "ath6k/AR6004/hw1.1/fw-2.bin" 145#define AR6004_HW_1_1_FW_DIR "ath6k/AR6004/hw1.1"
138#define AR6004_HW_1_1_FIRMWARE_FILE "ath6k/AR6004/hw1.1/fw.ram.bin" 146#define AR6004_HW_1_1_FIRMWARE_FILE "fw.ram.bin"
139#define AR6004_HW_1_1_BOARD_DATA_FILE "ath6k/AR6004/hw1.1/bdata.bin" 147#define AR6004_HW_1_1_BOARD_DATA_FILE "ath6k/AR6004/hw1.1/bdata.bin"
140#define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \ 148#define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \
141 "ath6k/AR6004/hw1.1/bdata.DB132.bin" 149 "ath6k/AR6004/hw1.1/bdata.DB132.bin"
@@ -144,6 +152,8 @@ struct ath6kl_fw_ie {
144#define STA_PS_AWAKE BIT(0) 152#define STA_PS_AWAKE BIT(0)
145#define STA_PS_SLEEP BIT(1) 153#define STA_PS_SLEEP BIT(1)
146#define STA_PS_POLLED BIT(2) 154#define STA_PS_POLLED BIT(2)
155#define STA_PS_APSD_TRIGGER BIT(3)
156#define STA_PS_APSD_EOSP BIT(4)
147 157
148/* HTC TX packet tagging definitions */ 158/* HTC TX packet tagging definitions */
149#define ATH6KL_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED 159#define ATH6KL_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED
@@ -186,7 +196,7 @@ struct ath6kl_fw_ie {
186#define ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN BIT(1) 196#define ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN BIT(1)
187#define ATH6KL_CONF_ENABLE_11N BIT(2) 197#define ATH6KL_CONF_ENABLE_11N BIT(2)
188#define ATH6KL_CONF_ENABLE_TX_BURST BIT(3) 198#define ATH6KL_CONF_ENABLE_TX_BURST BIT(3)
189#define ATH6KL_CONF_SUSPEND_CUTPOWER BIT(4) 199#define ATH6KL_CONF_UART_DEBUG BIT(4)
190 200
191enum wlan_low_pwr_state { 201enum wlan_low_pwr_state {
192 WLAN_POWER_STATE_ON, 202 WLAN_POWER_STATE_ON,
@@ -231,14 +241,19 @@ struct rxtid_stats {
231 u32 num_bar; 241 u32 num_bar;
232}; 242};
233 243
234struct aggr_info { 244struct aggr_info_conn {
235 u8 aggr_sz; 245 u8 aggr_sz;
236 u8 timer_scheduled; 246 u8 timer_scheduled;
237 struct timer_list timer; 247 struct timer_list timer;
238 struct net_device *dev; 248 struct net_device *dev;
239 struct rxtid rx_tid[NUM_OF_TIDS]; 249 struct rxtid rx_tid[NUM_OF_TIDS];
240 struct sk_buff_head free_q;
241 struct rxtid_stats stat[NUM_OF_TIDS]; 250 struct rxtid_stats stat[NUM_OF_TIDS];
251 struct aggr_info *aggr_info;
252};
253
254struct aggr_info {
255 struct aggr_info_conn *aggr_conn;
256 struct sk_buff_head rx_amsdu_freeq;
242}; 257};
243 258
244struct ath6kl_wep_key { 259struct ath6kl_wep_key {
@@ -280,6 +295,9 @@ struct ath6kl_sta {
280 u8 wpa_ie[ATH6KL_MAX_IE]; 295 u8 wpa_ie[ATH6KL_MAX_IE];
281 struct sk_buff_head psq; 296 struct sk_buff_head psq;
282 spinlock_t psq_lock; 297 spinlock_t psq_lock;
298 u8 apsd_info;
299 struct sk_buff_head apsdq;
300 struct aggr_info_conn *aggr_conn;
283}; 301};
284 302
285struct ath6kl_version { 303struct ath6kl_version {
@@ -408,6 +426,13 @@ enum ath6kl_hif_type {
408 ATH6KL_HIF_TYPE_USB, 426 ATH6KL_HIF_TYPE_USB,
409}; 427};
410 428
429/* Max number of filters that hw supports */
430#define ATH6K_MAX_MC_FILTERS_PER_LIST 7
431struct ath6kl_mc_filter {
432 struct list_head list;
433 char hw_addr[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE];
434};
435
411/* 436/*
412 * Driver's maximum limit, note that some firmwares support only one vif 437 * Driver's maximum limit, note that some firmwares support only one vif
413 * and the runtime (current) limit must be checked from ar->vif_max. 438 * and the runtime (current) limit must be checked from ar->vif_max.
@@ -426,6 +451,7 @@ enum ath6kl_vif_state {
426 DTIM_PERIOD_AVAIL, 451 DTIM_PERIOD_AVAIL,
427 WLAN_ENABLED, 452 WLAN_ENABLED,
428 STATS_UPDATE_PEND, 453 STATS_UPDATE_PEND,
454 HOST_SLEEP_MODE_CMD_PROCESSED,
429}; 455};
430 456
431struct ath6kl_vif { 457struct ath6kl_vif {
@@ -471,6 +497,8 @@ struct ath6kl_vif {
471 u8 assoc_bss_dtim_period; 497 u8 assoc_bss_dtim_period;
472 struct net_device_stats net_stats; 498 struct net_device_stats net_stats;
473 struct target_stats target_stats; 499 struct target_stats target_stats;
500
501 struct list_head mc_filter;
474}; 502};
475 503
476#define WOW_LIST_ID 0 504#define WOW_LIST_ID 0
@@ -504,6 +532,7 @@ struct ath6kl {
504 struct wiphy *wiphy; 532 struct wiphy *wiphy;
505 533
506 enum ath6kl_state state; 534 enum ath6kl_state state;
535 unsigned int testmode;
507 536
508 struct ath6kl_bmi bmi; 537 struct ath6kl_bmi bmi;
509 const struct ath6kl_hif_ops *hif_ops; 538 const struct ath6kl_hif_ops *hif_ops;
@@ -523,7 +552,6 @@ struct ath6kl {
523 spinlock_t lock; 552 spinlock_t lock;
524 struct semaphore sem; 553 struct semaphore sem;
525 u16 listen_intvl_b; 554 u16 listen_intvl_b;
526 u16 listen_intvl_t;
527 u8 lrssi_roam_threshold; 555 u8 lrssi_roam_threshold;
528 struct ath6kl_version version; 556 struct ath6kl_version version;
529 u32 target_type; 557 u32 target_type;
@@ -574,17 +602,24 @@ struct ath6kl {
574 u32 board_addr; 602 u32 board_addr;
575 u32 refclk_hz; 603 u32 refclk_hz;
576 u32 uarttx_pin; 604 u32 uarttx_pin;
605 u32 testscript_addr;
606
607 struct ath6kl_hw_fw {
608 const char *dir;
609 const char *otp;
610 const char *fw;
611 const char *tcmd;
612 const char *patch;
613 const char *utf;
614 const char *testscript;
615 } fw;
577 616
578 const char *fw_otp;
579 const char *fw;
580 const char *fw_tcmd;
581 const char *fw_patch;
582 const char *fw_api2;
583 const char *fw_board; 617 const char *fw_board;
584 const char *fw_default_board; 618 const char *fw_default_board;
585 } hw; 619 } hw;
586 620
587 u16 conf_flags; 621 u16 conf_flags;
622 u16 suspend_mode;
588 wait_queue_head_t event_wq; 623 wait_queue_head_t event_wq;
589 struct ath6kl_mbox_info mbox_info; 624 struct ath6kl_mbox_info mbox_info;
590 625
@@ -603,6 +638,10 @@ struct ath6kl {
603 u8 *fw_patch; 638 u8 *fw_patch;
604 size_t fw_patch_len; 639 size_t fw_patch_len;
605 640
641 u8 *fw_testscript;
642 size_t fw_testscript_len;
643
644 unsigned int fw_api;
606 unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN]; 645 unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN];
607 646
608 struct workqueue_struct *ath6kl_wq; 647 struct workqueue_struct *ath6kl_wq;
@@ -676,7 +715,9 @@ struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar);
676void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie); 715void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie);
677int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev); 716int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev);
678 717
679struct aggr_info *aggr_init(struct net_device *dev); 718struct aggr_info *aggr_init(struct ath6kl_vif *vif);
719void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
720 struct aggr_info_conn *aggr_conn);
680void ath6kl_rx_refill(struct htc_target *target, 721void ath6kl_rx_refill(struct htc_target *target,
681 enum htc_endpoint_id endpoint); 722 enum htc_endpoint_id endpoint);
682void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count); 723void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count);
@@ -684,7 +725,7 @@ struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target,
684 enum htc_endpoint_id endpoint, 725 enum htc_endpoint_id endpoint,
685 int len); 726 int len);
686void aggr_module_destroy(struct aggr_info *aggr_info); 727void aggr_module_destroy(struct aggr_info *aggr_info);
687void aggr_reset_state(struct aggr_info *aggr_info); 728void aggr_reset_state(struct aggr_info_conn *aggr_conn);
688 729
689struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr); 730struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr);
690struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid); 731struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);
@@ -700,7 +741,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel,
700void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel); 741void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel);
701void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, 742void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
702 u8 keymgmt, u8 ucipher, u8 auth, 743 u8 keymgmt, u8 ucipher, u8 auth,
703 u8 assoc_req_len, u8 *assoc_info); 744 u8 assoc_req_len, u8 *assoc_info, u8 apsd_info);
704void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, 745void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason,
705 u8 *bssid, u8 assoc_resp_len, 746 u8 *bssid, u8 assoc_resp_len,
706 u8 *assoc_info, u16 prot_reason_status); 747 u8 *assoc_info, u16 prot_reason_status);
@@ -723,12 +764,18 @@ void ath6kl_wakeup_event(void *dev);
723void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, 764void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
724 bool wait_fot_compltn, bool cold_reset); 765 bool wait_fot_compltn, bool cold_reset);
725void ath6kl_init_control_info(struct ath6kl_vif *vif); 766void ath6kl_init_control_info(struct ath6kl_vif *vif);
726void ath6kl_deinit_if_data(struct ath6kl_vif *vif);
727void ath6kl_core_free(struct ath6kl *ar);
728struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar); 767struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar);
729void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready); 768void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready);
730int ath6kl_init_hw_start(struct ath6kl *ar); 769int ath6kl_init_hw_start(struct ath6kl *ar);
731int ath6kl_init_hw_stop(struct ath6kl *ar); 770int ath6kl_init_hw_stop(struct ath6kl *ar);
771int ath6kl_init_fetch_firmwares(struct ath6kl *ar);
772int ath6kl_init_hw_params(struct ath6kl *ar);
773
732void ath6kl_check_wow_status(struct ath6kl *ar); 774void ath6kl_check_wow_status(struct ath6kl *ar);
733 775
776struct ath6kl *ath6kl_core_create(struct device *dev);
777int ath6kl_core_init(struct ath6kl *ar);
778void ath6kl_core_cleanup(struct ath6kl *ar);
779void ath6kl_core_destroy(struct ath6kl *ar);
780
734#endif /* CORE_H */ 781#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index eb808b46f94c..d832058816fe 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -54,9 +54,42 @@ int ath6kl_printk(const char *level, const char *fmt, ...)
54 54
55 return rtn; 55 return rtn;
56} 56}
57EXPORT_SYMBOL(ath6kl_printk);
57 58
58#ifdef CONFIG_ATH6KL_DEBUG 59#ifdef CONFIG_ATH6KL_DEBUG
59 60
61void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...)
62{
63 struct va_format vaf;
64 va_list args;
65
66 if (!(debug_mask & mask))
67 return;
68
69 va_start(args, fmt);
70
71 vaf.fmt = fmt;
72 vaf.va = &args;
73
74 ath6kl_printk(KERN_DEBUG, "%pV", &vaf);
75
76 va_end(args);
77}
78EXPORT_SYMBOL(ath6kl_dbg);
79
80void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
81 const char *msg, const char *prefix,
82 const void *buf, size_t len)
83{
84 if (debug_mask & mask) {
85 if (msg)
86 ath6kl_dbg(mask, "%s\n", msg);
87
88 print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
89 }
90}
91EXPORT_SYMBOL(ath6kl_dbg_dump);
92
60#define REG_OUTPUT_LEN_PER_LINE 25 93#define REG_OUTPUT_LEN_PER_LINE 25
61#define REGTYPE_STR_LEN 100 94#define REGTYPE_STR_LEN 100
62 95
@@ -82,31 +115,31 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
82 struct ath6kl_irq_enable_reg *irq_enable_reg) 115 struct ath6kl_irq_enable_reg *irq_enable_reg)
83{ 116{
84 117
85 ath6kl_dbg(ATH6KL_DBG_ANY, ("<------- Register Table -------->\n")); 118 ath6kl_dbg(ATH6KL_DBG_IRQ, ("<------- Register Table -------->\n"));
86 119
87 if (irq_proc_reg != NULL) { 120 if (irq_proc_reg != NULL) {
88 ath6kl_dbg(ATH6KL_DBG_ANY, 121 ath6kl_dbg(ATH6KL_DBG_IRQ,
89 "Host Int status: 0x%x\n", 122 "Host Int status: 0x%x\n",
90 irq_proc_reg->host_int_status); 123 irq_proc_reg->host_int_status);
91 ath6kl_dbg(ATH6KL_DBG_ANY, 124 ath6kl_dbg(ATH6KL_DBG_IRQ,
92 "CPU Int status: 0x%x\n", 125 "CPU Int status: 0x%x\n",
93 irq_proc_reg->cpu_int_status); 126 irq_proc_reg->cpu_int_status);
94 ath6kl_dbg(ATH6KL_DBG_ANY, 127 ath6kl_dbg(ATH6KL_DBG_IRQ,
95 "Error Int status: 0x%x\n", 128 "Error Int status: 0x%x\n",
96 irq_proc_reg->error_int_status); 129 irq_proc_reg->error_int_status);
97 ath6kl_dbg(ATH6KL_DBG_ANY, 130 ath6kl_dbg(ATH6KL_DBG_IRQ,
98 "Counter Int status: 0x%x\n", 131 "Counter Int status: 0x%x\n",
99 irq_proc_reg->counter_int_status); 132 irq_proc_reg->counter_int_status);
100 ath6kl_dbg(ATH6KL_DBG_ANY, 133 ath6kl_dbg(ATH6KL_DBG_IRQ,
101 "Mbox Frame: 0x%x\n", 134 "Mbox Frame: 0x%x\n",
102 irq_proc_reg->mbox_frame); 135 irq_proc_reg->mbox_frame);
103 ath6kl_dbg(ATH6KL_DBG_ANY, 136 ath6kl_dbg(ATH6KL_DBG_IRQ,
104 "Rx Lookahead Valid: 0x%x\n", 137 "Rx Lookahead Valid: 0x%x\n",
105 irq_proc_reg->rx_lkahd_valid); 138 irq_proc_reg->rx_lkahd_valid);
106 ath6kl_dbg(ATH6KL_DBG_ANY, 139 ath6kl_dbg(ATH6KL_DBG_IRQ,
107 "Rx Lookahead 0: 0x%x\n", 140 "Rx Lookahead 0: 0x%x\n",
108 irq_proc_reg->rx_lkahd[0]); 141 irq_proc_reg->rx_lkahd[0]);
109 ath6kl_dbg(ATH6KL_DBG_ANY, 142 ath6kl_dbg(ATH6KL_DBG_IRQ,
110 "Rx Lookahead 1: 0x%x\n", 143 "Rx Lookahead 1: 0x%x\n",
111 irq_proc_reg->rx_lkahd[1]); 144 irq_proc_reg->rx_lkahd[1]);
112 145
@@ -115,16 +148,16 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
115 * If the target supports GMBOX hardware, dump some 148 * If the target supports GMBOX hardware, dump some
116 * additional state. 149 * additional state.
117 */ 150 */
118 ath6kl_dbg(ATH6KL_DBG_ANY, 151 ath6kl_dbg(ATH6KL_DBG_IRQ,
119 "GMBOX Host Int status 2: 0x%x\n", 152 "GMBOX Host Int status 2: 0x%x\n",
120 irq_proc_reg->host_int_status2); 153 irq_proc_reg->host_int_status2);
121 ath6kl_dbg(ATH6KL_DBG_ANY, 154 ath6kl_dbg(ATH6KL_DBG_IRQ,
122 "GMBOX RX Avail: 0x%x\n", 155 "GMBOX RX Avail: 0x%x\n",
123 irq_proc_reg->gmbox_rx_avail); 156 irq_proc_reg->gmbox_rx_avail);
124 ath6kl_dbg(ATH6KL_DBG_ANY, 157 ath6kl_dbg(ATH6KL_DBG_IRQ,
125 "GMBOX lookahead alias 0: 0x%x\n", 158 "GMBOX lookahead alias 0: 0x%x\n",
126 irq_proc_reg->rx_gmbox_lkahd_alias[0]); 159 irq_proc_reg->rx_gmbox_lkahd_alias[0]);
127 ath6kl_dbg(ATH6KL_DBG_ANY, 160 ath6kl_dbg(ATH6KL_DBG_IRQ,
128 "GMBOX lookahead alias 1: 0x%x\n", 161 "GMBOX lookahead alias 1: 0x%x\n",
129 irq_proc_reg->rx_gmbox_lkahd_alias[1]); 162 irq_proc_reg->rx_gmbox_lkahd_alias[1]);
130 } 163 }
@@ -132,13 +165,13 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
132 } 165 }
133 166
134 if (irq_enable_reg != NULL) { 167 if (irq_enable_reg != NULL) {
135 ath6kl_dbg(ATH6KL_DBG_ANY, 168 ath6kl_dbg(ATH6KL_DBG_IRQ,
136 "Int status Enable: 0x%x\n", 169 "Int status Enable: 0x%x\n",
137 irq_enable_reg->int_status_en); 170 irq_enable_reg->int_status_en);
138 ath6kl_dbg(ATH6KL_DBG_ANY, "Counter Int status Enable: 0x%x\n", 171 ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status Enable: 0x%x\n",
139 irq_enable_reg->cntr_int_status_en); 172 irq_enable_reg->cntr_int_status_en);
140 } 173 }
141 ath6kl_dbg(ATH6KL_DBG_ANY, "<------------------------------->\n"); 174 ath6kl_dbg(ATH6KL_DBG_IRQ, "<------------------------------->\n");
142} 175}
143 176
144static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist) 177static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist)
@@ -175,9 +208,6 @@ void dump_cred_dist_stats(struct htc_target *target)
175{ 208{
176 struct htc_endpoint_credit_dist *ep_list; 209 struct htc_endpoint_credit_dist *ep_list;
177 210
178 if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_CREDIT))
179 return;
180
181 list_for_each_entry(ep_list, &target->cred_dist_list, list) 211 list_for_each_entry(ep_list, &target->cred_dist_list, list)
182 dump_cred_dist(ep_list); 212 dump_cred_dist(ep_list);
183 213
@@ -1411,6 +1441,8 @@ static ssize_t ath6kl_create_qos_write(struct file *file,
1411 return -EINVAL; 1441 return -EINVAL;
1412 pstream.medium_time = cpu_to_le32(val32); 1442 pstream.medium_time = cpu_to_le32(val32);
1413 1443
1444 pstream.nominal_phy = le32_to_cpu(pstream.min_phy_rate) / 1000000;
1445
1414 ath6kl_wmi_create_pstream_cmd(ar->wmi, vif->fw_vif_idx, &pstream); 1446 ath6kl_wmi_create_pstream_cmd(ar->wmi, vif->fw_vif_idx, &pstream);
1415 1447
1416 return count; 1448 return count;
@@ -1505,57 +1537,46 @@ static const struct file_operations fops_bgscan_int = {
1505}; 1537};
1506 1538
1507static ssize_t ath6kl_listen_int_write(struct file *file, 1539static ssize_t ath6kl_listen_int_write(struct file *file,
1508 const char __user *user_buf, 1540 const char __user *user_buf,
1509 size_t count, loff_t *ppos) 1541 size_t count, loff_t *ppos)
1510{ 1542{
1511 struct ath6kl *ar = file->private_data; 1543 struct ath6kl *ar = file->private_data;
1512 u16 listen_int_t, listen_int_b; 1544 struct ath6kl_vif *vif;
1545 u16 listen_interval;
1513 char buf[32]; 1546 char buf[32];
1514 char *sptr, *token;
1515 ssize_t len; 1547 ssize_t len;
1516 1548
1549 vif = ath6kl_vif_first(ar);
1550 if (!vif)
1551 return -EIO;
1552
1517 len = min(count, sizeof(buf) - 1); 1553 len = min(count, sizeof(buf) - 1);
1518 if (copy_from_user(buf, user_buf, len)) 1554 if (copy_from_user(buf, user_buf, len))
1519 return -EFAULT; 1555 return -EFAULT;
1520 1556
1521 buf[len] = '\0'; 1557 buf[len] = '\0';
1522 sptr = buf; 1558 if (kstrtou16(buf, 0, &listen_interval))
1523
1524 token = strsep(&sptr, " ");
1525 if (!token)
1526 return -EINVAL;
1527
1528 if (kstrtou16(token, 0, &listen_int_t))
1529 return -EINVAL;
1530
1531 if (kstrtou16(sptr, 0, &listen_int_b))
1532 return -EINVAL;
1533
1534 if ((listen_int_t < 15) || (listen_int_t > 5000))
1535 return -EINVAL; 1559 return -EINVAL;
1536 1560
1537 if ((listen_int_b < 1) || (listen_int_b > 50)) 1561 if ((listen_interval < 1) || (listen_interval > 50))
1538 return -EINVAL; 1562 return -EINVAL;
1539 1563
1540 ar->listen_intvl_t = listen_int_t; 1564 ar->listen_intvl_b = listen_interval;
1541 ar->listen_intvl_b = listen_int_b; 1565 ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, 0,
1542
1543 ath6kl_wmi_listeninterval_cmd(ar->wmi, 0, ar->listen_intvl_t,
1544 ar->listen_intvl_b); 1566 ar->listen_intvl_b);
1545 1567
1546 return count; 1568 return count;
1547} 1569}
1548 1570
1549static ssize_t ath6kl_listen_int_read(struct file *file, 1571static ssize_t ath6kl_listen_int_read(struct file *file,
1550 char __user *user_buf, 1572 char __user *user_buf,
1551 size_t count, loff_t *ppos) 1573 size_t count, loff_t *ppos)
1552{ 1574{
1553 struct ath6kl *ar = file->private_data; 1575 struct ath6kl *ar = file->private_data;
1554 char buf[32]; 1576 char buf[32];
1555 int len; 1577 int len;
1556 1578
1557 len = scnprintf(buf, sizeof(buf), "%u %u\n", ar->listen_intvl_t, 1579 len = scnprintf(buf, sizeof(buf), "%u\n", ar->listen_intvl_b);
1558 ar->listen_intvl_b);
1559 1580
1560 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1581 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1561} 1582}
@@ -1710,6 +1731,9 @@ int ath6kl_debug_init(struct ath6kl *ar)
1710 debugfs_create_file("bgscan_interval", S_IWUSR, 1731 debugfs_create_file("bgscan_interval", S_IWUSR,
1711 ar->debugfs_phy, ar, &fops_bgscan_int); 1732 ar->debugfs_phy, ar, &fops_bgscan_int);
1712 1733
1734 debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR,
1735 ar->debugfs_phy, ar, &fops_listen_int);
1736
1713 debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar, 1737 debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar,
1714 &fops_power_params); 1738 &fops_power_params);
1715 1739
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index 9853c9c125c1..c4be6e50996b 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -41,6 +41,7 @@ enum ATH6K_DEBUG_MASK {
41 ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */ 41 ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */
42 ATH6KL_DBG_WMI_DUMP = BIT(19), 42 ATH6KL_DBG_WMI_DUMP = BIT(19),
43 ATH6KL_DBG_SUSPEND = BIT(20), 43 ATH6KL_DBG_SUSPEND = BIT(20),
44 ATH6KL_DBG_USB = BIT(21),
44 ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ 45 ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */
45}; 46};
46 47
@@ -55,35 +56,16 @@ int ath6kl_printk(const char *level, const char *fmt, ...);
55#define ath6kl_warn(fmt, ...) \ 56#define ath6kl_warn(fmt, ...) \
56 ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__) 57 ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__)
57 58
58#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask)
59
60enum ath6kl_war { 59enum ath6kl_war {
61 ATH6KL_WAR_INVALID_RATE, 60 ATH6KL_WAR_INVALID_RATE,
62}; 61};
63 62
64#ifdef CONFIG_ATH6KL_DEBUG 63#ifdef CONFIG_ATH6KL_DEBUG
65#define ath6kl_dbg(mask, fmt, ...) \
66 ({ \
67 int rtn; \
68 if (debug_mask & mask) \
69 rtn = ath6kl_printk(KERN_DEBUG, fmt, ##__VA_ARGS__); \
70 else \
71 rtn = 0; \
72 \
73 rtn; \
74 })
75 64
76static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, 65void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...);
77 const char *msg, const char *prefix, 66void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
78 const void *buf, size_t len) 67 const char *msg, const char *prefix,
79{ 68 const void *buf, size_t len);
80 if (debug_mask & mask) {
81 if (msg)
82 ath6kl_dbg(mask, "%s\n", msg);
83
84 print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
85 }
86}
87 69
88void ath6kl_dump_registers(struct ath6kl_device *dev, 70void ath6kl_dump_registers(struct ath6kl_device *dev,
89 struct ath6kl_irq_proc_registers *irq_proc_reg, 71 struct ath6kl_irq_proc_registers *irq_proc_reg,
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c
index e57da35e59fa..e911737ab345 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.c
+++ b/drivers/net/wireless/ath/ath6kl/hif.c
@@ -15,6 +15,8 @@
15 */ 15 */
16#include "hif.h" 16#include "hif.h"
17 17
18#include <linux/export.h>
19
18#include "core.h" 20#include "core.h"
19#include "target.h" 21#include "target.h"
20#include "hif-ops.h" 22#include "hif-ops.h"
@@ -59,6 +61,8 @@ int ath6kl_hif_rw_comp_handler(void *context, int status)
59 61
60 return 0; 62 return 0;
61} 63}
64EXPORT_SYMBOL(ath6kl_hif_rw_comp_handler);
65
62#define REG_DUMP_COUNT_AR6003 60 66#define REG_DUMP_COUNT_AR6003 60
63#define REGISTER_DUMP_LEN_MAX 60 67#define REGISTER_DUMP_LEN_MAX 60
64 68
@@ -429,9 +433,8 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
429 if (status) 433 if (status)
430 goto out; 434 goto out;
431 435
432 if (AR_DBG_LVL_CHECK(ATH6KL_DBG_IRQ)) 436 ath6kl_dump_registers(dev, &dev->irq_proc_reg,
433 ath6kl_dump_registers(dev, &dev->irq_proc_reg, 437 &dev->irq_en_reg);
434 &dev->irq_en_reg);
435 438
436 /* Update only those registers that are enabled */ 439 /* Update only those registers that are enabled */
437 host_int_status = dev->irq_proc_reg.host_int_status & 440 host_int_status = dev->irq_proc_reg.host_int_status &
@@ -561,6 +564,7 @@ int ath6kl_hif_intr_bh_handler(struct ath6kl *ar)
561 564
562 return status; 565 return status;
563} 566}
567EXPORT_SYMBOL(ath6kl_hif_intr_bh_handler);
564 568
565static int ath6kl_hif_enable_intrs(struct ath6kl_device *dev) 569static int ath6kl_hif_enable_intrs(struct ath6kl_device *dev)
566{ 570{
@@ -689,6 +693,11 @@ int ath6kl_hif_setup(struct ath6kl_device *dev)
689 ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n", 693 ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n",
690 dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr); 694 dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr);
691 695
696 /* usb doesn't support enabling interrupts */
697 /* FIXME: remove check once USB support is implemented */
698 if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB)
699 return 0;
700
692 status = ath6kl_hif_disable_intrs(dev); 701 status = ath6kl_hif_disable_intrs(dev);
693 702
694fail_setup: 703fail_setup:
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index f3b63ca25c7e..2d721903640b 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -2062,6 +2062,7 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
2062 enum htc_endpoint_id id; 2062 enum htc_endpoint_id id;
2063 int n_fetched = 0; 2063 int n_fetched = 0;
2064 2064
2065 INIT_LIST_HEAD(&comp_pktq);
2065 *num_pkts = 0; 2066 *num_pkts = 0;
2066 2067
2067 /* 2068 /*
@@ -2543,6 +2544,12 @@ int ath6kl_htc_wait_target(struct htc_target *target)
2543 struct htc_service_connect_resp resp; 2544 struct htc_service_connect_resp resp;
2544 int status; 2545 int status;
2545 2546
2547 /* FIXME: remove once USB support is implemented */
2548 if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) {
2549 ath6kl_err("HTC doesn't support USB yet. Patience!\n");
2550 return -EOPNOTSUPP;
2551 }
2552
2546 /* we should be getting 1 control message that the target is ready */ 2553 /* we should be getting 1 control message that the target is ready */
2547 packet = htc_wait_for_ctrl_msg(target); 2554 packet = htc_wait_for_ctrl_msg(target);
2548 2555
@@ -2772,7 +2779,9 @@ void ath6kl_htc_cleanup(struct htc_target *target)
2772{ 2779{
2773 struct htc_packet *packet, *tmp_packet; 2780 struct htc_packet *packet, *tmp_packet;
2774 2781
2775 ath6kl_hif_cleanup_scatter(target->dev->ar); 2782 /* FIXME: remove check once USB support is implemented */
2783 if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB)
2784 ath6kl_hif_cleanup_scatter(target->dev->ar);
2776 2785
2777 list_for_each_entry_safe(packet, tmp_packet, 2786 list_for_each_entry_safe(packet, tmp_packet,
2778 &target->free_ctrl_txbuf, list) { 2787 &target->free_ctrl_txbuf, list) {
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 7f55be3092d1..0d76c3778106 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -17,22 +17,16 @@
17 17
18#include <linux/moduleparam.h> 18#include <linux/moduleparam.h>
19#include <linux/errno.h> 19#include <linux/errno.h>
20#include <linux/export.h>
20#include <linux/of.h> 21#include <linux/of.h>
21#include <linux/mmc/sdio_func.h> 22#include <linux/mmc/sdio_func.h>
23
22#include "core.h" 24#include "core.h"
23#include "cfg80211.h" 25#include "cfg80211.h"
24#include "target.h" 26#include "target.h"
25#include "debug.h" 27#include "debug.h"
26#include "hif-ops.h" 28#include "hif-ops.h"
27 29
28unsigned int debug_mask;
29static unsigned int testmode;
30static bool suspend_cutpower;
31
32module_param(debug_mask, uint, 0644);
33module_param(testmode, uint, 0644);
34module_param(suspend_cutpower, bool, 0444);
35
36static const struct ath6kl_hw hw_list[] = { 30static const struct ath6kl_hw hw_list[] = {
37 { 31 {
38 .id = AR6003_HW_2_0_VERSION, 32 .id = AR6003_HW_2_0_VERSION,
@@ -47,11 +41,14 @@ static const struct ath6kl_hw hw_list[] = {
47 /* hw2.0 needs override address hardcoded */ 41 /* hw2.0 needs override address hardcoded */
48 .app_start_override_addr = 0x944C00, 42 .app_start_override_addr = 0x944C00,
49 43
50 .fw_otp = AR6003_HW_2_0_OTP_FILE, 44 .fw = {
51 .fw = AR6003_HW_2_0_FIRMWARE_FILE, 45 .dir = AR6003_HW_2_0_FW_DIR,
52 .fw_tcmd = AR6003_HW_2_0_TCMD_FIRMWARE_FILE, 46 .otp = AR6003_HW_2_0_OTP_FILE,
53 .fw_patch = AR6003_HW_2_0_PATCH_FILE, 47 .fw = AR6003_HW_2_0_FIRMWARE_FILE,
54 .fw_api2 = AR6003_HW_2_0_FIRMWARE_2_FILE, 48 .tcmd = AR6003_HW_2_0_TCMD_FIRMWARE_FILE,
49 .patch = AR6003_HW_2_0_PATCH_FILE,
50 },
51
55 .fw_board = AR6003_HW_2_0_BOARD_DATA_FILE, 52 .fw_board = AR6003_HW_2_0_BOARD_DATA_FILE,
56 .fw_default_board = AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE, 53 .fw_default_board = AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE,
57 }, 54 },
@@ -64,12 +61,18 @@ static const struct ath6kl_hw hw_list[] = {
64 .reserved_ram_size = 512, 61 .reserved_ram_size = 512,
65 .refclk_hz = 26000000, 62 .refclk_hz = 26000000,
66 .uarttx_pin = 8, 63 .uarttx_pin = 8,
64 .testscript_addr = 0x57ef74,
65
66 .fw = {
67 .dir = AR6003_HW_2_1_1_FW_DIR,
68 .otp = AR6003_HW_2_1_1_OTP_FILE,
69 .fw = AR6003_HW_2_1_1_FIRMWARE_FILE,
70 .tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE,
71 .patch = AR6003_HW_2_1_1_PATCH_FILE,
72 .utf = AR6003_HW_2_1_1_UTF_FIRMWARE_FILE,
73 .testscript = AR6003_HW_2_1_1_TESTSCRIPT_FILE,
74 },
67 75
68 .fw_otp = AR6003_HW_2_1_1_OTP_FILE,
69 .fw = AR6003_HW_2_1_1_FIRMWARE_FILE,
70 .fw_tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE,
71 .fw_patch = AR6003_HW_2_1_1_PATCH_FILE,
72 .fw_api2 = AR6003_HW_2_1_1_FIRMWARE_2_FILE,
73 .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE, 76 .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE,
74 .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE, 77 .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE,
75 }, 78 },
@@ -84,8 +87,11 @@ static const struct ath6kl_hw hw_list[] = {
84 .refclk_hz = 26000000, 87 .refclk_hz = 26000000,
85 .uarttx_pin = 11, 88 .uarttx_pin = 11,
86 89
87 .fw = AR6004_HW_1_0_FIRMWARE_FILE, 90 .fw = {
88 .fw_api2 = AR6004_HW_1_0_FIRMWARE_2_FILE, 91 .dir = AR6004_HW_1_0_FW_DIR,
92 .fw = AR6004_HW_1_0_FIRMWARE_FILE,
93 },
94
89 .fw_board = AR6004_HW_1_0_BOARD_DATA_FILE, 95 .fw_board = AR6004_HW_1_0_BOARD_DATA_FILE,
90 .fw_default_board = AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE, 96 .fw_default_board = AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE,
91 }, 97 },
@@ -100,8 +106,11 @@ static const struct ath6kl_hw hw_list[] = {
100 .refclk_hz = 40000000, 106 .refclk_hz = 40000000,
101 .uarttx_pin = 11, 107 .uarttx_pin = 11,
102 108
103 .fw = AR6004_HW_1_1_FIRMWARE_FILE, 109 .fw = {
104 .fw_api2 = AR6004_HW_1_1_FIRMWARE_2_FILE, 110 .dir = AR6004_HW_1_1_FW_DIR,
111 .fw = AR6004_HW_1_1_FIRMWARE_FILE,
112 },
113
105 .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE, 114 .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE,
106 .fw_default_board = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE, 115 .fw_default_board = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE,
107 }, 116 },
@@ -452,6 +461,13 @@ int ath6kl_configure_target(struct ath6kl *ar)
452 u8 fw_iftype, fw_mode = 0, fw_submode = 0; 461 u8 fw_iftype, fw_mode = 0, fw_submode = 0;
453 int i, status; 462 int i, status;
454 463
464 param = !!(ar->conf_flags & ATH6KL_CONF_UART_DEBUG);
465 if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
466 HI_ITEM(hi_serial_enable)), (u8 *)&param, 4)) {
467 ath6kl_err("bmi_write_memory for uart debug failed\n");
468 return -EIO;
469 }
470
455 /* 471 /*
456 * Note: Even though the firmware interface type is 472 * Note: Even though the firmware interface type is
457 * chosen as BSS_STA for all three interfaces, can 473 * chosen as BSS_STA for all three interfaces, can
@@ -573,36 +589,6 @@ int ath6kl_configure_target(struct ath6kl *ar)
573 return 0; 589 return 0;
574} 590}
575 591
576void ath6kl_core_free(struct ath6kl *ar)
577{
578 wiphy_free(ar->wiphy);
579}
580
581void ath6kl_core_cleanup(struct ath6kl *ar)
582{
583 ath6kl_hif_power_off(ar);
584
585 destroy_workqueue(ar->ath6kl_wq);
586
587 if (ar->htc_target)
588 ath6kl_htc_cleanup(ar->htc_target);
589
590 ath6kl_cookie_cleanup(ar);
591
592 ath6kl_cleanup_amsdu_rxbufs(ar);
593
594 ath6kl_bmi_cleanup(ar);
595
596 ath6kl_debug_cleanup(ar);
597
598 kfree(ar->fw_board);
599 kfree(ar->fw_otp);
600 kfree(ar->fw);
601 kfree(ar->fw_patch);
602
603 ath6kl_deinit_ieee80211_hw(ar);
604}
605
606/* firmware upload */ 592/* firmware upload */
607static int ath6kl_get_fw(struct ath6kl *ar, const char *filename, 593static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
608 u8 **fw, size_t *fw_len) 594 u8 **fw, size_t *fw_len)
@@ -626,21 +612,6 @@ static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
626} 612}
627 613
628#ifdef CONFIG_OF 614#ifdef CONFIG_OF
629static const char *get_target_ver_dir(const struct ath6kl *ar)
630{
631 switch (ar->version.target_ver) {
632 case AR6003_HW_1_0_VERSION:
633 return "ath6k/AR6003/hw1.0";
634 case AR6003_HW_2_0_VERSION:
635 return "ath6k/AR6003/hw2.0";
636 case AR6003_HW_2_1_1_VERSION:
637 return "ath6k/AR6003/hw2.1.1";
638 }
639 ath6kl_warn("%s: unsupported target version 0x%x.\n", __func__,
640 ar->version.target_ver);
641 return NULL;
642}
643
644/* 615/*
645 * Check the device tree for a board-id and use it to construct 616 * Check the device tree for a board-id and use it to construct
646 * the pathname to the firmware file. Used (for now) to find a 617 * the pathname to the firmware file. Used (for now) to find a
@@ -663,7 +634,7 @@ static bool check_device_tree(struct ath6kl *ar)
663 continue; 634 continue;
664 } 635 }
665 snprintf(board_filename, sizeof(board_filename), 636 snprintf(board_filename, sizeof(board_filename),
666 "%s/bdata.%s.bin", get_target_ver_dir(ar), board_id); 637 "%s/bdata.%s.bin", ar->hw.fw.dir, board_id);
667 638
668 ret = ath6kl_get_fw(ar, board_filename, &ar->fw_board, 639 ret = ath6kl_get_fw(ar, board_filename, &ar->fw_board,
669 &ar->fw_board_len); 640 &ar->fw_board_len);
@@ -730,19 +701,20 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar)
730 701
731static int ath6kl_fetch_otp_file(struct ath6kl *ar) 702static int ath6kl_fetch_otp_file(struct ath6kl *ar)
732{ 703{
733 const char *filename; 704 char filename[100];
734 int ret; 705 int ret;
735 706
736 if (ar->fw_otp != NULL) 707 if (ar->fw_otp != NULL)
737 return 0; 708 return 0;
738 709
739 if (ar->hw.fw_otp == NULL) { 710 if (ar->hw.fw.otp == NULL) {
740 ath6kl_dbg(ATH6KL_DBG_BOOT, 711 ath6kl_dbg(ATH6KL_DBG_BOOT,
741 "no OTP file configured for this hw\n"); 712 "no OTP file configured for this hw\n");
742 return 0; 713 return 0;
743 } 714 }
744 715
745 filename = ar->hw.fw_otp; 716 snprintf(filename, sizeof(filename), "%s/%s",
717 ar->hw.fw.dir, ar->hw.fw.otp);
746 718
747 ret = ath6kl_get_fw(ar, filename, &ar->fw_otp, 719 ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
748 &ar->fw_otp_len); 720 &ar->fw_otp_len);
@@ -755,33 +727,61 @@ static int ath6kl_fetch_otp_file(struct ath6kl *ar)
755 return 0; 727 return 0;
756} 728}
757 729
758static int ath6kl_fetch_fw_file(struct ath6kl *ar) 730static int ath6kl_fetch_testmode_file(struct ath6kl *ar)
759{ 731{
760 const char *filename; 732 char filename[100];
761 int ret; 733 int ret;
762 734
763 if (ar->fw != NULL) 735 if (ar->testmode == 0)
764 return 0; 736 return 0;
765 737
766 if (testmode) { 738 ath6kl_dbg(ATH6KL_DBG_BOOT, "testmode %d\n", ar->testmode);
767 if (ar->hw.fw_tcmd == NULL) { 739
768 ath6kl_warn("testmode not supported\n"); 740 if (ar->testmode == 2) {
741 if (ar->hw.fw.utf == NULL) {
742 ath6kl_warn("testmode 2 not supported\n");
743 return -EOPNOTSUPP;
744 }
745
746 snprintf(filename, sizeof(filename), "%s/%s",
747 ar->hw.fw.dir, ar->hw.fw.utf);
748 } else {
749 if (ar->hw.fw.tcmd == NULL) {
750 ath6kl_warn("testmode 1 not supported\n");
769 return -EOPNOTSUPP; 751 return -EOPNOTSUPP;
770 } 752 }
771 753
772 filename = ar->hw.fw_tcmd; 754 snprintf(filename, sizeof(filename), "%s/%s",
755 ar->hw.fw.dir, ar->hw.fw.tcmd);
756 }
773 757
774 set_bit(TESTMODE, &ar->flag); 758 set_bit(TESTMODE, &ar->flag);
775 759
776 goto get_fw; 760 ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
761 if (ret) {
762 ath6kl_err("Failed to get testmode %d firmware file %s: %d\n",
763 ar->testmode, filename, ret);
764 return ret;
777 } 765 }
778 766
779 if (WARN_ON(ar->hw.fw == NULL)) 767 return 0;
768}
769
770static int ath6kl_fetch_fw_file(struct ath6kl *ar)
771{
772 char filename[100];
773 int ret;
774
775 if (ar->fw != NULL)
776 return 0;
777
778 /* FIXME: remove WARN_ON() as we won't support FW API 1 for long */
779 if (WARN_ON(ar->hw.fw.fw == NULL))
780 return -EINVAL; 780 return -EINVAL;
781 781
782 filename = ar->hw.fw; 782 snprintf(filename, sizeof(filename), "%s/%s",
783 ar->hw.fw.dir, ar->hw.fw.fw);
783 784
784get_fw:
785 ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len); 785 ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
786 if (ret) { 786 if (ret) {
787 ath6kl_err("Failed to get firmware file %s: %d\n", 787 ath6kl_err("Failed to get firmware file %s: %d\n",
@@ -794,16 +794,17 @@ get_fw:
794 794
795static int ath6kl_fetch_patch_file(struct ath6kl *ar) 795static int ath6kl_fetch_patch_file(struct ath6kl *ar)
796{ 796{
797 const char *filename; 797 char filename[100];
798 int ret; 798 int ret;
799 799
800 if (ar->fw_patch != NULL) 800 if (ar->fw_patch != NULL)
801 return 0; 801 return 0;
802 802
803 if (ar->hw.fw_patch == NULL) 803 if (ar->hw.fw.patch == NULL)
804 return 0; 804 return 0;
805 805
806 filename = ar->hw.fw_patch; 806 snprintf(filename, sizeof(filename), "%s/%s",
807 ar->hw.fw.dir, ar->hw.fw.patch);
807 808
808 ret = ath6kl_get_fw(ar, filename, &ar->fw_patch, 809 ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
809 &ar->fw_patch_len); 810 &ar->fw_patch_len);
@@ -816,6 +817,34 @@ static int ath6kl_fetch_patch_file(struct ath6kl *ar)
816 return 0; 817 return 0;
817} 818}
818 819
820static int ath6kl_fetch_testscript_file(struct ath6kl *ar)
821{
822 char filename[100];
823 int ret;
824
825 if (ar->testmode != 2)
826 return 0;
827
828 if (ar->fw_testscript != NULL)
829 return 0;
830
831 if (ar->hw.fw.testscript == NULL)
832 return 0;
833
834 snprintf(filename, sizeof(filename), "%s/%s",
835 ar->hw.fw.dir, ar->hw.fw.testscript);
836
837 ret = ath6kl_get_fw(ar, filename, &ar->fw_testscript,
838 &ar->fw_testscript_len);
839 if (ret) {
840 ath6kl_err("Failed to get testscript file %s: %d\n",
841 filename, ret);
842 return ret;
843 }
844
845 return 0;
846}
847
819static int ath6kl_fetch_fw_api1(struct ath6kl *ar) 848static int ath6kl_fetch_fw_api1(struct ath6kl *ar)
820{ 849{
821 int ret; 850 int ret;
@@ -832,23 +861,24 @@ static int ath6kl_fetch_fw_api1(struct ath6kl *ar)
832 if (ret) 861 if (ret)
833 return ret; 862 return ret;
834 863
864 ret = ath6kl_fetch_testscript_file(ar);
865 if (ret)
866 return ret;
867
835 return 0; 868 return 0;
836} 869}
837 870
838static int ath6kl_fetch_fw_api2(struct ath6kl *ar) 871static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
839{ 872{
840 size_t magic_len, len, ie_len; 873 size_t magic_len, len, ie_len;
841 const struct firmware *fw; 874 const struct firmware *fw;
842 struct ath6kl_fw_ie *hdr; 875 struct ath6kl_fw_ie *hdr;
843 const char *filename; 876 char filename[100];
844 const u8 *data; 877 const u8 *data;
845 int ret, ie_id, i, index, bit; 878 int ret, ie_id, i, index, bit;
846 __le32 *val; 879 __le32 *val;
847 880
848 if (ar->hw.fw_api2 == NULL) 881 snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, name);
849 return -EOPNOTSUPP;
850
851 filename = ar->hw.fw_api2;
852 882
853 ret = request_firmware(&fw, filename, ar->dev); 883 ret = request_firmware(&fw, filename, ar->dev);
854 if (ret) 884 if (ret)
@@ -907,6 +937,10 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar)
907 ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n", 937 ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n",
908 ie_len); 938 ie_len);
909 939
940 /* in testmode we already might have a fw file */
941 if (ar->fw != NULL)
942 break;
943
910 ar->fw = kmemdup(data, ie_len, GFP_KERNEL); 944 ar->fw = kmemdup(data, ie_len, GFP_KERNEL);
911 945
912 if (ar->fw == NULL) { 946 if (ar->fw == NULL) {
@@ -1010,7 +1044,7 @@ out:
1010 return ret; 1044 return ret;
1011} 1045}
1012 1046
1013static int ath6kl_fetch_firmwares(struct ath6kl *ar) 1047int ath6kl_init_fetch_firmwares(struct ath6kl *ar)
1014{ 1048{
1015 int ret; 1049 int ret;
1016 1050
@@ -1018,17 +1052,30 @@ static int ath6kl_fetch_firmwares(struct ath6kl *ar)
1018 if (ret) 1052 if (ret)
1019 return ret; 1053 return ret;
1020 1054
1021 ret = ath6kl_fetch_fw_api2(ar); 1055 ret = ath6kl_fetch_testmode_file(ar);
1056 if (ret)
1057 return ret;
1058
1059 ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE);
1022 if (ret == 0) { 1060 if (ret == 0) {
1023 ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 2\n"); 1061 ar->fw_api = 3;
1024 return 0; 1062 goto out;
1063 }
1064
1065 ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API2_FILE);
1066 if (ret == 0) {
1067 ar->fw_api = 2;
1068 goto out;
1025 } 1069 }
1026 1070
1027 ret = ath6kl_fetch_fw_api1(ar); 1071 ret = ath6kl_fetch_fw_api1(ar);
1028 if (ret) 1072 if (ret)
1029 return ret; 1073 return ret;
1030 1074
1031 ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 1\n"); 1075 ar->fw_api = 1;
1076
1077out:
1078 ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api %d\n", ar->fw_api);
1032 1079
1033 return 0; 1080 return 0;
1034} 1081}
@@ -1249,6 +1296,50 @@ static int ath6kl_upload_patch(struct ath6kl *ar)
1249 return 0; 1296 return 0;
1250} 1297}
1251 1298
1299static int ath6kl_upload_testscript(struct ath6kl *ar)
1300{
1301 u32 address, param;
1302 int ret;
1303
1304 if (ar->testmode != 2)
1305 return 0;
1306
1307 if (ar->fw_testscript == NULL)
1308 return 0;
1309
1310 address = ar->hw.testscript_addr;
1311
1312 ath6kl_dbg(ATH6KL_DBG_BOOT, "writing testscript to 0x%x (%zd B)\n",
1313 address, ar->fw_testscript_len);
1314
1315 ret = ath6kl_bmi_write(ar, address, ar->fw_testscript,
1316 ar->fw_testscript_len);
1317 if (ret) {
1318 ath6kl_err("Failed to write testscript file: %d\n", ret);
1319 return ret;
1320 }
1321
1322 param = address;
1323 ath6kl_bmi_write(ar,
1324 ath6kl_get_hi_item_addr(ar,
1325 HI_ITEM(hi_ota_testscript)),
1326 (unsigned char *) &param, 4);
1327
1328 param = 4096;
1329 ath6kl_bmi_write(ar,
1330 ath6kl_get_hi_item_addr(ar,
1331 HI_ITEM(hi_end_ram_reserve_sz)),
1332 (unsigned char *) &param, 4);
1333
1334 param = 1;
1335 ath6kl_bmi_write(ar,
1336 ath6kl_get_hi_item_addr(ar,
1337 HI_ITEM(hi_test_apps_related)),
1338 (unsigned char *) &param, 4);
1339
1340 return 0;
1341}
1342
1252static int ath6kl_init_upload(struct ath6kl *ar) 1343static int ath6kl_init_upload(struct ath6kl *ar)
1253{ 1344{
1254 u32 param, options, sleep, address; 1345 u32 param, options, sleep, address;
@@ -1357,6 +1448,11 @@ static int ath6kl_init_upload(struct ath6kl *ar)
1357 if (status) 1448 if (status)
1358 return status; 1449 return status;
1359 1450
1451 /* Download the test script */
1452 status = ath6kl_upload_testscript(ar);
1453 if (status)
1454 return status;
1455
1360 /* Restore system sleep */ 1456 /* Restore system sleep */
1361 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS; 1457 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1362 status = ath6kl_bmi_reg_write(ar, address, sleep); 1458 status = ath6kl_bmi_reg_write(ar, address, sleep);
@@ -1372,9 +1468,9 @@ static int ath6kl_init_upload(struct ath6kl *ar)
1372 return status; 1468 return status;
1373} 1469}
1374 1470
1375static int ath6kl_init_hw_params(struct ath6kl *ar) 1471int ath6kl_init_hw_params(struct ath6kl *ar)
1376{ 1472{
1377 const struct ath6kl_hw *hw; 1473 const struct ath6kl_hw *uninitialized_var(hw);
1378 int i; 1474 int i;
1379 1475
1380 for (i = 0; i < ARRAY_SIZE(hw_list); i++) { 1476 for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
@@ -1481,10 +1577,11 @@ int ath6kl_init_hw_start(struct ath6kl *ar)
1481 1577
1482 1578
1483 if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) { 1579 if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) {
1484 ath6kl_info("%s %s fw %s%s\n", 1580 ath6kl_info("%s %s fw %s api %d%s\n",
1485 ar->hw.name, 1581 ar->hw.name,
1486 ath6kl_init_get_hif_name(ar->hif_type), 1582 ath6kl_init_get_hif_name(ar->hif_type),
1487 ar->wiphy->fw_version, 1583 ar->wiphy->fw_version,
1584 ar->fw_api,
1488 test_bit(TESTMODE, &ar->flag) ? " testmode" : ""); 1585 test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
1489 } 1586 }
1490 1587
@@ -1549,173 +1646,7 @@ int ath6kl_init_hw_stop(struct ath6kl *ar)
1549 return 0; 1646 return 0;
1550} 1647}
1551 1648
1552int ath6kl_core_init(struct ath6kl *ar) 1649/* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */
1553{
1554 struct ath6kl_bmi_target_info targ_info;
1555 struct net_device *ndev;
1556 int ret = 0, i;
1557
1558 ar->ath6kl_wq = create_singlethread_workqueue("ath6kl");
1559 if (!ar->ath6kl_wq)
1560 return -ENOMEM;
1561
1562 ret = ath6kl_bmi_init(ar);
1563 if (ret)
1564 goto err_wq;
1565
1566 /*
1567 * Turn on power to get hardware (target) version and leave power
1568 * on delibrately as we will boot the hardware anyway within few
1569 * seconds.
1570 */
1571 ret = ath6kl_hif_power_on(ar);
1572 if (ret)
1573 goto err_bmi_cleanup;
1574
1575 ret = ath6kl_bmi_get_target_info(ar, &targ_info);
1576 if (ret)
1577 goto err_power_off;
1578
1579 ar->version.target_ver = le32_to_cpu(targ_info.version);
1580 ar->target_type = le32_to_cpu(targ_info.type);
1581 ar->wiphy->hw_version = le32_to_cpu(targ_info.version);
1582
1583 ret = ath6kl_init_hw_params(ar);
1584 if (ret)
1585 goto err_power_off;
1586
1587 ar->htc_target = ath6kl_htc_create(ar);
1588
1589 if (!ar->htc_target) {
1590 ret = -ENOMEM;
1591 goto err_power_off;
1592 }
1593
1594 ret = ath6kl_fetch_firmwares(ar);
1595 if (ret)
1596 goto err_htc_cleanup;
1597
1598 /* FIXME: we should free all firmwares in the error cases below */
1599
1600 /* Indicate that WMI is enabled (although not ready yet) */
1601 set_bit(WMI_ENABLED, &ar->flag);
1602 ar->wmi = ath6kl_wmi_init(ar);
1603 if (!ar->wmi) {
1604 ath6kl_err("failed to initialize wmi\n");
1605 ret = -EIO;
1606 goto err_htc_cleanup;
1607 }
1608
1609 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
1610
1611 ret = ath6kl_register_ieee80211_hw(ar);
1612 if (ret)
1613 goto err_node_cleanup;
1614
1615 ret = ath6kl_debug_init(ar);
1616 if (ret) {
1617 wiphy_unregister(ar->wiphy);
1618 goto err_node_cleanup;
1619 }
1620
1621 for (i = 0; i < ar->vif_max; i++)
1622 ar->avail_idx_map |= BIT(i);
1623
1624 rtnl_lock();
1625
1626 /* Add an initial station interface */
1627 ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0,
1628 INFRA_NETWORK);
1629
1630 rtnl_unlock();
1631
1632 if (!ndev) {
1633 ath6kl_err("Failed to instantiate a network device\n");
1634 ret = -ENOMEM;
1635 wiphy_unregister(ar->wiphy);
1636 goto err_debug_init;
1637 }
1638
1639
1640 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
1641 __func__, ndev->name, ndev, ar);
1642
1643 /* setup access class priority mappings */
1644 ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */
1645 ar->ac_stream_pri_map[WMM_AC_BE] = 1;
1646 ar->ac_stream_pri_map[WMM_AC_VI] = 2;
1647 ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */
1648
1649 /* give our connected endpoints some buffers */
1650 ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep);
1651 ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]);
1652
1653 /* allocate some buffers that handle larger AMSDU frames */
1654 ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
1655
1656 ath6kl_cookie_init(ar);
1657
1658 ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
1659 ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
1660
1661 if (suspend_cutpower)
1662 ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER;
1663
1664 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
1665 WIPHY_FLAG_HAVE_AP_SME |
1666 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
1667 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
1668
1669 if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
1670 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
1671
1672 ar->wiphy->probe_resp_offload =
1673 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
1674 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
1675 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
1676 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
1677
1678 set_bit(FIRST_BOOT, &ar->flag);
1679
1680 ret = ath6kl_init_hw_start(ar);
1681 if (ret) {
1682 ath6kl_err("Failed to start hardware: %d\n", ret);
1683 goto err_rxbuf_cleanup;
1684 }
1685
1686 /*
1687 * Set mac address which is received in ready event
1688 * FIXME: Move to ath6kl_interface_add()
1689 */
1690 memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
1691
1692 return ret;
1693
1694err_rxbuf_cleanup:
1695 ath6kl_htc_flush_rx_buf(ar->htc_target);
1696 ath6kl_cleanup_amsdu_rxbufs(ar);
1697 rtnl_lock();
1698 ath6kl_deinit_if_data(netdev_priv(ndev));
1699 rtnl_unlock();
1700 wiphy_unregister(ar->wiphy);
1701err_debug_init:
1702 ath6kl_debug_cleanup(ar);
1703err_node_cleanup:
1704 ath6kl_wmi_shutdown(ar->wmi);
1705 clear_bit(WMI_ENABLED, &ar->flag);
1706 ar->wmi = NULL;
1707err_htc_cleanup:
1708 ath6kl_htc_cleanup(ar->htc_target);
1709err_power_off:
1710 ath6kl_hif_power_off(ar);
1711err_bmi_cleanup:
1712 ath6kl_bmi_cleanup(ar);
1713err_wq:
1714 destroy_workqueue(ar->ath6kl_wq);
1715
1716 return ret;
1717}
1718
1719void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) 1650void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
1720{ 1651{
1721 static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 1652 static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -1747,6 +1678,7 @@ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
1747void ath6kl_stop_txrx(struct ath6kl *ar) 1678void ath6kl_stop_txrx(struct ath6kl *ar)
1748{ 1679{
1749 struct ath6kl_vif *vif, *tmp_vif; 1680 struct ath6kl_vif *vif, *tmp_vif;
1681 int i;
1750 1682
1751 set_bit(DESTROY_IN_PROGRESS, &ar->flag); 1683 set_bit(DESTROY_IN_PROGRESS, &ar->flag);
1752 1684
@@ -1755,13 +1687,16 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
1755 return; 1687 return;
1756 } 1688 }
1757 1689
1690 for (i = 0; i < AP_MAX_NUM_STA; i++)
1691 aggr_reset_state(ar->sta_list[i].aggr_conn);
1692
1758 spin_lock_bh(&ar->list_lock); 1693 spin_lock_bh(&ar->list_lock);
1759 list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) { 1694 list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) {
1760 list_del(&vif->list); 1695 list_del(&vif->list);
1761 spin_unlock_bh(&ar->list_lock); 1696 spin_unlock_bh(&ar->list_lock);
1762 ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag)); 1697 ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
1763 rtnl_lock(); 1698 rtnl_lock();
1764 ath6kl_deinit_if_data(vif); 1699 ath6kl_cfg80211_vif_cleanup(vif);
1765 rtnl_unlock(); 1700 rtnl_unlock();
1766 spin_lock_bh(&ar->list_lock); 1701 spin_lock_bh(&ar->list_lock);
1767 } 1702 }
@@ -1796,3 +1731,4 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
1796 1731
1797 clear_bit(WLAN_ENABLED, &ar->flag); 1732 clear_bit(WLAN_ENABLED, &ar->flag);
1798} 1733}
1734EXPORT_SYMBOL(ath6kl_stop_txrx);
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index eea3c747653e..b96d01a7919b 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -52,9 +52,11 @@ struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid)
52 return conn; 52 return conn;
53} 53}
54 54
55static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie, 55static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid,
56 u8 ielen, u8 keymgmt, u8 ucipher, u8 auth) 56 u8 *wpaie, size_t ielen, u8 keymgmt,
57 u8 ucipher, u8 auth, u8 apsd_info)
57{ 58{
59 struct ath6kl *ar = vif->ar;
58 struct ath6kl_sta *sta; 60 struct ath6kl_sta *sta;
59 u8 free_slot; 61 u8 free_slot;
60 62
@@ -68,9 +70,11 @@ static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
68 sta->keymgmt = keymgmt; 70 sta->keymgmt = keymgmt;
69 sta->ucipher = ucipher; 71 sta->ucipher = ucipher;
70 sta->auth = auth; 72 sta->auth = auth;
73 sta->apsd_info = apsd_info;
71 74
72 ar->sta_list_index = ar->sta_list_index | (1 << free_slot); 75 ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
73 ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid); 76 ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid);
77 aggr_conn_init(vif, vif->aggr_cntxt, sta->aggr_conn);
74} 78}
75 79
76static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) 80static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
@@ -80,6 +84,7 @@ static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
80 /* empty the queued pkts in the PS queue if any */ 84 /* empty the queued pkts in the PS queue if any */
81 spin_lock_bh(&sta->psq_lock); 85 spin_lock_bh(&sta->psq_lock);
82 skb_queue_purge(&sta->psq); 86 skb_queue_purge(&sta->psq);
87 skb_queue_purge(&sta->apsdq);
83 spin_unlock_bh(&sta->psq_lock); 88 spin_unlock_bh(&sta->psq_lock);
84 89
85 memset(&ar->ap_stats.sta[sta->aid - 1], 0, 90 memset(&ar->ap_stats.sta[sta->aid - 1], 0,
@@ -90,7 +95,7 @@ static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
90 sta->sta_flags = 0; 95 sta->sta_flags = 0;
91 96
92 ar->sta_list_index = ar->sta_list_index & ~(1 << i); 97 ar->sta_list_index = ar->sta_list_index & ~(1 << i);
93 98 aggr_reset_state(sta->aggr_conn);
94} 99}
95 100
96static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason) 101static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason)
@@ -252,7 +257,7 @@ int ath6kl_read_fwlogs(struct ath6kl *ar)
252 struct ath6kl_dbglog_hdr debug_hdr; 257 struct ath6kl_dbglog_hdr debug_hdr;
253 struct ath6kl_dbglog_buf debug_buf; 258 struct ath6kl_dbglog_buf debug_buf;
254 u32 address, length, dropped, firstbuf, debug_hdr_addr; 259 u32 address, length, dropped, firstbuf, debug_hdr_addr;
255 int ret = 0, loop; 260 int ret, loop;
256 u8 *buf; 261 u8 *buf;
257 262
258 buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL); 263 buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL);
@@ -347,9 +352,6 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
347 case TARGET_TYPE_AR6004: 352 case TARGET_TYPE_AR6004:
348 address = AR6004_RESET_CONTROL_ADDRESS; 353 address = AR6004_RESET_CONTROL_ADDRESS;
349 break; 354 break;
350 default:
351 address = AR6003_RESET_CONTROL_ADDRESS;
352 break;
353 } 355 }
354 356
355 status = ath6kl_diag_write32(ar, address, data); 357 status = ath6kl_diag_write32(ar, address, data);
@@ -363,7 +365,7 @@ static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif)
363 u8 index; 365 u8 index;
364 u8 keyusage; 366 u8 keyusage;
365 367
366 for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) { 368 for (index = 0; index <= WMI_MAX_KEY_INDEX; index++) {
367 if (vif->wep_key_list[index].key_len) { 369 if (vif->wep_key_list[index].key_len) {
368 keyusage = GROUP_USAGE; 370 keyusage = GROUP_USAGE;
369 if (index == vif->def_txkey_index) 371 if (index == vif->def_txkey_index)
@@ -428,9 +430,8 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)
428 430
429void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, 431void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
430 u8 keymgmt, u8 ucipher, u8 auth, 432 u8 keymgmt, u8 ucipher, u8 auth,
431 u8 assoc_req_len, u8 *assoc_info) 433 u8 assoc_req_len, u8 *assoc_info, u8 apsd_info)
432{ 434{
433 struct ath6kl *ar = vif->ar;
434 u8 *ies = NULL, *wpa_ie = NULL, *pos; 435 u8 *ies = NULL, *wpa_ie = NULL, *pos;
435 size_t ies_len = 0; 436 size_t ies_len = 0;
436 struct station_info sinfo; 437 struct station_info sinfo;
@@ -484,9 +485,9 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
484 pos += 2 + pos[1]; 485 pos += 2 + pos[1];
485 } 486 }
486 487
487 ath6kl_add_new_sta(ar, mac_addr, aid, wpa_ie, 488 ath6kl_add_new_sta(vif, mac_addr, aid, wpa_ie,
488 wpa_ie ? 2 + wpa_ie[1] : 0, 489 wpa_ie ? 2 + wpa_ie[1] : 0,
489 keymgmt, ucipher, auth); 490 keymgmt, ucipher, auth, apsd_info);
490 491
491 /* send event to application */ 492 /* send event to application */
492 memset(&sinfo, 0, sizeof(sinfo)); 493 memset(&sinfo, 0, sizeof(sinfo));
@@ -587,10 +588,11 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
587 memcpy(vif->bssid, bssid, sizeof(vif->bssid)); 588 memcpy(vif->bssid, bssid, sizeof(vif->bssid));
588 vif->bss_ch = channel; 589 vif->bss_ch = channel;
589 590
590 if ((vif->nw_type == INFRA_NETWORK)) 591 if ((vif->nw_type == INFRA_NETWORK)) {
592 ar->listen_intvl_b = listen_int;
591 ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, 593 ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
592 ar->listen_intvl_t, 594 0, ar->listen_intvl_b);
593 ar->listen_intvl_b); 595 }
594 596
595 netif_wake_queue(vif->ndev); 597 netif_wake_queue(vif->ndev);
596 598
@@ -601,7 +603,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
601 netif_carrier_on(vif->ndev); 603 netif_carrier_on(vif->ndev);
602 spin_unlock_bh(&vif->if_lock); 604 spin_unlock_bh(&vif->if_lock);
603 605
604 aggr_reset_state(vif->aggr_cntxt); 606 aggr_reset_state(vif->aggr_cntxt->aggr_conn);
605 vif->reconnect_flag = 0; 607 vif->reconnect_flag = 0;
606 608
607 if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) { 609 if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) {
@@ -923,7 +925,7 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
923 assoc_resp_len, assoc_info, 925 assoc_resp_len, assoc_info,
924 prot_reason_status); 926 prot_reason_status);
925 927
926 aggr_reset_state(vif->aggr_cntxt); 928 aggr_reset_state(vif->aggr_cntxt->aggr_conn);
927 929
928 del_timer(&vif->disconnect_timer); 930 del_timer(&vif->disconnect_timer);
929 931
@@ -1020,11 +1022,155 @@ static struct net_device_stats *ath6kl_get_stats(struct net_device *dev)
1020 return &vif->net_stats; 1022 return &vif->net_stats;
1021} 1023}
1022 1024
1023static struct net_device_ops ath6kl_netdev_ops = { 1025static int ath6kl_set_features(struct net_device *dev,
1026 netdev_features_t features)
1027{
1028 struct ath6kl_vif *vif = netdev_priv(dev);
1029 struct ath6kl *ar = vif->ar;
1030 int err = 0;
1031
1032 if ((features & NETIF_F_RXCSUM) &&
1033 (ar->rx_meta_ver != WMI_META_VERSION_2)) {
1034 ar->rx_meta_ver = WMI_META_VERSION_2;
1035 err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,
1036 vif->fw_vif_idx,
1037 ar->rx_meta_ver, 0, 0);
1038 if (err) {
1039 dev->features = features & ~NETIF_F_RXCSUM;
1040 return err;
1041 }
1042 } else if (!(features & NETIF_F_RXCSUM) &&
1043 (ar->rx_meta_ver == WMI_META_VERSION_2)) {
1044 ar->rx_meta_ver = 0;
1045 err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,
1046 vif->fw_vif_idx,
1047 ar->rx_meta_ver, 0, 0);
1048 if (err) {
1049 dev->features = features | NETIF_F_RXCSUM;
1050 return err;
1051 }
1052
1053 }
1054
1055 return err;
1056}
1057
1058static void ath6kl_set_multicast_list(struct net_device *ndev)
1059{
1060 struct ath6kl_vif *vif = netdev_priv(ndev);
1061 bool mc_all_on = false, mc_all_off = false;
1062 int mc_count = netdev_mc_count(ndev);
1063 struct netdev_hw_addr *ha;
1064 bool found;
1065 struct ath6kl_mc_filter *mc_filter, *tmp;
1066 struct list_head mc_filter_new;
1067 int ret;
1068
1069 if (!test_bit(WMI_READY, &vif->ar->flag) ||
1070 !test_bit(WLAN_ENABLED, &vif->flags))
1071 return;
1072
1073 mc_all_on = !!(ndev->flags & IFF_PROMISC) ||
1074 !!(ndev->flags & IFF_ALLMULTI) ||
1075 !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST);
1076
1077 mc_all_off = !(ndev->flags & IFF_MULTICAST) || mc_count == 0;
1078
1079 if (mc_all_on || mc_all_off) {
1080 /* Enable/disable all multicast */
1081 ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n",
1082 mc_all_on ? "enabling" : "disabling");
1083 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx,
1084 mc_all_on);
1085 if (ret)
1086 ath6kl_warn("Failed to %s multicast receive\n",
1087 mc_all_on ? "enable" : "disable");
1088 return;
1089 }
1090
1091 list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
1092 found = false;
1093 netdev_for_each_mc_addr(ha, ndev) {
1094 if (memcmp(ha->addr, mc_filter->hw_addr,
1095 ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {
1096 found = true;
1097 break;
1098 }
1099 }
1100
1101 if (!found) {
1102 /*
1103 * Delete the filter which was previously set
1104 * but not in the new request.
1105 */
1106 ath6kl_dbg(ATH6KL_DBG_TRC,
1107 "Removing %pM from multicast filter\n",
1108 mc_filter->hw_addr);
1109 ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi,
1110 vif->fw_vif_idx, mc_filter->hw_addr,
1111 false);
1112 if (ret) {
1113 ath6kl_warn("Failed to remove multicast filter:%pM\n",
1114 mc_filter->hw_addr);
1115 return;
1116 }
1117
1118 list_del(&mc_filter->list);
1119 kfree(mc_filter);
1120 }
1121 }
1122
1123 INIT_LIST_HEAD(&mc_filter_new);
1124
1125 netdev_for_each_mc_addr(ha, ndev) {
1126 found = false;
1127 list_for_each_entry(mc_filter, &vif->mc_filter, list) {
1128 if (memcmp(ha->addr, mc_filter->hw_addr,
1129 ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {
1130 found = true;
1131 break;
1132 }
1133 }
1134
1135 if (!found) {
1136 mc_filter = kzalloc(sizeof(struct ath6kl_mc_filter),
1137 GFP_ATOMIC);
1138 if (!mc_filter) {
1139 WARN_ON(1);
1140 goto out;
1141 }
1142
1143 memcpy(mc_filter->hw_addr, ha->addr,
1144 ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE);
1145 /* Set the multicast filter */
1146 ath6kl_dbg(ATH6KL_DBG_TRC,
1147 "Adding %pM to multicast filter list\n",
1148 mc_filter->hw_addr);
1149 ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi,
1150 vif->fw_vif_idx, mc_filter->hw_addr,
1151 true);
1152 if (ret) {
1153 ath6kl_warn("Failed to add multicast filter :%pM\n",
1154 mc_filter->hw_addr);
1155 kfree(mc_filter);
1156 goto out;
1157 }
1158
1159 list_add_tail(&mc_filter->list, &mc_filter_new);
1160 }
1161 }
1162
1163out:
1164 list_splice_tail(&mc_filter_new, &vif->mc_filter);
1165}
1166
1167static const struct net_device_ops ath6kl_netdev_ops = {
1024 .ndo_open = ath6kl_open, 1168 .ndo_open = ath6kl_open,
1025 .ndo_stop = ath6kl_close, 1169 .ndo_stop = ath6kl_close,
1026 .ndo_start_xmit = ath6kl_data_tx, 1170 .ndo_start_xmit = ath6kl_data_tx,
1027 .ndo_get_stats = ath6kl_get_stats, 1171 .ndo_get_stats = ath6kl_get_stats,
1172 .ndo_set_features = ath6kl_set_features,
1173 .ndo_set_rx_mode = ath6kl_set_multicast_list,
1028}; 1174};
1029 1175
1030void init_netdev(struct net_device *dev) 1176void init_netdev(struct net_device *dev)
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 9475e2d0d0b7..4febee723495 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -49,11 +49,13 @@ struct ath6kl_sdio {
49 /* scatter request list head */ 49 /* scatter request list head */
50 struct list_head scat_req; 50 struct list_head scat_req;
51 51
52 /* Avoids disabling irq while the interrupts being handled */
53 struct mutex mtx_irq;
54
52 spinlock_t scat_lock; 55 spinlock_t scat_lock;
53 bool scatter_enabled; 56 bool scatter_enabled;
54 57
55 bool is_disabled; 58 bool is_disabled;
56 atomic_t irq_handling;
57 const struct sdio_device_id *id; 59 const struct sdio_device_id *id;
58 struct work_struct wr_async_work; 60 struct work_struct wr_async_work;
59 struct list_head wr_asyncq; 61 struct list_head wr_asyncq;
@@ -460,8 +462,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
460 ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n"); 462 ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n");
461 463
462 ar_sdio = sdio_get_drvdata(func); 464 ar_sdio = sdio_get_drvdata(func);
463 atomic_set(&ar_sdio->irq_handling, 1); 465 mutex_lock(&ar_sdio->mtx_irq);
464
465 /* 466 /*
466 * Release the host during interrups so we can pick it back up when 467 * Release the host during interrups so we can pick it back up when
467 * we process commands. 468 * we process commands.
@@ -470,7 +471,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
470 471
471 status = ath6kl_hif_intr_bh_handler(ar_sdio->ar); 472 status = ath6kl_hif_intr_bh_handler(ar_sdio->ar);
472 sdio_claim_host(ar_sdio->func); 473 sdio_claim_host(ar_sdio->func);
473 atomic_set(&ar_sdio->irq_handling, 0); 474 mutex_unlock(&ar_sdio->mtx_irq);
474 WARN_ON(status && status != -ECANCELED); 475 WARN_ON(status && status != -ECANCELED);
475} 476}
476 477
@@ -578,17 +579,14 @@ static void ath6kl_sdio_irq_disable(struct ath6kl *ar)
578 579
579 sdio_claim_host(ar_sdio->func); 580 sdio_claim_host(ar_sdio->func);
580 581
581 /* Mask our function IRQ */ 582 mutex_lock(&ar_sdio->mtx_irq);
582 while (atomic_read(&ar_sdio->irq_handling)) {
583 sdio_release_host(ar_sdio->func);
584 schedule_timeout(HZ / 10);
585 sdio_claim_host(ar_sdio->func);
586 }
587 583
588 ret = sdio_release_irq(ar_sdio->func); 584 ret = sdio_release_irq(ar_sdio->func);
589 if (ret) 585 if (ret)
590 ath6kl_err("Failed to release sdio irq: %d\n", ret); 586 ath6kl_err("Failed to release sdio irq: %d\n", ret);
591 587
588 mutex_unlock(&ar_sdio->mtx_irq);
589
592 sdio_release_host(ar_sdio->func); 590 sdio_release_host(ar_sdio->func);
593} 591}
594 592
@@ -772,7 +770,6 @@ static int ath6kl_sdio_config(struct ath6kl *ar)
772 if (ret) { 770 if (ret) {
773 ath6kl_err("Set sdio block size %d failed: %d)\n", 771 ath6kl_err("Set sdio block size %d failed: %d)\n",
774 HIF_MBOX_BLOCK_SIZE, ret); 772 HIF_MBOX_BLOCK_SIZE, ret);
775 sdio_release_host(func);
776 goto out; 773 goto out;
777 } 774 }
778 775
@@ -782,7 +779,7 @@ out:
782 return ret; 779 return ret;
783} 780}
784 781
785static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) 782static int ath6kl_set_sdio_pm_caps(struct ath6kl *ar)
786{ 783{
787 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); 784 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
788 struct sdio_func *func = ar_sdio->func; 785 struct sdio_func *func = ar_sdio->func;
@@ -793,60 +790,95 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
793 790
794 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio suspend pm_caps 0x%x\n", flags); 791 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio suspend pm_caps 0x%x\n", flags);
795 792
796 if (!(flags & MMC_PM_KEEP_POWER) || 793 if (!(flags & MMC_PM_WAKE_SDIO_IRQ) ||
797 (ar->conf_flags & ATH6KL_CONF_SUSPEND_CUTPOWER)) { 794 !(flags & MMC_PM_KEEP_POWER))
798 /* as host doesn't support keep power we need to cut power */ 795 return -EINVAL;
799 return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER,
800 NULL);
801 }
802 796
803 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); 797 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
804 if (ret) { 798 if (ret) {
805 printk(KERN_ERR "ath6kl: set sdio pm flags failed: %d\n", 799 ath6kl_err("set sdio keep pwr flag failed: %d\n", ret);
806 ret);
807 return ret; 800 return ret;
808 } 801 }
809 802
810 if (!(flags & MMC_PM_WAKE_SDIO_IRQ))
811 goto deepsleep;
812
813 /* sdio irq wakes up host */ 803 /* sdio irq wakes up host */
804 ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
805 if (ret)
806 ath6kl_err("set sdio wake irq flag failed: %d\n", ret);
807
808 return ret;
809}
810
811static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
812{
813 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
814 struct sdio_func *func = ar_sdio->func;
815 mmc_pm_flag_t flags;
816 int ret;
814 817
815 if (ar->state == ATH6KL_STATE_SCHED_SCAN) { 818 if (ar->state == ATH6KL_STATE_SCHED_SCAN) {
819 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sched scan is in progress\n");
820
821 ret = ath6kl_set_sdio_pm_caps(ar);
822 if (ret)
823 goto cut_pwr;
824
816 ret = ath6kl_cfg80211_suspend(ar, 825 ret = ath6kl_cfg80211_suspend(ar,
817 ATH6KL_CFG_SUSPEND_SCHED_SCAN, 826 ATH6KL_CFG_SUSPEND_SCHED_SCAN,
818 NULL); 827 NULL);
819 if (ret) { 828 if (ret)
820 ath6kl_warn("Schedule scan suspend failed: %d", ret); 829 goto cut_pwr;
821 return ret; 830
822 } 831 return 0;
832 }
833
834 if (ar->suspend_mode == WLAN_POWER_STATE_WOW ||
835 (!ar->suspend_mode && wow)) {
823 836
824 ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); 837 ret = ath6kl_set_sdio_pm_caps(ar);
825 if (ret) 838 if (ret)
826 ath6kl_warn("set sdio wake irq flag failed: %d\n", ret); 839 goto cut_pwr;
827 840
828 return ret; 841 ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow);
842 if (ret)
843 goto cut_pwr;
844
845 return 0;
829 } 846 }
830 847
831 if (wow) { 848 if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP ||
849 !ar->suspend_mode) {
850
851 flags = sdio_get_host_pm_caps(func);
852 if (!(flags & MMC_PM_KEEP_POWER))
853 goto cut_pwr;
854
855 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
856 if (ret)
857 goto cut_pwr;
858
832 /* 859 /*
833 * The host sdio controller is capable of keep power and 860 * Workaround to support Deep Sleep with MSM, set the host pm
834 * sdio irq wake up at this point. It's fine to continue 861 * flag as MMC_PM_WAKE_SDIO_IRQ to allow SDCC deiver to disable
835 * wow suspend operation. 862 * the sdc2_clock and internally allows MSM to enter
863 * TCXO shutdown properly.
836 */ 864 */
837 ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow); 865 if ((flags & MMC_PM_WAKE_SDIO_IRQ)) {
838 if (ret) 866 ret = sdio_set_host_pm_flags(func,
839 return ret; 867 MMC_PM_WAKE_SDIO_IRQ);
868 if (ret)
869 goto cut_pwr;
870 }
840 871
841 ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); 872 ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP,
873 NULL);
842 if (ret) 874 if (ret)
843 ath6kl_err("set sdio wake irq flag failed: %d\n", ret); 875 goto cut_pwr;
844 876
845 return ret; 877 return 0;
846 } 878 }
847 879
848deepsleep: 880cut_pwr:
849 return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, NULL); 881 return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL);
850} 882}
851 883
852static int ath6kl_sdio_resume(struct ath6kl *ar) 884static int ath6kl_sdio_resume(struct ath6kl *ar)
@@ -1253,6 +1285,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
1253 spin_lock_init(&ar_sdio->scat_lock); 1285 spin_lock_init(&ar_sdio->scat_lock);
1254 spin_lock_init(&ar_sdio->wr_async_lock); 1286 spin_lock_init(&ar_sdio->wr_async_lock);
1255 mutex_init(&ar_sdio->dma_buffer_mutex); 1287 mutex_init(&ar_sdio->dma_buffer_mutex);
1288 mutex_init(&ar_sdio->mtx_irq);
1256 1289
1257 INIT_LIST_HEAD(&ar_sdio->scat_req); 1290 INIT_LIST_HEAD(&ar_sdio->scat_req);
1258 INIT_LIST_HEAD(&ar_sdio->bus_req_freeq); 1291 INIT_LIST_HEAD(&ar_sdio->bus_req_freeq);
@@ -1263,7 +1296,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
1263 for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) 1296 for (count = 0; count < BUS_REQUEST_MAX_NUM; count++)
1264 ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]); 1297 ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]);
1265 1298
1266 ar = ath6kl_core_alloc(&ar_sdio->func->dev); 1299 ar = ath6kl_core_create(&ar_sdio->func->dev);
1267 if (!ar) { 1300 if (!ar) {
1268 ath6kl_err("Failed to alloc ath6kl core\n"); 1301 ath6kl_err("Failed to alloc ath6kl core\n");
1269 ret = -ENOMEM; 1302 ret = -ENOMEM;
@@ -1293,7 +1326,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
1293 return ret; 1326 return ret;
1294 1327
1295err_core_alloc: 1328err_core_alloc:
1296 ath6kl_core_free(ar_sdio->ar); 1329 ath6kl_core_destroy(ar_sdio->ar);
1297err_dma: 1330err_dma:
1298 kfree(ar_sdio->dma_buffer); 1331 kfree(ar_sdio->dma_buffer);
1299err_hif: 1332err_hif:
@@ -1316,6 +1349,7 @@ static void ath6kl_sdio_remove(struct sdio_func *func)
1316 cancel_work_sync(&ar_sdio->wr_async_work); 1349 cancel_work_sync(&ar_sdio->wr_async_work);
1317 1350
1318 ath6kl_core_cleanup(ar_sdio->ar); 1351 ath6kl_core_cleanup(ar_sdio->ar);
1352 ath6kl_core_destroy(ar_sdio->ar);
1319 1353
1320 kfree(ar_sdio->dma_buffer); 1354 kfree(ar_sdio->dma_buffer);
1321 kfree(ar_sdio); 1355 kfree(ar_sdio);
@@ -1332,7 +1366,7 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = {
1332MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices); 1366MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices);
1333 1367
1334static struct sdio_driver ath6kl_sdio_driver = { 1368static struct sdio_driver ath6kl_sdio_driver = {
1335 .name = "ath6kl", 1369 .name = "ath6kl_sdio",
1336 .id_table = ath6kl_sdio_devices, 1370 .id_table = ath6kl_sdio_devices,
1337 .probe = ath6kl_sdio_probe, 1371 .probe = ath6kl_sdio_probe,
1338 .remove = ath6kl_sdio_remove, 1372 .remove = ath6kl_sdio_remove,
@@ -1362,19 +1396,19 @@ MODULE_AUTHOR("Atheros Communications, Inc.");
1362MODULE_DESCRIPTION("Driver support for Atheros AR600x SDIO devices"); 1396MODULE_DESCRIPTION("Driver support for Atheros AR600x SDIO devices");
1363MODULE_LICENSE("Dual BSD/GPL"); 1397MODULE_LICENSE("Dual BSD/GPL");
1364 1398
1365MODULE_FIRMWARE(AR6003_HW_2_0_OTP_FILE); 1399MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_OTP_FILE);
1366MODULE_FIRMWARE(AR6003_HW_2_0_FIRMWARE_FILE); 1400MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_FIRMWARE_FILE);
1367MODULE_FIRMWARE(AR6003_HW_2_0_PATCH_FILE); 1401MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_PATCH_FILE);
1368MODULE_FIRMWARE(AR6003_HW_2_0_BOARD_DATA_FILE); 1402MODULE_FIRMWARE(AR6003_HW_2_0_BOARD_DATA_FILE);
1369MODULE_FIRMWARE(AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE); 1403MODULE_FIRMWARE(AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE);
1370MODULE_FIRMWARE(AR6003_HW_2_1_1_OTP_FILE); 1404MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_OTP_FILE);
1371MODULE_FIRMWARE(AR6003_HW_2_1_1_FIRMWARE_FILE); 1405MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_FIRMWARE_FILE);
1372MODULE_FIRMWARE(AR6003_HW_2_1_1_PATCH_FILE); 1406MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_PATCH_FILE);
1373MODULE_FIRMWARE(AR6003_HW_2_1_1_BOARD_DATA_FILE); 1407MODULE_FIRMWARE(AR6003_HW_2_1_1_BOARD_DATA_FILE);
1374MODULE_FIRMWARE(AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE); 1408MODULE_FIRMWARE(AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE);
1375MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE); 1409MODULE_FIRMWARE(AR6004_HW_1_0_FW_DIR "/" AR6004_HW_1_0_FIRMWARE_FILE);
1376MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE); 1410MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE);
1377MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); 1411MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
1378MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); 1412MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE);
1379MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); 1413MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
1380MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); 1414MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c
index 381eb66a605f..f0cd61d6188a 100644
--- a/drivers/net/wireless/ath/ath6kl/testmode.c
+++ b/drivers/net/wireless/ath/ath6kl/testmode.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include "testmode.h" 17#include "testmode.h"
18#include "debug.h"
18 19
19#include <net/netlink.h> 20#include <net/netlink.h>
20 21
@@ -30,7 +31,7 @@ enum ath6kl_tm_attr {
30 31
31enum ath6kl_tm_cmd { 32enum ath6kl_tm_cmd {
32 ATH6KL_TM_CMD_TCMD = 0, 33 ATH6KL_TM_CMD_TCMD = 0,
33 ATH6KL_TM_CMD_RX_REPORT = 1, 34 ATH6KL_TM_CMD_RX_REPORT = 1, /* not used anymore */
34}; 35};
35 36
36#define ATH6KL_TM_DATA_MAX_LEN 5000 37#define ATH6KL_TM_DATA_MAX_LEN 5000
@@ -41,84 +42,33 @@ static const struct nla_policy ath6kl_tm_policy[ATH6KL_TM_ATTR_MAX + 1] = {
41 .len = ATH6KL_TM_DATA_MAX_LEN }, 42 .len = ATH6KL_TM_DATA_MAX_LEN },
42}; 43};
43 44
44void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len) 45void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len)
45{ 46{
46 if (down_interruptible(&ar->sem)) 47 struct sk_buff *skb;
47 return;
48
49 kfree(ar->tm.rx_report);
50
51 ar->tm.rx_report = kmemdup(buf, buf_len, GFP_KERNEL);
52 ar->tm.rx_report_len = buf_len;
53
54 up(&ar->sem);
55
56 wake_up(&ar->event_wq);
57}
58
59static int ath6kl_tm_rx_report(struct ath6kl *ar, void *buf, size_t buf_len,
60 struct sk_buff *skb)
61{
62 int ret = 0;
63 long left;
64
65 if (down_interruptible(&ar->sem))
66 return -ERESTARTSYS;
67
68 if (!test_bit(WMI_READY, &ar->flag)) {
69 ret = -EIO;
70 goto out;
71 }
72
73 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
74 ret = -EBUSY;
75 goto out;
76 }
77
78 if (ath6kl_wmi_test_cmd(ar->wmi, buf, buf_len) < 0) {
79 up(&ar->sem);
80 return -EIO;
81 }
82
83 left = wait_event_interruptible_timeout(ar->event_wq,
84 ar->tm.rx_report != NULL,
85 WMI_TIMEOUT);
86 48
87 if (left == 0) { 49 if (!buf || buf_len == 0)
88 ret = -ETIMEDOUT; 50 return;
89 goto out;
90 } else if (left < 0) {
91 ret = left;
92 goto out;
93 }
94 51
95 if (ar->tm.rx_report == NULL || ar->tm.rx_report_len == 0) { 52 skb = cfg80211_testmode_alloc_event_skb(ar->wiphy, buf_len, GFP_KERNEL);
96 ret = -EINVAL; 53 if (!skb) {
97 goto out; 54 ath6kl_warn("failed to allocate testmode rx skb!\n");
55 return;
98 } 56 }
99 57 NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD);
100 NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, ar->tm.rx_report_len, 58 NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf);
101 ar->tm.rx_report); 59 cfg80211_testmode_event(skb, GFP_KERNEL);
102 60 return;
103 kfree(ar->tm.rx_report);
104 ar->tm.rx_report = NULL;
105
106out:
107 up(&ar->sem);
108
109 return ret;
110 61
111nla_put_failure: 62nla_put_failure:
112 ret = -ENOBUFS; 63 kfree_skb(skb);
113 goto out; 64 ath6kl_warn("nla_put failed on testmode rx skb!\n");
114} 65}
115 66
116int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len) 67int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
117{ 68{
118 struct ath6kl *ar = wiphy_priv(wiphy); 69 struct ath6kl *ar = wiphy_priv(wiphy);
119 struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1]; 70 struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1];
120 int err, buf_len, reply_len; 71 int err, buf_len;
121 struct sk_buff *skb;
122 void *buf; 72 void *buf;
123 73
124 err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len, 74 err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len,
@@ -143,24 +93,6 @@ int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
143 93
144 break; 94 break;
145 case ATH6KL_TM_CMD_RX_REPORT: 95 case ATH6KL_TM_CMD_RX_REPORT:
146 if (!tb[ATH6KL_TM_ATTR_DATA])
147 return -EINVAL;
148
149 buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]);
150 buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]);
151
152 reply_len = nla_total_size(ATH6KL_TM_DATA_MAX_LEN);
153 skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len);
154 if (!skb)
155 return -ENOMEM;
156
157 err = ath6kl_tm_rx_report(ar, buf, buf_len, skb);
158 if (err < 0) {
159 kfree_skb(skb);
160 return err;
161 }
162
163 return cfg80211_testmode_reply(skb);
164 default: 96 default:
165 return -EOPNOTSUPP; 97 return -EOPNOTSUPP;
166 } 98 }
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.h b/drivers/net/wireless/ath/ath6kl/testmode.h
index 43dffcc11fb1..7fd47a62d078 100644
--- a/drivers/net/wireless/ath/ath6kl/testmode.h
+++ b/drivers/net/wireless/ath/ath6kl/testmode.h
@@ -18,13 +18,13 @@
18 18
19#ifdef CONFIG_NL80211_TESTMODE 19#ifdef CONFIG_NL80211_TESTMODE
20 20
21void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len); 21void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len);
22int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len); 22int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len);
23 23
24#else 24#else
25 25
26static inline void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, 26static inline void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf,
27 size_t buf_len) 27 size_t buf_len)
28{ 28{
29} 29}
30 30
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 506a3031a885..a3dc6943c7f7 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -17,6 +17,23 @@
17#include "core.h" 17#include "core.h"
18#include "debug.h" 18#include "debug.h"
19 19
20/*
21 * tid - tid_mux0..tid_mux3
22 * aid - tid_mux4..tid_mux7
23 */
24#define ATH6KL_TID_MASK 0xf
25#define ATH6KL_AID_SHIFT 4
26
27static inline u8 ath6kl_get_tid(u8 tid_mux)
28{
29 return tid_mux & ATH6KL_TID_MASK;
30}
31
32static inline u8 ath6kl_get_aid(u8 tid_mux)
33{
34 return tid_mux >> ATH6KL_AID_SHIFT;
35}
36
20static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, 37static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev,
21 u32 *map_no) 38 u32 *map_no)
22{ 39{
@@ -77,12 +94,118 @@ static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev,
77 return ar->node_map[ep_map].ep_id; 94 return ar->node_map[ep_map].ep_id;
78} 95}
79 96
97static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn,
98 struct ath6kl_vif *vif,
99 struct sk_buff *skb,
100 u32 *flags)
101{
102 struct ath6kl *ar = vif->ar;
103 bool is_apsdq_empty = false;
104 struct ethhdr *datap = (struct ethhdr *) skb->data;
105 u8 up = 0, traffic_class, *ip_hdr;
106 u16 ether_type;
107 struct ath6kl_llc_snap_hdr *llc_hdr;
108
109 if (conn->sta_flags & STA_PS_APSD_TRIGGER) {
110 /*
111 * This tx is because of a uAPSD trigger, determine
112 * more and EOSP bit. Set EOSP if queue is empty
113 * or sufficient frames are delivered for this trigger.
114 */
115 spin_lock_bh(&conn->psq_lock);
116 if (!skb_queue_empty(&conn->apsdq))
117 *flags |= WMI_DATA_HDR_FLAGS_MORE;
118 else if (conn->sta_flags & STA_PS_APSD_EOSP)
119 *flags |= WMI_DATA_HDR_FLAGS_EOSP;
120 *flags |= WMI_DATA_HDR_FLAGS_UAPSD;
121 spin_unlock_bh(&conn->psq_lock);
122 return false;
123 } else if (!conn->apsd_info)
124 return false;
125
126 if (test_bit(WMM_ENABLED, &vif->flags)) {
127 ether_type = be16_to_cpu(datap->h_proto);
128 if (is_ethertype(ether_type)) {
129 /* packet is in DIX format */
130 ip_hdr = (u8 *)(datap + 1);
131 } else {
132 /* packet is in 802.3 format */
133 llc_hdr = (struct ath6kl_llc_snap_hdr *)
134 (datap + 1);
135 ether_type = be16_to_cpu(llc_hdr->eth_type);
136 ip_hdr = (u8 *)(llc_hdr + 1);
137 }
138
139 if (ether_type == IP_ETHERTYPE)
140 up = ath6kl_wmi_determine_user_priority(
141 ip_hdr, 0);
142 }
143
144 traffic_class = ath6kl_wmi_get_traffic_class(up);
145
146 if ((conn->apsd_info & (1 << traffic_class)) == 0)
147 return false;
148
149 /* Queue the frames if the STA is sleeping */
150 spin_lock_bh(&conn->psq_lock);
151 is_apsdq_empty = skb_queue_empty(&conn->apsdq);
152 skb_queue_tail(&conn->apsdq, skb);
153 spin_unlock_bh(&conn->psq_lock);
154
155 /*
156 * If this is the first pkt getting queued
157 * for this STA, update the PVB for this STA
158 */
159 if (is_apsdq_empty) {
160 ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
161 vif->fw_vif_idx,
162 conn->aid, 1, 0);
163 }
164 *flags |= WMI_DATA_HDR_FLAGS_UAPSD;
165
166 return true;
167}
168
169static bool ath6kl_process_psq(struct ath6kl_sta *conn,
170 struct ath6kl_vif *vif,
171 struct sk_buff *skb,
172 u32 *flags)
173{
174 bool is_psq_empty = false;
175 struct ath6kl *ar = vif->ar;
176
177 if (conn->sta_flags & STA_PS_POLLED) {
178 spin_lock_bh(&conn->psq_lock);
179 if (!skb_queue_empty(&conn->psq))
180 *flags |= WMI_DATA_HDR_FLAGS_MORE;
181 spin_unlock_bh(&conn->psq_lock);
182 return false;
183 }
184
185 /* Queue the frames if the STA is sleeping */
186 spin_lock_bh(&conn->psq_lock);
187 is_psq_empty = skb_queue_empty(&conn->psq);
188 skb_queue_tail(&conn->psq, skb);
189 spin_unlock_bh(&conn->psq_lock);
190
191 /*
192 * If this is the first pkt getting queued
193 * for this STA, update the PVB for this
194 * STA.
195 */
196 if (is_psq_empty)
197 ath6kl_wmi_set_pvb_cmd(ar->wmi,
198 vif->fw_vif_idx,
199 conn->aid, 1);
200 return true;
201}
202
80static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb, 203static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb,
81 bool *more_data) 204 u32 *flags)
82{ 205{
83 struct ethhdr *datap = (struct ethhdr *) skb->data; 206 struct ethhdr *datap = (struct ethhdr *) skb->data;
84 struct ath6kl_sta *conn = NULL; 207 struct ath6kl_sta *conn = NULL;
85 bool ps_queued = false, is_psq_empty = false; 208 bool ps_queued = false;
86 struct ath6kl *ar = vif->ar; 209 struct ath6kl *ar = vif->ar;
87 210
88 if (is_multicast_ether_addr(datap->h_dest)) { 211 if (is_multicast_ether_addr(datap->h_dest)) {
@@ -128,7 +251,7 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb,
128 */ 251 */
129 spin_lock_bh(&ar->mcastpsq_lock); 252 spin_lock_bh(&ar->mcastpsq_lock);
130 if (!skb_queue_empty(&ar->mcastpsq)) 253 if (!skb_queue_empty(&ar->mcastpsq))
131 *more_data = true; 254 *flags |= WMI_DATA_HDR_FLAGS_MORE;
132 spin_unlock_bh(&ar->mcastpsq_lock); 255 spin_unlock_bh(&ar->mcastpsq_lock);
133 } 256 }
134 } 257 }
@@ -142,37 +265,13 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb,
142 } 265 }
143 266
144 if (conn->sta_flags & STA_PS_SLEEP) { 267 if (conn->sta_flags & STA_PS_SLEEP) {
145 if (!(conn->sta_flags & STA_PS_POLLED)) { 268 ps_queued = ath6kl_process_uapsdq(conn,
146 /* Queue the frames if the STA is sleeping */ 269 vif, skb, flags);
147 spin_lock_bh(&conn->psq_lock); 270 if (!(*flags & WMI_DATA_HDR_FLAGS_UAPSD))
148 is_psq_empty = skb_queue_empty(&conn->psq); 271 ps_queued = ath6kl_process_psq(conn,
149 skb_queue_tail(&conn->psq, skb); 272 vif, skb, flags);
150 spin_unlock_bh(&conn->psq_lock);
151
152 /*
153 * If this is the first pkt getting queued
154 * for this STA, update the PVB for this
155 * STA.
156 */
157 if (is_psq_empty)
158 ath6kl_wmi_set_pvb_cmd(ar->wmi,
159 vif->fw_vif_idx,
160 conn->aid, 1);
161
162 ps_queued = true;
163 } else {
164 /*
165 * This tx is because of a PsPoll.
166 * Determine if MoreData bit has to be set.
167 */
168 spin_lock_bh(&conn->psq_lock);
169 if (!skb_queue_empty(&conn->psq))
170 *more_data = true;
171 spin_unlock_bh(&conn->psq_lock);
172 }
173 } 273 }
174 } 274 }
175
176 return ps_queued; 275 return ps_queued;
177} 276}
178 277
@@ -242,8 +341,13 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
242 u32 map_no = 0; 341 u32 map_no = 0;
243 u16 htc_tag = ATH6KL_DATA_PKT_TAG; 342 u16 htc_tag = ATH6KL_DATA_PKT_TAG;
244 u8 ac = 99 ; /* initialize to unmapped ac */ 343 u8 ac = 99 ; /* initialize to unmapped ac */
245 bool chk_adhoc_ps_mapping = false, more_data = false; 344 bool chk_adhoc_ps_mapping = false;
246 int ret; 345 int ret;
346 struct wmi_tx_meta_v2 meta_v2;
347 void *meta;
348 u8 csum_start = 0, csum_dest = 0, csum = skb->ip_summed;
349 u8 meta_ver = 0;
350 u32 flags = 0;
247 351
248 ath6kl_dbg(ATH6KL_DBG_WLAN_TX, 352 ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
249 "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__, 353 "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__,
@@ -260,11 +364,19 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
260 364
261 /* AP mode Power saving processing */ 365 /* AP mode Power saving processing */
262 if (vif->nw_type == AP_NETWORK) { 366 if (vif->nw_type == AP_NETWORK) {
263 if (ath6kl_powersave_ap(vif, skb, &more_data)) 367 if (ath6kl_powersave_ap(vif, skb, &flags))
264 return 0; 368 return 0;
265 } 369 }
266 370
267 if (test_bit(WMI_ENABLED, &ar->flag)) { 371 if (test_bit(WMI_ENABLED, &ar->flag)) {
372 if ((dev->features & NETIF_F_IP_CSUM) &&
373 (csum == CHECKSUM_PARTIAL)) {
374 csum_start = skb->csum_start -
375 (skb_network_header(skb) - skb->head) +
376 sizeof(struct ath6kl_llc_snap_hdr);
377 csum_dest = skb->csum_offset + csum_start;
378 }
379
268 if (skb_headroom(skb) < dev->needed_headroom) { 380 if (skb_headroom(skb) < dev->needed_headroom) {
269 struct sk_buff *tmp_skb = skb; 381 struct sk_buff *tmp_skb = skb;
270 382
@@ -281,10 +393,28 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
281 goto fail_tx; 393 goto fail_tx;
282 } 394 }
283 395
284 if (ath6kl_wmi_data_hdr_add(ar->wmi, skb, DATA_MSGTYPE, 396 if ((dev->features & NETIF_F_IP_CSUM) &&
285 more_data, 0, 0, NULL, 397 (csum == CHECKSUM_PARTIAL)) {
286 vif->fw_vif_idx)) { 398 meta_v2.csum_start = csum_start;
287 ath6kl_err("wmi_data_hdr_add failed\n"); 399 meta_v2.csum_dest = csum_dest;
400
401 /* instruct target to calculate checksum */
402 meta_v2.csum_flags = WMI_META_V2_FLAG_CSUM_OFFLOAD;
403 meta_ver = WMI_META_VERSION_2;
404 meta = &meta_v2;
405 } else {
406 meta_ver = 0;
407 meta = NULL;
408 }
409
410 ret = ath6kl_wmi_data_hdr_add(ar->wmi, skb,
411 DATA_MSGTYPE, flags, 0,
412 meta_ver,
413 meta, vif->fw_vif_idx);
414
415 if (ret) {
416 ath6kl_warn("failed to add wmi data header:%d\n"
417 , ret);
288 goto fail_tx; 418 goto fail_tx;
289 } 419 }
290 420
@@ -449,9 +579,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
449 * WMI queue with too many commands the only exception to 579 * WMI queue with too many commands the only exception to
450 * this is during testing using endpointping. 580 * this is during testing using endpointping.
451 */ 581 */
452 spin_lock_bh(&ar->lock);
453 set_bit(WMI_CTRL_EP_FULL, &ar->flag); 582 set_bit(WMI_CTRL_EP_FULL, &ar->flag);
454 spin_unlock_bh(&ar->lock);
455 ath6kl_err("wmi ctrl ep is full\n"); 583 ath6kl_err("wmi ctrl ep is full\n");
456 return action; 584 return action;
457 } 585 }
@@ -479,9 +607,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
479 action != HTC_SEND_FULL_DROP) { 607 action != HTC_SEND_FULL_DROP) {
480 spin_unlock_bh(&ar->list_lock); 608 spin_unlock_bh(&ar->list_lock);
481 609
482 spin_lock_bh(&vif->if_lock);
483 set_bit(NETQ_STOPPED, &vif->flags); 610 set_bit(NETQ_STOPPED, &vif->flags);
484 spin_unlock_bh(&vif->if_lock);
485 netif_stop_queue(vif->ndev); 611 netif_stop_queue(vif->ndev);
486 612
487 return action; 613 return action;
@@ -710,10 +836,12 @@ static struct sk_buff *aggr_get_free_skb(struct aggr_info *p_aggr)
710{ 836{
711 struct sk_buff *skb = NULL; 837 struct sk_buff *skb = NULL;
712 838
713 if (skb_queue_len(&p_aggr->free_q) < (AGGR_NUM_OF_FREE_NETBUFS >> 2)) 839 if (skb_queue_len(&p_aggr->rx_amsdu_freeq) <
714 ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS); 840 (AGGR_NUM_OF_FREE_NETBUFS >> 2))
841 ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq,
842 AGGR_NUM_OF_FREE_NETBUFS);
715 843
716 skb = skb_dequeue(&p_aggr->free_q); 844 skb = skb_dequeue(&p_aggr->rx_amsdu_freeq);
717 845
718 return skb; 846 return skb;
719} 847}
@@ -881,7 +1009,7 @@ static void aggr_slice_amsdu(struct aggr_info *p_aggr,
881 dev_kfree_skb(skb); 1009 dev_kfree_skb(skb);
882} 1010}
883 1011
884static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, 1012static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,
885 u16 seq_no, u8 order) 1013 u16 seq_no, u8 order)
886{ 1014{
887 struct sk_buff *skb; 1015 struct sk_buff *skb;
@@ -890,11 +1018,8 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
890 u16 idx, idx_end, seq_end; 1018 u16 idx, idx_end, seq_end;
891 struct rxtid_stats *stats; 1019 struct rxtid_stats *stats;
892 1020
893 if (!p_aggr) 1021 rxtid = &agg_conn->rx_tid[tid];
894 return; 1022 stats = &agg_conn->stat[tid];
895
896 rxtid = &p_aggr->rx_tid[tid];
897 stats = &p_aggr->stat[tid];
898 1023
899 idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz); 1024 idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
900 1025
@@ -923,7 +1048,8 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
923 1048
924 if (node->skb) { 1049 if (node->skb) {
925 if (node->is_amsdu) 1050 if (node->is_amsdu)
926 aggr_slice_amsdu(p_aggr, rxtid, node->skb); 1051 aggr_slice_amsdu(agg_conn->aggr_info, rxtid,
1052 node->skb);
927 else 1053 else
928 skb_queue_tail(&rxtid->q, node->skb); 1054 skb_queue_tail(&rxtid->q, node->skb);
929 node->skb = NULL; 1055 node->skb = NULL;
@@ -939,10 +1065,10 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
939 stats->num_delivered += skb_queue_len(&rxtid->q); 1065 stats->num_delivered += skb_queue_len(&rxtid->q);
940 1066
941 while ((skb = skb_dequeue(&rxtid->q))) 1067 while ((skb = skb_dequeue(&rxtid->q)))
942 ath6kl_deliver_frames_to_nw_stack(p_aggr->dev, skb); 1068 ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb);
943} 1069}
944 1070
945static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, 1071static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,
946 u16 seq_no, 1072 u16 seq_no,
947 bool is_amsdu, struct sk_buff *frame) 1073 bool is_amsdu, struct sk_buff *frame)
948{ 1074{
@@ -954,18 +1080,18 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
954 bool is_queued = false; 1080 bool is_queued = false;
955 u16 extended_end; 1081 u16 extended_end;
956 1082
957 rxtid = &agg_info->rx_tid[tid]; 1083 rxtid = &agg_conn->rx_tid[tid];
958 stats = &agg_info->stat[tid]; 1084 stats = &agg_conn->stat[tid];
959 1085
960 stats->num_into_aggr++; 1086 stats->num_into_aggr++;
961 1087
962 if (!rxtid->aggr) { 1088 if (!rxtid->aggr) {
963 if (is_amsdu) { 1089 if (is_amsdu) {
964 aggr_slice_amsdu(agg_info, rxtid, frame); 1090 aggr_slice_amsdu(agg_conn->aggr_info, rxtid, frame);
965 is_queued = true; 1091 is_queued = true;
966 stats->num_amsdu++; 1092 stats->num_amsdu++;
967 while ((skb = skb_dequeue(&rxtid->q))) 1093 while ((skb = skb_dequeue(&rxtid->q)))
968 ath6kl_deliver_frames_to_nw_stack(agg_info->dev, 1094 ath6kl_deliver_frames_to_nw_stack(agg_conn->dev,
969 skb); 1095 skb);
970 } 1096 }
971 return is_queued; 1097 return is_queued;
@@ -985,7 +1111,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
985 (cur < end || cur > extended_end)) || 1111 (cur < end || cur > extended_end)) ||
986 ((end > extended_end) && (cur > extended_end) && 1112 ((end > extended_end) && (cur > extended_end) &&
987 (cur < end))) { 1113 (cur < end))) {
988 aggr_deque_frms(agg_info, tid, 0, 0); 1114 aggr_deque_frms(agg_conn, tid, 0, 0);
989 if (cur >= rxtid->hold_q_sz - 1) 1115 if (cur >= rxtid->hold_q_sz - 1)
990 rxtid->seq_next = cur - (rxtid->hold_q_sz - 1); 1116 rxtid->seq_next = cur - (rxtid->hold_q_sz - 1);
991 else 1117 else
@@ -1002,7 +1128,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
1002 st = ATH6KL_MAX_SEQ_NO - 1128 st = ATH6KL_MAX_SEQ_NO -
1003 (rxtid->hold_q_sz - 2 - cur); 1129 (rxtid->hold_q_sz - 2 - cur);
1004 1130
1005 aggr_deque_frms(agg_info, tid, st, 0); 1131 aggr_deque_frms(agg_conn, tid, st, 0);
1006 } 1132 }
1007 1133
1008 stats->num_oow++; 1134 stats->num_oow++;
@@ -1041,9 +1167,9 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
1041 1167
1042 spin_unlock_bh(&rxtid->lock); 1168 spin_unlock_bh(&rxtid->lock);
1043 1169
1044 aggr_deque_frms(agg_info, tid, 0, 1); 1170 aggr_deque_frms(agg_conn, tid, 0, 1);
1045 1171
1046 if (agg_info->timer_scheduled) 1172 if (agg_conn->timer_scheduled)
1047 rxtid->progress = true; 1173 rxtid->progress = true;
1048 else 1174 else
1049 for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) { 1175 for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
@@ -1054,8 +1180,8 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
1054 * the frame doesn't remain stuck 1180 * the frame doesn't remain stuck
1055 * forever. 1181 * forever.
1056 */ 1182 */
1057 agg_info->timer_scheduled = true; 1183 agg_conn->timer_scheduled = true;
1058 mod_timer(&agg_info->timer, 1184 mod_timer(&agg_conn->timer,
1059 (jiffies + 1185 (jiffies +
1060 HZ * (AGGR_RX_TIMEOUT) / 1000)); 1186 HZ * (AGGR_RX_TIMEOUT) / 1000));
1061 rxtid->progress = false; 1187 rxtid->progress = false;
@@ -1067,6 +1193,76 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
1067 return is_queued; 1193 return is_queued;
1068} 1194}
1069 1195
1196static void ath6kl_uapsd_trigger_frame_rx(struct ath6kl_vif *vif,
1197 struct ath6kl_sta *conn)
1198{
1199 struct ath6kl *ar = vif->ar;
1200 bool is_apsdq_empty, is_apsdq_empty_at_start;
1201 u32 num_frames_to_deliver, flags;
1202 struct sk_buff *skb = NULL;
1203
1204 /*
1205 * If the APSD q for this STA is not empty, dequeue and
1206 * send a pkt from the head of the q. Also update the
1207 * More data bit in the WMI_DATA_HDR if there are
1208 * more pkts for this STA in the APSD q.
1209 * If there are no more pkts for this STA,
1210 * update the APSD bitmap for this STA.
1211 */
1212
1213 num_frames_to_deliver = (conn->apsd_info >> ATH6KL_APSD_NUM_OF_AC) &
1214 ATH6KL_APSD_FRAME_MASK;
1215 /*
1216 * Number of frames to send in a service period is
1217 * indicated by the station
1218 * in the QOS_INFO of the association request
1219 * If it is zero, send all frames
1220 */
1221 if (!num_frames_to_deliver)
1222 num_frames_to_deliver = ATH6KL_APSD_ALL_FRAME;
1223
1224 spin_lock_bh(&conn->psq_lock);
1225 is_apsdq_empty = skb_queue_empty(&conn->apsdq);
1226 spin_unlock_bh(&conn->psq_lock);
1227 is_apsdq_empty_at_start = is_apsdq_empty;
1228
1229 while ((!is_apsdq_empty) && (num_frames_to_deliver)) {
1230
1231 spin_lock_bh(&conn->psq_lock);
1232 skb = skb_dequeue(&conn->apsdq);
1233 is_apsdq_empty = skb_queue_empty(&conn->apsdq);
1234 spin_unlock_bh(&conn->psq_lock);
1235
1236 /*
1237 * Set the STA flag to Trigger delivery,
1238 * so that the frame will go out
1239 */
1240 conn->sta_flags |= STA_PS_APSD_TRIGGER;
1241 num_frames_to_deliver--;
1242
1243 /* Last frame in the service period, set EOSP or queue empty */
1244 if ((is_apsdq_empty) || (!num_frames_to_deliver))
1245 conn->sta_flags |= STA_PS_APSD_EOSP;
1246
1247 ath6kl_data_tx(skb, vif->ndev);
1248 conn->sta_flags &= ~(STA_PS_APSD_TRIGGER);
1249 conn->sta_flags &= ~(STA_PS_APSD_EOSP);
1250 }
1251
1252 if (is_apsdq_empty) {
1253 if (is_apsdq_empty_at_start)
1254 flags = WMI_AP_APSD_NO_DELIVERY_FRAMES;
1255 else
1256 flags = 0;
1257
1258 ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
1259 vif->fw_vif_idx,
1260 conn->aid, 0, flags);
1261 }
1262
1263 return;
1264}
1265
1070void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) 1266void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1071{ 1267{
1072 struct ath6kl *ar = target->dev->ar; 1268 struct ath6kl *ar = target->dev->ar;
@@ -1078,10 +1274,12 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1078 int status = packet->status; 1274 int status = packet->status;
1079 enum htc_endpoint_id ept = packet->endpoint; 1275 enum htc_endpoint_id ept = packet->endpoint;
1080 bool is_amsdu, prev_ps, ps_state = false; 1276 bool is_amsdu, prev_ps, ps_state = false;
1277 bool trig_state = false;
1081 struct ath6kl_sta *conn = NULL; 1278 struct ath6kl_sta *conn = NULL;
1082 struct sk_buff *skb1 = NULL; 1279 struct sk_buff *skb1 = NULL;
1083 struct ethhdr *datap = NULL; 1280 struct ethhdr *datap = NULL;
1084 struct ath6kl_vif *vif; 1281 struct ath6kl_vif *vif;
1282 struct aggr_info_conn *aggr_conn;
1085 u16 seq_no, offset; 1283 u16 seq_no, offset;
1086 u8 tid, if_idx; 1284 u8 tid, if_idx;
1087 1285
@@ -1171,6 +1369,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1171 WMI_DATA_HDR_PS_MASK); 1369 WMI_DATA_HDR_PS_MASK);
1172 1370
1173 offset = sizeof(struct wmi_data_hdr); 1371 offset = sizeof(struct wmi_data_hdr);
1372 trig_state = !!(le16_to_cpu(dhdr->info3) & WMI_DATA_HDR_TRIG);
1174 1373
1175 switch (meta_type) { 1374 switch (meta_type) {
1176 case 0: 1375 case 0:
@@ -1209,18 +1408,36 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1209 else 1408 else
1210 conn->sta_flags &= ~STA_PS_SLEEP; 1409 conn->sta_flags &= ~STA_PS_SLEEP;
1211 1410
1411 /* Accept trigger only when the station is in sleep */
1412 if ((conn->sta_flags & STA_PS_SLEEP) && trig_state)
1413 ath6kl_uapsd_trigger_frame_rx(vif, conn);
1414
1212 if (prev_ps ^ !!(conn->sta_flags & STA_PS_SLEEP)) { 1415 if (prev_ps ^ !!(conn->sta_flags & STA_PS_SLEEP)) {
1213 if (!(conn->sta_flags & STA_PS_SLEEP)) { 1416 if (!(conn->sta_flags & STA_PS_SLEEP)) {
1214 struct sk_buff *skbuff = NULL; 1417 struct sk_buff *skbuff = NULL;
1418 bool is_apsdq_empty;
1215 1419
1216 spin_lock_bh(&conn->psq_lock); 1420 spin_lock_bh(&conn->psq_lock);
1217 while ((skbuff = skb_dequeue(&conn->psq)) 1421 while ((skbuff = skb_dequeue(&conn->psq))) {
1218 != NULL) { 1422 spin_unlock_bh(&conn->psq_lock);
1423 ath6kl_data_tx(skbuff, vif->ndev);
1424 spin_lock_bh(&conn->psq_lock);
1425 }
1426
1427 is_apsdq_empty = skb_queue_empty(&conn->apsdq);
1428 while ((skbuff = skb_dequeue(&conn->apsdq))) {
1219 spin_unlock_bh(&conn->psq_lock); 1429 spin_unlock_bh(&conn->psq_lock);
1220 ath6kl_data_tx(skbuff, vif->ndev); 1430 ath6kl_data_tx(skbuff, vif->ndev);
1221 spin_lock_bh(&conn->psq_lock); 1431 spin_lock_bh(&conn->psq_lock);
1222 } 1432 }
1223 spin_unlock_bh(&conn->psq_lock); 1433 spin_unlock_bh(&conn->psq_lock);
1434
1435 if (!is_apsdq_empty)
1436 ath6kl_wmi_set_apsd_bfrd_traf(
1437 ar->wmi,
1438 vif->fw_vif_idx,
1439 conn->aid, 0, 0);
1440
1224 /* Clear the PVB for this STA */ 1441 /* Clear the PVB for this STA */
1225 ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, 1442 ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
1226 conn->aid, 0); 1443 conn->aid, 0);
@@ -1314,11 +1531,21 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1314 1531
1315 datap = (struct ethhdr *) skb->data; 1532 datap = (struct ethhdr *) skb->data;
1316 1533
1317 if (is_unicast_ether_addr(datap->h_dest) && 1534 if (is_unicast_ether_addr(datap->h_dest)) {
1318 aggr_process_recv_frm(vif->aggr_cntxt, tid, seq_no, 1535 if (vif->nw_type == AP_NETWORK) {
1319 is_amsdu, skb)) 1536 conn = ath6kl_find_sta(vif, datap->h_source);
1320 /* aggregation code will handle the skb */ 1537 if (!conn)
1321 return; 1538 return;
1539 aggr_conn = conn->aggr_conn;
1540 } else
1541 aggr_conn = vif->aggr_cntxt->aggr_conn;
1542
1543 if (aggr_process_recv_frm(aggr_conn, tid, seq_no,
1544 is_amsdu, skb)) {
1545 /* aggregation code will handle the skb */
1546 return;
1547 }
1548 }
1322 1549
1323 ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb); 1550 ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb);
1324} 1551}
@@ -1326,13 +1553,13 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1326static void aggr_timeout(unsigned long arg) 1553static void aggr_timeout(unsigned long arg)
1327{ 1554{
1328 u8 i, j; 1555 u8 i, j;
1329 struct aggr_info *p_aggr = (struct aggr_info *) arg; 1556 struct aggr_info_conn *aggr_conn = (struct aggr_info_conn *) arg;
1330 struct rxtid *rxtid; 1557 struct rxtid *rxtid;
1331 struct rxtid_stats *stats; 1558 struct rxtid_stats *stats;
1332 1559
1333 for (i = 0; i < NUM_OF_TIDS; i++) { 1560 for (i = 0; i < NUM_OF_TIDS; i++) {
1334 rxtid = &p_aggr->rx_tid[i]; 1561 rxtid = &aggr_conn->rx_tid[i];
1335 stats = &p_aggr->stat[i]; 1562 stats = &aggr_conn->stat[i];
1336 1563
1337 if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress) 1564 if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress)
1338 continue; 1565 continue;
@@ -1343,18 +1570,18 @@ static void aggr_timeout(unsigned long arg)
1343 rxtid->seq_next, 1570 rxtid->seq_next,
1344 ((rxtid->seq_next + rxtid->hold_q_sz-1) & 1571 ((rxtid->seq_next + rxtid->hold_q_sz-1) &
1345 ATH6KL_MAX_SEQ_NO)); 1572 ATH6KL_MAX_SEQ_NO));
1346 aggr_deque_frms(p_aggr, i, 0, 0); 1573 aggr_deque_frms(aggr_conn, i, 0, 0);
1347 } 1574 }
1348 1575
1349 p_aggr->timer_scheduled = false; 1576 aggr_conn->timer_scheduled = false;
1350 1577
1351 for (i = 0; i < NUM_OF_TIDS; i++) { 1578 for (i = 0; i < NUM_OF_TIDS; i++) {
1352 rxtid = &p_aggr->rx_tid[i]; 1579 rxtid = &aggr_conn->rx_tid[i];
1353 1580
1354 if (rxtid->aggr && rxtid->hold_q) { 1581 if (rxtid->aggr && rxtid->hold_q) {
1355 for (j = 0; j < rxtid->hold_q_sz; j++) { 1582 for (j = 0; j < rxtid->hold_q_sz; j++) {
1356 if (rxtid->hold_q[j].skb) { 1583 if (rxtid->hold_q[j].skb) {
1357 p_aggr->timer_scheduled = true; 1584 aggr_conn->timer_scheduled = true;
1358 rxtid->timer_mon = true; 1585 rxtid->timer_mon = true;
1359 rxtid->progress = false; 1586 rxtid->progress = false;
1360 break; 1587 break;
@@ -1366,24 +1593,24 @@ static void aggr_timeout(unsigned long arg)
1366 } 1593 }
1367 } 1594 }
1368 1595
1369 if (p_aggr->timer_scheduled) 1596 if (aggr_conn->timer_scheduled)
1370 mod_timer(&p_aggr->timer, 1597 mod_timer(&aggr_conn->timer,
1371 jiffies + msecs_to_jiffies(AGGR_RX_TIMEOUT)); 1598 jiffies + msecs_to_jiffies(AGGR_RX_TIMEOUT));
1372} 1599}
1373 1600
1374static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid) 1601static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid)
1375{ 1602{
1376 struct rxtid *rxtid; 1603 struct rxtid *rxtid;
1377 struct rxtid_stats *stats; 1604 struct rxtid_stats *stats;
1378 1605
1379 if (!p_aggr || tid >= NUM_OF_TIDS) 1606 if (!aggr_conn || tid >= NUM_OF_TIDS)
1380 return; 1607 return;
1381 1608
1382 rxtid = &p_aggr->rx_tid[tid]; 1609 rxtid = &aggr_conn->rx_tid[tid];
1383 stats = &p_aggr->stat[tid]; 1610 stats = &aggr_conn->stat[tid];
1384 1611
1385 if (rxtid->aggr) 1612 if (rxtid->aggr)
1386 aggr_deque_frms(p_aggr, tid, 0, 0); 1613 aggr_deque_frms(aggr_conn, tid, 0, 0);
1387 1614
1388 rxtid->aggr = false; 1615 rxtid->aggr = false;
1389 rxtid->progress = false; 1616 rxtid->progress = false;
@@ -1398,26 +1625,40 @@ static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
1398 memset(stats, 0, sizeof(struct rxtid_stats)); 1625 memset(stats, 0, sizeof(struct rxtid_stats));
1399} 1626}
1400 1627
1401void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no, 1628void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no,
1402 u8 win_sz) 1629 u8 win_sz)
1403{ 1630{
1404 struct aggr_info *p_aggr = vif->aggr_cntxt; 1631 struct ath6kl_sta *sta;
1632 struct aggr_info_conn *aggr_conn = NULL;
1405 struct rxtid *rxtid; 1633 struct rxtid *rxtid;
1406 struct rxtid_stats *stats; 1634 struct rxtid_stats *stats;
1407 u16 hold_q_size; 1635 u16 hold_q_size;
1636 u8 tid, aid;
1408 1637
1409 if (!p_aggr) 1638 if (vif->nw_type == AP_NETWORK) {
1639 aid = ath6kl_get_aid(tid_mux);
1640 sta = ath6kl_find_sta_by_aid(vif->ar, aid);
1641 if (sta)
1642 aggr_conn = sta->aggr_conn;
1643 } else
1644 aggr_conn = vif->aggr_cntxt->aggr_conn;
1645
1646 if (!aggr_conn)
1647 return;
1648
1649 tid = ath6kl_get_tid(tid_mux);
1650 if (tid >= NUM_OF_TIDS)
1410 return; 1651 return;
1411 1652
1412 rxtid = &p_aggr->rx_tid[tid]; 1653 rxtid = &aggr_conn->rx_tid[tid];
1413 stats = &p_aggr->stat[tid]; 1654 stats = &aggr_conn->stat[tid];
1414 1655
1415 if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) 1656 if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX)
1416 ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n", 1657 ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n",
1417 __func__, win_sz, tid); 1658 __func__, win_sz, tid);
1418 1659
1419 if (rxtid->aggr) 1660 if (rxtid->aggr)
1420 aggr_delete_tid_state(p_aggr, tid); 1661 aggr_delete_tid_state(aggr_conn, tid);
1421 1662
1422 rxtid->seq_next = seq_no; 1663 rxtid->seq_next = seq_no;
1423 hold_q_size = TID_WINDOW_SZ(win_sz) * sizeof(struct skb_hold_q); 1664 hold_q_size = TID_WINDOW_SZ(win_sz) * sizeof(struct skb_hold_q);
@@ -1433,31 +1674,23 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
1433 rxtid->aggr = true; 1674 rxtid->aggr = true;
1434} 1675}
1435 1676
1436struct aggr_info *aggr_init(struct net_device *dev) 1677void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
1678 struct aggr_info_conn *aggr_conn)
1437{ 1679{
1438 struct aggr_info *p_aggr = NULL;
1439 struct rxtid *rxtid; 1680 struct rxtid *rxtid;
1440 u8 i; 1681 u8 i;
1441 1682
1442 p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL); 1683 aggr_conn->aggr_sz = AGGR_SZ_DEFAULT;
1443 if (!p_aggr) { 1684 aggr_conn->dev = vif->ndev;
1444 ath6kl_err("failed to alloc memory for aggr_node\n"); 1685 init_timer(&aggr_conn->timer);
1445 return NULL; 1686 aggr_conn->timer.function = aggr_timeout;
1446 } 1687 aggr_conn->timer.data = (unsigned long) aggr_conn;
1447 1688 aggr_conn->aggr_info = aggr_info;
1448 p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
1449 p_aggr->dev = dev;
1450 init_timer(&p_aggr->timer);
1451 p_aggr->timer.function = aggr_timeout;
1452 p_aggr->timer.data = (unsigned long) p_aggr;
1453 1689
1454 p_aggr->timer_scheduled = false; 1690 aggr_conn->timer_scheduled = false;
1455 skb_queue_head_init(&p_aggr->free_q);
1456
1457 ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS);
1458 1691
1459 for (i = 0; i < NUM_OF_TIDS; i++) { 1692 for (i = 0; i < NUM_OF_TIDS; i++) {
1460 rxtid = &p_aggr->rx_tid[i]; 1693 rxtid = &aggr_conn->rx_tid[i];
1461 rxtid->aggr = false; 1694 rxtid->aggr = false;
1462 rxtid->progress = false; 1695 rxtid->progress = false;
1463 rxtid->timer_mon = false; 1696 rxtid->timer_mon = false;
@@ -1465,29 +1698,75 @@ struct aggr_info *aggr_init(struct net_device *dev)
1465 spin_lock_init(&rxtid->lock); 1698 spin_lock_init(&rxtid->lock);
1466 } 1699 }
1467 1700
1701}
1702
1703struct aggr_info *aggr_init(struct ath6kl_vif *vif)
1704{
1705 struct aggr_info *p_aggr = NULL;
1706
1707 p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL);
1708 if (!p_aggr) {
1709 ath6kl_err("failed to alloc memory for aggr_node\n");
1710 return NULL;
1711 }
1712
1713 p_aggr->aggr_conn = kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL);
1714 if (!p_aggr->aggr_conn) {
1715 ath6kl_err("failed to alloc memory for connection specific aggr info\n");
1716 kfree(p_aggr);
1717 return NULL;
1718 }
1719
1720 aggr_conn_init(vif, p_aggr, p_aggr->aggr_conn);
1721
1722 skb_queue_head_init(&p_aggr->rx_amsdu_freeq);
1723 ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, AGGR_NUM_OF_FREE_NETBUFS);
1724
1468 return p_aggr; 1725 return p_aggr;
1469} 1726}
1470 1727
1471void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid) 1728void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid_mux)
1472{ 1729{
1473 struct aggr_info *p_aggr = vif->aggr_cntxt; 1730 struct ath6kl_sta *sta;
1474 struct rxtid *rxtid; 1731 struct rxtid *rxtid;
1732 struct aggr_info_conn *aggr_conn = NULL;
1733 u8 tid, aid;
1734
1735 if (vif->nw_type == AP_NETWORK) {
1736 aid = ath6kl_get_aid(tid_mux);
1737 sta = ath6kl_find_sta_by_aid(vif->ar, aid);
1738 if (sta)
1739 aggr_conn = sta->aggr_conn;
1740 } else
1741 aggr_conn = vif->aggr_cntxt->aggr_conn;
1742
1743 if (!aggr_conn)
1744 return;
1475 1745
1476 if (!p_aggr) 1746 tid = ath6kl_get_tid(tid_mux);
1747 if (tid >= NUM_OF_TIDS)
1477 return; 1748 return;
1478 1749
1479 rxtid = &p_aggr->rx_tid[tid]; 1750 rxtid = &aggr_conn->rx_tid[tid];
1480 1751
1481 if (rxtid->aggr) 1752 if (rxtid->aggr)
1482 aggr_delete_tid_state(p_aggr, tid); 1753 aggr_delete_tid_state(aggr_conn, tid);
1483} 1754}
1484 1755
1485void aggr_reset_state(struct aggr_info *aggr_info) 1756void aggr_reset_state(struct aggr_info_conn *aggr_conn)
1486{ 1757{
1487 u8 tid; 1758 u8 tid;
1488 1759
1760 if (!aggr_conn)
1761 return;
1762
1763 if (aggr_conn->timer_scheduled) {
1764 del_timer(&aggr_conn->timer);
1765 aggr_conn->timer_scheduled = false;
1766 }
1767
1489 for (tid = 0; tid < NUM_OF_TIDS; tid++) 1768 for (tid = 0; tid < NUM_OF_TIDS; tid++)
1490 aggr_delete_tid_state(aggr_info, tid); 1769 aggr_delete_tid_state(aggr_conn, tid);
1491} 1770}
1492 1771
1493/* clean up our amsdu buffer list */ 1772/* clean up our amsdu buffer list */
@@ -1514,28 +1793,11 @@ void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar)
1514 1793
1515void aggr_module_destroy(struct aggr_info *aggr_info) 1794void aggr_module_destroy(struct aggr_info *aggr_info)
1516{ 1795{
1517 struct rxtid *rxtid;
1518 u8 i, k;
1519
1520 if (!aggr_info) 1796 if (!aggr_info)
1521 return; 1797 return;
1522 1798
1523 if (aggr_info->timer_scheduled) { 1799 aggr_reset_state(aggr_info->aggr_conn);
1524 del_timer(&aggr_info->timer); 1800 skb_queue_purge(&aggr_info->rx_amsdu_freeq);
1525 aggr_info->timer_scheduled = false; 1801 kfree(aggr_info->aggr_conn);
1526 }
1527
1528 for (i = 0; i < NUM_OF_TIDS; i++) {
1529 rxtid = &aggr_info->rx_tid[i];
1530 if (rxtid->hold_q) {
1531 for (k = 0; k < rxtid->hold_q_sz; k++)
1532 dev_kfree_skb(rxtid->hold_q[k].skb);
1533 kfree(rxtid->hold_q);
1534 }
1535
1536 skb_queue_purge(&rxtid->q);
1537 }
1538
1539 skb_queue_purge(&aggr_info->free_q);
1540 kfree(aggr_info); 1802 kfree(aggr_info);
1541} 1803}
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
new file mode 100644
index 000000000000..c72567c6d338
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -0,0 +1,431 @@
1/*
2 * Copyright (c) 2007-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/module.h>
18#include <linux/usb.h>
19
20#include "debug.h"
21#include "core.h"
22
23/* usb device object */
24struct ath6kl_usb {
25 struct usb_device *udev;
26 struct usb_interface *interface;
27 u8 *diag_cmd_buffer;
28 u8 *diag_resp_buffer;
29 struct ath6kl *ar;
30};
31
32/* diagnostic command defnitions */
33#define ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD 1
34#define ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP 2
35#define ATH6KL_USB_CONTROL_REQ_DIAG_CMD 3
36#define ATH6KL_USB_CONTROL_REQ_DIAG_RESP 4
37
38#define ATH6KL_USB_CTRL_DIAG_CC_READ 0
39#define ATH6KL_USB_CTRL_DIAG_CC_WRITE 1
40
41struct ath6kl_usb_ctrl_diag_cmd_write {
42 __le32 cmd;
43 __le32 address;
44 __le32 value;
45 __le32 _pad[1];
46} __packed;
47
48struct ath6kl_usb_ctrl_diag_cmd_read {
49 __le32 cmd;
50 __le32 address;
51} __packed;
52
53struct ath6kl_usb_ctrl_diag_resp_read {
54 __le32 value;
55} __packed;
56
57#define ATH6KL_USB_MAX_DIAG_CMD (sizeof(struct ath6kl_usb_ctrl_diag_cmd_write))
58#define ATH6KL_USB_MAX_DIAG_RESP (sizeof(struct ath6kl_usb_ctrl_diag_resp_read))
59
60static void ath6kl_usb_destroy(struct ath6kl_usb *ar_usb)
61{
62 usb_set_intfdata(ar_usb->interface, NULL);
63
64 kfree(ar_usb->diag_cmd_buffer);
65 kfree(ar_usb->diag_resp_buffer);
66
67 kfree(ar_usb);
68}
69
70static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface)
71{
72 struct ath6kl_usb *ar_usb = NULL;
73 struct usb_device *dev = interface_to_usbdev(interface);
74 int status = 0;
75
76 ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL);
77 if (ar_usb == NULL)
78 goto fail_ath6kl_usb_create;
79
80 memset(ar_usb, 0, sizeof(struct ath6kl_usb));
81 usb_set_intfdata(interface, ar_usb);
82 ar_usb->udev = dev;
83 ar_usb->interface = interface;
84
85 ar_usb->diag_cmd_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_CMD, GFP_KERNEL);
86 if (ar_usb->diag_cmd_buffer == NULL) {
87 status = -ENOMEM;
88 goto fail_ath6kl_usb_create;
89 }
90
91 ar_usb->diag_resp_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_RESP,
92 GFP_KERNEL);
93 if (ar_usb->diag_resp_buffer == NULL) {
94 status = -ENOMEM;
95 goto fail_ath6kl_usb_create;
96 }
97
98fail_ath6kl_usb_create:
99 if (status != 0) {
100 ath6kl_usb_destroy(ar_usb);
101 ar_usb = NULL;
102 }
103 return ar_usb;
104}
105
106static void ath6kl_usb_device_detached(struct usb_interface *interface)
107{
108 struct ath6kl_usb *ar_usb;
109
110 ar_usb = usb_get_intfdata(interface);
111 if (ar_usb == NULL)
112 return;
113
114 ath6kl_stop_txrx(ar_usb->ar);
115
116 ath6kl_core_cleanup(ar_usb->ar);
117
118 ath6kl_usb_destroy(ar_usb);
119}
120
121static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb,
122 u8 req, u16 value, u16 index, void *data,
123 u32 size)
124{
125 u8 *buf = NULL;
126 int ret;
127
128 if (size > 0) {
129 buf = kmalloc(size, GFP_KERNEL);
130 if (buf == NULL)
131 return -ENOMEM;
132
133 memcpy(buf, data, size);
134 }
135
136 /* note: if successful returns number of bytes transfered */
137 ret = usb_control_msg(ar_usb->udev,
138 usb_sndctrlpipe(ar_usb->udev, 0),
139 req,
140 USB_DIR_OUT | USB_TYPE_VENDOR |
141 USB_RECIP_DEVICE, value, index, buf,
142 size, 1000);
143
144 if (ret < 0) {
145 ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
146 __func__, ret);
147 }
148
149 kfree(buf);
150
151 return 0;
152}
153
154static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb,
155 u8 req, u16 value, u16 index, void *data,
156 u32 size)
157{
158 u8 *buf = NULL;
159 int ret;
160
161 if (size > 0) {
162 buf = kmalloc(size, GFP_KERNEL);
163 if (buf == NULL)
164 return -ENOMEM;
165 }
166
167 /* note: if successful returns number of bytes transfered */
168 ret = usb_control_msg(ar_usb->udev,
169 usb_rcvctrlpipe(ar_usb->udev, 0),
170 req,
171 USB_DIR_IN | USB_TYPE_VENDOR |
172 USB_RECIP_DEVICE, value, index, buf,
173 size, 2 * HZ);
174
175 if (ret < 0) {
176 ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
177 __func__, ret);
178 }
179
180 memcpy((u8 *) data, buf, size);
181
182 kfree(buf);
183
184 return 0;
185}
186
187static int ath6kl_usb_ctrl_msg_exchange(struct ath6kl_usb *ar_usb,
188 u8 req_val, u8 *req_buf, u32 req_len,
189 u8 resp_val, u8 *resp_buf, u32 *resp_len)
190{
191 int ret;
192
193 /* send command */
194 ret = ath6kl_usb_submit_ctrl_out(ar_usb, req_val, 0, 0,
195 req_buf, req_len);
196
197 if (ret != 0)
198 return ret;
199
200 if (resp_buf == NULL) {
201 /* no expected response */
202 return ret;
203 }
204
205 /* get response */
206 ret = ath6kl_usb_submit_ctrl_in(ar_usb, resp_val, 0, 0,
207 resp_buf, *resp_len);
208
209 return ret;
210}
211
212static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data)
213{
214 struct ath6kl_usb *ar_usb = ar->hif_priv;
215 struct ath6kl_usb_ctrl_diag_resp_read *resp;
216 struct ath6kl_usb_ctrl_diag_cmd_read *cmd;
217 u32 resp_len;
218 int ret;
219
220 cmd = (struct ath6kl_usb_ctrl_diag_cmd_read *) ar_usb->diag_cmd_buffer;
221
222 memset(cmd, 0, sizeof(*cmd));
223 cmd->cmd = ATH6KL_USB_CTRL_DIAG_CC_READ;
224 cmd->address = cpu_to_le32(address);
225 resp_len = sizeof(*resp);
226
227 ret = ath6kl_usb_ctrl_msg_exchange(ar_usb,
228 ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
229 (u8 *) cmd,
230 sizeof(struct ath6kl_usb_ctrl_diag_cmd_write),
231 ATH6KL_USB_CONTROL_REQ_DIAG_RESP,
232 ar_usb->diag_resp_buffer, &resp_len);
233
234 if (ret)
235 return ret;
236
237 resp = (struct ath6kl_usb_ctrl_diag_resp_read *)
238 ar_usb->diag_resp_buffer;
239
240 *data = le32_to_cpu(resp->value);
241
242 return ret;
243}
244
245static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data)
246{
247 struct ath6kl_usb *ar_usb = ar->hif_priv;
248 struct ath6kl_usb_ctrl_diag_cmd_write *cmd;
249
250 cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer;
251
252 memset(cmd, 0, sizeof(struct ath6kl_usb_ctrl_diag_cmd_write));
253 cmd->cmd = cpu_to_le32(ATH6KL_USB_CTRL_DIAG_CC_WRITE);
254 cmd->address = cpu_to_le32(address);
255 cmd->value = data;
256
257 return ath6kl_usb_ctrl_msg_exchange(ar_usb,
258 ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
259 (u8 *) cmd,
260 sizeof(*cmd),
261 0, NULL, NULL);
262
263}
264
265static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
266{
267 struct ath6kl_usb *ar_usb = ar->hif_priv;
268 int ret;
269
270 /* get response */
271 ret = ath6kl_usb_submit_ctrl_in(ar_usb,
272 ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP,
273 0, 0, buf, len);
274 if (ret != 0) {
275 ath6kl_err("Unable to read the bmi data from the device: %d\n",
276 ret);
277 return ret;
278 }
279
280 return 0;
281}
282
283static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
284{
285 struct ath6kl_usb *ar_usb = ar->hif_priv;
286 int ret;
287
288 /* send command */
289 ret = ath6kl_usb_submit_ctrl_out(ar_usb,
290 ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD,
291 0, 0, buf, len);
292 if (ret != 0) {
293 ath6kl_err("unable to send the bmi data to the device: %d\n",
294 ret);
295 return ret;
296 }
297
298 return 0;
299}
300
301static int ath6kl_usb_power_on(struct ath6kl *ar)
302{
303 return 0;
304}
305
306static int ath6kl_usb_power_off(struct ath6kl *ar)
307{
308 return 0;
309}
310
311static const struct ath6kl_hif_ops ath6kl_usb_ops = {
312 .diag_read32 = ath6kl_usb_diag_read32,
313 .diag_write32 = ath6kl_usb_diag_write32,
314 .bmi_read = ath6kl_usb_bmi_read,
315 .bmi_write = ath6kl_usb_bmi_write,
316 .power_on = ath6kl_usb_power_on,
317 .power_off = ath6kl_usb_power_off,
318};
319
320/* ath6kl usb driver registered functions */
321static int ath6kl_usb_probe(struct usb_interface *interface,
322 const struct usb_device_id *id)
323{
324 struct usb_device *dev = interface_to_usbdev(interface);
325 struct ath6kl *ar;
326 struct ath6kl_usb *ar_usb = NULL;
327 int vendor_id, product_id;
328 int ret = 0;
329
330 usb_get_dev(dev);
331
332 vendor_id = le16_to_cpu(dev->descriptor.idVendor);
333 product_id = le16_to_cpu(dev->descriptor.idProduct);
334
335 ath6kl_dbg(ATH6KL_DBG_USB, "vendor_id = %04x\n", vendor_id);
336 ath6kl_dbg(ATH6KL_DBG_USB, "product_id = %04x\n", product_id);
337
338 if (interface->cur_altsetting)
339 ath6kl_dbg(ATH6KL_DBG_USB, "USB Interface %d\n",
340 interface->cur_altsetting->desc.bInterfaceNumber);
341
342
343 if (dev->speed == USB_SPEED_HIGH)
344 ath6kl_dbg(ATH6KL_DBG_USB, "USB 2.0 Host\n");
345 else
346 ath6kl_dbg(ATH6KL_DBG_USB, "USB 1.1 Host\n");
347
348 ar_usb = ath6kl_usb_create(interface);
349
350 if (ar_usb == NULL) {
351 ret = -ENOMEM;
352 goto err_usb_put;
353 }
354
355 ar = ath6kl_core_create(&ar_usb->udev->dev);
356 if (ar == NULL) {
357 ath6kl_err("Failed to alloc ath6kl core\n");
358 ret = -ENOMEM;
359 goto err_usb_destroy;
360 }
361
362 ar->hif_priv = ar_usb;
363 ar->hif_type = ATH6KL_HIF_TYPE_USB;
364 ar->hif_ops = &ath6kl_usb_ops;
365 ar->mbox_info.block_size = 16;
366 ar->bmi.max_data_size = 252;
367
368 ar_usb->ar = ar;
369
370 ret = ath6kl_core_init(ar);
371 if (ret) {
372 ath6kl_err("Failed to init ath6kl core: %d\n", ret);
373 goto err_core_free;
374 }
375
376 return ret;
377
378err_core_free:
379 ath6kl_core_destroy(ar);
380err_usb_destroy:
381 ath6kl_usb_destroy(ar_usb);
382err_usb_put:
383 usb_put_dev(dev);
384
385 return ret;
386}
387
388static void ath6kl_usb_remove(struct usb_interface *interface)
389{
390 usb_put_dev(interface_to_usbdev(interface));
391 ath6kl_usb_device_detached(interface);
392}
393
394/* table of devices that work with this driver */
395static struct usb_device_id ath6kl_usb_ids[] = {
396 {USB_DEVICE(0x0cf3, 0x9374)},
397 { /* Terminating entry */ },
398};
399
400MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids);
401
402static struct usb_driver ath6kl_usb_driver = {
403 .name = "ath6kl_usb",
404 .probe = ath6kl_usb_probe,
405 .disconnect = ath6kl_usb_remove,
406 .id_table = ath6kl_usb_ids,
407};
408
409static int ath6kl_usb_init(void)
410{
411 usb_register(&ath6kl_usb_driver);
412 return 0;
413}
414
415static void ath6kl_usb_exit(void)
416{
417 usb_deregister(&ath6kl_usb_driver);
418}
419
420module_init(ath6kl_usb_init);
421module_exit(ath6kl_usb_exit);
422
423MODULE_AUTHOR("Atheros Communications, Inc.");
424MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices");
425MODULE_LICENSE("Dual BSD/GPL");
426MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE);
427MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE);
428MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
429MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE);
430MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
431MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index f6f2aa27fc20..18fa9aa8af92 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -180,7 +180,7 @@ static int ath6kl_wmi_meta_add(struct wmi *wmi, struct sk_buff *skb,
180} 180}
181 181
182int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb, 182int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
183 u8 msg_type, bool more_data, 183 u8 msg_type, u32 flags,
184 enum wmi_data_hdr_data_type data_type, 184 enum wmi_data_hdr_data_type data_type,
185 u8 meta_ver, void *tx_meta_info, u8 if_idx) 185 u8 meta_ver, void *tx_meta_info, u8 if_idx)
186{ 186{
@@ -204,17 +204,19 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
204 data_hdr->info = msg_type << WMI_DATA_HDR_MSG_TYPE_SHIFT; 204 data_hdr->info = msg_type << WMI_DATA_HDR_MSG_TYPE_SHIFT;
205 data_hdr->info |= data_type << WMI_DATA_HDR_DATA_TYPE_SHIFT; 205 data_hdr->info |= data_type << WMI_DATA_HDR_DATA_TYPE_SHIFT;
206 206
207 if (more_data) 207 if (flags & WMI_DATA_HDR_FLAGS_MORE)
208 data_hdr->info |= 208 data_hdr->info |= WMI_DATA_HDR_MORE;
209 WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT;
210 209
211 data_hdr->info2 = cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT); 210 if (flags & WMI_DATA_HDR_FLAGS_EOSP)
212 data_hdr->info3 = cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK); 211 data_hdr->info3 |= cpu_to_le16(WMI_DATA_HDR_EOSP);
212
213 data_hdr->info2 |= cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT);
214 data_hdr->info3 |= cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK);
213 215
214 return 0; 216 return 0;
215} 217}
216 218
217static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri) 219u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
218{ 220{
219 struct iphdr *ip_hdr = (struct iphdr *) pkt; 221 struct iphdr *ip_hdr = (struct iphdr *) pkt;
220 u8 ip_pri; 222 u8 ip_pri;
@@ -236,6 +238,11 @@ static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
236 return ip_pri; 238 return ip_pri;
237} 239}
238 240
241u8 ath6kl_wmi_get_traffic_class(u8 user_priority)
242{
243 return up_to_ac[user_priority & 0x7];
244}
245
239int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx, 246int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx,
240 struct sk_buff *skb, 247 struct sk_buff *skb,
241 u32 layer2_priority, bool wmm_enabled, 248 u32 layer2_priority, bool wmm_enabled,
@@ -419,9 +426,6 @@ static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)
419 ath6kl_dbg(ATH6KL_DBG_WMI, "comp: %d %d %d\n", 426 ath6kl_dbg(ATH6KL_DBG_WMI, "comp: %d %d %d\n",
420 evt->num_msg, evt->msg_len, evt->msg_type); 427 evt->num_msg, evt->msg_len, evt->msg_type);
421 428
422 if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_WMI))
423 return 0;
424
425 for (index = 0; index < evt->num_msg; index++) { 429 for (index = 0; index < evt->num_msg; index++) {
426 size = sizeof(struct wmi_tx_complete_event) + 430 size = sizeof(struct wmi_tx_complete_event) +
427 (index * sizeof(struct tx_complete_msg_v1)); 431 (index * sizeof(struct tx_complete_msg_v1));
@@ -786,12 +790,14 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len,
786 ev->u.ap_sta.keymgmt, 790 ev->u.ap_sta.keymgmt,
787 le16_to_cpu(ev->u.ap_sta.cipher), 791 le16_to_cpu(ev->u.ap_sta.cipher),
788 ev->u.ap_sta.apsd_info); 792 ev->u.ap_sta.apsd_info);
793
789 ath6kl_connect_ap_mode_sta( 794 ath6kl_connect_ap_mode_sta(
790 vif, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr, 795 vif, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr,
791 ev->u.ap_sta.keymgmt, 796 ev->u.ap_sta.keymgmt,
792 le16_to_cpu(ev->u.ap_sta.cipher), 797 le16_to_cpu(ev->u.ap_sta.cipher),
793 ev->u.ap_sta.auth, ev->assoc_req_len, 798 ev->u.ap_sta.auth, ev->assoc_req_len,
794 ev->assoc_info + ev->beacon_ie_len); 799 ev->assoc_info + ev->beacon_ie_len,
800 ev->u.ap_sta.apsd_info);
795 } 801 }
796 return 0; 802 return 0;
797 } 803 }
@@ -1145,9 +1151,9 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
1145 return 0; 1151 return 0;
1146} 1152}
1147 1153
1148static int ath6kl_wmi_tcmd_test_report_rx(struct wmi *wmi, u8 *datap, int len) 1154static int ath6kl_wmi_test_rx(struct wmi *wmi, u8 *datap, int len)
1149{ 1155{
1150 ath6kl_tm_rx_report_event(wmi->parent_dev, datap, len); 1156 ath6kl_tm_rx_event(wmi->parent_dev, datap, len);
1151 1157
1152 return 0; 1158 return 0;
1153} 1159}
@@ -2479,15 +2485,16 @@ int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class,
2479 return ret; 2485 return ret;
2480} 2486}
2481 2487
2482int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd) 2488int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
2489 __be32 ips0, __be32 ips1)
2483{ 2490{
2484 struct sk_buff *skb; 2491 struct sk_buff *skb;
2485 struct wmi_set_ip_cmd *cmd; 2492 struct wmi_set_ip_cmd *cmd;
2486 int ret; 2493 int ret;
2487 2494
2488 /* Multicast address are not valid */ 2495 /* Multicast address are not valid */
2489 if ((*((u8 *) &ip_cmd->ips[0]) >= 0xE0) || 2496 if (ipv4_is_multicast(ips0) ||
2490 (*((u8 *) &ip_cmd->ips[1]) >= 0xE0)) 2497 ipv4_is_multicast(ips1))
2491 return -EINVAL; 2498 return -EINVAL;
2492 2499
2493 skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_ip_cmd)); 2500 skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_ip_cmd));
@@ -2495,9 +2502,10 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd)
2495 return -ENOMEM; 2502 return -ENOMEM;
2496 2503
2497 cmd = (struct wmi_set_ip_cmd *) skb->data; 2504 cmd = (struct wmi_set_ip_cmd *) skb->data;
2498 memcpy(cmd, ip_cmd, sizeof(struct wmi_set_ip_cmd)); 2505 cmd->ips[0] = ips0;
2506 cmd->ips[1] = ips1;
2499 2507
2500 ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_IP_CMDID, 2508 ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_IP_CMDID,
2501 NO_SYNC_WMIFLAG); 2509 NO_SYNC_WMIFLAG);
2502 return ret; 2510 return ret;
2503} 2511}
@@ -2582,6 +2590,18 @@ int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
2582 return ret; 2590 return ret;
2583} 2591}
2584 2592
2593/* This command has zero length payload */
2594static int ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(struct wmi *wmi,
2595 struct ath6kl_vif *vif)
2596{
2597 struct ath6kl *ar = wmi->parent_dev;
2598
2599 set_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2600 wake_up(&ar->event_wq);
2601
2602 return 0;
2603}
2604
2585int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, 2605int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
2586 enum ath6kl_wow_mode wow_mode, 2606 enum ath6kl_wow_mode wow_mode,
2587 u32 filter, u16 host_req_delay) 2607 u32 filter, u16 host_req_delay)
@@ -2612,7 +2632,8 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
2612 2632
2613int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, 2633int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
2614 u8 list_id, u8 filter_size, 2634 u8 list_id, u8 filter_size,
2615 u8 filter_offset, u8 *filter, u8 *mask) 2635 u8 filter_offset, const u8 *filter,
2636 const u8 *mask)
2616{ 2637{
2617 struct sk_buff *skb; 2638 struct sk_buff *skb;
2618 struct wmi_add_wow_pattern_cmd *cmd; 2639 struct wmi_add_wow_pattern_cmd *cmd;
@@ -2853,6 +2874,51 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len)
2853 return ret; 2874 return ret;
2854} 2875}
2855 2876
2877int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on)
2878{
2879 struct sk_buff *skb;
2880 struct wmi_mcast_filter_cmd *cmd;
2881 int ret;
2882
2883 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
2884 if (!skb)
2885 return -ENOMEM;
2886
2887 cmd = (struct wmi_mcast_filter_cmd *) skb->data;
2888 cmd->mcast_all_enable = mc_all_on;
2889
2890 ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_MCAST_FILTER_CMDID,
2891 NO_SYNC_WMIFLAG);
2892 return ret;
2893}
2894
2895int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
2896 u8 *filter, bool add_filter)
2897{
2898 struct sk_buff *skb;
2899 struct wmi_mcast_filter_add_del_cmd *cmd;
2900 int ret;
2901
2902 if ((filter[0] != 0x33 || filter[1] != 0x33) &&
2903 (filter[0] != 0x01 || filter[1] != 0x00 ||
2904 filter[2] != 0x5e || filter[3] > 0x7f)) {
2905 ath6kl_warn("invalid multicast filter address\n");
2906 return -EINVAL;
2907 }
2908
2909 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
2910 if (!skb)
2911 return -ENOMEM;
2912
2913 cmd = (struct wmi_mcast_filter_add_del_cmd *) skb->data;
2914 memcpy(cmd->mcast_mac, filter, ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE);
2915 ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
2916 add_filter ? WMI_SET_MCAST_FILTER_CMDID :
2917 WMI_DEL_MCAST_FILTER_CMDID,
2918 NO_SYNC_WMIFLAG);
2919
2920 return ret;
2921}
2856 2922
2857s32 ath6kl_wmi_get_rate(s8 rate_index) 2923s32 ath6kl_wmi_get_rate(s8 rate_index)
2858{ 2924{
@@ -2946,6 +3012,43 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac,
2946 NO_SYNC_WMIFLAG); 3012 NO_SYNC_WMIFLAG);
2947} 3013}
2948 3014
3015/* This command will be used to enable/disable AP uAPSD feature */
3016int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable)
3017{
3018 struct wmi_ap_set_apsd_cmd *cmd;
3019 struct sk_buff *skb;
3020
3021 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
3022 if (!skb)
3023 return -ENOMEM;
3024
3025 cmd = (struct wmi_ap_set_apsd_cmd *)skb->data;
3026 cmd->enable = enable;
3027
3028 return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_SET_APSD_CMDID,
3029 NO_SYNC_WMIFLAG);
3030}
3031
3032int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi, u8 if_idx,
3033 u16 aid, u16 bitmap, u32 flags)
3034{
3035 struct wmi_ap_apsd_buffered_traffic_cmd *cmd;
3036 struct sk_buff *skb;
3037
3038 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
3039 if (!skb)
3040 return -ENOMEM;
3041
3042 cmd = (struct wmi_ap_apsd_buffered_traffic_cmd *)skb->data;
3043 cmd->aid = cpu_to_le16(aid);
3044 cmd->bitmap = cpu_to_le16(bitmap);
3045 cmd->flags = cpu_to_le32(flags);
3046
3047 return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
3048 WMI_AP_APSD_BUFFERED_TRAFFIC_CMDID,
3049 NO_SYNC_WMIFLAG);
3050}
3051
2949static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len, 3052static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len,
2950 struct ath6kl_vif *vif) 3053 struct ath6kl_vif *vif)
2951{ 3054{
@@ -3400,7 +3503,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
3400 break; 3503 break;
3401 case WMI_TEST_EVENTID: 3504 case WMI_TEST_EVENTID:
3402 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TEST_EVENTID\n"); 3505 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TEST_EVENTID\n");
3403 ret = ath6kl_wmi_tcmd_test_report_rx(wmi, datap, len); 3506 ret = ath6kl_wmi_test_rx(wmi, datap, len);
3404 break; 3507 break;
3405 case WMI_GET_FIXRATES_CMDID: 3508 case WMI_GET_FIXRATES_CMDID:
3406 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n"); 3509 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n");
@@ -3465,6 +3568,11 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
3465 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n"); 3568 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n");
3466 ret = ath6kl_wmi_tx_complete_event_rx(datap, len); 3569 ret = ath6kl_wmi_tx_complete_event_rx(datap, len);
3467 break; 3570 break;
3571 case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID:
3572 ath6kl_dbg(ATH6KL_DBG_WMI,
3573 "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID");
3574 ret = ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif);
3575 break;
3468 case WMI_REMAIN_ON_CHNL_EVENTID: 3576 case WMI_REMAIN_ON_CHNL_EVENTID:
3469 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n"); 3577 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n");
3470 ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif); 3578 ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif);
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 42ac311eda4e..e7919869725e 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -149,8 +149,7 @@ enum wmi_msg_type {
149#define WMI_DATA_HDR_PS_MASK 0x1 149#define WMI_DATA_HDR_PS_MASK 0x1
150#define WMI_DATA_HDR_PS_SHIFT 5 150#define WMI_DATA_HDR_PS_SHIFT 5
151 151
152#define WMI_DATA_HDR_MORE_MASK 0x1 152#define WMI_DATA_HDR_MORE 0x20
153#define WMI_DATA_HDR_MORE_SHIFT 5
154 153
155enum wmi_data_hdr_data_type { 154enum wmi_data_hdr_data_type {
156 WMI_DATA_HDR_DATA_TYPE_802_3 = 0, 155 WMI_DATA_HDR_DATA_TYPE_802_3 = 0,
@@ -160,6 +159,13 @@ enum wmi_data_hdr_data_type {
160 WMI_DATA_HDR_DATA_TYPE_ACL, 159 WMI_DATA_HDR_DATA_TYPE_ACL,
161}; 160};
162 161
162/* Bitmap of data header flags */
163enum wmi_data_hdr_flags {
164 WMI_DATA_HDR_FLAGS_MORE = 0x1,
165 WMI_DATA_HDR_FLAGS_EOSP = 0x2,
166 WMI_DATA_HDR_FLAGS_UAPSD = 0x4,
167};
168
163#define WMI_DATA_HDR_DATA_TYPE_MASK 0x3 169#define WMI_DATA_HDR_DATA_TYPE_MASK 0x3
164#define WMI_DATA_HDR_DATA_TYPE_SHIFT 6 170#define WMI_DATA_HDR_DATA_TYPE_SHIFT 6
165 171
@@ -173,8 +179,12 @@ enum wmi_data_hdr_data_type {
173#define WMI_DATA_HDR_META_MASK 0x7 179#define WMI_DATA_HDR_META_MASK 0x7
174#define WMI_DATA_HDR_META_SHIFT 13 180#define WMI_DATA_HDR_META_SHIFT 13
175 181
182/* Macros for operating on WMI_DATA_HDR (info3) field */
176#define WMI_DATA_HDR_IF_IDX_MASK 0xF 183#define WMI_DATA_HDR_IF_IDX_MASK 0xF
177 184
185#define WMI_DATA_HDR_TRIG 0x10
186#define WMI_DATA_HDR_EOSP 0x10
187
178struct wmi_data_hdr { 188struct wmi_data_hdr {
179 s8 rssi; 189 s8 rssi;
180 190
@@ -203,7 +213,8 @@ struct wmi_data_hdr {
203 /* 213 /*
204 * usage of info3, 16-bit: 214 * usage of info3, 16-bit:
205 * b3:b0 - Interface index 215 * b3:b0 - Interface index
206 * b15:b4 - Reserved 216 * b4 - uAPSD trigger in rx & EOSP in tx
217 * b15:b5 - Reserved
207 */ 218 */
208 __le16 info3; 219 __le16 info3;
209} __packed; 220} __packed;
@@ -257,6 +268,9 @@ static inline u8 wmi_data_hdr_get_if_idx(struct wmi_data_hdr *dhdr)
257#define WMI_META_VERSION_1 0x01 268#define WMI_META_VERSION_1 0x01
258#define WMI_META_VERSION_2 0x02 269#define WMI_META_VERSION_2 0x02
259 270
271/* Flag to signal to FW to calculate TCP checksum */
272#define WMI_META_V2_FLAG_CSUM_OFFLOAD 0x01
273
260struct wmi_tx_meta_v1 { 274struct wmi_tx_meta_v1 {
261 /* packet ID to identify the tx request */ 275 /* packet ID to identify the tx request */
262 u8 pkt_id; 276 u8 pkt_id;
@@ -646,7 +660,6 @@ enum auth_mode {
646 WPA2_AUTH_CCKM = 0x40, 660 WPA2_AUTH_CCKM = 0x40,
647}; 661};
648 662
649#define WMI_MIN_KEY_INDEX 0
650#define WMI_MAX_KEY_INDEX 3 663#define WMI_MAX_KEY_INDEX 3
651 664
652#define WMI_MAX_KEY_LEN 32 665#define WMI_MAX_KEY_LEN 32
@@ -1237,6 +1250,15 @@ enum target_event_report_config {
1237 NO_DISCONN_EVT_IN_RECONN 1250 NO_DISCONN_EVT_IN_RECONN
1238}; 1251};
1239 1252
1253struct wmi_mcast_filter_cmd {
1254 u8 mcast_all_enable;
1255} __packed;
1256
1257#define ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE 6
1258struct wmi_mcast_filter_add_del_cmd {
1259 u8 mcast_mac[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE];
1260} __packed;
1261
1240/* Command Replies */ 1262/* Command Replies */
1241 1263
1242/* WMI_GET_CHANNEL_LIST_CMDID reply */ 1264/* WMI_GET_CHANNEL_LIST_CMDID reply */
@@ -1335,6 +1357,8 @@ enum wmi_event_id {
1335 WMI_P2P_START_SDPD_EVENTID, 1357 WMI_P2P_START_SDPD_EVENTID,
1336 WMI_P2P_SDPD_RX_EVENTID, 1358 WMI_P2P_SDPD_RX_EVENTID,
1337 1359
1360 WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID = 0x1047,
1361
1338 WMI_THIN_RESERVED_START_EVENTID = 0x8000, 1362 WMI_THIN_RESERVED_START_EVENTID = 0x8000,
1339 /* Events in this range are reserved for thinmode */ 1363 /* Events in this range are reserved for thinmode */
1340 WMI_THIN_RESERVED_END_EVENTID = 0x8fff, 1364 WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
@@ -1903,7 +1927,7 @@ struct wow_filter {
1903 1927
1904struct wmi_set_ip_cmd { 1928struct wmi_set_ip_cmd {
1905 /* IP in network byte order */ 1929 /* IP in network byte order */
1906 __le32 ips[MAX_IP_ADDRS]; 1930 __be32 ips[MAX_IP_ADDRS];
1907} __packed; 1931} __packed;
1908 1932
1909enum ath6kl_wow_filters { 1933enum ath6kl_wow_filters {
@@ -2105,6 +2129,19 @@ struct wmi_rx_frame_format_cmd {
2105} __packed; 2129} __packed;
2106 2130
2107/* AP mode events */ 2131/* AP mode events */
2132struct wmi_ap_set_apsd_cmd {
2133 u8 enable;
2134} __packed;
2135
2136enum wmi_ap_apsd_buffered_traffic_flags {
2137 WMI_AP_APSD_NO_DELIVERY_FRAMES = 0x1,
2138};
2139
2140struct wmi_ap_apsd_buffered_traffic_cmd {
2141 __le16 aid;
2142 __le16 bitmap;
2143 __le32 flags;
2144} __packed;
2108 2145
2109/* WMI_PS_POLL_EVENT */ 2146/* WMI_PS_POLL_EVENT */
2110struct wmi_pspoll_event { 2147struct wmi_pspoll_event {
@@ -2321,7 +2358,7 @@ enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi);
2321void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id); 2358void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id);
2322int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb); 2359int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb);
2323int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb, 2360int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
2324 u8 msg_type, bool more_data, 2361 u8 msg_type, u32 flags,
2325 enum wmi_data_hdr_data_type data_type, 2362 enum wmi_data_hdr_data_type data_type,
2326 u8 meta_ver, void *tx_meta_info, u8 if_idx); 2363 u8 meta_ver, void *tx_meta_info, u8 if_idx);
2327 2364
@@ -2417,7 +2454,8 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
2417 2454
2418s32 ath6kl_wmi_get_rate(s8 rate_index); 2455s32 ath6kl_wmi_get_rate(s8 rate_index);
2419 2456
2420int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd); 2457int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
2458 __be32 ips0, __be32 ips1);
2421int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, 2459int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
2422 enum ath6kl_host_mode host_mode); 2460 enum ath6kl_host_mode host_mode);
2423int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, 2461int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
@@ -2425,13 +2463,26 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
2425 u32 filter, u16 host_req_delay); 2463 u32 filter, u16 host_req_delay);
2426int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, 2464int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
2427 u8 list_id, u8 filter_size, 2465 u8 list_id, u8 filter_size,
2428 u8 filter_offset, u8 *filter, u8 *mask); 2466 u8 filter_offset, const u8 *filter,
2467 const u8 *mask);
2429int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, 2468int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
2430 u16 list_id, u16 filter_id); 2469 u16 list_id, u16 filter_id);
2431int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); 2470int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
2432int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); 2471int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid);
2433int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode); 2472int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode);
2473int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);
2474int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
2475 u8 *filter, bool add_filter);
2476/* AP mode uAPSD */
2477int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable);
2478
2479int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi,
2480 u8 if_idx, u16 aid,
2481 u16 bitmap, u32 flags);
2482
2483u8 ath6kl_wmi_get_traffic_class(u8 user_priority);
2434 2484
2485u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri);
2435/* AP mode */ 2486/* AP mode */
2436int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, 2487int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx,
2437 struct wmi_connect_cmd *p); 2488 struct wmi_connect_cmd *p);
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index f317515d8bf3..424aabb2c730 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -981,7 +981,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
981 return -ENOMEM; 981 return -ENOMEM;
982 982
983 while (len) { 983 while (len) {
984 transfer = min_t(int, len, 4096); 984 transfer = min_t(size_t, len, 4096);
985 memcpy(buf, data, transfer); 985 memcpy(buf, data, transfer);
986 986
987 err = usb_control_msg(hif_dev->udev, 987 err = usb_control_msg(hif_dev->udev,
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 635b592ad961..a427a16bb739 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1346,7 +1346,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1346 fc = hdr->frame_control; 1346 fc = hdr->frame_control;
1347 for (i = 0; i < sc->hw->max_rates; i++) { 1347 for (i = 0; i < sc->hw->max_rates; i++) {
1348 struct ieee80211_tx_rate *rate = &tx_info->status.rates[i]; 1348 struct ieee80211_tx_rate *rate = &tx_info->status.rates[i];
1349 if (!rate->count) 1349 if (rate->idx < 0 || !rate->count)
1350 break; 1350 break;
1351 1351
1352 final_ts_idx = i; 1352 final_ts_idx = i;