aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath6kl
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl')
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c228
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.h2
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h41
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_mbox.c2
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c28
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c28
-rw-r--r--drivers/net/wireless/ath/ath6kl/target.h1
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c48
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c148
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h58
10 files changed, 472 insertions, 112 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index b869a358ce4..fd7dbd4609d 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -53,6 +53,11 @@
53 53
54#define DEFAULT_BG_SCAN_PERIOD 60 54#define DEFAULT_BG_SCAN_PERIOD 60
55 55
56struct ath6kl_cfg80211_match_probe_ssid {
57 struct cfg80211_ssid ssid;
58 u8 flag;
59};
60
56static struct ieee80211_rate ath6kl_rates[] = { 61static struct ieee80211_rate ath6kl_rates[] = {
57 RATETAB_ENT(10, 0x1, 0), 62 RATETAB_ENT(10, 0x1, 0),
58 RATETAB_ENT(20, 0x2, 0), 63 RATETAB_ENT(20, 0x2, 0),
@@ -576,6 +581,9 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
576 581
577 vif->nw_type = vif->next_mode; 582 vif->nw_type = vif->next_mode;
578 583
584 /* enable enhanced bmiss detection if applicable */
585 ath6kl_cfg80211_sta_bmiss_enhance(vif, true);
586
579 if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) 587 if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
580 nw_subtype = SUBTYPE_P2PCLIENT; 588 nw_subtype = SUBTYPE_P2PCLIENT;
581 589
@@ -852,20 +860,6 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
852 } 860 }
853 } 861 }
854 862
855 /*
856 * Send a disconnect command to target when a disconnect event is
857 * received with reason code other than 3 (DISCONNECT_CMD - disconnect
858 * request from host) to make the firmware stop trying to connect even
859 * after giving disconnect event. There will be one more disconnect
860 * event for this disconnect command with reason code DISCONNECT_CMD
861 * which will be notified to cfg80211.
862 */
863
864 if (reason != DISCONNECT_CMD) {
865 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
866 return;
867 }
868
869 clear_bit(CONNECT_PEND, &vif->flags); 863 clear_bit(CONNECT_PEND, &vif->flags);
870 864
871 if (vif->sme_state == SME_CONNECTING) { 865 if (vif->sme_state == SME_CONNECTING) {
@@ -875,32 +869,96 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
875 WLAN_STATUS_UNSPECIFIED_FAILURE, 869 WLAN_STATUS_UNSPECIFIED_FAILURE,
876 GFP_KERNEL); 870 GFP_KERNEL);
877 } else if (vif->sme_state == SME_CONNECTED) { 871 } else if (vif->sme_state == SME_CONNECTED) {
878 cfg80211_disconnected(vif->ndev, reason, 872 cfg80211_disconnected(vif->ndev, proto_reason,
879 NULL, 0, GFP_KERNEL); 873 NULL, 0, GFP_KERNEL);
880 } 874 }
881 875
882 vif->sme_state = SME_DISCONNECTED; 876 vif->sme_state = SME_DISCONNECTED;
877
878 /*
879 * Send a disconnect command to target when a disconnect event is
880 * received with reason code other than 3 (DISCONNECT_CMD - disconnect
881 * request from host) to make the firmware stop trying to connect even
882 * after giving disconnect event. There will be one more disconnect
883 * event for this disconnect command with reason code DISCONNECT_CMD
884 * which won't be notified to cfg80211.
885 */
886 if (reason != DISCONNECT_CMD)
887 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
883} 888}
884 889
885static int ath6kl_set_probed_ssids(struct ath6kl *ar, 890static int ath6kl_set_probed_ssids(struct ath6kl *ar,
886 struct ath6kl_vif *vif, 891 struct ath6kl_vif *vif,
887 struct cfg80211_ssid *ssids, int n_ssids) 892 struct cfg80211_ssid *ssids, int n_ssids,
893 struct cfg80211_match_set *match_set,
894 int n_match_ssid)
888{ 895{
889 u8 i; 896 u8 i, j, index_to_add, ssid_found = false;
897 struct ath6kl_cfg80211_match_probe_ssid ssid_list[MAX_PROBED_SSIDS];
890 898
891 if (n_ssids > MAX_PROBED_SSID_INDEX) 899 memset(ssid_list, 0, sizeof(ssid_list));
900
901 if (n_ssids > MAX_PROBED_SSIDS ||
902 n_match_ssid > MAX_PROBED_SSIDS)
892 return -EINVAL; 903 return -EINVAL;
893 904
894 for (i = 0; i < n_ssids; i++) { 905 for (i = 0; i < n_ssids; i++) {
906 memcpy(ssid_list[i].ssid.ssid,
907 ssids[i].ssid,
908 ssids[i].ssid_len);
909 ssid_list[i].ssid.ssid_len = ssids[i].ssid_len;
910
911 if (ssids[i].ssid_len)
912 ssid_list[i].flag = SPECIFIC_SSID_FLAG;
913 else
914 ssid_list[i].flag = ANY_SSID_FLAG;
915
916 if (n_match_ssid == 0)
917 ssid_list[i].flag |= MATCH_SSID_FLAG;
918 }
919
920 index_to_add = i;
921
922 for (i = 0; i < n_match_ssid; i++) {
923 ssid_found = false;
924
925 for (j = 0; j < n_ssids; j++) {
926 if ((match_set[i].ssid.ssid_len ==
927 ssid_list[j].ssid.ssid_len) &&
928 (!memcmp(ssid_list[j].ssid.ssid,
929 match_set[i].ssid.ssid,
930 match_set[i].ssid.ssid_len))) {
931 ssid_list[j].flag |= MATCH_SSID_FLAG;
932 ssid_found = true;
933 break;
934 }
935 }
936
937 if (ssid_found)
938 continue;
939
940 if (index_to_add >= MAX_PROBED_SSIDS)
941 continue;
942
943 ssid_list[index_to_add].ssid.ssid_len =
944 match_set[i].ssid.ssid_len;
945 memcpy(ssid_list[index_to_add].ssid.ssid,
946 match_set[i].ssid.ssid,
947 match_set[i].ssid.ssid_len);
948 ssid_list[index_to_add].flag |= MATCH_SSID_FLAG;
949 index_to_add++;
950 }
951
952 for (i = 0; i < index_to_add; i++) {
895 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i, 953 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
896 ssids[i].ssid_len ? 954 ssid_list[i].flag,
897 SPECIFIC_SSID_FLAG : ANY_SSID_FLAG, 955 ssid_list[i].ssid.ssid_len,
898 ssids[i].ssid_len, 956 ssid_list[i].ssid.ssid);
899 ssids[i].ssid); 957
900 } 958 }
901 959
902 /* Make sure no old entries are left behind */ 960 /* Make sure no old entries are left behind */
903 for (i = n_ssids; i < MAX_PROBED_SSID_INDEX; i++) { 961 for (i = index_to_add; i < MAX_PROBED_SSIDS; i++) {
904 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i, 962 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
905 DISABLE_SSID_FLAG, 0, NULL); 963 DISABLE_SSID_FLAG, 0, NULL);
906 } 964 }
@@ -934,7 +992,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
934 } 992 }
935 993
936 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, 994 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
937 request->n_ssids); 995 request->n_ssids, NULL, 0);
938 if (ret < 0) 996 if (ret < 0)
939 return ret; 997 return ret;
940 998
@@ -943,7 +1001,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
943 WMI_FRAME_PROBE_REQ, 1001 WMI_FRAME_PROBE_REQ,
944 request->ie, request->ie_len); 1002 request->ie, request->ie_len);
945 if (ret) { 1003 if (ret) {
946 ath6kl_err("failed to set Probe Request appie for scan"); 1004 ath6kl_err("failed to set Probe Request appie for scan\n");
947 return ret; 1005 return ret;
948 } 1006 }
949 1007
@@ -1512,6 +1570,9 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1512 } 1570 }
1513 } 1571 }
1514 1572
1573 /* need to clean up enhanced bmiss detection fw state */
1574 ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
1575
1515set_iface_type: 1576set_iface_type:
1516 switch (type) { 1577 switch (type) {
1517 case NL80211_IFTYPE_STATION: 1578 case NL80211_IFTYPE_STATION:
@@ -2074,7 +2135,9 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2074 if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) 2135 if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
2075 return -EINVAL; 2136 return -EINVAL;
2076 2137
2077 if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags)) { 2138 if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) &&
2139 test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2140 ar->fw_capabilities)) {
2078 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, 2141 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2079 vif->fw_vif_idx, false); 2142 vif->fw_vif_idx, false);
2080 if (ret) 2143 if (ret)
@@ -2209,7 +2272,9 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
2209 2272
2210 ar->state = ATH6KL_STATE_ON; 2273 ar->state = ATH6KL_STATE_ON;
2211 2274
2212 if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags)) { 2275 if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) &&
2276 test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2277 ar->fw_capabilities)) {
2213 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, 2278 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2214 vif->fw_vif_idx, true); 2279 vif->fw_vif_idx, true);
2215 if (ret) 2280 if (ret)
@@ -2475,7 +2540,7 @@ void ath6kl_check_wow_status(struct ath6kl *ar)
2475static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band, 2540static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band,
2476 bool ht_enable) 2541 bool ht_enable)
2477{ 2542{
2478 struct ath6kl_htcap *htcap = &vif->htcap; 2543 struct ath6kl_htcap *htcap = &vif->htcap[band];
2479 2544
2480 if (htcap->ht_enable == ht_enable) 2545 if (htcap->ht_enable == ht_enable)
2481 return 0; 2546 return 0;
@@ -2585,33 +2650,28 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif,
2585 return 0; 2650 return 0;
2586} 2651}
2587 2652
2588static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev, 2653void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable)
2589 struct ieee80211_channel *chan,
2590 enum nl80211_channel_type channel_type)
2591{ 2654{
2592 struct ath6kl_vif *vif; 2655 int err;
2593 2656
2594 /* 2657 if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag)))
2595 * 'dev' could be NULL if a channel change is required for the hardware 2658 return;
2596 * device itself, instead of a particular VIF.
2597 *
2598 * FIXME: To be handled properly when monitor mode is supported.
2599 */
2600 if (!dev)
2601 return -EBUSY;
2602 2659
2603 vif = netdev_priv(dev); 2660 if (vif->nw_type != INFRA_NETWORK)
2661 return;
2604 2662
2605 if (!ath6kl_cfg80211_ready(vif)) 2663 if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
2606 return -EIO; 2664 vif->ar->fw_capabilities))
2665 return;
2607 2666
2608 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n", 2667 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n",
2609 __func__, chan->center_freq, chan->hw_value); 2668 enable ? "enable" : "disable");
2610 vif->next_chan = chan->center_freq;
2611 vif->next_ch_type = channel_type;
2612 vif->next_ch_band = chan->band;
2613 2669
2614 return 0; 2670 err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi,
2671 vif->fw_vif_idx, enable);
2672 if (err)
2673 ath6kl_err("failed to %s enhanced bmiss detection: %d\n",
2674 enable ? "enable" : "disable", err);
2615} 2675}
2616 2676
2617static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon, 2677static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
@@ -2694,9 +2754,15 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2694 2754
2695 /* TODO: 2755 /* TODO:
2696 * info->interval 2756 * info->interval
2697 * info->dtim_period
2698 */ 2757 */
2699 2758
2759 ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
2760 info->dtim_period);
2761
2762 /* ignore error, just print a warning and continue normally */
2763 if (ret)
2764 ath6kl_warn("Failed to set dtim_period in beacon: %d\n", ret);
2765
2700 if (info->beacon.head == NULL) 2766 if (info->beacon.head == NULL)
2701 return -EINVAL; 2767 return -EINVAL;
2702 mgmt = (struct ieee80211_mgmt *) info->beacon.head; 2768 mgmt = (struct ieee80211_mgmt *) info->beacon.head;
@@ -2791,7 +2857,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2791 p.ssid_len = vif->ssid_len; 2857 p.ssid_len = vif->ssid_len;
2792 memcpy(p.ssid, vif->ssid, vif->ssid_len); 2858 memcpy(p.ssid, vif->ssid, vif->ssid_len);
2793 p.dot11_auth_mode = vif->dot11_auth_mode; 2859 p.dot11_auth_mode = vif->dot11_auth_mode;
2794 p.ch = cpu_to_le16(vif->next_chan); 2860 p.ch = cpu_to_le16(info->channel->center_freq);
2795 2861
2796 /* Enable uAPSD support by default */ 2862 /* Enable uAPSD support by default */
2797 res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); 2863 res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
@@ -2815,8 +2881,8 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2815 return res; 2881 return res;
2816 } 2882 }
2817 2883
2818 if (ath6kl_set_htcap(vif, vif->next_ch_band, 2884 if (ath6kl_set_htcap(vif, info->channel->band,
2819 vif->next_ch_type != NL80211_CHAN_NO_HT)) 2885 info->channel_type != NL80211_CHAN_NO_HT))
2820 return -EIO; 2886 return -EIO;
2821 2887
2822 /* 2888 /*
@@ -3160,10 +3226,24 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3160 ath6kl_cfg80211_scan_complete_event(vif, true); 3226 ath6kl_cfg80211_scan_complete_event(vif, true);
3161 3227
3162 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, 3228 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
3163 request->n_ssids); 3229 request->n_ssids,
3230 request->match_sets,
3231 request->n_match_sets);
3164 if (ret < 0) 3232 if (ret < 0)
3165 return ret; 3233 return ret;
3166 3234
3235 if (!request->n_match_sets) {
3236 ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3237 ALL_BSS_FILTER, 0);
3238 if (ret < 0)
3239 return ret;
3240 } else {
3241 ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3242 MATCHED_SSID_FILTER, 0);
3243 if (ret < 0)
3244 return ret;
3245 }
3246
3167 /* fw uses seconds, also make sure that it's >0 */ 3247 /* fw uses seconds, also make sure that it's >0 */
3168 interval = max_t(u16, 1, request->interval / 1000); 3248 interval = max_t(u16, 1, request->interval / 1000);
3169 3249
@@ -3185,7 +3265,7 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3185 WMI_FRAME_PROBE_REQ, 3265 WMI_FRAME_PROBE_REQ,
3186 request->ie, request->ie_len); 3266 request->ie, request->ie_len);
3187 if (ret) { 3267 if (ret) {
3188 ath6kl_warn("Failed to set probe request IE for scheduled scan: %d", 3268 ath6kl_warn("Failed to set probe request IE for scheduled scan: %d\n",
3189 ret); 3269 ret);
3190 return ret; 3270 return ret;
3191 } 3271 }
@@ -3217,6 +3297,18 @@ static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
3217 return 0; 3297 return 0;
3218} 3298}
3219 3299
3300static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
3301 struct net_device *dev,
3302 const u8 *addr,
3303 const struct cfg80211_bitrate_mask *mask)
3304{
3305 struct ath6kl *ar = ath6kl_priv(dev);
3306 struct ath6kl_vif *vif = netdev_priv(dev);
3307
3308 return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx,
3309 mask);
3310}
3311
3220static const struct ieee80211_txrx_stypes 3312static const struct ieee80211_txrx_stypes
3221ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { 3313ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
3222 [NL80211_IFTYPE_STATION] = { 3314 [NL80211_IFTYPE_STATION] = {
@@ -3271,7 +3363,6 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
3271 .suspend = __ath6kl_cfg80211_suspend, 3363 .suspend = __ath6kl_cfg80211_suspend,
3272 .resume = __ath6kl_cfg80211_resume, 3364 .resume = __ath6kl_cfg80211_resume,
3273#endif 3365#endif
3274 .set_channel = ath6kl_set_channel,
3275 .start_ap = ath6kl_start_ap, 3366 .start_ap = ath6kl_start_ap,
3276 .change_beacon = ath6kl_change_beacon, 3367 .change_beacon = ath6kl_change_beacon,
3277 .stop_ap = ath6kl_stop_ap, 3368 .stop_ap = ath6kl_stop_ap,
@@ -3283,6 +3374,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
3283 .mgmt_frame_register = ath6kl_mgmt_frame_register, 3374 .mgmt_frame_register = ath6kl_mgmt_frame_register,
3284 .sched_scan_start = ath6kl_cfg80211_sscan_start, 3375 .sched_scan_start = ath6kl_cfg80211_sscan_start,
3285 .sched_scan_stop = ath6kl_cfg80211_sscan_stop, 3376 .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
3377 .set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
3286}; 3378};
3287 3379
3288void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) 3380void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
@@ -3410,7 +3502,8 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
3410 vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL; 3502 vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
3411 vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME; 3503 vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
3412 vif->bg_scan_period = 0; 3504 vif->bg_scan_period = 0;
3413 vif->htcap.ht_enable = true; 3505 vif->htcap[IEEE80211_BAND_2GHZ].ht_enable = true;
3506 vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true;
3414 3507
3415 memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); 3508 memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
3416 if (fw_vif_idx != 0) 3509 if (fw_vif_idx != 0)
@@ -3470,7 +3563,13 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
3470 } 3563 }
3471 3564
3472 /* max num of ssids that can be probed during scanning */ 3565 /* max num of ssids that can be probed during scanning */
3473 wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; 3566 wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
3567
3568 /* max num of ssids that can be matched after scan */
3569 if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
3570 ar->fw_capabilities))
3571 wiphy->max_match_sets = MAX_PROBED_SSIDS;
3572
3474 wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ 3573 wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
3475 switch (ar->hw.cap) { 3574 switch (ar->hw.cap) {
3476 case WMI_11AN_CAP: 3575 case WMI_11AN_CAP:
@@ -3507,6 +3606,17 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
3507 ath6kl_band_5ghz.ht_cap.cap = 0; 3606 ath6kl_band_5ghz.ht_cap.cap = 0;
3508 ath6kl_band_5ghz.ht_cap.ht_supported = false; 3607 ath6kl_band_5ghz.ht_cap.ht_supported = false;
3509 } 3608 }
3609
3610 if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) {
3611 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3612 ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3613 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3614 ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3615 } else {
3616 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3617 ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3618 }
3619
3510 if (band_2gig) 3620 if (band_2gig)
3511 wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; 3621 wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
3512 if (band_5gig) 3622 if (band_5gig)
@@ -3527,7 +3637,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
3527 wiphy->wowlan.pattern_min_len = 1; 3637 wiphy->wowlan.pattern_min_len = 1;
3528 wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; 3638 wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
3529 3639
3530 wiphy->max_sched_scan_ssids = MAX_PROBED_SSID_INDEX; 3640 wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
3531 3641
3532 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | 3642 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
3533 WIPHY_FLAG_HAVE_AP_SME | 3643 WIPHY_FLAG_HAVE_AP_SME |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h
index 5ea8cbb79f4..b992046a1b0 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.h
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h
@@ -62,5 +62,7 @@ void ath6kl_cfg80211_cleanup(struct ath6kl *ar);
62 62
63struct ath6kl *ath6kl_cfg80211_create(void); 63struct ath6kl *ath6kl_cfg80211_create(void);
64void ath6kl_cfg80211_destroy(struct ath6kl *ar); 64void ath6kl_cfg80211_destroy(struct ath6kl *ar);
65/* TODO: remove this once ath6kl_vif_cleanup() is moved to cfg80211.c */
66void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable);
65 67
66#endif /* ATH6KL_CFG80211_H */ 68#endif /* ATH6KL_CFG80211_H */
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 4d9c6f14269..d38a31de344 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -100,6 +100,21 @@ enum ath6kl_fw_capability {
100 /* Firmware has support to override rsn cap of rsn ie */ 100 /* Firmware has support to override rsn cap of rsn ie */
101 ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, 101 ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
102 102
103 /*
104 * Multicast support in WOW and host awake mode.
105 * Allow all multicast in host awake mode.
106 * Apply multicast filter in WOW mode.
107 */
108 ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
109
110 /* Firmware supports enhanced bmiss detection */
111 ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
112
113 /*
114 * FW supports matching of ssid in schedule scan
115 */
116 ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
117
103 /* this needs to be last */ 118 /* this needs to be last */
104 ATH6KL_FW_CAPABILITY_MAX, 119 ATH6KL_FW_CAPABILITY_MAX,
105}; 120};
@@ -112,6 +127,10 @@ struct ath6kl_fw_ie {
112 u8 data[0]; 127 u8 data[0];
113}; 128};
114 129
130enum ath6kl_hw_flags {
131 ATH6KL_HW_FLAG_64BIT_RATES = BIT(0),
132};
133
115#define ATH6KL_FW_API2_FILE "fw-2.bin" 134#define ATH6KL_FW_API2_FILE "fw-2.bin"
116#define ATH6KL_FW_API3_FILE "fw-3.bin" 135#define ATH6KL_FW_API3_FILE "fw-3.bin"
117 136
@@ -196,7 +215,7 @@ struct ath6kl_fw_ie {
196 215
197#define AGGR_NUM_OF_FREE_NETBUFS 16 216#define AGGR_NUM_OF_FREE_NETBUFS 16
198 217
199#define AGGR_RX_TIMEOUT 400 /* in ms */ 218#define AGGR_RX_TIMEOUT 100 /* in ms */
200 219
201#define WMI_TIMEOUT (2 * HZ) 220#define WMI_TIMEOUT (2 * HZ)
202 221
@@ -245,7 +264,6 @@ struct skb_hold_q {
245 264
246struct rxtid { 265struct rxtid {
247 bool aggr; 266 bool aggr;
248 bool progress;
249 bool timer_mon; 267 bool timer_mon;
250 u16 win_sz; 268 u16 win_sz;
251 u16 seq_next; 269 u16 seq_next;
@@ -254,9 +272,15 @@ struct rxtid {
254 struct sk_buff_head q; 272 struct sk_buff_head q;
255 273
256 /* 274 /*
257 * FIXME: No clue what this should protect. Apparently it should 275 * lock mainly protects seq_next and hold_q. Movement of seq_next
258 * protect some of the fields above but they are also accessed 276 * needs to be protected between aggr_timeout() and
259 * without taking the lock. 277 * aggr_process_recv_frm(). hold_q will be holding the pending
278 * reorder frames and it's access should also be protected.
279 * Some of the other fields like hold_q_sz, win_sz and aggr are
280 * initialized/reset when receiving addba/delba req, also while
281 * deleting aggr state all the pending buffers are flushed before
282 * resetting these fields, so there should not be any race in accessing
283 * these fields.
260 */ 284 */
261 spinlock_t lock; 285 spinlock_t lock;
262}; 286};
@@ -541,7 +565,7 @@ struct ath6kl_vif {
541 struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1]; 565 struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
542 struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1]; 566 struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
543 struct aggr_info *aggr_cntxt; 567 struct aggr_info *aggr_cntxt;
544 struct ath6kl_htcap htcap; 568 struct ath6kl_htcap htcap[IEEE80211_NUM_BANDS];
545 569
546 struct timer_list disconnect_timer; 570 struct timer_list disconnect_timer;
547 struct timer_list sched_scan_timer; 571 struct timer_list sched_scan_timer;
@@ -553,9 +577,6 @@ struct ath6kl_vif {
553 u32 last_cancel_roc_id; 577 u32 last_cancel_roc_id;
554 u32 send_action_id; 578 u32 send_action_id;
555 bool probe_req_report; 579 bool probe_req_report;
556 u16 next_chan;
557 enum nl80211_channel_type next_ch_type;
558 enum ieee80211_band next_ch_band;
559 u16 assoc_bss_beacon_int; 580 u16 assoc_bss_beacon_int;
560 u16 listen_intvl_t; 581 u16 listen_intvl_t;
561 u16 bmiss_time_t; 582 u16 bmiss_time_t;
@@ -687,6 +708,8 @@ struct ath6kl {
687 u32 testscript_addr; 708 u32 testscript_addr;
688 enum wmi_phy_cap cap; 709 enum wmi_phy_cap cap;
689 710
711 u32 flags;
712
690 struct ath6kl_hw_fw { 713 struct ath6kl_hw_fw {
691 const char *dir; 714 const char *dir;
692 const char *otp; 715 const char *otp;
diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
index 2798624d3a9..cd0e1ba410d 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
@@ -1309,7 +1309,7 @@ static int ath6kl_htc_rx_packet(struct htc_target *target,
1309 } 1309 }
1310 1310
1311 ath6kl_dbg(ATH6KL_DBG_HTC, 1311 ath6kl_dbg(ATH6KL_DBG_HTC,
1312 "htc rx 0x%p hdr x%x len %d mbox 0x%x\n", 1312 "htc rx 0x%p hdr 0x%x len %d mbox 0x%x\n",
1313 packet, packet->info.rx.exp_hdr, 1313 packet, packet->info.rx.exp_hdr,
1314 padded_len, dev->ar->mbox_info.htc_addr); 1314 padded_len, dev->ar->mbox_info.htc_addr);
1315 1315
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 7eb0515f458..f90b5db741c 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -42,6 +42,7 @@ static const struct ath6kl_hw hw_list[] = {
42 .reserved_ram_size = 6912, 42 .reserved_ram_size = 6912,
43 .refclk_hz = 26000000, 43 .refclk_hz = 26000000,
44 .uarttx_pin = 8, 44 .uarttx_pin = 8,
45 .flags = 0,
45 46
46 /* hw2.0 needs override address hardcoded */ 47 /* hw2.0 needs override address hardcoded */
47 .app_start_override_addr = 0x944C00, 48 .app_start_override_addr = 0x944C00,
@@ -67,6 +68,7 @@ static const struct ath6kl_hw hw_list[] = {
67 .refclk_hz = 26000000, 68 .refclk_hz = 26000000,
68 .uarttx_pin = 8, 69 .uarttx_pin = 8,
69 .testscript_addr = 0x57ef74, 70 .testscript_addr = 0x57ef74,
71 .flags = 0,
70 72
71 .fw = { 73 .fw = {
72 .dir = AR6003_HW_2_1_1_FW_DIR, 74 .dir = AR6003_HW_2_1_1_FW_DIR,
@@ -91,6 +93,7 @@ static const struct ath6kl_hw hw_list[] = {
91 .board_addr = 0x433900, 93 .board_addr = 0x433900,
92 .refclk_hz = 26000000, 94 .refclk_hz = 26000000,
93 .uarttx_pin = 11, 95 .uarttx_pin = 11,
96 .flags = ATH6KL_HW_FLAG_64BIT_RATES,
94 97
95 .fw = { 98 .fw = {
96 .dir = AR6004_HW_1_0_FW_DIR, 99 .dir = AR6004_HW_1_0_FW_DIR,
@@ -110,6 +113,7 @@ static const struct ath6kl_hw hw_list[] = {
110 .board_addr = 0x43d400, 113 .board_addr = 0x43d400,
111 .refclk_hz = 40000000, 114 .refclk_hz = 40000000,
112 .uarttx_pin = 11, 115 .uarttx_pin = 11,
116 .flags = ATH6KL_HW_FLAG_64BIT_RATES,
113 117
114 .fw = { 118 .fw = {
115 .dir = AR6004_HW_1_1_FW_DIR, 119 .dir = AR6004_HW_1_1_FW_DIR,
@@ -129,6 +133,7 @@ static const struct ath6kl_hw hw_list[] = {
129 .board_addr = 0x435c00, 133 .board_addr = 0x435c00,
130 .refclk_hz = 40000000, 134 .refclk_hz = 40000000,
131 .uarttx_pin = 11, 135 .uarttx_pin = 11,
136 .flags = ATH6KL_HW_FLAG_64BIT_RATES,
132 137
133 .fw = { 138 .fw = {
134 .dir = AR6004_HW_1_2_FW_DIR, 139 .dir = AR6004_HW_1_2_FW_DIR,
@@ -938,6 +943,14 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
938 } 943 }
939 944
940 switch (ie_id) { 945 switch (ie_id) {
946 case ATH6KL_FW_IE_FW_VERSION:
947 strlcpy(ar->wiphy->fw_version, data,
948 sizeof(ar->wiphy->fw_version));
949
950 ath6kl_dbg(ATH6KL_DBG_BOOT,
951 "found fw version %s\n",
952 ar->wiphy->fw_version);
953 break;
941 case ATH6KL_FW_IE_OTP_IMAGE: 954 case ATH6KL_FW_IE_OTP_IMAGE:
942 ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n", 955 ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n",
943 ie_len); 956 ie_len);
@@ -991,9 +1004,6 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
991 ar->hw.reserved_ram_size); 1004 ar->hw.reserved_ram_size);
992 break; 1005 break;
993 case ATH6KL_FW_IE_CAPABILITIES: 1006 case ATH6KL_FW_IE_CAPABILITIES:
994 if (ie_len < DIV_ROUND_UP(ATH6KL_FW_CAPABILITY_MAX, 8))
995 break;
996
997 ath6kl_dbg(ATH6KL_DBG_BOOT, 1007 ath6kl_dbg(ATH6KL_DBG_BOOT,
998 "found firmware capabilities ie (%zd B)\n", 1008 "found firmware capabilities ie (%zd B)\n",
999 ie_len); 1009 ie_len);
@@ -1002,6 +1012,9 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
1002 index = i / 8; 1012 index = i / 8;
1003 bit = i % 8; 1013 bit = i % 8;
1004 1014
1015 if (index == ie_len)
1016 break;
1017
1005 if (data[index] & (1 << bit)) 1018 if (data[index] & (1 << bit))
1006 __set_bit(i, ar->fw_capabilities); 1019 __set_bit(i, ar->fw_capabilities);
1007 } 1020 }
@@ -1392,6 +1405,12 @@ static int ath6kl_init_upload(struct ath6kl *ar)
1392 ar->version.target_ver == AR6003_HW_2_1_1_VERSION) { 1405 ar->version.target_ver == AR6003_HW_2_1_1_VERSION) {
1393 ath6kl_err("temporary war to avoid sdio crc error\n"); 1406 ath6kl_err("temporary war to avoid sdio crc error\n");
1394 1407
1408 param = 0x28;
1409 address = GPIO_BASE_ADDRESS + GPIO_PIN9_ADDRESS;
1410 status = ath6kl_bmi_reg_write(ar, address, param);
1411 if (status)
1412 return status;
1413
1395 param = 0x20; 1414 param = 0x20;
1396 1415
1397 address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS; 1416 address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
@@ -1659,6 +1678,9 @@ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
1659 cfg80211_scan_done(vif->scan_req, true); 1678 cfg80211_scan_done(vif->scan_req, true);
1660 vif->scan_req = NULL; 1679 vif->scan_req = NULL;
1661 } 1680 }
1681
1682 /* need to clean up enhanced bmiss detection fw state */
1683 ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
1662} 1684}
1663 1685
1664void ath6kl_stop_txrx(struct ath6kl *ar) 1686void ath6kl_stop_txrx(struct ath6kl *ar)
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index e5524470529..c189e28e86a 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -554,20 +554,24 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver,
554 struct ath6kl *ar = devt; 554 struct ath6kl *ar = devt;
555 555
556 memcpy(ar->mac_addr, datap, ETH_ALEN); 556 memcpy(ar->mac_addr, datap, ETH_ALEN);
557 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: mac addr = %pM\n", 557
558 __func__, ar->mac_addr); 558 ath6kl_dbg(ATH6KL_DBG_BOOT,
559 "ready event mac addr %pM sw_ver 0x%x abi_ver 0x%x cap 0x%x\n",
560 ar->mac_addr, sw_ver, abi_ver, cap);
559 561
560 ar->version.wlan_ver = sw_ver; 562 ar->version.wlan_ver = sw_ver;
561 ar->version.abi_ver = abi_ver; 563 ar->version.abi_ver = abi_ver;
562 ar->hw.cap = cap; 564 ar->hw.cap = cap;
563 565
564 snprintf(ar->wiphy->fw_version, 566 if (strlen(ar->wiphy->fw_version) == 0) {
565 sizeof(ar->wiphy->fw_version), 567 snprintf(ar->wiphy->fw_version,
566 "%u.%u.%u.%u", 568 sizeof(ar->wiphy->fw_version),
567 (ar->version.wlan_ver & 0xf0000000) >> 28, 569 "%u.%u.%u.%u",
568 (ar->version.wlan_ver & 0x0f000000) >> 24, 570 (ar->version.wlan_ver & 0xf0000000) >> 28,
569 (ar->version.wlan_ver & 0x00ff0000) >> 16, 571 (ar->version.wlan_ver & 0x0f000000) >> 24,
570 (ar->version.wlan_ver & 0x0000ffff)); 572 (ar->version.wlan_ver & 0x00ff0000) >> 16,
573 (ar->version.wlan_ver & 0x0000ffff));
574 }
571 575
572 /* indicate to the waiting thread that the ready event was received */ 576 /* indicate to the waiting thread that the ready event was received */
573 set_bit(WMI_READY, &ar->flag); 577 set_bit(WMI_READY, &ar->flag);
@@ -598,7 +602,6 @@ static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel)
598 602
599 struct ath6kl *ar = vif->ar; 603 struct ath6kl *ar = vif->ar;
600 604
601 vif->next_chan = channel;
602 vif->profile.ch = cpu_to_le16(channel); 605 vif->profile.ch = cpu_to_le16(channel);
603 606
604 switch (vif->nw_type) { 607 switch (vif->nw_type) {
@@ -1167,7 +1170,10 @@ static void ath6kl_set_multicast_list(struct net_device *ndev)
1167 else 1170 else
1168 clear_bit(NETDEV_MCAST_ALL_ON, &vif->flags); 1171 clear_bit(NETDEV_MCAST_ALL_ON, &vif->flags);
1169 1172
1170 mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON); 1173 if (test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
1174 vif->ar->fw_capabilities)) {
1175 mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON);
1176 }
1171 1177
1172 if (!(ndev->flags & IFF_MULTICAST)) { 1178 if (!(ndev->flags & IFF_MULTICAST)) {
1173 mc_all_on = false; 1179 mc_all_on = false;
diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h
index 78e0ef4567a..a98c12ba70c 100644
--- a/drivers/net/wireless/ath/ath6kl/target.h
+++ b/drivers/net/wireless/ath/ath6kl/target.h
@@ -45,6 +45,7 @@
45#define LPO_CAL_ENABLE_S 20 45#define LPO_CAL_ENABLE_S 20
46#define LPO_CAL_ENABLE 0x00100000 46#define LPO_CAL_ENABLE 0x00100000
47 47
48#define GPIO_PIN9_ADDRESS 0x0000004c
48#define GPIO_PIN10_ADDRESS 0x00000050 49#define GPIO_PIN10_ADDRESS 0x00000050
49#define GPIO_PIN11_ADDRESS 0x00000054 50#define GPIO_PIN11_ADDRESS 0x00000054
50#define GPIO_PIN12_ADDRESS 0x00000058 51#define GPIO_PIN12_ADDRESS 0x00000058
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 67206aedea6..7dfa0fd86d7 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -1036,6 +1036,7 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,
1036 rxtid = &agg_conn->rx_tid[tid]; 1036 rxtid = &agg_conn->rx_tid[tid];
1037 stats = &agg_conn->stat[tid]; 1037 stats = &agg_conn->stat[tid];
1038 1038
1039 spin_lock_bh(&rxtid->lock);
1039 idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz); 1040 idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
1040 1041
1041 /* 1042 /*
@@ -1054,8 +1055,6 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,
1054 seq_end = seq_no ? seq_no : rxtid->seq_next; 1055 seq_end = seq_no ? seq_no : rxtid->seq_next;
1055 idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz); 1056 idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);
1056 1057
1057 spin_lock_bh(&rxtid->lock);
1058
1059 do { 1058 do {
1060 node = &rxtid->hold_q[idx]; 1059 node = &rxtid->hold_q[idx];
1061 if ((order == 1) && (!node->skb)) 1060 if ((order == 1) && (!node->skb))
@@ -1127,11 +1126,13 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,
1127 ((end > extended_end) && (cur > extended_end) && 1126 ((end > extended_end) && (cur > extended_end) &&
1128 (cur < end))) { 1127 (cur < end))) {
1129 aggr_deque_frms(agg_conn, tid, 0, 0); 1128 aggr_deque_frms(agg_conn, tid, 0, 0);
1129 spin_lock_bh(&rxtid->lock);
1130 if (cur >= rxtid->hold_q_sz - 1) 1130 if (cur >= rxtid->hold_q_sz - 1)
1131 rxtid->seq_next = cur - (rxtid->hold_q_sz - 1); 1131 rxtid->seq_next = cur - (rxtid->hold_q_sz - 1);
1132 else 1132 else
1133 rxtid->seq_next = ATH6KL_MAX_SEQ_NO - 1133 rxtid->seq_next = ATH6KL_MAX_SEQ_NO -
1134 (rxtid->hold_q_sz - 2 - cur); 1134 (rxtid->hold_q_sz - 2 - cur);
1135 spin_unlock_bh(&rxtid->lock);
1135 } else { 1136 } else {
1136 /* 1137 /*
1137 * Dequeue only those frames that are outside the 1138 * Dequeue only those frames that are outside the
@@ -1185,25 +1186,25 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,
1185 aggr_deque_frms(agg_conn, tid, 0, 1); 1186 aggr_deque_frms(agg_conn, tid, 0, 1);
1186 1187
1187 if (agg_conn->timer_scheduled) 1188 if (agg_conn->timer_scheduled)
1188 rxtid->progress = true; 1189 return is_queued;
1189 else 1190
1190 for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) { 1191 spin_lock_bh(&rxtid->lock);
1191 if (rxtid->hold_q[idx].skb) { 1192 for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
1192 /* 1193 if (rxtid->hold_q[idx].skb) {
1193 * There is a frame in the queue and no 1194 /*
1194 * timer so start a timer to ensure that 1195 * There is a frame in the queue and no
1195 * the frame doesn't remain stuck 1196 * timer so start a timer to ensure that
1196 * forever. 1197 * the frame doesn't remain stuck
1197 */ 1198 * forever.
1198 agg_conn->timer_scheduled = true; 1199 */
1199 mod_timer(&agg_conn->timer, 1200 agg_conn->timer_scheduled = true;
1200 (jiffies + 1201 mod_timer(&agg_conn->timer,
1201 HZ * (AGGR_RX_TIMEOUT) / 1000)); 1202 (jiffies + (HZ * AGGR_RX_TIMEOUT) / 1000));
1202 rxtid->progress = false; 1203 rxtid->timer_mon = true;
1203 rxtid->timer_mon = true; 1204 break;
1204 break;
1205 }
1206 } 1205 }
1206 }
1207 spin_unlock_bh(&rxtid->lock);
1207 1208
1208 return is_queued; 1209 return is_queued;
1209} 1210}
@@ -1608,7 +1609,7 @@ static void aggr_timeout(unsigned long arg)
1608 rxtid = &aggr_conn->rx_tid[i]; 1609 rxtid = &aggr_conn->rx_tid[i];
1609 stats = &aggr_conn->stat[i]; 1610 stats = &aggr_conn->stat[i];
1610 1611
1611 if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress) 1612 if (!rxtid->aggr || !rxtid->timer_mon)
1612 continue; 1613 continue;
1613 1614
1614 stats->num_timeouts++; 1615 stats->num_timeouts++;
@@ -1626,14 +1627,15 @@ static void aggr_timeout(unsigned long arg)
1626 rxtid = &aggr_conn->rx_tid[i]; 1627 rxtid = &aggr_conn->rx_tid[i];
1627 1628
1628 if (rxtid->aggr && rxtid->hold_q) { 1629 if (rxtid->aggr && rxtid->hold_q) {
1630 spin_lock_bh(&rxtid->lock);
1629 for (j = 0; j < rxtid->hold_q_sz; j++) { 1631 for (j = 0; j < rxtid->hold_q_sz; j++) {
1630 if (rxtid->hold_q[j].skb) { 1632 if (rxtid->hold_q[j].skb) {
1631 aggr_conn->timer_scheduled = true; 1633 aggr_conn->timer_scheduled = true;
1632 rxtid->timer_mon = true; 1634 rxtid->timer_mon = true;
1633 rxtid->progress = false;
1634 break; 1635 break;
1635 } 1636 }
1636 } 1637 }
1638 spin_unlock_bh(&rxtid->lock);
1637 1639
1638 if (j >= rxtid->hold_q_sz) 1640 if (j >= rxtid->hold_q_sz)
1639 rxtid->timer_mon = false; 1641 rxtid->timer_mon = false;
@@ -1660,7 +1662,6 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid)
1660 aggr_deque_frms(aggr_conn, tid, 0, 0); 1662 aggr_deque_frms(aggr_conn, tid, 0, 0);
1661 1663
1662 rxtid->aggr = false; 1664 rxtid->aggr = false;
1663 rxtid->progress = false;
1664 rxtid->timer_mon = false; 1665 rxtid->timer_mon = false;
1665 rxtid->win_sz = 0; 1666 rxtid->win_sz = 0;
1666 rxtid->seq_next = 0; 1667 rxtid->seq_next = 0;
@@ -1739,7 +1740,6 @@ void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
1739 for (i = 0; i < NUM_OF_TIDS; i++) { 1740 for (i = 0; i < NUM_OF_TIDS; i++) {
1740 rxtid = &aggr_conn->rx_tid[i]; 1741 rxtid = &aggr_conn->rx_tid[i];
1741 rxtid->aggr = false; 1742 rxtid->aggr = false;
1742 rxtid->progress = false;
1743 rxtid->timer_mon = false; 1743 rxtid->timer_mon = false;
1744 skb_queue_head_init(&rxtid->q); 1744 skb_queue_head_init(&rxtid->q);
1745 spin_lock_init(&rxtid->lock); 1745 spin_lock_init(&rxtid->lock);
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index ee8ec2394c2..a6caa673e8a 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -743,7 +743,6 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid)
743 return -ENOMEM; 743 return -ENOMEM;
744 744
745 cmd = (struct roam_ctrl_cmd *) skb->data; 745 cmd = (struct roam_ctrl_cmd *) skb->data;
746 memset(cmd, 0, sizeof(*cmd));
747 746
748 memcpy(cmd->info.bssid, bssid, ETH_ALEN); 747 memcpy(cmd->info.bssid, bssid, ETH_ALEN);
749 cmd->roam_ctrl = WMI_FORCE_ROAM; 748 cmd->roam_ctrl = WMI_FORCE_ROAM;
@@ -753,6 +752,22 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid)
753 NO_SYNC_WMIFLAG); 752 NO_SYNC_WMIFLAG);
754} 753}
755 754
755int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period)
756{
757 struct sk_buff *skb;
758 struct set_dtim_cmd *cmd;
759
760 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
761 if (!skb)
762 return -ENOMEM;
763
764 cmd = (struct set_dtim_cmd *) skb->data;
765
766 cmd->dtim_period = cpu_to_le32(dtim_period);
767 return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
768 WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG);
769}
770
756int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode) 771int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode)
757{ 772{
758 struct sk_buff *skb; 773 struct sk_buff *skb;
@@ -763,7 +778,6 @@ int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode)
763 return -ENOMEM; 778 return -ENOMEM;
764 779
765 cmd = (struct roam_ctrl_cmd *) skb->data; 780 cmd = (struct roam_ctrl_cmd *) skb->data;
766 memset(cmd, 0, sizeof(*cmd));
767 781
768 cmd->info.roam_mode = mode; 782 cmd->info.roam_mode = mode;
769 cmd->roam_ctrl = WMI_SET_ROAM_MODE; 783 cmd->roam_ctrl = WMI_SET_ROAM_MODE;
@@ -1995,7 +2009,7 @@ int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag,
1995 struct wmi_probed_ssid_cmd *cmd; 2009 struct wmi_probed_ssid_cmd *cmd;
1996 int ret; 2010 int ret;
1997 2011
1998 if (index > MAX_PROBED_SSID_INDEX) 2012 if (index >= MAX_PROBED_SSIDS)
1999 return -EINVAL; 2013 return -EINVAL;
2000 2014
2001 if (ssid_len > sizeof(cmd->ssid)) 2015 if (ssid_len > sizeof(cmd->ssid))
@@ -2599,6 +2613,115 @@ static void ath6kl_wmi_relinquish_implicit_pstream_credits(struct wmi *wmi)
2599 spin_unlock_bh(&wmi->lock); 2613 spin_unlock_bh(&wmi->lock);
2600} 2614}
2601 2615
2616static int ath6kl_set_bitrate_mask64(struct wmi *wmi, u8 if_idx,
2617 const struct cfg80211_bitrate_mask *mask)
2618{
2619 struct sk_buff *skb;
2620 int ret, mode, band;
2621 u64 mcsrate, ratemask[IEEE80211_NUM_BANDS];
2622 struct wmi_set_tx_select_rates64_cmd *cmd;
2623
2624 memset(&ratemask, 0, sizeof(ratemask));
2625 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2626 /* copy legacy rate mask */
2627 ratemask[band] = mask->control[band].legacy;
2628 if (band == IEEE80211_BAND_5GHZ)
2629 ratemask[band] =
2630 mask->control[band].legacy << 4;
2631
2632 /* copy mcs rate mask */
2633 mcsrate = mask->control[band].mcs[1];
2634 mcsrate <<= 8;
2635 mcsrate |= mask->control[band].mcs[0];
2636 ratemask[band] |= mcsrate << 12;
2637 ratemask[band] |= mcsrate << 28;
2638 }
2639
2640 ath6kl_dbg(ATH6KL_DBG_WMI,
2641 "Ratemask 64 bit: 2.4:%llx 5:%llx\n",
2642 ratemask[0], ratemask[1]);
2643
2644 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd) * WMI_RATES_MODE_MAX);
2645 if (!skb)
2646 return -ENOMEM;
2647
2648 cmd = (struct wmi_set_tx_select_rates64_cmd *) skb->data;
2649 for (mode = 0; mode < WMI_RATES_MODE_MAX; mode++) {
2650 /* A mode operate in 5GHZ band */
2651 if (mode == WMI_RATES_MODE_11A ||
2652 mode == WMI_RATES_MODE_11A_HT20 ||
2653 mode == WMI_RATES_MODE_11A_HT40)
2654 band = IEEE80211_BAND_5GHZ;
2655 else
2656 band = IEEE80211_BAND_2GHZ;
2657 cmd->ratemask[mode] = cpu_to_le64(ratemask[band]);
2658 }
2659
2660 ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
2661 WMI_SET_TX_SELECT_RATES_CMDID,
2662 NO_SYNC_WMIFLAG);
2663 return ret;
2664}
2665
2666static int ath6kl_set_bitrate_mask32(struct wmi *wmi, u8 if_idx,
2667 const struct cfg80211_bitrate_mask *mask)
2668{
2669 struct sk_buff *skb;
2670 int ret, mode, band;
2671 u32 mcsrate, ratemask[IEEE80211_NUM_BANDS];
2672 struct wmi_set_tx_select_rates32_cmd *cmd;
2673
2674 memset(&ratemask, 0, sizeof(ratemask));
2675 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2676 /* copy legacy rate mask */
2677 ratemask[band] = mask->control[band].legacy;
2678 if (band == IEEE80211_BAND_5GHZ)
2679 ratemask[band] =
2680 mask->control[band].legacy << 4;
2681
2682 /* copy mcs rate mask */
2683 mcsrate = mask->control[band].mcs[0];
2684 ratemask[band] |= mcsrate << 12;
2685 ratemask[band] |= mcsrate << 20;
2686 }
2687
2688 ath6kl_dbg(ATH6KL_DBG_WMI,
2689 "Ratemask 32 bit: 2.4:%x 5:%x\n",
2690 ratemask[0], ratemask[1]);
2691
2692 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd) * WMI_RATES_MODE_MAX);
2693 if (!skb)
2694 return -ENOMEM;
2695
2696 cmd = (struct wmi_set_tx_select_rates32_cmd *) skb->data;
2697 for (mode = 0; mode < WMI_RATES_MODE_MAX; mode++) {
2698 /* A mode operate in 5GHZ band */
2699 if (mode == WMI_RATES_MODE_11A ||
2700 mode == WMI_RATES_MODE_11A_HT20 ||
2701 mode == WMI_RATES_MODE_11A_HT40)
2702 band = IEEE80211_BAND_5GHZ;
2703 else
2704 band = IEEE80211_BAND_2GHZ;
2705 cmd->ratemask[mode] = cpu_to_le32(ratemask[band]);
2706 }
2707
2708 ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
2709 WMI_SET_TX_SELECT_RATES_CMDID,
2710 NO_SYNC_WMIFLAG);
2711 return ret;
2712}
2713
2714int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
2715 const struct cfg80211_bitrate_mask *mask)
2716{
2717 struct ath6kl *ar = wmi->parent_dev;
2718
2719 if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES)
2720 return ath6kl_set_bitrate_mask64(wmi, if_idx, mask);
2721 else
2722 return ath6kl_set_bitrate_mask32(wmi, if_idx, mask);
2723}
2724
2602int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, 2725int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
2603 enum ath6kl_host_mode host_mode) 2726 enum ath6kl_host_mode host_mode)
2604{ 2727{
@@ -2997,6 +3120,25 @@ int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
2997 return ret; 3120 return ret;
2998} 3121}
2999 3122
3123int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enhance)
3124{
3125 struct sk_buff *skb;
3126 struct wmi_sta_bmiss_enhance_cmd *cmd;
3127 int ret;
3128
3129 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
3130 if (!skb)
3131 return -ENOMEM;
3132
3133 cmd = (struct wmi_sta_bmiss_enhance_cmd *) skb->data;
3134 cmd->enable = enhance ? 1 : 0;
3135
3136 ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
3137 WMI_STA_BMISS_ENHANCE_CMDID,
3138 NO_SYNC_WMIFLAG);
3139 return ret;
3140}
3141
3000s32 ath6kl_wmi_get_rate(s8 rate_index) 3142s32 ath6kl_wmi_get_rate(s8 rate_index)
3001{ 3143{
3002 if (rate_index == RATE_AUTO) 3144 if (rate_index == RATE_AUTO)
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 9076bec3a2b..43339aca585 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -624,6 +624,10 @@ enum wmi_cmd_id {
624 WMI_SEND_MGMT_CMDID, 624 WMI_SEND_MGMT_CMDID,
625 WMI_BEGIN_SCAN_CMDID, 625 WMI_BEGIN_SCAN_CMDID,
626 626
627 WMI_SET_BLACK_LIST,
628 WMI_SET_MCASTRATE,
629
630 WMI_STA_BMISS_ENHANCE_CMDID,
627}; 631};
628 632
629enum wmi_mgmt_frame_type { 633enum wmi_mgmt_frame_type {
@@ -960,6 +964,9 @@ enum wmi_bss_filter {
960 /* beacons matching probed ssid */ 964 /* beacons matching probed ssid */
961 PROBED_SSID_FILTER, 965 PROBED_SSID_FILTER,
962 966
967 /* beacons matching matched ssid */
968 MATCHED_SSID_FILTER,
969
963 /* marker only */ 970 /* marker only */
964 LAST_BSS_FILTER, 971 LAST_BSS_FILTER,
965}; 972};
@@ -978,7 +985,7 @@ struct wmi_bss_filter_cmd {
978} __packed; 985} __packed;
979 986
980/* WMI_SET_PROBED_SSID_CMDID */ 987/* WMI_SET_PROBED_SSID_CMDID */
981#define MAX_PROBED_SSID_INDEX 9 988#define MAX_PROBED_SSIDS 16
982 989
983enum wmi_ssid_flag { 990enum wmi_ssid_flag {
984 /* disables entry */ 991 /* disables entry */
@@ -989,10 +996,13 @@ enum wmi_ssid_flag {
989 996
990 /* probes for any ssid */ 997 /* probes for any ssid */
991 ANY_SSID_FLAG = 0x02, 998 ANY_SSID_FLAG = 0x02,
999
1000 /* match for ssid */
1001 MATCH_SSID_FLAG = 0x08,
992}; 1002};
993 1003
994struct wmi_probed_ssid_cmd { 1004struct wmi_probed_ssid_cmd {
995 /* 0 to MAX_PROBED_SSID_INDEX */ 1005 /* 0 to MAX_PROBED_SSIDS - 1 */
996 u8 entry_index; 1006 u8 entry_index;
997 1007
998 /* see, enum wmi_ssid_flg */ 1008 /* see, enum wmi_ssid_flg */
@@ -1017,6 +1027,11 @@ struct wmi_bmiss_time_cmd {
1017 __le16 num_beacons; 1027 __le16 num_beacons;
1018}; 1028};
1019 1029
1030/* WMI_STA_ENHANCE_BMISS_CMDID */
1031struct wmi_sta_bmiss_enhance_cmd {
1032 u8 enable;
1033} __packed;
1034
1020/* WMI_SET_POWER_MODE_CMDID */ 1035/* WMI_SET_POWER_MODE_CMDID */
1021enum wmi_power_mode { 1036enum wmi_power_mode {
1022 REC_POWER = 0x01, 1037 REC_POWER = 0x01,
@@ -1048,6 +1063,36 @@ struct wmi_power_params_cmd {
1048 __le16 ps_fail_event_policy; 1063 __le16 ps_fail_event_policy;
1049} __packed; 1064} __packed;
1050 1065
1066/*
1067 * Ratemask for below modes should be passed
1068 * to WMI_SET_TX_SELECT_RATES_CMDID.
1069 * AR6003 has 32 bit mask for each modes.
1070 * First 12 bits for legacy rates, 13 to 20
1071 * bits for HT 20 rates and 21 to 28 bits for
1072 * HT 40 rates
1073 */
1074enum wmi_mode_phy {
1075 WMI_RATES_MODE_11A = 0,
1076 WMI_RATES_MODE_11G,
1077 WMI_RATES_MODE_11B,
1078 WMI_RATES_MODE_11GONLY,
1079 WMI_RATES_MODE_11A_HT20,
1080 WMI_RATES_MODE_11G_HT20,
1081 WMI_RATES_MODE_11A_HT40,
1082 WMI_RATES_MODE_11G_HT40,
1083 WMI_RATES_MODE_MAX
1084};
1085
1086/* WMI_SET_TX_SELECT_RATES_CMDID */
1087struct wmi_set_tx_select_rates32_cmd {
1088 __le32 ratemask[WMI_RATES_MODE_MAX];
1089} __packed;
1090
1091/* WMI_SET_TX_SELECT_RATES_CMDID */
1092struct wmi_set_tx_select_rates64_cmd {
1093 __le64 ratemask[WMI_RATES_MODE_MAX];
1094} __packed;
1095
1051/* WMI_SET_DISC_TIMEOUT_CMDID */ 1096/* WMI_SET_DISC_TIMEOUT_CMDID */
1052struct wmi_disc_timeout_cmd { 1097struct wmi_disc_timeout_cmd {
1053 /* seconds */ 1098 /* seconds */
@@ -1572,6 +1617,10 @@ struct roam_ctrl_cmd {
1572 u8 roam_ctrl; 1617 u8 roam_ctrl;
1573} __packed; 1618} __packed;
1574 1619
1620struct set_dtim_cmd {
1621 __le32 dtim_period;
1622} __packed;
1623
1575/* BSS INFO HDR version 2.0 */ 1624/* BSS INFO HDR version 2.0 */
1576struct wmi_bss_info_hdr2 { 1625struct wmi_bss_info_hdr2 {
1577 __le16 ch; /* frequency in MHz */ 1626 __le16 ch; /* frequency in MHz */
@@ -2532,6 +2581,8 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
2532 __be32 ips0, __be32 ips1); 2581 __be32 ips0, __be32 ips1);
2533int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, 2582int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
2534 enum ath6kl_host_mode host_mode); 2583 enum ath6kl_host_mode host_mode);
2584int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
2585 const struct cfg80211_bitrate_mask *mask);
2535int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, 2586int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
2536 enum ath6kl_wow_mode wow_mode, 2587 enum ath6kl_wow_mode wow_mode,
2537 u32 filter, u16 host_req_delay); 2588 u32 filter, u16 host_req_delay);
@@ -2542,11 +2593,14 @@ int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
2542int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, 2593int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
2543 u16 list_id, u16 filter_id); 2594 u16 list_id, u16 filter_id);
2544int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); 2595int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
2596int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period);
2545int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); 2597int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid);
2546int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode); 2598int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode);
2547int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); 2599int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);
2548int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, 2600int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
2549 u8 *filter, bool add_filter); 2601 u8 *filter, bool add_filter);
2602int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable);
2603
2550/* AP mode uAPSD */ 2604/* AP mode uAPSD */
2551int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); 2605int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable);
2552 2606