diff options
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/cfg80211.c | 238 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/cfg80211.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/core.h | 33 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/debug.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/htc_mbox.c | 45 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/htc_pipe.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/init.c | 29 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/main.c | 104 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/sdio.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/txrx.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/usb.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/wmi.c | 94 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/wmi.h | 24 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_calib.c | 50 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_mci.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_rtt.c | 84 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_rtt.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 9 |
19 files changed, 544 insertions, 248 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 28a65d3a03d0..b869a358ce43 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -693,8 +693,8 @@ ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, | |||
693 | ie, 2 + vif->ssid_len + beacon_ie_len, | 693 | ie, 2 + vif->ssid_len + beacon_ie_len, |
694 | 0, GFP_KERNEL); | 694 | 0, GFP_KERNEL); |
695 | if (bss) | 695 | if (bss) |
696 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added bss %pM to " | 696 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, |
697 | "cfg80211\n", bssid); | 697 | "added bss %pM to cfg80211\n", bssid); |
698 | kfree(ie); | 698 | kfree(ie); |
699 | } else | 699 | } else |
700 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n"); | 700 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n"); |
@@ -882,6 +882,32 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, | |||
882 | vif->sme_state = SME_DISCONNECTED; | 882 | vif->sme_state = SME_DISCONNECTED; |
883 | } | 883 | } |
884 | 884 | ||
885 | static int ath6kl_set_probed_ssids(struct ath6kl *ar, | ||
886 | struct ath6kl_vif *vif, | ||
887 | struct cfg80211_ssid *ssids, int n_ssids) | ||
888 | { | ||
889 | u8 i; | ||
890 | |||
891 | if (n_ssids > MAX_PROBED_SSID_INDEX) | ||
892 | return -EINVAL; | ||
893 | |||
894 | for (i = 0; i < n_ssids; i++) { | ||
895 | ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i, | ||
896 | ssids[i].ssid_len ? | ||
897 | SPECIFIC_SSID_FLAG : ANY_SSID_FLAG, | ||
898 | ssids[i].ssid_len, | ||
899 | ssids[i].ssid); | ||
900 | } | ||
901 | |||
902 | /* Make sure no old entries are left behind */ | ||
903 | for (i = n_ssids; i < MAX_PROBED_SSID_INDEX; i++) { | ||
904 | ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i, | ||
905 | DISABLE_SSID_FLAG, 0, NULL); | ||
906 | } | ||
907 | |||
908 | return 0; | ||
909 | } | ||
910 | |||
885 | static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, | 911 | static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, |
886 | struct cfg80211_scan_request *request) | 912 | struct cfg80211_scan_request *request) |
887 | { | 913 | { |
@@ -899,36 +925,25 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, | |||
899 | 925 | ||
900 | if (!ar->usr_bss_filter) { | 926 | if (!ar->usr_bss_filter) { |
901 | clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); | 927 | clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); |
902 | ret = ath6kl_wmi_bssfilter_cmd( | 928 | ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, |
903 | ar->wmi, vif->fw_vif_idx, | 929 | ALL_BSS_FILTER, 0); |
904 | (test_bit(CONNECTED, &vif->flags) ? | ||
905 | ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0); | ||
906 | if (ret) { | 930 | if (ret) { |
907 | ath6kl_err("couldn't set bss filtering\n"); | 931 | ath6kl_err("couldn't set bss filtering\n"); |
908 | return ret; | 932 | return ret; |
909 | } | 933 | } |
910 | } | 934 | } |
911 | 935 | ||
912 | if (request->n_ssids && request->ssids[0].ssid_len) { | 936 | ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, |
913 | u8 i; | 937 | request->n_ssids); |
914 | 938 | if (ret < 0) | |
915 | if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1)) | 939 | return ret; |
916 | request->n_ssids = MAX_PROBED_SSID_INDEX - 1; | ||
917 | |||
918 | for (i = 0; i < request->n_ssids; i++) | ||
919 | ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, | ||
920 | i + 1, SPECIFIC_SSID_FLAG, | ||
921 | request->ssids[i].ssid_len, | ||
922 | request->ssids[i].ssid); | ||
923 | } | ||
924 | 940 | ||
925 | /* this also clears IE in fw if it's not set */ | 941 | /* this also clears IE in fw if it's not set */ |
926 | ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, | 942 | ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, |
927 | WMI_FRAME_PROBE_REQ, | 943 | WMI_FRAME_PROBE_REQ, |
928 | request->ie, request->ie_len); | 944 | request->ie, request->ie_len); |
929 | if (ret) { | 945 | if (ret) { |
930 | ath6kl_err("failed to set Probe Request appie for " | 946 | ath6kl_err("failed to set Probe Request appie for scan"); |
931 | "scan"); | ||
932 | return ret; | 947 | return ret; |
933 | } | 948 | } |
934 | 949 | ||
@@ -945,8 +960,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, | |||
945 | 960 | ||
946 | channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL); | 961 | channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL); |
947 | if (channels == NULL) { | 962 | if (channels == NULL) { |
948 | ath6kl_warn("failed to set scan channels, " | 963 | ath6kl_warn("failed to set scan channels, scan all channels"); |
949 | "scan all channels"); | ||
950 | n_channels = 0; | 964 | n_channels = 0; |
951 | } | 965 | } |
952 | 966 | ||
@@ -1018,6 +1032,20 @@ out: | |||
1018 | vif->scan_req = NULL; | 1032 | vif->scan_req = NULL; |
1019 | } | 1033 | } |
1020 | 1034 | ||
1035 | void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, | ||
1036 | enum wmi_phy_mode mode) | ||
1037 | { | ||
1038 | enum nl80211_channel_type type; | ||
1039 | |||
1040 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, | ||
1041 | "channel switch notify nw_type %d freq %d mode %d\n", | ||
1042 | vif->nw_type, freq, mode); | ||
1043 | |||
1044 | type = (mode == WMI_11G_HT20) ? NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT; | ||
1045 | |||
1046 | cfg80211_ch_switch_notify(vif->ndev, freq, type); | ||
1047 | } | ||
1048 | |||
1021 | static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | 1049 | static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, |
1022 | u8 key_index, bool pairwise, | 1050 | u8 key_index, bool pairwise, |
1023 | const u8 *mac_addr, | 1051 | const u8 *mac_addr, |
@@ -1111,9 +1139,8 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
1111 | ar->ap_mode_bkey.key_len = key->key_len; | 1139 | ar->ap_mode_bkey.key_len = key->key_len; |
1112 | memcpy(ar->ap_mode_bkey.key, key->key, key->key_len); | 1140 | memcpy(ar->ap_mode_bkey.key, key->key, key->key_len); |
1113 | if (!test_bit(CONNECTED, &vif->flags)) { | 1141 | if (!test_bit(CONNECTED, &vif->flags)) { |
1114 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group " | 1142 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, |
1115 | "key configuration until AP mode has been " | 1143 | "Delay initial group key configuration until AP mode has been started\n"); |
1116 | "started\n"); | ||
1117 | /* | 1144 | /* |
1118 | * The key will be set in ath6kl_connect_ap_mode() once | 1145 | * The key will be set in ath6kl_connect_ap_mode() once |
1119 | * the connected event is received from the target. | 1146 | * the connected event is received from the target. |
@@ -1129,8 +1156,8 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
1129 | * the AP mode has properly started | 1156 | * the AP mode has properly started |
1130 | * (ath6kl_install_statioc_wep_keys). | 1157 | * (ath6kl_install_statioc_wep_keys). |
1131 | */ | 1158 | */ |
1132 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration " | 1159 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, |
1133 | "until AP mode has been started\n"); | 1160 | "Delay WEP key configuration until AP mode has been started\n"); |
1134 | vif->wep_key_list[key_index].key_len = key->key_len; | 1161 | vif->wep_key_list[key_index].key_len = key->key_len; |
1135 | memcpy(vif->wep_key_list[key_index].key, key->key, | 1162 | memcpy(vif->wep_key_list[key_index].key, key->key, |
1136 | key->key_len); | 1163 | key->key_len); |
@@ -1962,8 +1989,7 @@ static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif) | |||
1962 | sizeof(discvr_pattern), discvr_offset, | 1989 | sizeof(discvr_pattern), discvr_offset, |
1963 | discvr_pattern, discvr_mask); | 1990 | discvr_pattern, discvr_mask); |
1964 | if (ret) { | 1991 | if (ret) { |
1965 | ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR " | 1992 | ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n"); |
1966 | "pattern\n"); | ||
1967 | return ret; | 1993 | return ret; |
1968 | } | 1994 | } |
1969 | } | 1995 | } |
@@ -2031,6 +2057,10 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | |||
2031 | u8 index = 0; | 2057 | u8 index = 0; |
2032 | __be32 ips[MAX_IP_ADDRS]; | 2058 | __be32 ips[MAX_IP_ADDRS]; |
2033 | 2059 | ||
2060 | /* The FW currently can't support multi-vif WoW properly. */ | ||
2061 | if (ar->num_vif > 1) | ||
2062 | return -EIO; | ||
2063 | |||
2034 | vif = ath6kl_vif_first(ar); | 2064 | vif = ath6kl_vif_first(ar); |
2035 | if (!vif) | 2065 | if (!vif) |
2036 | return -EIO; | 2066 | return -EIO; |
@@ -2044,6 +2074,13 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | |||
2044 | if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) | 2074 | if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) |
2045 | return -EINVAL; | 2075 | return -EINVAL; |
2046 | 2076 | ||
2077 | if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags)) { | ||
2078 | ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, | ||
2079 | vif->fw_vif_idx, false); | ||
2080 | if (ret) | ||
2081 | return ret; | ||
2082 | } | ||
2083 | |||
2047 | /* Clear existing WOW patterns */ | 2084 | /* Clear existing WOW patterns */ |
2048 | for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++) | 2085 | for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++) |
2049 | ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx, | 2086 | ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx, |
@@ -2147,8 +2184,8 @@ static int ath6kl_wow_resume(struct ath6kl *ar) | |||
2147 | ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, | 2184 | ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, |
2148 | ATH6KL_HOST_MODE_AWAKE); | 2185 | ATH6KL_HOST_MODE_AWAKE); |
2149 | if (ret) { | 2186 | if (ret) { |
2150 | ath6kl_warn("Failed to configure host sleep mode for " | 2187 | ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n", |
2151 | "wow resume: %d\n", ret); | 2188 | ret); |
2152 | ar->state = ATH6KL_STATE_WOW; | 2189 | ar->state = ATH6KL_STATE_WOW; |
2153 | return ret; | 2190 | return ret; |
2154 | } | 2191 | } |
@@ -2172,6 +2209,13 @@ static int ath6kl_wow_resume(struct ath6kl *ar) | |||
2172 | 2209 | ||
2173 | ar->state = ATH6KL_STATE_ON; | 2210 | ar->state = ATH6KL_STATE_ON; |
2174 | 2211 | ||
2212 | if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags)) { | ||
2213 | ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, | ||
2214 | vif->fw_vif_idx, true); | ||
2215 | if (ret) | ||
2216 | return ret; | ||
2217 | } | ||
2218 | |||
2175 | netif_wake_queue(vif->ndev); | 2219 | netif_wake_queue(vif->ndev); |
2176 | 2220 | ||
2177 | return 0; | 2221 | return 0; |
@@ -2186,8 +2230,10 @@ static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar) | |||
2186 | if (!vif) | 2230 | if (!vif) |
2187 | return -EIO; | 2231 | return -EIO; |
2188 | 2232 | ||
2189 | if (!ath6kl_cfg80211_ready(vif)) | 2233 | if (!test_bit(WMI_READY, &ar->flag)) { |
2234 | ath6kl_err("deepsleep failed as wmi is not ready\n"); | ||
2190 | return -EIO; | 2235 | return -EIO; |
2236 | } | ||
2191 | 2237 | ||
2192 | ath6kl_cfg80211_stop_all(ar); | 2238 | ath6kl_cfg80211_stop_all(ar); |
2193 | 2239 | ||
@@ -2447,6 +2493,24 @@ static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band, | |||
2447 | band, htcap); | 2493 | band, htcap); |
2448 | } | 2494 | } |
2449 | 2495 | ||
2496 | static int ath6kl_restore_htcap(struct ath6kl_vif *vif) | ||
2497 | { | ||
2498 | struct wiphy *wiphy = vif->ar->wiphy; | ||
2499 | int band, ret = 0; | ||
2500 | |||
2501 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
2502 | if (!wiphy->bands[band]) | ||
2503 | continue; | ||
2504 | |||
2505 | ret = ath6kl_set_htcap(vif, band, | ||
2506 | wiphy->bands[band]->ht_cap.ht_supported); | ||
2507 | if (ret) | ||
2508 | return ret; | ||
2509 | } | ||
2510 | |||
2511 | return ret; | ||
2512 | } | ||
2513 | |||
2450 | static bool ath6kl_is_p2p_ie(const u8 *pos) | 2514 | static bool ath6kl_is_p2p_ie(const u8 *pos) |
2451 | { | 2515 | { |
2452 | return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && | 2516 | return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && |
@@ -2568,28 +2632,34 @@ static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon, | |||
2568 | /* skip element id and length */ | 2632 | /* skip element id and length */ |
2569 | rsn_ie += 2; | 2633 | rsn_ie += 2; |
2570 | 2634 | ||
2571 | /* skip version, group cipher */ | 2635 | /* skip version */ |
2572 | if (rsn_ie_len < 6) | 2636 | if (rsn_ie_len < 2) |
2573 | return -EINVAL; | 2637 | return -EINVAL; |
2574 | rsn_ie += 6; | 2638 | rsn_ie += 2; |
2575 | rsn_ie_len -= 6; | 2639 | rsn_ie_len -= 2; |
2640 | |||
2641 | /* skip group cipher suite */ | ||
2642 | if (rsn_ie_len < 4) | ||
2643 | return 0; | ||
2644 | rsn_ie += 4; | ||
2645 | rsn_ie_len -= 4; | ||
2576 | 2646 | ||
2577 | /* skip pairwise cipher suite */ | 2647 | /* skip pairwise cipher suite */ |
2578 | if (rsn_ie_len < 2) | 2648 | if (rsn_ie_len < 2) |
2579 | return -EINVAL; | 2649 | return 0; |
2580 | cnt = *((u16 *) rsn_ie); | 2650 | cnt = get_unaligned_le16(rsn_ie); |
2581 | rsn_ie += (2 + cnt * 4); | 2651 | rsn_ie += (2 + cnt * 4); |
2582 | rsn_ie_len -= (2 + cnt * 4); | 2652 | rsn_ie_len -= (2 + cnt * 4); |
2583 | 2653 | ||
2584 | /* skip akm suite */ | 2654 | /* skip akm suite */ |
2585 | if (rsn_ie_len < 2) | 2655 | if (rsn_ie_len < 2) |
2586 | return -EINVAL; | 2656 | return 0; |
2587 | cnt = *((u16 *) rsn_ie); | 2657 | cnt = get_unaligned_le16(rsn_ie); |
2588 | rsn_ie += (2 + cnt * 4); | 2658 | rsn_ie += (2 + cnt * 4); |
2589 | rsn_ie_len -= (2 + cnt * 4); | 2659 | rsn_ie_len -= (2 + cnt * 4); |
2590 | 2660 | ||
2591 | if (rsn_ie_len < 2) | 2661 | if (rsn_ie_len < 2) |
2592 | return -EINVAL; | 2662 | return 0; |
2593 | 2663 | ||
2594 | memcpy(rsn_capab, rsn_ie, 2); | 2664 | memcpy(rsn_capab, rsn_ie, 2); |
2595 | 2665 | ||
@@ -2766,6 +2836,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
2766 | return res; | 2836 | return res; |
2767 | } | 2837 | } |
2768 | 2838 | ||
2839 | memcpy(&vif->profile, &p, sizeof(p)); | ||
2769 | res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p); | 2840 | res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p); |
2770 | if (res < 0) | 2841 | if (res < 0) |
2771 | return res; | 2842 | return res; |
@@ -2801,13 +2872,7 @@ static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
2801 | clear_bit(CONNECTED, &vif->flags); | 2872 | clear_bit(CONNECTED, &vif->flags); |
2802 | 2873 | ||
2803 | /* Restore ht setting in firmware */ | 2874 | /* Restore ht setting in firmware */ |
2804 | if (ath6kl_set_htcap(vif, IEEE80211_BAND_2GHZ, true)) | 2875 | return ath6kl_restore_htcap(vif); |
2805 | return -EIO; | ||
2806 | |||
2807 | if (ath6kl_set_htcap(vif, IEEE80211_BAND_5GHZ, true)) | ||
2808 | return -EIO; | ||
2809 | |||
2810 | return 0; | ||
2811 | } | 2876 | } |
2812 | 2877 | ||
2813 | static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | 2878 | static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
@@ -3081,7 +3146,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, | |||
3081 | struct ath6kl_vif *vif = netdev_priv(dev); | 3146 | struct ath6kl_vif *vif = netdev_priv(dev); |
3082 | u16 interval; | 3147 | u16 interval; |
3083 | int ret; | 3148 | int ret; |
3084 | u8 i; | ||
3085 | 3149 | ||
3086 | if (ar->state != ATH6KL_STATE_ON) | 3150 | if (ar->state != ATH6KL_STATE_ON) |
3087 | return -EIO; | 3151 | return -EIO; |
@@ -3089,29 +3153,23 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, | |||
3089 | if (vif->sme_state != SME_DISCONNECTED) | 3153 | if (vif->sme_state != SME_DISCONNECTED) |
3090 | return -EBUSY; | 3154 | return -EBUSY; |
3091 | 3155 | ||
3156 | /* The FW currently can't support multi-vif WoW properly. */ | ||
3157 | if (ar->num_vif > 1) | ||
3158 | return -EIO; | ||
3159 | |||
3092 | ath6kl_cfg80211_scan_complete_event(vif, true); | 3160 | ath6kl_cfg80211_scan_complete_event(vif, true); |
3093 | 3161 | ||
3094 | for (i = 0; i < ar->wiphy->max_sched_scan_ssids; i++) { | 3162 | ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, |
3095 | ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, | 3163 | request->n_ssids); |
3096 | i, DISABLE_SSID_FLAG, | 3164 | if (ret < 0) |
3097 | 0, NULL); | 3165 | return ret; |
3098 | } | ||
3099 | 3166 | ||
3100 | /* fw uses seconds, also make sure that it's >0 */ | 3167 | /* fw uses seconds, also make sure that it's >0 */ |
3101 | interval = max_t(u16, 1, request->interval / 1000); | 3168 | interval = max_t(u16, 1, request->interval / 1000); |
3102 | 3169 | ||
3103 | ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, | 3170 | ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, |
3104 | interval, interval, | 3171 | interval, interval, |
3105 | 10, 0, 0, 0, 3, 0, 0, 0); | 3172 | vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0); |
3106 | |||
3107 | if (request->n_ssids && request->ssids[0].ssid_len) { | ||
3108 | for (i = 0; i < request->n_ssids; i++) { | ||
3109 | ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, | ||
3110 | i, SPECIFIC_SSID_FLAG, | ||
3111 | request->ssids[i].ssid_len, | ||
3112 | request->ssids[i].ssid); | ||
3113 | } | ||
3114 | } | ||
3115 | 3173 | ||
3116 | ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, | 3174 | ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, |
3117 | ATH6KL_WOW_MODE_ENABLE, | 3175 | ATH6KL_WOW_MODE_ENABLE, |
@@ -3271,8 +3329,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) | |||
3271 | ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; | 3329 | ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; |
3272 | 3330 | ||
3273 | if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0) | 3331 | if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0) |
3274 | ath6kl_warn("ath6kl_deep_sleep_enable: " | 3332 | ath6kl_warn("ath6kl_deep_sleep_enable: wmi_powermode_cmd failed\n"); |
3275 | "wmi_powermode_cmd failed\n"); | ||
3276 | return; | 3333 | return; |
3277 | } | 3334 | } |
3278 | 3335 | ||
@@ -3352,6 +3409,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, | |||
3352 | vif->next_mode = nw_type; | 3409 | vif->next_mode = nw_type; |
3353 | vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL; | 3410 | vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL; |
3354 | vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME; | 3411 | vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME; |
3412 | vif->bg_scan_period = 0; | ||
3355 | vif->htcap.ht_enable = true; | 3413 | vif->htcap.ht_enable = true; |
3356 | 3414 | ||
3357 | memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); | 3415 | memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); |
@@ -3393,6 +3451,7 @@ err: | |||
3393 | int ath6kl_cfg80211_init(struct ath6kl *ar) | 3451 | int ath6kl_cfg80211_init(struct ath6kl *ar) |
3394 | { | 3452 | { |
3395 | struct wiphy *wiphy = ar->wiphy; | 3453 | struct wiphy *wiphy = ar->wiphy; |
3454 | bool band_2gig = false, band_5gig = false, ht = false; | ||
3396 | int ret; | 3455 | int ret; |
3397 | 3456 | ||
3398 | wiphy->mgmt_stypes = ath6kl_mgmt_stypes; | 3457 | wiphy->mgmt_stypes = ath6kl_mgmt_stypes; |
@@ -3413,8 +3472,46 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) | |||
3413 | /* max num of ssids that can be probed during scanning */ | 3472 | /* max num of ssids that can be probed during scanning */ |
3414 | wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; | 3473 | wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; |
3415 | wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ | 3474 | wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ |
3416 | wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; | 3475 | switch (ar->hw.cap) { |
3417 | wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz; | 3476 | case WMI_11AN_CAP: |
3477 | ht = true; | ||
3478 | case WMI_11A_CAP: | ||
3479 | band_5gig = true; | ||
3480 | break; | ||
3481 | case WMI_11GN_CAP: | ||
3482 | ht = true; | ||
3483 | case WMI_11G_CAP: | ||
3484 | band_2gig = true; | ||
3485 | break; | ||
3486 | case WMI_11AGN_CAP: | ||
3487 | ht = true; | ||
3488 | case WMI_11AG_CAP: | ||
3489 | band_2gig = true; | ||
3490 | band_5gig = true; | ||
3491 | break; | ||
3492 | default: | ||
3493 | ath6kl_err("invalid phy capability!\n"); | ||
3494 | return -EINVAL; | ||
3495 | } | ||
3496 | |||
3497 | /* | ||
3498 | * Even if the fw has HT support, advertise HT cap only when | ||
3499 | * the firmware has support to override RSN capability, otherwise | ||
3500 | * 4-way handshake would fail. | ||
3501 | */ | ||
3502 | if (!(ht && | ||
3503 | test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, | ||
3504 | ar->fw_capabilities))) { | ||
3505 | ath6kl_band_2ghz.ht_cap.cap = 0; | ||
3506 | ath6kl_band_2ghz.ht_cap.ht_supported = false; | ||
3507 | ath6kl_band_5ghz.ht_cap.cap = 0; | ||
3508 | ath6kl_band_5ghz.ht_cap.ht_supported = false; | ||
3509 | } | ||
3510 | if (band_2gig) | ||
3511 | wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; | ||
3512 | if (band_5gig) | ||
3513 | wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz; | ||
3514 | |||
3418 | wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; | 3515 | wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; |
3419 | 3516 | ||
3420 | wiphy->cipher_suites = cipher_suites; | 3517 | wiphy->cipher_suites = cipher_suites; |
@@ -3430,7 +3527,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) | |||
3430 | wiphy->wowlan.pattern_min_len = 1; | 3527 | wiphy->wowlan.pattern_min_len = 1; |
3431 | wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; | 3528 | wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; |
3432 | 3529 | ||
3433 | wiphy->max_sched_scan_ssids = 10; | 3530 | wiphy->max_sched_scan_ssids = MAX_PROBED_SSID_INDEX; |
3434 | 3531 | ||
3435 | ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | | 3532 | ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | |
3436 | WIPHY_FLAG_HAVE_AP_SME | | 3533 | WIPHY_FLAG_HAVE_AP_SME | |
@@ -3447,8 +3544,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) | |||
3447 | ar->wiphy->probe_resp_offload = | 3544 | ar->wiphy->probe_resp_offload = |
3448 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | | 3545 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | |
3449 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | | 3546 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | |
3450 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | | 3547 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P; |
3451 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; | ||
3452 | 3548 | ||
3453 | ret = wiphy_register(wiphy); | 3549 | ret = wiphy_register(wiphy); |
3454 | if (ret < 0) { | 3550 | if (ret < 0) { |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index c5def436417f..5ea8cbb79f43 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h | |||
@@ -28,6 +28,8 @@ enum ath6kl_cfg_suspend_mode { | |||
28 | struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, | 28 | struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, |
29 | enum nl80211_iftype type, | 29 | enum nl80211_iftype type, |
30 | u8 fw_vif_idx, u8 nw_type); | 30 | u8 fw_vif_idx, u8 nw_type); |
31 | void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, | ||
32 | enum wmi_phy_mode mode); | ||
31 | void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); | 33 | void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); |
32 | 34 | ||
33 | void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, | 35 | void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, |
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 9d67964a51dd..4d9c6f142698 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h | |||
@@ -126,9 +126,9 @@ struct ath6kl_fw_ie { | |||
126 | #define AR6003_HW_2_0_FIRMWARE_FILE "athwlan.bin.z77" | 126 | #define AR6003_HW_2_0_FIRMWARE_FILE "athwlan.bin.z77" |
127 | #define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "athtcmd_ram.bin" | 127 | #define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "athtcmd_ram.bin" |
128 | #define AR6003_HW_2_0_PATCH_FILE "data.patch.bin" | 128 | #define AR6003_HW_2_0_PATCH_FILE "data.patch.bin" |
129 | #define AR6003_HW_2_0_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin" | 129 | #define AR6003_HW_2_0_BOARD_DATA_FILE AR6003_HW_2_0_FW_DIR "/bdata.bin" |
130 | #define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \ | 130 | #define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \ |
131 | "ath6k/AR6003/hw2.0/bdata.SD31.bin" | 131 | AR6003_HW_2_0_FW_DIR "/bdata.SD31.bin" |
132 | 132 | ||
133 | /* AR6003 3.0 definitions */ | 133 | /* AR6003 3.0 definitions */ |
134 | #define AR6003_HW_2_1_1_VERSION 0x30000582 | 134 | #define AR6003_HW_2_1_1_VERSION 0x30000582 |
@@ -139,25 +139,33 @@ struct ath6kl_fw_ie { | |||
139 | #define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE "utf.bin" | 139 | #define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE "utf.bin" |
140 | #define AR6003_HW_2_1_1_TESTSCRIPT_FILE "nullTestFlow.bin" | 140 | #define AR6003_HW_2_1_1_TESTSCRIPT_FILE "nullTestFlow.bin" |
141 | #define AR6003_HW_2_1_1_PATCH_FILE "data.patch.bin" | 141 | #define AR6003_HW_2_1_1_PATCH_FILE "data.patch.bin" |
142 | #define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin" | 142 | #define AR6003_HW_2_1_1_BOARD_DATA_FILE AR6003_HW_2_1_1_FW_DIR "/bdata.bin" |
143 | #define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \ | 143 | #define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \ |
144 | "ath6k/AR6003/hw2.1.1/bdata.SD31.bin" | 144 | AR6003_HW_2_1_1_FW_DIR "/bdata.SD31.bin" |
145 | 145 | ||
146 | /* AR6004 1.0 definitions */ | 146 | /* AR6004 1.0 definitions */ |
147 | #define AR6004_HW_1_0_VERSION 0x30000623 | 147 | #define AR6004_HW_1_0_VERSION 0x30000623 |
148 | #define AR6004_HW_1_0_FW_DIR "ath6k/AR6004/hw1.0" | 148 | #define AR6004_HW_1_0_FW_DIR "ath6k/AR6004/hw1.0" |
149 | #define AR6004_HW_1_0_FIRMWARE_FILE "fw.ram.bin" | 149 | #define AR6004_HW_1_0_FIRMWARE_FILE "fw.ram.bin" |
150 | #define AR6004_HW_1_0_BOARD_DATA_FILE "ath6k/AR6004/hw1.0/bdata.bin" | 150 | #define AR6004_HW_1_0_BOARD_DATA_FILE AR6004_HW_1_0_FW_DIR "/bdata.bin" |
151 | #define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \ | 151 | #define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \ |
152 | "ath6k/AR6004/hw1.0/bdata.DB132.bin" | 152 | AR6004_HW_1_0_FW_DIR "/bdata.DB132.bin" |
153 | 153 | ||
154 | /* AR6004 1.1 definitions */ | 154 | /* AR6004 1.1 definitions */ |
155 | #define AR6004_HW_1_1_VERSION 0x30000001 | 155 | #define AR6004_HW_1_1_VERSION 0x30000001 |
156 | #define AR6004_HW_1_1_FW_DIR "ath6k/AR6004/hw1.1" | 156 | #define AR6004_HW_1_1_FW_DIR "ath6k/AR6004/hw1.1" |
157 | #define AR6004_HW_1_1_FIRMWARE_FILE "fw.ram.bin" | 157 | #define AR6004_HW_1_1_FIRMWARE_FILE "fw.ram.bin" |
158 | #define AR6004_HW_1_1_BOARD_DATA_FILE "ath6k/AR6004/hw1.1/bdata.bin" | 158 | #define AR6004_HW_1_1_BOARD_DATA_FILE AR6004_HW_1_1_FW_DIR "/bdata.bin" |
159 | #define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \ | 159 | #define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \ |
160 | "ath6k/AR6004/hw1.1/bdata.DB132.bin" | 160 | AR6004_HW_1_1_FW_DIR "/bdata.DB132.bin" |
161 | |||
162 | /* AR6004 1.2 definitions */ | ||
163 | #define AR6004_HW_1_2_VERSION 0x300007e8 | ||
164 | #define AR6004_HW_1_2_FW_DIR "ath6k/AR6004/hw1.2" | ||
165 | #define AR6004_HW_1_2_FIRMWARE_FILE "fw.ram.bin" | ||
166 | #define AR6004_HW_1_2_BOARD_DATA_FILE AR6004_HW_1_2_FW_DIR "/bdata.bin" | ||
167 | #define AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE \ | ||
168 | AR6004_HW_1_2_FW_DIR "/bdata.bin" | ||
161 | 169 | ||
162 | /* Per STA data, used in AP mode */ | 170 | /* Per STA data, used in AP mode */ |
163 | #define STA_PS_AWAKE BIT(0) | 171 | #define STA_PS_AWAKE BIT(0) |
@@ -502,6 +510,8 @@ enum ath6kl_vif_state { | |||
502 | WLAN_ENABLED, | 510 | WLAN_ENABLED, |
503 | STATS_UPDATE_PEND, | 511 | STATS_UPDATE_PEND, |
504 | HOST_SLEEP_MODE_CMD_PROCESSED, | 512 | HOST_SLEEP_MODE_CMD_PROCESSED, |
513 | NETDEV_MCAST_ALL_ON, | ||
514 | NETDEV_MCAST_ALL_OFF, | ||
505 | }; | 515 | }; |
506 | 516 | ||
507 | struct ath6kl_vif { | 517 | struct ath6kl_vif { |
@@ -549,9 +559,11 @@ struct ath6kl_vif { | |||
549 | u16 assoc_bss_beacon_int; | 559 | u16 assoc_bss_beacon_int; |
550 | u16 listen_intvl_t; | 560 | u16 listen_intvl_t; |
551 | u16 bmiss_time_t; | 561 | u16 bmiss_time_t; |
562 | u16 bg_scan_period; | ||
552 | u8 assoc_bss_dtim_period; | 563 | u8 assoc_bss_dtim_period; |
553 | struct net_device_stats net_stats; | 564 | struct net_device_stats net_stats; |
554 | struct target_stats target_stats; | 565 | struct target_stats target_stats; |
566 | struct wmi_connect_cmd profile; | ||
555 | 567 | ||
556 | struct list_head mc_filter; | 568 | struct list_head mc_filter; |
557 | }; | 569 | }; |
@@ -640,6 +652,7 @@ struct ath6kl { | |||
640 | u8 sta_list_index; | 652 | u8 sta_list_index; |
641 | struct ath6kl_req_key ap_mode_bkey; | 653 | struct ath6kl_req_key ap_mode_bkey; |
642 | struct sk_buff_head mcastpsq; | 654 | struct sk_buff_head mcastpsq; |
655 | u32 want_ch_switch; | ||
643 | 656 | ||
644 | /* | 657 | /* |
645 | * FIXME: protects access to mcastpsq but is actually useless as | 658 | * FIXME: protects access to mcastpsq but is actually useless as |
@@ -672,6 +685,7 @@ struct ath6kl { | |||
672 | u32 refclk_hz; | 685 | u32 refclk_hz; |
673 | u32 uarttx_pin; | 686 | u32 uarttx_pin; |
674 | u32 testscript_addr; | 687 | u32 testscript_addr; |
688 | enum wmi_phy_cap cap; | ||
675 | 689 | ||
676 | struct ath6kl_hw_fw { | 690 | struct ath6kl_hw_fw { |
677 | const char *dir; | 691 | const char *dir; |
@@ -805,7 +819,8 @@ void aggr_reset_state(struct aggr_info_conn *aggr_conn); | |||
805 | struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr); | 819 | struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr); |
806 | struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid); | 820 | struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid); |
807 | 821 | ||
808 | void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver); | 822 | void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver, |
823 | enum wmi_phy_cap cap); | ||
809 | int ath6kl_control_tx(void *devt, struct sk_buff *skb, | 824 | int ath6kl_control_tx(void *devt, struct sk_buff *skb, |
810 | enum htc_endpoint_id eid); | 825 | enum htc_endpoint_id eid); |
811 | void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, | 826 | void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, |
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index 1b76aff78508..15cfe30e54fd 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c | |||
@@ -401,8 +401,10 @@ static ssize_t ath6kl_fwlog_block_read(struct file *file, | |||
401 | 401 | ||
402 | ret = wait_for_completion_interruptible( | 402 | ret = wait_for_completion_interruptible( |
403 | &ar->debug.fwlog_completion); | 403 | &ar->debug.fwlog_completion); |
404 | if (ret == -ERESTARTSYS) | 404 | if (ret == -ERESTARTSYS) { |
405 | vfree(buf); | ||
405 | return ret; | 406 | return ret; |
407 | } | ||
406 | 408 | ||
407 | spin_lock(&ar->debug.fwlog_queue.lock); | 409 | spin_lock(&ar->debug.fwlog_queue.lock); |
408 | } | 410 | } |
@@ -1570,10 +1572,15 @@ static ssize_t ath6kl_bgscan_int_write(struct file *file, | |||
1570 | size_t count, loff_t *ppos) | 1572 | size_t count, loff_t *ppos) |
1571 | { | 1573 | { |
1572 | struct ath6kl *ar = file->private_data; | 1574 | struct ath6kl *ar = file->private_data; |
1575 | struct ath6kl_vif *vif; | ||
1573 | u16 bgscan_int; | 1576 | u16 bgscan_int; |
1574 | char buf[32]; | 1577 | char buf[32]; |
1575 | ssize_t len; | 1578 | ssize_t len; |
1576 | 1579 | ||
1580 | vif = ath6kl_vif_first(ar); | ||
1581 | if (!vif) | ||
1582 | return -EIO; | ||
1583 | |||
1577 | len = min(count, sizeof(buf) - 1); | 1584 | len = min(count, sizeof(buf) - 1); |
1578 | if (copy_from_user(buf, user_buf, len)) | 1585 | if (copy_from_user(buf, user_buf, len)) |
1579 | return -EFAULT; | 1586 | return -EFAULT; |
@@ -1585,6 +1592,8 @@ static ssize_t ath6kl_bgscan_int_write(struct file *file, | |||
1585 | if (bgscan_int == 0) | 1592 | if (bgscan_int == 0) |
1586 | bgscan_int = 0xffff; | 1593 | bgscan_int = 0xffff; |
1587 | 1594 | ||
1595 | vif->bg_scan_period = bgscan_int; | ||
1596 | |||
1588 | ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, 0, bgscan_int, 0, 0, 0, 3, | 1597 | ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, 0, bgscan_int, 0, 0, 0, 3, |
1589 | 0, 0, 0); | 1598 | 0, 0, 0); |
1590 | 1599 | ||
@@ -1809,6 +1818,7 @@ int ath6kl_debug_init_fs(struct ath6kl *ar) | |||
1809 | void ath6kl_debug_cleanup(struct ath6kl *ar) | 1818 | void ath6kl_debug_cleanup(struct ath6kl *ar) |
1810 | { | 1819 | { |
1811 | skb_queue_purge(&ar->debug.fwlog_queue); | 1820 | skb_queue_purge(&ar->debug.fwlog_queue); |
1821 | complete(&ar->debug.fwlog_completion); | ||
1812 | kfree(ar->debug.roam_tbl); | 1822 | kfree(ar->debug.roam_tbl); |
1813 | } | 1823 | } |
1814 | 1824 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c index 065e61516d7a..2798624d3a9d 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c +++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c | |||
@@ -83,10 +83,7 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info, | |||
83 | * never goes inactive EVER. | 83 | * never goes inactive EVER. |
84 | */ | 84 | */ |
85 | cur_ep_dist->dist_flags |= HTC_EP_ACTIVE; | 85 | cur_ep_dist->dist_flags |= HTC_EP_ACTIVE; |
86 | } else if (cur_ep_dist->svc_id == WMI_DATA_BK_SVC) | 86 | } |
87 | /* this is the lowest priority data endpoint */ | ||
88 | /* FIXME: this looks fishy, check */ | ||
89 | cred_info->lowestpri_ep_dist = cur_ep_dist->list; | ||
90 | 87 | ||
91 | /* | 88 | /* |
92 | * Streams have to be created (explicit | implicit) for all | 89 | * Streams have to be created (explicit | implicit) for all |
@@ -100,6 +97,13 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info, | |||
100 | */ | 97 | */ |
101 | } | 98 | } |
102 | 99 | ||
100 | /* | ||
101 | * For ath6kl_credit_seek function, | ||
102 | * it use list_for_each_entry_reverse to walk around the whole ep list. | ||
103 | * Therefore assign this lowestpri_ep_dist after walk around the ep_list | ||
104 | */ | ||
105 | cred_info->lowestpri_ep_dist = cur_ep_dist->list; | ||
106 | |||
103 | WARN_ON(cred_info->cur_free_credits <= 0); | 107 | WARN_ON(cred_info->cur_free_credits <= 0); |
104 | 108 | ||
105 | list_for_each_entry(cur_ep_dist, ep_list, list) { | 109 | list_for_each_entry(cur_ep_dist, ep_list, list) { |
@@ -758,7 +762,7 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, | |||
758 | u32 txb_mask; | 762 | u32 txb_mask; |
759 | u8 ac = WMM_NUM_AC; | 763 | u8 ac = WMM_NUM_AC; |
760 | 764 | ||
761 | if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || | 765 | if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) && |
762 | (WMI_CONTROL_SVC != endpoint->svc_id)) | 766 | (WMI_CONTROL_SVC != endpoint->svc_id)) |
763 | ac = target->dev->ar->ep2ac_map[endpoint->eid]; | 767 | ac = target->dev->ar->ep2ac_map[endpoint->eid]; |
764 | 768 | ||
@@ -793,16 +797,17 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, | |||
793 | * itself | 797 | * itself |
794 | */ | 798 | */ |
795 | txb_mask = ((1 << ac) - 1); | 799 | txb_mask = ((1 << ac) - 1); |
796 | /* | 800 | |
797 | * when the scatter request resources drop below a | 801 | /* |
798 | * certain threshold, disable Tx bundling for all | 802 | * when the scatter request resources drop below a |
799 | * AC's with priority lower than the current requesting | 803 | * certain threshold, disable Tx bundling for all |
800 | * AC. Otherwise re-enable Tx bundling for them | 804 | * AC's with priority lower than the current requesting |
801 | */ | 805 | * AC. Otherwise re-enable Tx bundling for them |
802 | if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS) | 806 | */ |
803 | target->tx_bndl_mask &= ~txb_mask; | 807 | if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS) |
804 | else | 808 | target->tx_bndl_mask &= ~txb_mask; |
805 | target->tx_bndl_mask |= txb_mask; | 809 | else |
810 | target->tx_bndl_mask |= txb_mask; | ||
806 | } | 811 | } |
807 | 812 | ||
808 | ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n", | 813 | ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n", |
@@ -849,6 +854,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, | |||
849 | int bundle_sent; | 854 | int bundle_sent; |
850 | int n_pkts_bundle; | 855 | int n_pkts_bundle; |
851 | u8 ac = WMM_NUM_AC; | 856 | u8 ac = WMM_NUM_AC; |
857 | int status; | ||
852 | 858 | ||
853 | spin_lock_bh(&target->tx_lock); | 859 | spin_lock_bh(&target->tx_lock); |
854 | 860 | ||
@@ -866,7 +872,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, | |||
866 | */ | 872 | */ |
867 | INIT_LIST_HEAD(&txq); | 873 | INIT_LIST_HEAD(&txq); |
868 | 874 | ||
869 | if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || | 875 | if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) && |
870 | (WMI_CONTROL_SVC != endpoint->svc_id)) | 876 | (WMI_CONTROL_SVC != endpoint->svc_id)) |
871 | ac = target->dev->ar->ep2ac_map[endpoint->eid]; | 877 | ac = target->dev->ar->ep2ac_map[endpoint->eid]; |
872 | 878 | ||
@@ -910,7 +916,12 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, | |||
910 | 916 | ||
911 | ath6kl_htc_tx_prep_pkt(packet, packet->info.tx.flags, | 917 | ath6kl_htc_tx_prep_pkt(packet, packet->info.tx.flags, |
912 | 0, packet->info.tx.seqno); | 918 | 0, packet->info.tx.seqno); |
913 | ath6kl_htc_tx_issue(target, packet); | 919 | status = ath6kl_htc_tx_issue(target, packet); |
920 | |||
921 | if (status) { | ||
922 | packet->status = status; | ||
923 | packet->completion(packet->context, packet); | ||
924 | } | ||
914 | } | 925 | } |
915 | 926 | ||
916 | spin_lock_bh(&target->tx_lock); | 927 | spin_lock_bh(&target->tx_lock); |
diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c index b277b3446882..f9626c723693 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c +++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c | |||
@@ -108,8 +108,6 @@ static void get_htc_packet_credit_based(struct htc_target *target, | |||
108 | 108 | ||
109 | /* get packet at head, but don't remove it */ | 109 | /* get packet at head, but don't remove it */ |
110 | packet = list_first_entry(&ep->txq, struct htc_packet, list); | 110 | packet = list_first_entry(&ep->txq, struct htc_packet, list); |
111 | if (packet == NULL) | ||
112 | break; | ||
113 | 111 | ||
114 | ath6kl_dbg(ATH6KL_DBG_HTC, | 112 | ath6kl_dbg(ATH6KL_DBG_HTC, |
115 | "%s: got head packet:0x%p , queue depth: %d\n", | 113 | "%s: got head packet:0x%p , queue depth: %d\n", |
@@ -803,8 +801,6 @@ static int htc_send_packets_multiple(struct htc_target *target, | |||
803 | 801 | ||
804 | /* get first packet to find out which ep the packets will go into */ | 802 | /* get first packet to find out which ep the packets will go into */ |
805 | packet = list_first_entry(pkt_queue, struct htc_packet, list); | 803 | packet = list_first_entry(pkt_queue, struct htc_packet, list); |
806 | if (packet == NULL) | ||
807 | return -EINVAL; | ||
808 | 804 | ||
809 | if (packet->endpoint >= ENDPOINT_MAX) { | 805 | if (packet->endpoint >= ENDPOINT_MAX) { |
810 | WARN_ON_ONCE(1); | 806 | WARN_ON_ONCE(1); |
@@ -1382,6 +1378,9 @@ static int ath6kl_htc_pipe_conn_service(struct htc_target *target, | |||
1382 | /* copy all the callbacks */ | 1378 | /* copy all the callbacks */ |
1383 | ep->ep_cb = conn_req->ep_cb; | 1379 | ep->ep_cb = conn_req->ep_cb; |
1384 | 1380 | ||
1381 | /* initialize tx_drop_packet_threshold */ | ||
1382 | ep->tx_drop_packet_threshold = MAX_HI_COOKIE_NUM; | ||
1383 | |||
1385 | status = ath6kl_hif_pipe_map_service(ar, ep->svc_id, | 1384 | status = ath6kl_hif_pipe_map_service(ar, ep->svc_id, |
1386 | &ep->pipe.pipeid_ul, | 1385 | &ep->pipe.pipeid_ul, |
1387 | &ep->pipe.pipeid_dl); | 1386 | &ep->pipe.pipeid_dl); |
@@ -1636,10 +1635,6 @@ static int ath6kl_htc_pipe_add_rxbuf_multiple(struct htc_target *target, | |||
1636 | return -EINVAL; | 1635 | return -EINVAL; |
1637 | 1636 | ||
1638 | first = list_first_entry(pkt_queue, struct htc_packet, list); | 1637 | first = list_first_entry(pkt_queue, struct htc_packet, list); |
1639 | if (first == NULL) { | ||
1640 | WARN_ON_ONCE(1); | ||
1641 | return -EINVAL; | ||
1642 | } | ||
1643 | 1638 | ||
1644 | if (first->endpoint >= ENDPOINT_MAX) { | 1639 | if (first->endpoint >= ENDPOINT_MAX) { |
1645 | WARN_ON_ONCE(1); | 1640 | WARN_ON_ONCE(1); |
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 29ef50ea07d5..7eb0515f458a 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c | |||
@@ -119,6 +119,24 @@ static const struct ath6kl_hw hw_list[] = { | |||
119 | .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE, | 119 | .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE, |
120 | .fw_default_board = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE, | 120 | .fw_default_board = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE, |
121 | }, | 121 | }, |
122 | { | ||
123 | .id = AR6004_HW_1_2_VERSION, | ||
124 | .name = "ar6004 hw 1.2", | ||
125 | .dataset_patch_addr = 0x436ecc, | ||
126 | .app_load_addr = 0x1234, | ||
127 | .board_ext_data_addr = 0x437000, | ||
128 | .reserved_ram_size = 9216, | ||
129 | .board_addr = 0x435c00, | ||
130 | .refclk_hz = 40000000, | ||
131 | .uarttx_pin = 11, | ||
132 | |||
133 | .fw = { | ||
134 | .dir = AR6004_HW_1_2_FW_DIR, | ||
135 | .fw = AR6004_HW_1_2_FIRMWARE_FILE, | ||
136 | }, | ||
137 | .fw_board = AR6004_HW_1_2_BOARD_DATA_FILE, | ||
138 | .fw_default_board = AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE, | ||
139 | }, | ||
122 | }; | 140 | }; |
123 | 141 | ||
124 | /* | 142 | /* |
@@ -445,9 +463,9 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) | |||
445 | P2P_FLAG_MACADDR_REQ | | 463 | P2P_FLAG_MACADDR_REQ | |
446 | P2P_FLAG_HMODEL_REQ); | 464 | P2P_FLAG_HMODEL_REQ); |
447 | if (ret) { | 465 | if (ret) { |
448 | ath6kl_dbg(ATH6KL_DBG_TRC, "failed to request P2P " | 466 | ath6kl_dbg(ATH6KL_DBG_TRC, |
449 | "capabilities (%d) - assuming P2P not " | 467 | "failed to request P2P capabilities (%d) - assuming P2P not supported\n", |
450 | "supported\n", ret); | 468 | ret); |
451 | ar->p2p = false; | 469 | ar->p2p = false; |
452 | } | 470 | } |
453 | } | 471 | } |
@@ -456,8 +474,9 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) | |||
456 | /* Enable Probe Request reporting for P2P */ | 474 | /* Enable Probe Request reporting for P2P */ |
457 | ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, idx, true); | 475 | ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, idx, true); |
458 | if (ret) { | 476 | if (ret) { |
459 | ath6kl_dbg(ATH6KL_DBG_TRC, "failed to enable Probe " | 477 | ath6kl_dbg(ATH6KL_DBG_TRC, |
460 | "Request reporting (%d)\n", ret); | 478 | "failed to enable Probe Request reporting (%d)\n", |
479 | ret); | ||
461 | } | 480 | } |
462 | } | 481 | } |
463 | 482 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 4d818f96c415..e5524470529c 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c | |||
@@ -421,8 +421,8 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) | |||
421 | if (!ik->valid) | 421 | if (!ik->valid) |
422 | break; | 422 | break; |
423 | 423 | ||
424 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed addkey for " | 424 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, |
425 | "the initial group key for AP mode\n"); | 425 | "Delayed addkey for the initial group key for AP mode\n"); |
426 | memset(key_rsc, 0, sizeof(key_rsc)); | 426 | memset(key_rsc, 0, sizeof(key_rsc)); |
427 | res = ath6kl_wmi_addkey_cmd( | 427 | res = ath6kl_wmi_addkey_cmd( |
428 | ar->wmi, vif->fw_vif_idx, ik->key_index, ik->key_type, | 428 | ar->wmi, vif->fw_vif_idx, ik->key_index, ik->key_type, |
@@ -430,12 +430,19 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) | |||
430 | ik->key, | 430 | ik->key, |
431 | KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG); | 431 | KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG); |
432 | if (res) { | 432 | if (res) { |
433 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed " | 433 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, |
434 | "addkey failed: %d\n", res); | 434 | "Delayed addkey failed: %d\n", res); |
435 | } | 435 | } |
436 | break; | 436 | break; |
437 | } | 437 | } |
438 | 438 | ||
439 | if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) { | ||
440 | ar->want_ch_switch &= ~(1 << vif->fw_vif_idx); | ||
441 | /* we actually don't know the phymode, default to HT20 */ | ||
442 | ath6kl_cfg80211_ch_switch_notify(vif, channel, | ||
443 | WMI_11G_HT20); | ||
444 | } | ||
445 | |||
439 | ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0); | 446 | ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0); |
440 | set_bit(CONNECTED, &vif->flags); | 447 | set_bit(CONNECTED, &vif->flags); |
441 | netif_carrier_on(vif->ndev); | 448 | netif_carrier_on(vif->ndev); |
@@ -541,7 +548,8 @@ void ath6kl_disconnect(struct ath6kl_vif *vif) | |||
541 | 548 | ||
542 | /* WMI Event handlers */ | 549 | /* WMI Event handlers */ |
543 | 550 | ||
544 | void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver) | 551 | void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver, |
552 | enum wmi_phy_cap cap) | ||
545 | { | 553 | { |
546 | struct ath6kl *ar = devt; | 554 | struct ath6kl *ar = devt; |
547 | 555 | ||
@@ -551,6 +559,7 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver) | |||
551 | 559 | ||
552 | ar->version.wlan_ver = sw_ver; | 560 | ar->version.wlan_ver = sw_ver; |
553 | ar->version.abi_ver = abi_ver; | 561 | ar->version.abi_ver = abi_ver; |
562 | ar->hw.cap = cap; | ||
554 | 563 | ||
555 | snprintf(ar->wiphy->fw_version, | 564 | snprintf(ar->wiphy->fw_version, |
556 | sizeof(ar->wiphy->fw_version), | 565 | sizeof(ar->wiphy->fw_version), |
@@ -584,6 +593,45 @@ void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status) | |||
584 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "scan complete: %d\n", status); | 593 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "scan complete: %d\n", status); |
585 | } | 594 | } |
586 | 595 | ||
596 | static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel) | ||
597 | { | ||
598 | |||
599 | struct ath6kl *ar = vif->ar; | ||
600 | |||
601 | vif->next_chan = channel; | ||
602 | vif->profile.ch = cpu_to_le16(channel); | ||
603 | |||
604 | switch (vif->nw_type) { | ||
605 | case AP_NETWORK: | ||
606 | return ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, | ||
607 | &vif->profile); | ||
608 | default: | ||
609 | ath6kl_err("won't switch channels nw_type=%d\n", vif->nw_type); | ||
610 | return -ENOTSUPP; | ||
611 | } | ||
612 | } | ||
613 | |||
614 | static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel) | ||
615 | { | ||
616 | |||
617 | struct ath6kl_vif *vif; | ||
618 | int res = 0; | ||
619 | |||
620 | if (!ar->want_ch_switch) | ||
621 | return; | ||
622 | |||
623 | spin_lock_bh(&ar->list_lock); | ||
624 | list_for_each_entry(vif, &ar->vif_list, list) { | ||
625 | if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) | ||
626 | res = ath6kl_commit_ch_switch(vif, channel); | ||
627 | |||
628 | if (res) | ||
629 | ath6kl_err("channel switch failed nw_type %d res %d\n", | ||
630 | vif->nw_type, res); | ||
631 | } | ||
632 | spin_unlock_bh(&ar->list_lock); | ||
633 | } | ||
634 | |||
587 | void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, | 635 | void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, |
588 | u16 listen_int, u16 beacon_int, | 636 | u16 listen_int, u16 beacon_int, |
589 | enum network_type net_type, u8 beacon_ie_len, | 637 | enum network_type net_type, u8 beacon_ie_len, |
@@ -601,9 +649,11 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, | |||
601 | memcpy(vif->bssid, bssid, sizeof(vif->bssid)); | 649 | memcpy(vif->bssid, bssid, sizeof(vif->bssid)); |
602 | vif->bss_ch = channel; | 650 | vif->bss_ch = channel; |
603 | 651 | ||
604 | if ((vif->nw_type == INFRA_NETWORK)) | 652 | if ((vif->nw_type == INFRA_NETWORK)) { |
605 | ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, | 653 | ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, |
606 | vif->listen_intvl_t, 0); | 654 | vif->listen_intvl_t, 0); |
655 | ath6kl_check_ch_switch(ar, channel); | ||
656 | } | ||
607 | 657 | ||
608 | netif_wake_queue(vif->ndev); | 658 | netif_wake_queue(vif->ndev); |
609 | 659 | ||
@@ -926,6 +976,11 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, | |||
926 | struct ath6kl *ar = vif->ar; | 976 | struct ath6kl *ar = vif->ar; |
927 | 977 | ||
928 | if (vif->nw_type == AP_NETWORK) { | 978 | if (vif->nw_type == AP_NETWORK) { |
979 | /* disconnect due to other STA vif switching channels */ | ||
980 | if (reason == BSS_DISCONNECTED && | ||
981 | prot_reason_status == WMI_AP_REASON_STA_ROAM) | ||
982 | ar->want_ch_switch |= 1 << vif->fw_vif_idx; | ||
983 | |||
929 | if (!ath6kl_remove_sta(ar, bssid, prot_reason_status)) | 984 | if (!ath6kl_remove_sta(ar, bssid, prot_reason_status)) |
930 | return; | 985 | return; |
931 | 986 | ||
@@ -1090,7 +1145,7 @@ static int ath6kl_set_features(struct net_device *dev, | |||
1090 | static void ath6kl_set_multicast_list(struct net_device *ndev) | 1145 | static void ath6kl_set_multicast_list(struct net_device *ndev) |
1091 | { | 1146 | { |
1092 | struct ath6kl_vif *vif = netdev_priv(ndev); | 1147 | struct ath6kl_vif *vif = netdev_priv(ndev); |
1093 | bool mc_all_on = false, mc_all_off = false; | 1148 | bool mc_all_on = false; |
1094 | int mc_count = netdev_mc_count(ndev); | 1149 | int mc_count = netdev_mc_count(ndev); |
1095 | struct netdev_hw_addr *ha; | 1150 | struct netdev_hw_addr *ha; |
1096 | bool found; | 1151 | bool found; |
@@ -1102,24 +1157,41 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) | |||
1102 | !test_bit(WLAN_ENABLED, &vif->flags)) | 1157 | !test_bit(WLAN_ENABLED, &vif->flags)) |
1103 | return; | 1158 | return; |
1104 | 1159 | ||
1160 | /* Enable multicast-all filter. */ | ||
1105 | mc_all_on = !!(ndev->flags & IFF_PROMISC) || | 1161 | mc_all_on = !!(ndev->flags & IFF_PROMISC) || |
1106 | !!(ndev->flags & IFF_ALLMULTI) || | 1162 | !!(ndev->flags & IFF_ALLMULTI) || |
1107 | !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST); | 1163 | !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST); |
1108 | 1164 | ||
1109 | mc_all_off = !(ndev->flags & IFF_MULTICAST) || mc_count == 0; | 1165 | if (mc_all_on) |
1166 | set_bit(NETDEV_MCAST_ALL_ON, &vif->flags); | ||
1167 | else | ||
1168 | clear_bit(NETDEV_MCAST_ALL_ON, &vif->flags); | ||
1169 | |||
1170 | mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON); | ||
1110 | 1171 | ||
1111 | if (mc_all_on || mc_all_off) { | 1172 | if (!(ndev->flags & IFF_MULTICAST)) { |
1112 | /* Enable/disable all multicast */ | 1173 | mc_all_on = false; |
1113 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n", | 1174 | set_bit(NETDEV_MCAST_ALL_OFF, &vif->flags); |
1114 | mc_all_on ? "enabling" : "disabling"); | 1175 | } else { |
1115 | ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, | 1176 | clear_bit(NETDEV_MCAST_ALL_OFF, &vif->flags); |
1177 | } | ||
1178 | |||
1179 | /* Enable/disable "multicast-all" filter*/ | ||
1180 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast-all filter\n", | ||
1181 | mc_all_on ? "enabling" : "disabling"); | ||
1182 | |||
1183 | ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, | ||
1116 | mc_all_on); | 1184 | mc_all_on); |
1117 | if (ret) | 1185 | if (ret) { |
1118 | ath6kl_warn("Failed to %s multicast receive\n", | 1186 | ath6kl_warn("Failed to %s multicast-all receive\n", |
1119 | mc_all_on ? "enable" : "disable"); | 1187 | mc_all_on ? "enable" : "disable"); |
1120 | return; | 1188 | return; |
1121 | } | 1189 | } |
1122 | 1190 | ||
1191 | if (test_bit(NETDEV_MCAST_ALL_ON, &vif->flags)) | ||
1192 | return; | ||
1193 | |||
1194 | /* Keep the driver and firmware mcast list in sync. */ | ||
1123 | list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) { | 1195 | list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) { |
1124 | found = false; | 1196 | found = false; |
1125 | netdev_for_each_mc_addr(ha, ndev) { | 1197 | netdev_for_each_mc_addr(ha, ndev) { |
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 44ea7a742101..05b95405f7b5 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c | |||
@@ -552,7 +552,7 @@ static int ath6kl_sdio_write_async(struct ath6kl *ar, u32 address, u8 *buffer, | |||
552 | 552 | ||
553 | bus_req = ath6kl_sdio_alloc_busreq(ar_sdio); | 553 | bus_req = ath6kl_sdio_alloc_busreq(ar_sdio); |
554 | 554 | ||
555 | if (!bus_req) | 555 | if (WARN_ON_ONCE(!bus_req)) |
556 | return -ENOMEM; | 556 | return -ENOMEM; |
557 | 557 | ||
558 | bus_req->address = address; | 558 | bus_req->address = address; |
@@ -915,6 +915,9 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | |||
915 | } | 915 | } |
916 | 916 | ||
917 | cut_pwr: | 917 | cut_pwr: |
918 | if (func->card && func->card->host) | ||
919 | func->card->host->pm_flags &= ~MMC_PM_KEEP_POWER; | ||
920 | |||
918 | return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL); | 921 | return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL); |
919 | } | 922 | } |
920 | 923 | ||
@@ -985,9 +988,8 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr) | |||
985 | } | 988 | } |
986 | 989 | ||
987 | if (status) { | 990 | if (status) { |
988 | ath6kl_err("%s: failed to write initial bytes of 0x%x " | 991 | ath6kl_err("%s: failed to write initial bytes of 0x%x to window reg: 0x%X\n", |
989 | "to window reg: 0x%X\n", __func__, | 992 | __func__, addr, reg_addr); |
990 | addr, reg_addr); | ||
991 | return status; | 993 | return status; |
992 | } | 994 | } |
993 | 995 | ||
@@ -1076,8 +1078,8 @@ static int ath6kl_sdio_bmi_credits(struct ath6kl *ar) | |||
1076 | (u8 *)&ar->bmi.cmd_credits, 4, | 1078 | (u8 *)&ar->bmi.cmd_credits, 4, |
1077 | HIF_RD_SYNC_BYTE_INC); | 1079 | HIF_RD_SYNC_BYTE_INC); |
1078 | if (ret) { | 1080 | if (ret) { |
1079 | ath6kl_err("Unable to decrement the command credit " | 1081 | ath6kl_err("Unable to decrement the command credit count register: %d\n", |
1080 | "count register: %d\n", ret); | 1082 | ret); |
1081 | return ret; | 1083 | return ret; |
1082 | } | 1084 | } |
1083 | 1085 | ||
@@ -1457,3 +1459,6 @@ MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); | |||
1457 | MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE); | 1459 | MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE); |
1458 | MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); | 1460 | MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); |
1459 | MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); | 1461 | MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); |
1462 | MODULE_FIRMWARE(AR6004_HW_1_2_FW_DIR "/" AR6004_HW_1_2_FIRMWARE_FILE); | ||
1463 | MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); | ||
1464 | MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); | ||
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 82f2f5cb475b..67206aedea6c 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c | |||
@@ -362,15 +362,11 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) | |||
362 | skb, skb->data, skb->len); | 362 | skb, skb->data, skb->len); |
363 | 363 | ||
364 | /* If target is not associated */ | 364 | /* If target is not associated */ |
365 | if (!test_bit(CONNECTED, &vif->flags)) { | 365 | if (!test_bit(CONNECTED, &vif->flags)) |
366 | dev_kfree_skb(skb); | 366 | goto fail_tx; |
367 | return 0; | ||
368 | } | ||
369 | 367 | ||
370 | if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) { | 368 | if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) |
371 | dev_kfree_skb(skb); | 369 | goto fail_tx; |
372 | return 0; | ||
373 | } | ||
374 | 370 | ||
375 | if (!test_bit(WMI_READY, &ar->flag)) | 371 | if (!test_bit(WMI_READY, &ar->flag)) |
376 | goto fail_tx; | 372 | goto fail_tx; |
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index 44a795f14da9..3740c3d6ab88 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c | |||
@@ -1037,6 +1037,14 @@ static void ath6kl_usb_stop(struct ath6kl *ar) | |||
1037 | hif_stop(ar); | 1037 | hif_stop(ar); |
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | static void ath6kl_usb_cleanup_scatter(struct ath6kl *ar) | ||
1041 | { | ||
1042 | /* | ||
1043 | * USB doesn't support it. Just return. | ||
1044 | */ | ||
1045 | return; | ||
1046 | } | ||
1047 | |||
1040 | static const struct ath6kl_hif_ops ath6kl_usb_ops = { | 1048 | static const struct ath6kl_hif_ops ath6kl_usb_ops = { |
1041 | .diag_read32 = ath6kl_usb_diag_read32, | 1049 | .diag_read32 = ath6kl_usb_diag_read32, |
1042 | .diag_write32 = ath6kl_usb_diag_write32, | 1050 | .diag_write32 = ath6kl_usb_diag_write32, |
@@ -1049,6 +1057,7 @@ static const struct ath6kl_hif_ops ath6kl_usb_ops = { | |||
1049 | .pipe_get_default = ath6kl_usb_get_default_pipe, | 1057 | .pipe_get_default = ath6kl_usb_get_default_pipe, |
1050 | .pipe_map_service = ath6kl_usb_map_service_pipe, | 1058 | .pipe_map_service = ath6kl_usb_map_service_pipe, |
1051 | .pipe_get_free_queue_number = ath6kl_usb_get_free_queue_number, | 1059 | .pipe_get_free_queue_number = ath6kl_usb_get_free_queue_number, |
1060 | .cleanup_scatter = ath6kl_usb_cleanup_scatter, | ||
1052 | }; | 1061 | }; |
1053 | 1062 | ||
1054 | /* ath6kl usb driver registered functions */ | 1063 | /* ath6kl usb driver registered functions */ |
@@ -1208,3 +1217,6 @@ MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); | |||
1208 | MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); | 1217 | MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); |
1209 | MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); | 1218 | MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); |
1210 | MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); | 1219 | MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); |
1220 | MODULE_FIRMWARE(AR6004_HW_1_2_FIRMWARE_FILE); | ||
1221 | MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); | ||
1222 | MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); | ||
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 7c8a9977faf5..ee8ec2394c2c 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -16,6 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/ip.h> | 18 | #include <linux/ip.h> |
19 | #include <linux/in.h> | ||
19 | #include "core.h" | 20 | #include "core.h" |
20 | #include "debug.h" | 21 | #include "debug.h" |
21 | #include "testmode.h" | 22 | #include "testmode.h" |
@@ -289,6 +290,13 @@ int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx, | |||
289 | layer2_priority); | 290 | layer2_priority); |
290 | } else | 291 | } else |
291 | usr_pri = layer2_priority & 0x7; | 292 | usr_pri = layer2_priority & 0x7; |
293 | |||
294 | /* | ||
295 | * Queue the EAPOL frames in the same WMM_AC_VO queue | ||
296 | * as that of management frames. | ||
297 | */ | ||
298 | if (skb->protocol == cpu_to_be16(ETH_P_PAE)) | ||
299 | usr_pri = WMI_VOICE_USER_PRIORITY; | ||
292 | } | 300 | } |
293 | 301 | ||
294 | /* | 302 | /* |
@@ -460,8 +468,9 @@ static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap, | |||
460 | freq, dur); | 468 | freq, dur); |
461 | chan = ieee80211_get_channel(ar->wiphy, freq); | 469 | chan = ieee80211_get_channel(ar->wiphy, freq); |
462 | if (!chan) { | 470 | if (!chan) { |
463 | ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl: Unknown channel " | 471 | ath6kl_dbg(ATH6KL_DBG_WMI, |
464 | "(freq=%u)\n", freq); | 472 | "remain_on_chnl: Unknown channel (freq=%u)\n", |
473 | freq); | ||
465 | return -EINVAL; | 474 | return -EINVAL; |
466 | } | 475 | } |
467 | id = vif->last_roc_id; | 476 | id = vif->last_roc_id; |
@@ -488,12 +497,14 @@ static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi, | |||
488 | ev = (struct wmi_cancel_remain_on_chnl_event *) datap; | 497 | ev = (struct wmi_cancel_remain_on_chnl_event *) datap; |
489 | freq = le32_to_cpu(ev->freq); | 498 | freq = le32_to_cpu(ev->freq); |
490 | dur = le32_to_cpu(ev->duration); | 499 | dur = le32_to_cpu(ev->duration); |
491 | ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: freq=%u dur=%u " | 500 | ath6kl_dbg(ATH6KL_DBG_WMI, |
492 | "status=%u\n", freq, dur, ev->status); | 501 | "cancel_remain_on_chnl: freq=%u dur=%u status=%u\n", |
502 | freq, dur, ev->status); | ||
493 | chan = ieee80211_get_channel(ar->wiphy, freq); | 503 | chan = ieee80211_get_channel(ar->wiphy, freq); |
494 | if (!chan) { | 504 | if (!chan) { |
495 | ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: Unknown " | 505 | ath6kl_dbg(ATH6KL_DBG_WMI, |
496 | "channel (freq=%u)\n", freq); | 506 | "cancel_remain_on_chnl: Unknown channel (freq=%u)\n", |
507 | freq); | ||
497 | return -EINVAL; | 508 | return -EINVAL; |
498 | } | 509 | } |
499 | if (vif->last_cancel_roc_id && | 510 | if (vif->last_cancel_roc_id && |
@@ -548,12 +559,12 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
548 | freq = le32_to_cpu(ev->freq); | 559 | freq = le32_to_cpu(ev->freq); |
549 | dlen = le16_to_cpu(ev->len); | 560 | dlen = le16_to_cpu(ev->len); |
550 | if (datap + len < ev->data + dlen) { | 561 | if (datap + len < ev->data + dlen) { |
551 | ath6kl_err("invalid wmi_p2p_rx_probe_req_event: " | 562 | ath6kl_err("invalid wmi_p2p_rx_probe_req_event: len=%d dlen=%u\n", |
552 | "len=%d dlen=%u\n", len, dlen); | 563 | len, dlen); |
553 | return -EINVAL; | 564 | return -EINVAL; |
554 | } | 565 | } |
555 | ath6kl_dbg(ATH6KL_DBG_WMI, "rx_probe_req: len=%u freq=%u " | 566 | ath6kl_dbg(ATH6KL_DBG_WMI, |
556 | "probe_req_report=%d\n", | 567 | "rx_probe_req: len=%u freq=%u probe_req_report=%d\n", |
557 | dlen, freq, vif->probe_req_report); | 568 | dlen, freq, vif->probe_req_report); |
558 | 569 | ||
559 | if (vif->probe_req_report || vif->nw_type == AP_NETWORK) | 570 | if (vif->probe_req_report || vif->nw_type == AP_NETWORK) |
@@ -592,8 +603,8 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
592 | freq = le32_to_cpu(ev->freq); | 603 | freq = le32_to_cpu(ev->freq); |
593 | dlen = le16_to_cpu(ev->len); | 604 | dlen = le16_to_cpu(ev->len); |
594 | if (datap + len < ev->data + dlen) { | 605 | if (datap + len < ev->data + dlen) { |
595 | ath6kl_err("invalid wmi_rx_action_event: " | 606 | ath6kl_err("invalid wmi_rx_action_event: len=%d dlen=%u\n", |
596 | "len=%d dlen=%u\n", len, dlen); | 607 | len, dlen); |
597 | return -EINVAL; | 608 | return -EINVAL; |
598 | } | 609 | } |
599 | ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); | 610 | ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); |
@@ -687,7 +698,7 @@ static int ath6kl_wmi_ready_event_rx(struct wmi *wmi, u8 *datap, int len) | |||
687 | 698 | ||
688 | ath6kl_ready_event(wmi->parent_dev, ev->mac_addr, | 699 | ath6kl_ready_event(wmi->parent_dev, ev->mac_addr, |
689 | le32_to_cpu(ev->sw_version), | 700 | le32_to_cpu(ev->sw_version), |
690 | le32_to_cpu(ev->abi_version)); | 701 | le32_to_cpu(ev->abi_version), ev->phy_cap); |
691 | 702 | ||
692 | return 0; | 703 | return 0; |
693 | } | 704 | } |
@@ -777,16 +788,15 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
777 | /* AP mode start/STA connected event */ | 788 | /* AP mode start/STA connected event */ |
778 | struct net_device *dev = vif->ndev; | 789 | struct net_device *dev = vif->ndev; |
779 | if (memcmp(dev->dev_addr, ev->u.ap_bss.bssid, ETH_ALEN) == 0) { | 790 | if (memcmp(dev->dev_addr, ev->u.ap_bss.bssid, ETH_ALEN) == 0) { |
780 | ath6kl_dbg(ATH6KL_DBG_WMI, "%s: freq %d bssid %pM " | 791 | ath6kl_dbg(ATH6KL_DBG_WMI, |
781 | "(AP started)\n", | 792 | "%s: freq %d bssid %pM (AP started)\n", |
782 | __func__, le16_to_cpu(ev->u.ap_bss.ch), | 793 | __func__, le16_to_cpu(ev->u.ap_bss.ch), |
783 | ev->u.ap_bss.bssid); | 794 | ev->u.ap_bss.bssid); |
784 | ath6kl_connect_ap_mode_bss( | 795 | ath6kl_connect_ap_mode_bss( |
785 | vif, le16_to_cpu(ev->u.ap_bss.ch)); | 796 | vif, le16_to_cpu(ev->u.ap_bss.ch)); |
786 | } else { | 797 | } else { |
787 | ath6kl_dbg(ATH6KL_DBG_WMI, "%s: aid %u mac_addr %pM " | 798 | ath6kl_dbg(ATH6KL_DBG_WMI, |
788 | "auth=%u keymgmt=%u cipher=%u apsd_info=%u " | 799 | "%s: aid %u mac_addr %pM auth=%u keymgmt=%u cipher=%u apsd_info=%u (STA connected)\n", |
789 | "(STA connected)\n", | ||
790 | __func__, ev->u.ap_sta.aid, | 800 | __func__, ev->u.ap_sta.aid, |
791 | ev->u.ap_sta.mac_addr, | 801 | ev->u.ap_sta.mac_addr, |
792 | ev->u.ap_sta.auth, | 802 | ev->u.ap_sta.auth, |
@@ -1229,8 +1239,9 @@ static int ath6kl_wmi_neighbor_report_event_rx(struct wmi *wmi, u8 *datap, | |||
1229 | ev = (struct wmi_neighbor_report_event *) datap; | 1239 | ev = (struct wmi_neighbor_report_event *) datap; |
1230 | if (sizeof(*ev) + ev->num_neighbors * sizeof(struct wmi_neighbor_info) | 1240 | if (sizeof(*ev) + ev->num_neighbors * sizeof(struct wmi_neighbor_info) |
1231 | > len) { | 1241 | > len) { |
1232 | ath6kl_dbg(ATH6KL_DBG_WMI, "truncated neighbor event " | 1242 | ath6kl_dbg(ATH6KL_DBG_WMI, |
1233 | "(num=%d len=%d)\n", ev->num_neighbors, len); | 1243 | "truncated neighbor event (num=%d len=%d)\n", |
1244 | ev->num_neighbors, len); | ||
1234 | return -EINVAL; | 1245 | return -EINVAL; |
1235 | } | 1246 | } |
1236 | for (i = 0; i < ev->num_neighbors; i++) { | 1247 | for (i = 0; i < ev->num_neighbors; i++) { |
@@ -1814,12 +1825,14 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, | |||
1814 | u32 home_dwell_time, u32 force_scan_interval, | 1825 | u32 home_dwell_time, u32 force_scan_interval, |
1815 | s8 num_chan, u16 *ch_list, u32 no_cck, u32 *rates) | 1826 | s8 num_chan, u16 *ch_list, u32 no_cck, u32 *rates) |
1816 | { | 1827 | { |
1828 | struct ieee80211_supported_band *sband; | ||
1817 | struct sk_buff *skb; | 1829 | struct sk_buff *skb; |
1818 | struct wmi_begin_scan_cmd *sc; | 1830 | struct wmi_begin_scan_cmd *sc; |
1819 | s8 size; | 1831 | s8 size, *supp_rates; |
1820 | int i, band, ret; | 1832 | int i, band, ret; |
1821 | struct ath6kl *ar = wmi->parent_dev; | 1833 | struct ath6kl *ar = wmi->parent_dev; |
1822 | int num_rates; | 1834 | int num_rates; |
1835 | u32 ratemask; | ||
1823 | 1836 | ||
1824 | size = sizeof(struct wmi_begin_scan_cmd); | 1837 | size = sizeof(struct wmi_begin_scan_cmd); |
1825 | 1838 | ||
@@ -1846,10 +1859,13 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, | |||
1846 | sc->num_ch = num_chan; | 1859 | sc->num_ch = num_chan; |
1847 | 1860 | ||
1848 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 1861 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
1849 | struct ieee80211_supported_band *sband = | 1862 | sband = ar->wiphy->bands[band]; |
1850 | ar->wiphy->bands[band]; | 1863 | |
1851 | u32 ratemask = rates[band]; | 1864 | if (!sband) |
1852 | u8 *supp_rates = sc->supp_rates[band].rates; | 1865 | continue; |
1866 | |||
1867 | ratemask = rates[band]; | ||
1868 | supp_rates = sc->supp_rates[band].rates; | ||
1853 | num_rates = 0; | 1869 | num_rates = 0; |
1854 | 1870 | ||
1855 | for (i = 0; i < sband->n_bitrates; i++) { | 1871 | for (i = 0; i < sband->n_bitrates; i++) { |
@@ -2129,8 +2145,8 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index, | |||
2129 | struct wmi_add_cipher_key_cmd *cmd; | 2145 | struct wmi_add_cipher_key_cmd *cmd; |
2130 | int ret; | 2146 | int ret; |
2131 | 2147 | ||
2132 | ath6kl_dbg(ATH6KL_DBG_WMI, "addkey cmd: key_index=%u key_type=%d " | 2148 | ath6kl_dbg(ATH6KL_DBG_WMI, |
2133 | "key_usage=%d key_len=%d key_op_ctrl=%d\n", | 2149 | "addkey cmd: key_index=%u key_type=%d key_usage=%d key_len=%d key_op_ctrl=%d\n", |
2134 | key_index, key_type, key_usage, key_len, key_op_ctrl); | 2150 | key_index, key_type, key_usage, key_len, key_op_ctrl); |
2135 | 2151 | ||
2136 | if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) || | 2152 | if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) || |
@@ -3047,8 +3063,8 @@ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, | |||
3047 | 3063 | ||
3048 | res = ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_CONFIG_COMMIT_CMDID, | 3064 | res = ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_CONFIG_COMMIT_CMDID, |
3049 | NO_SYNC_WMIFLAG); | 3065 | NO_SYNC_WMIFLAG); |
3050 | ath6kl_dbg(ATH6KL_DBG_WMI, "%s: nw_type=%u auth_mode=%u ch=%u " | 3066 | ath6kl_dbg(ATH6KL_DBG_WMI, |
3051 | "ctrl_flags=0x%x-> res=%d\n", | 3067 | "%s: nw_type=%u auth_mode=%u ch=%u ctrl_flags=0x%x-> res=%d\n", |
3052 | __func__, p->nw_type, p->auth_mode, le16_to_cpu(p->ch), | 3068 | __func__, p->nw_type, p->auth_mode, le16_to_cpu(p->ch), |
3053 | le32_to_cpu(p->ctrl_flags), res); | 3069 | le32_to_cpu(p->ctrl_flags), res); |
3054 | return res; | 3070 | return res; |
@@ -3208,8 +3224,9 @@ int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type, | |||
3208 | if (!skb) | 3224 | if (!skb) |
3209 | return -ENOMEM; | 3225 | return -ENOMEM; |
3210 | 3226 | ||
3211 | ath6kl_dbg(ATH6KL_DBG_WMI, "set_appie_cmd: mgmt_frm_type=%u " | 3227 | ath6kl_dbg(ATH6KL_DBG_WMI, |
3212 | "ie_len=%u\n", mgmt_frm_type, ie_len); | 3228 | "set_appie_cmd: mgmt_frm_type=%u ie_len=%u\n", |
3229 | mgmt_frm_type, ie_len); | ||
3213 | p = (struct wmi_set_appie_cmd *) skb->data; | 3230 | p = (struct wmi_set_appie_cmd *) skb->data; |
3214 | p->mgmt_frm_type = mgmt_frm_type; | 3231 | p->mgmt_frm_type = mgmt_frm_type; |
3215 | p->ie_len = ie_len; | 3232 | p->ie_len = ie_len; |
@@ -3310,8 +3327,9 @@ static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, | |||
3310 | wmi->last_mgmt_tx_frame = buf; | 3327 | wmi->last_mgmt_tx_frame = buf; |
3311 | wmi->last_mgmt_tx_frame_len = data_len; | 3328 | wmi->last_mgmt_tx_frame_len = data_len; |
3312 | 3329 | ||
3313 | ath6kl_dbg(ATH6KL_DBG_WMI, "send_action_cmd: id=%u freq=%u wait=%u " | 3330 | ath6kl_dbg(ATH6KL_DBG_WMI, |
3314 | "len=%u\n", id, freq, wait, data_len); | 3331 | "send_action_cmd: id=%u freq=%u wait=%u len=%u\n", |
3332 | id, freq, wait, data_len); | ||
3315 | p = (struct wmi_send_action_cmd *) skb->data; | 3333 | p = (struct wmi_send_action_cmd *) skb->data; |
3316 | p->id = cpu_to_le32(id); | 3334 | p->id = cpu_to_le32(id); |
3317 | p->freq = cpu_to_le32(freq); | 3335 | p->freq = cpu_to_le32(freq); |
@@ -3348,8 +3366,9 @@ static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, | |||
3348 | wmi->last_mgmt_tx_frame = buf; | 3366 | wmi->last_mgmt_tx_frame = buf; |
3349 | wmi->last_mgmt_tx_frame_len = data_len; | 3367 | wmi->last_mgmt_tx_frame_len = data_len; |
3350 | 3368 | ||
3351 | ath6kl_dbg(ATH6KL_DBG_WMI, "send_action_cmd: id=%u freq=%u wait=%u " | 3369 | ath6kl_dbg(ATH6KL_DBG_WMI, |
3352 | "len=%u\n", id, freq, wait, data_len); | 3370 | "send_action_cmd: id=%u freq=%u wait=%u len=%u\n", |
3371 | id, freq, wait, data_len); | ||
3353 | p = (struct wmi_send_mgmt_cmd *) skb->data; | 3372 | p = (struct wmi_send_mgmt_cmd *) skb->data; |
3354 | p->id = cpu_to_le32(id); | 3373 | p->id = cpu_to_le32(id); |
3355 | p->freq = cpu_to_le32(freq); | 3374 | p->freq = cpu_to_le32(freq); |
@@ -3402,8 +3421,9 @@ int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq, | |||
3402 | if (!skb) | 3421 | if (!skb) |
3403 | return -ENOMEM; | 3422 | return -ENOMEM; |
3404 | 3423 | ||
3405 | ath6kl_dbg(ATH6KL_DBG_WMI, "send_probe_response_cmd: freq=%u dst=%pM " | 3424 | ath6kl_dbg(ATH6KL_DBG_WMI, |
3406 | "len=%u\n", freq, dst, data_len); | 3425 | "send_probe_response_cmd: freq=%u dst=%pM len=%u\n", |
3426 | freq, dst, data_len); | ||
3407 | p = (struct wmi_p2p_probe_response_cmd *) skb->data; | 3427 | p = (struct wmi_p2p_probe_response_cmd *) skb->data; |
3408 | p->freq = cpu_to_le32(freq); | 3428 | p->freq = cpu_to_le32(freq); |
3409 | memcpy(p->destination_addr, dst, ETH_ALEN); | 3429 | memcpy(p->destination_addr, dst, ETH_ALEN); |
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index d3d2ab5c1689..9076bec3a2ba 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h | |||
@@ -106,6 +106,8 @@ struct wmi_data_sync_bufs { | |||
106 | #define WMM_AC_VI 2 /* video */ | 106 | #define WMM_AC_VI 2 /* video */ |
107 | #define WMM_AC_VO 3 /* voice */ | 107 | #define WMM_AC_VO 3 /* voice */ |
108 | 108 | ||
109 | #define WMI_VOICE_USER_PRIORITY 0x7 | ||
110 | |||
109 | struct wmi { | 111 | struct wmi { |
110 | u16 stream_exist_for_ac[WMM_NUM_AC]; | 112 | u16 stream_exist_for_ac[WMM_NUM_AC]; |
111 | u8 fat_pipe_exist; | 113 | u8 fat_pipe_exist; |
@@ -1151,6 +1153,7 @@ enum wmi_phy_mode { | |||
1151 | WMI_11AG_MODE = 0x3, | 1153 | WMI_11AG_MODE = 0x3, |
1152 | WMI_11B_MODE = 0x4, | 1154 | WMI_11B_MODE = 0x4, |
1153 | WMI_11GONLY_MODE = 0x5, | 1155 | WMI_11GONLY_MODE = 0x5, |
1156 | WMI_11G_HT20 = 0x6, | ||
1154 | }; | 1157 | }; |
1155 | 1158 | ||
1156 | #define WMI_MAX_CHANNELS 32 | 1159 | #define WMI_MAX_CHANNELS 32 |
@@ -1416,6 +1419,16 @@ struct wmi_ready_event_2 { | |||
1416 | u8 phy_cap; | 1419 | u8 phy_cap; |
1417 | } __packed; | 1420 | } __packed; |
1418 | 1421 | ||
1422 | /* WMI_PHY_CAPABILITY */ | ||
1423 | enum wmi_phy_cap { | ||
1424 | WMI_11A_CAP = 0x01, | ||
1425 | WMI_11G_CAP = 0x02, | ||
1426 | WMI_11AG_CAP = 0x03, | ||
1427 | WMI_11AN_CAP = 0x04, | ||
1428 | WMI_11GN_CAP = 0x05, | ||
1429 | WMI_11AGN_CAP = 0x06, | ||
1430 | }; | ||
1431 | |||
1419 | /* Connect Event */ | 1432 | /* Connect Event */ |
1420 | struct wmi_connect_event { | 1433 | struct wmi_connect_event { |
1421 | union { | 1434 | union { |
@@ -1468,6 +1481,17 @@ enum wmi_disconnect_reason { | |||
1468 | IBSS_MERGE = 0xe, | 1481 | IBSS_MERGE = 0xe, |
1469 | }; | 1482 | }; |
1470 | 1483 | ||
1484 | /* AP mode disconnect proto_reasons */ | ||
1485 | enum ap_disconnect_reason { | ||
1486 | WMI_AP_REASON_STA_LEFT = 101, | ||
1487 | WMI_AP_REASON_FROM_HOST = 102, | ||
1488 | WMI_AP_REASON_COMM_TIMEOUT = 103, | ||
1489 | WMI_AP_REASON_MAX_STA = 104, | ||
1490 | WMI_AP_REASON_ACL = 105, | ||
1491 | WMI_AP_REASON_STA_ROAM = 106, | ||
1492 | WMI_AP_REASON_DFS_CHANNEL = 107, | ||
1493 | }; | ||
1494 | |||
1471 | #define ATH6KL_COUNTRY_RD_SHIFT 16 | 1495 | #define ATH6KL_COUNTRY_RD_SHIFT 16 |
1472 | 1496 | ||
1473 | struct ath6kl_wmi_regdomain { | 1497 | struct ath6kl_wmi_regdomain { |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index a0387a027db0..9fdd70fcaf5b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -892,34 +892,6 @@ static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah) | |||
892 | AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); | 892 | AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); |
893 | } | 893 | } |
894 | 894 | ||
895 | static bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan) | ||
896 | { | ||
897 | struct ath9k_rtt_hist *hist; | ||
898 | u32 *table; | ||
899 | int i; | ||
900 | bool restore; | ||
901 | |||
902 | if (!ah->caldata) | ||
903 | return false; | ||
904 | |||
905 | hist = &ah->caldata->rtt_hist; | ||
906 | if (!hist->num_readings) | ||
907 | return false; | ||
908 | |||
909 | ar9003_hw_rtt_enable(ah); | ||
910 | ar9003_hw_rtt_set_mask(ah, 0x00); | ||
911 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
912 | if (!(ah->rxchainmask & (1 << i))) | ||
913 | continue; | ||
914 | table = &hist->table[i][hist->num_readings][0]; | ||
915 | ar9003_hw_rtt_load_hist(ah, i, table); | ||
916 | } | ||
917 | restore = ar9003_hw_rtt_force_restore(ah); | ||
918 | ar9003_hw_rtt_disable(ah); | ||
919 | |||
920 | return restore; | ||
921 | } | ||
922 | |||
923 | static bool ar9003_hw_init_cal(struct ath_hw *ah, | 895 | static bool ar9003_hw_init_cal(struct ath_hw *ah, |
924 | struct ath9k_channel *chan) | 896 | struct ath9k_channel *chan) |
925 | { | 897 | { |
@@ -942,9 +914,10 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
942 | if (!ar9003_hw_rtt_restore(ah, chan)) | 914 | if (!ar9003_hw_rtt_restore(ah, chan)) |
943 | run_rtt_cal = true; | 915 | run_rtt_cal = true; |
944 | 916 | ||
945 | ath_dbg(common, CALIBRATE, "RTT restore %s\n", | 917 | if (run_rtt_cal) |
946 | run_rtt_cal ? "failed" : "succeed"); | 918 | ath_dbg(common, CALIBRATE, "RTT calibration to be done\n"); |
947 | } | 919 | } |
920 | |||
948 | run_agc_cal = run_rtt_cal; | 921 | run_agc_cal = run_rtt_cal; |
949 | 922 | ||
950 | if (run_rtt_cal) { | 923 | if (run_rtt_cal) { |
@@ -1069,17 +1042,14 @@ skip_tx_iqcal: | |||
1069 | #undef CL_TAB_ENTRY | 1042 | #undef CL_TAB_ENTRY |
1070 | 1043 | ||
1071 | if (run_rtt_cal && caldata) { | 1044 | if (run_rtt_cal && caldata) { |
1072 | struct ath9k_rtt_hist *hist = &caldata->rtt_hist; | 1045 | if (is_reusable) { |
1073 | if (is_reusable && (hist->num_readings < RTT_HIST_MAX)) { | 1046 | if (!ath9k_hw_rfbus_req(ah)) |
1074 | u32 *table; | 1047 | ath_err(ath9k_hw_common(ah), |
1048 | "Could not stop baseband\n"); | ||
1049 | else | ||
1050 | ar9003_hw_rtt_fill_hist(ah); | ||
1075 | 1051 | ||
1076 | hist->num_readings++; | 1052 | ath9k_hw_rfbus_done(ah); |
1077 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
1078 | if (!(ah->rxchainmask & (1 << i))) | ||
1079 | continue; | ||
1080 | table = &hist->table[i][hist->num_readings][0]; | ||
1081 | ar9003_hw_rtt_fill_hist(ah, i, table); | ||
1082 | } | ||
1083 | } | 1053 | } |
1084 | 1054 | ||
1085 | ar9003_hw_rtt_disable(ah); | 1055 | ar9003_hw_rtt_disable(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 3cac293a2849..ffbb180f91e1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c | |||
@@ -756,7 +756,7 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
756 | if (caldata) { | 756 | if (caldata) { |
757 | caldata->done_txiqcal_once = false; | 757 | caldata->done_txiqcal_once = false; |
758 | caldata->done_txclcal_once = false; | 758 | caldata->done_txclcal_once = false; |
759 | caldata->rtt_hist.num_readings = 0; | 759 | caldata->rtt_done = false; |
760 | } | 760 | } |
761 | 761 | ||
762 | if (!ath9k_hw_init_cal(ah, chan)) | 762 | if (!ath9k_hw_init_cal(ah, chan)) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c index 458bedf0b0ae..74de3539c2c8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "hw.h" | 17 | #include "hw.h" |
18 | #include "hw-ops.h" | ||
18 | #include "ar9003_phy.h" | 19 | #include "ar9003_phy.h" |
19 | #include "ar9003_rtt.h" | 20 | #include "ar9003_rtt.h" |
20 | 21 | ||
@@ -69,7 +70,7 @@ bool ar9003_hw_rtt_force_restore(struct ath_hw *ah) | |||
69 | } | 70 | } |
70 | 71 | ||
71 | static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain, | 72 | static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain, |
72 | u32 index, u32 data28) | 73 | u32 index, u32 data28) |
73 | { | 74 | { |
74 | u32 val; | 75 | u32 val; |
75 | 76 | ||
@@ -100,12 +101,21 @@ static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain, | |||
100 | RTT_ACCESS_TIMEOUT); | 101 | RTT_ACCESS_TIMEOUT); |
101 | } | 102 | } |
102 | 103 | ||
103 | void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table) | 104 | void ar9003_hw_rtt_load_hist(struct ath_hw *ah) |
104 | { | 105 | { |
105 | int i; | 106 | int chain, i; |
106 | 107 | ||
107 | for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) | 108 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { |
108 | ar9003_hw_rtt_load_hist_entry(ah, chain, i, table[i]); | 109 | if (!(ah->rxchainmask & (1 << chain))) |
110 | continue; | ||
111 | for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) { | ||
112 | ar9003_hw_rtt_load_hist_entry(ah, chain, i, | ||
113 | ah->caldata->rtt_table[chain][i]); | ||
114 | ath_dbg(ath9k_hw_common(ah), CALIBRATE, | ||
115 | "Load RTT value at idx %d, chain %d: 0x%x\n", | ||
116 | i, chain, ah->caldata->rtt_table[chain][i]); | ||
117 | } | ||
118 | } | ||
109 | } | 119 | } |
110 | 120 | ||
111 | static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index) | 121 | static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index) |
@@ -128,27 +138,71 @@ static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index) | |||
128 | RTT_ACCESS_TIMEOUT)) | 138 | RTT_ACCESS_TIMEOUT)) |
129 | return RTT_BAD_VALUE; | 139 | return RTT_BAD_VALUE; |
130 | 140 | ||
131 | val = REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)); | 141 | val = MS(REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)), |
142 | AR_PHY_RTT_SW_RTT_TABLE_DATA); | ||
143 | |||
132 | 144 | ||
133 | return val; | 145 | return val; |
134 | } | 146 | } |
135 | 147 | ||
136 | void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table) | 148 | void ar9003_hw_rtt_fill_hist(struct ath_hw *ah) |
137 | { | 149 | { |
138 | int i; | 150 | int chain, i; |
151 | |||
152 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | ||
153 | if (!(ah->rxchainmask & (1 << chain))) | ||
154 | continue; | ||
155 | for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) { | ||
156 | ah->caldata->rtt_table[chain][i] = | ||
157 | ar9003_hw_rtt_fill_hist_entry(ah, chain, i); | ||
158 | ath_dbg(ath9k_hw_common(ah), CALIBRATE, | ||
159 | "RTT value at idx %d, chain %d is: 0x%x\n", | ||
160 | i, chain, ah->caldata->rtt_table[chain][i]); | ||
161 | } | ||
162 | } | ||
139 | 163 | ||
140 | for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) | 164 | ah->caldata->rtt_done = true; |
141 | table[i] = ar9003_hw_rtt_fill_hist_entry(ah, chain, i); | ||
142 | } | 165 | } |
143 | 166 | ||
144 | void ar9003_hw_rtt_clear_hist(struct ath_hw *ah) | 167 | void ar9003_hw_rtt_clear_hist(struct ath_hw *ah) |
145 | { | 168 | { |
146 | int i, j; | 169 | int chain, i; |
147 | 170 | ||
148 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | 171 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { |
149 | if (!(ah->rxchainmask & (1 << i))) | 172 | if (!(ah->rxchainmask & (1 << chain))) |
150 | continue; | 173 | continue; |
151 | for (j = 0; j < MAX_RTT_TABLE_ENTRY; j++) | 174 | for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) |
152 | ar9003_hw_rtt_load_hist_entry(ah, i, j, 0); | 175 | ar9003_hw_rtt_load_hist_entry(ah, chain, i, 0); |
153 | } | 176 | } |
177 | |||
178 | if (ah->caldata) | ||
179 | ah->caldata->rtt_done = false; | ||
180 | } | ||
181 | |||
182 | bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan) | ||
183 | { | ||
184 | bool restore; | ||
185 | |||
186 | if (!ah->caldata) | ||
187 | return false; | ||
188 | |||
189 | if (!ah->caldata->rtt_done) | ||
190 | return false; | ||
191 | |||
192 | ar9003_hw_rtt_enable(ah); | ||
193 | ar9003_hw_rtt_set_mask(ah, 0x10); | ||
194 | |||
195 | if (!ath9k_hw_rfbus_req(ah)) { | ||
196 | ath_err(ath9k_hw_common(ah), "Could not stop baseband\n"); | ||
197 | restore = false; | ||
198 | goto fail; | ||
199 | } | ||
200 | |||
201 | ar9003_hw_rtt_load_hist(ah); | ||
202 | restore = ar9003_hw_rtt_force_restore(ah); | ||
203 | |||
204 | fail: | ||
205 | ath9k_hw_rfbus_done(ah); | ||
206 | ar9003_hw_rtt_disable(ah); | ||
207 | return restore; | ||
154 | } | 208 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h index 030758d087d6..a43b30d723a4 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h | |||
@@ -21,8 +21,9 @@ void ar9003_hw_rtt_enable(struct ath_hw *ah); | |||
21 | void ar9003_hw_rtt_disable(struct ath_hw *ah); | 21 | void ar9003_hw_rtt_disable(struct ath_hw *ah); |
22 | void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask); | 22 | void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask); |
23 | bool ar9003_hw_rtt_force_restore(struct ath_hw *ah); | 23 | bool ar9003_hw_rtt_force_restore(struct ath_hw *ah); |
24 | void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table); | 24 | void ar9003_hw_rtt_load_hist(struct ath_hw *ah); |
25 | void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table); | 25 | void ar9003_hw_rtt_fill_hist(struct ath_hw *ah); |
26 | void ar9003_hw_rtt_clear_hist(struct ath_hw *ah); | 26 | void ar9003_hw_rtt_clear_hist(struct ath_hw *ah); |
27 | bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan); | ||
27 | 28 | ||
28 | #endif | 29 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index f84477c5ebb1..abe05ec85d50 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1702,10 +1702,10 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) | |||
1702 | * For AR9462, make sure that calibration data for | 1702 | * For AR9462, make sure that calibration data for |
1703 | * re-using are present. | 1703 | * re-using are present. |
1704 | */ | 1704 | */ |
1705 | if (AR_SREV_9462(ah) && (!ah->caldata || | 1705 | if (AR_SREV_9462(ah) && (ah->caldata && |
1706 | !ah->caldata->done_txiqcal_once || | 1706 | (!ah->caldata->done_txiqcal_once || |
1707 | !ah->caldata->done_txclcal_once || | 1707 | !ah->caldata->done_txclcal_once || |
1708 | !ah->caldata->rtt_hist.num_readings)) | 1708 | !ah->caldata->rtt_done))) |
1709 | goto fail; | 1709 | goto fail; |
1710 | 1710 | ||
1711 | ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n", | 1711 | ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n", |
@@ -1941,7 +1941,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1941 | if (caldata) { | 1941 | if (caldata) { |
1942 | caldata->done_txiqcal_once = false; | 1942 | caldata->done_txiqcal_once = false; |
1943 | caldata->done_txclcal_once = false; | 1943 | caldata->done_txclcal_once = false; |
1944 | caldata->rtt_hist.num_readings = 0; | ||
1945 | } | 1944 | } |
1946 | if (!ath9k_hw_init_cal(ah, chan)) | 1945 | if (!ath9k_hw_init_cal(ah, chan)) |
1947 | return -EIO; | 1946 | return -EIO; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 828b9bbc456d..b620c557c2a6 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -348,12 +348,6 @@ enum ath9k_int { | |||
348 | CHANNEL_HT40MINUS) | 348 | CHANNEL_HT40MINUS) |
349 | 349 | ||
350 | #define MAX_RTT_TABLE_ENTRY 6 | 350 | #define MAX_RTT_TABLE_ENTRY 6 |
351 | #define RTT_HIST_MAX 3 | ||
352 | struct ath9k_rtt_hist { | ||
353 | u32 table[AR9300_MAX_CHAINS][RTT_HIST_MAX][MAX_RTT_TABLE_ENTRY]; | ||
354 | u8 num_readings; | ||
355 | }; | ||
356 | |||
357 | #define MAX_IQCAL_MEASUREMENT 8 | 351 | #define MAX_IQCAL_MEASUREMENT 8 |
358 | #define MAX_CL_TAB_ENTRY 16 | 352 | #define MAX_CL_TAB_ENTRY 16 |
359 | 353 | ||
@@ -363,6 +357,7 @@ struct ath9k_hw_cal_data { | |||
363 | int32_t CalValid; | 357 | int32_t CalValid; |
364 | int8_t iCoff; | 358 | int8_t iCoff; |
365 | int8_t qCoff; | 359 | int8_t qCoff; |
360 | bool rtt_done; | ||
366 | bool paprd_done; | 361 | bool paprd_done; |
367 | bool nfcal_pending; | 362 | bool nfcal_pending; |
368 | bool nfcal_interference; | 363 | bool nfcal_interference; |
@@ -373,8 +368,8 @@ struct ath9k_hw_cal_data { | |||
373 | u32 num_measures[AR9300_MAX_CHAINS]; | 368 | u32 num_measures[AR9300_MAX_CHAINS]; |
374 | int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS]; | 369 | int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS]; |
375 | u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY]; | 370 | u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY]; |
371 | u32 rtt_table[AR9300_MAX_CHAINS][MAX_RTT_TABLE_ENTRY]; | ||
376 | struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; | 372 | struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; |
377 | struct ath9k_rtt_hist rtt_hist; | ||
378 | }; | 373 | }; |
379 | 374 | ||
380 | struct ath9k_channel { | 375 | struct ath9k_channel { |